Thu, 15 Dec 2011 15:57:51 -0800
Merge
.hgtags | file | annotate | diff | comparison | revisions | |
test/tools/javac/parser/netbeans/JavacParserTest.java | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Thu Dec 15 15:47:47 2011 -0800 1.2 +++ b/.hgtags Thu Dec 15 15:57:51 2011 -0800 1.3 @@ -137,4 +137,5 @@ 1.4 ae25163501bc7477cd907e26a006a6f1b05fdb6d jdk8-b13 1.5 58f1325d72b2bacc901f5189ee5e4e81e81ea657 jdk8-b14 1.6 07599bd780cab1f40da7915e1dc6774629b0cf8c jdk8-b15 1.7 +1cbe86c11ba69521875c0b0357d7540781eb334d jdk8-b17 1.8 ec2c0973cc31e143cffc05ceb63d98fae76f97d4 jdk8-b16
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/share/classes/com/sun/source/tree/LambdaExpressionTree.java Thu Dec 15 15:57:51 2011 -0800 2.3 @@ -0,0 +1,56 @@ 2.4 +/* 2.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. Oracle designates this 2.11 + * particular file as subject to the "Classpath" exception as provided 2.12 + * by Oracle in the LICENSE file that accompanied this code. 2.13 + * 2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.17 + * version 2 for more details (a copy is included in the LICENSE file that 2.18 + * accompanied this code). 2.19 + * 2.20 + * You should have received a copy of the GNU General Public License version 2.21 + * 2 along with this work; if not, write to the Free Software Foundation, 2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.23 + * 2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.25 + * or visit www.oracle.com if you need additional information or have any 2.26 + * questions. 2.27 + */ 2.28 + 2.29 +package com.sun.source.tree; 2.30 + 2.31 +import java.util.List; 2.32 + 2.33 +/** 2.34 + * A tree node for a lambda expression. 2.35 + * 2.36 + * For example: 2.37 + * <pre> 2.38 + * ()->{} 2.39 + * (List<String> ls)->ls.size() 2.40 + * (x,y)-> { return x + y; } 2.41 + * </pre> 2.42 + */ 2.43 +public interface LambdaExpressionTree extends ExpressionTree { 2.44 + 2.45 + /** 2.46 + * Lambda expressions come in two forms: (i) expression lambdas, whose body 2.47 + * is an expression, and (ii) statement lambdas, whose body is a block 2.48 + */ 2.49 + public enum BodyKind { 2.50 + /** enum constant for expression lambdas */ 2.51 + EXPRESSION, 2.52 + /** enum constant for statement lambdas */ 2.53 + STATEMENT; 2.54 + } 2.55 + 2.56 + List<? extends VariableTree> getParameters(); 2.57 + Tree getBody(); 2.58 + BodyKind getBodyKind(); 2.59 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/share/classes/com/sun/source/tree/MemberReferenceTree.java Thu Dec 15 15:57:51 2011 -0800 3.3 @@ -0,0 +1,58 @@ 3.4 +/* 3.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. Oracle designates this 3.11 + * particular file as subject to the "Classpath" exception as provided 3.12 + * by Oracle in the LICENSE file that accompanied this code. 3.13 + * 3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.17 + * version 2 for more details (a copy is included in the LICENSE file that 3.18 + * accompanied this code). 3.19 + * 3.20 + * You should have received a copy of the GNU General Public License version 3.21 + * 2 along with this work; if not, write to the Free Software Foundation, 3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.23 + * 3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.25 + * or visit www.oracle.com if you need additional information or have any 3.26 + * questions. 3.27 + */ 3.28 + 3.29 +package com.sun.source.tree; 3.30 + 3.31 +import java.util.List; 3.32 + 3.33 +import javax.lang.model.element.Name; 3.34 + 3.35 +/** 3.36 + * A tree node for a member reference expression. 3.37 + * 3.38 + * For example: 3.39 + * <pre> 3.40 + * <em>expression</em> # <em>[ identifier | new ]</em> 3.41 + * </pre> 3.42 + * 3.43 + * @see JSR 292 3.44 + */ 3.45 +public interface MemberReferenceTree extends ExpressionTree { 3.46 + 3.47 + /** 3.48 + * There are two kinds of member references: (i) method references and 3.49 + * (ii) constructor references 3.50 + */ 3.51 + public enum ReferenceMode { 3.52 + /** enum constant for method references */ 3.53 + INVOKE, 3.54 + /** enum constant for constructor references */ 3.55 + NEW 3.56 + } 3.57 + ReferenceMode getMode(); 3.58 + ExpressionTree getQualifierExpression(); 3.59 + Name getName(); 3.60 + List<? extends ExpressionTree> getTypeArguments(); 3.61 +}
4.1 --- a/src/share/classes/com/sun/source/tree/Tree.java Thu Dec 15 15:47:47 2011 -0800 4.2 +++ b/src/share/classes/com/sun/source/tree/Tree.java Thu Dec 15 15:57:51 2011 -0800 4.3 @@ -132,6 +132,11 @@ 4.4 MEMBER_SELECT(MemberSelectTree.class), 4.5 4.6 /** 4.7 + * Used for instances of {@link MemberReferenceTree}. 4.8 + */ 4.9 + MEMBER_REFERENCE(MemberReferenceTree.class), 4.10 + 4.11 + /** 4.12 * Used for instances of {@link ForLoopTree}. 4.13 */ 4.14 FOR_LOOP(ForLoopTree.class), 4.15 @@ -187,6 +192,11 @@ 4.16 NEW_CLASS(NewClassTree.class), 4.17 4.18 /** 4.19 + * Used for instances of {@link LambdaExpressionTree}. 4.20 + */ 4.21 + LAMBDA_EXPRESSION(LambdaExpressionTree.class), 4.22 + 4.23 + /** 4.24 * Used for instances of {@link ParenthesizedTree}. 4.25 */ 4.26 PARENTHESIZED(ParenthesizedTree.class),
5.1 --- a/src/share/classes/com/sun/source/tree/TreeVisitor.java Thu Dec 15 15:47:47 2011 -0800 5.2 +++ b/src/share/classes/com/sun/source/tree/TreeVisitor.java Thu Dec 15 15:57:51 2011 -0800 5.3 @@ -85,9 +85,11 @@ 5.4 R visitModifiers(ModifiersTree node, P p); 5.5 R visitNewArray(NewArrayTree node, P p); 5.6 R visitNewClass(NewClassTree node, P p); 5.7 + R visitLambdaExpression(LambdaExpressionTree node, P p); 5.8 R visitParenthesized(ParenthesizedTree node, P p); 5.9 R visitReturn(ReturnTree node, P p); 5.10 R visitMemberSelect(MemberSelectTree node, P p); 5.11 + R visitMemberReference(MemberReferenceTree node, P p); 5.12 R visitEmptyStatement(EmptyStatementTree node, P p); 5.13 R visitSwitch(SwitchTree node, P p); 5.14 R visitSynchronized(SynchronizedTree node, P p);
6.1 --- a/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Thu Dec 15 15:47:47 2011 -0800 6.2 +++ b/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java Thu Dec 15 15:57:51 2011 -0800 6.3 @@ -172,6 +172,10 @@ 6.4 return defaultAction(node, p); 6.5 } 6.6 6.7 + public R visitLambdaExpression(LambdaExpressionTree node, P p) { 6.8 + return defaultAction(node, p); 6.9 + } 6.10 + 6.11 public R visitParenthesized(ParenthesizedTree node, P p) { 6.12 return defaultAction(node, p); 6.13 } 6.14 @@ -208,6 +212,10 @@ 6.15 return defaultAction(node, p); 6.16 } 6.17 6.18 + public R visitMemberReference(MemberReferenceTree node, P p) { 6.19 + return defaultAction(node, p); 6.20 + } 6.21 + 6.22 public R visitIdentifier(IdentifierTree node, P p) { 6.23 return defaultAction(node, p); 6.24 }
7.1 --- a/src/share/classes/com/sun/source/util/TreeScanner.java Thu Dec 15 15:47:47 2011 -0800 7.2 +++ b/src/share/classes/com/sun/source/util/TreeScanner.java Thu Dec 15 15:57:51 2011 -0800 7.3 @@ -285,6 +285,12 @@ 7.4 return r; 7.5 } 7.6 7.7 + public R visitLambdaExpression(LambdaExpressionTree node, P p) { 7.8 + R r = scan(node.getParameters(), p); 7.9 + r = scanAndReduce(node.getBody(), p, r); 7.10 + return r; 7.11 + } 7.12 + 7.13 public R visitParenthesized(ParenthesizedTree node, P p) { 7.14 return scan(node.getExpression(), p); 7.15 } 7.16 @@ -333,6 +339,12 @@ 7.17 return scan(node.getExpression(), p); 7.18 } 7.19 7.20 + public R visitMemberReference(MemberReferenceTree node, P p) { 7.21 + R r = scan(node.getQualifierExpression(), p); 7.22 + r = scanAndReduce(node.getTypeArguments(), p, r); 7.23 + return r; 7.24 + } 7.25 + 7.26 public R visitIdentifier(IdentifierTree node, P p) { 7.27 return null; 7.28 }
8.1 --- a/src/share/classes/com/sun/tools/javac/code/Source.java Thu Dec 15 15:47:47 2011 -0800 8.2 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java Thu Dec 15 15:57:51 2011 -0800 8.3 @@ -194,6 +194,12 @@ 8.4 public boolean allowObjectToPrimitiveCast() { 8.5 return compareTo(JDK1_7) >= 0; 8.6 } 8.7 + public boolean allowLambda() { 8.8 + return compareTo(JDK1_8) >= 0; 8.9 + } 8.10 + public boolean allowMethodReferences() { 8.11 + return compareTo(JDK1_8) >= 0; 8.12 + } 8.13 public static SourceVersion toSourceVersion(Source source) { 8.14 switch(source) { 8.15 case JDK1_2:
9.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Dec 15 15:47:47 2011 -0800 9.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Dec 15 15:57:51 2011 -0800 9.3 @@ -1975,6 +1975,16 @@ 9.4 result = check(tree, owntype, VAL, pkind, pt); 9.5 } 9.6 9.7 + @Override 9.8 + public void visitLambda(JCLambda that) { 9.9 + throw new UnsupportedOperationException("Lambda expression not supported yet"); 9.10 + } 9.11 + 9.12 + @Override 9.13 + public void visitReference(JCMemberReference that) { 9.14 + throw new UnsupportedOperationException("Member references not supported yet"); 9.15 + } 9.16 + 9.17 public void visitParens(JCParens tree) { 9.18 Type owntype = attribTree(tree.expr, env, pkind, pt); 9.19 result = check(tree, owntype, pkind, pkind, pt);
10.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Thu Dec 15 15:47:47 2011 -0800 10.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Thu Dec 15 15:57:51 2011 -0800 10.3 @@ -637,6 +637,10 @@ 10.4 lexError(pos, "unclosed.str.lit"); 10.5 } 10.6 break loop; 10.7 + case '#': 10.8 + reader.scanChar(); 10.9 + tk = TokenKind.HASH; 10.10 + break loop; 10.11 default: 10.12 if (isSpecial(reader.ch)) { 10.13 scanOperator();
11.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Dec 15 15:47:47 2011 -0800 11.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Dec 15 15:57:51 2011 -0800 11.3 @@ -27,6 +27,8 @@ 11.4 11.5 import java.util.*; 11.6 11.7 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 11.8 + 11.9 import com.sun.tools.javac.code.*; 11.10 import com.sun.tools.javac.parser.Tokens.*; 11.11 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; 11.12 @@ -110,6 +112,10 @@ 11.13 this.allowDiamond = source.allowDiamond(); 11.14 this.allowMulticatch = source.allowMulticatch(); 11.15 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true); 11.16 + this.allowLambda = source.allowLambda() && 11.17 + fac.options.isSet("allowLambda"); 11.18 + this.allowMethodReferences = source.allowMethodReferences() && 11.19 + fac.options.isSet("allowMethodReferences"); 11.20 this.keepDocComments = keepDocComments; 11.21 docComments = keepDocComments ? new HashMap<JCTree,String>() : null; 11.22 this.keepLineMap = keepLineMap; 11.23 @@ -166,6 +172,14 @@ 11.24 */ 11.25 boolean allowStringFolding; 11.26 11.27 + /** Switch: should we recognize lambda expressions? 11.28 + */ 11.29 + boolean allowLambda; 11.30 + 11.31 + /** Switch: should we allow method/constructor references? 11.32 + */ 11.33 + boolean allowMethodReferences; 11.34 + 11.35 /** Switch: should we keep docComments? 11.36 */ 11.37 boolean keepDocComments; 11.38 @@ -203,6 +217,30 @@ 11.39 token = S.token(); 11.40 } 11.41 11.42 + protected boolean peekToken(TokenKind tk) { 11.43 + return S.token(1).kind == tk; 11.44 + } 11.45 + 11.46 + protected boolean peekToken(TokenKind tk1, TokenKind tk2) { 11.47 + return S.token(1).kind == tk1 && 11.48 + S.token(2).kind == tk2; 11.49 + } 11.50 + 11.51 + protected boolean peekToken(TokenKind tk1, TokenKind tk2, TokenKind tk3) { 11.52 + return S.token(1).kind == tk1 && 11.53 + S.token(2).kind == tk2 && 11.54 + S.token(3).kind == tk3; 11.55 + } 11.56 + 11.57 + protected boolean peekToken(TokenKind... kinds) { 11.58 + for (int lookahead = 0 ; lookahead < kinds.length ; lookahead++) { 11.59 + if (S.token(lookahead + 1).kind != kinds[lookahead]) { 11.60 + return false; 11.61 + } 11.62 + } 11.63 + return true; 11.64 + } 11.65 + 11.66 /* ---------- error recovery -------------- */ 11.67 11.68 private JCErroneous errorTree; 11.69 @@ -749,7 +787,7 @@ 11.70 top++; 11.71 topOp = token; 11.72 nextToken(); 11.73 - odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3(); 11.74 + odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3NoParams(); 11.75 while (top > 0 && prec(topOp.kind) >= prec(token.kind)) { 11.76 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1], 11.77 odStack[top]); 11.78 @@ -849,7 +887,10 @@ 11.79 * | [TypeArguments] THIS [Arguments] 11.80 * | [TypeArguments] SUPER SuperSuffix 11.81 * | NEW [TypeArguments] Creator 11.82 + * | "(" Arguments ")" "->" ( Expression | Block ) 11.83 + * | Ident "->" ( Expression | Block ) 11.84 * | Ident { "." Ident } 11.85 + * | Expression3 MemberReferenceSuffix 11.86 * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 11.87 * | Arguments 11.88 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 11.89 @@ -890,60 +931,87 @@ 11.90 mode = EXPR; 11.91 t = literal(names.hyphen, pos); 11.92 } else { 11.93 - t = term3(); 11.94 + t = term3NoParams(); 11.95 return F.at(pos).Unary(unoptag(tk), t); 11.96 } 11.97 } else return illegal(); 11.98 break; 11.99 case LPAREN: 11.100 if (typeArgs == null && (mode & EXPR) != 0) { 11.101 - nextToken(); 11.102 - mode = EXPR | TYPE | NOPARAMS; 11.103 - t = term3(); 11.104 - if ((mode & TYPE) != 0 && token.kind == LT) { 11.105 - // Could be a cast to a parameterized type 11.106 - JCTree.Tag op = JCTree.Tag.LT; 11.107 - int pos1 = token.pos; 11.108 + if (peekToken(FINAL) || 11.109 + peekToken(RPAREN) || 11.110 + peekToken(IDENTIFIER, COMMA) || 11.111 + peekToken(IDENTIFIER, RPAREN, ARROW)) { 11.112 + //implicit n-ary lambda 11.113 + t = lambdaExpressionOrStatement(true, peekToken(FINAL), pos); 11.114 + break; 11.115 + } else { 11.116 nextToken(); 11.117 - mode &= (EXPR | TYPE); 11.118 - mode |= TYPEARG; 11.119 - JCExpression t1 = term3(); 11.120 - if ((mode & TYPE) != 0 && 11.121 - (token.kind == COMMA || token.kind == GT)) { 11.122 - mode = TYPE; 11.123 - ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 11.124 - args.append(t1); 11.125 - while (token.kind == COMMA) { 11.126 + mode = EXPR | TYPE; 11.127 + t = term3NoParams(); 11.128 + if ((mode & TYPE) != 0 && token.kind == LT) { 11.129 + // Could be a cast to a parameterized type 11.130 + JCTree.Tag op = JCTree.Tag.LT; 11.131 + int pos1 = token.pos; 11.132 + nextToken(); 11.133 + mode &= (EXPR | TYPE); 11.134 + mode |= TYPEARG; 11.135 + JCExpression t1 = term3(); 11.136 + if ((mode & TYPE) != 0 && 11.137 + (token.kind == COMMA || token.kind == GT)) { 11.138 + mode = TYPE; 11.139 + ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 11.140 + args.append(t1); 11.141 + while (token.kind == COMMA) { 11.142 + nextToken(); 11.143 + args.append(typeArgument()); 11.144 + } 11.145 + accept(GT); 11.146 + t = toP(F.at(pos1).TypeApply(t, args.toList())); 11.147 + checkGenerics(); 11.148 + mode = EXPR | TYPE; //could be a lambda or a method ref or a cast to a type 11.149 + t = term3Rest(t, typeArgs); 11.150 + if (token.kind == IDENTIFIER || token.kind == ELLIPSIS) { 11.151 + //explicit lambda (w/ generic type) 11.152 + mode = EXPR; 11.153 + JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER); 11.154 + if (token.kind == ELLIPSIS) { 11.155 + mods.flags = Flags.VARARGS; 11.156 + t = to(F.at(token.pos).TypeArray(t)); 11.157 + nextToken(); 11.158 + } 11.159 + t = lambdaExpressionOrStatement(variableDeclaratorId(mods, t), pos); 11.160 + break; 11.161 + } 11.162 + } else { 11.163 + Assert.check((mode & EXPR) != 0); 11.164 + mode = EXPR; 11.165 + JCExpression e = term2Rest(t1, TreeInfo.shiftPrec); 11.166 + t = F.at(pos1).Binary(op, t, e); 11.167 + t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 11.168 + } 11.169 + } else if ((mode & TYPE) != 0 && 11.170 + (token.kind == IDENTIFIER || token.kind == ELLIPSIS)) { 11.171 + //explicit lambda (w/ non-generic type) 11.172 + mode = EXPR; 11.173 + JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER); 11.174 + if (token.kind == ELLIPSIS) { 11.175 + mods.flags = Flags.VARARGS; 11.176 + t = to(F.at(token.pos).TypeArray(t)); 11.177 nextToken(); 11.178 - args.append(typeArgument()); 11.179 } 11.180 - accept(GT); 11.181 - t = toP(F.at(pos1).TypeApply(t, args.toList())); 11.182 - checkGenerics(); 11.183 - while (token.kind == DOT) { 11.184 - nextToken(); 11.185 - mode = TYPE; 11.186 - t = toP(F.at(token.pos).Select(t, ident())); 11.187 - t = typeArgumentsOpt(t); 11.188 - } 11.189 - t = bracketsOpt(toP(t)); 11.190 - } else if ((mode & EXPR) != 0) { 11.191 - mode = EXPR; 11.192 - JCExpression e = term2Rest(t1, TreeInfo.shiftPrec); 11.193 - t = F.at(pos1).Binary(op, t, e); 11.194 + t = lambdaExpressionOrStatement(variableDeclaratorId(mods, t), pos); 11.195 + break; 11.196 + } else { 11.197 t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 11.198 - } else { 11.199 - accept(GT); 11.200 } 11.201 } 11.202 - else { 11.203 - t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 11.204 - } 11.205 + 11.206 accept(RPAREN); 11.207 lastmode = mode; 11.208 mode = EXPR; 11.209 if ((lastmode & EXPR) == 0) { 11.210 - JCExpression t1 = term3(); 11.211 + JCExpression t1 = term3NoParams(); 11.212 return F.at(pos).TypeCast(t, t1); 11.213 } else if ((lastmode & TYPE) != 0) { 11.214 switch (token.kind) { 11.215 @@ -953,14 +1021,16 @@ 11.216 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: 11.217 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: 11.218 case TRUE: case FALSE: case NULL: 11.219 - case NEW: case IDENTIFIER: case ASSERT: case ENUM: 11.220 + case NEW: case IDENTIFIER: case ASSERT: case ENUM: 11.221 case BYTE: case SHORT: case CHAR: case INT: 11.222 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: 11.223 - JCExpression t1 = term3(); 11.224 + JCExpression t1 = term3NoParams(); 11.225 return F.at(pos).TypeCast(t, t1); 11.226 } 11.227 } 11.228 - } else return illegal(); 11.229 + } else { 11.230 + return illegal(); 11.231 + } 11.232 t = toP(F.at(pos).Parens(t)); 11.233 break; 11.234 case THIS: 11.235 @@ -1003,75 +1073,122 @@ 11.236 break; 11.237 case IDENTIFIER: case ASSERT: case ENUM: 11.238 if (typeArgs != null) return illegal(); 11.239 - t = toP(F.at(token.pos).Ident(ident())); 11.240 - loop: while (true) { 11.241 - pos = token.pos; 11.242 - switch (token.kind) { 11.243 - case LBRACKET: 11.244 - nextToken(); 11.245 - if (token.kind == RBRACKET) { 11.246 + if ((mode & EXPR) != 0 && peekToken(ARROW)) { 11.247 + t = lambdaExpressionOrStatement(false, false, pos); 11.248 + } else { 11.249 + t = toP(F.at(token.pos).Ident(ident())); 11.250 + loop: while (true) { 11.251 + pos = token.pos; 11.252 + switch (token.kind) { 11.253 + case LBRACKET: 11.254 nextToken(); 11.255 - t = bracketsOpt(t); 11.256 - t = toP(F.at(pos).TypeArray(t)); 11.257 - t = bracketsSuffix(t); 11.258 - } else { 11.259 + if (token.kind == RBRACKET) { 11.260 + nextToken(); 11.261 + t = bracketsOpt(t); 11.262 + t = toP(F.at(pos).TypeArray(t)); 11.263 + t = bracketsSuffix(t); 11.264 + } else { 11.265 + if ((mode & EXPR) != 0) { 11.266 + mode = EXPR; 11.267 + JCExpression t1 = term(); 11.268 + t = to(F.at(pos).Indexed(t, t1)); 11.269 + } 11.270 + accept(RBRACKET); 11.271 + } 11.272 + break loop; 11.273 + case LPAREN: 11.274 if ((mode & EXPR) != 0) { 11.275 mode = EXPR; 11.276 - JCExpression t1 = term(); 11.277 - t = to(F.at(pos).Indexed(t, t1)); 11.278 + t = arguments(typeArgs, t); 11.279 + typeArgs = null; 11.280 } 11.281 - accept(RBRACKET); 11.282 + break loop; 11.283 + case DOT: 11.284 + nextToken(); 11.285 + int oldmode = mode; 11.286 + mode &= ~NOPARAMS; 11.287 + typeArgs = typeArgumentsOpt(EXPR); 11.288 + mode = oldmode; 11.289 + if ((mode & EXPR) != 0) { 11.290 + switch (token.kind) { 11.291 + case CLASS: 11.292 + if (typeArgs != null) return illegal(); 11.293 + mode = EXPR; 11.294 + t = to(F.at(pos).Select(t, names._class)); 11.295 + nextToken(); 11.296 + break loop; 11.297 + case THIS: 11.298 + if (typeArgs != null) return illegal(); 11.299 + mode = EXPR; 11.300 + t = to(F.at(pos).Select(t, names._this)); 11.301 + nextToken(); 11.302 + break loop; 11.303 + case SUPER: 11.304 + mode = EXPR; 11.305 + t = to(F.at(pos).Select(t, names._super)); 11.306 + t = superSuffix(typeArgs, t); 11.307 + typeArgs = null; 11.308 + break loop; 11.309 + case NEW: 11.310 + if (typeArgs != null) return illegal(); 11.311 + mode = EXPR; 11.312 + int pos1 = token.pos; 11.313 + nextToken(); 11.314 + if (token.kind == LT) typeArgs = typeArguments(false); 11.315 + t = innerCreator(pos1, typeArgs, t); 11.316 + typeArgs = null; 11.317 + break loop; 11.318 + } 11.319 + } 11.320 + // typeArgs saved for next loop iteration. 11.321 + t = toP(F.at(pos).Select(t, ident())); 11.322 + break; 11.323 +// case LT: 11.324 +// if ((mode & (TYPE | NOPARAMS)) == 0) { 11.325 +// //could be an unbound method reference whose qualifier 11.326 +// //is a generic type i.e. A<S>#m 11.327 +// mode = EXPR | TYPE; 11.328 +// JCTree.Tag op = JCTree.Tag.LT; 11.329 +// int pos1 = token.pos; 11.330 +// nextToken(); 11.331 +// mode |= EXPR | TYPE | TYPEARG; 11.332 +// JCExpression t1 = term3(); 11.333 +// if ((mode & TYPE) != 0 && 11.334 +// (token.kind == COMMA || token.kind == GT)) { 11.335 +// mode = TYPE; 11.336 +// ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 11.337 +// args.append(t1); 11.338 +// while (token.kind == COMMA) { 11.339 +// nextToken(); 11.340 +// args.append(typeArgument()); 11.341 +// } 11.342 +// accept(GT); 11.343 +// t = toP(F.at(pos1).TypeApply(t, args.toList())); 11.344 +// checkGenerics(); 11.345 +// while (token.kind == DOT) { 11.346 +// nextToken(); 11.347 +// mode = TYPE; 11.348 +// t = toP(F.at(token.pos).Select(t, ident())); 11.349 +// t = typeArgumentsOpt(t); 11.350 +// } 11.351 +// if (token.kind != HASH) { 11.352 +// //method reference expected here 11.353 +// t = illegal(); 11.354 +// } 11.355 +// mode = EXPR; 11.356 +// break; 11.357 +// } else if ((mode & EXPR) != 0) { 11.358 +// //rollback - it was a binary expression 11.359 +// mode = EXPR; 11.360 +// JCExpression e = term2Rest(t1, TreeInfo.shiftPrec); 11.361 +// t = F.at(pos1).Binary(op, t, e); 11.362 +// t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 11.363 +// } 11.364 +// } 11.365 +// break loop; 11.366 + default: 11.367 + break loop; 11.368 } 11.369 - break loop; 11.370 - case LPAREN: 11.371 - if ((mode & EXPR) != 0) { 11.372 - mode = EXPR; 11.373 - t = arguments(typeArgs, t); 11.374 - typeArgs = null; 11.375 - } 11.376 - break loop; 11.377 - case DOT: 11.378 - nextToken(); 11.379 - int oldmode = mode; 11.380 - mode &= ~NOPARAMS; 11.381 - typeArgs = typeArgumentsOpt(EXPR); 11.382 - mode = oldmode; 11.383 - if ((mode & EXPR) != 0) { 11.384 - switch (token.kind) { 11.385 - case CLASS: 11.386 - if (typeArgs != null) return illegal(); 11.387 - mode = EXPR; 11.388 - t = to(F.at(pos).Select(t, names._class)); 11.389 - nextToken(); 11.390 - break loop; 11.391 - case THIS: 11.392 - if (typeArgs != null) return illegal(); 11.393 - mode = EXPR; 11.394 - t = to(F.at(pos).Select(t, names._this)); 11.395 - nextToken(); 11.396 - break loop; 11.397 - case SUPER: 11.398 - mode = EXPR; 11.399 - t = to(F.at(pos).Select(t, names._super)); 11.400 - t = superSuffix(typeArgs, t); 11.401 - typeArgs = null; 11.402 - break loop; 11.403 - case NEW: 11.404 - if (typeArgs != null) return illegal(); 11.405 - mode = EXPR; 11.406 - int pos1 = token.pos; 11.407 - nextToken(); 11.408 - if (token.kind == LT) typeArgs = typeArguments(false); 11.409 - t = innerCreator(pos1, typeArgs, t); 11.410 - typeArgs = null; 11.411 - break loop; 11.412 - } 11.413 - } 11.414 - // typeArgs saved for next loop iteration. 11.415 - t = toP(F.at(pos).Select(t, ident())); 11.416 - break; 11.417 - default: 11.418 - break loop; 11.419 } 11.420 } 11.421 if (typeArgs != null) illegal(); 11.422 @@ -1105,6 +1222,19 @@ 11.423 default: 11.424 return illegal(); 11.425 } 11.426 + return term3Rest(t, typeArgs); 11.427 + } 11.428 + 11.429 + JCExpression term3NoParams() { 11.430 + try { 11.431 + mode |= NOPARAMS; 11.432 + return term3(); 11.433 + } finally { 11.434 + mode &= ~NOPARAMS; 11.435 + } 11.436 + } 11.437 + 11.438 + JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) { 11.439 if (typeArgs != null) illegal(); 11.440 while (true) { 11.441 int pos1 = token.pos; 11.442 @@ -1149,6 +1279,11 @@ 11.443 t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 11.444 typeArgs = null; 11.445 } 11.446 + } else if ((mode & EXPR) != 0 && token.kind == HASH) { 11.447 + mode = EXPR; 11.448 + if (typeArgs != null) return illegal(); 11.449 + accept(HASH); 11.450 + t = memberReferenceSuffix(pos1, t); 11.451 } else { 11.452 break; 11.453 } 11.454 @@ -1162,12 +1297,59 @@ 11.455 return toP(t); 11.456 } 11.457 11.458 + JCExpression lambdaExpressionOrStatement(JCVariableDecl firstParam, int pos) { 11.459 + ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 11.460 + params.append(firstParam); 11.461 + JCVariableDecl lastParam = firstParam; 11.462 + while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) { 11.463 + nextToken(); 11.464 + params.append(lastParam = formalParameter()); 11.465 + } 11.466 + accept(RPAREN); 11.467 + return lambdaExpressionOrStatementRest(params.toList(), pos); 11.468 + } 11.469 + 11.470 + JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { 11.471 + List<JCVariableDecl> params = explicitParams ? 11.472 + formalParameters() : 11.473 + implicitParameters(hasParens); 11.474 + 11.475 + return lambdaExpressionOrStatementRest(params, pos); 11.476 + } 11.477 + 11.478 + JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) { 11.479 + if (token.kind != ARROW) { 11.480 + //better error recovery 11.481 + return F.at(pos).Erroneous(args); 11.482 + } 11.483 + 11.484 + checkLambda(); 11.485 + accept(ARROW); 11.486 + 11.487 + return token.kind == LBRACE ? 11.488 + lambdaStatement(args, pos, pos) : 11.489 + lambdaExpression(args, pos); 11.490 + } 11.491 + 11.492 + JCExpression lambdaStatement(List<JCVariableDecl> args, int pos, int pos2) { 11.493 + JCBlock block = block(pos2, 0); 11.494 + return toP(F.at(pos).Lambda(args, block)); 11.495 + } 11.496 + 11.497 + JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) { 11.498 + JCTree expr = parseExpression(); 11.499 + return toP(F.at(pos).Lambda(args, expr)); 11.500 + } 11.501 + 11.502 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 11.503 */ 11.504 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 11.505 nextToken(); 11.506 if (token.kind == LPAREN || typeArgs != null) { 11.507 t = arguments(typeArgs, t); 11.508 + } else if (token.kind == HASH) { 11.509 + if (typeArgs != null) return illegal(); 11.510 + t = memberReferenceSuffix(t); 11.511 } else { 11.512 int pos = token.pos; 11.513 accept(DOT); 11.514 @@ -1377,6 +1559,36 @@ 11.515 return t; 11.516 } 11.517 11.518 + /** 11.519 + * MemberReferenceSuffix = "#" [TypeArguments] Ident 11.520 + * | "#" [TypeArguments] "new" 11.521 + */ 11.522 + JCExpression memberReferenceSuffix(JCExpression t) { 11.523 + int pos1 = token.pos; 11.524 + accept(HASH); 11.525 + return memberReferenceSuffix(pos1, t); 11.526 + } 11.527 + 11.528 + JCExpression memberReferenceSuffix(int pos1, JCExpression t) { 11.529 + checkMethodReferences(); 11.530 + mode = EXPR; 11.531 + List<JCExpression> typeArgs = null; 11.532 + if (token.kind == LT) { 11.533 + typeArgs = typeArguments(false); 11.534 + } 11.535 + Name refName = null; 11.536 + ReferenceMode refMode = null; 11.537 + if (token.kind == NEW) { 11.538 + refMode = ReferenceMode.NEW; 11.539 + refName = names.init; 11.540 + nextToken(); 11.541 + } else { 11.542 + refMode = ReferenceMode.INVOKE; 11.543 + refName = ident(); 11.544 + } 11.545 + return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs)); 11.546 + } 11.547 + 11.548 /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 11.549 */ 11.550 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 11.551 @@ -2392,7 +2604,7 @@ 11.552 * @param mods The modifiers starting the class declaration 11.553 * @param dc The documentation comment for the class, or null. 11.554 */ 11.555 - JCClassDecl classDeclaration(JCModifiers mods, String dc) { 11.556 + protected JCClassDecl classDeclaration(JCModifiers mods, String dc) { 11.557 int pos = token.pos; 11.558 accept(CLASS); 11.559 Name name = ident(); 11.560 @@ -2421,7 +2633,7 @@ 11.561 * @param mods The modifiers starting the interface declaration 11.562 * @param dc The documentation comment for the interface, or null. 11.563 */ 11.564 - JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) { 11.565 + protected JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) { 11.566 int pos = token.pos; 11.567 accept(INTERFACE); 11.568 Name name = ident(); 11.569 @@ -2444,7 +2656,7 @@ 11.570 * @param mods The modifiers starting the enum declaration 11.571 * @param dc The documentation comment for the enum, or null. 11.572 */ 11.573 - JCClassDecl enumDeclaration(JCModifiers mods, String dc) { 11.574 + protected JCClassDecl enumDeclaration(JCModifiers mods, String dc) { 11.575 int pos = token.pos; 11.576 accept(ENUM); 11.577 Name name = ident(); 11.578 @@ -2666,7 +2878,7 @@ 11.579 * ConstructorDeclaratorRest = 11.580 * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody 11.581 */ 11.582 - JCTree methodDeclaratorRest(int pos, 11.583 + protected JCTree methodDeclaratorRest(int pos, 11.584 JCModifiers mods, 11.585 JCExpression type, 11.586 Name name, 11.587 @@ -2779,6 +2991,24 @@ 11.588 return params.toList(); 11.589 } 11.590 11.591 + List<JCVariableDecl> implicitParameters(boolean hasParens) { 11.592 + if (hasParens) { 11.593 + accept(LPAREN); 11.594 + } 11.595 + ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 11.596 + if (token.kind != RPAREN && token.kind != ARROW) { 11.597 + params.append(implicitParameter()); 11.598 + while (token.kind == COMMA) { 11.599 + nextToken(); 11.600 + params.append(implicitParameter()); 11.601 + } 11.602 + } 11.603 + if (hasParens) { 11.604 + accept(RPAREN); 11.605 + } 11.606 + return params.toList(); 11.607 + } 11.608 + 11.609 JCModifiers optFinal(long flags) { 11.610 JCModifiers mods = modifiersOpt(); 11.611 checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED)); 11.612 @@ -2801,6 +3031,11 @@ 11.613 return variableDeclaratorId(mods, type); 11.614 } 11.615 11.616 + protected JCVariableDecl implicitParameter() { 11.617 + JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER); 11.618 + return variableDeclaratorId(mods, null); 11.619 + } 11.620 + 11.621 /* ---------- auxiliary methods -------------- */ 11.622 11.623 void error(int pos, String key, Object ... args) { 11.624 @@ -3024,6 +3259,18 @@ 11.625 allowTWR = true; 11.626 } 11.627 } 11.628 + void checkLambda() { 11.629 + if (!allowLambda) { 11.630 + log.error(token.pos, "lambda.not.supported.in.source", source.name); 11.631 + allowLambda = true; 11.632 + } 11.633 + } 11.634 + void checkMethodReferences() { 11.635 + if (!allowMethodReferences) { 11.636 + log.error(token.pos, "method.references.not.supported.in.source", source.name); 11.637 + allowMethodReferences = true; 11.638 + } 11.639 + } 11.640 11.641 /* 11.642 * a functional source tree and end position mappings
12.1 --- a/src/share/classes/com/sun/tools/javac/parser/Lexer.java Thu Dec 15 15:47:47 2011 -0800 12.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Lexer.java Thu Dec 15 15:57:51 2011 -0800 12.3 @@ -50,6 +50,11 @@ 12.4 Token token(); 12.5 12.6 /** 12.7 + * Return token with given lookahead. 12.8 + */ 12.9 + Token token(int lookahead); 12.10 + 12.11 + /** 12.12 * Return the last character position of the previous token. 12.13 */ 12.14 Token prevToken();
13.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java Thu Dec 15 15:47:47 2011 -0800 13.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java Thu Dec 15 15:57:51 2011 -0800 13.3 @@ -26,8 +26,9 @@ 13.4 package com.sun.tools.javac.parser; 13.5 13.6 import java.nio.*; 13.7 +import java.util.List; 13.8 +import java.util.ArrayList; 13.9 13.10 -import com.sun.tools.javac.util.*; 13.11 import com.sun.tools.javac.util.Position.LineMap; 13.12 import com.sun.tools.javac.parser.JavaTokenizer.*; 13.13 13.14 @@ -53,6 +54,10 @@ 13.15 */ 13.16 private Token prevToken; 13.17 13.18 + /** Buffer of saved tokens (used during lookahead) 13.19 + */ 13.20 + private List<Token> savedTokens = new ArrayList<Token>(); 13.21 + 13.22 private JavaTokenizer tokenizer; 13.23 /** 13.24 * Create a scanner from the input array. This method might 13.25 @@ -80,16 +85,35 @@ 13.26 } 13.27 13.28 public Token token() { 13.29 - return token; 13.30 + return token(0); 13.31 } 13.32 13.33 + public Token token(int lookahead) { 13.34 + if (lookahead == 0) { 13.35 + return token; 13.36 + } else { 13.37 + ensureLookahead(lookahead); 13.38 + return savedTokens.get(lookahead - 1); 13.39 + } 13.40 + } 13.41 + //where 13.42 + private void ensureLookahead(int lookahead) { 13.43 + for (int i = savedTokens.size() ; i < lookahead ; i ++) { 13.44 + savedTokens.add(tokenizer.readToken()); 13.45 + } 13.46 + } 13.47 + 13.48 public Token prevToken() { 13.49 return prevToken; 13.50 } 13.51 13.52 public void nextToken() { 13.53 prevToken = token; 13.54 - token = tokenizer.readToken(); 13.55 + if (!savedTokens.isEmpty()) { 13.56 + token = savedTokens.remove(0); 13.57 + } else { 13.58 + token = tokenizer.readToken(); 13.59 + } 13.60 } 13.61 13.62 public Token split() {
14.1 --- a/src/share/classes/com/sun/tools/javac/parser/Tokens.java Thu Dec 15 15:47:47 2011 -0800 14.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Tokens.java Thu Dec 15 15:57:51 2011 -0800 14.3 @@ -176,6 +176,8 @@ 14.4 TRUE("true", Tag.NAMED), 14.5 FALSE("false", Tag.NAMED), 14.6 NULL("null", Tag.NAMED), 14.7 + ARROW("->"), 14.8 + HASH("#"), 14.9 LPAREN("("), 14.10 RPAREN(")"), 14.11 LBRACE("{"),
15.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Dec 15 15:47:47 2011 -0800 15.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Dec 15 15:57:51 2011 -0800 15.3 @@ -1945,6 +1945,16 @@ 15.4 strings in switch are not supported in -source {0}\n\ 15.5 (use -source 7 or higher to enable strings in switch) 15.6 15.7 +# 0: string 15.8 +compiler.err.lambda.not.supported.in.source=\ 15.9 + lambda expressions are not supported in -source {0}\n\ 15.10 + (use -source 8 or higher to enable lambda expressions) 15.11 + 15.12 +# 0: string 15.13 +compiler.err.method.references.not.supported.in.source=\ 15.14 + method references are not supported in -source {0}\n\ 15.15 + (use -source 8 or higher to enable method references) 15.16 + 15.17 ######################################## 15.18 # Diagnostics for verbose resolution 15.19 # used by Resolve (debug only)
16.1 --- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Dec 15 15:47:47 2011 -0800 16.2 +++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Dec 15 15:57:51 2011 -0800 16.3 @@ -41,6 +41,8 @@ 16.4 import com.sun.tools.javac.code.Symbol.*; 16.5 import com.sun.tools.javac.parser.EndPosTable; 16.6 import com.sun.source.tree.*; 16.7 +import com.sun.source.tree.LambdaExpressionTree.BodyKind; 16.8 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 16.9 16.10 import static com.sun.tools.javac.code.BoundKind.*; 16.11 import static com.sun.tools.javac.tree.JCTree.Tag.*; 16.12 @@ -198,6 +200,10 @@ 16.13 */ 16.14 NEWARRAY, 16.15 16.16 + /** Lambda expression, of type Lambda. 16.17 + */ 16.18 + LAMBDA, 16.19 + 16.20 /** Parenthesized subexpressions, of type Parens. 16.21 */ 16.22 PARENS, 16.23 @@ -222,6 +228,10 @@ 16.24 */ 16.25 SELECT, 16.26 16.27 + /** Member references, of type Reference. 16.28 + */ 16.29 + REFERENCE, 16.30 + 16.31 /** Simple identifiers, of type Ident. 16.32 */ 16.33 IDENT, 16.34 @@ -1487,6 +1497,56 @@ 16.35 } 16.36 16.37 /** 16.38 + * A lambda expression. 16.39 + */ 16.40 + public static class JCLambda extends JCExpression implements LambdaExpressionTree { 16.41 + 16.42 + public List<JCVariableDecl> params; 16.43 + public JCTree body; 16.44 + public Type targetType; 16.45 + public boolean canCompleteNormally = true; 16.46 + public List<Type> inferredThrownTypes; 16.47 + 16.48 + public JCLambda(List<JCVariableDecl> params, 16.49 + JCTree body) { 16.50 + this.params = params; 16.51 + this.body = body; 16.52 + } 16.53 + @Override 16.54 + public Tag getTag() { 16.55 + return LAMBDA; 16.56 + } 16.57 + @Override 16.58 + public void accept(Visitor v) { 16.59 + v.visitLambda(this); 16.60 + } 16.61 + @Override 16.62 + public <R, D> R accept(TreeVisitor<R, D> v, D d) { 16.63 + return v.visitLambdaExpression(this, d); 16.64 + } 16.65 + public Kind getKind() { 16.66 + return Kind.LAMBDA_EXPRESSION; 16.67 + } 16.68 + public JCTree getBody() { 16.69 + return body; 16.70 + } 16.71 + public java.util.List<? extends VariableTree> getParameters() { 16.72 + return params; 16.73 + } 16.74 + @Override 16.75 + public JCLambda setType(Type type) { 16.76 + super.setType(type); 16.77 + return this; 16.78 + } 16.79 + @Override 16.80 + public BodyKind getBodyKind() { 16.81 + return body.hasTag(BLOCK) ? 16.82 + BodyKind.STATEMENT : 16.83 + BodyKind.EXPRESSION; 16.84 + } 16.85 + } 16.86 + 16.87 + /** 16.88 * A parenthesized subexpression ( ... ) 16.89 */ 16.90 public static class JCParens extends JCExpression implements ParenthesizedTree { 16.91 @@ -1747,6 +1807,46 @@ 16.92 } 16.93 16.94 /** 16.95 + * Selects a member expression. 16.96 + */ 16.97 + public static class JCMemberReference extends JCExpression implements MemberReferenceTree { 16.98 + public ReferenceMode mode; 16.99 + public Name name; 16.100 + public JCExpression expr; 16.101 + public List<JCExpression> typeargs; 16.102 + public Type targetType; 16.103 + public Symbol sym; 16.104 + 16.105 + protected JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> typeargs) { 16.106 + this.mode = mode; 16.107 + this.name = name; 16.108 + this.expr = expr; 16.109 + this.typeargs = typeargs; 16.110 + } 16.111 + @Override 16.112 + public void accept(Visitor v) { v.visitReference(this); } 16.113 + 16.114 + public Kind getKind() { return Kind.MEMBER_REFERENCE; } 16.115 + @Override 16.116 + public ReferenceMode getMode() { return mode; } 16.117 + @Override 16.118 + public JCExpression getQualifierExpression() { return expr; } 16.119 + @Override 16.120 + public Name getName() { return name; } 16.121 + @Override 16.122 + public List<JCExpression> getTypeArguments() { return typeargs; } 16.123 + 16.124 + @Override 16.125 + public <R,D> R accept(TreeVisitor<R,D> v, D d) { 16.126 + return v.visitMemberReference(this, d); 16.127 + } 16.128 + @Override 16.129 + public Tag getTag() { 16.130 + return REFERENCE; 16.131 + } 16.132 + } 16.133 + 16.134 + /** 16.135 * An identifier 16.136 * @param idname the name 16.137 * @param sym the symbol 16.138 @@ -2271,6 +2371,7 @@ 16.139 public void visitApply(JCMethodInvocation that) { visitTree(that); } 16.140 public void visitNewClass(JCNewClass that) { visitTree(that); } 16.141 public void visitNewArray(JCNewArray that) { visitTree(that); } 16.142 + public void visitLambda(JCLambda that) { visitTree(that); } 16.143 public void visitParens(JCParens that) { visitTree(that); } 16.144 public void visitAssign(JCAssign that) { visitTree(that); } 16.145 public void visitAssignop(JCAssignOp that) { visitTree(that); } 16.146 @@ -2280,6 +2381,7 @@ 16.147 public void visitTypeTest(JCInstanceOf that) { visitTree(that); } 16.148 public void visitIndexed(JCArrayAccess that) { visitTree(that); } 16.149 public void visitSelect(JCFieldAccess that) { visitTree(that); } 16.150 + public void visitReference(JCMemberReference that) { visitTree(that); } 16.151 public void visitIdent(JCIdent that) { visitTree(that); } 16.152 public void visitLiteral(JCLiteral that) { visitTree(that); } 16.153 public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); }
17.1 --- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java Thu Dec 15 15:47:47 2011 -0800 17.2 +++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java Thu Dec 15 15:57:51 2011 -0800 17.3 @@ -28,6 +28,8 @@ 17.4 import java.io.*; 17.5 import java.util.*; 17.6 17.7 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 17.8 + 17.9 import com.sun.tools.javac.util.*; 17.10 import com.sun.tools.javac.util.List; 17.11 import com.sun.tools.javac.code.*; 17.12 @@ -907,6 +909,17 @@ 17.13 } 17.14 } 17.15 17.16 + public void visitLambda(JCLambda tree) { 17.17 + try { 17.18 + print("("); 17.19 + printExprs(tree.params); 17.20 + print(")->"); 17.21 + printExpr(tree.body); 17.22 + } catch (IOException e) { 17.23 + throw new UncheckedIOException(e); 17.24 + } 17.25 + } 17.26 + 17.27 public void visitParens(JCParens tree) { 17.28 try { 17.29 print("("); 17.30 @@ -1052,6 +1065,21 @@ 17.31 } 17.32 } 17.33 17.34 + public void visitReference(JCMemberReference tree) { 17.35 + try { 17.36 + printExpr(tree.expr); 17.37 + print("#"); 17.38 + if (tree.typeargs != null) { 17.39 + print("<"); 17.40 + printExprs(tree.typeargs); 17.41 + print(">"); 17.42 + } 17.43 + print(tree.getMode() == ReferenceMode.INVOKE ? tree.name : "new"); 17.44 + } catch (IOException e) { 17.45 + throw new UncheckedIOException(e); 17.46 + } 17.47 + } 17.48 + 17.49 public void visitIdent(JCIdent tree) { 17.50 try { 17.51 print(tree.name);
18.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Thu Dec 15 15:47:47 2011 -0800 18.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java Thu Dec 15 15:57:51 2011 -0800 18.3 @@ -271,6 +271,13 @@ 18.4 return M.at(t.pos).NewClass(encl, typeargs, clazz, args, def); 18.5 } 18.6 18.7 + public JCTree visitLambdaExpression(LambdaExpressionTree node, P p) { 18.8 + JCLambda t = (JCLambda) node; 18.9 + List<JCVariableDecl> params = copy(t.params, p); 18.10 + JCTree body = copy(t.body, p); 18.11 + return M.at(t.pos).Lambda(params, body); 18.12 + } 18.13 + 18.14 public JCTree visitParenthesized(ParenthesizedTree node, P p) { 18.15 JCParens t = (JCParens) node; 18.16 JCExpression expr = copy(t.expr, p); 18.17 @@ -289,6 +296,13 @@ 18.18 return M.at(t.pos).Select(selected, t.name); 18.19 } 18.20 18.21 + public JCTree visitMemberReference(MemberReferenceTree node, P p) { 18.22 + JCMemberReference t = (JCMemberReference) node; 18.23 + JCExpression expr = copy(t.expr, p); 18.24 + List<JCExpression> typeargs = copy(t.typeargs, p); 18.25 + return M.at(t.pos).Reference(t.mode, t.name, expr, typeargs); 18.26 + } 18.27 + 18.28 public JCTree visitEmptyStatement(EmptyStatementTree node, P p) { 18.29 JCSkip t = (JCSkip) node; 18.30 return M.at(t.pos).Skip();
19.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Dec 15 15:47:47 2011 -0800 19.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Dec 15 15:57:51 2011 -0800 19.3 @@ -227,6 +227,34 @@ 19.4 } 19.5 } 19.6 19.7 + /** 19.8 + * Return true if the AST corresponds to a static select of the kind A.B 19.9 + */ 19.10 + public static boolean isStaticSelector(JCTree base, Names names) { 19.11 + if (base == null) 19.12 + return false; 19.13 + switch (base.getTag()) { 19.14 + case IDENT: 19.15 + JCIdent id = (JCIdent)base; 19.16 + return id.name != names._this && 19.17 + id.name != names._super && 19.18 + isStaticSym(base); 19.19 + case SELECT: 19.20 + return isStaticSym(base) && 19.21 + isStaticSelector(((JCFieldAccess)base).selected, names); 19.22 + case TYPEAPPLY: 19.23 + return true; 19.24 + default: 19.25 + return false; 19.26 + } 19.27 + } 19.28 + //where 19.29 + private static boolean isStaticSym(JCTree tree) { 19.30 + Symbol sym = symbol(tree); 19.31 + return (sym.kind == Kinds.TYP || 19.32 + sym.kind == Kinds.PCK); 19.33 + } 19.34 + 19.35 /** Return true if a tree represents the null literal. */ 19.36 public static boolean isNull(JCTree tree) { 19.37 if (!tree.hasTag(LITERAL))
20.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Dec 15 15:47:47 2011 -0800 20.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Dec 15 15:57:51 2011 -0800 20.3 @@ -351,6 +351,14 @@ 20.4 return tree; 20.5 } 20.6 20.7 + public JCLambda Lambda(List<JCVariableDecl> params, 20.8 + JCTree body) 20.9 + { 20.10 + JCLambda tree = new JCLambda(params, body); 20.11 + tree.pos = pos; 20.12 + return tree; 20.13 + } 20.14 + 20.15 public JCParens Parens(JCExpression expr) { 20.16 JCParens tree = new JCParens(expr); 20.17 tree.pos = pos; 20.18 @@ -405,6 +413,13 @@ 20.19 return tree; 20.20 } 20.21 20.22 + public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name, 20.23 + JCExpression expr, List<JCExpression> typeargs) { 20.24 + JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs); 20.25 + tree.pos = pos; 20.26 + return tree; 20.27 + } 20.28 + 20.29 public JCIdent Ident(Name name) { 20.30 JCIdent tree = new JCIdent(name, null); 20.31 tree.pos = pos;
21.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Thu Dec 15 15:47:47 2011 -0800 21.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java Thu Dec 15 15:57:51 2011 -0800 21.3 @@ -212,6 +212,11 @@ 21.4 scan(tree.elems); 21.5 } 21.6 21.7 + public void visitLambda(JCLambda tree) { 21.8 + scan(tree.body); 21.9 + scan(tree.params); 21.10 + } 21.11 + 21.12 public void visitParens(JCParens tree) { 21.13 scan(tree.expr); 21.14 } 21.15 @@ -254,6 +259,11 @@ 21.16 scan(tree.selected); 21.17 } 21.18 21.19 + public void visitReference(JCMemberReference tree) { 21.20 + scan(tree.expr); 21.21 + scan(tree.typeargs); 21.22 + } 21.23 + 21.24 public void visitIdent(JCIdent tree) { 21.25 } 21.26
22.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Thu Dec 15 15:47:47 2011 -0800 22.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java Thu Dec 15 15:57:51 2011 -0800 22.3 @@ -282,6 +282,12 @@ 22.4 result = tree; 22.5 } 22.6 22.7 + public void visitLambda(JCLambda tree) { 22.8 + tree.params = translate(tree.params); 22.9 + tree.body = translate(tree.body); 22.10 + result = tree; 22.11 + } 22.12 + 22.13 public void visitNewArray(JCNewArray tree) { 22.14 tree.elemtype = translate(tree.elemtype); 22.15 tree.dims = translate(tree.dims); 22.16 @@ -340,6 +346,11 @@ 22.17 result = tree; 22.18 } 22.19 22.20 + public void visitReference(JCMemberReference tree) { 22.21 + tree.expr = translate(tree.expr); 22.22 + result = tree; 22.23 + } 22.24 + 22.25 public void visitIdent(JCIdent tree) { 22.26 result = tree; 22.27 }
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/tools/javac/T7120266.java Thu Dec 15 15:57:51 2011 -0800 23.3 @@ -0,0 +1,34 @@ 23.4 +/* 23.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.7 + * 23.8 + * This code is free software; you can redistribute it and/or modify it 23.9 + * under the terms of the GNU General Public License version 2 only, as 23.10 + * published by the Free Software Foundation. 23.11 + * 23.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 23.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.15 + * version 2 for more details (a copy is included in the LICENSE file that 23.16 + * accompanied this code). 23.17 + * 23.18 + * You should have received a copy of the GNU General Public License version 23.19 + * 2 along with this work; if not, write to the Free Software Foundation, 23.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.21 + * 23.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23.23 + * or visit www.oracle.com if you need additional information or have any 23.24 + * questions. 23.25 + */ 23.26 + 23.27 +/* 23.28 + * @test 23.29 + * @bug 7120266 23.30 + * @summary javac fails to compile hotspot code 23.31 + * @compile T7120266.java 23.32 + */ 23.33 + 23.34 +class T7120266 { 23.35 + void test(int i, int len) { that(i < len, "oopmap"); } 23.36 + void that(boolean b, String s) { }; 23.37 +}
24.1 --- a/test/tools/javac/diags/examples/CatchWithoutTry.java Thu Dec 15 15:47:47 2011 -0800 24.2 +++ b/test/tools/javac/diags/examples/CatchWithoutTry.java Thu Dec 15 15:57:51 2011 -0800 24.3 @@ -1,5 +1,5 @@ 24.4 /* 24.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24.6 + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. 24.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.8 * 24.9 * This code is free software; you can redistribute it and/or modify it 24.10 @@ -23,7 +23,6 @@ 24.11 24.12 // key: compiler.err.catch.without.try 24.13 // key: compiler.err.expected 24.14 -// key: compiler.err.not.stmt 24.15 24.16 class CatchWithoutTry { 24.17 void m() {
25.1 --- a/test/tools/javac/diags/examples/IllegalChar.java Thu Dec 15 15:47:47 2011 -0800 25.2 +++ b/test/tools/javac/diags/examples/IllegalChar.java Thu Dec 15 15:57:51 2011 -0800 25.3 @@ -1,5 +1,5 @@ 25.4 /* 25.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 25.6 + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. 25.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.8 * 25.9 * This code is free software; you can redistribute it and/or modify it 25.10 @@ -24,5 +24,5 @@ 25.11 // key: compiler.err.illegal.char 25.12 25.13 class IllegalChar { 25.14 - int i = #; 25.15 + int i = `; 25.16 }
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/test/tools/javac/diags/examples/LambdaNotSupported.java Thu Dec 15 15:57:51 2011 -0800 26.3 @@ -0,0 +1,29 @@ 26.4 +/* 26.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.7 + * 26.8 + * This code is free software; you can redistribute it and/or modify it 26.9 + * under the terms of the GNU General Public License version 2 only, as 26.10 + * published by the Free Software Foundation. 26.11 + * 26.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 26.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 26.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26.15 + * version 2 for more details (a copy is included in the LICENSE file that 26.16 + * accompanied this code). 26.17 + * 26.18 + * You should have received a copy of the GNU General Public License version 26.19 + * 2 along with this work; if not, write to the Free Software Foundation, 26.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26.21 + * 26.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 26.23 + * or visit www.oracle.com if you need additional information or have any 26.24 + * questions. 26.25 + */ 26.26 + 26.27 +// key: compiler.err.lambda.not.supported.in.source 26.28 +// options: -source 7 -Xlint:-options 26.29 + 26.30 +class LambdaNotSupported { 26.31 + S s = ()->{}; 26.32 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/test/tools/javac/diags/examples/MethodReferencesNotSupported.java Thu Dec 15 15:57:51 2011 -0800 27.3 @@ -0,0 +1,29 @@ 27.4 +/* 27.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.7 + * 27.8 + * This code is free software; you can redistribute it and/or modify it 27.9 + * under the terms of the GNU General Public License version 2 only, as 27.10 + * published by the Free Software Foundation. 27.11 + * 27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 27.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27.15 + * version 2 for more details (a copy is included in the LICENSE file that 27.16 + * accompanied this code). 27.17 + * 27.18 + * You should have received a copy of the GNU General Public License version 27.19 + * 2 along with this work; if not, write to the Free Software Foundation, 27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27.21 + * 27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 27.23 + * or visit www.oracle.com if you need additional information or have any 27.24 + * questions. 27.25 + */ 27.26 + 27.27 +// key: compiler.err.method.references.not.supported.in.source 27.28 +// options: -source 7 -Xlint:-options 27.29 + 27.30 +class MethodReferencesNotSupported { 27.31 + S s = A#foo; 27.32 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/test/tools/javac/diags/examples/NotAStatement.java Thu Dec 15 15:57:51 2011 -0800 28.3 @@ -0,0 +1,30 @@ 28.4 +/* 28.5 + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 28.7 + * 28.8 + * This code is free software; you can redistribute it and/or modify it 28.9 + * under the terms of the GNU General Public License version 2 only, as 28.10 + * published by the Free Software Foundation. 28.11 + * 28.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 28.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 28.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 28.15 + * version 2 for more details (a copy is included in the LICENSE file that 28.16 + * accompanied this code). 28.17 + * 28.18 + * You should have received a copy of the GNU General Public License version 28.19 + * 2 along with this work; if not, write to the Free Software Foundation, 28.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 28.21 + * 28.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28.23 + * or visit www.oracle.com if you need additional information or have any 28.24 + * questions. 28.25 + */ 28.26 + 28.27 +// key: compiler.err.not.stmt 28.28 + 28.29 +class NotAStatement { 28.30 + void m() { 28.31 + x + 1; 28.32 + } 28.33 +}
29.1 --- a/test/tools/javac/generics/rare/6665356/T6665356.out Thu Dec 15 15:47:47 2011 -0800 29.2 +++ b/test/tools/javac/generics/rare/6665356/T6665356.out Thu Dec 15 15:57:51 2011 -0800 29.3 @@ -1,5 +1,5 @@ 29.4 T6665356.java:17:37: compiler.err.improperly.formed.type.param.missing 29.5 T6665356.java:18:40: compiler.err.improperly.formed.type.inner.raw.param 29.6 -T6665356.java:26:23: compiler.err.improperly.formed.type.param.missing 29.7 +T6665356.java:26:22: compiler.err.improperly.formed.type.param.missing 29.8 T6665356.java:27:25: compiler.err.improperly.formed.type.inner.raw.param 29.9 4 errors
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/test/tools/javac/lambda/LambdaParserTest.java Thu Dec 15 15:57:51 2011 -0800 30.3 @@ -0,0 +1,276 @@ 30.4 +/* 30.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.7 + * 30.8 + * This code is free software; you can redistribute it and/or modify it 30.9 + * under the terms of the GNU General Public License version 2 only, as 30.10 + * published by the Free Software Foundation. 30.11 + * 30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 30.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 30.15 + * version 2 for more details (a copy is included in the LICENSE file that 30.16 + * accompanied this code). 30.17 + * 30.18 + * You should have received a copy of the GNU General Public License version 30.19 + * 2 along with this work; if not, write to the Free Software Foundation, 30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 30.21 + * 30.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 30.23 + * or visit www.oracle.com if you need additional information or have any 30.24 + * questions. 30.25 + */ 30.26 + 30.27 +/* 30.28 + * @test 30.29 + * @bug 7115050 30.30 + * @summary Add parser support for lambda expressions 30.31 + */ 30.32 + 30.33 +import com.sun.source.util.JavacTask; 30.34 +import java.net.URI; 30.35 +import java.util.Arrays; 30.36 +import javax.tools.Diagnostic; 30.37 +import javax.tools.JavaCompiler; 30.38 +import javax.tools.JavaFileObject; 30.39 +import javax.tools.SimpleJavaFileObject; 30.40 +import javax.tools.StandardJavaFileManager; 30.41 +import javax.tools.ToolProvider; 30.42 + 30.43 +public class LambdaParserTest { 30.44 + 30.45 + static int checkCount = 0; 30.46 + 30.47 + enum LambdaKind { 30.48 + NILARY_EXPR("()->x"), 30.49 + NILARY_STMT("()->{ return x; }"), 30.50 + ONEARY_SHORT_EXPR("x->x"), 30.51 + ONEARY_SHORT_STMT("x->{ return x; }"), 30.52 + ONEARY_EXPR("(#M1 #T1 x)->x"), 30.53 + ONEARY_STMT("(#M1 #T1 x)->{ return x; }"), 30.54 + TWOARY_EXPR("(#M1 #T1 x, #M2 #T2 y)->x"), 30.55 + TWOARY_STMT("(#M1 #T1 x, #M2 #T2 y)->{ return x; }"); 30.56 + 30.57 + String lambdaTemplate; 30.58 + 30.59 + LambdaKind(String lambdaTemplate) { 30.60 + this.lambdaTemplate = lambdaTemplate; 30.61 + } 30.62 + 30.63 + String getLambdaString(LambdaParameterKind pk1, LambdaParameterKind pk2, 30.64 + ModifierKind mk1, ModifierKind mk2) { 30.65 + return lambdaTemplate.replaceAll("#M1", mk1.modifier) 30.66 + .replaceAll("#M2", mk2.modifier) 30.67 + .replaceAll("#T1", pk1.parameterType) 30.68 + .replaceAll("#T2", pk2.parameterType); 30.69 + } 30.70 + 30.71 + int arity() { 30.72 + switch (this) { 30.73 + case NILARY_EXPR: 30.74 + case NILARY_STMT: return 0; 30.75 + case ONEARY_SHORT_EXPR: 30.76 + case ONEARY_SHORT_STMT: 30.77 + case ONEARY_EXPR: 30.78 + case ONEARY_STMT: return 1; 30.79 + case TWOARY_EXPR: 30.80 + case TWOARY_STMT: return 2; 30.81 + default: throw new AssertionError("Invalid lambda kind " + this); 30.82 + } 30.83 + } 30.84 + 30.85 + boolean isShort() { 30.86 + return this == ONEARY_SHORT_EXPR || 30.87 + this == ONEARY_SHORT_STMT; 30.88 + } 30.89 + } 30.90 + 30.91 + enum LambdaParameterKind { 30.92 + IMPLICIT(""), 30.93 + EXPLIICT_SIMPLE("A"), 30.94 + EXPLICIT_VARARGS("A..."), 30.95 + EXPLICIT_GENERIC1("A<X>"), 30.96 + EXPLICIT_GENERIC3("A<? extends X, ? super Y>"); 30.97 + 30.98 + String parameterType; 30.99 + 30.100 + LambdaParameterKind(String parameterType) { 30.101 + this.parameterType = parameterType; 30.102 + } 30.103 + 30.104 + boolean explicit() { 30.105 + return this != IMPLICIT; 30.106 + } 30.107 + } 30.108 + 30.109 + enum ModifierKind { 30.110 + NONE(""), 30.111 + FINAL("final"), 30.112 + PUBLIC("public"); 30.113 + 30.114 + String modifier; 30.115 + 30.116 + ModifierKind(String modifier) { 30.117 + this.modifier = modifier; 30.118 + } 30.119 + 30.120 + boolean compatibleWith(LambdaParameterKind pk) { 30.121 + switch (this) { 30.122 + case PUBLIC: return false; 30.123 + case FINAL: return pk != LambdaParameterKind.IMPLICIT; 30.124 + case NONE: return true; 30.125 + default: throw new AssertionError("Invalid modifier kind " + this); 30.126 + } 30.127 + } 30.128 + } 30.129 + 30.130 + enum ExprKind { 30.131 + NONE("#L#S"), 30.132 + SINGLE_PAREN1("(#L#S)"), 30.133 + SINGLE_PAREN2("(#L)#S"), 30.134 + DOUBLE_PAREN1("((#L#S))"), 30.135 + DOUBLE_PAREN2("((#L)#S)"), 30.136 + DOUBLE_PAREN3("((#L))#S"); 30.137 + 30.138 + String expressionTemplate; 30.139 + 30.140 + ExprKind(String expressionTemplate) { 30.141 + this.expressionTemplate = expressionTemplate; 30.142 + } 30.143 + 30.144 + String expressionString(LambdaParameterKind pk1, LambdaParameterKind pk2, 30.145 + ModifierKind mk1, ModifierKind mk2, LambdaKind lk, SubExprKind sk) { 30.146 + return expressionTemplate.replaceAll("#L", lk.getLambdaString(pk1, pk2, mk1, mk2)) 30.147 + .replaceAll("#S", sk.subExpression); 30.148 + } 30.149 + } 30.150 + 30.151 + enum SubExprKind { 30.152 + NONE(""), 30.153 + SELECT_FIELD(".f"), 30.154 + SELECT_METHOD(".f()"), 30.155 + SELECT_NEW(".new Foo()"), 30.156 + POSTINC("++"), 30.157 + POSTDEC("--"); 30.158 + 30.159 + String subExpression; 30.160 + 30.161 + SubExprKind(String subExpression) { 30.162 + this.subExpression = subExpression; 30.163 + } 30.164 + } 30.165 + 30.166 + public static void main(String... args) throws Exception { 30.167 + 30.168 + //create default shared JavaCompiler - reused across multiple compilations 30.169 + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 30.170 + StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); 30.171 + 30.172 + for (LambdaKind lk : LambdaKind.values()) { 30.173 + for (LambdaParameterKind pk1 : LambdaParameterKind.values()) { 30.174 + if (lk.arity() < 1 && pk1 != LambdaParameterKind.IMPLICIT) continue; 30.175 + for (LambdaParameterKind pk2 : LambdaParameterKind.values()) { 30.176 + if (lk.arity() < 2 && pk2 != LambdaParameterKind.IMPLICIT) continue; 30.177 + for (ModifierKind mk1 : ModifierKind.values()) { 30.178 + if (mk1 != ModifierKind.NONE && lk.isShort()) continue; 30.179 + if (lk.arity() < 1 && mk1 != ModifierKind.NONE) continue; 30.180 + for (ModifierKind mk2 : ModifierKind.values()) { 30.181 + if (lk.arity() < 2 && mk2 != ModifierKind.NONE) continue; 30.182 + for (SubExprKind sk : SubExprKind.values()) { 30.183 + for (ExprKind ek : ExprKind.values()) { 30.184 + new LambdaParserTest(pk1, pk2, mk1, mk2, lk, sk, ek) 30.185 + .run(comp, fm); 30.186 + } 30.187 + } 30.188 + } 30.189 + } 30.190 + } 30.191 + } 30.192 + } 30.193 + System.out.println("Total check executed: " + checkCount); 30.194 + } 30.195 + 30.196 + LambdaParameterKind pk1; 30.197 + LambdaParameterKind pk2; 30.198 + ModifierKind mk1; 30.199 + ModifierKind mk2; 30.200 + LambdaKind lk; 30.201 + SubExprKind sk; 30.202 + ExprKind ek; 30.203 + JavaSource source; 30.204 + DiagnosticChecker diagChecker; 30.205 + 30.206 + LambdaParserTest(LambdaParameterKind pk1, LambdaParameterKind pk2, ModifierKind mk1, 30.207 + ModifierKind mk2, LambdaKind lk, SubExprKind sk, ExprKind ek) { 30.208 + this.pk1 = pk1; 30.209 + this.pk2 = pk2; 30.210 + this.mk1 = mk1; 30.211 + this.mk2 = mk2; 30.212 + this.lk = lk; 30.213 + this.sk = sk; 30.214 + this.ek = ek; 30.215 + this.source = new JavaSource(); 30.216 + this.diagChecker = new DiagnosticChecker(); 30.217 + } 30.218 + 30.219 + class JavaSource extends SimpleJavaFileObject { 30.220 + 30.221 + String template = "class Test {\n" + 30.222 + " SAM s = #E;\n" + 30.223 + "}"; 30.224 + 30.225 + String source; 30.226 + 30.227 + public JavaSource() { 30.228 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 30.229 + source = template.replaceAll("#E", ek.expressionString(pk1, pk2, mk1, mk2, lk, sk)); 30.230 + } 30.231 + 30.232 + @Override 30.233 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 30.234 + return source; 30.235 + } 30.236 + } 30.237 + 30.238 + void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { 30.239 + JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, 30.240 + Arrays.asList("-XDallowLambda"), null, Arrays.asList(source)); 30.241 + try { 30.242 + ct.parse(); 30.243 + } catch (Throwable ex) { 30.244 + throw new AssertionError("Error thron when parsing the following source:\n" + source.getCharContent(true)); 30.245 + } 30.246 + check(); 30.247 + } 30.248 + 30.249 + void check() { 30.250 + checkCount++; 30.251 + 30.252 + boolean errorExpected = (lk.arity() > 0 && !mk1.compatibleWith(pk1)) || 30.253 + (lk.arity() > 1 && !mk2.compatibleWith(pk2)); 30.254 + 30.255 + if (lk.arity() == 2 && 30.256 + (pk1.explicit() != pk2.explicit() || 30.257 + pk1 == LambdaParameterKind.EXPLICIT_VARARGS)) { 30.258 + errorExpected = true; 30.259 + } 30.260 + 30.261 + if (errorExpected != diagChecker.errorFound) { 30.262 + throw new Error("invalid diagnostics for source:\n" + 30.263 + source.getCharContent(true) + 30.264 + "\nFound error: " + diagChecker.errorFound + 30.265 + "\nExpected error: " + errorExpected); 30.266 + } 30.267 + } 30.268 + 30.269 + static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> { 30.270 + 30.271 + boolean errorFound; 30.272 + 30.273 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 30.274 + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { 30.275 + errorFound = true; 30.276 + } 30.277 + } 30.278 + } 30.279 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/test/tools/javac/lambda/MethodReferenceParserTest.java Thu Dec 15 15:57:51 2011 -0800 31.3 @@ -0,0 +1,234 @@ 31.4 +/* 31.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. 31.11 + * 31.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.15 + * version 2 for more details (a copy is included in the LICENSE file that 31.16 + * accompanied this code). 31.17 + * 31.18 + * You should have received a copy of the GNU General Public License version 31.19 + * 2 along with this work; if not, write to the Free Software Foundation, 31.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.21 + * 31.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.23 + * or visit www.oracle.com if you need additional information or have any 31.24 + * questions. 31.25 + */ 31.26 + 31.27 +/* 31.28 + * @test 31.29 + * @bug 7115052 31.30 + * @ignore 7120266 31.31 + * @summary Add parser support for method references 31.32 + */ 31.33 + 31.34 +import com.sun.source.util.JavacTask; 31.35 +import java.net.URI; 31.36 +import java.util.Arrays; 31.37 +import javax.tools.Diagnostic; 31.38 +import javax.tools.JavaCompiler; 31.39 +import javax.tools.JavaFileObject; 31.40 +import javax.tools.SimpleJavaFileObject; 31.41 +import javax.tools.StandardJavaFileManager; 31.42 +import javax.tools.ToolProvider; 31.43 + 31.44 +public class MethodReferenceParserTest { 31.45 + 31.46 + static int checkCount = 0; 31.47 + 31.48 + enum ReferenceKind { 31.49 + METHOD_REF("#Q##Gm"), 31.50 + CONSTRUCTOR_REF("#Q##Gnew"), 31.51 + ERR_SUPER("#Q##Gsuper"), 31.52 + ERR_METH0("#Q##Gm()"), 31.53 + ERR_METH1("#Q##Gm(X)"), 31.54 + ERR_CONSTR0("#Q##Gnew()"), 31.55 + ERR_CONSTR1("#Q##Gnew(X)"); 31.56 + 31.57 + String referenceTemplate; 31.58 + 31.59 + ReferenceKind(String referenceTemplate) { 31.60 + this.referenceTemplate = referenceTemplate; 31.61 + } 31.62 + 31.63 + String getReferenceString(QualifierKind qk, GenericKind gk) { 31.64 + return referenceTemplate 31.65 + .replaceAll("#Q", qk.qualifier) 31.66 + .replaceAll("#G", gk.typeParameters); 31.67 + } 31.68 + 31.69 + boolean erroneous() { 31.70 + switch (this) { 31.71 + case ERR_SUPER: 31.72 + case ERR_METH0: 31.73 + case ERR_METH1: 31.74 + case ERR_CONSTR0: 31.75 + case ERR_CONSTR1: 31.76 + return true; 31.77 + default: return false; 31.78 + } 31.79 + } 31.80 + } 31.81 + 31.82 + enum GenericKind { 31.83 + NONE(""), 31.84 + ONE("<X>"), 31.85 + TWO("<X,Y>"); 31.86 + 31.87 + String typeParameters; 31.88 + 31.89 + GenericKind(String typeParameters) { 31.90 + this.typeParameters = typeParameters; 31.91 + } 31.92 + } 31.93 + 31.94 + enum QualifierKind { 31.95 + THIS("this"), 31.96 + SUPER("super"), 31.97 + NEW("new Foo()"), 31.98 + METHOD("m()"), 31.99 + FIELD("a.f"), 31.100 + UBOUND_SIMPLE("A"), 31.101 + UNBOUND_GENERIC1("A<X>"), 31.102 + UNBOUND_GENERIC2("A<X, Y>"), 31.103 + UNBOUND_GENERIC3("A<? extends X, ? super Y>"); 31.104 + 31.105 + String qualifier; 31.106 + 31.107 + QualifierKind(String qualifier) { 31.108 + this.qualifier = qualifier; 31.109 + } 31.110 + } 31.111 + 31.112 + enum ExprKind { 31.113 + NONE("#R#S"), 31.114 + SINGLE_PAREN1("(#R#S)"), 31.115 + SINGLE_PAREN2("(#R)#S"), 31.116 + DOUBLE_PAREN1("((#R#S))"), 31.117 + DOUBLE_PAREN2("((#R)#S)"), 31.118 + DOUBLE_PAREN3("((#R))#S"); 31.119 + 31.120 + String expressionTemplate; 31.121 + 31.122 + ExprKind(String expressionTemplate) { 31.123 + this.expressionTemplate = expressionTemplate; 31.124 + } 31.125 + 31.126 + String expressionString(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) { 31.127 + return expressionTemplate 31.128 + .replaceAll("#R", rk.getReferenceString(qk, gk)) 31.129 + .replaceAll("#S", sk.subExpression); 31.130 + } 31.131 + } 31.132 + 31.133 + enum SubExprKind { 31.134 + NONE(""), 31.135 + SELECT_FIELD(".f"), 31.136 + SELECT_METHOD(".f()"), 31.137 + SELECT_NEW(".new Foo()"), 31.138 + POSTINC("++"), 31.139 + POSTDEC("--"); 31.140 + 31.141 + String subExpression; 31.142 + 31.143 + SubExprKind(String subExpression) { 31.144 + this.subExpression = subExpression; 31.145 + } 31.146 + } 31.147 + 31.148 + public static void main(String... args) throws Exception { 31.149 + 31.150 + //create default shared JavaCompiler - reused across multiple compilations 31.151 + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 31.152 + StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); 31.153 + 31.154 + for (ReferenceKind rk : ReferenceKind.values()) { 31.155 + for (QualifierKind qk : QualifierKind.values()) { 31.156 + for (GenericKind gk : GenericKind.values()) { 31.157 + for (SubExprKind sk : SubExprKind.values()) { 31.158 + for (ExprKind ek : ExprKind.values()) { 31.159 + new MethodReferenceParserTest(rk, qk, gk, sk, ek).run(comp, fm); 31.160 + } 31.161 + } 31.162 + } 31.163 + } 31.164 + } 31.165 + System.out.println("Total check executed: " + checkCount); 31.166 + } 31.167 + 31.168 + ReferenceKind rk; 31.169 + QualifierKind qk; 31.170 + GenericKind gk; 31.171 + SubExprKind sk; 31.172 + ExprKind ek; 31.173 + JavaSource source; 31.174 + DiagnosticChecker diagChecker; 31.175 + 31.176 + MethodReferenceParserTest(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk, ExprKind ek) { 31.177 + this.rk = rk; 31.178 + this.qk = qk; 31.179 + this.gk = gk; 31.180 + this.sk = sk; 31.181 + this.ek = ek; 31.182 + this.source = new JavaSource(); 31.183 + this.diagChecker = new DiagnosticChecker(); 31.184 + } 31.185 + 31.186 + class JavaSource extends SimpleJavaFileObject { 31.187 + 31.188 + String template = "class Test {\n" + 31.189 + " SAM s = #E;\n" + 31.190 + "}"; 31.191 + 31.192 + String source; 31.193 + 31.194 + public JavaSource() { 31.195 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 31.196 + source = template.replaceAll("#E", ek.expressionString(rk, qk, gk, sk)); 31.197 + } 31.198 + 31.199 + @Override 31.200 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 31.201 + return source; 31.202 + } 31.203 + } 31.204 + 31.205 + void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { 31.206 + JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, 31.207 + Arrays.asList("-XDallowMethodReferences"), null, Arrays.asList(source)); 31.208 + try { 31.209 + ct.parse(); 31.210 + } catch (Throwable ex) { 31.211 + throw new AssertionError("Error thrown when parsing the following source:\n" + source.getCharContent(true)); 31.212 + } 31.213 + check(); 31.214 + } 31.215 + 31.216 + void check() { 31.217 + checkCount++; 31.218 + 31.219 + if (diagChecker.errorFound != rk.erroneous()) { 31.220 + throw new Error("invalid diagnostics for source:\n" + 31.221 + source.getCharContent(true) + 31.222 + "\nFound error: " + diagChecker.errorFound + 31.223 + "\nExpected error: " + rk.erroneous()); 31.224 + } 31.225 + } 31.226 + 31.227 + static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> { 31.228 + 31.229 + boolean errorFound; 31.230 + 31.231 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 31.232 + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { 31.233 + errorFound = true; 31.234 + } 31.235 + } 31.236 + } 31.237 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/test/tools/javac/parser/JavacParserTest.java Thu Dec 15 15:57:51 2011 -0800 32.3 @@ -0,0 +1,883 @@ 32.4 +/* 32.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.7 + * 32.8 + * This code is free software; you can redistribute it and/or modify it 32.9 + * under the terms of the GNU General Public License version 2 only, as 32.10 + * published by the Free Software Foundation. 32.11 + * 32.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 32.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 32.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 32.15 + * version 2 for more details (a copy is included in the LICENSE file that 32.16 + * accompanied this code). 32.17 + * 32.18 + * You should have received a copy of the GNU General Public License version 32.19 + * 2 along with this work; if not, write to the Free Software Foundation, 32.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 32.21 + * 32.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 32.23 + * or visit www.oracle.com if you need additional information or have any 32.24 + * questions. 32.25 + */ 32.26 + 32.27 +/* 32.28 + * @test 32.29 + * @bug 7073631 32.30 + * @summary tests error and diagnostics positions 32.31 + * @author Jan Lahoda 32.32 + */ 32.33 + 32.34 +import com.sun.source.tree.BinaryTree; 32.35 +import com.sun.source.tree.BlockTree; 32.36 +import com.sun.source.tree.ClassTree; 32.37 +import com.sun.source.tree.CompilationUnitTree; 32.38 +import com.sun.source.tree.ErroneousTree; 32.39 +import com.sun.source.tree.ExpressionStatementTree; 32.40 +import com.sun.source.tree.ExpressionTree; 32.41 +import com.sun.source.tree.MethodInvocationTree; 32.42 +import com.sun.source.tree.MethodTree; 32.43 +import com.sun.source.tree.ModifiersTree; 32.44 +import com.sun.source.tree.StatementTree; 32.45 +import com.sun.source.tree.Tree; 32.46 +import com.sun.source.tree.Tree.Kind; 32.47 +import com.sun.source.tree.VariableTree; 32.48 +import com.sun.source.tree.WhileLoopTree; 32.49 +import com.sun.source.util.SourcePositions; 32.50 +import com.sun.source.util.TreeScanner; 32.51 +import com.sun.source.util.Trees; 32.52 +import com.sun.tools.javac.api.JavacTaskImpl; 32.53 +import com.sun.tools.javac.tree.JCTree; 32.54 +import java.io.IOException; 32.55 +import java.net.URI; 32.56 +import java.util.ArrayList; 32.57 +import java.util.Arrays; 32.58 +import java.util.LinkedList; 32.59 +import java.util.List; 32.60 +import javax.tools.Diagnostic; 32.61 +import javax.tools.DiagnosticCollector; 32.62 +import javax.tools.DiagnosticListener; 32.63 +import javax.tools.JavaCompiler; 32.64 +import javax.tools.JavaFileObject; 32.65 +import javax.tools.SimpleJavaFileObject; 32.66 +import javax.tools.ToolProvider; 32.67 + 32.68 +public class JavacParserTest extends TestCase { 32.69 + final JavaCompiler tool; 32.70 + public JavacParserTest(String testName) { 32.71 + tool = ToolProvider.getSystemJavaCompiler(); 32.72 + System.out.println("java.home=" + System.getProperty("java.home")); 32.73 + } 32.74 + 32.75 + static class MyFileObject extends SimpleJavaFileObject { 32.76 + 32.77 + private String text; 32.78 + 32.79 + public MyFileObject(String text) { 32.80 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 32.81 + this.text = text; 32.82 + } 32.83 + 32.84 + @Override 32.85 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 32.86 + return text; 32.87 + } 32.88 + } 32.89 + /* 32.90 + * converts Windows to Unix style LFs for comparing strings 32.91 + */ 32.92 + private String normalize(String in) { 32.93 + return in.replace(System.getProperty("line.separator"), "\n"); 32.94 + } 32.95 + 32.96 + public CompilationUnitTree getCompilationUnitTree(String code) throws IOException { 32.97 + 32.98 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.99 + null, Arrays.asList(new MyFileObject(code))); 32.100 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.101 + return cut; 32.102 + } 32.103 + 32.104 + public List<String> getErroneousTreeValues(ErroneousTree node) { 32.105 + 32.106 + List<String> values = new ArrayList<>(); 32.107 + if (node.getErrorTrees() != null) { 32.108 + for (Tree t : node.getErrorTrees()) { 32.109 + values.add(t.toString()); 32.110 + } 32.111 + } else { 32.112 + throw new RuntimeException("ERROR: No Erroneous tree " 32.113 + + "has been created."); 32.114 + } 32.115 + return values; 32.116 + } 32.117 + 32.118 + public void testPositionForSuperConstructorCalls() throws IOException { 32.119 + assert tool != null; 32.120 + 32.121 + String code = "package test; public class Test {public Test() {super();}}"; 32.122 + 32.123 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.124 + null, Arrays.asList(new MyFileObject(code))); 32.125 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.126 + SourcePositions pos = Trees.instance(ct).getSourcePositions(); 32.127 + 32.128 + MethodTree method = 32.129 + (MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); 32.130 + ExpressionStatementTree es = 32.131 + (ExpressionStatementTree) method.getBody().getStatements().get(0); 32.132 + 32.133 + final int esStartPos = code.indexOf(es.toString()); 32.134 + final int esEndPos = esStartPos + es.toString().length(); 32.135 + assertEquals("testPositionForSuperConstructorCalls", 32.136 + esStartPos, pos.getStartPosition(cut, es)); 32.137 + assertEquals("testPositionForSuperConstructorCalls", 32.138 + esEndPos, pos.getEndPosition(cut, es)); 32.139 + 32.140 + MethodInvocationTree mit = (MethodInvocationTree) es.getExpression(); 32.141 + 32.142 + final int mitStartPos = code.indexOf(mit.toString()); 32.143 + final int mitEndPos = mitStartPos + mit.toString().length(); 32.144 + assertEquals("testPositionForSuperConstructorCalls", 32.145 + mitStartPos, pos.getStartPosition(cut, mit)); 32.146 + assertEquals("testPositionForSuperConstructorCalls", 32.147 + mitEndPos, pos.getEndPosition(cut, mit)); 32.148 + 32.149 + final int methodStartPos = mitStartPos; 32.150 + final int methodEndPos = methodStartPos + mit.getMethodSelect().toString().length(); 32.151 + assertEquals("testPositionForSuperConstructorCalls", 32.152 + methodStartPos, pos.getStartPosition(cut, mit.getMethodSelect())); 32.153 + assertEquals("testPositionForSuperConstructorCalls", 32.154 + methodEndPos, pos.getEndPosition(cut, mit.getMethodSelect())); 32.155 + 32.156 + } 32.157 + 32.158 + public void testPositionForEnumModifiers() throws IOException { 32.159 + 32.160 + String code = "package test; public enum Test {A;}"; 32.161 + 32.162 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.163 + null, Arrays.asList(new MyFileObject(code))); 32.164 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.165 + SourcePositions pos = Trees.instance(ct).getSourcePositions(); 32.166 + 32.167 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.168 + ModifiersTree mt = clazz.getModifiers(); 32.169 + 32.170 + assertEquals("testPositionForEnumModifiers", 32.171 + 38 - 24, pos.getStartPosition(cut, mt)); 32.172 + assertEquals("testPositionForEnumModifiers", 32.173 + 44 - 24, pos.getEndPosition(cut, mt)); 32.174 + } 32.175 + 32.176 + public void testNewClassWithEnclosing() throws IOException { 32.177 + 32.178 + 32.179 + String code = "package test; class Test { " + 32.180 + "class d {} private void method() { " + 32.181 + "Object o = Test.this.new d(); } }"; 32.182 + 32.183 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.184 + null, Arrays.asList(new MyFileObject(code))); 32.185 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.186 + SourcePositions pos = Trees.instance(ct).getSourcePositions(); 32.187 + 32.188 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.189 + ExpressionTree est = 32.190 + ((VariableTree) ((MethodTree) clazz.getMembers().get(1)).getBody().getStatements().get(0)).getInitializer(); 32.191 + 32.192 + assertEquals("testNewClassWithEnclosing", 32.193 + 97 - 24, pos.getStartPosition(cut, est)); 32.194 + assertEquals("testNewClassWithEnclosing", 32.195 + 114 - 24, pos.getEndPosition(cut, est)); 32.196 + } 32.197 + 32.198 + public void testPreferredPositionForBinaryOp() throws IOException { 32.199 + 32.200 + String code = "package test; public class Test {" 32.201 + + "private void test() {" 32.202 + + "Object o = null; boolean b = o != null && o instanceof String;" 32.203 + + "} private Test() {}}"; 32.204 + 32.205 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.206 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.207 + MethodTree method = (MethodTree) clazz.getMembers().get(0); 32.208 + VariableTree condSt = (VariableTree) method.getBody().getStatements().get(1); 32.209 + BinaryTree cond = (BinaryTree) condSt.getInitializer(); 32.210 + 32.211 + JCTree condJC = (JCTree) cond; 32.212 + int condStartPos = code.indexOf("&&"); 32.213 + assertEquals("testPreferredPositionForBinaryOp", 32.214 + condStartPos, condJC.pos); 32.215 + } 32.216 + 32.217 + public void testPositionBrokenSource126732a() throws IOException { 32.218 + String[] commands = new String[]{ 32.219 + "return Runnable()", 32.220 + "do { } while (true)", 32.221 + "throw UnsupportedOperationException()", 32.222 + "assert true", 32.223 + "1 + 1",}; 32.224 + 32.225 + for (String command : commands) { 32.226 + 32.227 + String code = "package test;\n" 32.228 + + "public class Test {\n" 32.229 + + " public static void test() {\n" 32.230 + + " " + command + " {\n" 32.231 + + " new Runnable() {\n" 32.232 + + " };\n" 32.233 + + " }\n" 32.234 + + "}"; 32.235 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, 32.236 + null, null, Arrays.asList(new MyFileObject(code))); 32.237 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.238 + 32.239 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.240 + MethodTree method = (MethodTree) clazz.getMembers().get(0); 32.241 + List<? extends StatementTree> statements = 32.242 + method.getBody().getStatements(); 32.243 + 32.244 + StatementTree ret = statements.get(0); 32.245 + StatementTree block = statements.get(1); 32.246 + 32.247 + Trees t = Trees.instance(ct); 32.248 + int len = code.indexOf(command + " {") + (command + " ").length(); 32.249 + assertEquals(command, len, 32.250 + t.getSourcePositions().getEndPosition(cut, ret)); 32.251 + assertEquals(command, len, 32.252 + t.getSourcePositions().getStartPosition(cut, block)); 32.253 + } 32.254 + } 32.255 + 32.256 + public void testPositionBrokenSource126732b() throws IOException { 32.257 + String[] commands = new String[]{ 32.258 + "break", 32.259 + "break A", 32.260 + "continue ", 32.261 + "continue A",}; 32.262 + 32.263 + for (String command : commands) { 32.264 + 32.265 + String code = "package test;\n" 32.266 + + "public class Test {\n" 32.267 + + " public static void test() {\n" 32.268 + + " while (true) {\n" 32.269 + + " " + command + " {\n" 32.270 + + " new Runnable() {\n" 32.271 + + " };\n" 32.272 + + " }\n" 32.273 + + " }\n" 32.274 + + "}"; 32.275 + 32.276 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, 32.277 + null, null, Arrays.asList(new MyFileObject(code))); 32.278 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.279 + 32.280 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.281 + MethodTree method = (MethodTree) clazz.getMembers().get(0); 32.282 + List<? extends StatementTree> statements = 32.283 + ((BlockTree) ((WhileLoopTree) method.getBody().getStatements().get(0)).getStatement()).getStatements(); 32.284 + 32.285 + StatementTree ret = statements.get(0); 32.286 + StatementTree block = statements.get(1); 32.287 + 32.288 + Trees t = Trees.instance(ct); 32.289 + int len = code.indexOf(command + " {") + (command + " ").length(); 32.290 + assertEquals(command, len, 32.291 + t.getSourcePositions().getEndPosition(cut, ret)); 32.292 + assertEquals(command, len, 32.293 + t.getSourcePositions().getStartPosition(cut, block)); 32.294 + } 32.295 + } 32.296 + 32.297 + public void testErrorRecoveryForEnhancedForLoop142381() throws IOException { 32.298 + 32.299 + String code = "package test; class Test { " + 32.300 + "private void method() { " + 32.301 + "java.util.Set<String> s = null; for (a : s) {} } }"; 32.302 + 32.303 + final List<Diagnostic<? extends JavaFileObject>> errors = 32.304 + new LinkedList<Diagnostic<? extends JavaFileObject>>(); 32.305 + 32.306 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 32.307 + new DiagnosticListener<JavaFileObject>() { 32.308 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 32.309 + errors.add(diagnostic); 32.310 + } 32.311 + }, null, null, Arrays.asList(new MyFileObject(code))); 32.312 + 32.313 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.314 + 32.315 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.316 + StatementTree forStatement = 32.317 + ((MethodTree) clazz.getMembers().get(0)).getBody().getStatements().get(1); 32.318 + 32.319 + assertEquals("testErrorRecoveryForEnhancedForLoop142381", 32.320 + Kind.ENHANCED_FOR_LOOP, forStatement.getKind()); 32.321 + assertFalse("testErrorRecoveryForEnhancedForLoop142381", errors.isEmpty()); 32.322 + } 32.323 + 32.324 + public void testPositionAnnotationNoPackage187551() throws IOException { 32.325 + 32.326 + String code = "\n@interface Test {}"; 32.327 + 32.328 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.329 + null, Arrays.asList(new MyFileObject(code))); 32.330 + 32.331 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.332 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.333 + Trees t = Trees.instance(ct); 32.334 + 32.335 + assertEquals("testPositionAnnotationNoPackage187551", 32.336 + 1, t.getSourcePositions().getStartPosition(cut, clazz)); 32.337 + } 32.338 + 32.339 + public void testPositionsSane() throws IOException { 32.340 + performPositionsSanityTest("package test; class Test { " + 32.341 + "private void method() { " + 32.342 + "java.util.List<? extends java.util.List<? extends String>> l; " + 32.343 + "} }"); 32.344 + performPositionsSanityTest("package test; class Test { " + 32.345 + "private void method() { " + 32.346 + "java.util.List<? super java.util.List<? super String>> l; " + 32.347 + "} }"); 32.348 + performPositionsSanityTest("package test; class Test { " + 32.349 + "private void method() { " + 32.350 + "java.util.List<? super java.util.List<?>> l; } }"); 32.351 + } 32.352 + 32.353 + private void performPositionsSanityTest(String code) throws IOException { 32.354 + 32.355 + final List<Diagnostic<? extends JavaFileObject>> errors = 32.356 + new LinkedList<Diagnostic<? extends JavaFileObject>>(); 32.357 + 32.358 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 32.359 + new DiagnosticListener<JavaFileObject>() { 32.360 + 32.361 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 32.362 + errors.add(diagnostic); 32.363 + } 32.364 + }, null, null, Arrays.asList(new MyFileObject(code))); 32.365 + 32.366 + final CompilationUnitTree cut = ct.parse().iterator().next(); 32.367 + final Trees trees = Trees.instance(ct); 32.368 + 32.369 + new TreeScanner<Void, Void>() { 32.370 + 32.371 + private long parentStart = 0; 32.372 + private long parentEnd = Integer.MAX_VALUE; 32.373 + 32.374 + @Override 32.375 + public Void scan(Tree node, Void p) { 32.376 + if (node == null) { 32.377 + return null; 32.378 + } 32.379 + 32.380 + long start = trees.getSourcePositions().getStartPosition(cut, node); 32.381 + 32.382 + if (start == (-1)) { 32.383 + return null; //synthetic tree 32.384 + } 32.385 + assertTrue(node.toString() + ":" + start + "/" + parentStart, 32.386 + parentStart <= start); 32.387 + 32.388 + long prevParentStart = parentStart; 32.389 + 32.390 + parentStart = start; 32.391 + 32.392 + long end = trees.getSourcePositions().getEndPosition(cut, node); 32.393 + 32.394 + assertTrue(node.toString() + ":" + end + "/" + parentEnd, 32.395 + end <= parentEnd); 32.396 + 32.397 + long prevParentEnd = parentEnd; 32.398 + 32.399 + parentEnd = end; 32.400 + 32.401 + super.scan(node, p); 32.402 + 32.403 + parentStart = prevParentStart; 32.404 + parentEnd = prevParentEnd; 32.405 + 32.406 + return null; 32.407 + } 32.408 + 32.409 + private void assertTrue(String message, boolean b) { 32.410 + if (!b) fail(message); 32.411 + } 32.412 + }.scan(cut, null); 32.413 + } 32.414 + 32.415 + public void testCorrectWilcardPositions() throws IOException { 32.416 + performWildcardPositionsTest("package test; import java.util.List; " + 32.417 + "class Test { private void method() { List<? extends List<? extends String>> l; } }", 32.418 + 32.419 + Arrays.asList("List<? extends List<? extends String>> l;", 32.420 + "List<? extends List<? extends String>>", 32.421 + "List", 32.422 + "? extends List<? extends String>", 32.423 + "List<? extends String>", 32.424 + "List", 32.425 + "? extends String", 32.426 + "String")); 32.427 + performWildcardPositionsTest("package test; import java.util.List; " + 32.428 + "class Test { private void method() { List<? super List<? super String>> l; } }", 32.429 + 32.430 + Arrays.asList("List<? super List<? super String>> l;", 32.431 + "List<? super List<? super String>>", 32.432 + "List", 32.433 + "? super List<? super String>", 32.434 + "List<? super String>", 32.435 + "List", 32.436 + "? super String", 32.437 + "String")); 32.438 + performWildcardPositionsTest("package test; import java.util.List; " + 32.439 + "class Test { private void method() { List<? super List<?>> l; } }", 32.440 + 32.441 + Arrays.asList("List<? super List<?>> l;", 32.442 + "List<? super List<?>>", 32.443 + "List", 32.444 + "? super List<?>", 32.445 + "List<?>", 32.446 + "List", 32.447 + "?")); 32.448 + performWildcardPositionsTest("package test; import java.util.List; " + 32.449 + "class Test { private void method() { " + 32.450 + "List<? extends List<? extends List<? extends String>>> l; } }", 32.451 + 32.452 + Arrays.asList("List<? extends List<? extends List<? extends String>>> l;", 32.453 + "List<? extends List<? extends List<? extends String>>>", 32.454 + "List", 32.455 + "? extends List<? extends List<? extends String>>", 32.456 + "List<? extends List<? extends String>>", 32.457 + "List", 32.458 + "? extends List<? extends String>", 32.459 + "List<? extends String>", 32.460 + "List", 32.461 + "? extends String", 32.462 + "String")); 32.463 + performWildcardPositionsTest("package test; import java.util.List; " + 32.464 + "class Test { private void method() { " + 32.465 + "List<? extends List<? extends List<? extends String >>> l; } }", 32.466 + Arrays.asList("List<? extends List<? extends List<? extends String >>> l;", 32.467 + "List<? extends List<? extends List<? extends String >>>", 32.468 + "List", 32.469 + "? extends List<? extends List<? extends String >>", 32.470 + "List<? extends List<? extends String >>", 32.471 + "List", 32.472 + "? extends List<? extends String >", 32.473 + "List<? extends String >", 32.474 + "List", 32.475 + "? extends String", 32.476 + "String")); 32.477 + } 32.478 + 32.479 + public void performWildcardPositionsTest(final String code, 32.480 + List<String> golden) throws IOException { 32.481 + 32.482 + final List<Diagnostic<? extends JavaFileObject>> errors = 32.483 + new LinkedList<Diagnostic<? extends JavaFileObject>>(); 32.484 + 32.485 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 32.486 + new DiagnosticListener<JavaFileObject>() { 32.487 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 32.488 + errors.add(diagnostic); 32.489 + } 32.490 + }, null, null, Arrays.asList(new MyFileObject(code))); 32.491 + 32.492 + final CompilationUnitTree cut = ct.parse().iterator().next(); 32.493 + final List<String> content = new LinkedList<String>(); 32.494 + final Trees trees = Trees.instance(ct); 32.495 + 32.496 + new TreeScanner<Void, Void>() { 32.497 + @Override 32.498 + public Void scan(Tree node, Void p) { 32.499 + if (node == null) { 32.500 + return null; 32.501 + } 32.502 + long start = trees.getSourcePositions().getStartPosition(cut, node); 32.503 + 32.504 + if (start == (-1)) { 32.505 + return null; //synthetic tree 32.506 + } 32.507 + long end = trees.getSourcePositions().getEndPosition(cut, node); 32.508 + String s = code.substring((int) start, (int) end); 32.509 + content.add(s); 32.510 + 32.511 + return super.scan(node, p); 32.512 + } 32.513 + }.scan(((MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0)).getBody().getStatements().get(0), null); 32.514 + 32.515 + assertEquals("performWildcardPositionsTest",golden.toString(), 32.516 + content.toString()); 32.517 + } 32.518 + 32.519 + public void testStartPositionForMethodWithoutModifiers() throws IOException { 32.520 + 32.521 + String code = "package t; class Test { <T> void t() {} }"; 32.522 + 32.523 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.524 + null, Arrays.asList(new MyFileObject(code))); 32.525 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.526 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.527 + MethodTree mt = (MethodTree) clazz.getMembers().get(0); 32.528 + Trees t = Trees.instance(ct); 32.529 + int start = (int) t.getSourcePositions().getStartPosition(cut, mt); 32.530 + int end = (int) t.getSourcePositions().getEndPosition(cut, mt); 32.531 + 32.532 + assertEquals("testStartPositionForMethodWithoutModifiers", 32.533 + "<T> void t() {}", code.substring(start, end)); 32.534 + } 32.535 + 32.536 + public void testStartPositionEnumConstantInit() throws IOException { 32.537 + 32.538 + String code = "package t; enum Test { AAA; }"; 32.539 + 32.540 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.541 + null, Arrays.asList(new MyFileObject(code))); 32.542 + CompilationUnitTree cut = ct.parse().iterator().next(); 32.543 + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 32.544 + VariableTree enumAAA = (VariableTree) clazz.getMembers().get(0); 32.545 + Trees t = Trees.instance(ct); 32.546 + int start = (int) t.getSourcePositions().getStartPosition(cut, 32.547 + enumAAA.getInitializer()); 32.548 + 32.549 + assertEquals("testStartPositionEnumConstantInit", -1, start); 32.550 + } 32.551 + 32.552 + public void testVariableInIfThen1() throws IOException { 32.553 + 32.554 + String code = "package t; class Test { " + 32.555 + "private static void t(String name) { " + 32.556 + "if (name != null) String nn = name.trim(); } }"; 32.557 + 32.558 + DiagnosticCollector<JavaFileObject> coll = 32.559 + new DiagnosticCollector<JavaFileObject>(); 32.560 + 32.561 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 32.562 + null, Arrays.asList(new MyFileObject(code))); 32.563 + 32.564 + ct.parse(); 32.565 + 32.566 + List<String> codes = new LinkedList<String>(); 32.567 + 32.568 + for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 32.569 + codes.add(d.getCode()); 32.570 + } 32.571 + 32.572 + assertEquals("testVariableInIfThen1", 32.573 + Arrays.<String>asList("compiler.err.variable.not.allowed"), 32.574 + codes); 32.575 + } 32.576 + 32.577 + public void testVariableInIfThen2() throws IOException { 32.578 + 32.579 + String code = "package t; class Test { " + 32.580 + "private static void t(String name) { " + 32.581 + "if (name != null) class X {} } }"; 32.582 + DiagnosticCollector<JavaFileObject> coll = 32.583 + new DiagnosticCollector<JavaFileObject>(); 32.584 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 32.585 + null, Arrays.asList(new MyFileObject(code))); 32.586 + 32.587 + ct.parse(); 32.588 + 32.589 + List<String> codes = new LinkedList<String>(); 32.590 + 32.591 + for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 32.592 + codes.add(d.getCode()); 32.593 + } 32.594 + 32.595 + assertEquals("testVariableInIfThen2", 32.596 + Arrays.<String>asList("compiler.err.class.not.allowed"), codes); 32.597 + } 32.598 + 32.599 + public void testVariableInIfThen3() throws IOException { 32.600 + 32.601 + String code = "package t; class Test { "+ 32.602 + "private static void t(String name) { " + 32.603 + "if (name != null) abstract } }"; 32.604 + DiagnosticCollector<JavaFileObject> coll = 32.605 + new DiagnosticCollector<JavaFileObject>(); 32.606 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 32.607 + null, Arrays.asList(new MyFileObject(code))); 32.608 + 32.609 + ct.parse(); 32.610 + 32.611 + List<String> codes = new LinkedList<String>(); 32.612 + 32.613 + for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 32.614 + codes.add(d.getCode()); 32.615 + } 32.616 + 32.617 + assertEquals("testVariableInIfThen3", 32.618 + Arrays.<String>asList("compiler.err.illegal.start.of.expr"), 32.619 + codes); 32.620 + } 32.621 + 32.622 + //see javac bug #6882235, NB bug #98234: 32.623 + public void testMissingExponent() throws IOException { 32.624 + 32.625 + String code = "\nclass Test { { System.err.println(0e); } }"; 32.626 + 32.627 + JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 32.628 + null, Arrays.asList(new MyFileObject(code))); 32.629 + 32.630 + assertNotNull(ct.parse().iterator().next()); 32.631 + } 32.632 + 32.633 + public void testTryResourcePos() throws IOException { 32.634 + 32.635 + final String code = "package t; class Test { " + 32.636 + "{ try (java.io.InputStream in = null) { } } }"; 32.637 + 32.638 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.639 + 32.640 + new TreeScanner<Void, Void>() { 32.641 + @Override 32.642 + public Void visitVariable(VariableTree node, Void p) { 32.643 + if ("in".contentEquals(node.getName())) { 32.644 + JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; 32.645 + System.out.println(node.getName() + "," + var.pos); 32.646 + assertEquals("testTryResourcePos", "in = null) { } } }", 32.647 + code.substring(var.pos)); 32.648 + } 32.649 + return super.visitVariable(node, p); 32.650 + } 32.651 + }.scan(cut, null); 32.652 + } 32.653 + 32.654 + public void testVarPos() throws IOException { 32.655 + 32.656 + final String code = "package t; class Test { " + 32.657 + "{ java.io.InputStream in = null; } }"; 32.658 + 32.659 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.660 + 32.661 + new TreeScanner<Void, Void>() { 32.662 + 32.663 + @Override 32.664 + public Void visitVariable(VariableTree node, Void p) { 32.665 + if ("in".contentEquals(node.getName())) { 32.666 + JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; 32.667 + assertEquals("testVarPos","in = null; } }", 32.668 + code.substring(var.pos)); 32.669 + } 32.670 + return super.visitVariable(node, p); 32.671 + } 32.672 + }.scan(cut, null); 32.673 + } 32.674 + 32.675 + // expected erroneous tree: int x = y;(ERROR); 32.676 + public void testOperatorMissingError() throws IOException { 32.677 + 32.678 + String code = "package test; public class ErrorTest { " 32.679 + + "void method() { int x = y z } }"; 32.680 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.681 + final List<String> values = new ArrayList<>(); 32.682 + final List<String> expectedValues = 32.683 + new ArrayList<>(Arrays.asList("[z]")); 32.684 + 32.685 + new TreeScanner<Void, Void>() { 32.686 + 32.687 + @Override 32.688 + public Void visitErroneous(ErroneousTree node, Void p) { 32.689 + 32.690 + values.add(getErroneousTreeValues(node).toString()); 32.691 + return null; 32.692 + 32.693 + } 32.694 + }.scan(cut, null); 32.695 + 32.696 + assertEquals("testSwitchError: The Erroneous tree " 32.697 + + "error values: " + values 32.698 + + " do not match expected error values: " 32.699 + + expectedValues, values, expectedValues); 32.700 + } 32.701 + 32.702 + //expected erroneous tree: String s = (ERROR); 32.703 + public void testMissingParenthesisError() throws IOException { 32.704 + 32.705 + String code = "package test; public class ErrorTest { " 32.706 + + "void f() {String s = new String; } }"; 32.707 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.708 + final List<String> values = new ArrayList<>(); 32.709 + final List<String> expectedValues = 32.710 + new ArrayList<>(Arrays.asList("[new String()]")); 32.711 + 32.712 + new TreeScanner<Void, Void>() { 32.713 + 32.714 + @Override 32.715 + public Void visitErroneous(ErroneousTree node, Void p) { 32.716 + 32.717 + values.add(getErroneousTreeValues(node).toString()); 32.718 + return null; 32.719 + } 32.720 + }.scan(cut, null); 32.721 + 32.722 + assertEquals("testSwitchError: The Erroneous tree " 32.723 + + "error values: " + values 32.724 + + " do not match expected error values: " 32.725 + + expectedValues, values, expectedValues); 32.726 + } 32.727 + 32.728 + //expected erroneous tree: package test; (ERROR)(ERROR) 32.729 + public void testMissingClassError() throws IOException { 32.730 + 32.731 + String code = "package Test; clas ErrorTest { " 32.732 + + "void f() {String s = new String(); } }"; 32.733 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.734 + final List<String> values = new ArrayList<>(); 32.735 + final List<String> expectedValues = 32.736 + new ArrayList<>(Arrays.asList("[, clas]", "[]")); 32.737 + 32.738 + new TreeScanner<Void, Void>() { 32.739 + 32.740 + @Override 32.741 + public Void visitErroneous(ErroneousTree node, Void p) { 32.742 + 32.743 + values.add(getErroneousTreeValues(node).toString()); 32.744 + return null; 32.745 + } 32.746 + }.scan(cut, null); 32.747 + 32.748 + assertEquals("testSwitchError: The Erroneous tree " 32.749 + + "error values: " + values 32.750 + + " do not match expected error values: " 32.751 + + expectedValues, values, expectedValues); 32.752 + } 32.753 + 32.754 + //expected erroneous tree: void m1(int i) {(ERROR);{(ERROR);} 32.755 + public void testSwitchError() throws IOException { 32.756 + 32.757 + String code = "package test; public class ErrorTest { " 32.758 + + "int numDays; void m1(int i) { switchh {i} { case 1: " 32.759 + + "numDays = 31; break; } } }"; 32.760 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.761 + final List<String> values = new ArrayList<>(); 32.762 + final List<String> expectedValues = 32.763 + new ArrayList<>(Arrays.asList("[switchh]", "[i]")); 32.764 + 32.765 + new TreeScanner<Void, Void>() { 32.766 + 32.767 + @Override 32.768 + public Void visitErroneous(ErroneousTree node, Void p) { 32.769 + 32.770 + values.add(getErroneousTreeValues(node).toString()); 32.771 + return null; 32.772 + } 32.773 + }.scan(cut, null); 32.774 + 32.775 + assertEquals("testSwitchError: The Erroneous tree " 32.776 + + "error values: " + values 32.777 + + " do not match expected error values: " 32.778 + + expectedValues, values, expectedValues); 32.779 + } 32.780 + 32.781 + //expected erroneous tree: class ErrorTest {(ERROR) 32.782 + public void testMethodError() throws IOException { 32.783 + 32.784 + String code = "package Test; class ErrorTest { " 32.785 + + "static final void f) {String s = new String(); } }"; 32.786 + CompilationUnitTree cut = getCompilationUnitTree(code); 32.787 + final List<String> values = new ArrayList<>(); 32.788 + final List<String> expectedValues = 32.789 + new ArrayList<>(Arrays.asList("[\nstatic final void f();]")); 32.790 + 32.791 + new TreeScanner<Void, Void>() { 32.792 + 32.793 + @Override 32.794 + public Void visitErroneous(ErroneousTree node, Void p) { 32.795 + 32.796 + values.add(normalize(getErroneousTreeValues(node).toString())); 32.797 + return null; 32.798 + } 32.799 + }.scan(cut, null); 32.800 + 32.801 + assertEquals("testMethodError: The Erroneous tree " 32.802 + + "error value: " + values 32.803 + + " does not match expected error values: " 32.804 + + expectedValues, values, expectedValues); 32.805 + } 32.806 + 32.807 + void testsNotWorking() throws IOException { 32.808 + 32.809 + // Fails with nb-javac, needs further investigation 32.810 + testPositionBrokenSource126732a(); 32.811 + testPositionBrokenSource126732b(); 32.812 + 32.813 + // Fails, these tests yet to be addressed 32.814 + testVariableInIfThen1(); 32.815 + testVariableInIfThen2(); 32.816 + testPositionForEnumModifiers(); 32.817 + testStartPositionEnumConstantInit(); 32.818 + } 32.819 + void testPositions() throws IOException { 32.820 + testPositionsSane(); 32.821 + testCorrectWilcardPositions(); 32.822 + testPositionAnnotationNoPackage187551(); 32.823 + testPositionForSuperConstructorCalls(); 32.824 + testPreferredPositionForBinaryOp(); 32.825 + testStartPositionForMethodWithoutModifiers(); 32.826 + testVarPos(); 32.827 + testVariableInIfThen3(); 32.828 + testMissingExponent(); 32.829 + testTryResourcePos(); 32.830 + testOperatorMissingError(); 32.831 + testMissingParenthesisError(); 32.832 + testMissingClassError(); 32.833 + testSwitchError(); 32.834 + testMethodError(); 32.835 + } 32.836 + 32.837 + public static void main(String... args) throws IOException { 32.838 + JavacParserTest jpt = new JavacParserTest("JavacParserTest"); 32.839 + jpt.testPositions(); 32.840 + System.out.println("PASS"); 32.841 + } 32.842 +} 32.843 + 32.844 +abstract class TestCase { 32.845 + 32.846 + void assertEquals(String message, int i, int pos) { 32.847 + if (i != pos) { 32.848 + fail(message); 32.849 + } 32.850 + } 32.851 + 32.852 + void assertFalse(String message, boolean empty) { 32.853 + throw new UnsupportedOperationException("Not yet implemented"); 32.854 + } 32.855 + 32.856 + void assertEquals(String message, int i, long l) { 32.857 + if (i != l) { 32.858 + fail(message + ":" + i + ":" + l); 32.859 + } 32.860 + } 32.861 + 32.862 + void assertEquals(String message, Object o1, Object o2) { 32.863 + System.out.println(o1); 32.864 + System.out.println(o2); 32.865 + if (o1 != null && o2 != null && !o1.equals(o2)) { 32.866 + fail(message); 32.867 + } 32.868 + if (o1 == null && o2 != null) { 32.869 + fail(message); 32.870 + } 32.871 + } 32.872 + 32.873 + void assertNotNull(Object o) { 32.874 + if (o == null) { 32.875 + fail(); 32.876 + } 32.877 + } 32.878 + 32.879 + void fail() { 32.880 + fail("test failed"); 32.881 + } 32.882 + 32.883 + void fail(String message) { 32.884 + throw new RuntimeException(message); 32.885 + } 32.886 +}
33.1 --- a/test/tools/javac/parser/netbeans/JavacParserTest.java Thu Dec 15 15:47:47 2011 -0800 33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 33.3 @@ -1,716 +0,0 @@ 33.4 -/* 33.5 - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 33.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.7 - * 33.8 - * This code is free software; you can redistribute it and/or modify it 33.9 - * under the terms of the GNU General Public License version 2 only, as 33.10 - * published by the Free Software Foundation. 33.11 - * 33.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 33.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 33.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 33.15 - * version 2 for more details (a copy is included in the LICENSE file that 33.16 - * accompanied this code). 33.17 - * 33.18 - * You should have received a copy of the GNU General Public License version 33.19 - * 2 along with this work; if not, write to the Free Software Foundation, 33.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 33.21 - * 33.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 33.23 - * or visit www.oracle.com if you need additional information or have any 33.24 - * questions. 33.25 - */ 33.26 - 33.27 -/* 33.28 - * @test 33.29 - * @bug 7073631 33.30 - * @summary tests error and diagnostics positions 33.31 - * @author jan.lahoda@oracle.com 33.32 - */ 33.33 - 33.34 -import com.sun.source.tree.BinaryTree; 33.35 -import com.sun.source.tree.BlockTree; 33.36 -import com.sun.source.tree.ClassTree; 33.37 -import com.sun.source.tree.CompilationUnitTree; 33.38 -import com.sun.source.tree.ExpressionStatementTree; 33.39 -import com.sun.source.tree.ExpressionTree; 33.40 -import com.sun.source.tree.MethodInvocationTree; 33.41 -import com.sun.source.tree.MethodTree; 33.42 -import com.sun.source.tree.ModifiersTree; 33.43 -import com.sun.source.tree.StatementTree; 33.44 -import com.sun.source.tree.Tree; 33.45 -import com.sun.source.tree.Tree.Kind; 33.46 -import com.sun.source.tree.VariableTree; 33.47 -import com.sun.source.tree.WhileLoopTree; 33.48 -import com.sun.source.util.SourcePositions; 33.49 -import com.sun.source.util.TreeScanner; 33.50 -import com.sun.source.util.Trees; 33.51 -import com.sun.tools.javac.api.JavacTaskImpl; 33.52 -import com.sun.tools.javac.tree.JCTree; 33.53 -import java.io.IOException; 33.54 -import java.net.URI; 33.55 -import java.util.Arrays; 33.56 -import java.util.LinkedList; 33.57 -import java.util.List; 33.58 -import javax.tools.Diagnostic; 33.59 -import javax.tools.DiagnosticCollector; 33.60 -import javax.tools.DiagnosticListener; 33.61 -import javax.tools.JavaCompiler; 33.62 -import javax.tools.JavaFileObject; 33.63 -import javax.tools.SimpleJavaFileObject; 33.64 -import javax.tools.ToolProvider; 33.65 - 33.66 -public class JavacParserTest extends TestCase { 33.67 - final JavaCompiler tool; 33.68 - public JavacParserTest(String testName) { 33.69 - tool = ToolProvider.getSystemJavaCompiler(); 33.70 - System.out.println("java.home=" + System.getProperty("java.home")); 33.71 - } 33.72 - 33.73 - static class MyFileObject extends SimpleJavaFileObject { 33.74 - 33.75 - private String text; 33.76 - 33.77 - public MyFileObject(String text) { 33.78 - super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 33.79 - this.text = text; 33.80 - } 33.81 - 33.82 - @Override 33.83 - public CharSequence getCharContent(boolean ignoreEncodingErrors) { 33.84 - return text; 33.85 - } 33.86 - } 33.87 - 33.88 - public void testPositionForSuperConstructorCalls() throws IOException { 33.89 - assert tool != null; 33.90 - 33.91 - String code = "package test; public class Test {public Test() {super();}}"; 33.92 - 33.93 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.94 - null, Arrays.asList(new MyFileObject(code))); 33.95 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.96 - SourcePositions pos = Trees.instance(ct).getSourcePositions(); 33.97 - 33.98 - MethodTree method = 33.99 - (MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0); 33.100 - ExpressionStatementTree es = 33.101 - (ExpressionStatementTree) method.getBody().getStatements().get(0); 33.102 - 33.103 - assertEquals("testPositionForSuperConstructorCalls", 33.104 - 72 - 24, pos.getStartPosition(cut, es)); 33.105 - assertEquals("testPositionForSuperConstructorCalls", 33.106 - 80 - 24, pos.getEndPosition(cut, es)); 33.107 - 33.108 - MethodInvocationTree mit = (MethodInvocationTree) es.getExpression(); 33.109 - 33.110 - assertEquals("testPositionForSuperConstructorCalls", 33.111 - 72 - 24, pos.getStartPosition(cut, mit)); 33.112 - assertEquals("testPositionForSuperConstructorCalls", 33.113 - 79 - 24, pos.getEndPosition(cut, mit)); 33.114 - 33.115 - assertEquals("testPositionForSuperConstructorCalls", 33.116 - 72 - 24, pos.getStartPosition(cut, mit.getMethodSelect())); 33.117 - assertEquals("testPositionForSuperConstructorCalls", 33.118 - 77 - 24, pos.getEndPosition(cut, mit.getMethodSelect())); 33.119 - 33.120 - } 33.121 - 33.122 - public void testPositionForEnumModifiers() throws IOException { 33.123 - 33.124 - String code = "package test; public enum Test {A;}"; 33.125 - 33.126 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.127 - null, Arrays.asList(new MyFileObject(code))); 33.128 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.129 - SourcePositions pos = Trees.instance(ct).getSourcePositions(); 33.130 - 33.131 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.132 - ModifiersTree mt = clazz.getModifiers(); 33.133 - 33.134 - assertEquals("testPositionForEnumModifiers", 33.135 - 38 - 24, pos.getStartPosition(cut, mt)); 33.136 - assertEquals("testPositionForEnumModifiers", 33.137 - 44 - 24, pos.getEndPosition(cut, mt)); 33.138 - } 33.139 - 33.140 - public void testNewClassWithEnclosing() throws IOException { 33.141 - 33.142 - 33.143 - String code = "package test; class Test { " + 33.144 - "class d {} private void method() { " + 33.145 - "Object o = Test.this.new d(); } }"; 33.146 - 33.147 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.148 - null, Arrays.asList(new MyFileObject(code))); 33.149 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.150 - SourcePositions pos = Trees.instance(ct).getSourcePositions(); 33.151 - 33.152 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.153 - ExpressionTree est = 33.154 - ((VariableTree) ((MethodTree) clazz.getMembers().get(1)).getBody().getStatements().get(0)).getInitializer(); 33.155 - 33.156 - assertEquals("testNewClassWithEnclosing", 33.157 - 97 - 24, pos.getStartPosition(cut, est)); 33.158 - assertEquals("testNewClassWithEnclosing", 33.159 - 114 - 24, pos.getEndPosition(cut, est)); 33.160 - } 33.161 - 33.162 - public void testPreferredPositionForBinaryOp() throws IOException { 33.163 - 33.164 - String code = "package test; public class Test {" + 33.165 - "private void test() {" + 33.166 - "Object o = null; boolean b = o != null && o instanceof String;" + 33.167 - "} private Test() {}}"; 33.168 - 33.169 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.170 - null, Arrays.asList(new MyFileObject(code))); 33.171 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.172 - 33.173 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.174 - MethodTree method = (MethodTree) clazz.getMembers().get(0); 33.175 - VariableTree condSt = (VariableTree) method.getBody().getStatements().get(1); 33.176 - BinaryTree cond = (BinaryTree) condSt.getInitializer(); 33.177 - 33.178 - JCTree condJC = (JCTree) cond; 33.179 - 33.180 - assertEquals("testNewClassWithEnclosing", 33.181 - 117 - 24, condJC.pos); 33.182 - } 33.183 - 33.184 - public void testPositionBrokenSource126732a() throws IOException { 33.185 - String[] commands = new String[]{ 33.186 - "return Runnable()", 33.187 - "do { } while (true)", 33.188 - "throw UnsupportedOperationException()", 33.189 - "assert true", 33.190 - "1 + 1",}; 33.191 - 33.192 - for (String command : commands) { 33.193 - 33.194 - String code = "package test;\n" 33.195 - + "public class Test {\n" 33.196 - + " public static void test() {\n" 33.197 - + " " + command + " {\n" 33.198 - + " new Runnable() {\n" 33.199 - + " };\n" 33.200 - + " }\n" 33.201 - + "}"; 33.202 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, 33.203 - null, null, Arrays.asList(new MyFileObject(code))); 33.204 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.205 - 33.206 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.207 - MethodTree method = (MethodTree) clazz.getMembers().get(0); 33.208 - List<? extends StatementTree> statements = 33.209 - method.getBody().getStatements(); 33.210 - 33.211 - StatementTree ret = statements.get(0); 33.212 - StatementTree block = statements.get(1); 33.213 - 33.214 - Trees t = Trees.instance(ct); 33.215 - int len = code.indexOf(command + " {") + (command + " ").length(); 33.216 - assertEquals(command, len, 33.217 - t.getSourcePositions().getEndPosition(cut, ret)); 33.218 - assertEquals(command, len, 33.219 - t.getSourcePositions().getStartPosition(cut, block)); 33.220 - } 33.221 - } 33.222 - 33.223 - public void testPositionBrokenSource126732b() throws IOException { 33.224 - String[] commands = new String[]{ 33.225 - "break", 33.226 - "break A", 33.227 - "continue ", 33.228 - "continue A",}; 33.229 - 33.230 - for (String command : commands) { 33.231 - 33.232 - String code = "package test;\n" 33.233 - + "public class Test {\n" 33.234 - + " public static void test() {\n" 33.235 - + " while (true) {\n" 33.236 - + " " + command + " {\n" 33.237 - + " new Runnable() {\n" 33.238 - + " };\n" 33.239 - + " }\n" 33.240 - + " }\n" 33.241 - + "}"; 33.242 - 33.243 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, 33.244 - null, null, Arrays.asList(new MyFileObject(code))); 33.245 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.246 - 33.247 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.248 - MethodTree method = (MethodTree) clazz.getMembers().get(0); 33.249 - List<? extends StatementTree> statements = 33.250 - ((BlockTree) ((WhileLoopTree) method.getBody().getStatements().get(0)).getStatement()).getStatements(); 33.251 - 33.252 - StatementTree ret = statements.get(0); 33.253 - StatementTree block = statements.get(1); 33.254 - 33.255 - Trees t = Trees.instance(ct); 33.256 - int len = code.indexOf(command + " {") + (command + " ").length(); 33.257 - assertEquals(command, len, 33.258 - t.getSourcePositions().getEndPosition(cut, ret)); 33.259 - assertEquals(command, len, 33.260 - t.getSourcePositions().getStartPosition(cut, block)); 33.261 - } 33.262 - } 33.263 - 33.264 - public void testErrorRecoveryForEnhancedForLoop142381() throws IOException { 33.265 - 33.266 - String code = "package test; class Test { " + 33.267 - "private void method() { " + 33.268 - "java.util.Set<String> s = null; for (a : s) {} } }"; 33.269 - 33.270 - final List<Diagnostic<? extends JavaFileObject>> errors = 33.271 - new LinkedList<Diagnostic<? extends JavaFileObject>>(); 33.272 - 33.273 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 33.274 - new DiagnosticListener<JavaFileObject>() { 33.275 - public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 33.276 - errors.add(diagnostic); 33.277 - } 33.278 - }, null, null, Arrays.asList(new MyFileObject(code))); 33.279 - 33.280 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.281 - 33.282 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.283 - StatementTree forStatement = 33.284 - ((MethodTree) clazz.getMembers().get(0)).getBody().getStatements().get(1); 33.285 - 33.286 - assertEquals("testErrorRecoveryForEnhancedForLoop142381", 33.287 - Kind.ENHANCED_FOR_LOOP, forStatement.getKind()); 33.288 - assertFalse("testErrorRecoveryForEnhancedForLoop142381", errors.isEmpty()); 33.289 - } 33.290 - 33.291 - public void testPositionAnnotationNoPackage187551() throws IOException { 33.292 - 33.293 - String code = "\n@interface Test {}"; 33.294 - 33.295 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.296 - null, Arrays.asList(new MyFileObject(code))); 33.297 - 33.298 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.299 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.300 - Trees t = Trees.instance(ct); 33.301 - 33.302 - assertEquals("testPositionAnnotationNoPackage187551", 33.303 - 1, t.getSourcePositions().getStartPosition(cut, clazz)); 33.304 - } 33.305 - 33.306 - public void testPositionsSane() throws IOException { 33.307 - performPositionsSanityTest("package test; class Test { " + 33.308 - "private void method() { " + 33.309 - "java.util.List<? extends java.util.List<? extends String>> l; " + 33.310 - "} }"); 33.311 - performPositionsSanityTest("package test; class Test { " + 33.312 - "private void method() { " + 33.313 - "java.util.List<? super java.util.List<? super String>> l; " + 33.314 - "} }"); 33.315 - performPositionsSanityTest("package test; class Test { " + 33.316 - "private void method() { " + 33.317 - "java.util.List<? super java.util.List<?>> l; } }"); 33.318 - } 33.319 - 33.320 - private void performPositionsSanityTest(String code) throws IOException { 33.321 - 33.322 - final List<Diagnostic<? extends JavaFileObject>> errors = 33.323 - new LinkedList<Diagnostic<? extends JavaFileObject>>(); 33.324 - 33.325 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 33.326 - new DiagnosticListener<JavaFileObject>() { 33.327 - 33.328 - public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 33.329 - errors.add(diagnostic); 33.330 - } 33.331 - }, null, null, Arrays.asList(new MyFileObject(code))); 33.332 - 33.333 - final CompilationUnitTree cut = ct.parse().iterator().next(); 33.334 - final Trees trees = Trees.instance(ct); 33.335 - 33.336 - new TreeScanner<Void, Void>() { 33.337 - 33.338 - private long parentStart = 0; 33.339 - private long parentEnd = Integer.MAX_VALUE; 33.340 - 33.341 - @Override 33.342 - public Void scan(Tree node, Void p) { 33.343 - if (node == null) { 33.344 - return null; 33.345 - } 33.346 - 33.347 - long start = trees.getSourcePositions().getStartPosition(cut, node); 33.348 - 33.349 - if (start == (-1)) { 33.350 - return null; //synthetic tree 33.351 - } 33.352 - assertTrue(node.toString() + ":" + start + "/" + parentStart, 33.353 - parentStart <= start); 33.354 - 33.355 - long prevParentStart = parentStart; 33.356 - 33.357 - parentStart = start; 33.358 - 33.359 - long end = trees.getSourcePositions().getEndPosition(cut, node); 33.360 - 33.361 - assertTrue(node.toString() + ":" + end + "/" + parentEnd, 33.362 - end <= parentEnd); 33.363 - 33.364 - long prevParentEnd = parentEnd; 33.365 - 33.366 - parentEnd = end; 33.367 - 33.368 - super.scan(node, p); 33.369 - 33.370 - parentStart = prevParentStart; 33.371 - parentEnd = prevParentEnd; 33.372 - 33.373 - return null; 33.374 - } 33.375 - 33.376 - private void assertTrue(String message, boolean b) { 33.377 - if (!b) fail(message); 33.378 - } 33.379 - }.scan(cut, null); 33.380 - } 33.381 - 33.382 - public void testCorrectWilcardPositions() throws IOException { 33.383 - performWildcardPositionsTest("package test; import java.util.List; " + 33.384 - "class Test { private void method() { List<? extends List<? extends String>> l; } }", 33.385 - 33.386 - Arrays.asList("List<? extends List<? extends String>> l;", 33.387 - "List<? extends List<? extends String>>", 33.388 - "List", 33.389 - "? extends List<? extends String>", 33.390 - "List<? extends String>", 33.391 - "List", 33.392 - "? extends String", 33.393 - "String")); 33.394 - performWildcardPositionsTest("package test; import java.util.List; " + 33.395 - "class Test { private void method() { List<? super List<? super String>> l; } }", 33.396 - 33.397 - Arrays.asList("List<? super List<? super String>> l;", 33.398 - "List<? super List<? super String>>", 33.399 - "List", 33.400 - "? super List<? super String>", 33.401 - "List<? super String>", 33.402 - "List", 33.403 - "? super String", 33.404 - "String")); 33.405 - performWildcardPositionsTest("package test; import java.util.List; " + 33.406 - "class Test { private void method() { List<? super List<?>> l; } }", 33.407 - 33.408 - Arrays.asList("List<? super List<?>> l;", 33.409 - "List<? super List<?>>", 33.410 - "List", 33.411 - "? super List<?>", 33.412 - "List<?>", 33.413 - "List", 33.414 - "?")); 33.415 - performWildcardPositionsTest("package test; import java.util.List; " + 33.416 - "class Test { private void method() { " + 33.417 - "List<? extends List<? extends List<? extends String>>> l; } }", 33.418 - 33.419 - Arrays.asList("List<? extends List<? extends List<? extends String>>> l;", 33.420 - "List<? extends List<? extends List<? extends String>>>", 33.421 - "List", 33.422 - "? extends List<? extends List<? extends String>>", 33.423 - "List<? extends List<? extends String>>", 33.424 - "List", 33.425 - "? extends List<? extends String>", 33.426 - "List<? extends String>", 33.427 - "List", 33.428 - "? extends String", 33.429 - "String")); 33.430 - performWildcardPositionsTest("package test; import java.util.List; " + 33.431 - "class Test { private void method() { " + 33.432 - "List<? extends List<? extends List<? extends String >>> l; } }", 33.433 - Arrays.asList("List<? extends List<? extends List<? extends String >>> l;", 33.434 - "List<? extends List<? extends List<? extends String >>>", 33.435 - "List", 33.436 - "? extends List<? extends List<? extends String >>", 33.437 - "List<? extends List<? extends String >>", 33.438 - "List", 33.439 - "? extends List<? extends String >", 33.440 - "List<? extends String >", 33.441 - "List", 33.442 - "? extends String", 33.443 - "String")); 33.444 - } 33.445 - 33.446 - public void performWildcardPositionsTest(final String code, 33.447 - List<String> golden) throws IOException { 33.448 - 33.449 - final List<Diagnostic<? extends JavaFileObject>> errors = 33.450 - new LinkedList<Diagnostic<? extends JavaFileObject>>(); 33.451 - 33.452 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, 33.453 - new DiagnosticListener<JavaFileObject>() { 33.454 - public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 33.455 - errors.add(diagnostic); 33.456 - } 33.457 - }, null, null, Arrays.asList(new MyFileObject(code))); 33.458 - 33.459 - final CompilationUnitTree cut = ct.parse().iterator().next(); 33.460 - final List<String> content = new LinkedList<String>(); 33.461 - final Trees trees = Trees.instance(ct); 33.462 - 33.463 - new TreeScanner<Void, Void>() { 33.464 - @Override 33.465 - public Void scan(Tree node, Void p) { 33.466 - if (node == null) { 33.467 - return null; 33.468 - } 33.469 - long start = trees.getSourcePositions().getStartPosition(cut, node); 33.470 - 33.471 - if (start == (-1)) { 33.472 - return null; //synthetic tree 33.473 - } 33.474 - long end = trees.getSourcePositions().getEndPosition(cut, node); 33.475 - String s = code.substring((int) start, (int) end); 33.476 - content.add(s); 33.477 - 33.478 - return super.scan(node, p); 33.479 - } 33.480 - }.scan(((MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0)).getBody().getStatements().get(0), null); 33.481 - 33.482 - assertEquals("performWildcardPositionsTest",golden.toString(), 33.483 - content.toString()); 33.484 - } 33.485 - 33.486 - public void testStartPositionForMethodWithoutModifiers() throws IOException { 33.487 - 33.488 - String code = "package t; class Test { <T> void t() {} }"; 33.489 - 33.490 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.491 - null, Arrays.asList(new MyFileObject(code))); 33.492 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.493 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.494 - MethodTree mt = (MethodTree) clazz.getMembers().get(0); 33.495 - Trees t = Trees.instance(ct); 33.496 - int start = (int) t.getSourcePositions().getStartPosition(cut, mt); 33.497 - int end = (int) t.getSourcePositions().getEndPosition(cut, mt); 33.498 - 33.499 - assertEquals("testStartPositionForMethodWithoutModifiers", 33.500 - "<T> void t() {}", code.substring(start, end)); 33.501 - } 33.502 - 33.503 - public void testStartPositionEnumConstantInit() throws IOException { 33.504 - 33.505 - String code = "package t; enum Test { AAA; }"; 33.506 - 33.507 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.508 - null, Arrays.asList(new MyFileObject(code))); 33.509 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.510 - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); 33.511 - VariableTree enumAAA = (VariableTree) clazz.getMembers().get(0); 33.512 - Trees t = Trees.instance(ct); 33.513 - int start = (int) t.getSourcePositions().getStartPosition(cut, 33.514 - enumAAA.getInitializer()); 33.515 - 33.516 - assertEquals("testStartPositionEnumConstantInit", -1, start); 33.517 - } 33.518 - 33.519 - public void testVariableInIfThen1() throws IOException { 33.520 - 33.521 - String code = "package t; class Test { " + 33.522 - "private static void t(String name) { " + 33.523 - "if (name != null) String nn = name.trim(); } }"; 33.524 - 33.525 - DiagnosticCollector<JavaFileObject> coll = 33.526 - new DiagnosticCollector<JavaFileObject>(); 33.527 - 33.528 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 33.529 - null, Arrays.asList(new MyFileObject(code))); 33.530 - 33.531 - ct.parse(); 33.532 - 33.533 - List<String> codes = new LinkedList<String>(); 33.534 - 33.535 - for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 33.536 - codes.add(d.getCode()); 33.537 - } 33.538 - 33.539 - assertEquals("testVariableInIfThen1", 33.540 - Arrays.<String>asList("compiler.err.variable.not.allowed"), 33.541 - codes); 33.542 - } 33.543 - 33.544 - public void testVariableInIfThen2() throws IOException { 33.545 - 33.546 - String code = "package t; class Test { " + 33.547 - "private static void t(String name) { " + 33.548 - "if (name != null) class X {} } }"; 33.549 - DiagnosticCollector<JavaFileObject> coll = 33.550 - new DiagnosticCollector<JavaFileObject>(); 33.551 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 33.552 - null, Arrays.asList(new MyFileObject(code))); 33.553 - 33.554 - ct.parse(); 33.555 - 33.556 - List<String> codes = new LinkedList<String>(); 33.557 - 33.558 - for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 33.559 - codes.add(d.getCode()); 33.560 - } 33.561 - 33.562 - assertEquals("testVariableInIfThen2", 33.563 - Arrays.<String>asList("compiler.err.class.not.allowed"), codes); 33.564 - } 33.565 - 33.566 - public void testVariableInIfThen3() throws IOException { 33.567 - 33.568 - String code = "package t; class Test { "+ 33.569 - "private static void t(String name) { " + 33.570 - "if (name != null) abstract } }"; 33.571 - DiagnosticCollector<JavaFileObject> coll = 33.572 - new DiagnosticCollector<JavaFileObject>(); 33.573 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null, 33.574 - null, Arrays.asList(new MyFileObject(code))); 33.575 - 33.576 - ct.parse(); 33.577 - 33.578 - List<String> codes = new LinkedList<String>(); 33.579 - 33.580 - for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) { 33.581 - codes.add(d.getCode()); 33.582 - } 33.583 - 33.584 - assertEquals("testVariableInIfThen3", 33.585 - Arrays.<String>asList("compiler.err.illegal.start.of.expr"), 33.586 - codes); 33.587 - } 33.588 - 33.589 - //see javac bug #6882235, NB bug #98234: 33.590 - public void testMissingExponent() throws IOException { 33.591 - 33.592 - String code = "\nclass Test { { System.err.println(0e); } }"; 33.593 - 33.594 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.595 - null, Arrays.asList(new MyFileObject(code))); 33.596 - 33.597 - assertNotNull(ct.parse().iterator().next()); 33.598 - } 33.599 - 33.600 - public void testTryResourcePos() throws IOException { 33.601 - 33.602 - final String code = "package t; class Test { " + 33.603 - "{ try (java.io.InputStream in = null) { } } }"; 33.604 - 33.605 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.606 - null, Arrays.asList(new MyFileObject(code))); 33.607 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.608 - 33.609 - new TreeScanner<Void, Void>() { 33.610 - @Override 33.611 - public Void visitVariable(VariableTree node, Void p) { 33.612 - if ("in".contentEquals(node.getName())) { 33.613 - JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; 33.614 - System.out.println(node.getName() + "," + var.pos); 33.615 - assertEquals("testTryResourcePos", "in = null) { } } }", 33.616 - code.substring(var.pos)); 33.617 - } 33.618 - return super.visitVariable(node, p); 33.619 - } 33.620 - }.scan(cut, null); 33.621 - } 33.622 - 33.623 - public void testVarPos() throws IOException { 33.624 - 33.625 - final String code = "package t; class Test { " + 33.626 - "{ java.io.InputStream in = null; } }"; 33.627 - 33.628 - JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null, 33.629 - null, Arrays.asList(new MyFileObject(code))); 33.630 - CompilationUnitTree cut = ct.parse().iterator().next(); 33.631 - 33.632 - new TreeScanner<Void, Void>() { 33.633 - 33.634 - @Override 33.635 - public Void visitVariable(VariableTree node, Void p) { 33.636 - if ("in".contentEquals(node.getName())) { 33.637 - JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node; 33.638 - assertEquals("testVarPos","in = null; } }", 33.639 - code.substring(var.pos)); 33.640 - } 33.641 - return super.visitVariable(node, p); 33.642 - } 33.643 - }.scan(cut, null); 33.644 - } 33.645 - 33.646 - void testsNotWorking() throws IOException { 33.647 - 33.648 - // Fails with nb-javac, needs further investigation 33.649 - testPositionBrokenSource126732a(); 33.650 - testPositionBrokenSource126732b(); 33.651 - 33.652 - // Fails, these tests yet to be addressed 33.653 - testVariableInIfThen1(); 33.654 - testVariableInIfThen2(); 33.655 - testPositionForEnumModifiers(); 33.656 - testStartPositionEnumConstantInit(); 33.657 - } 33.658 - void testPositions() throws IOException { 33.659 - testPositionsSane(); 33.660 - testCorrectWilcardPositions(); 33.661 - testPositionAnnotationNoPackage187551(); 33.662 - testPositionForSuperConstructorCalls(); 33.663 - testPreferredPositionForBinaryOp(); 33.664 - testStartPositionForMethodWithoutModifiers(); 33.665 - testVarPos(); 33.666 - testVariableInIfThen3(); 33.667 - testTryResourcePos(); 33.668 - } 33.669 - 33.670 - public static void main(String... args) throws IOException { 33.671 - JavacParserTest jpt = new JavacParserTest("JavacParserTest"); 33.672 - jpt.testPositions(); 33.673 - System.out.println("PASS"); 33.674 - } 33.675 -} 33.676 - 33.677 -abstract class TestCase { 33.678 - 33.679 - void assertEquals(String message, int i, int pos) { 33.680 - if (i != pos) { 33.681 - fail(message); 33.682 - } 33.683 - } 33.684 - 33.685 - void assertFalse(String message, boolean empty) { 33.686 - throw new UnsupportedOperationException("Not yet implemented"); 33.687 - } 33.688 - 33.689 - void assertEquals(String message, int i, long l) { 33.690 - if (i != l) { 33.691 - fail(message + ":" + i + ":" + l); 33.692 - } 33.693 - } 33.694 - 33.695 - void assertEquals(String message, Object o1, Object o2) { 33.696 - System.out.println(o1); 33.697 - System.out.println(o2); 33.698 - if (o1 != null && o2 != null && !o1.equals(o2)) { 33.699 - fail(message); 33.700 - } 33.701 - if (o1 == null && o2 != null) { 33.702 - fail(message); 33.703 - } 33.704 - } 33.705 - 33.706 - void assertNotNull(Object o) { 33.707 - if (o == null) { 33.708 - fail(); 33.709 - } 33.710 - } 33.711 - 33.712 - void fail() { 33.713 - fail("test failed"); 33.714 - } 33.715 - 33.716 - void fail(String message) { 33.717 - throw new RuntimeException(message); 33.718 - } 33.719 -}
34.1 --- a/test/tools/javac/quid/T6999438.out Thu Dec 15 15:47:47 2011 -0800 34.2 +++ b/test/tools/javac/quid/T6999438.out Thu Dec 15 15:57:51 2011 -0800 34.3 @@ -1,4 +1,4 @@ 34.4 -T6999438.java:8:9: compiler.err.illegal.char: 35 34.5 +T6999438.java:8:8: compiler.err.expected: token.identifier 34.6 T6999438.java:8:10: compiler.err.illegal.start.of.type 34.7 T6999438.java:8:25: compiler.err.expected: token.identifier 34.8 T6999438.java:8:26: compiler.err.expected: ';'