You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2018/02/17 15:36:49 UTC
groovy git commit: Refine constructor reference to support generics
Repository: groovy
Updated Branches:
refs/heads/master e2f4ceb50 -> 2ac5b4852
Refine constructor reference to support generics
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/2ac5b485
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/2ac5b485
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/2ac5b485
Branch: refs/heads/master
Commit: 2ac5b48520cd404157ab09c586d329a6afa0f366
Parents: e2f4ceb
Author: Daniel Sun <re...@hotmail.com>
Authored: Sat Feb 17 23:36:42 2018 +0800
Committer: Daniel Sun <re...@hotmail.com>
Committed: Sat Feb 17 23:36:42 2018 +0800
----------------------------------------------------------------------
src/antlr/GroovyParser.g4 | 40 ++++++++++----------
.../apache/groovy/parser/antlr4/AstBuilder.java | 30 ++++++++++-----
.../resources/core/MethodReference_01x.groovy | 8 ++++
3 files changed, 49 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/2ac5b485/src/antlr/GroovyParser.g4
----------------------------------------------------------------------
diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index 2db4c7f..df86f3c 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -192,11 +192,11 @@ typeParameter
;
typeBound
- : type (BITAND nls type)*
+ : type[false] (BITAND nls type[false])*
;
typeList
- : type (COMMA nls type)*
+ : type[false] (COMMA nls type[false])*
;
@@ -223,7 +223,7 @@ locals[ int t ]
// Only interface can extend more than one super class
{1 == $t}? scs=typeList
|
- sc=type
+ sc=type[false]
)
nls)?
|
@@ -347,14 +347,13 @@ options { baseContext = type; }
dimsOpt
;
-type
+type[boolean allowVoid]
: annotationsOpt
(
(
primitiveType
|
- // !!! ERROR ALTERNATIVE !!!
- VOID { require(false, "void is not allowed here", -4); }
+ VOID
)
|
generalClassOrInterfaceType
@@ -387,8 +386,8 @@ typeArguments
;
typeArgument
- : type
- | annotationsOpt QUESTION ((EXTENDS | SUPER) nls type)?
+ : type[false]
+ | annotationsOpt QUESTION ((EXTENDS | SUPER) nls type[false])?
;
annotatedQualifiedClassName
@@ -408,11 +407,11 @@ formalParameterList
;
thisFormalParameter
- : type THIS
+ : type[false] THIS
;
formalParameter
- : variableModifiersOpt type? ELLIPSIS? variableDeclaratorId (nls ASSIGN nls expression)?
+ : variableModifiersOpt type[false]? ELLIPSIS? variableDeclaratorId (nls ASSIGN nls expression)?
;
methodBody
@@ -584,12 +583,12 @@ classifiedModifiers[int t]
variableDeclaration[int t]
@leftfactor { classifiedModifiers }
: classifiedModifiers[$t]
- ( type? variableDeclarators
+ ( type[false]? variableDeclarators
| typeNamePairs nls ASSIGN nls variableInitializer
)
|
classifiedModifiers[$t]?
- type variableDeclarators
+ type[false] variableDeclarators
;
typeNamePairs
@@ -597,7 +596,7 @@ typeNamePairs
;
typeNamePair
- : type? variableDeclaratorId
+ : type[false]? variableDeclaratorId
;
variableNames
@@ -720,7 +719,7 @@ forControl
;
enhancedForControl
- : variableModifiersOpt type? variableDeclaratorId (COLON | IN) expression
+ : variableModifiersOpt type[false]? variableDeclaratorId (COLON | IN) expression
;
classicalForControl
@@ -740,7 +739,7 @@ forUpdate
// EXPRESSIONS
castParExpression
- : LPAREN type rparen
+ : LPAREN type[false] rparen
;
parExpression
@@ -814,7 +813,7 @@ expression
right=expression #shiftExprAlt
// boolean relational expressions (level 7)
- | left=expression nls op=(AS | INSTANCEOF | NOT_INSTANCEOF) nls type #relationalExprAlt
+ | left=expression nls op=(AS | INSTANCEOF | NOT_INSTANCEOF) nls type[false] #relationalExprAlt
| left=expression nls op=(LE | GE | GT | LT | IN | NOT_IN) nls right=expression #relationalExprAlt
// equality/inequality (==/!=) (level 8)
@@ -1011,7 +1010,10 @@ namedPropertyArgs
;
primary
- : identifier #identifierPrmrAlt
+ :
+ // Append `typeArguments?` to `identifier` to support constructor reference with generics, e.g. HashMap<String, Integer>::new
+ // Though this is not a graceful solution, it is much faster than replacing `builtInType` with `type`
+ identifier typeArguments? #identifierPrmrAlt
| literal #literalPrmrAlt
| gstring #gstringPrmrAlt
| NEW nls creator #newPrmrAlt
@@ -1022,7 +1024,7 @@ primary
| lambdaExpression #lambdaPrmrAlt
| list #listPrmrAlt
| map #mapPrmrAlt
- | builtInType #typePrmrAlt
+ | builtInType #builtInTypePrmrAlt
;
list
@@ -1210,5 +1212,3 @@ nls
sep : SEMI NL*
| NL+ (SEMI NL*)*
;
-
-
http://git-wip-us.apache.org/repos/asf/groovy/blob/2ac5b485/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index e1bed5d..6c02297 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -159,6 +159,7 @@ import static org.apache.groovy.parser.antlr4.GroovyLangParser.BooleanLiteralAlt
import static org.apache.groovy.parser.antlr4.GroovyLangParser.BreakStatementContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.BreakStmtAltContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.BuiltInTypeContext;
+import static org.apache.groovy.parser.antlr4.GroovyLangParser.BuiltInTypePrmrAltContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.CASE;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.CastExprAltContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.CastParExpressionContext;
@@ -329,7 +330,6 @@ import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeNamePairConte
import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeNamePairsContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeParameterContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypeParametersContext;
-import static org.apache.groovy.parser.antlr4.GroovyLangParser.TypePrmrAltContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.UnaryAddExprAltContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.UnaryNotExprAltContext;
import static org.apache.groovy.parser.antlr4.GroovyLangParser.VariableDeclarationContext;
@@ -2348,7 +2348,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
return configureAST(methodCallExpression, ctx);
}
- if (baseExpr instanceof VariableExpression) { // void and primitive type AST node must be an instance of VariableExpression
+ if (baseExpr instanceof ClassExpression) { // void and primitive type AST node must be an instance of ClassExpression
String baseExprText = baseExpr.getText();
if (VOID_STR.equals(baseExprText)) { // e.g. void()
return configureAST(createCallMethodCallExpression(this.createConstantExpression(baseExpr), argumentsExpr), ctx);
@@ -3055,7 +3055,16 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
// primary { --------------------------------------------------------------------
@Override
- public VariableExpression visitIdentifierPrmrAlt(IdentifierPrmrAltContext ctx) {
+ public Expression visitIdentifierPrmrAlt(IdentifierPrmrAltContext ctx) {
+ if (asBoolean(ctx.typeArguments())) {
+ ClassNode classNode = ClassHelper.make(ctx.identifier().getText());
+
+ classNode.setGenericsTypes(
+ this.visitTypeArguments(ctx.typeArguments()));
+
+ return configureAST(new ClassExpression(classNode), ctx);
+ }
+
return configureAST(new VariableExpression(this.visitIdentifier(ctx.identifier())), ctx);
}
@@ -3113,10 +3122,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
}
@Override
- public VariableExpression visitTypePrmrAlt(TypePrmrAltContext ctx) {
- return configureAST(
- this.visitBuiltInType(ctx.builtInType()),
- ctx);
+ public ClassExpression visitBuiltInTypePrmrAlt(BuiltInTypePrmrAltContext ctx) {
+ return configureAST(this.visitBuiltInType(ctx.builtInType()), ctx);
}
@@ -3359,7 +3366,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
*/
@Override
- public VariableExpression visitBuiltInType(BuiltInTypeContext ctx) {
+ public ClassExpression visitBuiltInType(BuiltInTypeContext ctx) {
String text;
if (asBoolean(ctx.VOID())) {
text = ctx.VOID().getText();
@@ -3369,7 +3376,7 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
throw createParsingFailedException("Unsupported built-in type: " + ctx, ctx);
}
- return configureAST(new VariableExpression(text), ctx);
+ return configureAST(new ClassExpression(ClassHelper.make(text)), ctx);
}
@@ -3864,9 +3871,14 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> implements Groov
classNode = this.visitClassOrInterfaceType(ctx.classOrInterfaceType());
} else if (asBoolean(ctx.primitiveType())) {
classNode = this.visitPrimitiveType(ctx.primitiveType());
+ } else if (asBoolean(ctx.VOID())) {
+ if (ctx.allowVoid) {
+ classNode = configureAST(ClassHelper.make(ctx.getText()), ctx.VOID());
+ }
}
if (!asBoolean(classNode)) {
+ // TODO refine error message for `void`
throw createParsingFailedException("Unsupported type: " + ctx.getText(), ctx);
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/2ac5b485/subprojects/parser-antlr4/src/test/resources/core/MethodReference_01x.groovy
----------------------------------------------------------------------
diff --git a/subprojects/parser-antlr4/src/test/resources/core/MethodReference_01x.groovy b/subprojects/parser-antlr4/src/test/resources/core/MethodReference_01x.groovy
index 4816adf..997a7bf 100644
--- a/subprojects/parser-antlr4/src/test/resources/core/MethodReference_01x.groovy
+++ b/subprojects/parser-antlr4/src/test/resources/core/MethodReference_01x.groovy
@@ -77,6 +77,14 @@ def mr = String::toUpperCase
assert 'ABC' == mr('abc')
assert 'ABC' == String::toUpperCase('abc')
+def m = ['apple', 'banana', 'orange'].stream().collect(Collectors.toMap(e -> e.charAt(0), e -> e, (e1, e2) -> e1, LinkedHashMap<String, String>::new))
+assert m instanceof LinkedHashMap
+assert ['a', 'b', 'o'] as TreeSet == m.keySet() as TreeSet
+assert ['apple', 'banana', 'orange'] as TreeSet == m.values() as TreeSet
+
+assert new HashMap<String, Integer>() == HashMap<String, Integer>::new()
+assert new HashSet<Integer>() == HashSet<Integer>::new()
+
assert new HashSet() == HashSet::new()
assert new String() == String::new()
assert 1 == Integer::new(1)