[PATCH] Diagnostic position fix for statement-bodied lambdas

Liam Miller-Cushon cushon at google.com
Sat Nov 15 01:16:49 UTC 2014


When parsing statement-bodied lambda expressions, javac currently uses the
start position of the parameter list for the body. This patch fixes the
parser to record the body's start position correctly.

Example diagnostic before this change:

Test.java:17: error: incompatible types: bad return type in lambda
expression
        foo((x) -> { return ""; System.out.println(""); });
            ^

After:

Test.java:17: error: lambda body is neither value nor void compatible
        foo((x) -> { return ""; System.out.println(""); });
                   ^

Placing the caret at the parameter list may be deliberate, but it should be
possible to do that without recording the body's start position incorrectly.

Thanks,
Liam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20141114/6e002efd/attachment-0001.html>
-------------- next part --------------
# HG changeset patch
# User cushon <cushon at google.com>
# Date 1416012777 28800
#      Fri Nov 14 16:52:57 2014 -0800
# Node ID c8760b71c10ea1cd970be1e004b4b14a964695e5
# Parent  0b467b70ad82687eeafddfd36485fe52657d7fdd
Fix diagnostic position of statement-bodied lambdas.

Previously the start position of the lambda's parameter list was used for the
body.

diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -1680,7 +1680,7 @@
         accept(ARROW);
 
         return token.kind == LBRACE ?
-            lambdaStatement(args, pos, pos) :
+            lambdaStatement(args, pos, token.pos) :
             lambdaExpression(args, pos);
     }
 
diff --git a/test/tools/javac/lambda/MostSpecific09.out b/test/tools/javac/lambda/MostSpecific09.out
--- a/test/tools/javac/lambda/MostSpecific09.out
+++ b/test/tools/javac/lambda/MostSpecific09.out
@@ -2,7 +2,7 @@
 MostSpecific09.java:26:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)}
 MostSpecific09.java:27:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)}
 MostSpecific09.java:27:32: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)}
-MostSpecific09.java:28:13: compiler.err.lambda.body.neither.value.nor.void.compatible
+MostSpecific09.java:28:20: compiler.err.lambda.body.neither.value.nor.void.compatible
 MostSpecific09.java:28:9: compiler.err.cant.apply.symbols: kindname.method, foo, @680,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))}
 MostSpecific09.java:28:43: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)}
 MostSpecific09.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09
@@ -10,7 +10,7 @@
 MostSpecific09.java:30:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09
 MostSpecific09.java:32:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(MostSpecific09.I), MostSpecific09, kindname.method, foo(MostSpecific09.J), MostSpecific09
 MostSpecific09.java:33:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.I), null)}
-MostSpecific09.java:42:13: compiler.err.lambda.body.neither.value.nor.void.compatible
+MostSpecific09.java:42:20: compiler.err.lambda.body.neither.value.nor.void.compatible
 MostSpecific09.java:42:9: compiler.err.cant.apply.symbols: kindname.method, foo, @1129,{(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.I), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.String)))),(compiler.misc.inapplicable.method: kindname.method, MostSpecific09, foo(MostSpecific09.J), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.unexpected.ret.val)))}
 MostSpecific09.java:46:23: compiler.note.verbose.resolve.multi: println, java.io.PrintStream, 1, BASIC, java.lang.String, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, println(java.lang.Object), null),(compiler.misc.applicable.method.found: 1, println(java.lang.String), null)}
 MostSpecific09.java:49:9: compiler.note.verbose.resolve.multi: foo, MostSpecific09, 0, BASIC, compiler.misc.type.none, compiler.misc.no.args,{(compiler.misc.applicable.method.found: 0, foo(MostSpecific09.J), null)}


More information about the compiler-dev mailing list