[1/2] groovy git commit: GROOVY-7632: Groovy named parameters static check (initial cut of support) (closes #822)
Repository: groovy Updated Branches: refs/heads/GROOVY_2_5_X 43908fa49 -> 4912730ba GROOVY-7632: Groovy named parameters static check (initial cut of support) (closes #822) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/eaae5586 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/eaae5586 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/eaae5586 Branch: refs/heads/GROOVY_2_5_X Commit: eaae5586c22143b415fd0b833c53bd23f14176ea Parents: 43908fa Author: Paul King Authored: Thu Nov 15 00:33:14 2018 +1000 Committer: Paul King Committed: Fri Nov 16 11:18:00 2018 +1000 -- .../stc/StaticTypeCheckingVisitor.java | 84 +++ src/test/groovy/NamedParameterHelper.java | 40 + src/test/groovy/NamedParameterTest.groovy | 87 3 files changed, 211 insertions(+) -- http://git-wip-us.apache.org/repos/asf/groovy/blob/eaae5586/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java -- diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 9690c0b..943ef6d 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -22,6 +22,8 @@ import groovy.lang.Closure; import groovy.lang.DelegatesTo; import groovy.lang.IntRange; import groovy.lang.Range; +import groovy.transform.NamedParam; +import groovy.transform.NamedParams; import groovy.transform.TypeChecked; import groovy.transform.TypeCheckingMode; import groovy.transform.stc.ClosureParams; @@ -43,6 +45,7 @@ import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.Parameter; import org.codehaus.groovy.ast.PropertyNode; import org.codehaus.groovy.ast.Variable; +import org.codehaus.groovy.ast.expr.AnnotationConstantExpression; import org.codehaus.groovy.ast.expr.ArgumentListExpression; import org.codehaus.groovy.ast.expr.AttributeExpression; import org.codehaus.groovy.ast.expr.BinaryExpression; @@ -282,6 +285,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { protected static final ClassNode DELEGATES_TO_TARGET = ClassHelper.make(DelegatesTo.Target.class); protected static final ClassNode LINKEDHASHMAP_CLASSNODE = make(LinkedHashMap.class); protected static final ClassNode CLOSUREPARAMS_CLASSNODE = make(ClosureParams.class); +protected static final ClassNode NAMED_PARAMS_CLASSNODE = make(NamedParams.class); protected static final ClassNode MAP_ENTRY_TYPE = make(Map.Entry.class); protected static final ClassNode ENUMERATION_TYPE = make(Enumeration.class); @@ -2600,6 +2604,86 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { } } } +if (expressions.size() > 0 && expressions.get(0) instanceof MapExpression && params.length > 0) { +checkNamedParamsAnnotation(params[0], (MapExpression) expressions.get(0)); +} +} + +private void checkNamedParamsAnnotation(Parameter param, MapExpression args) { +if (!param.getType().isDerivedFrom(ClassHelper.MAP_TYPE)) return; +List entryExpressions = args.getMapEntryExpressions(); +Map entries = new LinkedHashMap(); +for (MapEntryExpression entry : entryExpressions) { +Object key = entry.getKeyExpression(); +if (key instanceof ConstantExpression) { +key = ((ConstantExpression) key).getValue(); +} +entries.put(key, entry.getValueExpression()); +} +List annotations = param.getAnnotations(NAMED_PARAMS_CLASSNODE); +if (annotations != null && !annotations.isEmpty()) { +AnnotationNode an = null; +for (AnnotationNode next : annotations) { +if (next.getClassNode().getName().equals(NamedParams.class.getName())) { +an = next; +} +} +List collectedNames = new ArrayList(); +if (an != null) { +Expression value = an.getMember("value"); +if (value instanceof AnnotationConstantExpression) { +processNamedParam((AnnotationConstantExpression) value, entries, args, collectedNames); +} else if (value instanceof ListExpression) { +ListExpression le = (ListExpression) value; +for (Expression next : le.getExpressions()) { +if (next instanceof AnnotationConstantExpression) { +
groovy git commit: GROOVY-7632: Groovy named parameters static check (initial cut of support) (closes #822)
Repository: groovy Updated Branches: refs/heads/master 3ac1abcd0 -> 3bdea65e1 GROOVY-7632: Groovy named parameters static check (initial cut of support) (closes #822) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/3bdea65e Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/3bdea65e Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/3bdea65e Branch: refs/heads/master Commit: 3bdea65e1b7b2382f0f743670e19dfa5f61d21c6 Parents: 3ac1abc Author: Paul King Authored: Thu Nov 15 00:33:14 2018 +1000 Committer: Paul King Committed: Fri Nov 16 10:27:49 2018 +1000 -- .../stc/StaticTypeCheckingVisitor.java | 84 +++ src/test/groovy/NamedParameterHelper.java | 40 + src/test/groovy/NamedParameterTest.groovy | 87 .../apache/groovy/parser/antlr4/AstBuilder.java | 3 +- 4 files changed, 212 insertions(+), 2 deletions(-) -- http://git-wip-us.apache.org/repos/asf/groovy/blob/3bdea65e/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java -- diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 3e6d945..72ea3bc 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -22,6 +22,8 @@ import groovy.lang.Closure; import groovy.lang.DelegatesTo; import groovy.lang.IntRange; import groovy.lang.Range; +import groovy.transform.NamedParam; +import groovy.transform.NamedParams; import groovy.transform.TypeChecked; import groovy.transform.TypeCheckingMode; import groovy.transform.stc.ClosureParams; @@ -43,6 +45,7 @@ import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.Parameter; import org.codehaus.groovy.ast.PropertyNode; import org.codehaus.groovy.ast.Variable; +import org.codehaus.groovy.ast.expr.AnnotationConstantExpression; import org.codehaus.groovy.ast.expr.ArgumentListExpression; import org.codehaus.groovy.ast.expr.AttributeExpression; import org.codehaus.groovy.ast.expr.BinaryExpression; @@ -285,6 +288,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { protected static final ClassNode DELEGATES_TO_TARGET = ClassHelper.make(DelegatesTo.Target.class); protected static final ClassNode LINKEDHASHMAP_CLASSNODE = make(LinkedHashMap.class); protected static final ClassNode CLOSUREPARAMS_CLASSNODE = make(ClosureParams.class); +protected static final ClassNode NAMED_PARAMS_CLASSNODE = make(NamedParams.class); protected static final ClassNode MAP_ENTRY_TYPE = make(Map.Entry.class); protected static final ClassNode ENUMERATION_TYPE = make(Enumeration.class); @@ -2609,6 +2613,86 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { } } } +if (expressions.size() > 0 && expressions.get(0) instanceof MapExpression && params.length > 0) { +checkNamedParamsAnnotation(params[0], (MapExpression) expressions.get(0)); +} +} + +private void checkNamedParamsAnnotation(Parameter param, MapExpression args) { +if (!param.getType().isDerivedFrom(ClassHelper.MAP_TYPE)) return; +List entryExpressions = args.getMapEntryExpressions(); +Map entries = new LinkedHashMap(); +for (MapEntryExpression entry : entryExpressions) { +Object key = entry.getKeyExpression(); +if (key instanceof ConstantExpression) { +key = ((ConstantExpression) key).getValue(); +} +entries.put(key, entry.getValueExpression()); +} +List annotations = param.getAnnotations(NAMED_PARAMS_CLASSNODE); +if (annotations != null && !annotations.isEmpty()) { +AnnotationNode an = null; +for (AnnotationNode next : annotations) { +if (next.getClassNode().getName().equals(NamedParams.class.getName())) { +an = next; +} +} +List collectedNames = new ArrayList(); +if (an != null) { +Expression value = an.getMember("value"); +if (value instanceof AnnotationConstantExpression) { +processNamedParam((AnnotationConstantExpression) value, entries, args, collectedNames); +} else if (value instanceof ListExpression) { +ListExpression le = (ListExpression) value; +for (Expression next : le.getExpressions()) { +if (next