[1/2] groovy git commit: GROOVY-7632: Groovy named parameters static check (initial cut of support) (closes #822)

2018-11-16 Thread paulk
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)

2018-11-15 Thread paulk
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