@@ -938,30 +938,9 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType())) {
938938 if (!isEmptyDeclaration && isAssignment (op )) {
939939 if (rightExpression instanceof ConstructorCallExpression )
940940 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
965944 ClassNode originType = getOriginalDeclarationType (leftExpression );
966945 typeCheckAssignment (expression , leftExpression , originType , rightExpression , resultType );
967946 // 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
49144893 */
49154894 ClassNode sourceType = type , targetType = null ;
49164895 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
49224906 } else if (enclosingMethod != null
49234907 && !enclosingMethod .isAbstract ()
49244908 && !enclosingMethod .isVoidMethod ()
49254909 && isTypeSource (expr , enclosingMethod )) {
49264910 targetType = enclosingMethod .getReturnType ();
49274911 }
49284912
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 ;
49334915
4934- if (targetType == null ) return sourceType ;
4916+ if (expr instanceof ConstructorCallExpression )
4917+ inferDiamondType ((ConstructorCallExpression ) expr , targetType );
49354918
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 );
49434920 // GRECLIPSE end
49444921 }
49454922
4946- /* GRECLIPSE edit
4923+ /* GRECLIPSE edit -- GROOVY-10688
49474924 private static ClassNode adjustForTargetType(final ClassNode targetType, final ClassNode resultType) {
49484925 if (targetType.isUsingGenerics() && missesGenericsTypes(resultType)) {
49494926 // unchecked assignment within ternary/elvis
@@ -4956,6 +4933,39 @@ private static ClassNode adjustForTargetType(final ClassNode targetType, final C
49564933 return resultType;
49574934 }
49584935 */
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+
49594969 private static boolean isTypeSource (final Expression expr , final Expression right ) {
49604970 if (right instanceof TernaryExpression ) {
49614971 return isTypeSource (expr , ((TernaryExpression ) right ).getTrueExpression ())
0 commit comments