@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())); } }
@Nullable public static PsiType getExpectedClosureReturnType(GrClosableBlock closure) { final Set<PsiType> expectedTypes = getDefaultExpectedTypes(closure); List<PsiType> expectedReturnTypes = new ArrayList<PsiType>(); for (PsiType expectedType : expectedTypes) { if (!(expectedType instanceof PsiClassType)) return null; final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType) expectedType).resolveGenerics(); final PsiClass resolved = resolveResult.getElement(); if (resolved == null || !(GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(resolved.getQualifiedName()))) return null; final PsiTypeParameter[] typeParameters = resolved.getTypeParameters(); if (typeParameters.length != 1) return null; final PsiTypeParameter expected = typeParameters[0]; final PsiType expectedReturnType = resolveResult.getSubstitutor().substitute(expected); if (expectedReturnType == PsiType.VOID || expectedReturnType == null) return null; expectedReturnTypes.add(expectedReturnType); } return TypesUtil.getLeastUpperBoundNullable(expectedReturnTypes, closure.getManager()); }
private <T extends InstructionImpl> T addNode(T instruction) { instruction.setNumber(myInstructionNumber++); myInstructions.add(instruction); if (myHead != null) { addEdge(myHead, instruction); } myHead = instruction; return instruction; }
private List<GotoInstruction> collectAndRemoveAllPendingNegations(GroovyPsiElement currentScope) { List<GotoInstruction> negations = new ArrayList<GotoInstruction>(); for (Iterator<Pair<InstructionImpl, GroovyPsiElement>> iterator = myPending.iterator(); iterator.hasNext(); ) { Pair<InstructionImpl, GroovyPsiElement> pair = iterator.next(); InstructionImpl instruction = pair.first; GroovyPsiElement scope = pair.second; if (!PsiTreeUtil.isAncestor(scope, currentScope, true) && instruction instanceof GotoInstruction) { negations.add((GotoInstruction) instruction); iterator.remove(); } } return negations; }
@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)}; }