@Override public PsiType[] guessContainerElementType(PsiExpression containerExpr, TextRange rangeToIgnore) { HashSet<PsiType> typesSet = new HashSet<>(); PsiType type = containerExpr.getType(); PsiType elemType; if ((elemType = getGenericElementType(type)) != null) return new PsiType[] {elemType}; if (containerExpr instanceof PsiReferenceExpression) { PsiElement refElement = ((PsiReferenceExpression) containerExpr).resolve(); if (refElement instanceof PsiVariable) { PsiFile file = refElement.getContainingFile(); if (file == null) { file = containerExpr.getContainingFile(); // implicit variable in jsp } HashSet<PsiVariable> checkedVariables = new HashSet<>(); addTypesByVariable( typesSet, (PsiVariable) refElement, file, checkedVariables, CHECK_USAGE | CHECK_DOWN, rangeToIgnore); checkedVariables.clear(); addTypesByVariable( typesSet, (PsiVariable) refElement, file, checkedVariables, CHECK_UP, rangeToIgnore); } } return typesSet.toArray(PsiType.createArray(typesSet.size())); }
@Nullable private static Map<PsiExpression, PsiType> buildDataflowTypeMap(PsiExpression forPlace) { PsiElement scope = DfaPsiUtil.getTopmostBlockInSameClass(forPlace); if (scope == null) { PsiFile file = forPlace.getContainingFile(); if (!(file instanceof PsiCodeFragment)) { return Collections.emptyMap(); } scope = file; } DataFlowRunner runner = new DataFlowRunner() { @NotNull @Override protected DfaMemoryState createMemoryState() { return new ExpressionTypeMemoryState(getFactory()); } }; final ExpressionTypeInstructionVisitor visitor = new ExpressionTypeInstructionVisitor(forPlace); if (runner.analyzeMethod(scope, visitor) == RunnerResult.OK) { return visitor.getResult(); } return null; }