8028235: Better error recovery for parsing 'void' as a type of the lambda parameter
authorjlahoda
Tue, 17 Dec 2013 10:58:26 +0100
changeset 22155 2f0a83a98593
parent 22154 3c8d86bf756b
child 22156 8eefa8ab3f41
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
langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
langtools/test/tools/javac/lambda/VoidLambdaParameter.java
langtools/test/tools/javac/lambda/VoidLambdaParameter.out
langtools/test/tools/javac/parser/JavacParserTest.java
--- 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)