@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; }
@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()); } }); }
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; }
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; }