Mon, 24 Nov 2014 12:49:30 -0500
8029012: parameter_index for type annotation not updated after outer.this added
Summary: Fix javac's handling of type annotations when synthetic parameters are added
Reviewed-by: jjg, mcimadamore
vromero@1428 | 1 | |
vromero@1428 | 2 | /* |
vromero@1428 | 3 | * @test /nodynamiccopyright/ |
vromero@1428 | 4 | * @bug 7190862 7109747 |
vromero@1428 | 5 | * @summary javap shows an incorrect type for operands if the 'wide' prefix is used |
vromero@1428 | 6 | */ |
vromero@1428 | 7 | |
vromero@1428 | 8 | import com.sun.source.util.JavacTask; |
vromero@1428 | 9 | import com.sun.tools.javap.JavapFileManager; |
vromero@1428 | 10 | import com.sun.tools.javap.JavapTask; |
vromero@1428 | 11 | import java.io.PrintWriter; |
vromero@1428 | 12 | import java.io.StringWriter; |
vromero@1428 | 13 | import java.net.URI; |
vromero@1428 | 14 | import java.util.Arrays; |
vromero@1428 | 15 | import java.util.List; |
vromero@1428 | 16 | import java.util.Locale; |
vromero@1428 | 17 | import javax.tools.Diagnostic; |
vromero@1428 | 18 | import javax.tools.DiagnosticCollector; |
vromero@1428 | 19 | import javax.tools.JavaCompiler; |
vromero@1428 | 20 | import javax.tools.JavaFileManager; |
vromero@1428 | 21 | import javax.tools.JavaFileObject; |
vromero@1428 | 22 | import javax.tools.SimpleJavaFileObject; |
vromero@1428 | 23 | import javax.tools.ToolProvider; |
vromero@1428 | 24 | |
vromero@1428 | 25 | public class T7190862 { |
vromero@1428 | 26 | |
vromero@1428 | 27 | enum TypeWideInstructionMap { |
vromero@1428 | 28 | INT("int", new String[]{"istore_w", "iload_w"}), |
vromero@1428 | 29 | LONG("long", new String[]{"lstore_w", "lload_w"}), |
vromero@1428 | 30 | FLOAT("float", new String[]{"fstore_w", "fload_w"}), |
vromero@1428 | 31 | DOUBLE("double", new String[]{"dstore_w", "dload_w"}), |
vromero@1428 | 32 | OBJECT("Object", new String[]{"astore_w", "aload_w"}); |
vromero@1428 | 33 | |
vromero@1428 | 34 | String type; |
vromero@1428 | 35 | String[] instructions; |
vromero@1428 | 36 | |
vromero@1428 | 37 | TypeWideInstructionMap(String type, String[] instructions) { |
vromero@1428 | 38 | this.type = type; |
vromero@1428 | 39 | this.instructions = instructions; |
vromero@1428 | 40 | } |
vromero@1428 | 41 | } |
vromero@1428 | 42 | |
vromero@1428 | 43 | JavaSource source; |
vromero@1428 | 44 | |
vromero@1428 | 45 | public static void main(String[] args) { |
vromero@1428 | 46 | JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); |
vromero@1428 | 47 | new T7190862().run(comp); |
vromero@1428 | 48 | } |
vromero@1428 | 49 | |
vromero@1428 | 50 | private void run(JavaCompiler comp) { |
vromero@1428 | 51 | String code; |
vromero@1428 | 52 | for (TypeWideInstructionMap typeInstructionMap: TypeWideInstructionMap.values()) { |
vromero@1428 | 53 | if (typeInstructionMap != TypeWideInstructionMap.OBJECT) { |
vromero@1428 | 54 | code = createWideLocalSource(typeInstructionMap.type, 300); |
vromero@1428 | 55 | } else { |
vromero@1428 | 56 | code = createWideLocalSourceForObject(300); |
vromero@1428 | 57 | } |
vromero@1428 | 58 | source = new JavaSource(code); |
vromero@1428 | 59 | compile(comp); |
vromero@1428 | 60 | check(typeInstructionMap.instructions); |
vromero@1428 | 61 | } |
vromero@1428 | 62 | |
vromero@1428 | 63 | //an extra test for the iinc instruction |
vromero@1428 | 64 | code = createIincSource(); |
vromero@1428 | 65 | source = new JavaSource(code); |
vromero@1428 | 66 | compile(comp); |
vromero@1428 | 67 | check(new String[]{"iinc_w"}); |
vromero@1428 | 68 | } |
vromero@1428 | 69 | |
vromero@1428 | 70 | private void compile(JavaCompiler comp) { |
vromero@1428 | 71 | JavacTask ct = (JavacTask)comp.getTask(null, null, null, null, null, Arrays.asList(source)); |
vromero@1428 | 72 | try { |
vromero@1428 | 73 | if (!ct.call()) { |
vromero@1428 | 74 | throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true)); |
vromero@1428 | 75 | } |
vromero@1428 | 76 | } catch (Throwable ex) { |
vromero@1428 | 77 | throw new AssertionError("Error thrown when compiling the following source:\n" + source.getCharContent(true)); |
vromero@1428 | 78 | } |
vromero@1428 | 79 | } |
vromero@1428 | 80 | |
vromero@1428 | 81 | private void check(String[] instructions) { |
vromero@1428 | 82 | String out = javap(Arrays.asList("-c"), Arrays.asList("Test.class")); |
vromero@1428 | 83 | for (String line: out.split(System.getProperty("line.separator"))) { |
vromero@1428 | 84 | line = line.trim(); |
vromero@1428 | 85 | for (String instruction: instructions) { |
vromero@1428 | 86 | if (line.contains(instruction) && line.contains("#")) { |
vromero@1428 | 87 | throw new Error("incorrect type for operands for instruction " + instruction); |
vromero@1428 | 88 | } |
vromero@1428 | 89 | } |
vromero@1428 | 90 | } |
vromero@1428 | 91 | } |
vromero@1428 | 92 | |
vromero@1428 | 93 | private String javap(List<String> args, List<String> classes) { |
vromero@1428 | 94 | DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<JavaFileObject>(); |
vromero@1428 | 95 | StringWriter sw = new StringWriter(); |
vromero@1428 | 96 | PrintWriter pw = new PrintWriter(sw); |
vromero@1428 | 97 | JavaFileManager fm = JavapFileManager.create(dc, pw); |
vromero@1428 | 98 | JavapTask t = new JavapTask(pw, fm, dc, args, classes); |
vromero@1819 | 99 | if (t.run() != 0) |
vromero@1428 | 100 | throw new Error("javap failed unexpectedly"); |
vromero@1428 | 101 | |
vromero@1428 | 102 | List<Diagnostic<? extends JavaFileObject>> diags = dc.getDiagnostics(); |
vromero@1428 | 103 | for (Diagnostic<? extends JavaFileObject> d: diags) { |
vromero@1428 | 104 | if (d.getKind() == Diagnostic.Kind.ERROR) |
vromero@1428 | 105 | throw new Error(d.getMessage(Locale.ENGLISH)); |
vromero@1428 | 106 | } |
vromero@1428 | 107 | return sw.toString(); |
vromero@1428 | 108 | |
vromero@1428 | 109 | } |
vromero@1428 | 110 | |
vromero@1428 | 111 | private String createWideLocalSource(String type, int numberOfVars) { |
vromero@1428 | 112 | String result = " " + type + " x0 = 0;\n"; |
vromero@1428 | 113 | for (int i = 1; i < numberOfVars; i++) { |
vromero@1428 | 114 | result += " " + type + " x" + i + " = x" + (i - 1) + " + 1;\n"; |
vromero@1428 | 115 | } |
vromero@1428 | 116 | return result; |
vromero@1428 | 117 | } |
vromero@1428 | 118 | |
vromero@1428 | 119 | private String createWideLocalSourceForObject(int numberOfVars) { |
vromero@1428 | 120 | String result = " Object x0 = new Object();\n"; |
vromero@1428 | 121 | for (int i = 1; i < numberOfVars; i++) { |
vromero@1428 | 122 | result += " Object x" + i + " = x0;\n"; |
vromero@1428 | 123 | } |
vromero@1428 | 124 | return result; |
vromero@1428 | 125 | } |
vromero@1428 | 126 | |
vromero@1428 | 127 | private String createIincSource() { |
vromero@1428 | 128 | return " int i = 0;\n" |
vromero@1428 | 129 | + " i += 1;\n" |
vromero@1428 | 130 | + " i += 51;\n" |
vromero@1428 | 131 | + " i += 101;\n" |
vromero@1428 | 132 | + " i += 151;\n"; |
vromero@1428 | 133 | } |
vromero@1428 | 134 | |
vromero@1428 | 135 | class JavaSource extends SimpleJavaFileObject { |
vromero@1428 | 136 | |
vromero@1428 | 137 | String template = "class Test {\n" + |
vromero@1428 | 138 | " public static void main(String[] args)\n" + |
vromero@1428 | 139 | " {\n" + |
vromero@1428 | 140 | " #C" + |
vromero@1428 | 141 | " }\n" + |
vromero@1428 | 142 | "}"; |
vromero@1428 | 143 | |
vromero@1428 | 144 | String source; |
vromero@1428 | 145 | |
vromero@1428 | 146 | public JavaSource(String code) { |
vromero@1428 | 147 | super(URI.create("Test.java"), JavaFileObject.Kind.SOURCE); |
vromero@1428 | 148 | source = template.replaceAll("#C", code); |
vromero@1428 | 149 | } |
vromero@1428 | 150 | |
vromero@1428 | 151 | @Override |
vromero@1428 | 152 | public CharSequence getCharContent(boolean ignoreEncodingErrors) { |
vromero@1428 | 153 | return source; |
vromero@1428 | 154 | } |
vromero@1428 | 155 | } |
vromero@1428 | 156 | } |