@@ -676,7 +676,7 @@ public void visitVariableExpression(VariableExpression vexp) {
676676
677677 ClassNode inferredType = getInferredTypeFromTempInfo (vexp , null );
678678 if (inferredType != null && !inferredType .equals (OBJECT_TYPE )) {
679- vexp .putNodeMetaData (StaticTypesMarker .INFERRED_RETURN_TYPE , inferredType );
679+ vexp .putNodeMetaData (StaticTypesMarker .INFERRED_TYPE , inferredType ); // GROOVY-9454
680680 } else {
681681 storeType (vexp , getType (vexp ));
682682 }
@@ -722,10 +722,15 @@ public void visitVariableExpression(VariableExpression vexp) {
722722
723723 if (variable != null ) {
724724 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.
726726 if (inferredType != null && !inferredType.getName().equals("java.lang.Object")) {
727727 vexp.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, inferredType);
728728 }
729+ */
730+ if (inferredType != null && !inferredType .equals (OBJECT_TYPE ) && !inferredType .equals (accessedVariable .getType ())) {
731+ vexp .putNodeMetaData (StaticTypesMarker .INFERRED_TYPE , inferredType );
732+ }
733+ // GRECLIPSE end
729734 }
730735 }
731736 return ;
@@ -888,8 +893,6 @@ public void visitBinaryExpression(final BinaryExpression expression) {
888893 } else if (isClosureWithType (lType ) && rightExpression instanceof ClosureExpression ) {
889894 storeInferredReturnType (rightExpression , getCombinedBoundType (lType .getGenericsTypes ()[0 ]));
890895 }
891- } else if (leftExpression instanceof VariableExpression && hasInferredReturnType (leftExpression )) {
892- lType = getInferredReturnType (leftExpression );
893896 } else {
894897 lType = getType (leftExpression );
895898 }
@@ -1033,7 +1036,6 @@ else if (GenericsUtils.hasUnresolvedGenerics(resultType)) {
10331036 resultType = originType;
10341037 }
10351038 */
1036-
10371039 // track conditional assignment
10381040 if (!isNullConstant (rightExpression )
10391041 && leftExpression instanceof VariableExpression
@@ -1446,7 +1448,7 @@ private void addListAssignmentConstructorErrors(
14461448 ClassNode[] args = getArgumentTypes(argList);
14471449 MethodNode methodNode = checkGroovyStyleConstructor(leftRedirect, args, assignmentExpression);
14481450 if (methodNode != null) {
1449- rightExpression.putNodeMetaData(StaticTypesMarker. DIRECT_METHOD_CALL_TARGET, methodNode);
1451+ rightExpression.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, methodNode);
14501452 }
14511453 } else if (!implementsInterfaceOrIsSubclassOf(inferredRightExpressionType, leftRedirect)
14521454 && implementsInterfaceOrIsSubclassOf(inferredRightExpressionType, LIST_TYPE)
@@ -1574,23 +1576,17 @@ protected void typeCheckAssignment(
15741576
15751577 if (addedReadOnlyPropertyError (leftExpression )) return ;
15761578
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 );
15841580
15851581 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 );
15881584 }
15891585 } else {
15901586 ClassNode lTypeRedirect = leftExpressionType .redirect ();
1591- addPrecisionErrors (lTypeRedirect , leftExpressionType , rTypeInferred , rightExpression );
1587+ addPrecisionErrors (lTypeRedirect , leftExpressionType , rightExpressionType , rightExpression );
15921588 if (rightExpression instanceof ListExpression ) {
1593- addListAssignmentConstructorErrors (lTypeRedirect , leftExpressionType , rTypeInferred , rightExpression , assignmentExpression );
1589+ addListAssignmentConstructorErrors (lTypeRedirect , leftExpressionType , rightExpressionType , rightExpression , assignmentExpression );
15941590 } else if (rightExpression instanceof MapExpression ) {
15951591 addMapAssignmentConstructorErrors (lTypeRedirect , leftExpression , rightExpression );
15961592 }
@@ -1844,7 +1840,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
18441840 // skip property/accessor checks for "x.@field"
18451841 if (storeField (field , isAttributeExpression , pexp , receiverType , visitor , receiver .getData (), !readMode )) {
18461842 /* GRECLIPSE edit -- GROOVY-5450
1847- pexp.removeNodeMetaData(StaticTypesMarker. READONLY_PROPERTY);
1843+ pexp.removeNodeMetaData(READONLY_PROPERTY);
18481844 */
18491845 return true ;
18501846 } else if (isAttributeExpression ) {
@@ -1854,7 +1850,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
18541850 // skip property/accessor checks for "field", "this.field", "this.with { field }", etc. in declaring class of field
18551851 if (storeField (field , enclosingTypes .contains (current ), pexp , receiverType , visitor , receiver .getData (), !readMode )) {
18561852 /* GRECLIPSE edit -- GROOVY-5450
1857- pexp.removeNodeMetaData(StaticTypesMarker. READONLY_PROPERTY);
1853+ pexp.removeNodeMetaData(READONLY_PROPERTY);
18581854 */
18591855 return true ;
18601856 }
@@ -1882,7 +1878,9 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
18821878 ClassNode cn = inferReturnTypeGenerics (current , getter , ArgumentListExpression .EMPTY_ARGUMENTS );
18831879 storeInferredTypeForPropertyExpression (pexp , cn );
18841880 storeTargetMethod (pexp , getter );
1885- pexp .removeNodeMetaData (StaticTypesMarker .READONLY_PROPERTY );
1881+ /* GRECLIPSE edit -- GROOVY-5450
1882+ pexp.removeNodeMetaData(READONLY_PROPERTY);
1883+ */
18861884 String delegationData = receiver .getData ();
18871885 if (delegationData != null )
18881886 pexp .putNodeMetaData (StaticTypesMarker .IMPLICIT_RECEIVER , delegationData );
@@ -1914,10 +1912,10 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
19141912 return true ;
19151913 /* GRECLIPSE edit -- GROOVY-9127
19161914 } 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);
19191917 } else if (getter != null) {
1920- pexp.putNodeMetaData(StaticTypesMarker. READONLY_PROPERTY, Boolean.TRUE);
1918+ pexp.putNodeMetaData(READONLY_PROPERTY, Boolean.TRUE);
19211919 }
19221920 */
19231921 } else if (getter != null && field == null ) {
@@ -2367,16 +2365,7 @@ public void visitForLoop(final ForStatement forLoop) {
23672365 super .visitForLoop (forLoop );
23682366 } else {
23692367 collectionExpression .visit (this );
2370- /* GRECLIPSE edit -- GROOVY-10179
23712368 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
23802369 ClassNode forLoopVariableType = forLoop .getVariableType ();
23812370 ClassNode componentType ;
23822371 if (Character_TYPE .equals (ClassHelper .getWrapper (forLoopVariableType )) && STRING_TYPE .equals (collectionType )) {
@@ -2729,7 +2718,7 @@ private ClassNode infer(ClassNode target, ClassNode source) {
27292718 varX("{source}", source)
27302719 );
27312720 virtualDecl.visit(this);
2732- ClassNode newlyInferred = (ClassNode) virtualDecl.getNodeMetaData(StaticTypesMarker. INFERRED_TYPE);
2721+ ClassNode newlyInferred = (ClassNode) virtualDecl.getNodeMetaData(INFERRED_TYPE);
27332722
27342723 return !missesGenericsTypes(newlyInferred) ? newlyInferred : null;
27352724 }
@@ -2748,12 +2737,7 @@ protected ClassNode checkReturnType(final ReturnStatement statement) {
27482737 type = expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
27492738 }
27502739 */
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 );
27572741 if (typeCheckingContext .getEnclosingClosure () != null ) {
27582742 ClassNode inferredReturnType = getInferredReturnType (typeCheckingContext .getEnclosingClosure ().getClosureExpression ());
27592743 if (expression instanceof ConstructorCallExpression ) {
@@ -3236,6 +3220,7 @@ protected void startMethodInference(final MethodNode node, ErrorCollector collec
32363220 node .putNodeMetaData (ERROR_COLLECTOR , collector );
32373221 }
32383222
3223+ /* GRECLIPSE edit
32393224 protected void addTypeCheckingInfoAnnotation(final MethodNode node) {
32403225 // TypeChecked$TypeCheckingInfo can not be applied on constructors
32413226 if (node instanceof ConstructorNode) return;
@@ -3256,6 +3241,7 @@ protected void addTypeCheckingInfoAnnotation(final MethodNode node) {
32563241 }
32573242 }
32583243 }
3244+ */
32593245
32603246 @ Override
32613247 public void visitStaticMethodCallExpression (final StaticMethodCallExpression call ) {
@@ -3496,6 +3482,12 @@ private void processNamedParam(AnnotationConstantExpression value, Map<Object, E
34963482 }
34973483 }
34983484
3485+ /* GRECLIPSE edit
3486+ private boolean isCompatibleType(ClassNode expectedType, boolean b, ClassNode type) {
3487+ return b && !isAssignableTo(type, expectedType);
3488+ }
3489+ */
3490+
34993491 /**
35003492 * This method is responsible for performing type inference on closure argument types whenever code like this is
35013493 * found: <code>foo.collect { it.toUpperCase() }</code>.
@@ -3523,6 +3515,7 @@ protected void inferClosureParameterTypes(final ClassNode receiver, final Expres
35233515 }
35243516 /* GRECLIPSE edit -- GROOVY-8917, GROOVY-9347, GROOVY-10049
35253517 } else if (isSAMType(param.getOriginType())) {
3518+ // SAM coercion
35263519 inferSAMType(param, receiver, selectedMethod, InvocationWriter.makeArgumentList(arguments), expression);
35273520 }
35283521 */
@@ -4112,16 +4105,7 @@ public void visitMethodCallExpression(MethodCallExpression call) {
41124105
41134106 // for arguments, we need to visit closures *after* the method has been chosen
41144107
4115- /* GRECLIPSE edit
41164108 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
41254109 visitMethodCallArguments (receiver , argumentList , false , null );
41264110
41274111 ClassNode [] args = getArgumentTypes (argumentList );
@@ -4436,22 +4420,6 @@ private int getResolveStrategy(final Parameter parameter) {
44364420 }
44374421 // GRECLIPSE end
44384422
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-
44554423 /**
44564424 * A special method handling the "withTrait" call for which the type checker knows more than
44574425 * 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
45194487
45204488 visitClosureExpression (closure );
45214489
4522- if (getInferredReturnType (closure ) != null ) {
4523- return getInferredReturnType (closure );
4524- }
4525-
4526- return null ;
4490+ return getInferredReturnType (closure );
45274491 }
45284492
45294493 /**
@@ -4542,6 +4506,7 @@ protected List<Receiver<String>> makeOwnerList(final Expression objectExpression
45424506 owners.add(0, Receiver.<String>make(clazzGT.getType()));
45434507 }
45444508 if (receiver.isInterface()) {
4509+ // GROOVY-xxxx
45454510 owners.add(Receiver.<String>make(OBJECT_TYPE));
45464511 }
45474512 addSelfTypes(receiver, owners);
@@ -4986,10 +4951,10 @@ public void visitTernaryExpression(final TernaryExpression expression) {
49864951 */
49874952 // handle instanceof cases
49884953 if (hasInferredReturnType (falseExpression )) {
4989- typeOfFalse = falseExpression . getNodeMetaData ( StaticTypesMarker . INFERRED_RETURN_TYPE );
4954+ typeOfFalse = getInferredReturnType ( falseExpression );
49904955 }
49914956 if (hasInferredReturnType (trueExpression )) {
4992- typeOfTrue = trueExpression . getNodeMetaData ( StaticTypesMarker . INFERRED_RETURN_TYPE );
4957+ typeOfTrue = getInferredReturnType ( trueExpression );
49934958 }
49944959 /* GRECLIPSE edit -- GROOVY-9972
49954960 typeOfFalse = checkForTargetType(falseExpression, typeOfFalse);
@@ -5235,7 +5200,7 @@ protected ClassNode getResultType(ClassNode left, int op, ClassNode right, Binar
52355200 if (leftRedirect.isArray() && implementsInterfaceOrIsSubclassOf(rightRedirect, Collection_TYPE))
52365201 return leftRedirect;
52375202 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
52395204 // is an empty list expression ([]). In that case and only in that case, the inferred type
52405205 // will be wrong, so we will prefer the left type
52415206 if (rightExpression instanceof ListExpression) {
@@ -5770,11 +5735,10 @@ protected List<MethodNode> findMethod(ClassNode receiver, final String name, fin
57705735 collectAllInterfaceMethodsByName(receiver, name, methods);
57715736 }
57725737 */
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+ }
57785742 methods = filterMethodsByVisibility (methods );
57795743 List <MethodNode > chosen = chooseBestMethod (receiver , methods , args );
57805744 if (!chosen .isEmpty ()) return chosen ;
@@ -6423,7 +6387,7 @@ private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals,
64236387 Expression a = argumentList.getExpression(i);
64246388 if (!(a instanceof MethodCallExpression)) continue;
64256389 if (((MethodCallExpression) a).isUsingGenerics()) continue;
6426- MethodNode aNode = a.getNodeMetaData(StaticTypesMarker. DIRECT_METHOD_CALL_TARGET);
6390+ MethodNode aNode = a.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
64276391 if (aNode == null || aNode.getGenericsTypes() == null) continue;
64286392
64296393 // and unknown generics
@@ -6656,7 +6620,8 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression
66566620 }
66576621 ClassNode result = applyGenericsContext(placeholders, samType.redirect());
66586622 return result;
6659- */
6623+ }
6624+ */
66606625 private static ClassNode convertClosureTypeToSAMType (final Expression expression , final ClassNode closureType , final MethodNode sam , final ClassNode samType ) {
66616626 Map <GenericsTypeName , GenericsType > samTypeConnections = GenericsUtils .extractPlaceholders (samType );
66626627 samTypeConnections .replaceAll ((xx , gt ) -> // GROOVY-9762, GROOVY-9803: reduce "? super T" to "T"
@@ -6696,8 +6661,8 @@ private static ClassNode convertClosureTypeToSAMType(final Expression expression
66966661 }
66976662
66986663 return applyGenericsContext (samTypeConnections , samType .redirect ());
6699- // GRECLIPSE end
67006664 }
6665+ // GRECLIPSE end
67016666
67026667 private ClassNode resolveGenericsWithContext (Map <GenericsTypeName , GenericsType > resolvedPlaceholders , ClassNode currentType ) {
67036668 /* GRECLIPSE edit -- GROOVY-9570
@@ -7120,11 +7085,11 @@ private static class ParameterVariableExpression extends VariableExpression {
71207085 super (parameter );
71217086 this .parameter = parameter ;
71227087 /* GRECLIPSE edit -- GROOVY-6919
7123- ClassNode inferred = parameter.getNodeMetaData(StaticTypesMarker. INFERRED_TYPE);
7088+ ClassNode inferred = parameter.getNodeMetaData(INFERRED_TYPE);
71247089 if (inferred == null) {
71257090 inferred = infer(parameter);
71267091
7127- parameter.setNodeMetaData(StaticTypesMarker. INFERRED_TYPE, inferred);
7092+ parameter.setNodeMetaData(INFERRED_TYPE, inferred);
71287093 }
71297094 */
71307095 parameter .getNodeMetaData (StaticTypesMarker .INFERRED_TYPE , x -> parameter .getOriginType ());
0 commit comments