@@ -676,7 +676,7 @@ public void visitVariableExpression(VariableExpression vexp) {
676
676
677
677
ClassNode inferredType = getInferredTypeFromTempInfo (vexp , null );
678
678
if (inferredType != null && !inferredType .equals (OBJECT_TYPE )) {
679
- vexp .putNodeMetaData (StaticTypesMarker .INFERRED_RETURN_TYPE , inferredType );
679
+ vexp .putNodeMetaData (StaticTypesMarker .INFERRED_TYPE , inferredType ); // GROOVY-9454
680
680
} else {
681
681
storeType (vexp , getType (vexp ));
682
682
}
@@ -722,10 +722,15 @@ public void visitVariableExpression(VariableExpression vexp) {
722
722
723
723
if (variable != null ) {
724
724
ClassNode inferredType = getInferredTypeFromTempInfo (variable , (ClassNode ) variable .getNodeMetaData (StaticTypesMarker .INFERRED_TYPE ));
725
- // instanceof applies, stash away the type, reusing key used elsewhere
725
+ /* GRECLIPSE edit -- GROOVY-10102, GROOVY-10179, GROOVY-10217, GROOVY-10308, et al.
726
726
if (inferredType != null && !inferredType.getName().equals("java.lang.Object")) {
727
727
vexp.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, inferredType);
728
728
}
729
+ */
730
+ if (inferredType != null && !inferredType .equals (OBJECT_TYPE ) && !inferredType .equals (accessedVariable .getType ())) {
731
+ vexp .putNodeMetaData (StaticTypesMarker .INFERRED_TYPE , inferredType );
732
+ }
733
+ // GRECLIPSE end
729
734
}
730
735
}
731
736
return ;
@@ -888,8 +893,6 @@ public void visitBinaryExpression(final BinaryExpression expression) {
888
893
} else if (isClosureWithType (lType ) && rightExpression instanceof ClosureExpression ) {
889
894
storeInferredReturnType (rightExpression , getCombinedBoundType (lType .getGenericsTypes ()[0 ]));
890
895
}
891
- } else if (leftExpression instanceof VariableExpression && hasInferredReturnType (leftExpression )) {
892
- lType = getInferredReturnType (leftExpression );
893
896
} else {
894
897
lType = getType (leftExpression );
895
898
}
@@ -1033,7 +1036,6 @@ else if (GenericsUtils.hasUnresolvedGenerics(resultType)) {
1033
1036
resultType = originType;
1034
1037
}
1035
1038
*/
1036
-
1037
1039
// track conditional assignment
1038
1040
if (!isNullConstant (rightExpression )
1039
1041
&& leftExpression instanceof VariableExpression
@@ -1446,7 +1448,7 @@ private void addListAssignmentConstructorErrors(
1446
1448
ClassNode[] args = getArgumentTypes(argList);
1447
1449
MethodNode methodNode = checkGroovyStyleConstructor(leftRedirect, args, assignmentExpression);
1448
1450
if (methodNode != null) {
1449
- rightExpression.putNodeMetaData(StaticTypesMarker. DIRECT_METHOD_CALL_TARGET, methodNode);
1451
+ rightExpression.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, methodNode);
1450
1452
}
1451
1453
} else if (!implementsInterfaceOrIsSubclassOf(inferredRightExpressionType, leftRedirect)
1452
1454
&& implementsInterfaceOrIsSubclassOf(inferredRightExpressionType, LIST_TYPE)
@@ -1574,23 +1576,17 @@ protected void typeCheckAssignment(
1574
1576
1575
1577
if (addedReadOnlyPropertyError (leftExpression )) return ;
1576
1578
1577
- ClassNode rTypeInferred , rTypeWrapped ; // check for instanceof and spreading
1578
- if (rightExpression instanceof VariableExpression && hasInferredReturnType (rightExpression ) && assignmentExpression .getOperation ().getType () == ASSIGN ) {
1579
- rTypeInferred = getInferredReturnType (rightExpression );
1580
- } else {
1581
- rTypeInferred = rightExpressionType ;
1582
- }
1583
- rTypeWrapped = adjustTypeForSpreading (rTypeInferred , leftExpression );
1579
+ ClassNode rTypeWrapped = adjustTypeForSpreading (rightExpressionType , leftExpression );
1584
1580
1585
1581
if (!checkCompatibleAssignmentTypes (leftExpressionType , rTypeWrapped , rightExpression )) {
1586
- if (!extension .handleIncompatibleAssignment (leftExpressionType , rTypeInferred , assignmentExpression )) {
1587
- addAssignmentError (leftExpressionType , rTypeInferred , rightExpression );
1582
+ if (!extension .handleIncompatibleAssignment (leftExpressionType , rightExpressionType , assignmentExpression )) {
1583
+ addAssignmentError (leftExpressionType , rightExpressionType , rightExpression );
1588
1584
}
1589
1585
} else {
1590
1586
ClassNode lTypeRedirect = leftExpressionType .redirect ();
1591
- addPrecisionErrors (lTypeRedirect , leftExpressionType , rTypeInferred , rightExpression );
1587
+ addPrecisionErrors (lTypeRedirect , leftExpressionType , rightExpressionType , rightExpression );
1592
1588
if (rightExpression instanceof ListExpression ) {
1593
- addListAssignmentConstructorErrors (lTypeRedirect , leftExpressionType , rTypeInferred , rightExpression , assignmentExpression );
1589
+ addListAssignmentConstructorErrors (lTypeRedirect , leftExpressionType , rightExpressionType , rightExpression , assignmentExpression );
1594
1590
} else if (rightExpression instanceof MapExpression ) {
1595
1591
addMapAssignmentConstructorErrors (lTypeRedirect , leftExpression , rightExpression );
1596
1592
}
@@ -1844,7 +1840,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
1844
1840
// skip property/accessor checks for "x.@field"
1845
1841
if (storeField (field , isAttributeExpression , pexp , receiverType , visitor , receiver .getData (), !readMode )) {
1846
1842
/* GRECLIPSE edit -- GROOVY-5450
1847
- pexp.removeNodeMetaData(StaticTypesMarker. READONLY_PROPERTY);
1843
+ pexp.removeNodeMetaData(READONLY_PROPERTY);
1848
1844
*/
1849
1845
return true ;
1850
1846
} else if (isAttributeExpression ) {
@@ -1854,7 +1850,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
1854
1850
// skip property/accessor checks for "field", "this.field", "this.with { field }", etc. in declaring class of field
1855
1851
if (storeField (field , enclosingTypes .contains (current ), pexp , receiverType , visitor , receiver .getData (), !readMode )) {
1856
1852
/* GRECLIPSE edit -- GROOVY-5450
1857
- pexp.removeNodeMetaData(StaticTypesMarker. READONLY_PROPERTY);
1853
+ pexp.removeNodeMetaData(READONLY_PROPERTY);
1858
1854
*/
1859
1855
return true ;
1860
1856
}
@@ -1882,7 +1878,9 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
1882
1878
ClassNode cn = inferReturnTypeGenerics (current , getter , ArgumentListExpression .EMPTY_ARGUMENTS );
1883
1879
storeInferredTypeForPropertyExpression (pexp , cn );
1884
1880
storeTargetMethod (pexp , getter );
1885
- pexp .removeNodeMetaData (StaticTypesMarker .READONLY_PROPERTY );
1881
+ /* GRECLIPSE edit -- GROOVY-5450
1882
+ pexp.removeNodeMetaData(READONLY_PROPERTY);
1883
+ */
1886
1884
String delegationData = receiver .getData ();
1887
1885
if (delegationData != null )
1888
1886
pexp .putNodeMetaData (StaticTypesMarker .IMPLICIT_RECEIVER , delegationData );
@@ -1914,10 +1912,10 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
1914
1912
return true ;
1915
1913
/* GRECLIPSE edit -- GROOVY-9127
1916
1914
} else if (propertyNode == null) {
1917
- if (field != null && hasAccessToField(typeCheckingContext.getEnclosingClassNode(), field )) {
1918
- pexp.removeNodeMetaData(StaticTypesMarker. READONLY_PROPERTY);
1915
+ if (field != null && hasAccessToField(field, typeCheckingContext.getEnclosingClassNode())) {
1916
+ pexp.removeNodeMetaData(READONLY_PROPERTY);
1919
1917
} else if (getter != null) {
1920
- pexp.putNodeMetaData(StaticTypesMarker. READONLY_PROPERTY, Boolean.TRUE);
1918
+ pexp.putNodeMetaData(READONLY_PROPERTY, Boolean.TRUE);
1921
1919
}
1922
1920
*/
1923
1921
} else if (getter != null && field == null ) {
@@ -2367,16 +2365,7 @@ public void visitForLoop(final ForStatement forLoop) {
2367
2365
super .visitForLoop (forLoop );
2368
2366
} else {
2369
2367
collectionExpression .visit (this );
2370
- /* GRECLIPSE edit -- GROOVY-10179
2371
2368
final ClassNode collectionType = getType (collectionExpression );
2372
- */
2373
- ClassNode collectionType ;
2374
- if (collectionExpression instanceof VariableExpression && hasInferredReturnType (collectionExpression )) {
2375
- collectionType = getInferredReturnType (collectionExpression );
2376
- } else {
2377
- collectionType = getType (collectionExpression );
2378
- }
2379
- // GRECLIPSE end
2380
2369
ClassNode forLoopVariableType = forLoop .getVariableType ();
2381
2370
ClassNode componentType ;
2382
2371
if (Character_TYPE .equals (ClassHelper .getWrapper (forLoopVariableType )) && STRING_TYPE .equals (collectionType )) {
@@ -2729,7 +2718,7 @@ private ClassNode infer(ClassNode target, ClassNode source) {
2729
2718
varX("{source}", source)
2730
2719
);
2731
2720
virtualDecl.visit(this);
2732
- ClassNode newlyInferred = (ClassNode) virtualDecl.getNodeMetaData(StaticTypesMarker. INFERRED_TYPE);
2721
+ ClassNode newlyInferred = (ClassNode) virtualDecl.getNodeMetaData(INFERRED_TYPE);
2733
2722
2734
2723
return !missesGenericsTypes(newlyInferred) ? newlyInferred : null;
2735
2724
}
@@ -2748,12 +2737,7 @@ protected ClassNode checkReturnType(final ReturnStatement statement) {
2748
2737
type = expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
2749
2738
}
2750
2739
*/
2751
- ClassNode type ;
2752
- if (expression instanceof VariableExpression && hasInferredReturnType (expression )) {
2753
- type = getInferredReturnType (expression );
2754
- } else {
2755
- type = getType (expression );
2756
- }
2740
+ ClassNode type = getType (expression );
2757
2741
if (typeCheckingContext .getEnclosingClosure () != null ) {
2758
2742
ClassNode inferredReturnType = getInferredReturnType (typeCheckingContext .getEnclosingClosure ().getClosureExpression ());
2759
2743
if (expression instanceof ConstructorCallExpression ) {
@@ -3236,6 +3220,7 @@ protected void startMethodInference(final MethodNode node, ErrorCollector collec
3236
3220
node .putNodeMetaData (ERROR_COLLECTOR , collector );
3237
3221
}
3238
3222
3223
+ /* GRECLIPSE edit
3239
3224
protected void addTypeCheckingInfoAnnotation(final MethodNode node) {
3240
3225
// TypeChecked$TypeCheckingInfo can not be applied on constructors
3241
3226
if (node instanceof ConstructorNode) return;
@@ -3256,6 +3241,7 @@ protected void addTypeCheckingInfoAnnotation(final MethodNode node) {
3256
3241
}
3257
3242
}
3258
3243
}
3244
+ */
3259
3245
3260
3246
@ Override
3261
3247
public void visitStaticMethodCallExpression (final StaticMethodCallExpression call ) {
@@ -3496,6 +3482,12 @@ private void processNamedParam(AnnotationConstantExpression value, Map<Object, E
3496
3482
}
3497
3483
}
3498
3484
3485
+ /* GRECLIPSE edit
3486
+ private boolean isCompatibleType(ClassNode expectedType, boolean b, ClassNode type) {
3487
+ return b && !isAssignableTo(type, expectedType);
3488
+ }
3489
+ */
3490
+
3499
3491
/**
3500
3492
* This method is responsible for performing type inference on closure argument types whenever code like this is
3501
3493
* found: <code>foo.collect { it.toUpperCase() }</code>.
@@ -3523,6 +3515,7 @@ protected void inferClosureParameterTypes(final ClassNode receiver, final Expres
3523
3515
}
3524
3516
/* GRECLIPSE edit -- GROOVY-8917, GROOVY-9347, GROOVY-10049
3525
3517
} else if (isSAMType(param.getOriginType())) {
3518
+ // SAM coercion
3526
3519
inferSAMType(param, receiver, selectedMethod, InvocationWriter.makeArgumentList(arguments), expression);
3527
3520
}
3528
3521
*/
@@ -4112,16 +4105,7 @@ public void visitMethodCallExpression(MethodCallExpression call) {
4112
4105
4113
4106
// for arguments, we need to visit closures *after* the method has been chosen
4114
4107
4115
- /* GRECLIPSE edit
4116
4108
ClassNode receiver = getType (objectExpression );
4117
- */
4118
- ClassNode receiver ;
4119
- if (objectExpression instanceof VariableExpression && hasInferredReturnType (objectExpression )) {
4120
- receiver = getInferredReturnType (objectExpression );
4121
- } else {
4122
- receiver = getType (objectExpression );
4123
- }
4124
- // GRECLIPSE end
4125
4109
visitMethodCallArguments (receiver , argumentList , false , null );
4126
4110
4127
4111
ClassNode [] args = getArgumentTypes (argumentList );
@@ -4436,22 +4420,6 @@ private int getResolveStrategy(final Parameter parameter) {
4436
4420
}
4437
4421
// GRECLIPSE end
4438
4422
4439
- /**
4440
- * e.g. c(b(a())), a() and b() are nested method call, but c() is not
4441
- * new C(b(a())) a() and b() are nested method call
4442
- *
4443
- * a().b().c(), a() and b() are sandwiched method call, but c() is not
4444
- *
4445
- * a().b().c a() and b() are sandwiched method call
4446
- *
4447
- */
4448
- @ SuppressWarnings ("unused" )
4449
- private boolean isNestedOrSandwichedMethodCall () {
4450
- return typeCheckingContext .getEnclosingMethodCalls ().size () > 1
4451
- || typeCheckingContext .getEnclosingConstructorCalls ().size () > 0
4452
- || typeCheckingContext .getEnclosingPropertyExpressions ().size () > 0 ;
4453
- }
4454
-
4455
4423
/**
4456
4424
* A special method handling the "withTrait" call for which the type checker knows more than
4457
4425
* what the type signature is able to tell. If "withTrait" is detected, then a new class node
@@ -4519,11 +4487,7 @@ protected ClassNode getInferredReturnTypeFromWithClosureArgument(Expression call
4519
4487
4520
4488
visitClosureExpression (closure );
4521
4489
4522
- if (getInferredReturnType (closure ) != null ) {
4523
- return getInferredReturnType (closure );
4524
- }
4525
-
4526
- return null ;
4490
+ return getInferredReturnType (closure );
4527
4491
}
4528
4492
4529
4493
/**
@@ -4542,6 +4506,7 @@ protected List<Receiver<String>> makeOwnerList(final Expression objectExpression
4542
4506
owners.add(0, Receiver.<String>make(clazzGT.getType()));
4543
4507
}
4544
4508
if (receiver.isInterface()) {
4509
+ // GROOVY-xxxx
4545
4510
owners.add(Receiver.<String>make(OBJECT_TYPE));
4546
4511
}
4547
4512
addSelfTypes(receiver, owners);
@@ -4986,10 +4951,10 @@ public void visitTernaryExpression(final TernaryExpression expression) {
4986
4951
*/
4987
4952
// handle instanceof cases
4988
4953
if (hasInferredReturnType (falseExpression )) {
4989
- typeOfFalse = falseExpression . getNodeMetaData ( StaticTypesMarker . INFERRED_RETURN_TYPE );
4954
+ typeOfFalse = getInferredReturnType ( falseExpression );
4990
4955
}
4991
4956
if (hasInferredReturnType (trueExpression )) {
4992
- typeOfTrue = trueExpression . getNodeMetaData ( StaticTypesMarker . INFERRED_RETURN_TYPE );
4957
+ typeOfTrue = getInferredReturnType ( trueExpression );
4993
4958
}
4994
4959
/* GRECLIPSE edit -- GROOVY-9972
4995
4960
typeOfFalse = checkForTargetType(falseExpression, typeOfFalse);
@@ -5235,7 +5200,7 @@ protected ClassNode getResultType(ClassNode left, int op, ClassNode right, Binar
5235
5200
if (leftRedirect.isArray() && implementsInterfaceOrIsSubclassOf(rightRedirect, Collection_TYPE))
5236
5201
return leftRedirect;
5237
5202
if (leftRedirect.implementsInterface(Collection_TYPE) && rightRedirect.implementsInterface(Collection_TYPE)) {
5238
- // because of type inference , we must perform an additional check if the right expression
5203
+ // because of type inferrence , we must perform an additional check if the right expression
5239
5204
// is an empty list expression ([]). In that case and only in that case, the inferred type
5240
5205
// will be wrong, so we will prefer the left type
5241
5206
if (rightExpression instanceof ListExpression) {
@@ -5770,11 +5735,10 @@ protected List<MethodNode> findMethod(ClassNode receiver, final String name, fin
5770
5735
collectAllInterfaceMethodsByName(receiver, name, methods);
5771
5736
}
5772
5737
*/
5773
- // lookup in DGM methods too
5774
- // GRECLIPSE add
5775
- if (!"<init>" .equals (name ) && !"<clinit>" .equals (name ))
5776
- // GRECLIPSE end
5777
- findDGMMethodsByNameAndArguments (getSourceUnit ().getClassLoader (), receiver , name , args , methods );
5738
+ if (!"<init>" .equals (name ) && !"<clinit>" .equals (name )) {
5739
+ // lookup in DGM methods too
5740
+ findDGMMethodsByNameAndArguments (getSourceUnit ().getClassLoader (), receiver , name , args , methods );
5741
+ }
5778
5742
methods = filterMethodsByVisibility (methods );
5779
5743
List <MethodNode > chosen = chooseBestMethod (receiver , methods , args );
5780
5744
if (!chosen .isEmpty ()) return chosen ;
@@ -6423,7 +6387,7 @@ private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals,
6423
6387
Expression a = argumentList.getExpression(i);
6424
6388
if (!(a instanceof MethodCallExpression)) continue;
6425
6389
if (((MethodCallExpression) a).isUsingGenerics()) continue;
6426
- MethodNode aNode = a.getNodeMetaData(StaticTypesMarker. DIRECT_METHOD_CALL_TARGET);
6390
+ MethodNode aNode = a.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
6427
6391
if (aNode == null || aNode.getGenericsTypes() == null) continue;
6428
6392
6429
6393
// and unknown generics
@@ -6656,7 +6620,8 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression
6656
6620
}
6657
6621
ClassNode result = applyGenericsContext(placeholders, samType.redirect());
6658
6622
return result;
6659
- */
6623
+ }
6624
+ */
6660
6625
private static ClassNode convertClosureTypeToSAMType (final Expression expression , final ClassNode closureType , final MethodNode sam , final ClassNode samType ) {
6661
6626
Map <GenericsTypeName , GenericsType > samTypeConnections = GenericsUtils .extractPlaceholders (samType );
6662
6627
samTypeConnections .replaceAll ((xx , gt ) -> // GROOVY-9762, GROOVY-9803: reduce "? super T" to "T"
@@ -6696,8 +6661,8 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression
6696
6661
}
6697
6662
6698
6663
return applyGenericsContext (samTypeConnections , samType .redirect ());
6699
- // GRECLIPSE end
6700
6664
}
6665
+ // GRECLIPSE end
6701
6666
6702
6667
private ClassNode resolveGenericsWithContext (Map <GenericsTypeName , GenericsType > resolvedPlaceholders , ClassNode currentType ) {
6703
6668
/* GRECLIPSE edit -- GROOVY-9570
@@ -7120,11 +7085,11 @@ private static class ParameterVariableExpression extends VariableExpression {
7120
7085
super (parameter );
7121
7086
this .parameter = parameter ;
7122
7087
/* GRECLIPSE edit -- GROOVY-6919
7123
- ClassNode inferred = parameter.getNodeMetaData(StaticTypesMarker. INFERRED_TYPE);
7088
+ ClassNode inferred = parameter.getNodeMetaData(INFERRED_TYPE);
7124
7089
if (inferred == null) {
7125
7090
inferred = infer(parameter);
7126
7091
7127
- parameter.setNodeMetaData(StaticTypesMarker. INFERRED_TYPE, inferred);
7092
+ parameter.setNodeMetaData(INFERRED_TYPE, inferred);
7128
7093
}
7129
7094
*/
7130
7095
parameter .getNodeMetaData (StaticTypesMarker .INFERRED_TYPE , x -> parameter .getOriginType ());
0 commit comments