Skip to content

Commit 904e559

Browse files
committed
GROOVY-11375, GROOVY-11769: SC: lookup type of variable before target
see also GROOVY-9344, GROOVY-9607 4_0_X backport
1 parent 3f57258 commit 904e559

4 files changed

Lines changed: 52 additions & 6 deletions

File tree

src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesTypeChooser.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,23 @@
3232
* type information from node metadata generated by the static type checker.
3333
*/
3434
public class StaticTypesTypeChooser extends StatementMetaTypeChooser {
35+
3536
@Override
3637
public ClassNode resolveType(final Expression exp, final ClassNode current) {
37-
ASTNode target = getTarget(exp); // see GROOVY-9344, GROOVY-9607
38-
39-
ClassNode inferredType = target.getNodeMetaData(StaticTypesMarker.DECLARATION_INFERRED_TYPE);
38+
ClassNode inferredType = exp.getNodeMetaData(StaticTypesMarker.DECLARATION_INFERRED_TYPE);
39+
if (inferredType == null) {
40+
inferredType = exp.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
41+
}
4042
if (inferredType == null) {
41-
inferredType = target.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
43+
ASTNode node = getTarget(exp); // GROOVY-9344, GROOVY-9607
44+
inferredType = node.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
4245
}
4346
if (inferredType != null && !isPrimitiveVoid(inferredType)) {
4447
return inferredType;
4548
}
4649

47-
// AsmClassGenerator may create "this" expressions that the type checker knows nothing about
48-
if (target instanceof VariableExpression && ((VariableExpression) target).isThisExpression()) {
50+
// AsmClassGenerator creates "this" expressions that the type checker knows nothing about
51+
if (exp instanceof VariableExpression && ((VariableExpression) exp).isThisExpression()) {
4952
return current;
5053
}
5154

src/test/groovy/groovy/transform/stc/STCAssignmentTest.groovy

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,21 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
645645
'''
646646
}
647647

648+
void testCastObjectToInterface() {
649+
assertScript '''
650+
List<Object> m(object) {
651+
if (object == null) return new ArrayList<>()
652+
if (object instanceof Collection) return new ArrayList<Object>((Collection) object)
653+
return [object]
654+
}
655+
def item = 0
656+
def list = [1,2]
657+
assert m(null).size() == 0
658+
assert m(item).size() == 1
659+
assert m(list).size() == 2
660+
'''
661+
}
662+
648663
void testIfElseBranch() {
649664
shouldFailWithMessages '''
650665
def x

src/test/groovy/groovy/transform/stc/STCnAryExpressionTest.groovy

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,26 @@ class STCnAryExpressionTest extends StaticTypeCheckingTestCase {
132132
'''
133133
}
134134

135+
// GROOVY-11375
136+
void testShiftOnPrimitivesVariableFlowType() {
137+
assertScript '''
138+
def x = "--"
139+
x = x.size()
140+
def y = x << x
141+
assert y === 8
142+
'''
143+
}
144+
145+
// GROOVY-11375
146+
void testPowerOnPrimitivesVariableFlowType() {
147+
assertScript '''
148+
def x = "--"
149+
x = x.size()
150+
def y = x ** x
151+
assert y === 4
152+
'''
153+
}
154+
135155
// GROOVY-5644
136156
void testSpaceshipOperatorNoAmbiguousError() {
137157
assertScript '''

src/test/groovy/org/codehaus/groovy/classgen/asm/sc/AssignmentsStaticCompileTest.groovy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,12 @@ final class AssignmentsStaticCompileTest extends STCAssignmentTest implements St
3131
String bytecode = astTrees['C'][1]
3232
assert !bytecode.contains('ScriptBytecodeAdapter.setGroovyObjectProperty') : '"c.i += 10" should use setter, not dynamic property'
3333
}
34+
35+
@Override // GROOVY-11769
36+
void testCastObjectToInterface() {
37+
super.testCastObjectToInterface()
38+
String bytecode = astTrees.values()[0][1]
39+
bytecode = bytecode.substring(bytecode.indexOf('m(Ljava/lang/Object;)'))
40+
assert bytecode.count('CHECKCAST') == 1 // guarded typecast isn't groovy
41+
}
3442
}

0 commit comments

Comments
 (0)