1 /*
2  * Copyright (c) 2011, 2015, 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 6993305
27  * @summary starting position of a method without modifiers and with type parameters is incorrect
28  * @modules jdk.compiler/com.sun.tools.javac.api
29  *          jdk.compiler/com.sun.tools.javac.file
30  */
31 
32 import java.io.File;
33 import javax.tools.JavaFileObject;
34 import javax.tools.StandardJavaFileManager;
35 
36 import com.sun.source.tree.CompilationUnitTree;
37 import com.sun.source.tree.MethodTree;
38 import com.sun.source.util.JavacTask;
39 import com.sun.source.util.SourcePositions;
40 import com.sun.source.util.TreeScanner;
41 import com.sun.source.util.Trees;
42 import com.sun.tools.javac.api.JavacTool;
43 import java.io.IOException;
44 
45 /*
46  * Test verifies the starting position of all methods by computing the start position
47  * of each method as the first non-white character on the first line containing
48  * (" " + methodName + "("), and then comparing this value against the reported
49  * value in the SourcePositions table.
50  */
51 public class T6993305 {
test1(T t)52     <T> void test1(T t) { }  // this is the primary case to be tested
test2(T t)53     public <T> void test2(T t) { }
test3(T t)54     @Deprecated <T> void test3(T t) { }
55 
main(String... args)56     public static void main(String... args) throws Exception {
57         new T6993305().run();
58     }
59 
run()60     void run() throws Exception {
61         File testSrc = new File(System.getProperty("test.src"));
62 
63         JavacTool tool = JavacTool.create();
64         try (StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null)) {
65 
66             File f = new File(testSrc, T6993305.class.getSimpleName() + ".java");
67             Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjects(f);
68             JavacTask task = tool.getTask(null, fm, null, null, null, fos);
69             Iterable<? extends CompilationUnitTree> cus = task.parse();
70 
71             TestScanner s = new TestScanner();
72             s.scan(cus, task);
73 
74             if (errors > 0)
75                 throw new Exception(errors + " errors occurred");
76         }
77     }
78 
error(String msg)79     void error(String msg) {
80         System.err.println("Error: " + msg);
81         errors++;
82     }
83 
84     int errors;
85 
86     class TestScanner extends TreeScanner<Void, JavacTask> {
87         CompilationUnitTree cu;
88         SourcePositions sourcePositions;
89         String source;
90 
show(String label, int pos)91         void show(String label, int pos) {
92             System.err.println(label + ": " +
93                     source.substring(pos, Math.min(source.length(), pos + 10)));
94         }
95 
visitCompilationUnit(CompilationUnitTree tree, JavacTask task)96         @Override public Void visitCompilationUnit(CompilationUnitTree tree, JavacTask task) {
97             cu = tree;
98             Trees trees = Trees.instance(task);
99             sourcePositions = trees.getSourcePositions();
100             try {
101                 source = String.valueOf(tree.getSourceFile().getCharContent(true));
102             } catch (IOException e) {
103                 throw new Error(e);
104             }
105             return super.visitCompilationUnit(tree, task);
106         }
107 
108         // this is the core of the test
visitMethod(MethodTree tree, JavacTask task)109         @Override public Void visitMethod(MethodTree tree, JavacTask task) {
110             String name = String.valueOf(tree.getName());
111             int pos = source.indexOf(" " + name + "(");
112             while (source.charAt(pos - 1) != '\n') pos--;
113             while (source.charAt(pos) == ' ') pos++;
114             int expectedStart = pos;
115             int reportedStart = (int) sourcePositions.getStartPosition(cu, tree);
116             System.err.println("Method " + name
117                     + " expectedStart:" + expectedStart
118                     + " reportedStart:" + reportedStart);
119             if (expectedStart != reportedStart) {
120                 error("Unexpected value for " + name);
121                 show("expected", expectedStart);
122                 show("reported", reportedStart);
123             }
124             return super.visitMethod(tree, task);
125         }
126     }
127 }
128