JDK 10/11 RFR of JDK-8189146: Have use of "var" in 9 and earlier source versions issue a warning
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Jan 10 00:39:51 UTC 2018
Thanks for the update. This is close, but compared to the existing
golden file, as you noticed, there are missing warnings, esp. when 'var'
is used as an array element type.
I believe the issue is with this code:
if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) {
2998 Name typeName = ((JCIdent)elemType).name;
2999 if (isRestrictedLocalVarTypeName(typeName, pos)) {
3000 if (type.hasTag(TYPEARRAY)) {
3001 //error - 'var' and arrays
3002 reportSyntaxError(pos, "var.not.allowed.array");
3003 } else {
3004 startPos = TreeInfo.getStartPos(mods);
3005 if (startPos == Position.NOPOS)
3006 startPos = TreeInfo.getStartPos(type);
3007 //implicit type
3008 type = null;
3009 }
3010 }
3011 }
Here, if LVTI is disabled, the 'isRestrictedLocalVarTypeName' call would
not even take place, hence the missing warnings. I suggest to shuffle as
follows:
if (elemType.hasTag(IDENT)) {
2998 Name typeName = ((JCIdent)elemType).name;
2999 if (isRestrictedLocalVarTypeName(typeName, pos)) {
3000 if (type.hasTag(TYPEARRAY)) {
3001 //error - 'var' and arrays
3002 reportSyntaxError(pos, "var.not.allowed.array");
3003 } else {
3004 startPos = TreeInfo.getStartPos(mods);
3005 if (startPos == Position.NOPOS)
3006 startPos = TreeInfo.getStartPos(type);
3007 //implicit type
3008 type = null;
3009 }
3010 }
3011 }
This should be more or less equivalent, behavior-wise
(isRestrictedLocalVarTypeName returns 'false' if lvti is disabled, so
that makes it equivalent to what was there before), but it will execute
the test regardless of whether LVTI is disabled or not, which is what
you want.
There is another 'special' case where the parser reject 'var' and that
is with the compound case (e.g. 'var x, y = ...'), but I think that's a
corner^3 case and we can live w/o the warning there. But if you want to
get there, this is the code to tweak:
boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null;
2960 vdefs.append(head);
2961 while (token.kind == COMMA) {
2962 if (implicit) {
2963 reportSyntaxError(pos, "var.not.allowed.compound");
2964 }
2965 // All but last of multiple declarators subsume a comma
2966 storeEnd((JCTree)vdefs.last(), token.endPos);
2967 nextToken();
2968 vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
2969 }
Again, the name of the game is to make sure that we issue the warning
regardless of whether lvti is enable or not. This should do:
2960 vdefs.append(head);
2961 while (token.kind == COMMA) {
2962 if (isRestrictedLocalVarTypeName
(type)) {
2963 reportSyntaxError(pos, "var.not.allowed.compound");
2964 }
2965 // All but last of multiple declarators subsume a comma
2966 storeEnd((JCTree)vdefs.last(), token.endPos);
2967 nextToken();
2968 vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
2969 }
I'm less sure about this last one, so take it for a spin and see what
happens.
Maurizio
On 09/01/18 22:29, joe darcy wrote:
> Hi Maurizio,
>
>
> On 1/9/2018 10:49 AM, Maurizio Cimadamore wrote:
>> Hi Joe,
>> I'm a bit unsure about having a retroactive warning in JDK 10 - e.g.
>> I'm not sure how useful that would be, but I get the spirit of what
>> you're getting at.
>
> I think this kind of warning allows a smoother cross-release transition.
>
>>
>> In terms of code, I think your warning should go inside the
>> isRestrictedLocalVarTypeName(Name), which is called in a few places
>> (not just the one you have touched). For instance, I don't think your
>> patch will cover this case:
>>
>> List<var> l = null;
>>
>> So, the code for isRestrictedLocalVarTypeName(Name) is currently:
>>
>> return allowLocalVariableTypeInference && name == names.var;
>>
>> I think it should be updated to:
>>
>> if (name == names.var) {
>> if (allowLocalVariableTypeInference) {
>> return true;
>> } else {
>> warning(pos, "var.not.allowed", name);
>> }
>> }
>> return false;
>>
>>
>> Of course you need to enhance the method to take an extra position
>> argument (pos).
>>
>>
>
> Webrev updated as suggested:
>
> http://cr.openjdk.java.net/~darcy/8189146.1/
>
> That does emit more warnings than the earlier iteration in ParserTest,
> 17 rather than 6. As a review aid, the 17 expanded non-raw warnings
> are listed below. Under release 10, there are 24 errors generated for
> the file, including different error messages.
>
> Thanks,
>
> -Joe
>
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:14:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> class ParserTest<var> {
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:16:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> static class var { } //illegal
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:20:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> interface var { } //illegal
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:24:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> enum var { } //illegal
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:28:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> @interface var { } //illegal
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:36:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> static class var extends RuntimeException { } //illegal
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:38:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> var x = null; //illegal
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:54:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> var m() { //illegal
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:58:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> void test2(var x) { //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:59:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> List<var> l1; //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:60:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> List<? extends var> l2; //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:61:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> List<? super var> l3; //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:63:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> Function<var, String> f = (var x2) -> ""; //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:63:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> Function<var, String> f = (var x2) -> ""; //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:64:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> } catch (var ex) { } //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:68:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> boolean b1 = o instanceof var; //error
> ^
> /home/darcy/JDK/10/hg/test/langtools/tools/javac/lvti/ParserTest.java:69:
> warning: as of release 10, 'var' is a restricted local variable type
> and cannot be used for type declarations
> Object o2 = (var)o; //error
> ^
> 17 warnings
>
More information about the compiler-dev
mailing list