use of com.intellij.patterns.PsiMethodPattern in project intellij-community by JetBrains.
the class IconsReferencesContributor method registerReferenceProviders.
@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
final PsiJavaElementPattern.Capture<PsiLiteralExpression> presentationAnno = literalExpression().annotationParam("com.intellij.ide.presentation.Presentation", "icon");
registrar.registerReferenceProvider(presentationAnno, new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) {
if (!PsiUtil.isPluginProject(element.getProject()))
return PsiReference.EMPTY_ARRAY;
return new PsiReference[] { new PsiReferenceBase<PsiElement>(element, true) {
@Override
public PsiElement resolve() {
String value = (String) ((PsiLiteralExpression) element).getValue();
if (value != null) {
List<String> path = StringUtil.split(value, ".");
if (path.size() > 1 && path.get(0).endsWith("Icons")) {
Project project = element.getProject();
PsiClass cur = findIconClass(project, path.get(0));
if (cur == null) {
return null;
}
for (int i = 1; i < path.size() - 1; i++) {
cur = cur.findInnerClassByName(path.get(i), false);
if (cur == null) {
return null;
}
}
return cur.findFieldByName(path.get(path.size() - 1), false);
}
}
return null;
}
@Override
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
PsiElement field = resolve();
if (field instanceof PsiField) {
String fqn = ((PsiField) field).getContainingClass().getQualifiedName();
if (fqn.startsWith("com.intellij.icons.")) {
return replace(newElementName, fqn, "com.intellij.icons.", element);
}
if (fqn.startsWith("icons.")) {
return replace(newElementName, fqn, "icons.", element);
}
}
return super.handleElementRename(newElementName);
}
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (element instanceof PsiField) {
String fqn = ((PsiField) element).getContainingClass().getQualifiedName();
String newElementName = ((PsiField) element).getName();
if (fqn.startsWith("com.intellij.icons.")) {
return replace(newElementName, fqn, "com.intellij.icons.", getElement());
}
if (fqn.startsWith("icons.")) {
return replace(newElementName, fqn, "icons.", getElement());
}
}
return super.bindToElement(element);
}
private PsiElement replace(String newElementName, String fqn, String pckg, PsiElement container) {
String newValue = "\"" + fqn.substring(pckg.length()) + "." + newElementName + "\"";
return getElement().replace(JavaPsiFacade.getElementFactory(container.getProject()).createExpressionFromText(newValue, container.getParent()));
}
@NotNull
@Override
public Object[] getVariants() {
return EMPTY_ARRAY;
}
} };
}
});
final PsiMethodPattern method = psiMethod().withName("findIcon", "getIcon").definedInClass(IconLoader.class.getName());
final PsiJavaElementPattern.Capture<PsiLiteralExpression> findGetIconPattern = literalExpression().and(psiExpression().methodCallParameter(0, method));
registrar.registerReferenceProvider(findGetIconPattern, new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) {
if (!PsiUtil.isIdeaProject(element.getProject()))
return PsiReference.EMPTY_ARRAY;
return new FileReferenceSet(element) {
@Override
protected Collection<PsiFileSystemItem> getExtraContexts() {
final Module icons = ModuleManager.getInstance(element.getProject()).findModuleByName("icons");
if (icons != null) {
final ArrayList<PsiFileSystemItem> result = new ArrayList<>();
final VirtualFile[] roots = ModuleRootManager.getInstance(icons).getSourceRoots();
final PsiManager psiManager = element.getManager();
for (VirtualFile root : roots) {
final PsiDirectory directory = psiManager.findDirectory(root);
if (directory != null) {
result.add(directory);
}
}
return result;
}
return super.getExtraContexts();
}
}.getAllReferences();
}
});
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withLocalName("icon"), new PsiReferenceProvider() {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) {
if (!PsiUtil.isPluginProject(element.getProject()) || !DescriptorUtil.isPluginXml(element.getContainingFile())) {
return PsiReference.EMPTY_ARRAY;
}
return new PsiReference[] { new PsiReferenceBase<PsiElement>(element, true) {
@Override
public PsiElement resolve() {
String value = ((XmlAttributeValue) element).getValue();
if (value.startsWith("/")) {
FileReference lastRef = new FileReferenceSet(element).getLastReference();
return lastRef != null ? lastRef.resolve() : null;
}
List<String> path = StringUtil.split(value, ".");
if (path.size() > 1 && path.get(0).endsWith("Icons")) {
Project project = element.getProject();
PsiClass cur = findIconClass(project, path.get(0));
if (cur == null)
return null;
for (int i = 1; i < path.size() - 1; i++) {
cur = cur.findInnerClassByName(path.get(i), false);
if (cur == null)
return null;
}
return cur.findFieldByName(path.get(path.size() - 1), false);
}
return null;
}
@Override
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
PsiElement element = resolve();
if (element instanceof PsiFile) {
FileReference lastRef = new FileReferenceSet(element).getLastReference();
return lastRef.handleElementRename(newElementName);
}
if (element instanceof PsiField) {
String fqn = ((PsiField) element).getContainingClass().getQualifiedName();
if (fqn.startsWith("com.intellij.icons.")) {
return replace(fqn, newElementName, "com.intellij.icons.");
}
if (fqn.startsWith("icons.")) {
return replace(fqn, newElementName, "icons.");
}
}
return super.handleElementRename(newElementName);
}
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (element instanceof PsiFile) {
FileReference lastRef = new FileReferenceSet(element).getLastReference();
return lastRef.bindToElement(element);
}
if (element instanceof PsiField) {
String fqn = ((PsiField) element).getContainingClass().getQualifiedName();
String newName = ((PsiField) element).getName();
if (fqn.startsWith("com.intellij.icons.")) {
return replace(fqn, newName, "com.intellij.icons.");
}
if (fqn.startsWith("icons.")) {
return replace(fqn, newName, "icons.");
}
}
return super.bindToElement(element);
}
private PsiElement replace(String fqn, String newName, String pckg) {
XmlAttribute parent = (XmlAttribute) getElement().getParent();
parent.setValue(fqn.substring(pckg.length()) + "." + newName);
return parent.getValueElement();
}
@NotNull
@Override
public Object[] getVariants() {
return EMPTY_ARRAY;
}
} };
}
});
}
Aggregations