@Override public GroovyResolveResult[] resolve( GrAssignmentExpressionImpl assignmentExpression, boolean incompleteCode) { final IElementType opType = assignmentExpression.getOperationToken(); if (opType == null || opType == GroovyTokenTypes.mASSIGN) return GroovyResolveResult.EMPTY_ARRAY; final GrExpression lValue = assignmentExpression.getLValue(); final PsiType lType; if (!(lValue instanceof GrIndexProperty)) { lType = lValue.getType(); } else { /* now we have something like map[i] += 2. It equals to map.putAt(i, map.getAt(i).plus(2)) by default map[i] resolves to putAt, but we need getAt(). so this hack is for it =) */ lType = ((GrExpression) lValue.copy()).getType(); } if (lType == null) return GroovyResolveResult.EMPTY_ARRAY; final GrExpression rightOperand = assignmentExpression.getRValue(); PsiType rType = rightOperand == null ? null : rightOperand.getType(); final IElementType operatorToken = TokenSets.ASSIGNMENTS_TO_OPERATORS.get(opType); return TypesUtil.getOverloadedOperatorCandidates( lType, operatorToken, assignmentExpression, new PsiType[] {rType}); }
@Override public PsiType fun(GrAssignmentExpressionImpl assignment) { final GroovyResolveResult[] results = assignment.multiResolve(false); if (results.length == 0) { final GrExpression rValue = assignment.getRValue(); return rValue == null ? null : rValue.getType(); } PsiType returnType = null; final PsiManager manager = assignment.getManager(); for (GroovyResolveResult result : results) { final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(result, assignment); returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager); } return returnType; }