/** * @return true, if the element contains a reference to a different class than fullyQualifiedName * but which has the same class name */ public static boolean containsConflictingReference(PsiFile element, String fullyQualifiedName) { final Map<String, Boolean> cachedValue = CachedValuesManager.getManager(element.getProject()) .getCachedValue( element, new CachedValueProvider<Map<String, Boolean>>() { @Nullable @Override public Result<Map<String, Boolean>> compute() { return new Result<Map<String, Boolean>>( Collections.synchronizedMap(new HashMap<String, Boolean>()), PsiModificationTracker.MODIFICATION_COUNT); } }); Boolean conflictingRef = cachedValue.get(fullyQualifiedName); if (conflictingRef != null) { return conflictingRef.booleanValue(); } final ConflictingClassReferenceVisitor visitor = new ConflictingClassReferenceVisitor(fullyQualifiedName); element.accept(visitor); conflictingRef = visitor.isConflictingReferenceFound(); cachedValue.put(fullyQualifiedName, conflictingRef); return conflictingRef.booleanValue(); }
public static GdkMethodHolder getHolderForClass( final PsiClass categoryClass, final boolean isStatic, final GlobalSearchScope scope) { final Project project = categoryClass.getProject(); Key<CachedValue<GdkMethodHolder>> key = isStatic ? CACHED_STATIC : CACHED_NON_STATIC; return CachedValuesManager.getManager(project) .getCachedValue( categoryClass, key, new CachedValueProvider<GdkMethodHolder>() { @Override public Result<GdkMethodHolder> compute() { GdkMethodHolder result = new GdkMethodHolder(categoryClass, isStatic, scope); final ProjectRootManager rootManager = ProjectRootManager.getInstance(project); final VirtualFile vfile = categoryClass.getContainingFile().getVirtualFile(); if (vfile != null && (rootManager.getFileIndex().isInLibraryClasses(vfile) || rootManager.getFileIndex().isInLibrarySource(vfile))) { return Result.create(result, rootManager); } return Result.create( result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, rootManager); } }, false); }
public static boolean hasTest(PsiModifierListOwner element) { return CachedValuesManager.getCachedValue( element, () -> CachedValueProvider.Result.create( hasTest(element, true), PsiModificationTracker.MODIFICATION_COUNT)); }
@Override @Nullable public PsiModifierList getAnnotationList() { if (myAnnotationList == null) { myAnnotationList = CachedValuesManager.getManager(myManager.getProject()) .createCachedValue(new PackageAnnotationValueProvider()); } return myAnnotationList.getValue(); }
@NotNull @Override public GrReflectedMethod[] getReflectedMethods() { return CachedValuesManager.getCachedValue( this, new CachedValueProvider<GrReflectedMethod[]>() { @Override public Result<GrReflectedMethod[]> compute() { return Result.create( GrReflectedMethodImpl.createReflectedMethods(GrMethodBaseImpl.this), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } }); }
@NotNull public static PsiExpression getToplevelExpression( @NotNull final Project project, @NotNull final PsiExpression expression) { if (expression instanceof PsiBinaryExpression || expression.getParent() instanceof PsiBinaryExpression) { // can be large, cache return CachedValuesManager.getManager(project) .getParameterizedCachedValue( expression, TOP_LEVEL_EXPRESSION, TOP_LEVEL_PROVIDER, true, Pair.create(project, expression)); } return getTopLevel(project, expression); }
@NotNull private static ParameterizedCachedValue<MembersMap, PsiClass> getValues( @NotNull PsiClass aClass) { ParameterizedCachedValue<MembersMap, PsiClass> value = aClass.getUserData(MAP_IN_CLASS_KEY); if (value == null) { value = CachedValuesManager.getManager(aClass.getProject()) .createParameterizedCachedValue(ByNameCachedValueProvider.INSTANCE, false); // Do not cache for nonphysical elements if (aClass.isPhysical()) { value = ((UserDataHolderEx) aClass).putUserDataIfAbsent(MAP_IN_CLASS_KEY, value); } } return value; }
private CachedValue<ElementNames> createCachedValue(final PsiFile file) { return CachedValuesManager.getManager(file.getProject()) .createCachedValue( new CachedValueProvider<ElementNames>() { public Result<ElementNames> compute() { final ElementNames names = new ElementNames(); final PsiFile[] associations = myFileAssociationsManager.getAssociationsFor( file, FileAssociationsManager.XML_FILES); if (associations.length == 0) { fillFromSchema(file, names); } else { names.validateNames = true; //noinspection unchecked ContainerUtil.addAll(names.dependencies, associations); } //noinspection unchecked names.dependencies.add(myFileAssociationsManager); for (PsiFile file : associations) { if (!(file instanceof XmlFile)) continue; file.accept( new XmlRecursiveElementVisitor() { @Override public void visitXmlTag(XmlTag tag) { names.elementNames.add(QNameUtil.createQName(tag)); super.visitXmlTag(tag); } @Override public void visitXmlAttribute(XmlAttribute attribute) { if (!attribute.isNamespaceDeclaration()) { names.attributeNames.add(QNameUtil.createQName(attribute)); } super.visitXmlAttribute(attribute); } }); } //noinspection unchecked return new Result<ElementNames>(names, ArrayUtil.toObjectArray(names.dependencies)); } }, false); }
@NotNull public static PsiMethod[] getAllMethods(final GrTypeDefinition grType) { return CachedValuesManager.getCachedValue( grType, new CachedValueProvider<PsiMethod[]>() { @Nullable @Override public Result<PsiMethod[]> compute() { List<PsiMethod> list = ContainerUtil.newArrayList(); getAllMethodsInner(grType, list, new HashSet<PsiClass>()); return Result.create( list.toArray(new PsiMethod[list.size()]), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, grType); } }); }
private static Set<String> collectDevPatternClassNames(@NotNull final Project project) { CachedValue<Set<String>> cachedValue = project.getUserData(PATTERN_CLASSES); if (cachedValue == null) { cachedValue = CachedValuesManager.getManager(project) .createCachedValue( new CachedValueProvider<Set<String>>() { @Nullable @Override public Result<Set<String>> compute() { return Result.create( calcDevPatternClassNames(project), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } }, false); project.putUserData(PATTERN_CLASSES, cachedValue); } return cachedValue.getValue(); }
@NotNull private CachedValue<Collection<PsiDirectory>> createCachedDirectories( final boolean includeLibrarySources) { return CachedValuesManager.getManager(myManager.getProject()) .createCachedValue( new CachedValueProvider<Collection<PsiDirectory>>() { @Override public Result<Collection<PsiDirectory>> compute() { final CommonProcessors.CollectProcessor<PsiDirectory> processor = new CommonProcessors.CollectProcessor<PsiDirectory>(); getFacade() .processPackageDirectories( PsiPackageImpl.this, allScope(), processor, includeLibrarySources); return Result.create( processor.getResults(), PsiPackageImplementationHelper.getInstance() .getDirectoryCachedValueDependencies(PsiPackageImpl.this)); } }, false); }
/** * Returns all annotations for <code>listOwner</code>, possibly walking up the method hierarchy. * * @see com.intellij.codeInsight.AnnotationUtil#isAnnotated(com.intellij.psi.PsiModifierListOwner, * java.lang.String, boolean) */ private static PsiAnnotation[] getAnnotations( @NotNull final PsiModifierListOwner listOwner, final boolean inHierarchy) { final PsiModifierList modifierList = listOwner.getModifierList(); if (modifierList == null) { return PsiAnnotation.EMPTY_ARRAY; } if (!inHierarchy) { return modifierList.getAnnotations(); } return CachedValuesManager.getCachedValue( listOwner, new CachedValueProvider<PsiAnnotation[]>() { @Nullable @Override public Result<PsiAnnotation[]> compute() { return Result.create( getHierarchyAnnotations(listOwner, modifierList), PsiModificationTracker.MODIFICATION_COUNT); } }); }
@NotNull public XmlTag[] getSubTags() { return CachedValuesManager.getManager(getProject()) .getCachedValue( this, new CachedValueProvider<XmlTag[]>() { @Override public Result<XmlTag[]> compute() { final List<XmlTag> result = new ArrayList<XmlTag>(); fillSubTags(result); final int s = result.size(); XmlTag[] tags = s > 0 ? ContainerUtil.toArray(result, new XmlTag[s]) : EMPTY; return Result.create( tags, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, getContainingFile()); } }); }
@NotNull public static HierarchicalMethodSignature getHierarchicalMethodSignature(final PsiMethod method) { return CachedValuesManager.getCachedValue( method, new CachedValueProvider<HierarchicalMethodSignature>() { @Nullable @Override public Result<HierarchicalMethodSignature> compute() { PsiClass aClass = method.getContainingClass(); HierarchicalMethodSignature result = null; if (aClass != null) { result = getSignaturesMap(aClass).get(method.getSignature(PsiSubstitutor.EMPTY)); } if (result == null) { result = new HierarchicalMethodSignatureImpl( (MethodSignatureBackedByPsiMethod) method.getSignature(PsiSubstitutor.EMPTY)); } return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } }); }
@Override protected Collection<PsiDirectory> getAllDirectories() { if (myDirectories == null) { myDirectories = CachedValuesManager.getManager(myManager.getProject()) .createCachedValue( new CachedValueProvider<Collection<PsiDirectory>>() { @Override public Result<Collection<PsiDirectory>> compute() { final CommonProcessors.CollectProcessor<PsiDirectory> processor = new CommonProcessors.CollectProcessor<PsiDirectory>(); getFacade() .processPackageDirectories(PsiPackageImpl.this, allScope(), processor); return Result.create( processor.getResults(), PsiPackageImplementationHelper.getInstance() .getDirectoryCachedValueDependencies(PsiPackageImpl.this)); } }, false); } return myDirectories.getValue(); }
private Map<String, CachedValue<XmlNSDescriptor>> initializeSchema( final String namespace, final String version, final String fileLocation, Map<String, CachedValue<XmlNSDescriptor>> map) { if (map == null) map = new THashMap<String, CachedValue<XmlNSDescriptor>>(); // We put cached value in any case to cause its value update on e.g. mapping change map.put( namespace, CachedValuesManager.getManager(getManager().getProject()) .createCachedValue( new CachedValueProvider<XmlNSDescriptor>() { public Result<XmlNSDescriptor> compute() { XmlNSDescriptor descriptor = getImplicitNamespaceDescriptor(fileLocation); if (descriptor != null) { return new Result<XmlNSDescriptor>( descriptor, ArrayUtil.append(descriptor.getDependences(), XmlTagImpl.this)); } XmlFile currentFile = retrieveFile(fileLocation, version); if (currentFile == null) { final XmlDocument document = XmlUtil.getContainingFile(XmlTagImpl.this).getDocument(); if (document != null) { final String uri = XmlUtil.getDtdUri(document); if (uri != null) { final XmlFile containingFile = XmlUtil.getContainingFile(document); final XmlFile xmlFile = XmlUtil.findNamespace(containingFile, uri); descriptor = xmlFile == null ? null : (XmlNSDescriptor) xmlFile.getDocument().getMetaData(); } // We want to get fixed xmlns attr from dtd and check its default with // requested namespace if (descriptor instanceof XmlNSDescriptorImpl) { final XmlElementDescriptor elementDescriptor = descriptor.getElementDescriptor(XmlTagImpl.this); if (elementDescriptor != null) { final XmlAttributeDescriptor attributeDescriptor = elementDescriptor.getAttributeDescriptor("xmlns", XmlTagImpl.this); if (attributeDescriptor != null && attributeDescriptor.isFixed()) { final String defaultValue = attributeDescriptor.getDefaultValue(); if (defaultValue != null && defaultValue.equals(namespace)) { return new Result<XmlNSDescriptor>( descriptor, descriptor.getDependences(), XmlTagImpl.this, ExternalResourceManager.getInstance()); } } } } } } PsiMetaOwner currentOwner = retrieveOwner(currentFile, namespace); if (currentOwner != null) { descriptor = (XmlNSDescriptor) currentOwner.getMetaData(); if (descriptor != null) { return new Result<XmlNSDescriptor>( descriptor, descriptor.getDependences(), XmlTagImpl.this, ExternalResourceManager.getInstance()); } } return new Result<XmlNSDescriptor>( null, XmlTagImpl.this, currentFile, ExternalResourceManager.getInstance()); } }, false)); return map; }
static PsiSubstitutor infer( @NotNull PsiTypeParameter[] typeParameters, @NotNull PsiParameter[] parameters, @NotNull PsiExpression[] arguments, @NotNull PsiSubstitutor partialSubstitutor, @NotNull final PsiElement parent, @NotNull final ParameterTypeInferencePolicy policy) { if (parent instanceof PsiCall) { final PsiExpressionList argumentList = ((PsiCall) parent).getArgumentList(); final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(argumentList); // overload resolution can't depend on outer call => should not traverse to top if (properties != null && !properties.isApplicabilityCheck() && // in order to to avoid caching of candidates's errors on parent (!) , so check for // overload resolution is left here // But overload resolution can depend on type of lambda parameter. As it can't depend on // lambda body, // traversing down would stop at lambda level and won't take into account overloaded // method !MethodCandidateInfo.ourOverloadGuard.currentStack().contains(argumentList)) { final PsiCall topLevelCall = PsiResolveHelper.ourGraphGuard.doPreventingRecursion( parent, false, new Computable<PsiCall>() { @Override public PsiCall compute() { if (parent instanceof PsiExpression && !PsiPolyExpressionUtil.isPolyExpression((PsiExpression) parent)) { return null; } return LambdaUtil.treeWalkUp(parent); } }); if (topLevelCall != null) { InferenceSession session; if (MethodCandidateInfo.isOverloadCheck() || !PsiDiamondType.ourDiamondGuard.currentStack().isEmpty() || LambdaUtil.isLambdaParameterCheck()) { session = startTopLevelInference(topLevelCall, policy); } else { session = CachedValuesManager.getCachedValue( topLevelCall, new CachedValueProvider<InferenceSession>() { @Nullable @Override public Result<InferenceSession> compute() { return new Result<InferenceSession>( startTopLevelInference(topLevelCall, policy), PsiModificationTracker.MODIFICATION_COUNT); } }); if (session != null) { // reject cached top level session if it was based on wrong candidate: check nested // session if candidate (it's type parameters) are the same // such situations are avoided when overload resolution is performed // (MethodCandidateInfo.isOverloadCheck above) // but situations when client code iterates through // PsiResolveHelper.getReferencedMethodCandidates or similar are impossible to guess final Map<PsiElement, InferenceSession> sessions = session.getInferenceSessionContainer().myNestedSessions; final InferenceSession childSession = sessions.get(parent); if (childSession != null) { for (PsiTypeParameter parameter : typeParameters) { if (!childSession .getInferenceSubstitution() .getSubstitutionMap() .containsKey(parameter)) { session = startTopLevelInference(topLevelCall, policy); break; } } } } } if (session != null) { final PsiSubstitutor childSubstitutor = inferNested( typeParameters, parameters, arguments, partialSubstitutor, (PsiCall) parent, policy, properties, session); if (childSubstitutor != null) return childSubstitutor; } else if (topLevelCall instanceof PsiMethodCallExpression) { return new InferenceSession( typeParameters, partialSubstitutor, parent.getManager(), parent, policy) .prepareSubstitution(); } } } } final InferenceSession inferenceSession = new InferenceSession( typeParameters, partialSubstitutor, parent.getManager(), parent, policy); inferenceSession.initExpressionConstraints(parameters, arguments, parent); return inferenceSession.infer(parameters, arguments, parent); }
private static MultiHostRegistrarImpl probeElementsUp( @NotNull PsiElement element, @NotNull PsiFile hostPsiFile, boolean probeUp) { PsiManager psiManager = hostPsiFile.getManager(); final Project project = psiManager.getProject(); InjectedLanguageManagerImpl injectedManager = InjectedLanguageManagerImpl.getInstanceImpl(project); if (injectedManager == null) { return null; // for tests } MultiHostRegistrarImpl registrar = null; PsiElement current = element; nextParent: while (current != null && current != hostPsiFile) { ProgressManager.checkCanceled(); if ("EL".equals(current.getLanguage().getID())) break; ParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement> data = current.getUserData(INJECTED_PSI); if (data == null) { registrar = InjectedPsiCachedValueProvider.doCompute( current, injectedManager, project, hostPsiFile); } else { registrar = data.getValue(current); } current = current.getParent(); // cache no injection for current if (registrar != null) { List<Pair<Place, PsiFile>> places = registrar.getResult(); // check that injections found intersect with queried element TextRange elementRange = element.getTextRange(); for (Pair<Place, PsiFile> pair : places) { Place place = pair.first; for (PsiLanguageInjectionHost.Shred shred : place) { if (shred.getHost().getTextRange().intersects(elementRange)) { if (place.isValid()) break nextParent; } } } } if (!probeUp) { break; } } if (probeUp) { // cache only if we walked all parents for (PsiElement e = element; e != current && e != null && e != hostPsiFile; e = e.getParent()) { ProgressManager.checkCanceled(); if (registrar == null) { e.putUserData(INJECTED_PSI, null); } else { ParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement> cachedValue = CachedValuesManager.getManager(project) .createParameterizedCachedValue(INJECTED_PSI_PROVIDER, false); CachedValueProvider.Result<MultiHostRegistrarImpl> result = CachedValueProvider.Result.create( registrar, PsiModificationTracker.MODIFICATION_COUNT, registrar); ((PsiParameterizedCachedValue<MultiHostRegistrarImpl, PsiElement>) cachedValue) .setValue(result); e.putUserData(INJECTED_PSI, cachedValue); } } } return registrar; }