1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 7118412 27 * @summary javac should generate method parameters correctly. 28 */ 29 import java.io.File; 30 import java.io.FileWriter; 31 import java.io.IOException; 32 import java.io.PrintWriter; 33 import java.io.StringWriter; 34 35 public class ShadowingTest { 36 37 enum MethodCall { 38 INNER("inner"), 39 TYPEVAR("iterator"), 40 OUTER("outer"); 41 42 public final String methodcall; 43 44 MethodCall(final String methodcall) { 45 this.methodcall = methodcall; 46 } 47 48 public boolean succeeds(final MethodContext ctx, 49 final InsideDef inside, 50 final TyVar tyvar) { 51 switch(this) { 52 case INNER: switch(ctx) { 53 case STATIC: switch(inside) { 54 case INSTANCE: 55 case STATIC: 56 return true; 57 default: return false; 58 } 59 case INSTANCE: switch(inside) { 60 case INSTANCE: 61 case STATIC: return true; 62 default: return false; 63 } 64 } 65 case TYPEVAR: switch(ctx) { 66 case INSTANCE: switch(inside) { 67 case NONE: switch(tyvar) { 68 case YES: return true; 69 default: return false; 70 } 71 default: return false; 72 } 73 default: return false; 74 } 75 case OUTER: switch(inside) { 76 case NONE: switch(tyvar) { 77 case NO: return true; 78 default: return false; 79 } 80 default: return false; 81 } 82 } 83 return false; 84 } 85 } 86 87 enum MethodContext { 88 STATIC("static "), 89 INSTANCE(""); 90 91 public final String methodcontext; 92 93 MethodContext(final String methodcontext) { 94 this.methodcontext = methodcontext; 95 } 96 } 97 98 enum InsideDef { 99 NONE(""), 100 STATIC("static class T { public void inner() {} }\n"), 101 INSTANCE("class T { public void inner() {} }\n"); 102 103 public final String instancedef; 104 105 InsideDef(final String instancedef) { 106 this.instancedef = instancedef; 107 } 108 } 109 110 enum TyVar { 111 NO(""), 112 YES("<T extends Collection>"); 113 114 public final String tyvar; 115 116 TyVar(final String tyvar) { 117 this.tyvar = tyvar; 118 } 119 } 120 121 static final File classesdir = new File("7118412"); 122 123 private int errors = 0; 124 125 public static void main(String... args) throws Exception { 126 new ShadowingTest().run(); 127 } 128 129 int dirnum = 0; 130 131 private void doTest(final TyVar tyvar, final InsideDef insidedef, 132 final MethodContext ctx, final MethodCall call) 133 throws IOException { 134 final String content = "import java.util.Collection;\n" + 135 "class Test" + tyvar.tyvar + " {\n" + 136 " " + insidedef.instancedef + 137 " " + ctx.methodcontext + "void test(T t) { t." + 138 call.methodcall + "(); }\n" + 139 "}\n" + 140 "class T { void outer() {} }\n"; 141 final File dir = new File(classesdir, "" + dirnum); 142 final File Test_java = writeFile(dir, "Test.java", content); 143 dirnum++; 144 if(call.succeeds(ctx, insidedef, tyvar)) { 145 if(!assert_compile_succeed(Test_java)) 146 System.err.println("Failed file:\n" + content); 147 } 148 else { 149 if(!assert_compile_fail(Test_java)) 150 System.err.println("Failed file:\n" + content); 151 } 152 } 153 154 void run() throws Exception { 155 classesdir.mkdir(); 156 for(TyVar tyvar : TyVar.values()) 157 for(InsideDef insidedef : InsideDef.values()) 158 for(MethodContext ctx : MethodContext.values()) 159 for(MethodCall methodcall : MethodCall.values()) 160 doTest(tyvar, insidedef, ctx, methodcall); 161 if (errors != 0) 162 throw new Exception("ShadowingTest test failed with " + 163 errors + " errors."); 164 } 165 166 boolean assert_compile_fail(final File file) { 167 final String filename = file.getPath(); 168 final String[] args = { filename }; 169 final StringWriter sw = new StringWriter(); 170 final PrintWriter pw = new PrintWriter(sw); 171 final int rc = com.sun.tools.javac.Main.compile(args, pw); 172 pw.close(); 173 if (rc == 0) { 174 System.err.println("Compilation of " + file.getName() + 175 " didn't fail as expected."); 176 errors++; 177 return false; 178 } else return true; 179 } 180 181 boolean assert_compile_succeed(final File file) { 182 final String filename = file.getPath(); 183 final String[] args = { filename }; 184 final StringWriter sw = new StringWriter(); 185 final PrintWriter pw = new PrintWriter(sw); 186 final int rc = com.sun.tools.javac.Main.compile(args, pw); 187 pw.close(); 188 if (rc != 0) { 189 System.err.println("Compilation of " + file.getName() + 190 " didn't succeed as expected. Output:"); 191 System.err.println(sw.toString()); 192 errors++; 193 return false; 194 } else return true; 195 } 196 197 File writeFile(final File dir, 198 final String path, 199 final String body) throws IOException { 200 final File f = new File(dir, path); 201 f.getParentFile().mkdirs(); 202 final FileWriter out = new FileWriter(f); 203 out.write(body); 204 out.close(); 205 return f; 206 } 207 }