TreeEndPosTest.java revision 3643:589ff4d43428
1/*
2 * Copyright (c) 2013, 2016, 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 8017216 8019422 8019421 8054956
27 * @summary verify start and end positions
28 * @modules java.compiler
29 *          jdk.compiler
30 * @run main TreeEndPosTest
31 */
32
33import java.io.ByteArrayOutputStream;
34import java.io.File;
35import java.io.IOException;
36import java.io.PrintWriter;
37import java.net.URI;
38import java.util.ArrayList;
39import java.util.List;
40import javax.tools.Diagnostic;
41import javax.tools.DiagnosticCollector;
42import javax.tools.JavaCompiler;
43import javax.tools.JavaFileManager;
44import javax.tools.JavaFileObject;
45import javax.tools.SimpleJavaFileObject;
46import javax.tools.ToolProvider;
47
48public class TreeEndPosTest {
49    private static JavaFileManager getJavaFileManager(JavaCompiler compiler,
50            DiagnosticCollector dc) {
51        return compiler.getStandardFileManager(dc, null, null);
52    }
53
54    static class JavaSource extends SimpleJavaFileObject {
55
56        final String source;
57        int startPos;
58        int endPos;
59
60        private JavaSource(String filename, String source) {
61            super(URI.create("myfo:/" + filename), JavaFileObject.Kind.SOURCE);
62            this.source = source;
63        }
64
65        @Override
66        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
67            return source;
68        }
69
70        static JavaSource createJavaSource(String preamble, String body,
71                String postamble, String expected) {
72            JavaSource js = createJavaSource(preamble, body, postamble, -1, -1);
73            js.startPos = js.source.indexOf(expected);
74            js.endPos   = js.startPos + expected.length();
75            return js;
76        }
77
78        static JavaSource createJavaSource(String body, String expected) {
79            return createJavaSource(null, body, null, expected);
80        }
81
82        private static JavaSource createJavaSource(String preamble, String body,
83                String postamble, int start, int end) {
84            final String name = "Bug";
85            StringBuilder code = new StringBuilder();
86            if (preamble != null) {
87                code.append(preamble);
88            }
89            code.append("public class " + name + "{");
90            if (body != null) {
91                code.append(body);
92            }
93            code.append("}");
94            if (postamble != null) {
95                code.append(postamble);
96            }
97            JavaSource js = new JavaSource(name + ".java", code.toString());
98            js.startPos = start;
99            js.endPos = end;
100            return js;
101        }
102    }
103
104    public static void main(String... args) throws IOException {
105        testUninitializedVariable();
106        testMissingAnnotationValue();
107        testUnresolvableAnnotationAttribute();
108        testFinalVariableWithDefaultConstructor();
109        testFinalVariableWithConstructor();
110    }
111
112    static void testUninitializedVariable() throws IOException {
113        compile(JavaSource.createJavaSource("Object o = new A().new B(); class A { }",
114                "B()"));
115    }
116    static void testMissingAnnotationValue() throws IOException {
117        compile(JavaSource.createJavaSource("@Foo(\"vvvv\")",
118                null, "@interface Foo { }", "\"vvvv\""));
119    }
120
121    static void testUnresolvableAnnotationAttribute() throws IOException {
122        compile(JavaSource.createJavaSource("@Foo(value=\"vvvv\")",
123                null, "@interface Foo { }", "value"));
124    }
125
126    static void testFinalVariableWithDefaultConstructor() throws IOException {
127        compile(JavaSource.createJavaSource("private static final String Foo; public void bar() { }",
128                "private static final String Foo;"));
129    }
130
131    static void testFinalVariableWithConstructor() throws IOException {
132        compile(JavaSource.createJavaSource("public Bug (){} private static final String Foo; public void bar() { }",
133                "{}"));
134    }
135
136    static void compile(JavaSource src) throws IOException {
137        ByteArrayOutputStream ba = new ByteArrayOutputStream();
138        PrintWriter writer = new PrintWriter(ba);
139        File tempDir = new File(".");
140        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
141        DiagnosticCollector dc = new DiagnosticCollector();
142        try (JavaFileManager javaFileManager = getJavaFileManager(compiler, dc)) {
143            List<String> options = new ArrayList<>();
144            options.add("-cp");
145            options.add(tempDir.getPath());
146            options.add("-d");
147            options.add(tempDir.getPath());
148            options.add("--should-stop:at=GENERATE");
149
150            List<JavaFileObject> sources = new ArrayList<>();
151            sources.add(src);
152            JavaCompiler.CompilationTask task =
153                    compiler.getTask(writer, javaFileManager,
154                    dc, options, null,
155                    sources);
156            task.call();
157            for (Diagnostic diagnostic : (List<Diagnostic>) dc.getDiagnostics()) {
158                long actualStart = diagnostic.getStartPosition();
159                long actualEnd = diagnostic.getEndPosition();
160                System.out.println("Source: " + src.source);
161                System.out.println("Diagnostic: " + diagnostic);
162                System.out.print("Start position: Expected: " + src.startPos);
163                System.out.println(", Actual: " + actualStart);
164                System.out.print("End position: Expected: " + src.endPos);
165                System.out.println(", Actual: " + actualEnd);
166                if (src.startPos != actualStart || src.endPos != actualEnd) {
167                    throw new RuntimeException("error: trees don't match");
168                }
169            }
170        }
171    }
172}
173