@@ -938,30 +938,9 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType())) {
938
938
if (!isEmptyDeclaration && isAssignment (op )) {
939
939
if (rightExpression instanceof ConstructorCallExpression )
940
940
inferDiamondType ((ConstructorCallExpression ) rightExpression , lType );
941
-
942
- if (lType .isUsingGenerics () && missesGenericsTypes (resultType )) {
943
- // unchecked assignment
944
- // List<Type> list = new LinkedList()
945
- // Iterable<Type> iter = new LinkedList()
946
- // Collection<Type> coll = Collections.emptyList()
947
- // Collection<Type> view = ConcurrentHashMap.newKeySet()
948
-
949
- // the inferred type of the binary expression is the type of the RHS
950
- // "completed" with generics type information available from the LHS
951
- if (lType .equals (resultType )) {
952
- if (!lType .isGenericsPlaceHolder ()) resultType = lType ;
953
- } else if (!resultType .isGenericsPlaceHolder ()) { // GROOVY-10235, GROOVY-10324, et al.
954
- Map <GenericsTypeName , GenericsType > gt = new HashMap <>();
955
- extractGenericsConnections (gt , resultType , resultType .redirect ());
956
- ClassNode sc = resultType ;
957
- do { sc = getNextSuperClass (sc , lType );
958
- } while (sc != null && !sc .equals (lType ));
959
- extractGenericsConnections (gt , lType , sc );
960
-
961
- resultType = applyGenericsContext (gt , resultType .redirect ());
962
- }
963
- }
964
-
941
+ // GRECLIPSE edit -- GROOVY-10235, GROOVY-10324, et al.
942
+ resultType = adjustForTargetType (resultType , lType );
943
+ // GRECLIPSE end
965
944
ClassNode originType = getOriginalDeclarationType (leftExpression );
966
945
typeCheckAssignment (expression , leftExpression , originType , rightExpression , resultType );
967
946
// check for implicit conversion like "String a = 123", "int[] b = [1,2,3]", "List c = [].stream()", etc.
@@ -4914,36 +4893,34 @@ && isEmptyCollection(expr) && isAssignment(enclosingBinaryExpression.getOperatio
4914
4893
*/
4915
4894
ClassNode sourceType = type , targetType = null ;
4916
4895
MethodNode enclosingMethod = typeCheckingContext .getEnclosingMethod ();
4917
- BinaryExpression enclosingBinaryExpression = typeCheckingContext .getEnclosingBinaryExpression ();
4918
- if (enclosingBinaryExpression != null
4919
- && isAssignment (enclosingBinaryExpression .getOperation ().getType ())
4920
- && isTypeSource (expr , enclosingBinaryExpression .getRightExpression ())) {
4921
- targetType = getDeclaredOrInferredType (enclosingBinaryExpression .getLeftExpression ());
4896
+ MethodCall enclosingMethodCall = (MethodCall )typeCheckingContext .getEnclosingMethodCall ();
4897
+ BinaryExpression enclosingExpression = typeCheckingContext .getEnclosingBinaryExpression ();
4898
+ if (enclosingExpression != null
4899
+ && isAssignment (enclosingExpression .getOperation ().getType ())
4900
+ && isTypeSource (expr , enclosingExpression .getRightExpression ())) {
4901
+ targetType = getDeclaredOrInferredType (enclosingExpression .getLeftExpression ());
4902
+ } else if (enclosingMethodCall != null
4903
+ && InvocationWriter .makeArgumentList (enclosingMethodCall .getArguments ())
4904
+ .getExpressions ().stream ().anyMatch (arg -> isTypeSource (expr , arg ))) {
4905
+ // TODO: locate method target parameter
4922
4906
} else if (enclosingMethod != null
4923
4907
&& !enclosingMethod .isAbstract ()
4924
4908
&& !enclosingMethod .isVoidMethod ()
4925
4909
&& isTypeSource (expr , enclosingMethod )) {
4926
4910
targetType = enclosingMethod .getReturnType ();
4927
4911
}
4928
4912
4929
- if (expr instanceof ConstructorCallExpression ) {
4930
- if (targetType == null ) targetType = OBJECT_TYPE ;
4931
- inferDiamondType ((ConstructorCallExpression ) expr , targetType );
4932
- }
4913
+ if (targetType == null ) targetType = OBJECT_TYPE ;
4914
+ if (sourceType == UNKNOWN_PARAMETER_TYPE ) return targetType ;
4933
4915
4934
- if (targetType == null ) return sourceType ;
4916
+ if (expr instanceof ConstructorCallExpression )
4917
+ inferDiamondType ((ConstructorCallExpression ) expr , targetType );
4935
4918
4936
- if (!isPrimitiveType (getUnwrapper (targetType ))
4937
- && !targetType .equals (OBJECT_TYPE ) && missesGenericsTypes (sourceType )) {
4938
- // unchecked assignment with ternary/elvis, like "List<T> list = listOfT ?: []"
4939
- // the inferred type is the RHS type "completed" with generics information from LHS
4940
- return GenericsUtils .parameterizeType (targetType , sourceType .getPlainNodeReference ());
4941
- }
4942
- return targetType != null && sourceType == UNKNOWN_PARAMETER_TYPE ? targetType : sourceType ;
4919
+ return adjustForTargetType (sourceType , targetType );
4943
4920
// GRECLIPSE end
4944
4921
}
4945
4922
4946
- /* GRECLIPSE edit
4923
+ /* GRECLIPSE edit -- GROOVY-10688
4947
4924
private static ClassNode adjustForTargetType(final ClassNode targetType, final ClassNode resultType) {
4948
4925
if (targetType.isUsingGenerics() && missesGenericsTypes(resultType)) {
4949
4926
// unchecked assignment within ternary/elvis
@@ -4956,6 +4933,39 @@ private static ClassNode adjustForTargetType(final ClassNode targetType, final C
4956
4933
return resultType;
4957
4934
}
4958
4935
*/
4936
+ private static ClassNode adjustForTargetType (final ClassNode resultType , final ClassNode targetType ) {
4937
+ if (targetType .isUsingGenerics ()
4938
+ && missesGenericsTypes (resultType )
4939
+ // GROOVY-10324, GROOVY-10342, et al.
4940
+ && !resultType .isGenericsPlaceHolder ()) {
4941
+ // unchecked assignment
4942
+ // List<Type> list = new LinkedList()
4943
+ // Iterable<Type> iter = new LinkedList()
4944
+ // Collection<Type> col1 = Collections.emptyList()
4945
+ // Collection<Type> col2 = Collections.emptyList() ?: []
4946
+ // Collection<Type> view = ConcurrentHashMap.newKeySet()
4947
+
4948
+ // the inferred type of the binary expression is the type of the RHS
4949
+ // "completed" with generics type information available from the LHS
4950
+ if (targetType .equals (resultType )) {
4951
+ // GROOVY-6126, GROOVY-6558, GROOVY-6564, et al.
4952
+ if (!targetType .isGenericsPlaceHolder ()) return targetType ;
4953
+ } else {
4954
+ // GROOVY-5640, GROOVY-9033, GROOVY-10220, GROOVY-10235, et al.
4955
+ Map <GenericsTypeName , GenericsType > gt = new HashMap <>();
4956
+ extractGenericsConnections (gt , resultType , resultType .redirect ());
4957
+ ClassNode sc = resultType ;
4958
+ do { sc = getNextSuperClass (sc , targetType );
4959
+ } while (sc != null && !sc .equals (targetType ));
4960
+ extractGenericsConnections (gt , targetType , sc );
4961
+
4962
+ return applyGenericsContext (gt , resultType .redirect ());
4963
+ }
4964
+ }
4965
+
4966
+ return resultType ;
4967
+ }
4968
+
4959
4969
private static boolean isTypeSource (final Expression expr , final Expression right ) {
4960
4970
if (right instanceof TernaryExpression ) {
4961
4971
return isTypeSource (expr , ((TernaryExpression ) right ).getTrueExpression ())
0 commit comments