public void visitAssignmentExpression(GrAssignmentExpression expression) { GrExpression rValue = expression.getRValue(); GrExpression lValue = expression.getLValue(); if (myExpression.equals(rValue)) { PsiType lType = lValue.getNominalType(); if (lType != null) { myResult = new TypeConstraint[] {SubtypeConstraint.create(lType)}; } else if (lValue instanceof GrReferenceExpression) { GroovyResolveResult result = ((GrReferenceExpression) lValue).advancedResolve(); PsiElement resolved = result.getElement(); if (resolved instanceof GrVariable) { PsiType type = ((GrVariable) resolved).getTypeGroovy(); if (type != null) { myResult = new TypeConstraint[] { SubtypeConstraint.create(result.getSubstitutor().substitute(type)) }; } } } } else if (myExpression.equals(lValue)) { if (rValue != null) { PsiType rType = rValue.getType(); if (rType != null) { myResult = new TypeConstraint[] {SupertypeConstraint.create(rType)}; } } } }
@Override public void visitListOrMap(GrListOrMap listOrMap) { if (listOrMap.isMap()) return; final TypeConstraint[] constraints = calculateTypeConstraints(listOrMap); List<PsiType> result = new ArrayList<PsiType>(constraints.length); for (TypeConstraint constraint : constraints) { if (constraint instanceof SubtypeConstraint) { final PsiType type = constraint.getType(); final PsiType iterable = com.intellij.psi.util.PsiUtil.extractIterableTypeParameter(type, true); if (iterable != null) { result.add(iterable); } } } if (result.size() == 0) { myResult = TypeConstraint.EMPTY_ARRAY; } else { myResult = new TypeConstraint[result.size()]; for (int i = 0; i < result.size(); i++) { final PsiType type = result.get(i); if (type != null) { myResult[i] = SubtypeConstraint.create(type); } } } }
private void addConstraintsFromMap( List<TypeConstraint> constraints, Map<GrExpression, Pair<PsiParameter, PsiType>> map) { if (map == null) return; final Pair<PsiParameter, PsiType> pair = map.get(myExpression); if (pair == null) return; final PsiType type = pair.second; if (type == null) return; constraints.add(SubtypeConstraint.create(type)); if (type instanceof PsiArrayType && pair.first.isVarArgs()) { constraints.add(SubtypeConstraint.create(((PsiArrayType) type).getComponentType())); } }
public void visitReturnStatement(GrReturnStatement returnStatement) { GrParametersOwner parent = PsiTreeUtil.getParentOfType(returnStatement, GrMethod.class, GrClosableBlock.class); if (parent instanceof GrMethod) { GrTypeElement typeElement = ((GrMethod) parent).getReturnTypeElementGroovy(); if (typeElement != null) { PsiType type = typeElement.getType(); myResult = new TypeConstraint[] {SubtypeConstraint.create(type)}; } } }
@Override public void visitCaseLabel(GrCaseLabel caseLabel) { final PsiElement parent = caseLabel.getParent().getParent(); assert parent instanceof GrSwitchStatement : parent + " of class " + parent.getClass(); final GrExpression condition = ((GrSwitchStatement) parent).getCondition(); if (condition == null) return; final PsiType type = condition.getType(); if (type == null) return; myResult = new TypeConstraint[] {SubtypeConstraint.create(type)}; }
@Override public void visitSwitchStatement(GrSwitchStatement switchStatement) { final GrCaseSection[] sections = switchStatement.getCaseSections(); List<PsiType> types = new ArrayList<PsiType>(sections.length); for (GrCaseSection section : sections) { final GrExpression value = section.getCaseLabel().getValue(); final PsiType type = value != null ? value.getType() : null; if (type != null) types.add(type); } final PsiType upperBoundNullable = TypesUtil.getLeastUpperBoundNullable(types, switchStatement.getManager()); if (upperBoundNullable == null) return; myResult = new TypeConstraint[] {SubtypeConstraint.create(upperBoundNullable)}; }
public void visitMethodCallExpression(GrMethodCallExpression methodCall) { final GrExpression invokedExpression = methodCall.getInvokedExpression(); if (myExpression.equals(invokedExpression)) { myResult = new TypeConstraint[] { SubtypeConstraint.create(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, methodCall) }; return; } final GrClosableBlock[] closureArgs = methodCall.getClosureArguments(); //noinspection SuspiciousMethodCalls final int closureIndex = Arrays.asList(closureArgs).indexOf(myExpression); if (closureIndex >= 0) { List<TypeConstraint> constraints = new ArrayList<TypeConstraint>(); for (GroovyResolveResult variant : ResolveUtil.getCallVariants(myExpression)) { final GrArgumentList argumentList = methodCall.getArgumentList(); final GrNamedArgument[] namedArgs = argumentList == null ? GrNamedArgument.EMPTY_ARRAY : argumentList.getNamedArguments(); final GrExpression[] expressionArgs = argumentList == null ? GrExpression.EMPTY_ARRAY : argumentList.getExpressionArguments(); try { final Map<GrExpression, Pair<PsiParameter, PsiType>> map = GrClosureSignatureUtil.mapArgumentsToParameters( variant, methodCall, true, true, namedArgs, expressionArgs, closureArgs); addConstraintsFromMap(constraints, map); } catch (RuntimeException e) { LOG.error( "call: " + methodCall.getText() + "\nsymbol: " + variant.getElement().getText(), e); } } if (!constraints.isEmpty()) { myResult = constraints.toArray(new TypeConstraint[constraints.size()]); } } }
@Override public void visitThrowStatement(GrThrowStatement throwStatement) { final PsiClassType throwable = PsiType.getJavaLangThrowable(myExpression.getManager(), throwStatement.getResolveScope()); myResult = new TypeConstraint[] {SubtypeConstraint.create(throwable)}; }