module_context_providers

This commit is contained in:
Serega Vasiliev
2013-01-28 13:52:50 +01:00
parent f610ca8369
commit 010285e0c5
18 changed files with 166 additions and 83 deletions
@@ -23,6 +23,8 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.*;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -45,11 +47,15 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
@NotNull
public PsiReference[] getReferencesByElement(PsiElement element, String text, int offset, final boolean soft) {
return getReferencesByElement(element, text, offset, soft, null);
return getReferencesByElement(element, text, offset, soft, Module.EMPTY_ARRAY);
}
@NotNull
public PsiReference[] getReferencesByElement(PsiElement element, String text, int offset, final boolean soft, final @Nullable Module forModule) {
public PsiReference[] getReferencesByElement(PsiElement element,
String text,
int offset,
final boolean soft,
final @NotNull Module... forModules) {
return new FileReferenceSet(text, element, offset, this, true, myEndingSlashNotAllowed) {
@@ -75,9 +81,17 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
}
@Override
@NotNull public Collection<PsiFileSystemItem> computeDefaultContexts() {
final Module module = forModule == null ? ModuleUtil.findModuleForPsiElement(getElement()) : forModule;
return getRoots(module, true);
@NotNull
public Collection<PsiFileSystemItem> computeDefaultContexts() {
Set<PsiFileSystemItem> systemItems = new HashSet<PsiFileSystemItem>();
if (forModules.length > 0) {
for (Module forModule : forModules) {
systemItems.addAll(getRoots(forModule, true));
}
} else {
systemItems.addAll(getRoots(ModuleUtil.findModuleForPsiElement(getElement()), true));
}
return systemItems;
}
@Override
@@ -95,7 +109,6 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
};
}
}.getAllReferences();
}
@Override
@@ -162,5 +175,4 @@ public class FilePathReferenceProvider extends PsiReferenceProvider {
}
return result;
}
}
@@ -86,7 +86,7 @@ public class JvmPsiTypeConverterImpl extends JvmPsiTypeConverter implements Cust
if (Arrays.binarySearch(CanonicalPsiTypeConverterImpl.PRIMITIVES, s) >= 0) {
return JavaPsiFacade.getInstance(context.getProject()).getElementFactory().createPrimitiveType(s);
}
final PsiClass aClass1 = DomJavaUtil.findClass(s, context.getFile(), context.getModule(), null);
final PsiClass aClass1 = DomJavaUtil.findClass(s, context.getFile(), context.getModule(), context.getSearchScope());
return aClass1 == null ? null : createType(aClass1);
}
@@ -43,7 +43,7 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe
public static PsiClass findClass(String s, ConvertContext context) {
final DomElement element = context.getInvocationElement();
final GlobalSearchScope scope = element instanceof GenericDomValue ? getSearchScope(context) : null;
final GlobalSearchScope scope = element instanceof GenericDomValue ? context.getSearchScope() : null;
return DomJavaUtil.findClass(s, context.getFile(), context.getModule(), scope);
}
@@ -64,7 +64,8 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe
return provider.getReferencesByElement(element);
}
protected JavaClassReferenceProvider createClassReferenceProvider(final GenericDomValue<PsiClass> genericDomValue, final ConvertContext context,
protected JavaClassReferenceProvider createClassReferenceProvider(final GenericDomValue<PsiClass> genericDomValue,
final ConvertContext context,
ExtendClass extendClass) {
return createJavaClassReferenceProvider(genericDomValue, extendClass, new JavaClassReferenceProvider() {
@@ -99,7 +100,6 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe
provider.setOption(JavaClassReferenceProvider.JVM_FORMAT, Boolean.TRUE);
}
provider.setAllowEmpty(extendClass.allowEmpty());
}
ClassTemplate template = genericDomValue.getAnnotation(ClassTemplate.class);
@@ -114,22 +114,9 @@ public class PsiClassConverter extends Converter<PsiClass> implements CustomRefe
return provider;
}
public static GlobalSearchScope getSearchScope(@NotNull ConvertContext context) {
final Module module = context.getModule();
if (module == null) return null;
PsiFile file = context.getFile();
file = file.getOriginalFile();
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) return null;
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex();
boolean tests = fileIndex.isInTestSourceContent(virtualFile);
return module.getModuleRuntimeScope(tests);
}
@Nullable
protected GlobalSearchScope getScope(@NotNull ConvertContext context) {
return getSearchScope(context);
protected GlobalSearchScope getScope(@NotNull ConvertContext context) {
return context.getSearchScope();
}
public static class AnnotationType extends PsiClassConverter {
@@ -84,7 +84,9 @@ public abstract class PathReferenceManager {
@Nullable
public abstract PathReference getPathReference(@NotNull String path, @NotNull Module module, @NotNull PsiElement element, PathReferenceProvider... additionalProviders);
public abstract PathReference getPathReference(@NotNull String path,
@NotNull PsiElement element,
PathReferenceProvider... additionalProviders);
@Nullable
public abstract PathReference getCustomPathReference(@NotNull String path, @NotNull Module module, @NotNull PsiElement element, PathReferenceProvider... providers);
@@ -43,7 +43,9 @@ public class PathReferenceManagerImpl extends PathReferenceManager {
@Override
@Nullable
public PathReference getPathReference(@NotNull String path, @NotNull final Module module, @NotNull PsiElement element, PathReferenceProvider... additionalProviders) {
public PathReference getPathReference(@NotNull String path,
@NotNull PsiElement element,
PathReferenceProvider... additionalProviders) {
PathReference pathReference;
for (PathReferenceProvider provider : getProviders()) {
pathReference = provider.getPathReference(path, element);
+1 -1
View File
@@ -9,7 +9,7 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="dom-openapi" exported="" />
<orderEntry type="library" name="asm" level="project" />
<orderEntry type="library" name="CGLIB" level="project" />
<orderEntry type="library" exported="" name="CGLIB" level="project" />
<orderEntry type="library" name="Xerces" level="project" />
<orderEntry type="module" module-name="xml" />
<orderEntry type="module" module-name="util" />
+2
View File
@@ -17,6 +17,8 @@
<extensionPoint name="dom.uiControlsProvider"
interface="com.intellij.util.Consumer"/>
<extensionPoint name="moduleContextProvider" interface="com.intellij.util.xml.ModuleContextProvider"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
@@ -27,7 +27,7 @@ import com.intellij.psi.xml.XmlElement;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.*;
import com.intellij.util.xml.impl.ConvertContextImpl;
import com.intellij.util.xml.impl.ConvertContextFactory;
import com.intellij.util.xml.impl.DomManagerImpl;
import com.intellij.util.xml.reflect.DomCollectionChildDescription;
import org.jetbrains.annotations.NotNull;
@@ -122,7 +122,7 @@ public class DomElementAnnotationHolderImpl extends SmartList<DomElementProblemD
if (converter instanceof ResolvingConverter) {
final ResolvingConverter resolvingConverter = (ResolvingConverter)converter;
ContainerUtil
.addAll(result, resolvingConverter.getQuickFixes(new ConvertContextImpl(DomManagerImpl.getDomInvocationHandler(element))));
.addAll(result, resolvingConverter.getQuickFixes(ConvertContextFactory.createConvertContext(DomManagerImpl.getDomInvocationHandler(element))));
}
if (reference instanceof LocalQuickFixProvider) {
final LocalQuickFix[] localQuickFixes = ((LocalQuickFixProvider)reference).getQuickFixes();
@@ -132,7 +132,7 @@ public class DomHighlightingHelperImpl extends DomHighlightingHelper {
hasBadResolve(domReference = new GenericDomValueReference(element)))) {
hasBadResolve = true;
final String errorMessage = converter
.getErrorMessage(element.getStringValue(), new ConvertContextImpl(DomManagerImpl.getDomInvocationHandler(element)));
.getErrorMessage(element.getStringValue(), ConvertContextFactory.createConvertContext(DomManagerImpl.getDomInvocationHandler(element)));
if (errorMessage != null && XmlHighlightVisitor.getErrorDescription(domReference) != null) {
list.add(holder.createResolveProblem(element, domReference));
}
@@ -140,7 +140,7 @@ public class DomHighlightingHelperImpl extends DomHighlightingHelper {
}
if (!hasBadResolve && psiReferences.length == 0 && element.getValue() == null && !PsiTreeUtil.hasErrorElements(valueElement)) {
final String errorMessage = converter
.getErrorMessage(element.getStringValue(), new ConvertContextImpl(DomManagerImpl.getDomInvocationHandler(element)));
.getErrorMessage(element.getStringValue(), ConvertContextFactory.createConvertContext(DomManagerImpl.getDomInvocationHandler(element)));
if (errorMessage != null) {
list.add(holder.createProblem(element, errorMessage));
}
@@ -0,0 +1,14 @@
package com.intellij.util.xml.impl;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomElement;
public class ConvertContextFactory {
public static ConvertContext createConvertContext(final DomElement element) {
return createConvertContext(DomManagerImpl.getDomInvocationHandler(element));
}
public static ConvertContext createConvertContext(final DomInvocationHandler element) {
return new ConvertContextImpl(element);
}
}
@@ -143,12 +143,12 @@ public class GenericDomValueReference<T> extends PsiReferenceBase<XmlElement> im
}
public String getUnresolvedMessagePattern() {
final ConvertContextImpl context = getConvertContext();
final ConvertContext context = getConvertContext();
return getConverter().getErrorMessage(getStringValue(), context);
}
public final ConvertContextImpl getConvertContext() {
return new ConvertContextImpl(DomManagerImpl.getDomInvocationHandler(myGenericValue));
public final ConvertContext getConvertContext() {
return ConvertContextFactory.createConvertContext(DomManagerImpl.getDomInvocationHandler(myGenericValue));
}
public PsiElement handleElementRename(final String newElementName) throws IncorrectOperationException {
@@ -89,17 +89,8 @@ public class GenericValueReferenceProvider extends PsiReferenceProvider {
return references;
}
private static AbstractConvertContext createConvertContext(final PsiElement psiElement, final GenericDomValue domValue) {
return new AbstractConvertContext() {
@NotNull
public DomElement getInvocationElement() {
return domValue;
}
public PsiManager getPsiManager() {
return psiElement.getManager();
}
};
private static ConvertContext createConvertContext(final PsiElement psiElement, final GenericDomValue domValue) {
return ConvertContextFactory.createConvertContext(domValue);
}
@Nullable
@@ -108,7 +99,7 @@ public class GenericValueReferenceProvider extends PsiReferenceProvider {
}
private PsiReference[] createReferences(final GenericDomValue domValue, final XmlElement psiElement, final Object converter) {
AbstractConvertContext context = createConvertContext(psiElement, domValue);
ConvertContext context = createConvertContext(psiElement, domValue);
List<PsiReference> result = new ArrayList<PsiReference>();
String unresolvedText = ElementManipulators.getValueText(psiElement);
@@ -9,10 +9,7 @@ import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.Converter;
import com.intellij.util.xml.DomReferenceInjector;
import com.intellij.util.xml.DomUtil;
import com.intellij.util.xml.SubTag;
import com.intellij.util.xml.*;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -81,7 +78,7 @@ public class GetInvocation implements Invocation {
}
String tagValue = handler.getValue();
ConvertContextImpl context = new ConvertContextImpl(handler);
ConvertContext context = ConvertContextFactory.createConvertContext(handler);
for (DomReferenceInjector each : DomUtil.getFileElement(handler).getFileDescription().getReferenceInjectors()) {
tagValue = each.resolveString(tagValue, context);
@@ -17,7 +17,12 @@ package com.intellij.util.xml;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
@@ -29,15 +34,6 @@ import org.jetbrains.annotations.Nullable;
*/
public abstract class AbstractConvertContext extends ConvertContext {
public static ConvertContext createConvertContext(final DomElement domElement) {
return new AbstractConvertContext() {
@NotNull
public DomElement getInvocationElement() {
return domElement;
}
};
}
public final XmlTag getTag() {
return getInvocationElement().getXmlTag();
}
@@ -56,7 +52,7 @@ public abstract class AbstractConvertContext extends ConvertContext {
final DomFileElement<DomElement> fileElement = DomUtil.getFileElement(getInvocationElement());
if (fileElement == null) {
final XmlElement xmlElement = getInvocationElement().getXmlElement();
return xmlElement == null? null : ModuleUtil.findModuleForPsiElement(xmlElement);
return xmlElement == null ? null : ModuleUtil.findModuleForPsiElement(xmlElement);
}
return fileElement.getRootElement().getModule();
}
@@ -65,4 +61,66 @@ public abstract class AbstractConvertContext extends ConvertContext {
return getFile().getManager();
}
@Nullable
public GlobalSearchScope getSearchScope() {
GlobalSearchScope scope = null;
Module[] modules = getConvertContextModules(this);
if (modules.length != 0) {
PsiFile file = getFile();
file = file.getOriginalFile();
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile != null) {
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex();
boolean tests = fileIndex.isInTestSourceContent(virtualFile);
for (Module module : modules) {
if (scope == null) {
scope = module.getModuleRuntimeScope(tests);
}
else {
scope.union(module.getModuleRuntimeScope(tests));
}
}
}
}
return scope; // ??? scope == null ? GlobalSearchScope.allScope(getProject()) : scope; ???
}
public static GlobalSearchScope getSearchScope(@NotNull ConvertContext context) {
Module[] modules = getConvertContextModules(context);
if (modules.length == 0) return null;
PsiFile file = context.getFile();
file = file.getOriginalFile();
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) return null;
ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex();
boolean tests = fileIndex.isInTestSourceContent(virtualFile);
GlobalSearchScope scope = null;
for (Module module : modules) {
if (scope == null) {
scope = module.getModuleRuntimeScope(tests);
}
else {
scope.union(module.getModuleRuntimeScope(tests));
}
}
return scope;
}
@NotNull
private static Module[] getConvertContextModules(@NotNull ConvertContext context) {
Module[] modules = ModuleContextProvider.getModules(context.getFile());
if (modules.length > 0) return modules;
final Module module = context.getModule();
if (module != null) return new Module[]{module};
return new Module[0];
}
}
@@ -18,6 +18,7 @@ package com.intellij.util.xml;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
@@ -56,6 +57,9 @@ public abstract class ConvertContext {
@Nullable
public abstract Module getModule();
@Nullable
public abstract GlobalSearchScope getSearchScope();
public abstract PsiManager getPsiManager();
@@ -0,0 +1,33 @@
package com.intellij.util.xml;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public abstract class ModuleContextProvider {
public static final ExtensionPointName<ModuleContextProvider> EP_NAME = ExtensionPointName.create("com.intellij.moduleContextProvider");
@NotNull
public abstract Module[] getContextModules(@NotNull PsiFile context);
public static Module[] getModules(@Nullable PsiFile context) {
if (context == null) return Module.EMPTY_ARRAY;
final Set<Module> modules = new HashSet<Module>();
for (ModuleContextProvider moduleContextProvider : Extensions.getExtensions(EP_NAME)) {
ContainerUtil.addAllNotNull(modules, moduleContextProvider.getContextModules(context));
}
Module module = ModuleUtilCore.findModuleForPsiElement(context);
if (module != null) modules.add(module);
return modules.toArray(new Module[modules.size()]);
}
}
@@ -36,9 +36,8 @@ public class PathReferenceConverter extends Converter<PathReference> implements
public final static Converter<PathReference> INSTANCE = new PathReferenceConverter();
public PathReference fromString(@Nullable final String s, final ConvertContext context) {
Module module = context.getModule();
final XmlElement element = context.getXmlElement();
return s == null || module == null || element == null ? null : PathReferenceManager.getInstance().getPathReference(s, module, element);
return s == null || element == null ? null : PathReferenceManager.getInstance().getPathReference(s, element);
}
public String toString(final PathReference t, final ConvertContext context) {
@@ -112,24 +112,6 @@ public class ComboControl extends BaseModifiableControl<JComboBox, String> {
};
}
public static Factory<Collection<? extends Object>> createVariantsGetter(final GenericDomValue<?> reference) {
return new Factory<Collection<? extends Object>>() {
public Collection<? extends Object> create() {
final Converter converter = reference.getConverter();
if (converter instanceof ResolvingConverter) {
return ((ResolvingConverter)converter).getVariants(new AbstractConvertContext() {
@NotNull
public DomElement getInvocationElement() {
return reference;
}
});
}
return Collections.emptyList();
}
};
}
public static Factory<List<Pair<String, Icon>>> createPresentationFunction(final Factory<Collection<? extends Object>> variantFactory) {
return new Factory<List<Pair<String, Icon>>>() {
public List<Pair<String, Icon>> create() {