You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2017/09/27 08:07:50 UTC
[1/2] groovy git commit: GROOVY-8220: SC GroovyCastException on
parameter flow typing (closes #605)
Repository: groovy
Updated Branches:
refs/heads/GROOVY_2_5_X 3e1007f6c -> 671b4fe4a
GROOVY-8220: SC GroovyCastException on parameter flow typing (closes #605)
GROOVY-8157 introduced flow typing for parameters and this fix is
required in order to track their assignments in `if` branches for
temporary type assignments.
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/a6bbacfb
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/a6bbacfb
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/a6bbacfb
Branch: refs/heads/GROOVY_2_5_X
Commit: a6bbacfb5393d2238f0b8ae97f2888d204ff5cb1
Parents: 3e1007f
Author: John Wagenleitner <jw...@apache.org>
Authored: Thu Sep 7 17:27:06 2017 -0700
Committer: paulk <pa...@asert.com.au>
Committed: Wed Sep 27 18:07:37 2017 +1000
----------------------------------------------------------------------
.../stc/StaticTypeCheckingVisitor.java | 67 ++++++++++++++-
.../transform/stc/STCAssignmentTest.groovy | 89 +++++++++++++++++++-
2 files changed, 151 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/a6bbacfb/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index e5d8d23..20f5d97 100644
--- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -130,9 +130,6 @@ import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.*;
/**
* The main class code visitor responsible for static type checking. It will perform various inspections like checking
* assignment types, type inference, ... Eventually, class nodes may be annotated with inferred type information.
- *
- * @author Cedric Champeau
- * @author Jochen Theodorou
*/
public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
@@ -670,6 +667,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (typeCheckingContext.ifElseForWhileAssignmentTracker != null && leftExpression instanceof VariableExpression
&& !isNullConstant(rightExpression)) {
Variable accessedVariable = ((VariableExpression) leftExpression).getAccessedVariable();
+ if (accessedVariable instanceof Parameter) {
+ accessedVariable = new ParameterVariableExpression((Parameter) accessedVariable);
+ }
if (accessedVariable instanceof VariableExpression) {
VariableExpression var = (VariableExpression) accessedVariable;
List<ClassNode> types = typeCheckingContext.ifElseForWhileAssignmentTracker.get(var);
@@ -4849,4 +4849,65 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
}
+ /**
+ * Wrapper for a Parameter so it can be treated like a VariableExpression
+ * and tracked in the ifElseForWhileAssignmentTracker.
+ *
+ * This class purposely does not adhere to the normal equals and hashCode
+ * contract on the Object class and delegates those calls to the wrapped
+ * variable.
+ */
+ private static class ParameterVariableExpression extends VariableExpression {
+
+ private final Parameter parameter;
+
+ ParameterVariableExpression(Parameter parameter) {
+ super(parameter);
+ this.parameter = parameter;
+ ClassNode inferred = parameter.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
+ if (inferred == null) {
+ parameter.setNodeMetaData(StaticTypesMarker.INFERRED_TYPE, parameter.getOriginType());
+ }
+ }
+
+ @Override
+ public void copyNodeMetaData(ASTNode other) {
+ parameter.copyNodeMetaData(other);
+ }
+
+ @Override
+ public Object putNodeMetaData(Object key, Object value) {
+ return parameter.putNodeMetaData(key, value);
+ }
+
+ @Override
+ public void removeNodeMetaData(Object key) {
+ parameter.removeNodeMetaData(key);
+ }
+
+ @Override
+ public Map<?, ?> getNodeMetaData() {
+ return parameter.getNodeMetaData();
+ }
+
+ @Override
+ public <T> T getNodeMetaData(Object key) {
+ return parameter.getNodeMetaData(key);
+ }
+
+ @Override
+ public void setNodeMetaData(Object key, Object value) {
+ parameter.setNodeMetaData(key, value);
+ }
+
+ @Override
+ public int hashCode() {
+ return parameter.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return parameter.equals(other);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/a6bbacfb/src/test/groovy/transform/stc/STCAssignmentTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/transform/stc/STCAssignmentTest.groovy b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
index acb1c75..645a6de 100644
--- a/src/test/groovy/transform/stc/STCAssignmentTest.groovy
+++ b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
@@ -20,8 +20,6 @@ package groovy.transform.stc
/**
* Unit tests for static type checking : assignments.
- *
- * @author Cedric Champeau
*/
class STCAssignmentTest extends StaticTypeCheckingTestCase {
@@ -446,6 +444,21 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
''', 'Cannot find matching method java.io.Serializable#toInteger()'
}
+ void testIfElseBranchParameter() {
+ shouldFailWithMessages '''
+ def foo(x) {
+ def y = 'foo'
+ if (y) {
+ x = new HashSet()
+ } else {
+ x = '123'
+ }
+ x.toInteger()
+ }
+ foo('bar')
+ ''', 'Cannot find matching method java.lang.Object#toInteger()'
+ }
+
void testIfOnly() {
shouldFailWithMessages '''
def x = '123'
@@ -457,6 +470,20 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
''', 'Cannot find matching method java.io.Serializable#toInteger()'
}
+ void testIfOnlyParameter() {
+ shouldFailWithMessages '''
+ def foo(x) {
+ def y = 'foo'
+ if (y) {
+ x = new HashSet()
+ assert x.isEmpty()
+ }
+ x.toInteger()
+ }
+ foo('123')
+ ''', 'Cannot find matching method java.lang.Object#toInteger()'
+ }
+
void testIfWithCommonInterface() {
assertScript '''
interface Foo { void foo() }
@@ -873,6 +900,64 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-8220
+ void testFlowTypingParameterTempTypeAssignmentTracking() {
+ assertScript '''
+ class Foo {
+ CharSequence makeEnv( env, StringBuilder result = new StringBuilder() ) {
+ if (env instanceof File) {
+ env = env.toPath()
+ }
+ if (env instanceof String && env.contains('=')) {
+ result << 'export ' << env << ';'
+ }
+ return result.toString()
+ }
+ }
+ assert new Foo().makeEnv('X=1') == 'export X=1;'
+ '''
+ // GROOVY-8237
+ assertScript '''
+ class Foo {
+ String parse(Reader reader) {
+ if (reader == null)
+ reader = new BufferedReader(reader)
+ int i = reader.read()
+ return (i != -1) ? 'bar' : 'baz'
+ }
+ }
+ assert new Foo().parse(new StringReader('foo')) == 'bar'
+ '''
+ }
+
+ void testFlowTypingParameterTempTypeAssignmentTrackingWithGenerics() {
+ assertScript '''
+ class M {
+ Map<String, List<Object>> mvm = new HashMap<String, List<Object>>()
+ void setProperty(String name, value) {
+ if (value instanceof File) {
+ value = new File(value, 'bar.txt')
+ }
+ else if (value instanceof URL) {
+ value = value.toURI()
+ }
+ else if (value instanceof InputStream) {
+ value = new BufferedInputStream(value)
+ }
+ else if (value instanceof GString) {
+ value = value.toString()
+ }
+ if (mvm[name]) {
+ mvm[name].add value
+ } else {
+ mvm.put(name, [value])
+ }
+ }
+ }
+ new M().setProperty('foo', 'bar')
+ '''
+ }
+
void testNarrowingConversion() {
assertScript '''
interface A1{}
[2/2] groovy git commit: GROOVY-8249: Newify local variable
declaration fails to resolve class expression (closes #584)
Posted by pa...@apache.org.
GROOVY-8249: Newify local variable declaration fails to resolve class expression (closes #584)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/671b4fe4
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/671b4fe4
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/671b4fe4
Branch: refs/heads/GROOVY_2_5_X
Commit: 671b4fe4a72ba18210d18cfc014c45a1ff25b73d
Parents: a6bbacf
Author: John Wagenleitner <jw...@apache.org>
Authored: Sun Aug 13 17:15:00 2017 -0700
Committer: paulk <pa...@asert.com.au>
Committed: Wed Sep 27 18:07:38 2017 +1000
----------------------------------------------------------------------
.../groovy/classgen/VariableScopeVisitor.java | 3 +--
.../groovy/transform/NewifyTransformTest.groovy | 24 ++++++++++++++++++++
2 files changed, 25 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/671b4fe4/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index 9085eb7..1801e5e 100644
--- a/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -38,8 +38,6 @@ import static java.lang.reflect.Modifier.isFinal;
/**
* goes through an AST and initializes the scopes
- *
- * @author Jochen Theodorou
*/
public class VariableScopeVisitor extends ClassCodeVisitorSupport {
@@ -330,6 +328,7 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
}
public void visitDeclarationExpression(DeclarationExpression expression) {
+ visitAnnotations(expression);
// visit right side first to avoid the usage of a
// variable before its declaration
expression.getRightExpression().visit(this);
http://git-wip-us.apache.org/repos/asf/groovy/blob/671b4fe4/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy b/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy
index d585c8a..c2cce48 100644
--- a/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/NewifyTransformTest.groovy
@@ -211,4 +211,28 @@ class NewifyTransformTest extends GroovyShellTestCase {
assert Foo.answer == 42
'''
}
+
+ // GROOVY-8249
+ void testLocalVariableDeclResolvesClass() {
+ assertScript '''
+ class A {
+ final int id
+ A(int id) { this.id = id + 10 }
+ }
+ class Foo {
+ static String test() {
+ @Newify(String)
+ String answer = String('bar')
+ answer
+ }
+ static int test2() {
+ @Newify(A)
+ int answer = A(32).id
+ answer
+ }
+ }
+ assert Foo.test() == 'bar'
+ assert Foo.test2() == 42
+ '''
+ }
}
\ No newline at end of file