8028235: Better error recovery for parsing 'void' as a type of the lambda parameter
Summary: Handle "void" as a primitive type in JavacParser.analyzeParens.
Reviewed-by: vromero
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Dec 17 10:58:21 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Dec 17 10:58:26 2013 +0100
@@ -1547,7 +1547,7 @@
}
break;
case BYTE: case SHORT: case INT: case LONG: case FLOAT:
- case DOUBLE: case BOOLEAN: case CHAR:
+ case DOUBLE: case BOOLEAN: case CHAR: case VOID:
if (peekToken(lookahead, RPAREN)) {
//Type, ')' -> cast
return ParensResult.CAST;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/VoidLambdaParameter.java Tue Dec 17 10:58:26 2013 +0100
@@ -0,0 +1,12 @@
+/* @test /nodynamiccopyright/
+ * @bug 8028235
+ * @summary Using void as a lambda parameter should produce sane AST and errors
+ * @compile/fail/ref=VoidLambdaParameter.out -XDrawDiagnostics VoidLambdaParameter.java
+ */
+public class VoidLambdaParameter {
+ Runnable r = (void v) -> { };
+ I i = (void v) -> { };
+ interface I {
+ public void v(void v);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/VoidLambdaParameter.out Tue Dec 17 10:58:26 2013 +0100
@@ -0,0 +1,5 @@
+VoidLambdaParameter.java:7:19: compiler.err.void.not.allowed.here
+VoidLambdaParameter.java:7:18: compiler.err.prob.found.req: (compiler.misc.incompatible.arg.types.in.lambda)
+VoidLambdaParameter.java:8:12: compiler.err.void.not.allowed.here
+VoidLambdaParameter.java:10:23: compiler.err.void.not.allowed.here
+4 errors
--- a/langtools/test/tools/javac/parser/JavacParserTest.java Tue Dec 17 10:58:21 2013 +0100
+++ b/langtools/test/tools/javac/parser/JavacParserTest.java Tue Dec 17 10:58:26 2013 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7073631 7159445 7156633
+ * @bug 7073631 7159445 7156633 8028235
* @summary tests error and diagnostics positions
* @author Jan Lahoda
*/
@@ -35,9 +35,11 @@
import com.sun.source.tree.ErroneousTree;
import com.sun.source.tree.ExpressionStatementTree;
import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.ModifiersTree;
+import com.sun.source.tree.PrimitiveTypeTree;
import com.sun.source.tree.StatementTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.Tree.Kind;
@@ -60,6 +62,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
+import javax.lang.model.type.TypeKind;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.DiagnosticListener;
@@ -895,6 +898,43 @@
assertEquals("testStartPositionEnumConstantInit", -1, start);
}
+ @Test
+ void testVoidLambdaParameter() throws IOException {
+ String code = "package t; class Test { " +
+ "Runnable r = (void v) -> { };" +
+ "}";
+ DiagnosticCollector<JavaFileObject> coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
+ null, Arrays.asList(new MyFileObject(code)));
+
+ CompilationUnitTree cut = ct.parse().iterator().next();
+ ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
+ VariableTree field = (VariableTree) clazz.getMembers().get(0);
+
+ assertEquals("actual kind: " + field.getInitializer().getKind(),
+ field.getInitializer().getKind(),
+ Kind.LAMBDA_EXPRESSION);
+
+ LambdaExpressionTree lambda = (LambdaExpressionTree) field.getInitializer();
+
+ assertEquals("actual parameters: " + lambda.getParameters().size(),
+ lambda.getParameters().size(),
+ 1);
+
+ Tree paramType = lambda.getParameters().get(0).getType();
+
+ assertEquals("actual parameter type: " + paramType.getKind(),
+ paramType.getKind(),
+ Kind.PRIMITIVE_TYPE);
+
+ TypeKind primitiveTypeKind = ((PrimitiveTypeTree) paramType).getPrimitiveTypeKind();
+
+ assertEquals("actual parameter type: " + primitiveTypeKind,
+ primitiveTypeKind,
+ TypeKind.VOID);
+ }
+
void run(String[] args) throws Exception {
int passed = 0, failed = 0;
final Pattern p = (args != null && args.length > 0)