Wed, 27 Apr 2016 01:34:52 +0800
Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. |
aoqi@0 | 8 | * |
aoqi@0 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 13 | * accompanied this code). |
aoqi@0 | 14 | * |
aoqi@0 | 15 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 18 | * |
aoqi@0 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 20 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 21 | * questions. |
aoqi@0 | 22 | */ |
aoqi@0 | 23 | |
aoqi@0 | 24 | /* |
aoqi@0 | 25 | * @test |
aoqi@0 | 26 | * @bug 8005085 8005681 8008769 8010015 |
aoqi@0 | 27 | * @summary Check (repeating)type annotations on lambda usage. |
aoqi@0 | 28 | * @run main CombinationsTargetTest3 |
aoqi@0 | 29 | */ |
aoqi@0 | 30 | |
aoqi@0 | 31 | import com.sun.tools.classfile.*; |
aoqi@0 | 32 | import java.io.File; |
aoqi@0 | 33 | import java.util.Vector; |
aoqi@0 | 34 | |
aoqi@0 | 35 | public class CombinationsTargetTest3 extends ClassfileTestHelper { |
aoqi@0 | 36 | |
aoqi@0 | 37 | // Helps identify test case in event of failure. |
aoqi@0 | 38 | int testcount = 0; |
aoqi@0 | 39 | |
aoqi@0 | 40 | // Known failure cases due to open bugs. |
aoqi@0 | 41 | Vector<String> skippedTests = new Vector<>(); |
aoqi@0 | 42 | void printSkips() { |
aoqi@0 | 43 | if(!skippedTests.isEmpty()) { |
aoqi@0 | 44 | println(skippedTests.size() + " tests were skipped:"); |
aoqi@0 | 45 | for(String t : skippedTests) |
aoqi@0 | 46 | println(" " + t); |
aoqi@0 | 47 | } |
aoqi@0 | 48 | } |
aoqi@0 | 49 | |
aoqi@0 | 50 | // Test case descriptions and expected annotation counts. |
aoqi@0 | 51 | enum srce { |
aoqi@0 | 52 | src1("type annotations on lambda expression as method arg.",4,0), |
aoqi@0 | 53 | src2("type annotations on new in single line lambda expression",2,0), |
aoqi@0 | 54 | src3("type annotations in lambda expression code block",4,0), |
aoqi@0 | 55 | src4("type annotations in code block with recursion,cast",2,0), |
aoqi@0 | 56 | src5("type annotations in lambda expression code block",4,0), |
aoqi@0 | 57 | src6("type annotations on type parm in method reference",4,0), |
aoqi@0 | 58 | src7("type annotations on inner class field of lambda expression",2,2), |
aoqi@0 | 59 | src8("type annotations in inner class of lambda expression",4,2), |
aoqi@0 | 60 | src9("type annotations on static method of interface",4,2); |
aoqi@0 | 61 | |
aoqi@0 | 62 | String description; |
aoqi@0 | 63 | // Expected annotation counts are same for Vis or Invis, but which one |
aoqi@0 | 64 | // depends on retention type. |
aoqi@0 | 65 | Integer[] exp = { 0, 0 }; |
aoqi@0 | 66 | |
aoqi@0 | 67 | // If class to test is inner class, this may be set in SourceString() |
aoqi@0 | 68 | String innerClassname = null ; |
aoqi@0 | 69 | |
aoqi@0 | 70 | // If class to test is not main or inner class; set in sourceString() |
aoqi@0 | 71 | String altClassName = null; |
aoqi@0 | 72 | |
aoqi@0 | 73 | srce(String desc, int e1, int e2) { |
aoqi@0 | 74 | description = this + ": " +desc; |
aoqi@0 | 75 | exp[0]=e1; |
aoqi@0 | 76 | exp[1]=e2; |
aoqi@0 | 77 | } |
aoqi@0 | 78 | } |
aoqi@0 | 79 | |
aoqi@0 | 80 | // Check for RuntimeInvisible or RuntimeVisible annotations. |
aoqi@0 | 81 | String[] RType={"CLASS", "RUNTIME"}; |
aoqi@0 | 82 | |
aoqi@0 | 83 | // This can be a compile only test. |
aoqi@0 | 84 | static boolean compileonly=false; |
aoqi@0 | 85 | |
aoqi@0 | 86 | // Collect failure for end of test report() |
aoqi@0 | 87 | Vector<String> vFailures = new Vector<>(); |
aoqi@0 | 88 | |
aoqi@0 | 89 | // pass/fail determined after all tests have run. |
aoqi@0 | 90 | void report() { |
aoqi@0 | 91 | if(vFailures.isEmpty()) { |
aoqi@0 | 92 | printSkips(); |
aoqi@0 | 93 | println("PASS"); |
aoqi@0 | 94 | } else { |
aoqi@0 | 95 | System.err.println("FAILED: There were failures:"); |
aoqi@0 | 96 | for(String f : vFailures) |
aoqi@0 | 97 | System.err.println(f); |
aoqi@0 | 98 | throw new RuntimeException("There were failures. See test log."); |
aoqi@0 | 99 | } |
aoqi@0 | 100 | } |
aoqi@0 | 101 | |
aoqi@0 | 102 | public static void main(String[] args) throws Exception { |
aoqi@0 | 103 | if(args.length>0 && args[0].compareTo("compileonly")==0) |
aoqi@0 | 104 | compileonly=true; |
aoqi@0 | 105 | new CombinationsTargetTest3().run(); |
aoqi@0 | 106 | } |
aoqi@0 | 107 | |
aoqi@0 | 108 | void run() throws Exception { |
aoqi@0 | 109 | // Determines which repeat and order in source(ABMix). |
aoqi@0 | 110 | Boolean As= false, BDs=true, ABMix=false; |
aoqi@0 | 111 | int testrun=0; |
aoqi@0 | 112 | // A repeats and/or B/D repeats, ABMix for order of As and Bs. |
aoqi@0 | 113 | Boolean [][] bRepeat = new Boolean[][]{{false,false,false}, //no repeats |
aoqi@0 | 114 | {true,false,false}, //repeat @A |
aoqi@0 | 115 | {false,true,false}, //repeat @B |
aoqi@0 | 116 | {true,true,false}, //repeat both |
aoqi@0 | 117 | {false,false,true} //repeat mix |
aoqi@0 | 118 | }; |
aoqi@0 | 119 | // Added ElementType's. All set; not permuted (so far) for this test |
aoqi@0 | 120 | String et = "TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE"; |
aoqi@0 | 121 | |
aoqi@0 | 122 | // test loop |
aoqi@0 | 123 | for(Boolean[] bCombo : bRepeat) { |
aoqi@0 | 124 | As=bCombo[0]; BDs=bCombo[1]; ABMix=bCombo[2]; |
aoqi@0 | 125 | for(srce src : srce.values()) |
aoqi@0 | 126 | for( String rtype : RType ) { |
aoqi@0 | 127 | switch( rtype ) { |
aoqi@0 | 128 | case "RUNTIME": |
aoqi@0 | 129 | test(0,src.exp[0],0,src.exp[1],As, BDs, ABMix, |
aoqi@0 | 130 | "RUNTIME", et, ++testrun, src); |
aoqi@0 | 131 | break; |
aoqi@0 | 132 | case "CLASS": |
aoqi@0 | 133 | test(src.exp[0],0,src.exp[1],0,As, BDs, ABMix, |
aoqi@0 | 134 | "CLASS", et, ++testrun, src); |
aoqi@0 | 135 | break; |
aoqi@0 | 136 | } |
aoqi@0 | 137 | } |
aoqi@0 | 138 | } |
aoqi@0 | 139 | report(); |
aoqi@0 | 140 | } |
aoqi@0 | 141 | |
aoqi@0 | 142 | // Filter out skipped cases, compile, pass class file to test method, |
aoqi@0 | 143 | // count annotations and asses results. |
aoqi@0 | 144 | public void test(int tinv, int tvis, int inv, int vis, Boolean Arepeats, |
aoqi@0 | 145 | Boolean BDrepeats, Boolean ABmix, String rtn, String et2, |
aoqi@0 | 146 | Integer N, srce source) throws Exception { |
aoqi@0 | 147 | ++testcount; |
aoqi@0 | 148 | expected_tvisibles = tvis; |
aoqi@0 | 149 | expected_tinvisibles = tinv; |
aoqi@0 | 150 | expected_visibles = vis; |
aoqi@0 | 151 | expected_invisibles = inv; |
aoqi@0 | 152 | File testFile = null; |
aoqi@0 | 153 | String tname="Test" + N.toString(); |
aoqi@0 | 154 | String testDef = "Test " + testcount + " parameters: tinv=" + tinv + |
aoqi@0 | 155 | ", tvis=" + tvis + ", inv=" + inv + ", vis=" + vis + |
aoqi@0 | 156 | ", Arepeats=" + Arepeats + ", BDrepeats=" + BDrepeats + |
aoqi@0 | 157 | ", ABmix=" + ABmix + ", retention: " + rtn + ", anno2: " + |
aoqi@0 | 158 | et2 + ", src=" + source; |
aoqi@0 | 159 | |
aoqi@0 | 160 | // Skip failing cases with bug ID's |
aoqi@0 | 161 | if ((source.equals(srce.src2) || source.equals(srce.src4) || |
aoqi@0 | 162 | source.equals(srce.src5)) && |
aoqi@0 | 163 | (ABmix || (Arepeats && BDrepeats))) { |
aoqi@0 | 164 | skippedTests.add(testDef + |
aoqi@0 | 165 | "\n--8005681 repeated type-annotations on new/cast/array in" + |
aoqi@0 | 166 | " inner class in lambda expression."); |
aoqi@0 | 167 | return; |
aoqi@0 | 168 | }//8008769 Repeated type-annotations on type parm of local variable |
aoqi@0 | 169 | else if (source.equals(srce.src6) && |
aoqi@0 | 170 | (ABmix || (Arepeats && BDrepeats))) { |
aoqi@0 | 171 | skippedTests.add(testDef + "\n--8008769 Repeated " + |
aoqi@0 | 172 | "type-annotations on type parm of local variable"); |
aoqi@0 | 173 | return; |
aoqi@0 | 174 | } |
aoqi@0 | 175 | |
aoqi@0 | 176 | println(testDef); |
aoqi@0 | 177 | // Create test source and File. |
aoqi@0 | 178 | String sourceString = sourceString(tname, rtn, et2, Arepeats, |
aoqi@0 | 179 | BDrepeats, ABmix, source); |
aoqi@0 | 180 | testFile = writeTestFile(tname+".java", sourceString); |
aoqi@0 | 181 | // Compile test source and read classfile. |
aoqi@0 | 182 | File classFile = null; |
aoqi@0 | 183 | try { |
aoqi@0 | 184 | classFile = compile(testFile); |
aoqi@0 | 185 | System.out.println("pass compile: " + tname + ".java"); |
aoqi@0 | 186 | } catch (Error err) { |
aoqi@0 | 187 | System.err.println("fail compile. Source:\n" + sourceString); |
aoqi@0 | 188 | throw err; |
aoqi@0 | 189 | } |
aoqi@0 | 190 | if(!compileonly) { |
aoqi@0 | 191 | //check if innerClassname is set |
aoqi@0 | 192 | String classdir = classFile.getAbsolutePath(); |
aoqi@0 | 193 | if(source.innerClassname != null) { |
aoqi@0 | 194 | StringBuffer sb = new StringBuffer(classdir); |
aoqi@0 | 195 | classFile=new File(sb.insert(sb.lastIndexOf(".class"), |
aoqi@0 | 196 | source.innerClassname).toString()); |
aoqi@0 | 197 | source.innerClassname=null; |
aoqi@0 | 198 | } else if (source.altClassName != null) { |
aoqi@0 | 199 | classdir = classdir.substring(0,classdir.lastIndexOf("Test")); |
aoqi@0 | 200 | classFile=new File(classdir.concat(source.altClassName)); |
aoqi@0 | 201 | source.innerClassname=null; |
aoqi@0 | 202 | } |
aoqi@0 | 203 | ClassFile cf = ClassFile.read(classFile); |
aoqi@0 | 204 | |
aoqi@0 | 205 | println("Testing classfile: " + cf.getName()); |
aoqi@0 | 206 | //Test class,fields and method counts. |
aoqi@0 | 207 | test(cf); |
aoqi@0 | 208 | |
aoqi@0 | 209 | for (Field f : cf.fields) { |
aoqi@0 | 210 | test(cf, f); |
aoqi@0 | 211 | test(cf, f, true); |
aoqi@0 | 212 | } |
aoqi@0 | 213 | for (Method m: cf.methods) { |
aoqi@0 | 214 | test(cf, m); |
aoqi@0 | 215 | test(cf, m, true); |
aoqi@0 | 216 | } |
aoqi@0 | 217 | |
aoqi@0 | 218 | countAnnotations(); // sets errors=0 before counting. |
aoqi@0 | 219 | if (errors > 0) { |
aoqi@0 | 220 | System.err.println( testDef ); |
aoqi@0 | 221 | System.err.println( "Source:\n" + sourceString ); |
aoqi@0 | 222 | vFailures.add(testDef); |
aoqi@0 | 223 | } |
aoqi@0 | 224 | } |
aoqi@0 | 225 | if(errors==0) println("Pass"); println(""); |
aoqi@0 | 226 | } |
aoqi@0 | 227 | |
aoqi@0 | 228 | /* |
aoqi@0 | 229 | * Source definitions for test cases. |
aoqi@0 | 230 | * To add a test: |
aoqi@0 | 231 | * Add enum to srce(near top of file) with expected annotation counts. |
aoqi@0 | 232 | * Add source defintion below. |
aoqi@0 | 233 | */ |
aoqi@0 | 234 | String sourceString(String testname, String retentn, String annot2, |
aoqi@0 | 235 | Boolean Arepeats, Boolean BDrepeats, Boolean ABmix, |
aoqi@0 | 236 | srce src) { |
aoqi@0 | 237 | |
aoqi@0 | 238 | String As = "@A", Bs = "@B", Ds = "@D"; |
aoqi@0 | 239 | if(Arepeats) As = "@A @A"; |
aoqi@0 | 240 | if(BDrepeats) { |
aoqi@0 | 241 | Bs = "@B @B"; |
aoqi@0 | 242 | Ds = "@D @D"; |
aoqi@0 | 243 | } |
aoqi@0 | 244 | if(ABmix) { As = "@A @B"; Bs = "@A @B"; Ds = "@D @D"; } |
aoqi@0 | 245 | |
aoqi@0 | 246 | // Source to check for TYPE_USE and TYPE_PARAMETER annotations. |
aoqi@0 | 247 | // Source base (annotations) is same for all test cases. |
aoqi@0 | 248 | String source = new String(); |
aoqi@0 | 249 | String imports = new String("import java.lang.annotation.*; \n" + |
aoqi@0 | 250 | "import static java.lang.annotation.RetentionPolicy.*; \n" + |
aoqi@0 | 251 | "import static java.lang.annotation.ElementType.*; \n" + |
aoqi@0 | 252 | "import java.util.List; \n" + |
aoqi@0 | 253 | "import java.util.ArrayList;\n\n"); |
aoqi@0 | 254 | |
aoqi@0 | 255 | String sourceBase = new String( |
aoqi@0 | 256 | "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @Repeatable( AC.class ) @interface A { }\n" + |
aoqi@0 | 257 | "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @interface AC { A[] value(); } \n" + |
aoqi@0 | 258 | "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @Repeatable( BC.class ) @interface B { }\n" + |
aoqi@0 | 259 | "@Retention("+retentn+") @Target({TYPE_USE,_OTHER_}) @interface BC { B[] value(); } \n" + |
aoqi@0 | 260 | "@Retention("+retentn+") @Target({TYPE_USE,TYPE_PARAMETER,_OTHER_}) @Repeatable(DC.class) @interface D { }\n" + |
aoqi@0 | 261 | "@Retention("+retentn+") @Target({TYPE_USE,TYPE_PARAMETER,_OTHER_}) @interface DC { D[] value(); }"); |
aoqi@0 | 262 | |
aoqi@0 | 263 | // Test case sources with sample generated source |
aoqi@0 | 264 | switch(src) { |
aoqi@0 | 265 | case src1: //(repeating) type annotations on lambda expressions. |
aoqi@0 | 266 | /* |
aoqi@0 | 267 | * class Test1 { |
aoqi@0 | 268 | * Test1(){} |
aoqi@0 | 269 | * interface MapFun<T,R> { R m( T n); } |
aoqi@0 | 270 | * void meth( MapFun<String,Integer> mf ) { |
aoqi@0 | 271 | * assert( mf.m("four") == 4); |
aoqi@0 | 272 | * } |
aoqi@0 | 273 | * void test(Integer i) { |
aoqi@0 | 274 | * // lambda expression as method arg |
aoqi@0 | 275 | * meth( (@A @B String s) -> { @A @B Integer len = s.length(); return len; } ); |
aoqi@0 | 276 | * }} |
aoqi@0 | 277 | */ |
aoqi@0 | 278 | source = new String( source + |
aoqi@0 | 279 | "// " + src.description + "\n" + |
aoqi@0 | 280 | "class " + testname + " {\n" + |
aoqi@0 | 281 | " " + testname +"(){} \n" + |
aoqi@0 | 282 | " interface MapFun<T,R> { R m( T n); }\n\n" + |
aoqi@0 | 283 | " void meth( MapFun<String,Integer> mf ) {\n" + |
aoqi@0 | 284 | " assert( mf.m(\"four\") == 4);\n" + |
aoqi@0 | 285 | " }\n\n" + |
aoqi@0 | 286 | " void test(Integer i) {\n" + |
aoqi@0 | 287 | " // lambda expression as method arg\n" + |
aoqi@0 | 288 | " meth( (_As_ _Bs_ String s) -> { _As_ _Bs_ Integer len = s.length(); return len; } );\n" + |
aoqi@0 | 289 | "}}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 290 | "\n"; |
aoqi@0 | 291 | break; |
aoqi@0 | 292 | case src2: //(repeating) type annotations on new in single line lambda expression. |
aoqi@0 | 293 | /* |
aoqi@0 | 294 | * //case2: (repeating) type annotations on new in single lambda expressions. |
aoqi@0 | 295 | * class Test2{ |
aoqi@0 | 296 | * interface MapFun<T, R> { R m( T n); } |
aoqi@0 | 297 | * MapFun<Integer, String> its; |
aoqi@0 | 298 | * void test(Integer i) { |
aoqi@0 | 299 | * its = a -> "~"+new @A @B Integer(a).toString()+"~"; |
aoqi@0 | 300 | * System.out.println("in: " + i + " out: " + its.m(i)); |
aoqi@0 | 301 | * }} |
aoqi@0 | 302 | */ |
aoqi@0 | 303 | source = new String( source + |
aoqi@0 | 304 | "// " + src.description + "\n" + |
aoqi@0 | 305 | "class " + testname + "{\n" + |
aoqi@0 | 306 | " interface MapFun<T, R> { R m( T n); }\n" + |
aoqi@0 | 307 | " MapFun<Integer, String> its;\n" + |
aoqi@0 | 308 | " void test(Integer i) {\n" + |
aoqi@0 | 309 | " its = a -> \"~\"+new _As_ _Bs_ Integer(a).toString()+\"~\";\n" + |
aoqi@0 | 310 | " System.out.println(\"in: \" + i + \" out: \" + its.m(i));\n" + |
aoqi@0 | 311 | " }\n" + |
aoqi@0 | 312 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 313 | "\n"; |
aoqi@0 | 314 | break; |
aoqi@0 | 315 | case src3: //(repeating) type annotations in lambda expression code block. |
aoqi@0 | 316 | /* |
aoqi@0 | 317 | * class Test183{ |
aoqi@0 | 318 | * interface MapFun<T, R> { R m( T n); } |
aoqi@0 | 319 | * MapFun<List<Integer>, String> iLs; |
aoqi@0 | 320 | * void testm(Integer i) { |
aoqi@0 | 321 | * iLs = l -> { @A @B @A @B String ret = new String(); |
aoqi@0 | 322 | * for( @A @B @A @B Integer i2 : l) |
aoqi@0 | 323 | * ret=ret.concat(i2.toString() + " "); |
aoqi@0 | 324 | * return ret; }; |
aoqi@0 | 325 | * List<Integer> li = new ArrayList<>(); |
aoqi@0 | 326 | * for(int j=0; j<i; j++) li.add(j); |
aoqi@0 | 327 | * System.out.println(iLs.m(li) ); |
aoqi@0 | 328 | * }} |
aoqi@0 | 329 | */ |
aoqi@0 | 330 | source = new String( source + |
aoqi@0 | 331 | "// " + src.description + "\n" + |
aoqi@0 | 332 | "class "+ testname + "{\n" + |
aoqi@0 | 333 | " interface MapFun<T, R> { R m( T n); }\n" + |
aoqi@0 | 334 | " MapFun<List<Integer>, String> iLs;\n" + |
aoqi@0 | 335 | " void testm(Integer i) {\n" + |
aoqi@0 | 336 | " iLs = l -> { _As_ _Bs_ String ret = new String();\n" + |
aoqi@0 | 337 | " for( _As_ _Bs_ Integer i2 : l)\n" + |
aoqi@0 | 338 | " ret=ret.concat(i2.toString() + \" \");\n" + |
aoqi@0 | 339 | " return ret; };\n" + |
aoqi@0 | 340 | " List<Integer> li = new ArrayList<>();\n" + |
aoqi@0 | 341 | " for(int j=0; j<i; j++) li.add(j);\n" + |
aoqi@0 | 342 | " System.out.println(iLs.m(li) );\n" + |
aoqi@0 | 343 | "}\n" + |
aoqi@0 | 344 | "\n" + |
aoqi@0 | 345 | " public static void main(String... args) {new " + testname + "().testm(5); }\n" + |
aoqi@0 | 346 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 347 | "\n"; |
aoqi@0 | 348 | break; |
aoqi@0 | 349 | case src4: //(repeating) type annotations in code block with recursion,cast |
aoqi@0 | 350 | /* |
aoqi@0 | 351 | * class Test194{ |
aoqi@0 | 352 | * interface MapFun<T, R> { R m( T n); } |
aoqi@0 | 353 | * MapFun<Integer, Double> nf; |
aoqi@0 | 354 | * void testm(Integer i) { |
aoqi@0 | 355 | * nf = j -> { return j == 1 ? 1.0 : (@A @B @A @B Double)(nf.m(j-1) * j); }; |
aoqi@0 | 356 | * System.out.println( "nf.m(" + i + "): " + nf.m(i)); |
aoqi@0 | 357 | * } |
aoqi@0 | 358 | * } |
aoqi@0 | 359 | */ |
aoqi@0 | 360 | source = new String( source + |
aoqi@0 | 361 | "// " + src.description + "\n" + |
aoqi@0 | 362 | "class "+ testname + "{\n" + |
aoqi@0 | 363 | " interface MapFun<T, R> { R m( T n); }\n" + |
aoqi@0 | 364 | " MapFun<Integer, Double> nf;\n" + |
aoqi@0 | 365 | " void testm(Integer i) {\n" + |
aoqi@0 | 366 | " nf = j -> { return j == 1 ? 1.0 : (_As_ _Bs_ Double)(nf.m(j-1) * j); };\n" + |
aoqi@0 | 367 | " System.out.println( \"nf.m(\" + i + \"): \" + nf.m(i));\n" + |
aoqi@0 | 368 | " }\n" + |
aoqi@0 | 369 | " public static void main(String... args) {new " + testname + "().testm(5); }\n" + |
aoqi@0 | 370 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 371 | "\n"; |
aoqi@0 | 372 | break; |
aoqi@0 | 373 | case src5: //(repeating) type annotations in lambda expression code block. |
aoqi@0 | 374 | /* |
aoqi@0 | 375 | * class Test180 { |
aoqi@0 | 376 | * interface MapFun<T, R> { R m( T n); } |
aoqi@0 | 377 | * MapFun<Integer,List<Integer>> iLi; |
aoqi@0 | 378 | * void test(Integer i) { |
aoqi@0 | 379 | * // type parameter use. |
aoqi@0 | 380 | * iLi = n -> { List<@A @B @A @B Integer> LI = new ArrayList<@A @B @A @B Integer>(n); |
aoqi@0 | 381 | * for(int nn = n; nn >=0; nn--) LI.add(nn); |
aoqi@0 | 382 | * return LI; }; |
aoqi@0 | 383 | * List<Integer> li = iLi.m(i); |
aoqi@0 | 384 | * for(Integer k : li) System.out.print(k); |
aoqi@0 | 385 | * } |
aoqi@0 | 386 | * } |
aoqi@0 | 387 | */ |
aoqi@0 | 388 | source = new String( source + |
aoqi@0 | 389 | "// " + src.description + "\n" + |
aoqi@0 | 390 | "class "+ testname + "{\n" + |
aoqi@0 | 391 | " interface MapFun<T, R> { R m( T n); }\n" + |
aoqi@0 | 392 | " MapFun<Integer,List<Integer>> iLi;\n" + |
aoqi@0 | 393 | " void test(Integer i) {\n" + |
aoqi@0 | 394 | " // type parameter use.\n" + |
aoqi@0 | 395 | " iLi = n -> { List<_As_ _Bs_ Integer> LI = new ArrayList<_As_ _Bs_ Integer>(n);\n" + |
aoqi@0 | 396 | " for(int nn = n; nn >=0; nn--) LI.add(nn);\n" + |
aoqi@0 | 397 | " return LI; };\n" + |
aoqi@0 | 398 | " List<Integer> li = iLi.m(i);\n" + |
aoqi@0 | 399 | " for(Integer k : li) System.out.print(k);\n" + |
aoqi@0 | 400 | "}\n" + |
aoqi@0 | 401 | " public static void main(String... args) {new " + testname + "().test(5); }\n" + |
aoqi@0 | 402 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs).replace("_Ds_",Ds) + |
aoqi@0 | 403 | "\n"; |
aoqi@0 | 404 | break; |
aoqi@0 | 405 | case src6: //(repeating) type annotations on type parm in method reference. |
aoqi@0 | 406 | /* |
aoqi@0 | 407 | * class Test240{ |
aoqi@0 | 408 | * interface PrintString { void print(String s); } |
aoqi@0 | 409 | * public void printArray(Object[] oa, PrintString ps) { |
aoqi@0 | 410 | * for(Object o : oa ) ps.print(o.toString()); |
aoqi@0 | 411 | * } |
aoqi@0 | 412 | * public void test() { |
aoqi@0 | 413 | * Integer[] intarray = {1,2,3,4,5}; |
aoqi@0 | 414 | * printArray(intarray, @A @B @A @B TPrint::<@A @B @A @B String>print); |
aoqi@0 | 415 | * } |
aoqi@0 | 416 | * } |
aoqi@0 | 417 | * class TPrint { |
aoqi@0 | 418 | * public static <T> void print(T t) { System.out.println( t.toString()); } |
aoqi@0 | 419 | * } |
aoqi@0 | 420 | */ |
aoqi@0 | 421 | source = new String( source + |
aoqi@0 | 422 | "// " + src.description + "\n" + |
aoqi@0 | 423 | "class "+ testname + "{\n" + |
aoqi@0 | 424 | " interface PrintString { void print(String s); }\n" + |
aoqi@0 | 425 | " public void printArray(Object[] oa, PrintString ps) {\n" + |
aoqi@0 | 426 | " for(Object o : oa ) ps.print(o.toString());\n" + |
aoqi@0 | 427 | " }\n" + |
aoqi@0 | 428 | " public void test() {\n" + |
aoqi@0 | 429 | " Integer[] intarray = {1,2,3,4,5};\n" + |
aoqi@0 | 430 | " printArray(intarray, _As_ _Bs_ TPrint::<_As_ _Bs_ String>print);\n" + |
aoqi@0 | 431 | " }\n" + |
aoqi@0 | 432 | " public static void main(String... args) {new " + testname + "().test(); }\n" + |
aoqi@0 | 433 | "}\n\n" + |
aoqi@0 | 434 | "class TPrint {\n" + |
aoqi@0 | 435 | " public static <T> void print(T t) { System.out.println( t.toString()); }\n" + |
aoqi@0 | 436 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 437 | "\n"; |
aoqi@0 | 438 | break; |
aoqi@0 | 439 | case src7: //(repeating)type annotations in inner class of lambda expression. |
aoqi@0 | 440 | /* |
aoqi@0 | 441 | * class Test2{ |
aoqi@0 | 442 | * interface MapFun<T, R> { R m( T n); } |
aoqi@0 | 443 | * MapFun<Class<?>,String> cs; |
aoqi@0 | 444 | * void test() { |
aoqi@0 | 445 | * cs = c -> { |
aoqi@0 | 446 | * class innerClass { |
aoqi@0 | 447 | * @A @B Class<?> icc = null; |
aoqi@0 | 448 | * String getString() { return icc.toString(); } |
aoqi@0 | 449 | * } |
aoqi@0 | 450 | * return new innerClass().getString(); |
aoqi@0 | 451 | * }; |
aoqi@0 | 452 | * System.out.println("cs.m : " + cs.m(Integer.class)); |
aoqi@0 | 453 | * } |
aoqi@0 | 454 | * } |
aoqi@0 | 455 | */ |
aoqi@0 | 456 | source = new String( source + |
aoqi@0 | 457 | "// " + src.description + "\n" + |
aoqi@0 | 458 | "class "+ testname + "{\n" + |
aoqi@0 | 459 | " interface MapFun<T, R> { R m( T n); }\n" + |
aoqi@0 | 460 | " MapFun<Class<?>,String> cs;\n" + |
aoqi@0 | 461 | " void test() {\n" + |
aoqi@0 | 462 | " cs = c -> {\n" + |
aoqi@0 | 463 | " class innerClass {\n" + |
aoqi@0 | 464 | " _As_ _Bs_ Class<?> icc = null;\n" + |
aoqi@0 | 465 | " innerClass(Class<?> _c) { icc = _c; }\n" + |
aoqi@0 | 466 | " String getString() { return icc.toString(); }\n" + |
aoqi@0 | 467 | " }\n" + |
aoqi@0 | 468 | " return new innerClass(c).getString();\n" + |
aoqi@0 | 469 | " };\n" + |
aoqi@0 | 470 | " System.out.println(\"cs.m : \" + cs.m(Integer.class));\n" + |
aoqi@0 | 471 | " }\n" + |
aoqi@0 | 472 | "\n" + |
aoqi@0 | 473 | " public static void main(String... args) {new " + testname + "().test(); }\n" + |
aoqi@0 | 474 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 475 | "\n"; |
aoqi@0 | 476 | src.innerClassname="$1innerClass"; |
aoqi@0 | 477 | break; |
aoqi@0 | 478 | case src8: //(repeating)type annotations in inner class of lambda expression. |
aoqi@0 | 479 | /* |
aoqi@0 | 480 | * class Test2{ |
aoqi@0 | 481 | * interface MapFun<T, R> { R m( T n); } |
aoqi@0 | 482 | * MapFun<Class<?>,String> cs; |
aoqi@0 | 483 | * void test() { |
aoqi@0 | 484 | * cs = c -> { |
aoqi@0 | 485 | * class innerClass { |
aoqi@0 | 486 | * Class<?> icc; |
aoqi@0 | 487 | * innerClass(@A @B Class<?> _c) { icc = _c; } |
aoqi@0 | 488 | * @A @B String getString() { return icc.toString(); } |
aoqi@0 | 489 | * } |
aoqi@0 | 490 | * return new innerClass(c).getString(); |
aoqi@0 | 491 | * }; |
aoqi@0 | 492 | * System.out.println("cs.m : " + cs.m(Integer.class)); |
aoqi@0 | 493 | * } |
aoqi@0 | 494 | * } |
aoqi@0 | 495 | */ |
aoqi@0 | 496 | source = new String( source + |
aoqi@0 | 497 | "// " + src.description + "\n" + |
aoqi@0 | 498 | "class "+ testname + "{\n" + |
aoqi@0 | 499 | " interface MapFun<T, R> { R m( T n); }\n" + |
aoqi@0 | 500 | " MapFun<Class<?>,String> cs;\n" + |
aoqi@0 | 501 | " void test() {\n" + |
aoqi@0 | 502 | " cs = c -> {\n" + |
aoqi@0 | 503 | " class innerClass {\n" + |
aoqi@0 | 504 | " Class<?> icc;\n" + |
aoqi@0 | 505 | " innerClass(_As_ _Bs_ Class<?> _c) { icc = _c; }\n" + |
aoqi@0 | 506 | " _As_ _Bs_ String getString() { return icc.toString(); }\n" + |
aoqi@0 | 507 | " }\n" + |
aoqi@0 | 508 | " return new innerClass(c).getString();\n" + |
aoqi@0 | 509 | " };\n" + |
aoqi@0 | 510 | " System.out.println(\"cs.m : \" + cs.m(Integer.class));\n" + |
aoqi@0 | 511 | " }\n" + |
aoqi@0 | 512 | "\n" + |
aoqi@0 | 513 | " public static void main(String... args) {new " + testname + "().test(); }\n" + |
aoqi@0 | 514 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 515 | "\n"; |
aoqi@0 | 516 | src.innerClassname="$1innerClass"; |
aoqi@0 | 517 | break; |
aoqi@0 | 518 | case src9: //(repeating)type annotations on static method of interface |
aoqi@0 | 519 | /* |
aoqi@0 | 520 | * class Test90{ |
aoqi@0 | 521 | * interface I { |
aoqi@0 | 522 | * static @A @B @A @B String m() { @A @B @A @B String ret = "I.m"; return ret; } |
aoqi@0 | 523 | * } |
aoqi@0 | 524 | * } |
aoqi@0 | 525 | */ |
aoqi@0 | 526 | source = new String( source + |
aoqi@0 | 527 | "// " + src.description + "\n" + |
aoqi@0 | 528 | "class "+ testname + "{\n" + |
aoqi@0 | 529 | " interface I { \n" + |
aoqi@0 | 530 | " static _As_ _Bs_ String m() { _As_ _Bs_ String ret = \"I.m\"; return ret; }\n" + |
aoqi@0 | 531 | " }\n" + |
aoqi@0 | 532 | "}\n\n").concat(sourceBase).replace("_OTHER_", annot2).replace("_As_",As).replace("_Bs_",Bs) + |
aoqi@0 | 533 | "\n"; |
aoqi@0 | 534 | src.innerClassname="$I"; |
aoqi@0 | 535 | break; |
aoqi@0 | 536 | } |
aoqi@0 | 537 | return imports + source; |
aoqi@0 | 538 | } |
aoqi@0 | 539 | } |