PsiType (@NotNull GrFunctionalExpression expression, int index) { PsiElement parent = expression.getParent(); if (parent instanceof GrStringInjection && index == 0) { return TypesUtil.createTypeByFQClassName("java.io.StringWriter", expression); } if (parent instanceof GrArgumentList) parent = parent.getParent(); if (!(parent instanceof GrMethodCall)) { return null; } String methodName = findMethodName((GrMethodCall)parent); GrExpression invokedExpression = ((GrMethodCall)parent).getInvokedExpression(); if (!(invokedExpression instanceof GrReferenceExpression)) return null; GrExpression qualifier = ((GrReferenceExpression)invokedExpression).getQualifierExpression(); if (qualifier == null) return null; PsiType type = qualifier.getType(); if (type == null) { return null; } final PsiParameter[] params = expression.getAllParameters(); if (params.length == 1 && simpleTypes.containsKey(methodName)) { final String typeText = simpleTypes.get(methodName); if (typeText.indexOf('<') < 0) { return TypesUtil.createTypeByFQClassName(typeText, expression); } else { return JavaPsiFacade.getElementFactory(expression.getProject()).createTypeFromText(typeText, expression); } } if (iterations.contains(methodName)) { if (params.length == 1) { return findTypeForIteration(qualifier, expression); } if (params.length == 2 && InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) { if (index == 0) { return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 0, true); } return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 1, true); } } else if (GdkMethodUtil.isWithName(methodName) && params.length == 1) { return type; } else if (GdkMethodUtil.EACH_WITH_INDEX.equals(methodName)) { PsiType res = findTypeForIteration(qualifier, expression); if (params.length == 2 && res != null) { if (index == 0) { return res; } return TypesUtil.createTypeByFQClassName(JAVA_LANG_INTEGER, expression); } if (InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) { if (params.length == 2) { if (index == 0) { return getEntryForMap(type, expression.getProject(), expression.getResolveScope()); } return TypesUtil.createTypeByFQClassName(JAVA_LANG_INTEGER, expression); } if (params.length == 3) { if (index == 0) { return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 0, true); } if (index == 1) { return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 1, true); } return TypesUtil.createTypeByFQClassName(JAVA_LANG_INTEGER, expression); } } } else if (GdkMethodUtil.INJECT.equals(methodName) && params.length == 2) { if (index == 0) { return TypesUtil.createTypeByFQClassName(JAVA_LANG_OBJECT, expression); } PsiType res = findTypeForIteration(qualifier, expression); if (res != null) { return res; } if (InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) { return getEntryForMap(type, expression.getProject(), expression.getResolveScope()); } } else if (GdkMethodUtil.EACH_PERMUTATION.equals(methodName) && params.length == 1) { final PsiType itemType = findTypeForIteration(qualifier, expression); if (itemType != null) { return JavaPsiFacade.getElementFactory(expression.getProject()).createTypeFromText( JAVA_UTIL_ARRAY_LIST + "<" + itemType.getCanonicalText() + ">", expression); } return TypesUtil.createTypeByFQClassName(JAVA_UTIL_ARRAY_LIST, expression); } else if (GdkMethodUtil.WITH_DEFAULT.equals(methodName)) { if (params.length == 1 && InheritanceUtil.isInheritor(type, JAVA_UTIL_MAP)) { return PsiUtil.substituteTypeParameter(type, JAVA_UTIL_MAP, 0, true); } } else if (GdkMethodUtil.SORT.equals(methodName)) { if (params.length < 3) { return findTypeForIteration(qualifier, expression); } } else if (GdkMethodUtil.WITH_STREAM.equals(methodName)) { final PsiMethod method = ((GrMethodCall)parent).resolveMethod(); if (method instanceof GrGdkMethod) { return qualifier.getType(); } else if (method != null) { final PsiParameter[] parameters = method.getParameterList().getParameters(); if (parameters.length > 0) { return parameters[0].getType(); } } } else if (GdkMethodUtil.WITH_STREAMS.equals(methodName)) { if (index == 0) { return TypesUtil.createTypeByFQClassName("java.io.InputStream", expression); } else if (index == 1) return TypesUtil.createTypeByFQClassName("java.io.OutputStream", expression); } else if (GdkMethodUtil.WITH_OBJECT_STREAMS.equals(methodName)) { if (index == 0) { return TypesUtil.createTypeByFQClassName("java.io.ObjectInputStream", expression); } else if (index == 1) return TypesUtil.createTypeByFQClassName("java.io.ObjectOutputStream", expression); } return null; }