Thu, 01 Sep 2011 09:14:25 -0700
7073631: (javac) javac parser improvements for error position reporting
Summary: JavacParser improvements for NetBeans, improved by LangTools.
Reviewed-by: mcimadamore, jjg
Contributed-by: jan.lahoda@oracle.com
1.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Wed Aug 31 15:39:00 2011 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Sep 01 09:14:25 2011 -0700 1.3 @@ -27,15 +27,15 @@ 1.4 1.5 import java.util.*; 1.6 1.7 +import com.sun.tools.javac.code.*; 1.8 import com.sun.tools.javac.tree.*; 1.9 -import com.sun.tools.javac.code.*; 1.10 +import com.sun.tools.javac.tree.JCTree.*; 1.11 import com.sun.tools.javac.util.*; 1.12 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 1.13 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 1.14 import com.sun.tools.javac.util.List; 1.15 + 1.16 import static com.sun.tools.javac.util.ListBuffer.lb; 1.17 - 1.18 -import com.sun.tools.javac.tree.JCTree.*; 1.19 - 1.20 import static com.sun.tools.javac.parser.Token.*; 1.21 1.22 /** The parser maps a token sequence into an abstract syntax 1.23 @@ -254,26 +254,44 @@ 1.24 } 1.25 1.26 private JCErroneous syntaxError(int pos, String key, Token... args) { 1.27 - return syntaxError(pos, null, key, args); 1.28 + return syntaxError(pos, List.<JCTree>nil(), key, args); 1.29 } 1.30 1.31 private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) { 1.32 setErrorEndPos(pos); 1.33 - reportSyntaxError(pos, key, (Object[])args); 1.34 - return toP(F.at(pos).Erroneous(errs)); 1.35 + JCErroneous err = F.at(pos).Erroneous(errs); 1.36 + reportSyntaxError(err, key, (Object[])args); 1.37 + if (errs != null) { 1.38 + JCTree last = errs.last(); 1.39 + if (last != null) 1.40 + storeEnd(last, pos); 1.41 + } 1.42 + return toP(err); 1.43 } 1.44 1.45 private int errorPos = Position.NOPOS; 1.46 + 1.47 /** 1.48 - * Report a syntax error at given position using the given 1.49 - * argument unless one was already reported at the same position. 1.50 + * Report a syntax using the given the position parameter and arguments, 1.51 + * unless one was already reported at the same position. 1.52 */ 1.53 private void reportSyntaxError(int pos, String key, Object... args) { 1.54 + JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos); 1.55 + reportSyntaxError(diag, key, args); 1.56 + } 1.57 + 1.58 + /** 1.59 + * Report a syntax error using the given DiagnosticPosition object and 1.60 + * arguments, unless one was already reported at the same position. 1.61 + */ 1.62 + private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) { 1.63 + int pos = diagPos.getPreferredPosition(); 1.64 if (pos > S.errPos() || pos == Position.NOPOS) { 1.65 - if (S.token() == EOF) 1.66 - error(pos, "premature.eof"); 1.67 - else 1.68 - error(pos, key, args); 1.69 + if (S.token() == EOF) { 1.70 + error(diagPos, "premature.eof"); 1.71 + } else { 1.72 + error(diagPos, key, args); 1.73 + } 1.74 } 1.75 S.errPos(pos); 1.76 if (S.pos() == errorPos) 1.77 @@ -311,7 +329,7 @@ 1.78 /** Report an illegal start of expression/type error at given position. 1.79 */ 1.80 JCExpression illegal(int pos) { 1.81 - setErrorEndPos(S.pos()); 1.82 + setErrorEndPos(pos); 1.83 if ((mode & EXPR) != 0) 1.84 return syntaxError(pos, "illegal.start.of.expr"); 1.85 else 1.86 @@ -340,7 +358,7 @@ 1.87 * indexed by the tree nodes they refer to. 1.88 * defined only if option flag keepDocComment is set. 1.89 */ 1.90 - Map<JCTree, String> docComments; 1.91 + private final Map<JCTree, String> docComments; 1.92 1.93 /** Make an entry into docComments hashtable, 1.94 * provided flag keepDocComments is set and given doc comment is non-null. 1.95 @@ -462,6 +480,10 @@ 1.96 return t; 1.97 } 1.98 1.99 + JCExpression literal(Name prefix) { 1.100 + return literal(prefix, S.pos()); 1.101 + } 1.102 + 1.103 /** 1.104 * Literal = 1.105 * INTLITERAL 1.106 @@ -474,8 +496,7 @@ 1.107 * | FALSE 1.108 * | NULL 1.109 */ 1.110 - JCExpression literal(Name prefix) { 1.111 - int pos = S.pos(); 1.112 + JCExpression literal(Name prefix, int pos) { 1.113 JCExpression t = errorTree; 1.114 switch (S.token()) { 1.115 case INTLITERAL: 1.116 @@ -869,7 +890,7 @@ 1.117 (S.token() == INTLITERAL || S.token() == LONGLITERAL) && 1.118 S.radix() == 10) { 1.119 mode = EXPR; 1.120 - t = literal(names.hyphen); 1.121 + t = literal(names.hyphen, pos); 1.122 } else { 1.123 t = term3(); 1.124 return F.at(pos).Unary(unoptag(token), t); 1.125 @@ -1267,15 +1288,17 @@ 1.126 case GTGT: 1.127 S.token(GT); 1.128 break; 1.129 + case GT: 1.130 + S.nextToken(); 1.131 + break; 1.132 default: 1.133 - accept(GT); 1.134 + args.append(syntaxError(S.pos(), "expected", GT)); 1.135 break; 1.136 } 1.137 return args.toList(); 1.138 } 1.139 } else { 1.140 - syntaxError(S.pos(), "expected", LT); 1.141 - return List.nil(); 1.142 + return List.<JCExpression>of(syntaxError(S.pos(), "expected", LT)); 1.143 } 1.144 } 1.145 1.146 @@ -1300,12 +1323,12 @@ 1.147 return F.at(pos).Wildcard(t, bound); 1.148 } else if (S.token() == IDENTIFIER) { 1.149 //error recovery 1.150 - reportSyntaxError(S.prevEndPos(), "expected3", 1.151 - GT, EXTENDS, SUPER); 1.152 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1.153 JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 1.154 JCIdent id = toP(F.at(S.pos()).Ident(ident())); 1.155 - return F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 1.156 + JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 1.157 + reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER); 1.158 + return err; 1.159 } else { 1.160 TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND)); 1.161 return toP(F.at(pos).Wildcard(t, null)); 1.162 @@ -1391,7 +1414,7 @@ 1.163 while (S.token() == DOT) { 1.164 if (diamondFound) { 1.165 //cannot select after a diamond 1.166 - illegal(S.pos()); 1.167 + illegal(); 1.168 } 1.169 int pos = S.pos(); 1.170 S.nextToken(); 1.171 @@ -1419,15 +1442,16 @@ 1.172 pos = typeArgs.head.pos; 1.173 } 1.174 setErrorEndPos(S.prevEndPos()); 1.175 - reportSyntaxError(pos, "cannot.create.array.with.type.arguments"); 1.176 - return toP(F.at(newpos).Erroneous(typeArgs.prepend(e))); 1.177 + JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e)); 1.178 + reportSyntaxError(err, "cannot.create.array.with.type.arguments"); 1.179 + return toP(err); 1.180 } 1.181 return e; 1.182 } else if (S.token() == LPAREN) { 1.183 return classCreatorRest(newpos, null, typeArgs, t); 1.184 } else { 1.185 - reportSyntaxError(S.pos(), "expected2", 1.186 - LPAREN, LBRACKET); 1.187 + setErrorEndPos(S.pos()); 1.188 + reportSyntaxError(S.pos(), "expected2", LPAREN, LBRACKET); 1.189 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null)); 1.190 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 1.191 } 1.192 @@ -1457,7 +1481,8 @@ 1.193 if (S.token() == LBRACE) { 1.194 return arrayInitializer(newpos, elemtype); 1.195 } else { 1.196 - return syntaxError(S.pos(), "array.dimension.missing"); 1.197 + JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null)); 1.198 + return syntaxError(S.pos(), List.<JCTree>of(t), "array.dimension.missing"); 1.199 } 1.200 } else { 1.201 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>(); 1.202 @@ -1843,7 +1868,7 @@ 1.203 1.204 /** CatchClause = CATCH "(" FormalParameter ")" Block 1.205 */ 1.206 - JCCatch catchClause() { 1.207 + protected JCCatch catchClause() { 1.208 int pos = S.pos(); 1.209 accept(CATCH); 1.210 accept(LPAREN); 1.211 @@ -1973,7 +1998,7 @@ 1.212 JCModifiers modifiersOpt() { 1.213 return modifiersOpt(null); 1.214 } 1.215 - JCModifiers modifiersOpt(JCModifiers partial) { 1.216 + protected JCModifiers modifiersOpt(JCModifiers partial) { 1.217 long flags; 1.218 ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>(); 1.219 int pos; 1.220 @@ -2006,6 +2031,7 @@ 1.221 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; 1.222 case STRICTFP : flag = Flags.STRICTFP; break; 1.223 case MONKEYS_AT : flag = Flags.ANNOTATION; break; 1.224 + case ERROR : flag = 0; S.nextToken(); break; 1.225 default: break loop; 1.226 } 1.227 if ((flags & flag) != 0) error(S.pos(), "repeated.modifier"); 1.228 @@ -2219,9 +2245,12 @@ 1.229 1.230 /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression 1.231 */ 1.232 - JCTree resource() { 1.233 - return variableDeclaratorRest(S.pos(), optFinal(Flags.FINAL), 1.234 - parseType(), ident(), true, null); 1.235 + protected JCTree resource() { 1.236 + JCModifiers optFinal = optFinal(Flags.FINAL); 1.237 + JCExpression type = parseType(); 1.238 + int pos = S.pos(); 1.239 + Name ident = ident(); 1.240 + return variableDeclaratorRest(pos, optFinal, type, ident, true, null); 1.241 } 1.242 1.243 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} 1.244 @@ -2568,7 +2597,7 @@ 1.245 * | ModifiersOpt Type Ident 1.246 * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) 1.247 */ 1.248 - List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 1.249 + protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 1.250 if (S.token() == SEMI) { 1.251 S.nextToken(); 1.252 return List.<JCTree>nil(); 1.253 @@ -2770,7 +2799,7 @@ 1.254 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 1.255 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 1.256 */ 1.257 - JCVariableDecl formalParameter() { 1.258 + protected JCVariableDecl formalParameter() { 1.259 JCModifiers mods = optFinal(Flags.PARAMETER); 1.260 JCExpression type = parseType(); 1.261 if (S.token() == ELLIPSIS) { 1.262 @@ -2788,6 +2817,10 @@ 1.263 log.error(DiagnosticFlag.SYNTAX, pos, key, args); 1.264 } 1.265 1.266 + void error(DiagnosticPosition pos, String key, Object ... args) { 1.267 + log.error(DiagnosticFlag.SYNTAX, pos, key, args); 1.268 + } 1.269 + 1.270 void warning(int pos, String key, Object ... args) { 1.271 log.warning(pos, key, args); 1.272 } 1.273 @@ -2807,8 +2840,9 @@ 1.274 case JCTree.ERRONEOUS: 1.275 return t; 1.276 default: 1.277 - error(t.pos, "not.stmt"); 1.278 - return F.at(t.pos).Erroneous(List.<JCTree>of(t)); 1.279 + JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t)); 1.280 + error(ret, "not.stmt"); 1.281 + return ret; 1.282 } 1.283 } 1.284
2.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java Wed Aug 31 15:39:00 2011 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java Thu Sep 01 09:14:25 2011 -0700 2.3 @@ -982,8 +982,16 @@ 2.4 } 2.5 2.6 /** Sets the current token. 2.7 + * This method is primarily used to update the token stream when the 2.8 + * parser is handling the end of nested type arguments such as 2.9 + * {@code List<List<String>>} and needs to disambiguate between 2.10 + * repeated use of ">" and relation operators such as ">>" and ">>>". Noting 2.11 + * that this does not handle arbitrary tokens containing Unicode escape 2.12 + * sequences. 2.13 */ 2.14 public void token(Token token) { 2.15 + pos += this.token.name.length() - token.name.length(); 2.16 + prevEndPos = pos; 2.17 this.token = token; 2.18 } 2.19
3.1 --- a/src/share/classes/com/sun/tools/javac/util/AbstractLog.java Wed Aug 31 15:39:00 2011 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/util/AbstractLog.java Thu Sep 01 09:14:25 2011 -0700 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -96,6 +96,19 @@ 3.11 3.12 /** Report an error, unless another error was already reported at same 3.13 * source position. 3.14 + * @param flag A flag to set on the diagnostic 3.15 + * @param pos The source position at which to report the error. 3.16 + * @param key The key for the localized error message. 3.17 + * @param args Fields of the error message. 3.18 + */ 3.19 + public void error(DiagnosticFlag flag, DiagnosticPosition pos, String key, Object ... args) { 3.20 + JCDiagnostic d = diags.error(source, pos, key, args); 3.21 + d.setFlag(flag); 3.22 + report(d); 3.23 + } 3.24 + 3.25 + /** Report an error, unless another error was already reported at same 3.26 + * source position. 3.27 * @param pos The source position at which to report the error. 3.28 * @param key The key for the localized error message. 3.29 * @param args Fields of the error message.
4.1 --- a/test/tools/javac/TryWithResources/BadTwr.out Wed Aug 31 15:39:00 2011 -0700 4.2 +++ b/test/tools/javac/TryWithResources/BadTwr.out Thu Sep 01 09:14:25 2011 -0700 4.3 @@ -1,5 +1,5 @@ 4.4 -BadTwr.java:13:39: compiler.err.already.defined: r1, main(java.lang.String...) 4.5 -BadTwr.java:18:13: compiler.err.already.defined: args, main(java.lang.String...) 4.6 +BadTwr.java:13:46: compiler.err.already.defined: r1, main(java.lang.String...) 4.7 +BadTwr.java:18:20: compiler.err.already.defined: args, main(java.lang.String...) 4.8 BadTwr.java:21:13: compiler.err.cant.assign.val.to.final.var: thatsIt 4.9 -BadTwr.java:26:17: compiler.err.already.defined: name, main(java.lang.String...) 4.10 +BadTwr.java:26:24: compiler.err.already.defined: name, main(java.lang.String...) 4.11 4 errors
5.1 --- a/test/tools/javac/TryWithResources/DuplicateResourceDecl.out Wed Aug 31 15:39:00 2011 -0700 5.2 +++ b/test/tools/javac/TryWithResources/DuplicateResourceDecl.out Thu Sep 01 09:14:25 2011 -0700 5.3 @@ -1,2 +1,2 @@ 5.4 -DuplicateResourceDecl.java:12:45: compiler.err.already.defined: c, main(java.lang.String[]) 5.5 +DuplicateResourceDecl.java:12:56: compiler.err.already.defined: c, main(java.lang.String[]) 5.6 1 error
6.1 --- a/test/tools/javac/TryWithResources/ResourceInterface.out Wed Aug 31 15:39:00 2011 -0700 6.2 +++ b/test/tools/javac/TryWithResources/ResourceInterface.out Thu Sep 01 09:14:25 2011 -0700 6.3 @@ -1,2 +1,2 @@ 6.4 -ResourceInterface.java:38:13: compiler.err.unreported.exception.implicit.close: ResourceInterface.E1, r2 6.5 +ResourceInterface.java:38:23: compiler.err.unreported.exception.implicit.close: ResourceInterface.E1, r2 6.6 1 error
7.1 --- a/test/tools/javac/TryWithResources/TwrFlow.out Wed Aug 31 15:39:00 2011 -0700 7.2 +++ b/test/tools/javac/TryWithResources/TwrFlow.out Thu Sep 01 09:14:25 2011 -0700 7.3 @@ -1,3 +1,3 @@ 7.4 TwrFlow.java:14:11: compiler.err.except.never.thrown.in.try: java.io.IOException 7.5 -TwrFlow.java:12:13: compiler.err.unreported.exception.implicit.close: CustomCloseException, twrFlow 7.6 +TwrFlow.java:12:21: compiler.err.unreported.exception.implicit.close: CustomCloseException, twrFlow 7.7 2 errors
8.1 --- a/test/tools/javac/TryWithResources/TwrLint.out Wed Aug 31 15:39:00 2011 -0700 8.2 +++ b/test/tools/javac/TryWithResources/TwrLint.out Thu Sep 01 09:14:25 2011 -0700 8.3 @@ -1,3 +1,3 @@ 8.4 TwrLint.java:14:15: compiler.warn.try.explicit.close.call 8.5 -TwrLint.java:13:13: compiler.warn.try.resource.not.referenced: r3 8.6 +TwrLint.java:13:21: compiler.warn.try.resource.not.referenced: r3 8.7 2 warnings
9.1 --- a/test/tools/javac/TryWithResources/TwrOnNonResource.out Wed Aug 31 15:39:00 2011 -0700 9.2 +++ b/test/tools/javac/TryWithResources/TwrOnNonResource.out Thu Sep 01 09:14:25 2011 -0700 9.3 @@ -1,4 +1,4 @@ 9.4 -TwrOnNonResource.java:12:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable 9.5 -TwrOnNonResource.java:15:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable 9.6 -TwrOnNonResource.java:18:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable 9.7 +TwrOnNonResource.java:12:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable 9.8 +TwrOnNonResource.java:15:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable 9.9 +TwrOnNonResource.java:18:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable 9.10 3 errors
10.1 --- a/test/tools/javac/diags/examples/EmptyCharLiteral.java Wed Aug 31 15:39:00 2011 -0700 10.2 +++ b/test/tools/javac/diags/examples/EmptyCharLiteral.java Thu Sep 01 09:14:25 2011 -0700 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -23,7 +23,6 @@ 10.11 10.12 // key: compiler.err.empty.char.lit 10.13 // key: compiler.err.unclosed.char.lit 10.14 -// key: compiler.err.expected 10.15 // key: compiler.err.premature.eof 10.16 10.17 class X {
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/tools/javac/parser/netbeans/JavacParserTest.java Thu Sep 01 09:14:25 2011 -0700 11.3 @@ -0,0 +1,716 @@ 11.4 +/* 11.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + */ 11.26 + 11.27 +/* 11.28 + * @test 11.29 + * @bug 7073631 11.30 + * @summary tests error and diagnostics positions 11.31 + * @author jan.lahoda@oracle.com 11.32 + */ 11.33 + 11.34 +import com.sun.source.tree.BinaryTree; 11.35 +import com.sun.source.tree.BlockTree; 11.36 +import com.sun.source.tree.ClassTree; 11.37 +import com.sun.source.tree.CompilationUnitTree; 11.38 +import com.sun.source.tree.ExpressionStatementTree; 11.39 +import com.sun.source.tree.ExpressionTree; 11.40 +import com.sun.source.tree.MethodInvocationTree; 11.41 +import com.sun.source.tree.MethodTree; 11.42 +import com.sun.source.tree.ModifiersTree; 11.43 +import com.sun.source.tree.StatementTree; 11.44 +import com.sun.source.tree.Tree; 11.45 +import com.sun.source.tree.Tree.Kind; 11.46 +import com.sun.source.tree.VariableTree; 11.47 +import com.sun.source.tree.WhileLoopTree; 11.48 +import com.sun.source.util.SourcePositions; 11.49 +import com.sun.source.util.TreeScanner; 11.50 +import com.sun.source.util.Trees; 11.51 +import com.sun.tools.javac.api.JavacTaskImpl; 11.52 +import com.sun.tools.javac.tree.JCTree; 11.53 +import java.io.IOException; 11.54 +import java.net.URI; 11.55 +import java.util.Arrays; 11.56 +import java.util.LinkedList; 11.57 +import java.util.List; 11.58 +import javax.tools.Diagnostic; 11.59 +import javax.tools.DiagnosticCollector; 11.60 +import javax.tools.DiagnosticListener; 11.61 +import javax.tools.JavaCompiler; 11.62 +import javax.tools.JavaFileObject; 11.63 +import javax.tools.SimpleJavaFileObject; 11.64 +import javax.tools.ToolProvider; 11.65 + 11.66 +public class JavacParserTest extends TestCase { 11.67 + final JavaCompiler tool; 11.68 + public JavacParserTest(String testName) { 11.69 + tool = ToolProvider.getSystemJavaCompiler(); 11.70 + System.out.println("java.home=" + System.getProperty("java.home")); 11.71 + } 11.72 + 11.73 + static class MyFileObject extends SimpleJavaFileObject { 11.74 + 11.75 + private String text; 11.76 + 11.77 + public MyFileObject(String text) { 11.78 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 11.79 + this.text = text; 11.80 + } 11.81 + 11.82 + @Override 11.83 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 11.84 + return text; 11.85 + } 11.86 + } 11.87 + 11.88 + public void testPositionForSuperConstructorCalls() throws IOException { 11.89 + assert tool != null; 11.90 + 11.91 + String code = "package test; public class Test {public Test() {super();}}"; 11.92 + 11.93 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.94 + null, Arrays.asList(new MyFileObject(code))); 11.95 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.96 + SourcePositions pos = Trees.instance(ct).getSourcePositions(); 11.97 + 11.98 + MethodTree method = 11.99 + (MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); 11.100 + ExpressionStatementTree es = 11.101 + (ExpressionStatementTree) method.getBody().getStatements().get(0); 11.102 + 11.103 + assertEquals("testPositionForSuperConstructorCalls", 11.104 + 72 - 24, pos.getStartPosition(cut, es)); 11.105 + assertEquals("testPositionForSuperConstructorCalls", 11.106 + 80 - 24, pos.getEndPosition(cut, es)); 11.107 + 11.108 + MethodInvocationTree mit = (MethodInvocationTree) es.getExpression(); 11.109 + 11.110 + assertEquals("testPositionForSuperConstructorCalls", 11.111 + 72 - 24, pos.getStartPosition(cut, mit)); 11.112 + assertEquals("testPositionForSuperConstructorCalls", 11.113 + 79 - 24, pos.getEndPosition(cut, mit)); 11.114 + 11.115 + assertEquals("testPositionForSuperConstructorCalls", 11.116 + 72 - 24, pos.getStartPosition(cut, mit.getMethodSelect())); 11.117 + assertEquals("testPositionForSuperConstructorCalls", 11.118 + 77 - 24, pos.getEndPosition(cut, mit.getMethodSelect())); 11.119 + 11.120 + } 11.121 + 11.122 + public void testPositionForEnumModifiers() throws IOException { 11.123 + 11.124 + String code = "package test; public enum Test {A;}"; 11.125 + 11.126 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.127 + null, Arrays.asList(new MyFileObject(code))); 11.128 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.129 + SourcePositions pos = Trees.instance(ct).getSourcePositions(); 11.130 + 11.131 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.132 + ModifiersTree mt = clazz.getModifiers(); 11.133 + 11.134 + assertEquals("testPositionForEnumModifiers", 11.135 + 38 - 24, pos.getStartPosition(cut, mt)); 11.136 + assertEquals("testPositionForEnumModifiers", 11.137 + 44 - 24, pos.getEndPosition(cut, mt)); 11.138 + } 11.139 + 11.140 + public void testNewClassWithEnclosing() throws IOException { 11.141 + 11.142 + 11.143 + String code = "package test; class Test { " + 11.144 + "class d {} private void method() { " + 11.145 + "Object o = Test.this.new d(); } }"; 11.146 + 11.147 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.148 + null, Arrays.asList(new MyFileObject(code))); 11.149 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.150 + SourcePositions pos = Trees.instance(ct).getSourcePositions(); 11.151 + 11.152 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.153 + ExpressionTree est = 11.154 + ((VariableTree) ((MethodTree) clazz.getMembers().get(1)).getBody().getStatements().get(0)).getInitializer(); 11.155 + 11.156 + assertEquals("testNewClassWithEnclosing", 11.157 + 97 - 24, pos.getStartPosition(cut, est)); 11.158 + assertEquals("testNewClassWithEnclosing", 11.159 + 114 - 24, pos.getEndPosition(cut, est)); 11.160 + } 11.161 + 11.162 + public void testPreferredPositionForBinaryOp() throws IOException { 11.163 + 11.164 + String code = "package test; public class Test {" + 11.165 + "private void test() {" + 11.166 + "Object o = null; boolean b = o != null && o instanceof String;" + 11.167 + "} private Test() {}}"; 11.168 + 11.169 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.170 + null, Arrays.asList(new MyFileObject(code))); 11.171 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.172 + 11.173 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.174 + MethodTree method = (MethodTree) clazz.getMembers().get(0); 11.175 + VariableTree condSt = (VariableTree) method.getBody().getStatements().get(1); 11.176 + BinaryTree cond = (BinaryTree) condSt.getInitializer(); 11.177 + 11.178 + JCTree condJC = (JCTree) cond; 11.179 + 11.180 + assertEquals("testNewClassWithEnclosing", 11.181 + 117 - 24, condJC.pos); 11.182 + } 11.183 + 11.184 + public void testPositionBrokenSource126732a() throws IOException { 11.185 + String[] commands = new String[]{ 11.186 + "return Runnable()", 11.187 + "do { } while (true)", 11.188 + "throw UnsupportedOperationException()", 11.189 + "assert true", 11.190 + "1 + 1",}; 11.191 + 11.192 + for (String command : commands) { 11.193 + 11.194 + String code = "package test;\n" 11.195 + + "public class Test {\n" 11.196 + + " public static void test() {\n" 11.197 + + " " + command + " {\n" 11.198 + + " new Runnable() {\n" 11.199 + + " };\n" 11.200 + + " }\n" 11.201 + + "}"; 11.202 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, 11.203 + null, null, Arrays.asList(new MyFileObject(code))); 11.204 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.205 + 11.206 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.207 + MethodTree method = (MethodTree) clazz.getMembers().get(0); 11.208 + List<? extends StatementTree> statements = 11.209 + method.getBody().getStatements(); 11.210 + 11.211 + StatementTree ret = statements.get(0); 11.212 + StatementTree block = statements.get(1); 11.213 + 11.214 + Trees t = Trees.instance(ct); 11.215 + int len = code.indexOf(command + " {") + (command + " ").length(); 11.216 + assertEquals(command, len, 11.217 + t.getSourcePositions().getEndPosition(cut, ret)); 11.218 + assertEquals(command, len, 11.219 + t.getSourcePositions().getStartPosition(cut, block)); 11.220 + } 11.221 + } 11.222 + 11.223 + public void testPositionBrokenSource126732b() throws IOException { 11.224 + String[] commands = new String[]{ 11.225 + "break", 11.226 + "break A", 11.227 + "continue ", 11.228 + "continue A",}; 11.229 + 11.230 + for (String command : commands) { 11.231 + 11.232 + String code = "package test;\n" 11.233 + + "public class Test {\n" 11.234 + + " public static void test() {\n" 11.235 + + " while (true) {\n" 11.236 + + " " + command + " {\n" 11.237 + + " new Runnable() {\n" 11.238 + + " };\n" 11.239 + + " }\n" 11.240 + + " }\n" 11.241 + + "}"; 11.242 + 11.243 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, 11.244 + null, null, Arrays.asList(new MyFileObject(code))); 11.245 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.246 + 11.247 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.248 + MethodTree method = (MethodTree) clazz.getMembers().get(0); 11.249 + List<? extends StatementTree> statements = 11.250 + ((BlockTree) ((WhileLoopTree) method.getBody().getStatements().get(0)).getStatement()).getStatements(); 11.251 + 11.252 + StatementTree ret = statements.get(0); 11.253 + StatementTree block = statements.get(1); 11.254 + 11.255 + Trees t = Trees.instance(ct); 11.256 + int len = code.indexOf(command + " {") + (command + " ").length(); 11.257 + assertEquals(command, len, 11.258 + t.getSourcePositions().getEndPosition(cut, ret)); 11.259 + assertEquals(command, len, 11.260 + t.getSourcePositions().getStartPosition(cut, block)); 11.261 + } 11.262 + } 11.263 + 11.264 + public void testErrorRecoveryForEnhancedForLoop142381() throws IOException { 11.265 + 11.266 + String code = "package test; class Test { " + 11.267 + "private void method() { " + 11.268 + "java.util.Set<String> s = null; for (a : s) {} } }"; 11.269 + 11.270 + final List<Diagnostic<? extends JavaFileObject>> errors = 11.271 + new LinkedList<Diagnostic<? extends JavaFileObject>>(); 11.272 + 11.273 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 11.274 + new DiagnosticListener<JavaFileObject>() { 11.275 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 11.276 + errors.add(diagnostic); 11.277 + } 11.278 + }, null, null, Arrays.asList(new MyFileObject(code))); 11.279 + 11.280 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.281 + 11.282 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.283 + StatementTree forStatement = 11.284 + ((MethodTree) clazz.getMembers().get(0)).getBody().getStatements().get(1); 11.285 + 11.286 + assertEquals("testErrorRecoveryForEnhancedForLoop142381", 11.287 + Kind.ENHANCED_FOR_LOOP, forStatement.getKind()); 11.288 + assertFalse("testErrorRecoveryForEnhancedForLoop142381", errors.isEmpty()); 11.289 + } 11.290 + 11.291 + public void testPositionAnnotationNoPackage187551() throws IOException { 11.292 + 11.293 + String code = "\n@interface Test {}"; 11.294 + 11.295 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.296 + null, Arrays.asList(new MyFileObject(code))); 11.297 + 11.298 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.299 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.300 + Trees t = Trees.instance(ct); 11.301 + 11.302 + assertEquals("testPositionAnnotationNoPackage187551", 11.303 + 1, t.getSourcePositions().getStartPosition(cut, clazz)); 11.304 + } 11.305 + 11.306 + public void testPositionsSane() throws IOException { 11.307 + performPositionsSanityTest("package test; class Test { " + 11.308 + "private void method() { " + 11.309 + "java.util.List<? extends java.util.List<? extends String>> l; " + 11.310 + "} }"); 11.311 + performPositionsSanityTest("package test; class Test { " + 11.312 + "private void method() { " + 11.313 + "java.util.List<? super java.util.List<? super String>> l; " + 11.314 + "} }"); 11.315 + performPositionsSanityTest("package test; class Test { " + 11.316 + "private void method() { " + 11.317 + "java.util.List<? super java.util.List<?>> l; } }"); 11.318 + } 11.319 + 11.320 + private void performPositionsSanityTest(String code) throws IOException { 11.321 + 11.322 + final List<Diagnostic<? extends JavaFileObject>> errors = 11.323 + new LinkedList<Diagnostic<? extends JavaFileObject>>(); 11.324 + 11.325 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 11.326 + new DiagnosticListener<JavaFileObject>() { 11.327 + 11.328 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 11.329 + errors.add(diagnostic); 11.330 + } 11.331 + }, null, null, Arrays.asList(new MyFileObject(code))); 11.332 + 11.333 + final CompilationUnitTree cut = ct.parse().iterator().next(); 11.334 + final Trees trees = Trees.instance(ct); 11.335 + 11.336 + new TreeScanner<Void, Void>() { 11.337 + 11.338 + private long parentStart = 0; 11.339 + private long parentEnd = Integer.MAX_VALUE; 11.340 + 11.341 + @Override 11.342 + public Void scan(Tree node, Void p) { 11.343 + if (node == null) { 11.344 + return null; 11.345 + } 11.346 + 11.347 + long start = trees.getSourcePositions().getStartPosition(cut, node); 11.348 + 11.349 + if (start == (-1)) { 11.350 + return null; //synthetic tree 11.351 + } 11.352 + assertTrue(node.toString() + ":" + start + "/" + parentStart, 11.353 + parentStart <= start); 11.354 + 11.355 + long prevParentStart = parentStart; 11.356 + 11.357 + parentStart = start; 11.358 + 11.359 + long end = trees.getSourcePositions().getEndPosition(cut, node); 11.360 + 11.361 + assertTrue(node.toString() + ":" + end + "/" + parentEnd, 11.362 + end <= parentEnd); 11.363 + 11.364 + long prevParentEnd = parentEnd; 11.365 + 11.366 + parentEnd = end; 11.367 + 11.368 + super.scan(node, p); 11.369 + 11.370 + parentStart = prevParentStart; 11.371 + parentEnd = prevParentEnd; 11.372 + 11.373 + return null; 11.374 + } 11.375 + 11.376 + private void assertTrue(String message, boolean b) { 11.377 + if (!b) fail(message); 11.378 + } 11.379 + }.scan(cut, null); 11.380 + } 11.381 + 11.382 + public void testCorrectWilcardPositions() throws IOException { 11.383 + performWildcardPositionsTest("package test; import java.util.List; " + 11.384 + "class Test { private void method() { List<? extends List<? extends String>> l; } }", 11.385 + 11.386 + Arrays.asList("List<? extends List<? extends String>> l;", 11.387 + "List<? extends List<? extends String>>", 11.388 + "List", 11.389 + "? extends List<? extends String>", 11.390 + "List<? extends String>", 11.391 + "List", 11.392 + "? extends String", 11.393 + "String")); 11.394 + performWildcardPositionsTest("package test; import java.util.List; " + 11.395 + "class Test { private void method() { List<? super List<? super String>> l; } }", 11.396 + 11.397 + Arrays.asList("List<? super List<? super String>> l;", 11.398 + "List<? super List<? super String>>", 11.399 + "List", 11.400 + "? super List<? super String>", 11.401 + "List<? super String>", 11.402 + "List", 11.403 + "? super String", 11.404 + "String")); 11.405 + performWildcardPositionsTest("package test; import java.util.List; " + 11.406 + "class Test { private void method() { List<? super List<?>> l; } }", 11.407 + 11.408 + Arrays.asList("List<? super List<?>> l;", 11.409 + "List<? super List<?>>", 11.410 + "List", 11.411 + "? super List<?>", 11.412 + "List<?>", 11.413 + "List", 11.414 + "?")); 11.415 + performWildcardPositionsTest("package test; import java.util.List; " + 11.416 + "class Test { private void method() { " + 11.417 + "List<? extends List<? extends List<? extends String>>> l; } }", 11.418 + 11.419 + Arrays.asList("List<? extends List<? extends List<? extends String>>> l;", 11.420 + "List<? extends List<? extends List<? extends String>>>", 11.421 + "List", 11.422 + "? extends List<? extends List<? extends String>>", 11.423 + "List<? extends List<? extends String>>", 11.424 + "List", 11.425 + "? extends List<? extends String>", 11.426 + "List<? extends String>", 11.427 + "List", 11.428 + "? extends String", 11.429 + "String")); 11.430 + performWildcardPositionsTest("package test; import java.util.List; " + 11.431 + "class Test { private void method() { " + 11.432 + "List<? extends List<? extends List<? extends String >>> l; } }", 11.433 + Arrays.asList("List<? extends List<? extends List<? extends String >>> l;", 11.434 + "List<? extends List<? extends List<? extends String >>>", 11.435 + "List", 11.436 + "? extends List<? extends List<? extends String >>", 11.437 + "List<? extends List<? extends String >>", 11.438 + "List", 11.439 + "? extends List<? extends String >", 11.440 + "List<? extends String >", 11.441 + "List", 11.442 + "? extends String", 11.443 + "String")); 11.444 + } 11.445 + 11.446 + public void performWildcardPositionsTest(final String code, 11.447 + List<String> golden) throws IOException { 11.448 + 11.449 + final List<Diagnostic<? extends JavaFileObject>> errors = 11.450 + new LinkedList<Diagnostic<? extends JavaFileObject>>(); 11.451 + 11.452 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 11.453 + new DiagnosticListener<JavaFileObject>() { 11.454 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 11.455 + errors.add(diagnostic); 11.456 + } 11.457 + }, null, null, Arrays.asList(new MyFileObject(code))); 11.458 + 11.459 + final CompilationUnitTree cut = ct.parse().iterator().next(); 11.460 + final List<String> content = new LinkedList<String>(); 11.461 + final Trees trees = Trees.instance(ct); 11.462 + 11.463 + new TreeScanner<Void, Void>() { 11.464 + @Override 11.465 + public Void scan(Tree node, Void p) { 11.466 + if (node == null) { 11.467 + return null; 11.468 + } 11.469 + long start = trees.getSourcePositions().getStartPosition(cut, node); 11.470 + 11.471 + if (start == (-1)) { 11.472 + return null; //synthetic tree 11.473 + } 11.474 + long end = trees.getSourcePositions().getEndPosition(cut, node); 11.475 + String s = code.substring((int) start, (int) end); 11.476 + content.add(s); 11.477 + 11.478 + return super.scan(node, p); 11.479 + } 11.480 + }.scan(((MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0)).getBody().getStatements().get(0), null); 11.481 + 11.482 + assertEquals("performWildcardPositionsTest",golden.toString(), 11.483 + content.toString()); 11.484 + } 11.485 + 11.486 + public void testStartPositionForMethodWithoutModifiers() throws IOException { 11.487 + 11.488 + String code = "package t; class Test { <T> void t() {} }"; 11.489 + 11.490 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.491 + null, Arrays.asList(new MyFileObject(code))); 11.492 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.493 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.494 + MethodTree mt = (MethodTree) clazz.getMembers().get(0); 11.495 + Trees t = Trees.instance(ct); 11.496 + int start = (int) t.getSourcePositions().getStartPosition(cut, mt); 11.497 + int end = (int) t.getSourcePositions().getEndPosition(cut, mt); 11.498 + 11.499 + assertEquals("testStartPositionForMethodWithoutModifiers", 11.500 + "<T> void t() {}", code.substring(start, end)); 11.501 + } 11.502 + 11.503 + public void testStartPositionEnumConstantInit() throws IOException { 11.504 + 11.505 + String code = "package t; enum Test { AAA; }"; 11.506 + 11.507 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.508 + null, Arrays.asList(new MyFileObject(code))); 11.509 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.510 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 11.511 + VariableTree enumAAA = (VariableTree) clazz.getMembers().get(0); 11.512 + Trees t = Trees.instance(ct); 11.513 + int start = (int) t.getSourcePositions().getStartPosition(cut, 11.514 + enumAAA.getInitializer()); 11.515 + 11.516 + assertEquals("testStartPositionEnumConstantInit", -1, start); 11.517 + } 11.518 + 11.519 + public void testVariableInIfThen1() throws IOException { 11.520 + 11.521 + String code = "package t; class Test { " + 11.522 + "private static void t(String name) { " + 11.523 + "if (name != null) String nn = name.trim(); } }"; 11.524 + 11.525 + DiagnosticCollector<JavaFileObject> coll = 11.526 + new DiagnosticCollector<JavaFileObject>(); 11.527 + 11.528 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 11.529 + null, Arrays.asList(new MyFileObject(code))); 11.530 + 11.531 + ct.parse(); 11.532 + 11.533 + List<String> codes = new LinkedList<String>(); 11.534 + 11.535 + for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 11.536 + codes.add(d.getCode()); 11.537 + } 11.538 + 11.539 + assertEquals("testVariableInIfThen1", 11.540 + Arrays.<String>asList("compiler.err.variable.not.allowed"), 11.541 + codes); 11.542 + } 11.543 + 11.544 + public void testVariableInIfThen2() throws IOException { 11.545 + 11.546 + String code = "package t; class Test { " + 11.547 + "private static void t(String name) { " + 11.548 + "if (name != null) class X {} } }"; 11.549 + DiagnosticCollector<JavaFileObject> coll = 11.550 + new DiagnosticCollector<JavaFileObject>(); 11.551 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 11.552 + null, Arrays.asList(new MyFileObject(code))); 11.553 + 11.554 + ct.parse(); 11.555 + 11.556 + List<String> codes = new LinkedList<String>(); 11.557 + 11.558 + for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 11.559 + codes.add(d.getCode()); 11.560 + } 11.561 + 11.562 + assertEquals("testVariableInIfThen2", 11.563 + Arrays.<String>asList("compiler.err.class.not.allowed"), codes); 11.564 + } 11.565 + 11.566 + public void testVariableInIfThen3() throws IOException { 11.567 + 11.568 + String code = "package t; class Test { "+ 11.569 + "private static void t(String name) { " + 11.570 + "if (name != null) abstract } }"; 11.571 + DiagnosticCollector<JavaFileObject> coll = 11.572 + new DiagnosticCollector<JavaFileObject>(); 11.573 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 11.574 + null, Arrays.asList(new MyFileObject(code))); 11.575 + 11.576 + ct.parse(); 11.577 + 11.578 + List<String> codes = new LinkedList<String>(); 11.579 + 11.580 + for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 11.581 + codes.add(d.getCode()); 11.582 + } 11.583 + 11.584 + assertEquals("testVariableInIfThen3", 11.585 + Arrays.<String>asList("compiler.err.illegal.start.of.expr"), 11.586 + codes); 11.587 + } 11.588 + 11.589 + //see javac bug #6882235, NB bug #98234: 11.590 + public void testMissingExponent() throws IOException { 11.591 + 11.592 + String code = "\nclass Test { { System.err.println(0e); } }"; 11.593 + 11.594 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.595 + null, Arrays.asList(new MyFileObject(code))); 11.596 + 11.597 + assertNotNull(ct.parse().iterator().next()); 11.598 + } 11.599 + 11.600 + public void testTryResourcePos() throws IOException { 11.601 + 11.602 + final String code = "package t; class Test { " + 11.603 + "{ try (java.io.InputStream in = null) { } } }"; 11.604 + 11.605 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.606 + null, Arrays.asList(new MyFileObject(code))); 11.607 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.608 + 11.609 + new TreeScanner<Void, Void>() { 11.610 + @Override 11.611 + public Void visitVariable(VariableTree node, Void p) { 11.612 + if ("in".contentEquals(node.getName())) { 11.613 + JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; 11.614 + System.out.println(node.getName() + "," + var.pos); 11.615 + assertEquals("testTryResourcePos", "in = null) { } } }", 11.616 + code.substring(var.pos)); 11.617 + } 11.618 + return super.visitVariable(node, p); 11.619 + } 11.620 + }.scan(cut, null); 11.621 + } 11.622 + 11.623 + public void testVarPos() throws IOException { 11.624 + 11.625 + final String code = "package t; class Test { " + 11.626 + "{ java.io.InputStream in = null; } }"; 11.627 + 11.628 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 11.629 + null, Arrays.asList(new MyFileObject(code))); 11.630 + CompilationUnitTree cut = ct.parse().iterator().next(); 11.631 + 11.632 + new TreeScanner<Void, Void>() { 11.633 + 11.634 + @Override 11.635 + public Void visitVariable(VariableTree node, Void p) { 11.636 + if ("in".contentEquals(node.getName())) { 11.637 + JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; 11.638 + assertEquals("testVarPos","in = null; } }", 11.639 + code.substring(var.pos)); 11.640 + } 11.641 + return super.visitVariable(node, p); 11.642 + } 11.643 + }.scan(cut, null); 11.644 + } 11.645 + 11.646 + void testsNotWorking() throws IOException { 11.647 + 11.648 + // Fails with nb-javac, needs further investigation 11.649 + testPositionBrokenSource126732a(); 11.650 + testPositionBrokenSource126732b(); 11.651 + 11.652 + // Fails, these tests yet to be addressed 11.653 + testVariableInIfThen1(); 11.654 + testVariableInIfThen2(); 11.655 + testPositionForEnumModifiers(); 11.656 + testStartPositionEnumConstantInit(); 11.657 + } 11.658 + void testPositions() throws IOException { 11.659 + testPositionsSane(); 11.660 + testCorrectWilcardPositions(); 11.661 + testPositionAnnotationNoPackage187551(); 11.662 + testPositionForSuperConstructorCalls(); 11.663 + testPreferredPositionForBinaryOp(); 11.664 + testStartPositionForMethodWithoutModifiers(); 11.665 + testVarPos(); 11.666 + testVariableInIfThen3(); 11.667 + testTryResourcePos(); 11.668 + } 11.669 + 11.670 + public static void main(String... args) throws IOException { 11.671 + JavacParserTest jpt = new JavacParserTest("JavacParserTest"); 11.672 + jpt.testPositions(); 11.673 + System.out.println("PASS"); 11.674 + } 11.675 +} 11.676 + 11.677 +abstract class TestCase { 11.678 + 11.679 + void assertEquals(String message, int i, int pos) { 11.680 + if (i != pos) { 11.681 + fail(message); 11.682 + } 11.683 + } 11.684 + 11.685 + void assertFalse(String message, boolean empty) { 11.686 + throw new UnsupportedOperationException("Not yet implemented"); 11.687 + } 11.688 + 11.689 + void assertEquals(String message, int i, long l) { 11.690 + if (i != l) { 11.691 + fail(message + ":" + i + ":" + l); 11.692 + } 11.693 + } 11.694 + 11.695 + void assertEquals(String message, Object o1, Object o2) { 11.696 + System.out.println(o1); 11.697 + System.out.println(o2); 11.698 + if (o1 != null && o2 != null && !o1.equals(o2)) { 11.699 + fail(message); 11.700 + } 11.701 + if (o1 == null && o2 != null) { 11.702 + fail(message); 11.703 + } 11.704 + } 11.705 + 11.706 + void assertNotNull(Object o) { 11.707 + if (o == null) { 11.708 + fail(); 11.709 + } 11.710 + } 11.711 + 11.712 + void fail() { 11.713 + fail("test failed"); 11.714 + } 11.715 + 11.716 + void fail(String message) { 11.717 + throw new RuntimeException(message); 11.718 + } 11.719 +}