Mon, 14 Nov 2011 15:11:10 -0800
7106166: (javac) re-factor EndPos parser
Reviewed-by: jjg
ksrini@1074 | 1 | /* |
ksrini@1074 | 2 | * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
ksrini@1074 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
ksrini@1074 | 4 | * |
ksrini@1074 | 5 | * This code is free software; you can redistribute it and/or modify it |
ksrini@1074 | 6 | * under the terms of the GNU General Public License version 2 only, as |
ksrini@1074 | 7 | * published by the Free Software Foundation. |
ksrini@1074 | 8 | * |
ksrini@1074 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
ksrini@1074 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
ksrini@1074 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
ksrini@1074 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
ksrini@1074 | 13 | * accompanied this code). |
ksrini@1074 | 14 | * |
ksrini@1074 | 15 | * You should have received a copy of the GNU General Public License version |
ksrini@1074 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
ksrini@1074 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
ksrini@1074 | 18 | * |
ksrini@1074 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
ksrini@1074 | 20 | * or visit www.oracle.com if you need additional information or have any |
ksrini@1074 | 21 | * questions. |
ksrini@1074 | 22 | */ |
ksrini@1074 | 23 | |
ksrini@1074 | 24 | /* |
ksrini@1074 | 25 | * @test |
ksrini@1074 | 26 | * @bug 7073631 |
ksrini@1074 | 27 | * @summary tests error and diagnostics positions |
ksrini@1074 | 28 | * @author jan.lahoda@oracle.com |
ksrini@1074 | 29 | */ |
ksrini@1074 | 30 | |
ksrini@1074 | 31 | import com.sun.source.tree.BinaryTree; |
ksrini@1074 | 32 | import com.sun.source.tree.BlockTree; |
ksrini@1074 | 33 | import com.sun.source.tree.ClassTree; |
ksrini@1074 | 34 | import com.sun.source.tree.CompilationUnitTree; |
ksrini@1074 | 35 | import com.sun.source.tree.ExpressionStatementTree; |
ksrini@1074 | 36 | import com.sun.source.tree.ExpressionTree; |
ksrini@1074 | 37 | import com.sun.source.tree.MethodInvocationTree; |
ksrini@1074 | 38 | import com.sun.source.tree.MethodTree; |
ksrini@1074 | 39 | import com.sun.source.tree.ModifiersTree; |
ksrini@1074 | 40 | import com.sun.source.tree.StatementTree; |
ksrini@1074 | 41 | import com.sun.source.tree.Tree; |
ksrini@1074 | 42 | import com.sun.source.tree.Tree.Kind; |
ksrini@1074 | 43 | import com.sun.source.tree.VariableTree; |
ksrini@1074 | 44 | import com.sun.source.tree.WhileLoopTree; |
ksrini@1074 | 45 | import com.sun.source.util.SourcePositions; |
ksrini@1074 | 46 | import com.sun.source.util.TreeScanner; |
ksrini@1074 | 47 | import com.sun.source.util.Trees; |
ksrini@1074 | 48 | import com.sun.tools.javac.api.JavacTaskImpl; |
ksrini@1074 | 49 | import com.sun.tools.javac.tree.JCTree; |
ksrini@1074 | 50 | import java.io.IOException; |
ksrini@1074 | 51 | import java.net.URI; |
ksrini@1074 | 52 | import java.util.Arrays; |
ksrini@1074 | 53 | import java.util.LinkedList; |
ksrini@1074 | 54 | import java.util.List; |
ksrini@1074 | 55 | import javax.tools.Diagnostic; |
ksrini@1074 | 56 | import javax.tools.DiagnosticCollector; |
ksrini@1074 | 57 | import javax.tools.DiagnosticListener; |
ksrini@1074 | 58 | import javax.tools.JavaCompiler; |
ksrini@1074 | 59 | import javax.tools.JavaFileObject; |
ksrini@1074 | 60 | import javax.tools.SimpleJavaFileObject; |
ksrini@1074 | 61 | import javax.tools.ToolProvider; |
ksrini@1074 | 62 | |
ksrini@1074 | 63 | public class JavacParserTest extends TestCase { |
ksrini@1074 | 64 | final JavaCompiler tool; |
ksrini@1074 | 65 | public JavacParserTest(String testName) { |
ksrini@1074 | 66 | tool = ToolProvider.getSystemJavaCompiler(); |
ksrini@1074 | 67 | System.out.println("java.home=" + System.getProperty("java.home")); |
ksrini@1074 | 68 | } |
ksrini@1074 | 69 | |
ksrini@1074 | 70 | static class MyFileObject extends SimpleJavaFileObject { |
ksrini@1074 | 71 | |
ksrini@1074 | 72 | private String text; |
ksrini@1074 | 73 | |
ksrini@1074 | 74 | public MyFileObject(String text) { |
ksrini@1074 | 75 | super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); |
ksrini@1074 | 76 | this.text = text; |
ksrini@1074 | 77 | } |
ksrini@1074 | 78 | |
ksrini@1074 | 79 | @Override |
ksrini@1074 | 80 | public CharSequence getCharContent(boolean ignoreEncodingErrors) { |
ksrini@1074 | 81 | return text; |
ksrini@1074 | 82 | } |
ksrini@1074 | 83 | } |
ksrini@1074 | 84 | |
ksrini@1074 | 85 | public void testPositionForSuperConstructorCalls() throws IOException { |
ksrini@1074 | 86 | assert tool != null; |
ksrini@1074 | 87 | |
ksrini@1074 | 88 | String code = "package test; public class Test {public Test() {super();}}"; |
ksrini@1074 | 89 | |
ksrini@1074 | 90 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 91 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 92 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 93 | SourcePositions pos = Trees.instance(ct).getSourcePositions(); |
ksrini@1074 | 94 | |
ksrini@1074 | 95 | MethodTree method = |
ksrini@1074 | 96 | (MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); |
ksrini@1074 | 97 | ExpressionStatementTree es = |
ksrini@1074 | 98 | (ExpressionStatementTree) method.getBody().getStatements().get(0); |
ksrini@1074 | 99 | |
ksrini@1074 | 100 | assertEquals("testPositionForSuperConstructorCalls", |
ksrini@1074 | 101 | 72 - 24, pos.getStartPosition(cut, es)); |
ksrini@1074 | 102 | assertEquals("testPositionForSuperConstructorCalls", |
ksrini@1074 | 103 | 80 - 24, pos.getEndPosition(cut, es)); |
ksrini@1074 | 104 | |
ksrini@1074 | 105 | MethodInvocationTree mit = (MethodInvocationTree) es.getExpression(); |
ksrini@1074 | 106 | |
ksrini@1074 | 107 | assertEquals("testPositionForSuperConstructorCalls", |
ksrini@1074 | 108 | 72 - 24, pos.getStartPosition(cut, mit)); |
ksrini@1074 | 109 | assertEquals("testPositionForSuperConstructorCalls", |
ksrini@1074 | 110 | 79 - 24, pos.getEndPosition(cut, mit)); |
ksrini@1074 | 111 | |
ksrini@1074 | 112 | assertEquals("testPositionForSuperConstructorCalls", |
ksrini@1074 | 113 | 72 - 24, pos.getStartPosition(cut, mit.getMethodSelect())); |
ksrini@1074 | 114 | assertEquals("testPositionForSuperConstructorCalls", |
ksrini@1074 | 115 | 77 - 24, pos.getEndPosition(cut, mit.getMethodSelect())); |
ksrini@1074 | 116 | |
ksrini@1074 | 117 | } |
ksrini@1074 | 118 | |
ksrini@1074 | 119 | public void testPositionForEnumModifiers() throws IOException { |
ksrini@1074 | 120 | |
ksrini@1074 | 121 | String code = "package test; public enum Test {A;}"; |
ksrini@1074 | 122 | |
ksrini@1074 | 123 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 124 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 125 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 126 | SourcePositions pos = Trees.instance(ct).getSourcePositions(); |
ksrini@1074 | 127 | |
ksrini@1074 | 128 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 129 | ModifiersTree mt = clazz.getModifiers(); |
ksrini@1074 | 130 | |
ksrini@1074 | 131 | assertEquals("testPositionForEnumModifiers", |
ksrini@1074 | 132 | 38 - 24, pos.getStartPosition(cut, mt)); |
ksrini@1074 | 133 | assertEquals("testPositionForEnumModifiers", |
ksrini@1074 | 134 | 44 - 24, pos.getEndPosition(cut, mt)); |
ksrini@1074 | 135 | } |
ksrini@1074 | 136 | |
ksrini@1074 | 137 | public void testNewClassWithEnclosing() throws IOException { |
ksrini@1074 | 138 | |
ksrini@1074 | 139 | |
ksrini@1074 | 140 | String code = "package test; class Test { " + |
ksrini@1074 | 141 | "class d {} private void method() { " + |
ksrini@1074 | 142 | "Object o = Test.this.new d(); } }"; |
ksrini@1074 | 143 | |
ksrini@1074 | 144 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 145 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 146 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 147 | SourcePositions pos = Trees.instance(ct).getSourcePositions(); |
ksrini@1074 | 148 | |
ksrini@1074 | 149 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 150 | ExpressionTree est = |
ksrini@1074 | 151 | ((VariableTree) ((MethodTree) clazz.getMembers().get(1)).getBody().getStatements().get(0)).getInitializer(); |
ksrini@1074 | 152 | |
ksrini@1074 | 153 | assertEquals("testNewClassWithEnclosing", |
ksrini@1074 | 154 | 97 - 24, pos.getStartPosition(cut, est)); |
ksrini@1074 | 155 | assertEquals("testNewClassWithEnclosing", |
ksrini@1074 | 156 | 114 - 24, pos.getEndPosition(cut, est)); |
ksrini@1074 | 157 | } |
ksrini@1074 | 158 | |
ksrini@1074 | 159 | public void testPreferredPositionForBinaryOp() throws IOException { |
ksrini@1074 | 160 | |
ksrini@1074 | 161 | String code = "package test; public class Test {" + |
ksrini@1074 | 162 | "private void test() {" + |
ksrini@1074 | 163 | "Object o = null; boolean b = o != null && o instanceof String;" + |
ksrini@1074 | 164 | "} private Test() {}}"; |
ksrini@1074 | 165 | |
ksrini@1074 | 166 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 167 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 168 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 169 | |
ksrini@1074 | 170 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 171 | MethodTree method = (MethodTree) clazz.getMembers().get(0); |
ksrini@1074 | 172 | VariableTree condSt = (VariableTree) method.getBody().getStatements().get(1); |
ksrini@1074 | 173 | BinaryTree cond = (BinaryTree) condSt.getInitializer(); |
ksrini@1074 | 174 | |
ksrini@1074 | 175 | JCTree condJC = (JCTree) cond; |
ksrini@1074 | 176 | |
ksrini@1074 | 177 | assertEquals("testNewClassWithEnclosing", |
ksrini@1074 | 178 | 117 - 24, condJC.pos); |
ksrini@1074 | 179 | } |
ksrini@1074 | 180 | |
ksrini@1074 | 181 | public void testPositionBrokenSource126732a() throws IOException { |
ksrini@1074 | 182 | String[] commands = new String[]{ |
ksrini@1074 | 183 | "return Runnable()", |
ksrini@1074 | 184 | "do { } while (true)", |
ksrini@1074 | 185 | "throw UnsupportedOperationException()", |
ksrini@1074 | 186 | "assert true", |
ksrini@1074 | 187 | "1 + 1",}; |
ksrini@1074 | 188 | |
ksrini@1074 | 189 | for (String command : commands) { |
ksrini@1074 | 190 | |
ksrini@1074 | 191 | String code = "package test;\n" |
ksrini@1074 | 192 | + "public class Test {\n" |
ksrini@1074 | 193 | + " public static void test() {\n" |
ksrini@1074 | 194 | + " " + command + " {\n" |
ksrini@1074 | 195 | + " new Runnable() {\n" |
ksrini@1074 | 196 | + " };\n" |
ksrini@1074 | 197 | + " }\n" |
ksrini@1074 | 198 | + "}"; |
ksrini@1074 | 199 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, |
ksrini@1074 | 200 | null, null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 201 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 202 | |
ksrini@1074 | 203 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 204 | MethodTree method = (MethodTree) clazz.getMembers().get(0); |
ksrini@1074 | 205 | List<? extends StatementTree> statements = |
ksrini@1074 | 206 | method.getBody().getStatements(); |
ksrini@1074 | 207 | |
ksrini@1074 | 208 | StatementTree ret = statements.get(0); |
ksrini@1074 | 209 | StatementTree block = statements.get(1); |
ksrini@1074 | 210 | |
ksrini@1074 | 211 | Trees t = Trees.instance(ct); |
ksrini@1074 | 212 | int len = code.indexOf(command + " {") + (command + " ").length(); |
ksrini@1074 | 213 | assertEquals(command, len, |
ksrini@1074 | 214 | t.getSourcePositions().getEndPosition(cut, ret)); |
ksrini@1074 | 215 | assertEquals(command, len, |
ksrini@1074 | 216 | t.getSourcePositions().getStartPosition(cut, block)); |
ksrini@1074 | 217 | } |
ksrini@1074 | 218 | } |
ksrini@1074 | 219 | |
ksrini@1074 | 220 | public void testPositionBrokenSource126732b() throws IOException { |
ksrini@1074 | 221 | String[] commands = new String[]{ |
ksrini@1074 | 222 | "break", |
ksrini@1074 | 223 | "break A", |
ksrini@1074 | 224 | "continue ", |
ksrini@1074 | 225 | "continue A",}; |
ksrini@1074 | 226 | |
ksrini@1074 | 227 | for (String command : commands) { |
ksrini@1074 | 228 | |
ksrini@1074 | 229 | String code = "package test;\n" |
ksrini@1074 | 230 | + "public class Test {\n" |
ksrini@1074 | 231 | + " public static void test() {\n" |
ksrini@1074 | 232 | + " while (true) {\n" |
ksrini@1074 | 233 | + " " + command + " {\n" |
ksrini@1074 | 234 | + " new Runnable() {\n" |
ksrini@1074 | 235 | + " };\n" |
ksrini@1074 | 236 | + " }\n" |
ksrini@1074 | 237 | + " }\n" |
ksrini@1074 | 238 | + "}"; |
ksrini@1074 | 239 | |
ksrini@1074 | 240 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, |
ksrini@1074 | 241 | null, null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 242 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 243 | |
ksrini@1074 | 244 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 245 | MethodTree method = (MethodTree) clazz.getMembers().get(0); |
ksrini@1074 | 246 | List<? extends StatementTree> statements = |
ksrini@1074 | 247 | ((BlockTree) ((WhileLoopTree) method.getBody().getStatements().get(0)).getStatement()).getStatements(); |
ksrini@1074 | 248 | |
ksrini@1074 | 249 | StatementTree ret = statements.get(0); |
ksrini@1074 | 250 | StatementTree block = statements.get(1); |
ksrini@1074 | 251 | |
ksrini@1074 | 252 | Trees t = Trees.instance(ct); |
ksrini@1074 | 253 | int len = code.indexOf(command + " {") + (command + " ").length(); |
ksrini@1074 | 254 | assertEquals(command, len, |
ksrini@1074 | 255 | t.getSourcePositions().getEndPosition(cut, ret)); |
ksrini@1074 | 256 | assertEquals(command, len, |
ksrini@1074 | 257 | t.getSourcePositions().getStartPosition(cut, block)); |
ksrini@1074 | 258 | } |
ksrini@1074 | 259 | } |
ksrini@1074 | 260 | |
ksrini@1074 | 261 | public void testErrorRecoveryForEnhancedForLoop142381() throws IOException { |
ksrini@1074 | 262 | |
ksrini@1074 | 263 | String code = "package test; class Test { " + |
ksrini@1074 | 264 | "private void method() { " + |
ksrini@1074 | 265 | "java.util.Set<String> s = null; for (a : s) {} } }"; |
ksrini@1074 | 266 | |
ksrini@1074 | 267 | final List<Diagnostic<? extends JavaFileObject>> errors = |
ksrini@1074 | 268 | new LinkedList<Diagnostic<? extends JavaFileObject>>(); |
ksrini@1074 | 269 | |
ksrini@1074 | 270 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, |
ksrini@1074 | 271 | new DiagnosticListener<JavaFileObject>() { |
ksrini@1074 | 272 | public void report(Diagnostic<? extends JavaFileObject> diagnostic) { |
ksrini@1074 | 273 | errors.add(diagnostic); |
ksrini@1074 | 274 | } |
ksrini@1074 | 275 | }, null, null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 276 | |
ksrini@1074 | 277 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 278 | |
ksrini@1074 | 279 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 280 | StatementTree forStatement = |
ksrini@1074 | 281 | ((MethodTree) clazz.getMembers().get(0)).getBody().getStatements().get(1); |
ksrini@1074 | 282 | |
ksrini@1074 | 283 | assertEquals("testErrorRecoveryForEnhancedForLoop142381", |
ksrini@1074 | 284 | Kind.ENHANCED_FOR_LOOP, forStatement.getKind()); |
ksrini@1074 | 285 | assertFalse("testErrorRecoveryForEnhancedForLoop142381", errors.isEmpty()); |
ksrini@1074 | 286 | } |
ksrini@1074 | 287 | |
ksrini@1074 | 288 | public void testPositionAnnotationNoPackage187551() throws IOException { |
ksrini@1074 | 289 | |
ksrini@1074 | 290 | String code = "\n@interface Test {}"; |
ksrini@1074 | 291 | |
ksrini@1074 | 292 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 293 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 294 | |
ksrini@1074 | 295 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 296 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 297 | Trees t = Trees.instance(ct); |
ksrini@1074 | 298 | |
ksrini@1074 | 299 | assertEquals("testPositionAnnotationNoPackage187551", |
ksrini@1074 | 300 | 1, t.getSourcePositions().getStartPosition(cut, clazz)); |
ksrini@1074 | 301 | } |
ksrini@1074 | 302 | |
ksrini@1074 | 303 | public void testPositionsSane() throws IOException { |
ksrini@1074 | 304 | performPositionsSanityTest("package test; class Test { " + |
ksrini@1074 | 305 | "private void method() { " + |
ksrini@1074 | 306 | "java.util.List<? extends java.util.List<? extends String>> l; " + |
ksrini@1074 | 307 | "} }"); |
ksrini@1074 | 308 | performPositionsSanityTest("package test; class Test { " + |
ksrini@1074 | 309 | "private void method() { " + |
ksrini@1074 | 310 | "java.util.List<? super java.util.List<? super String>> l; " + |
ksrini@1074 | 311 | "} }"); |
ksrini@1074 | 312 | performPositionsSanityTest("package test; class Test { " + |
ksrini@1074 | 313 | "private void method() { " + |
ksrini@1074 | 314 | "java.util.List<? super java.util.List<?>> l; } }"); |
ksrini@1074 | 315 | } |
ksrini@1074 | 316 | |
ksrini@1074 | 317 | private void performPositionsSanityTest(String code) throws IOException { |
ksrini@1074 | 318 | |
ksrini@1074 | 319 | final List<Diagnostic<? extends JavaFileObject>> errors = |
ksrini@1074 | 320 | new LinkedList<Diagnostic<? extends JavaFileObject>>(); |
ksrini@1074 | 321 | |
ksrini@1074 | 322 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, |
ksrini@1074 | 323 | new DiagnosticListener<JavaFileObject>() { |
ksrini@1074 | 324 | |
ksrini@1074 | 325 | public void report(Diagnostic<? extends JavaFileObject> diagnostic) { |
ksrini@1074 | 326 | errors.add(diagnostic); |
ksrini@1074 | 327 | } |
ksrini@1074 | 328 | }, null, null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 329 | |
ksrini@1074 | 330 | final CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 331 | final Trees trees = Trees.instance(ct); |
ksrini@1074 | 332 | |
ksrini@1074 | 333 | new TreeScanner<Void, Void>() { |
ksrini@1074 | 334 | |
ksrini@1074 | 335 | private long parentStart = 0; |
ksrini@1074 | 336 | private long parentEnd = Integer.MAX_VALUE; |
ksrini@1074 | 337 | |
ksrini@1074 | 338 | @Override |
ksrini@1074 | 339 | public Void scan(Tree node, Void p) { |
ksrini@1074 | 340 | if (node == null) { |
ksrini@1074 | 341 | return null; |
ksrini@1074 | 342 | } |
ksrini@1074 | 343 | |
ksrini@1074 | 344 | long start = trees.getSourcePositions().getStartPosition(cut, node); |
ksrini@1074 | 345 | |
ksrini@1074 | 346 | if (start == (-1)) { |
ksrini@1074 | 347 | return null; //synthetic tree |
ksrini@1074 | 348 | } |
ksrini@1074 | 349 | assertTrue(node.toString() + ":" + start + "/" + parentStart, |
ksrini@1074 | 350 | parentStart <= start); |
ksrini@1074 | 351 | |
ksrini@1074 | 352 | long prevParentStart = parentStart; |
ksrini@1074 | 353 | |
ksrini@1074 | 354 | parentStart = start; |
ksrini@1074 | 355 | |
ksrini@1074 | 356 | long end = trees.getSourcePositions().getEndPosition(cut, node); |
ksrini@1074 | 357 | |
ksrini@1074 | 358 | assertTrue(node.toString() + ":" + end + "/" + parentEnd, |
ksrini@1074 | 359 | end <= parentEnd); |
ksrini@1074 | 360 | |
ksrini@1074 | 361 | long prevParentEnd = parentEnd; |
ksrini@1074 | 362 | |
ksrini@1074 | 363 | parentEnd = end; |
ksrini@1074 | 364 | |
ksrini@1074 | 365 | super.scan(node, p); |
ksrini@1074 | 366 | |
ksrini@1074 | 367 | parentStart = prevParentStart; |
ksrini@1074 | 368 | parentEnd = prevParentEnd; |
ksrini@1074 | 369 | |
ksrini@1074 | 370 | return null; |
ksrini@1074 | 371 | } |
ksrini@1074 | 372 | |
ksrini@1074 | 373 | private void assertTrue(String message, boolean b) { |
ksrini@1074 | 374 | if (!b) fail(message); |
ksrini@1074 | 375 | } |
ksrini@1074 | 376 | }.scan(cut, null); |
ksrini@1074 | 377 | } |
ksrini@1074 | 378 | |
ksrini@1074 | 379 | public void testCorrectWilcardPositions() throws IOException { |
ksrini@1074 | 380 | performWildcardPositionsTest("package test; import java.util.List; " + |
ksrini@1074 | 381 | "class Test { private void method() { List<? extends List<? extends String>> l; } }", |
ksrini@1074 | 382 | |
ksrini@1074 | 383 | Arrays.asList("List<? extends List<? extends String>> l;", |
ksrini@1074 | 384 | "List<? extends List<? extends String>>", |
ksrini@1074 | 385 | "List", |
ksrini@1074 | 386 | "? extends List<? extends String>", |
ksrini@1074 | 387 | "List<? extends String>", |
ksrini@1074 | 388 | "List", |
ksrini@1074 | 389 | "? extends String", |
ksrini@1074 | 390 | "String")); |
ksrini@1074 | 391 | performWildcardPositionsTest("package test; import java.util.List; " + |
ksrini@1074 | 392 | "class Test { private void method() { List<? super List<? super String>> l; } }", |
ksrini@1074 | 393 | |
ksrini@1074 | 394 | Arrays.asList("List<? super List<? super String>> l;", |
ksrini@1074 | 395 | "List<? super List<? super String>>", |
ksrini@1074 | 396 | "List", |
ksrini@1074 | 397 | "? super List<? super String>", |
ksrini@1074 | 398 | "List<? super String>", |
ksrini@1074 | 399 | "List", |
ksrini@1074 | 400 | "? super String", |
ksrini@1074 | 401 | "String")); |
ksrini@1074 | 402 | performWildcardPositionsTest("package test; import java.util.List; " + |
ksrini@1074 | 403 | "class Test { private void method() { List<? super List<?>> l; } }", |
ksrini@1074 | 404 | |
ksrini@1074 | 405 | Arrays.asList("List<? super List<?>> l;", |
ksrini@1074 | 406 | "List<? super List<?>>", |
ksrini@1074 | 407 | "List", |
ksrini@1074 | 408 | "? super List<?>", |
ksrini@1074 | 409 | "List<?>", |
ksrini@1074 | 410 | "List", |
ksrini@1074 | 411 | "?")); |
ksrini@1074 | 412 | performWildcardPositionsTest("package test; import java.util.List; " + |
ksrini@1074 | 413 | "class Test { private void method() { " + |
ksrini@1074 | 414 | "List<? extends List<? extends List<? extends String>>> l; } }", |
ksrini@1074 | 415 | |
ksrini@1074 | 416 | Arrays.asList("List<? extends List<? extends List<? extends String>>> l;", |
ksrini@1074 | 417 | "List<? extends List<? extends List<? extends String>>>", |
ksrini@1074 | 418 | "List", |
ksrini@1074 | 419 | "? extends List<? extends List<? extends String>>", |
ksrini@1074 | 420 | "List<? extends List<? extends String>>", |
ksrini@1074 | 421 | "List", |
ksrini@1074 | 422 | "? extends List<? extends String>", |
ksrini@1074 | 423 | "List<? extends String>", |
ksrini@1074 | 424 | "List", |
ksrini@1074 | 425 | "? extends String", |
ksrini@1074 | 426 | "String")); |
ksrini@1074 | 427 | performWildcardPositionsTest("package test; import java.util.List; " + |
ksrini@1074 | 428 | "class Test { private void method() { " + |
ksrini@1074 | 429 | "List<? extends List<? extends List<? extends String >>> l; } }", |
ksrini@1074 | 430 | Arrays.asList("List<? extends List<? extends List<? extends String >>> l;", |
ksrini@1074 | 431 | "List<? extends List<? extends List<? extends String >>>", |
ksrini@1074 | 432 | "List", |
ksrini@1074 | 433 | "? extends List<? extends List<? extends String >>", |
ksrini@1074 | 434 | "List<? extends List<? extends String >>", |
ksrini@1074 | 435 | "List", |
ksrini@1074 | 436 | "? extends List<? extends String >", |
ksrini@1074 | 437 | "List<? extends String >", |
ksrini@1074 | 438 | "List", |
ksrini@1074 | 439 | "? extends String", |
ksrini@1074 | 440 | "String")); |
ksrini@1074 | 441 | } |
ksrini@1074 | 442 | |
ksrini@1074 | 443 | public void performWildcardPositionsTest(final String code, |
ksrini@1074 | 444 | List<String> golden) throws IOException { |
ksrini@1074 | 445 | |
ksrini@1074 | 446 | final List<Diagnostic<? extends JavaFileObject>> errors = |
ksrini@1074 | 447 | new LinkedList<Diagnostic<? extends JavaFileObject>>(); |
ksrini@1074 | 448 | |
ksrini@1074 | 449 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, |
ksrini@1074 | 450 | new DiagnosticListener<JavaFileObject>() { |
ksrini@1074 | 451 | public void report(Diagnostic<? extends JavaFileObject> diagnostic) { |
ksrini@1074 | 452 | errors.add(diagnostic); |
ksrini@1074 | 453 | } |
ksrini@1074 | 454 | }, null, null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 455 | |
ksrini@1074 | 456 | final CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 457 | final List<String> content = new LinkedList<String>(); |
ksrini@1074 | 458 | final Trees trees = Trees.instance(ct); |
ksrini@1074 | 459 | |
ksrini@1074 | 460 | new TreeScanner<Void, Void>() { |
ksrini@1074 | 461 | @Override |
ksrini@1074 | 462 | public Void scan(Tree node, Void p) { |
ksrini@1074 | 463 | if (node == null) { |
ksrini@1074 | 464 | return null; |
ksrini@1074 | 465 | } |
ksrini@1074 | 466 | long start = trees.getSourcePositions().getStartPosition(cut, node); |
ksrini@1074 | 467 | |
ksrini@1074 | 468 | if (start == (-1)) { |
ksrini@1074 | 469 | return null; //synthetic tree |
ksrini@1074 | 470 | } |
ksrini@1074 | 471 | long end = trees.getSourcePositions().getEndPosition(cut, node); |
ksrini@1074 | 472 | String s = code.substring((int) start, (int) end); |
ksrini@1074 | 473 | content.add(s); |
ksrini@1074 | 474 | |
ksrini@1074 | 475 | return super.scan(node, p); |
ksrini@1074 | 476 | } |
ksrini@1074 | 477 | }.scan(((MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0)).getBody().getStatements().get(0), null); |
ksrini@1074 | 478 | |
ksrini@1074 | 479 | assertEquals("performWildcardPositionsTest",golden.toString(), |
ksrini@1074 | 480 | content.toString()); |
ksrini@1074 | 481 | } |
ksrini@1074 | 482 | |
ksrini@1074 | 483 | public void testStartPositionForMethodWithoutModifiers() throws IOException { |
ksrini@1074 | 484 | |
ksrini@1074 | 485 | String code = "package t; class Test { <T> void t() {} }"; |
ksrini@1074 | 486 | |
ksrini@1074 | 487 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 488 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 489 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 490 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 491 | MethodTree mt = (MethodTree) clazz.getMembers().get(0); |
ksrini@1074 | 492 | Trees t = Trees.instance(ct); |
ksrini@1074 | 493 | int start = (int) t.getSourcePositions().getStartPosition(cut, mt); |
ksrini@1074 | 494 | int end = (int) t.getSourcePositions().getEndPosition(cut, mt); |
ksrini@1074 | 495 | |
ksrini@1074 | 496 | assertEquals("testStartPositionForMethodWithoutModifiers", |
ksrini@1074 | 497 | "<T> void t() {}", code.substring(start, end)); |
ksrini@1074 | 498 | } |
ksrini@1074 | 499 | |
ksrini@1074 | 500 | public void testStartPositionEnumConstantInit() throws IOException { |
ksrini@1074 | 501 | |
ksrini@1074 | 502 | String code = "package t; enum Test { AAA; }"; |
ksrini@1074 | 503 | |
ksrini@1074 | 504 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 505 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 506 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 507 | ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); |
ksrini@1074 | 508 | VariableTree enumAAA = (VariableTree) clazz.getMembers().get(0); |
ksrini@1074 | 509 | Trees t = Trees.instance(ct); |
ksrini@1074 | 510 | int start = (int) t.getSourcePositions().getStartPosition(cut, |
ksrini@1074 | 511 | enumAAA.getInitializer()); |
ksrini@1074 | 512 | |
ksrini@1074 | 513 | assertEquals("testStartPositionEnumConstantInit", -1, start); |
ksrini@1074 | 514 | } |
ksrini@1074 | 515 | |
ksrini@1074 | 516 | public void testVariableInIfThen1() throws IOException { |
ksrini@1074 | 517 | |
ksrini@1074 | 518 | String code = "package t; class Test { " + |
ksrini@1074 | 519 | "private static void t(String name) { " + |
ksrini@1074 | 520 | "if (name != null) String nn = name.trim(); } }"; |
ksrini@1074 | 521 | |
ksrini@1074 | 522 | DiagnosticCollector<JavaFileObject> coll = |
ksrini@1074 | 523 | new DiagnosticCollector<JavaFileObject>(); |
ksrini@1074 | 524 | |
ksrini@1074 | 525 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, |
ksrini@1074 | 526 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 527 | |
ksrini@1074 | 528 | ct.parse(); |
ksrini@1074 | 529 | |
ksrini@1074 | 530 | List<String> codes = new LinkedList<String>(); |
ksrini@1074 | 531 | |
ksrini@1074 | 532 | for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { |
ksrini@1074 | 533 | codes.add(d.getCode()); |
ksrini@1074 | 534 | } |
ksrini@1074 | 535 | |
ksrini@1074 | 536 | assertEquals("testVariableInIfThen1", |
ksrini@1074 | 537 | Arrays.<String>asList("compiler.err.variable.not.allowed"), |
ksrini@1074 | 538 | codes); |
ksrini@1074 | 539 | } |
ksrini@1074 | 540 | |
ksrini@1074 | 541 | public void testVariableInIfThen2() throws IOException { |
ksrini@1074 | 542 | |
ksrini@1074 | 543 | String code = "package t; class Test { " + |
ksrini@1074 | 544 | "private static void t(String name) { " + |
ksrini@1074 | 545 | "if (name != null) class X {} } }"; |
ksrini@1074 | 546 | DiagnosticCollector<JavaFileObject> coll = |
ksrini@1074 | 547 | new DiagnosticCollector<JavaFileObject>(); |
ksrini@1074 | 548 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, |
ksrini@1074 | 549 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 550 | |
ksrini@1074 | 551 | ct.parse(); |
ksrini@1074 | 552 | |
ksrini@1074 | 553 | List<String> codes = new LinkedList<String>(); |
ksrini@1074 | 554 | |
ksrini@1074 | 555 | for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { |
ksrini@1074 | 556 | codes.add(d.getCode()); |
ksrini@1074 | 557 | } |
ksrini@1074 | 558 | |
ksrini@1074 | 559 | assertEquals("testVariableInIfThen2", |
ksrini@1074 | 560 | Arrays.<String>asList("compiler.err.class.not.allowed"), codes); |
ksrini@1074 | 561 | } |
ksrini@1074 | 562 | |
ksrini@1074 | 563 | public void testVariableInIfThen3() throws IOException { |
ksrini@1074 | 564 | |
ksrini@1074 | 565 | String code = "package t; class Test { "+ |
ksrini@1074 | 566 | "private static void t(String name) { " + |
ksrini@1074 | 567 | "if (name != null) abstract } }"; |
ksrini@1074 | 568 | DiagnosticCollector<JavaFileObject> coll = |
ksrini@1074 | 569 | new DiagnosticCollector<JavaFileObject>(); |
ksrini@1074 | 570 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, |
ksrini@1074 | 571 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 572 | |
ksrini@1074 | 573 | ct.parse(); |
ksrini@1074 | 574 | |
ksrini@1074 | 575 | List<String> codes = new LinkedList<String>(); |
ksrini@1074 | 576 | |
ksrini@1074 | 577 | for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { |
ksrini@1074 | 578 | codes.add(d.getCode()); |
ksrini@1074 | 579 | } |
ksrini@1074 | 580 | |
ksrini@1074 | 581 | assertEquals("testVariableInIfThen3", |
ksrini@1074 | 582 | Arrays.<String>asList("compiler.err.illegal.start.of.expr"), |
ksrini@1074 | 583 | codes); |
ksrini@1074 | 584 | } |
ksrini@1074 | 585 | |
ksrini@1074 | 586 | //see javac bug #6882235, NB bug #98234: |
ksrini@1074 | 587 | public void testMissingExponent() throws IOException { |
ksrini@1074 | 588 | |
ksrini@1074 | 589 | String code = "\nclass Test { { System.err.println(0e); } }"; |
ksrini@1074 | 590 | |
ksrini@1074 | 591 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 592 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 593 | |
ksrini@1074 | 594 | assertNotNull(ct.parse().iterator().next()); |
ksrini@1074 | 595 | } |
ksrini@1074 | 596 | |
ksrini@1074 | 597 | public void testTryResourcePos() throws IOException { |
ksrini@1074 | 598 | |
ksrini@1074 | 599 | final String code = "package t; class Test { " + |
ksrini@1074 | 600 | "{ try (java.io.InputStream in = null) { } } }"; |
ksrini@1074 | 601 | |
ksrini@1074 | 602 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 603 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 604 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 605 | |
ksrini@1074 | 606 | new TreeScanner<Void, Void>() { |
ksrini@1074 | 607 | @Override |
ksrini@1074 | 608 | public Void visitVariable(VariableTree node, Void p) { |
ksrini@1074 | 609 | if ("in".contentEquals(node.getName())) { |
ksrini@1074 | 610 | JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; |
ksrini@1074 | 611 | System.out.println(node.getName() + "," + var.pos); |
ksrini@1074 | 612 | assertEquals("testTryResourcePos", "in = null) { } } }", |
ksrini@1074 | 613 | code.substring(var.pos)); |
ksrini@1074 | 614 | } |
ksrini@1074 | 615 | return super.visitVariable(node, p); |
ksrini@1074 | 616 | } |
ksrini@1074 | 617 | }.scan(cut, null); |
ksrini@1074 | 618 | } |
ksrini@1074 | 619 | |
ksrini@1074 | 620 | public void testVarPos() throws IOException { |
ksrini@1074 | 621 | |
ksrini@1074 | 622 | final String code = "package t; class Test { " + |
ksrini@1074 | 623 | "{ java.io.InputStream in = null; } }"; |
ksrini@1074 | 624 | |
ksrini@1074 | 625 | JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, |
ksrini@1074 | 626 | null, Arrays.asList(new MyFileObject(code))); |
ksrini@1074 | 627 | CompilationUnitTree cut = ct.parse().iterator().next(); |
ksrini@1074 | 628 | |
ksrini@1074 | 629 | new TreeScanner<Void, Void>() { |
ksrini@1074 | 630 | |
ksrini@1074 | 631 | @Override |
ksrini@1074 | 632 | public Void visitVariable(VariableTree node, Void p) { |
ksrini@1074 | 633 | if ("in".contentEquals(node.getName())) { |
ksrini@1074 | 634 | JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; |
ksrini@1074 | 635 | assertEquals("testVarPos","in = null; } }", |
ksrini@1074 | 636 | code.substring(var.pos)); |
ksrini@1074 | 637 | } |
ksrini@1074 | 638 | return super.visitVariable(node, p); |
ksrini@1074 | 639 | } |
ksrini@1074 | 640 | }.scan(cut, null); |
ksrini@1074 | 641 | } |
ksrini@1074 | 642 | |
ksrini@1074 | 643 | void testsNotWorking() throws IOException { |
ksrini@1074 | 644 | |
ksrini@1074 | 645 | // Fails with nb-javac, needs further investigation |
ksrini@1074 | 646 | testPositionBrokenSource126732a(); |
ksrini@1074 | 647 | testPositionBrokenSource126732b(); |
ksrini@1074 | 648 | |
ksrini@1074 | 649 | // Fails, these tests yet to be addressed |
ksrini@1074 | 650 | testVariableInIfThen1(); |
ksrini@1074 | 651 | testVariableInIfThen2(); |
ksrini@1074 | 652 | testPositionForEnumModifiers(); |
ksrini@1074 | 653 | testStartPositionEnumConstantInit(); |
ksrini@1074 | 654 | } |
ksrini@1074 | 655 | void testPositions() throws IOException { |
ksrini@1074 | 656 | testPositionsSane(); |
ksrini@1074 | 657 | testCorrectWilcardPositions(); |
ksrini@1074 | 658 | testPositionAnnotationNoPackage187551(); |
ksrini@1074 | 659 | testPositionForSuperConstructorCalls(); |
ksrini@1074 | 660 | testPreferredPositionForBinaryOp(); |
ksrini@1074 | 661 | testStartPositionForMethodWithoutModifiers(); |
ksrini@1074 | 662 | testVarPos(); |
ksrini@1074 | 663 | testVariableInIfThen3(); |
ksrini@1074 | 664 | testTryResourcePos(); |
ksrini@1074 | 665 | } |
ksrini@1074 | 666 | |
ksrini@1074 | 667 | public static void main(String... args) throws IOException { |
ksrini@1074 | 668 | JavacParserTest jpt = new JavacParserTest("JavacParserTest"); |
ksrini@1074 | 669 | jpt.testPositions(); |
ksrini@1074 | 670 | System.out.println("PASS"); |
ksrini@1074 | 671 | } |
ksrini@1074 | 672 | } |
ksrini@1074 | 673 | |
ksrini@1074 | 674 | abstract class TestCase { |
ksrini@1074 | 675 | |
ksrini@1074 | 676 | void assertEquals(String message, int i, int pos) { |
ksrini@1074 | 677 | if (i != pos) { |
ksrini@1074 | 678 | fail(message); |
ksrini@1074 | 679 | } |
ksrini@1074 | 680 | } |
ksrini@1074 | 681 | |
ksrini@1074 | 682 | void assertFalse(String message, boolean empty) { |
ksrini@1074 | 683 | throw new UnsupportedOperationException("Not yet implemented"); |
ksrini@1074 | 684 | } |
ksrini@1074 | 685 | |
ksrini@1074 | 686 | void assertEquals(String message, int i, long l) { |
ksrini@1074 | 687 | if (i != l) { |
ksrini@1074 | 688 | fail(message + ":" + i + ":" + l); |
ksrini@1074 | 689 | } |
ksrini@1074 | 690 | } |
ksrini@1074 | 691 | |
ksrini@1074 | 692 | void assertEquals(String message, Object o1, Object o2) { |
ksrini@1074 | 693 | System.out.println(o1); |
ksrini@1074 | 694 | System.out.println(o2); |
ksrini@1074 | 695 | if (o1 != null && o2 != null && !o1.equals(o2)) { |
ksrini@1074 | 696 | fail(message); |
ksrini@1074 | 697 | } |
ksrini@1074 | 698 | if (o1 == null && o2 != null) { |
ksrini@1074 | 699 | fail(message); |
ksrini@1074 | 700 | } |
ksrini@1074 | 701 | } |
ksrini@1074 | 702 | |
ksrini@1074 | 703 | void assertNotNull(Object o) { |
ksrini@1074 | 704 | if (o == null) { |
ksrini@1074 | 705 | fail(); |
ksrini@1074 | 706 | } |
ksrini@1074 | 707 | } |
ksrini@1074 | 708 | |
ksrini@1074 | 709 | void fail() { |
ksrini@1074 | 710 | fail("test failed"); |
ksrini@1074 | 711 | } |
ksrini@1074 | 712 | |
ksrini@1074 | 713 | void fail(String message) { |
ksrini@1074 | 714 | throw new RuntimeException(message); |
ksrini@1074 | 715 | } |
ksrini@1074 | 716 | } |