@NotNull public static List<MethodContract> inferContracts(@NotNull final PsiMethod method) { if (!InferenceFromSourceUtil.shouldInferFromSource(method)) { return Collections.emptyList(); } return CachedValuesManager.getCachedValue(method, new CachedValueProvider<List<MethodContract>>() { @Nullable @Override public Result<List<MethodContract>> compute() { List<MethodContract> result = RecursionManager.doPreventingRecursion(method, true, new Computable<List<MethodContract>>() { @Override public List<MethodContract> compute() { return new ContractInferenceInterpreter(method).inferContracts(); } }); if (result == null) result = Collections.emptyList(); return Result.create(result, method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } }); }
public static Nullness inferNullity(final PsiMethod method) { if (!InferenceFromSourceUtil.shouldInferFromSource(method)) { return Nullness.UNKNOWN; } PsiType type = method.getReturnType(); if (type == null || type instanceof PsiPrimitiveType) { return Nullness.UNKNOWN; } return CachedValuesManager.getCachedValue(method, new CachedValueProvider<Nullness>() { @Nullable @Override public Result<Nullness> compute() { Nullness result = RecursionManager.doPreventingRecursion(method, true, new Computable<Nullness>() { @Override public Nullness compute() { return doInferNullity(method); } }); if (result == null) result = Nullness.UNKNOWN; return Result.create(result, method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } }); }
public static boolean inferPurity(@NotNull final PsiMethod method) { if (!InferenceFromSourceUtil.shouldInferFromSource(method) || method.getReturnType() == PsiType.VOID || method.getBody() == null || method.isConstructor() || PropertyUtil.isSimpleGetter(method)) { return false; } return CachedValuesManager.getCachedValue(method, new CachedValueProvider<Boolean>() { @Nullable @Override public Result<Boolean> compute() { boolean pure = RecursionManager.doPreventingRecursion(method, true, new Computable<Boolean>() { @Override public Boolean compute() { return doInferPurity(method); } }) == Boolean.TRUE; return Result.create(pure, method); } }); }
@Nullable private static PsiType getLeastUpperBoundByVar(@NotNull final GrVariable var) { return RecursionManager.doPreventingRecursion(var, false, new NullableComputable<PsiType>() { @Override public PsiType compute() { final Collection<PsiReference> all = ReferencesSearch.search(var, var.getUseScope()).findAll(); final GrExpression initializer = var.getInitializerGroovy(); if (initializer == null && all.isEmpty()) { return var.getDeclaredType(); } PsiType result = initializer != null ? initializer.getType() : null; final PsiManager manager = var.getManager(); for (PsiReference reference : all) { final PsiElement ref = reference.getElement(); if (ref instanceof GrReferenceExpression && PsiUtil.isLValue(((GrReferenceExpression)ref))) { result = TypesUtil.getLeastUpperBoundNullable(result, TypeInferenceHelper.getInitializerTypeFor(ref), manager); } } return result; } }); }
@Override public GroovyResolveResult[] resolveByShape() { final InferenceContext context = TypeInferenceHelper.getCurrentContext(); return context.getCachedValue(this, new Computable<GroovyResolveResult[]>() { @Override public GroovyResolveResult[] compute() { Pair<GrReferenceExpressionImpl, InferenceContext> key = Pair.create(GrReferenceExpressionImpl.this, context); GroovyResolveResult[] value = RecursionManager.doPreventingRecursion(key, true, new Computable<GroovyResolveResult[]>() { @Override public GroovyResolveResult[] compute() { return doPolyResolve(false, false); } }); return value == null ? GroovyResolveResult.EMPTY_ARRAY : value; } }); }
private ASTNode failedToBindStubToAst(@Nonnull PsiFileImpl file, @Nonnull final FileElement fileElement) { VirtualFile vFile = file.getVirtualFile(); StubTree stubTree = file.getStubTree(); final String stubString = stubTree != null ? ((PsiFileStubImpl)stubTree.getRoot()).printTree() : null; final String astString = RecursionManager.doPreventingRecursion("failedToBindStubToAst", true, () -> DebugUtil.treeToString(fileElement, true)); @NonNls final String message = "Failed to bind stub to AST for element " + getClass() + " in " + (vFile == null ? "<unknown file>" : vFile.getPath()) + "\nFile:\n" + file + "@" + System.identityHashCode(file); final String creationTraces = ourTraceStubAstBinding ? dumpCreationTraces(fileElement) : null; List<Attachment> attachments = new ArrayList<>(); if (stubString != null) { attachments.add(new Attachment("stubTree.txt", stubString)); } if (astString != null) { attachments.add(new Attachment("ast.txt", astString)); } if (creationTraces != null) { attachments.add(new Attachment("creationTraces.txt", creationTraces)); } throw new RuntimeExceptionWithAttachments(message, attachments.toArray(Attachment.EMPTY_ARRAY)); }
@NotNull @Override public JavaScriptType getType() { final JSExpression initializer = getInitializer(); if(initializer != null) { JavaScriptType javaScriptType = RecursionManager.doPreventingRecursion(this, false, new Computable<JavaScriptType>() { @Override @RequiredReadAction public JavaScriptType compute() { return initializer.getType(); } }); return javaScriptType == null ? JavaScriptType.UNKNOWN : javaScriptType; } return JavaScriptType.UNKNOWN; }
@NotNull public static List<StandardMethodContract> inferContracts(@NotNull PsiMethodImpl method) { if(!InferenceFromSourceUtil.shouldInferFromSource(method)) { return Collections.emptyList(); } return CachedValuesManager.getCachedValue(method, () -> { MethodData data = ContractInferenceIndexKt.getIndexedData(method); List<PreContract> preContracts = data == null ? Collections.emptyList() : data.getContracts(); List<StandardMethodContract> result = RecursionManager.doPreventingRecursion(method, true, () -> postProcessContracts(method, data, preContracts)); if(result == null) { result = Collections.emptyList(); } return CachedValueProvider.Result.create(result, method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); }); }
public static Nullness inferNullity(PsiMethodImpl method) { if(!InferenceFromSourceUtil.shouldInferFromSource(method)) { return Nullness.UNKNOWN; } PsiType type = method.getReturnType(); if(type == null || type instanceof PsiPrimitiveType) { return Nullness.UNKNOWN; } return CachedValuesManager.getCachedValue(method, () -> { MethodData data = ContractInferenceIndexKt.getIndexedData(method); NullityInferenceResult result = data == null ? null : data.getNullity(); Nullness nullness = result == null ? null : RecursionManager.doPreventingRecursion(method, true, () -> result.getNullness(method, data.methodBody(method))); if(nullness == null) { nullness = Nullness.UNKNOWN; } return CachedValueProvider.Result.create(nullness, method, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); }); }
@Nullable private static Color getInitializerColor(@NotNull PsiVariable var) { if(!JavaColorProvider.isColorType(var.getType())) { return null; } PsiExpression expression = getInitializer(var); if(expression instanceof PsiReferenceExpression) { final PsiElement target = ((PsiReferenceExpression) expression).resolve(); if(target instanceof PsiVariable) { return RecursionManager.doPreventingRecursion(expression, true, () -> getInitializerColor((PsiVariable) target)); } } return JavaColorProvider.getJavaColorFromExpression(expression); }
@Nullable private static Color getExpressionColor(@Nullable PsiExpression expression) { if (expression instanceof PsiReferenceExpression) { final PsiElement target = ((PsiReferenceExpression)expression).resolve(); if (target instanceof PsiVariable) { return RecursionManager.doPreventingRecursion(expression, true, new Computable<Color>() { @Override public Color compute() { return getExpressionColor(((PsiVariable)target).getInitializer()); } }); } } return JavaColorProvider.getJavaColorFromExpression(expression); }
@Override @Nullable public <T extends SemElement> List<T> getSemElements(final SemKey<T> key, @NotNull final PsiElement psi) { List<T> cached = _getCachedSemElements(key, true, psi); if (cached != null) { return cached; } ensureInitialized(); RecursionGuard.StackStamp stamp = RecursionManager.createGuard("semService").markStack(); LinkedHashSet<T> result = new LinkedHashSet<T>(); final Map<SemKey, List<SemElement>> map = new THashMap<SemKey, List<SemElement>>(); for (final SemKey each : key.getInheritors()) { List<SemElement> list = createSemElements(each, psi); map.put(each, list); result.addAll((List<T>)list); } if (stamp.mayCacheNow()) { final SemCacheChunk persistent = getOrCreateChunk(psi); for (SemKey semKey : map.keySet()) { persistent.putSemElements(semKey, map.get(semKey)); } } return new ArrayList<T>(result); }
@Override public Result<PsiElement[]> compute() { PsiElement[] result = RecursionManager.doPreventingRecursion(myXincludeTag, true, new NullableComputable<PsiElement[]>() { @Override public PsiElement[] compute() { return computeInclusion(myXincludeTag); } }); return Result.create(result == null ? PsiElement.EMPTY_ARRAY : result, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); }
@Nullable public static PsiType getTypeOf(@Nullable final GrExpression expression) { if (expression == null) return null; return RecursionManager.doPreventingRecursion(expression, true, new Computable<PsiType>() { @Override public PsiType compute() { return expression.getNominalType(); } }); }
@Nullable public static PsiClassType getCategoryType(@NotNull final PsiClass categoryAnnotationOwner) { return CachedValuesManager.getCachedValue(categoryAnnotationOwner, new CachedValueProvider<PsiClassType>() { @Override public Result<PsiClassType> compute() { return Result.create(inferCategoryType(categoryAnnotationOwner), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } @Nullable private PsiClassType inferCategoryType(final PsiClass aClass) { return RecursionManager.doPreventingRecursion(aClass, true, new NullableComputable<PsiClassType>() { @Nullable @Override public PsiClassType compute() { final PsiModifierList modifierList = aClass.getModifierList(); if (modifierList == null) return null; final PsiAnnotation annotation = modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_LANG_CATEGORY); if (annotation == null) return null; PsiAnnotationMemberValue value = annotation.findAttributeValue("value"); if (!(value instanceof GrReferenceExpression)) return null; if ("class".equals(((GrReferenceExpression)value).getReferenceName())) value = ((GrReferenceExpression)value).getQualifier(); if (!(value instanceof GrReferenceExpression)) return null; final PsiElement resolved = ((GrReferenceExpression)value).resolve(); if (!(resolved instanceof PsiClass)) return null; String className = ((PsiClass)resolved).getQualifiedName(); if (className == null) className = ((PsiClass)resolved).getName(); if (className == null) return null; return JavaPsiFacade.getElementFactory(aClass.getProject()).createTypeByFQClassName(className, resolved.getResolveScope()); } }); } }); }
@Nullable private static PsiType inferTypePreventingRecursion(final GrExpression expression) { return RecursionManager.doPreventingRecursion(expression, false, new Computable<PsiType>() { @Override public PsiType compute() { return expression.getType(); } }); }
@Override @Nullable public <T extends SemElement> List<T> getSemElements(final SemKey<T> key, @NotNull final PsiElement psi) { List<T> cached = _getCachedSemElements(key, true, psi); if (cached != null) { return cached; } RecursionGuard.StackStamp stamp = RecursionManager.createGuard("semService").markStack(); LinkedHashSet<T> result = new LinkedHashSet<T>(); final Map<SemKey, List<SemElement>> map = new THashMap<SemKey, List<SemElement>>(); for (final SemKey each : myInheritors.get(key)) { List<SemElement> list = createSemElements(each, psi); map.put(each, list); result.addAll((List<T>)list); } if (stamp.mayCacheNow()) { final SemCacheChunk persistent = getOrCreateChunk(psi); for (SemKey semKey : map.keySet()) { persistent.putSemElements(semKey, map.get(semKey)); } } return new ArrayList<T>(result); }
public Result<PsiElement[]> compute() { PsiElement[] result = RecursionManager.doPreventingRecursion(myXincludeTag, true, new NullableComputable<PsiElement[]>() { @Override public PsiElement[] compute() { return computeInclusion(myXincludeTag); } }); return Result.create(result == null ? PsiElement.EMPTY_ARRAY : result, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); }
@NotNull public static Collection<PsiMethod> runContributorsForMethods(@NotNull final GrTypeDefinition clazz) { Collection<PsiMethod> result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Collection<PsiMethod>>() { @Override public Collection<PsiMethod> compute() { Collection<PsiMethod> collector = new ArrayList<PsiMethod>(); for (final AstTransformContributor contributor : EP_NAME.getExtensions()) { contributor.collectMethods(clazz, collector); } return collector; } }); return result == null ? Collections.<PsiMethod>emptyList() : result; }
@NotNull public static List<GrField> runContributorsForFields(@NotNull final GrTypeDefinition clazz) { List<GrField> fields = RecursionManager.doPreventingRecursion(clazz, true, new Computable<List<GrField>>() { @Override public List<GrField> compute() { List<GrField> collector = new ArrayList<GrField>(); for (final AstTransformContributor contributor : EP_NAME.getExtensions()) { contributor.collectFields(clazz, collector); } return collector; } }); return fields != null ? fields : Collections.<GrField>emptyList(); }
@Nullable private static List<PsiClassType> getImplementsFromDelegate(@NotNull final GrTypeDefinition grType, final Set<PsiClass> visited) { return RecursionManager.doPreventingRecursion(grType, true, new Computable<List<PsiClassType>>() { @Override public List<PsiClassType> compute() { List<PsiClassType> result = new ArrayList<PsiClassType>(); final GrField[] fields = grType.getCodeFields(); for (GrField field : fields) { final PsiAnnotation delegate = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE); if (delegate == null) continue; final boolean shouldImplement = shouldImplementDelegatedInterfaces(delegate); if (!shouldImplement) continue; final PsiType type = field.getDeclaredType(); if (!(type instanceof PsiClassType)) continue; final PsiClass psiClass = ((PsiClassType)type).resolve(); if (psiClass == null) continue; if (psiClass instanceof GrTypeDefinition) { getImplementListsInner((GrTypeDefinition)psiClass, result, visited); } else { result.addAll(Arrays.asList(psiClass.getImplementsListTypes())); } if (psiClass.isInterface()) { result.add((PsiClassType)type); } } return result; } }); }
@Nullable public static PsiClassType getCategoryType(@NotNull final PsiClass categoryAnnotationOwner) { CachedValuesManager cachedValuesManager = CachedValuesManager.getManager(categoryAnnotationOwner.getProject()); return cachedValuesManager.getCachedValue(categoryAnnotationOwner, new CachedValueProvider<PsiClassType>() { @Override public Result<PsiClassType> compute() { return Result.create(inferCategoryType(categoryAnnotationOwner), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } @Nullable private PsiClassType inferCategoryType(final PsiClass aClass) { return RecursionManager.doPreventingRecursion(aClass, true, new NullableComputable<PsiClassType>() { @Nullable @Override public PsiClassType compute() { final PsiModifierList modifierList = aClass.getModifierList(); if (modifierList == null) return null; final PsiAnnotation annotation = modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_LANG_CATEGORY); if (annotation == null) return null; PsiAnnotationMemberValue value = annotation.findAttributeValue("value"); if (!(value instanceof GrReferenceExpression)) return null; if ("class".equals(((GrReferenceExpression)value).getReferenceName())) value = ((GrReferenceExpression)value).getQualifier(); if (!(value instanceof GrReferenceExpression)) return null; final PsiElement resolved = ((GrReferenceExpression)value).resolve(); if (!(resolved instanceof PsiClass)) return null; String className = ((PsiClass)resolved).getQualifiedName(); if (className == null) className = ((PsiClass)resolved).getName(); if (className == null) return null; return JavaPsiFacade.getElementFactory(aClass.getProject()).createTypeByFQClassName(className, resolved.getResolveScope()); } }); } }); }
@NotNull @RequiredReadAction public DotNetTypeRef toTypeRefForInference() { // recursion when child lambda reference to parameter from parent lambda DotNetTypeRef returnType = RecursionManager.doPreventingRecursion("C# lambda return type", false, this::findPossibleReturnTypeRef); if(returnType == null) { returnType = DotNetTypeRef.ERROR_TYPE; } return new CSharpLambdaTypeRef(this, null, getParameterInfos(true), returnType); }
@Override @Nullable public ObjectStubTree readOrBuild(Project project, final VirtualFile vFile, @Nullable PsiFile psiFile) { final ObjectStubTree fromIndices = readFromVFile(project, vFile); if (fromIndices != null) { return fromIndices; } try { byte[] content = vFile.contentsToByteArray(); vFile.setPreloadedContentHint(content); final FileContent fc; try { fc = new FileContentImpl(vFile, content); fc.putUserData(IndexingDataKeys.PROJECT, project); if (psiFile != null && !vFile.getFileType().isBinary()) { fc.putUserData(IndexingDataKeys.FILE_TEXT_CONTENT_KEY, psiFile.getViewProvider().getContents()); // but don't reuse psiFile itself to avoid loading its contents. If we load AST, the stub will be thrown out anyway. } Stub element = RecursionManager.doPreventingRecursion(vFile, false, () -> StubTreeBuilder.buildStubTree(fc)); if (element instanceof PsiFileStub) { StubTree tree = new StubTree((PsiFileStub)element); tree.setDebugInfo("created from file content"); return tree; } } finally { vFile.setPreloadedContentHint(null); } } catch (IOException e) { LOG.info(e); // content can be not cached yet, and the file can be deleted on disk already, without refresh } return null; }
@Override @Nullable public <T extends SemElement> List<T> getSemElements(final SemKey<T> key, @Nonnull final PsiElement psi) { List<T> cached = _getCachedSemElements(key, true, psi); if (cached != null) { return cached; } ensureInitialized(); RecursionGuard.StackStamp stamp = RecursionManager.createGuard("semService").markStack(); LinkedHashSet<T> result = new LinkedHashSet<>(); final Map<SemKey, List<SemElement>> map = new THashMap<>(); for (final SemKey each : key.getInheritors()) { List<SemElement> list = createSemElements(each, psi); map.put(each, list); result.addAll((List<T>)list); } if (stamp.mayCacheNow()) { final SemCacheChunk persistent = getOrCreateChunk(psi); for (SemKey semKey : map.keySet()) { persistent.putSemElements(semKey, map.get(semKey)); } } return new ArrayList<>(result); }
private PsiAnnotation takeAnnotationFromSuperParameters(@NotNull PsiParameter owner, final List<PsiParameter> superOwners) { return RecursionManager.doPreventingRecursion(owner, true, () -> { for(PsiParameter superOwner : superOwners) { PsiAnnotation anno = findNullabilityAnnotationWithDefault(superOwner, false, false); if(anno != null) { return anno; } } return null; }); }
public static boolean inferPurity(@NotNull PsiMethodImpl method) { if(!InferenceFromSourceUtil.shouldInferFromSource(method) || PsiType.VOID.equals(method.getReturnType()) || method.isConstructor()) { return false; } return CachedValuesManager.getCachedValue(method, () -> { MethodData data = ContractInferenceIndexKt.getIndexedData(method); PurityInferenceResult result = data == null ? null : data.getPurity(); Boolean pure = RecursionManager.doPreventingRecursion(method, true, () -> result != null && result.isPure(method, data.methodBody(method))); return CachedValueProvider.Result.create(pure == Boolean.TRUE, method); }); }
private PsiType processLocalVariableInitializer( final PsiExpression psiExpression ) { PsiType result = null; if( null != psiExpression && !(psiExpression instanceof PsiArrayInitializerExpression) ) { if( psiExpression instanceof PsiConditionalExpression ) { result = RecursionManager.doPreventingRecursion( psiExpression, true, () -> { final PsiExpression thenExpression = ((PsiConditionalExpression)psiExpression).getThenExpression(); final PsiExpression elseExpression = ((PsiConditionalExpression)psiExpression).getElseExpression(); final PsiType thenType = null != thenExpression ? thenExpression.getType() : null; final PsiType elseType = null != elseExpression ? elseExpression.getType() : null; if( thenType == null ) { return elseType; } if( elseType == null ) { return thenType; } if( TypeConversionUtil.isAssignable( thenType, elseType, false ) ) { return thenType; } if( TypeConversionUtil.isAssignable( elseType, thenType, false ) ) { return elseType; } return thenType; } ); } else { result = RecursionManager.doPreventingRecursion( psiExpression, true, psiExpression::getType ); } if( psiExpression instanceof PsiNewExpression ) { final PsiJavaCodeReferenceElement reference = ((PsiNewExpression)psiExpression).getClassOrAnonymousClassReference(); if( reference != null ) { final PsiReferenceParameterList parameterList = reference.getParameterList(); if( parameterList != null ) { final PsiTypeElement[] elements = parameterList.getTypeParameterElements(); if( elements.length == 1 && elements[0].getType() instanceof PsiDiamondType ) { result = TypeConversionUtil.erasure( result ); } } } } } return result; }
private static PsiClassType getTupleType(final GrExpression[] initializers, GrListOrMap listOrMap) { final JavaPsiFacade facade = JavaPsiFacade.getInstance(listOrMap.getProject()); GlobalSearchScope scope = listOrMap.getResolveScope(); if (initializers.length == 0) { PsiType lType = PsiImplUtil.inferExpectedTypeForDiamond(listOrMap); if (lType instanceof PsiClassType && InheritanceUtil.isInheritor(lType, CommonClassNames.JAVA_UTIL_LIST)) { PsiClass arrayList = facade.findClass(CommonClassNames.JAVA_UTIL_ARRAY_LIST, scope); if (arrayList == null) arrayList = facade.findClass(CommonClassNames.JAVA_UTIL_LIST, scope); if (arrayList != null) { PsiSubstitutor arrayListSubstitutor = PsiSubstitutor.EMPTY. put(arrayList.getTypeParameters()[0], com.intellij.psi.util.PsiUtil.substituteTypeParameter(lType, CommonClassNames.JAVA_UTIL_LIST, 0, false)); return facade.getElementFactory().createType(arrayList, arrayListSubstitutor); } } } return new GrTupleType(scope, facade) { @NotNull @Override protected PsiType[] inferComponents() { return ContainerUtil.map(initializers, new Function<GrExpression, PsiType>() { @Override public PsiType fun(final GrExpression expression) { return RecursionManager.doPreventingRecursion(expression, false, new Computable<PsiType>() { @Override public PsiType compute() { return expression.getType(); } }); } }, new PsiType[initializers.length]); } @Override public boolean isValid() { for (GrExpression initializer : initializers) { if (!initializer.isValid()) return false; } return true; } }; }
@NotNull @RequiredReadAction public static GenericInferenceResult inferenceGenericExtractor(@NotNull CSharpCallArgument[] callArguments, @NotNull DotNetTypeRef[] typeArgumentListRefs, @NotNull PsiElement scope, @NotNull DotNetLikeMethodDeclaration methodDeclaration) { DotNetGenericParameter[] genericParameters = methodDeclaration.getGenericParameters(); if(genericParameters.length == 0 || typeArgumentListRefs.length > 0) { DotNetGenericExtractor extractor = genericParameters.length != typeArgumentListRefs.length ? DotNetGenericExtractor.EMPTY : CSharpGenericExtractor.create(genericParameters, typeArgumentListRefs); return new GenericInferenceResult(genericParameters.length == typeArgumentListRefs.length, extractor); } List<NCallArgument> methodCallArguments = RecursionManager.doPreventingRecursion(methodDeclaration, false, () -> MethodResolver.buildCallArguments(callArguments, methodDeclaration, scope)); if(ContainerUtil.isEmpty(methodCallArguments)) { return new GenericInferenceResult(true, DotNetGenericExtractor.EMPTY); } final Map<DotNetGenericParameter, DotNetTypeRef> map = new THashMap<>(); for(NCallArgument nCallArgument : methodCallArguments) { ProgressManager.checkCanceled(); DotNetTypeRef parameterTypeRef = nCallArgument.getParameterTypeRef(); if(parameterTypeRef == null) { continue; } DotNetTypeRef expressionTypeRef = unwrapPossibleGenericTypeRefs(nCallArgument, parameterTypeRef, map, scope); if(expressionTypeRef instanceof CSharpFastImplicitTypeRef) { DotNetTypeRef mirror = ((CSharpFastImplicitTypeRef) expressionTypeRef).doMirror(parameterTypeRef, scope); if(mirror != null) { expressionTypeRef = mirror; } } DotNetTypeResolveResult parameterTypeResolveResult = parameterTypeRef.resolve(); DotNetTypeResolveResult expressionTypeResolveResult = expressionTypeRef.resolve(); if(parameterTypeResolveResult instanceof CSharpLambdaResolveResult && expressionTypeResolveResult instanceof CSharpLambdaResolveResult) { CSharpLambdaResolveResult pLambdaResolveResult = (CSharpLambdaResolveResult) parameterTypeResolveResult; CSharpLambdaResolveResult eLambdaResolveResult = (CSharpLambdaResolveResult) expressionTypeResolveResult; DotNetTypeRef[] pParameterTypeRefs = pLambdaResolveResult.getParameterTypeRefs(); DotNetTypeRef[] eParameterTypeRefs = eLambdaResolveResult.getParameterTypeRefs(); if(pParameterTypeRefs.length == eParameterTypeRefs.length) { for(int i = 0; i < eParameterTypeRefs.length; i++) { DotNetTypeRef pParameterTypeRef = pParameterTypeRefs[i]; DotNetTypeRef eParameterTypeRef = eParameterTypeRefs[i]; inferenceGenericFromExpressionTypeRefAndParameterTypeRef(genericParameters, map, pParameterTypeRef, eParameterTypeRef, scope); } } inferenceGenericFromExpressionTypeRefAndParameterTypeRef(genericParameters, map, pLambdaResolveResult.getReturnTypeRef(), eLambdaResolveResult.getReturnTypeRef(), scope); } if(parameterTypeResolveResult instanceof CSharpArrayTypeRef.ArrayResolveResult && expressionTypeResolveResult instanceof CSharpArrayTypeRef.ArrayResolveResult) { DotNetTypeRef pTypeRef = ((CSharpArrayTypeRef.ArrayResolveResult) parameterTypeResolveResult).getInnerTypeRef(); DotNetTypeRef eTypeRef = ((CSharpArrayTypeRef.ArrayResolveResult) expressionTypeResolveResult).getInnerTypeRef(); inferenceGenericFromExpressionTypeRefAndParameterTypeRef(genericParameters, map, pTypeRef, eTypeRef, scope); } inferenceGenericFromExpressionTypeRefAndParameterTypeRef(genericParameters, map, parameterTypeRef, expressionTypeRef, scope); } return new GenericInferenceResult(genericParameters.length == map.size(), CSharpGenericExtractor.create(map)); }
private PsiType processLocalVariableInitializer(final PsiExpression psiExpression) { PsiType result = null; if (null != psiExpression && !(psiExpression instanceof PsiArrayInitializerExpression)) { if (psiExpression instanceof PsiConditionalExpression) { result = RecursionManager.doPreventingRecursion(psiExpression, true, new Computable<PsiType>() { @Override public PsiType compute() { final PsiExpression thenExpression = ((PsiConditionalExpression) psiExpression).getThenExpression(); final PsiExpression elseExpression = ((PsiConditionalExpression) psiExpression).getElseExpression(); final PsiType thenType = null != thenExpression ? thenExpression.getType() : null; final PsiType elseType = null != elseExpression ? elseExpression.getType() : null; if (thenType == null) { return elseType; } if (elseType == null) { return thenType; } if (TypeConversionUtil.isAssignable(thenType, elseType, false)) { return thenType; } if (TypeConversionUtil.isAssignable(elseType, thenType, false)) { return elseType; } return thenType; } }); } else { result = RecursionManager.doPreventingRecursion(psiExpression, true, new Computable<PsiType>() { @Override public PsiType compute() { return psiExpression.getType(); } }); } if (psiExpression instanceof PsiNewExpression) { final PsiJavaCodeReferenceElement reference = ((PsiNewExpression) psiExpression).getClassOrAnonymousClassReference(); if (reference != null) { final PsiReferenceParameterList parameterList = reference.getParameterList(); if (parameterList != null) { final PsiTypeElement[] elements = parameterList.getTypeParameterElements(); if (elements.length == 1 && elements[0].getType() instanceof PsiDiamondType) { result = TypeConversionUtil.erasure(result); } } } } } return result; }
@Nullable protected TypeDescriptor findTypeDescriptorImpl(XmlTag rootTag, final String name, String namespace) { return RecursionManager.createGuard("findDescriptor").doPreventingRecursion(rootTag, true, () -> { XmlNSDescriptorImpl responsibleDescriptor = this; if(namespace != null && namespace.length() != 0 && !namespace.equals(getDefaultNamespace())) { final XmlNSDescriptor nsDescriptor = rootTag.getNSDescriptor(namespace, true); if(nsDescriptor instanceof XmlNSDescriptorImpl) { responsibleDescriptor = (XmlNSDescriptorImpl) nsDescriptor; } } if(responsibleDescriptor != this) { return responsibleDescriptor.findTypeDescriptor(XmlUtil.findLocalNameByQualifiedName(name)); } if(rootTag == null) { return null; } final Pair<QNameKey, XmlTag> pair = Pair.create(new QNameKey(name, namespace), rootTag); final CachedValue<TypeDescriptor> descriptor = myTypesMap.get(pair); if(descriptor != null) { TypeDescriptor value = descriptor.getValue(); if(value == null || (value instanceof ComplexTypeDescriptor && ((ComplexTypeDescriptor) value).getDeclaration().isValid())) { return value; } } XmlTag[] tags = rootTag.getSubTags(); return doFindIn(tags, name, namespace, pair, rootTag); }); }