Mon, 28 Nov 2011 16:05:46 +0000
7115052: Add parser support for method references
Summary: Add support for parsing method references to JavacParser
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/javac/code/Source.java Mon Nov 28 15:56:42 2011 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/code/Source.java Mon Nov 28 16:05:46 2011 +0000 1.3 @@ -197,6 +197,9 @@ 1.4 public boolean allowLambda() { 1.5 return compareTo(JDK1_8) >= 0; 1.6 } 1.7 + public boolean allowMethodReferences() { 1.8 + return compareTo(JDK1_8) >= 0; 1.9 + } 1.10 public static SourceVersion toSourceVersion(Source source) { 1.11 switch(source) { 1.12 case JDK1_2:
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Nov 28 15:56:42 2011 +0000 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Mon Nov 28 16:05:46 2011 +0000 2.3 @@ -1980,6 +1980,11 @@ 2.4 throw new UnsupportedOperationException("Lambda expression not supported yet"); 2.5 } 2.6 2.7 + @Override 2.8 + public void visitReference(JCMemberReference that) { 2.9 + throw new UnsupportedOperationException("Member references not supported yet"); 2.10 + } 2.11 + 2.12 public void visitParens(JCParens tree) { 2.13 Type owntype = attribTree(tree.expr, env, pkind, pt); 2.14 result = check(tree, owntype, pkind, pkind, pt);
3.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Mon Nov 28 15:56:42 2011 +0000 3.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Mon Nov 28 16:05:46 2011 +0000 3.3 @@ -637,6 +637,10 @@ 3.4 lexError(pos, "unclosed.str.lit"); 3.5 } 3.6 break loop; 3.7 + case '#': 3.8 + reader.scanChar(); 3.9 + tk = TokenKind.HASH; 3.10 + break loop; 3.11 default: 3.12 if (isSpecial(reader.ch)) { 3.13 scanOperator();
4.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Nov 28 15:56:42 2011 +0000 4.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Nov 28 16:05:46 2011 +0000 4.3 @@ -27,6 +27,8 @@ 4.4 4.5 import java.util.*; 4.6 4.7 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 4.8 + 4.9 import com.sun.tools.javac.code.*; 4.10 import com.sun.tools.javac.parser.Tokens.*; 4.11 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; 4.12 @@ -112,6 +114,8 @@ 4.13 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true); 4.14 this.allowLambda = source.allowLambda() && 4.15 fac.options.isSet("allowLambda"); 4.16 + this.allowMethodReferences = source.allowMethodReferences() && 4.17 + fac.options.isSet("allowMethodReferences"); 4.18 this.keepDocComments = keepDocComments; 4.19 docComments = keepDocComments ? new HashMap<JCTree,String>() : null; 4.20 this.keepLineMap = keepLineMap; 4.21 @@ -172,6 +176,10 @@ 4.22 */ 4.23 boolean allowLambda; 4.24 4.25 + /** Switch: should we allow method/constructor references? 4.26 + */ 4.27 + boolean allowMethodReferences; 4.28 + 4.29 /** Switch: should we keep docComments? 4.30 */ 4.31 boolean keepDocComments; 4.32 @@ -779,7 +787,7 @@ 4.33 top++; 4.34 topOp = token; 4.35 nextToken(); 4.36 - odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3(); 4.37 + odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3NoParams(); 4.38 while (top > 0 && prec(topOp.kind) >= prec(token.kind)) { 4.39 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1], 4.40 odStack[top]); 4.41 @@ -882,6 +890,7 @@ 4.42 * | "(" Arguments ")" "->" ( Expression | Block ) 4.43 * | Ident "->" ( Expression | Block ) 4.44 * | Ident { "." Ident } 4.45 + * | Expression3 MemberReferenceSuffix 4.46 * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 4.47 * | Arguments 4.48 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 4.49 @@ -922,7 +931,7 @@ 4.50 mode = EXPR; 4.51 t = literal(names.hyphen, pos); 4.52 } else { 4.53 - t = term3(); 4.54 + t = term3NoParams(); 4.55 return F.at(pos).Unary(unoptag(tk), t); 4.56 } 4.57 } else return illegal(); 4.58 @@ -938,8 +947,8 @@ 4.59 break; 4.60 } else { 4.61 nextToken(); 4.62 - mode = EXPR | TYPE | NOPARAMS; 4.63 - t = term3(); 4.64 + mode = EXPR | TYPE; 4.65 + t = term3NoParams(); 4.66 if ((mode & TYPE) != 0 && token.kind == LT) { 4.67 // Could be a cast to a parameterized type 4.68 JCTree.Tag op = JCTree.Tag.LT; 4.69 @@ -1002,7 +1011,7 @@ 4.70 lastmode = mode; 4.71 mode = EXPR; 4.72 if ((lastmode & EXPR) == 0) { 4.73 - JCExpression t1 = term3(); 4.74 + JCExpression t1 = term3NoParams(); 4.75 return F.at(pos).TypeCast(t, t1); 4.76 } else if ((lastmode & TYPE) != 0) { 4.77 switch (token.kind) { 4.78 @@ -1015,7 +1024,7 @@ 4.79 case NEW: case IDENTIFIER: case ASSERT: case ENUM: 4.80 case BYTE: case SHORT: case CHAR: case INT: 4.81 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: 4.82 - JCExpression t1 = term3(); 4.83 + JCExpression t1 = term3NoParams(); 4.84 return F.at(pos).TypeCast(t, t1); 4.85 } 4.86 } 4.87 @@ -1134,6 +1143,49 @@ 4.88 // typeArgs saved for next loop iteration. 4.89 t = toP(F.at(pos).Select(t, ident())); 4.90 break; 4.91 + case LT: 4.92 + if ((mode & (TYPE | NOPARAMS)) == 0) { 4.93 + //could be an unbound method reference whose qualifier 4.94 + //is a generic type i.e. A<S>#m 4.95 + mode = EXPR | TYPE; 4.96 + JCTree.Tag op = JCTree.Tag.LT; 4.97 + int pos1 = token.pos; 4.98 + nextToken(); 4.99 + mode |= EXPR | TYPE | TYPEARG; 4.100 + JCExpression t1 = term3(); 4.101 + if ((mode & TYPE) != 0 && 4.102 + (token.kind == COMMA || token.kind == GT)) { 4.103 + mode = TYPE; 4.104 + ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 4.105 + args.append(t1); 4.106 + while (token.kind == COMMA) { 4.107 + nextToken(); 4.108 + args.append(typeArgument()); 4.109 + } 4.110 + accept(GT); 4.111 + t = toP(F.at(pos1).TypeApply(t, args.toList())); 4.112 + checkGenerics(); 4.113 + while (token.kind == DOT) { 4.114 + nextToken(); 4.115 + mode = TYPE; 4.116 + t = toP(F.at(token.pos).Select(t, ident())); 4.117 + t = typeArgumentsOpt(t); 4.118 + } 4.119 + if (token.kind != HASH) { 4.120 + //method reference expected here 4.121 + t = illegal(); 4.122 + } 4.123 + mode = EXPR; 4.124 + break; 4.125 + } else if ((mode & EXPR) != 0) { 4.126 + //rollback - it was a binary expression 4.127 + mode = EXPR; 4.128 + JCExpression e = term2Rest(t1, TreeInfo.shiftPrec); 4.129 + t = F.at(pos1).Binary(op, t, e); 4.130 + t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 4.131 + } 4.132 + } 4.133 + break loop; 4.134 default: 4.135 break loop; 4.136 } 4.137 @@ -1173,6 +1225,15 @@ 4.138 return term3Rest(t, typeArgs); 4.139 } 4.140 4.141 + JCExpression term3NoParams() { 4.142 + try { 4.143 + mode |= NOPARAMS; 4.144 + return term3(); 4.145 + } finally { 4.146 + mode &= ~NOPARAMS; 4.147 + } 4.148 + } 4.149 + 4.150 JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) { 4.151 if (typeArgs != null) illegal(); 4.152 while (true) { 4.153 @@ -1218,6 +1279,11 @@ 4.154 t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 4.155 typeArgs = null; 4.156 } 4.157 + } else if ((mode & EXPR) != 0 && token.kind == HASH) { 4.158 + mode = EXPR; 4.159 + if (typeArgs != null) return illegal(); 4.160 + accept(HASH); 4.161 + t = memberReferenceSuffix(pos1, t); 4.162 } else { 4.163 break; 4.164 } 4.165 @@ -1281,6 +1347,9 @@ 4.166 nextToken(); 4.167 if (token.kind == LPAREN || typeArgs != null) { 4.168 t = arguments(typeArgs, t); 4.169 + } else if (token.kind == HASH) { 4.170 + if (typeArgs != null) return illegal(); 4.171 + t = memberReferenceSuffix(t); 4.172 } else { 4.173 int pos = token.pos; 4.174 accept(DOT); 4.175 @@ -1490,6 +1559,36 @@ 4.176 return t; 4.177 } 4.178 4.179 + /** 4.180 + * MemberReferenceSuffix = "#" [TypeArguments] Ident 4.181 + * | "#" [TypeArguments] "new" 4.182 + */ 4.183 + JCExpression memberReferenceSuffix(JCExpression t) { 4.184 + int pos1 = token.pos; 4.185 + accept(HASH); 4.186 + return memberReferenceSuffix(pos1, t); 4.187 + } 4.188 + 4.189 + JCExpression memberReferenceSuffix(int pos1, JCExpression t) { 4.190 + checkMethodReferences(); 4.191 + mode = EXPR; 4.192 + List<JCExpression> typeArgs = null; 4.193 + if (token.kind == LT) { 4.194 + typeArgs = typeArguments(false); 4.195 + } 4.196 + Name refName = null; 4.197 + ReferenceMode refMode = null; 4.198 + if (token.kind == NEW) { 4.199 + refMode = ReferenceMode.NEW; 4.200 + refName = names.init; 4.201 + nextToken(); 4.202 + } else { 4.203 + refMode = ReferenceMode.INVOKE; 4.204 + refName = ident(); 4.205 + } 4.206 + return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs)); 4.207 + } 4.208 + 4.209 /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 4.210 */ 4.211 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 4.212 @@ -3166,6 +3265,12 @@ 4.213 allowLambda = true; 4.214 } 4.215 } 4.216 + void checkMethodReferences() { 4.217 + if (!allowMethodReferences) { 4.218 + log.error(token.pos, "method.references.not.supported.in.source", source.name); 4.219 + allowMethodReferences = true; 4.220 + } 4.221 + } 4.222 4.223 /* 4.224 * a functional source tree and end position mappings
5.1 --- a/src/share/classes/com/sun/tools/javac/parser/Tokens.java Mon Nov 28 15:56:42 2011 +0000 5.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Tokens.java Mon Nov 28 16:05:46 2011 +0000 5.3 @@ -177,6 +177,7 @@ 5.4 FALSE("false", Tag.NAMED), 5.5 NULL("null", Tag.NAMED), 5.6 ARROW("->"), 5.7 + HASH("#"), 5.8 LPAREN("("), 5.9 RPAREN(")"), 5.10 LBRACE("{"),
6.1 --- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Nov 28 15:56:42 2011 +0000 6.2 +++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties Mon Nov 28 16:05:46 2011 +0000 6.3 @@ -1950,6 +1950,11 @@ 6.4 lambda expressions are not supported in -source {0}\n\ 6.5 (use -source 8 or higher to enable lambda expressions) 6.6 6.7 +# 0: string 6.8 +compiler.err.method.references.not.supported.in.source=\ 6.9 + method references are not supported in -source {0}\n\ 6.10 + (use -source 8 or higher to enable method references) 6.11 + 6.12 ######################################## 6.13 # Diagnostics for verbose resolution 6.14 # used by Resolve (debug only)
7.1 --- a/test/tools/javac/diags/examples/IllegalChar.java Mon Nov 28 15:56:42 2011 +0000 7.2 +++ b/test/tools/javac/diags/examples/IllegalChar.java Mon Nov 28 16:05:46 2011 +0000 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -24,5 +24,5 @@ 7.11 // key: compiler.err.illegal.char 7.12 7.13 class IllegalChar { 7.14 - int i = #; 7.15 + int i = `; 7.16 }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/tools/javac/diags/examples/MethodReferencesNotSupported.java Mon Nov 28 16:05:46 2011 +0000 8.3 @@ -0,0 +1,29 @@ 8.4 +/* 8.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.23 + * or visit www.oracle.com if you need additional information or have any 8.24 + * questions. 8.25 + */ 8.26 + 8.27 +// key: compiler.err.method.references.not.supported.in.source 8.28 +// options: -source 7 -Xlint:-options 8.29 + 8.30 +class MethodReferencesNotSupported { 8.31 + S s = A#foo; 8.32 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/tools/javac/lambda/MethodReferenceParserTest.java Mon Nov 28 16:05:46 2011 +0000 9.3 @@ -0,0 +1,233 @@ 9.4 +/* 9.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. 9.11 + * 9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.15 + * version 2 for more details (a copy is included in the LICENSE file that 9.16 + * accompanied this code). 9.17 + * 9.18 + * You should have received a copy of the GNU General Public License version 9.19 + * 2 along with this work; if not, write to the Free Software Foundation, 9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.21 + * 9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 9.23 + * or visit www.oracle.com if you need additional information or have any 9.24 + * questions. 9.25 + */ 9.26 + 9.27 +/* 9.28 + * @test 9.29 + * @bug 7115052 9.30 + * @summary Add parser support for method references 9.31 + */ 9.32 + 9.33 +import com.sun.source.util.JavacTask; 9.34 +import java.net.URI; 9.35 +import java.util.Arrays; 9.36 +import javax.tools.Diagnostic; 9.37 +import javax.tools.JavaCompiler; 9.38 +import javax.tools.JavaFileObject; 9.39 +import javax.tools.SimpleJavaFileObject; 9.40 +import javax.tools.StandardJavaFileManager; 9.41 +import javax.tools.ToolProvider; 9.42 + 9.43 +public class MethodReferenceParserTest { 9.44 + 9.45 + static int checkCount = 0; 9.46 + 9.47 + enum ReferenceKind { 9.48 + METHOD_REF("#Q##Gm"), 9.49 + CONSTRUCTOR_REF("#Q##Gnew"), 9.50 + ERR_SUPER("#Q##Gsuper"), 9.51 + ERR_METH0("#Q##Gm()"), 9.52 + ERR_METH1("#Q##Gm(X)"), 9.53 + ERR_CONSTR0("#Q##Gnew()"), 9.54 + ERR_CONSTR1("#Q##Gnew(X)"); 9.55 + 9.56 + String referenceTemplate; 9.57 + 9.58 + ReferenceKind(String referenceTemplate) { 9.59 + this.referenceTemplate = referenceTemplate; 9.60 + } 9.61 + 9.62 + String getReferenceString(QualifierKind qk, GenericKind gk) { 9.63 + return referenceTemplate 9.64 + .replaceAll("#Q", qk.qualifier) 9.65 + .replaceAll("#G", gk.typeParameters); 9.66 + } 9.67 + 9.68 + boolean erroneous() { 9.69 + switch (this) { 9.70 + case ERR_SUPER: 9.71 + case ERR_METH0: 9.72 + case ERR_METH1: 9.73 + case ERR_CONSTR0: 9.74 + case ERR_CONSTR1: 9.75 + return true; 9.76 + default: return false; 9.77 + } 9.78 + } 9.79 + } 9.80 + 9.81 + enum GenericKind { 9.82 + NONE(""), 9.83 + ONE("<X>"), 9.84 + TWO("<X,Y>"); 9.85 + 9.86 + String typeParameters; 9.87 + 9.88 + GenericKind(String typeParameters) { 9.89 + this.typeParameters = typeParameters; 9.90 + } 9.91 + } 9.92 + 9.93 + enum QualifierKind { 9.94 + THIS("this"), 9.95 + SUPER("super"), 9.96 + NEW("new Foo()"), 9.97 + METHOD("m()"), 9.98 + FIELD("a.f"), 9.99 + UBOUND_SIMPLE("A"), 9.100 + UNBOUND_GENERIC1("A<X>"), 9.101 + UNBOUND_GENERIC2("A<X, Y>"), 9.102 + UNBOUND_GENERIC3("A<? extends X, ? super Y>"); 9.103 + 9.104 + String qualifier; 9.105 + 9.106 + QualifierKind(String qualifier) { 9.107 + this.qualifier = qualifier; 9.108 + } 9.109 + } 9.110 + 9.111 + enum ExprKind { 9.112 + NONE("#R#S"), 9.113 + SINGLE_PAREN1("(#R#S)"), 9.114 + SINGLE_PAREN2("(#R)#S"), 9.115 + DOUBLE_PAREN1("((#R#S))"), 9.116 + DOUBLE_PAREN2("((#R)#S)"), 9.117 + DOUBLE_PAREN3("((#R))#S"); 9.118 + 9.119 + String expressionTemplate; 9.120 + 9.121 + ExprKind(String expressionTemplate) { 9.122 + this.expressionTemplate = expressionTemplate; 9.123 + } 9.124 + 9.125 + String expressionString(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk) { 9.126 + return expressionTemplate 9.127 + .replaceAll("#R", rk.getReferenceString(qk, gk)) 9.128 + .replaceAll("#S", sk.subExpression); 9.129 + } 9.130 + } 9.131 + 9.132 + enum SubExprKind { 9.133 + NONE(""), 9.134 + SELECT_FIELD(".f"), 9.135 + SELECT_METHOD(".f()"), 9.136 + SELECT_NEW(".new Foo()"), 9.137 + POSTINC("++"), 9.138 + POSTDEC("--"); 9.139 + 9.140 + String subExpression; 9.141 + 9.142 + SubExprKind(String subExpression) { 9.143 + this.subExpression = subExpression; 9.144 + } 9.145 + } 9.146 + 9.147 + public static void main(String... args) throws Exception { 9.148 + 9.149 + //create default shared JavaCompiler - reused across multiple compilations 9.150 + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 9.151 + StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); 9.152 + 9.153 + for (ReferenceKind rk : ReferenceKind.values()) { 9.154 + for (QualifierKind qk : QualifierKind.values()) { 9.155 + for (GenericKind gk : GenericKind.values()) { 9.156 + for (SubExprKind sk : SubExprKind.values()) { 9.157 + for (ExprKind ek : ExprKind.values()) { 9.158 + new MethodReferenceParserTest(rk, qk, gk, sk, ek).run(comp, fm); 9.159 + } 9.160 + } 9.161 + } 9.162 + } 9.163 + } 9.164 + System.out.println("Total check executed: " + checkCount); 9.165 + } 9.166 + 9.167 + ReferenceKind rk; 9.168 + QualifierKind qk; 9.169 + GenericKind gk; 9.170 + SubExprKind sk; 9.171 + ExprKind ek; 9.172 + JavaSource source; 9.173 + DiagnosticChecker diagChecker; 9.174 + 9.175 + MethodReferenceParserTest(ReferenceKind rk, QualifierKind qk, GenericKind gk, SubExprKind sk, ExprKind ek) { 9.176 + this.rk = rk; 9.177 + this.qk = qk; 9.178 + this.gk = gk; 9.179 + this.sk = sk; 9.180 + this.ek = ek; 9.181 + this.source = new JavaSource(); 9.182 + this.diagChecker = new DiagnosticChecker(); 9.183 + } 9.184 + 9.185 + class JavaSource extends SimpleJavaFileObject { 9.186 + 9.187 + String template = "class Test {\n" + 9.188 + " SAM s = #E;\n" + 9.189 + "}"; 9.190 + 9.191 + String source; 9.192 + 9.193 + public JavaSource() { 9.194 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 9.195 + source = template.replaceAll("#E", ek.expressionString(rk, qk, gk, sk)); 9.196 + } 9.197 + 9.198 + @Override 9.199 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 9.200 + return source; 9.201 + } 9.202 + } 9.203 + 9.204 + void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { 9.205 + JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, 9.206 + Arrays.asList("-XDallowMethodReferences"), null, Arrays.asList(source)); 9.207 + try { 9.208 + ct.parse(); 9.209 + } catch (Throwable ex) { 9.210 + throw new AssertionError("Error thrown when parsing the following source:\n" + source.getCharContent(true)); 9.211 + } 9.212 + check(); 9.213 + } 9.214 + 9.215 + void check() { 9.216 + checkCount++; 9.217 + 9.218 + if (diagChecker.errorFound != rk.erroneous()) { 9.219 + throw new Error("invalid diagnostics for source:\n" + 9.220 + source.getCharContent(true) + 9.221 + "\nFound error: " + diagChecker.errorFound + 9.222 + "\nExpected error: " + rk.erroneous()); 9.223 + } 9.224 + } 9.225 + 9.226 + static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> { 9.227 + 9.228 + boolean errorFound; 9.229 + 9.230 + public void report(Diagnostic<? extends JavaFileObject> diagnostic) { 9.231 + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { 9.232 + errorFound = true; 9.233 + } 9.234 + } 9.235 + } 9.236 +}
10.1 --- a/test/tools/javac/quid/T6999438.out Mon Nov 28 15:56:42 2011 +0000 10.2 +++ b/test/tools/javac/quid/T6999438.out Mon Nov 28 16:05:46 2011 +0000 10.3 @@ -1,4 +1,4 @@ 10.4 -T6999438.java:8:9: compiler.err.illegal.char: 35 10.5 +T6999438.java:8:8: compiler.err.expected: token.identifier 10.6 T6999438.java:8:10: compiler.err.illegal.start.of.type 10.7 T6999438.java:8:25: compiler.err.expected: token.identifier 10.8 T6999438.java:8:26: compiler.err.expected: ';'