package com.intellij.javascript.flex; import com.intellij.lang.javascript.flex.ReferenceSupport; import com.intellij.lang.javascript.psi.impl.JSReferenceSet; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.filters.position.NamespaceFilter; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlTag; import com.intellij.util.ProcessingContext; import com.intellij.xml.util.XmlUtil; import org.jetbrains.annotations.NotNull; import static com.intellij.patterns.XmlPatterns.*; public class FlexConfigXmlReferenceContributor extends PsiReferenceContributor { public static final String CLASS_REFERENCE = "ClassReference"; public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { XmlUtil.registerXmlTagReferenceProvider( registrar, new String[]{"path-element", "class", "classname", "symbol"}, new NamespaceFilter(FlexApplicationComponent.HTTP_WWW_ADOBE_COM_2006_FLEX_CONFIG), true, new PsiReferenceProvider() { @NotNull @Override public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) { TextRange myRange = ElementManipulators.getValueTextRange(element); if (myRange.getStartOffset() == 0) return PsiReference.EMPTY_ARRAY; XmlTag tag = (XmlTag)element; final String trimmed = tag.getValue().getTrimmedText(); if (trimmed.indexOf('{') != -1) return PsiReference.EMPTY_ARRAY; if ("path-element".equals(tag.getLocalName())) { return ReferenceSupport .getFileRefs(element, myRange.getStartOffset(), trimmed, ReferenceSupport.LookupOptions.FLEX_COMPILER_CONFIG_PATH_ELEMENT); } return new FlexConfigXmlReferenceSet(element, trimmed, myRange.getStartOffset()).getReferences(); } }); registrar.registerReferenceProvider( xmlAttributeValue(xmlAttribute("class").withParent(xmlTag().withName("component").withParent(xmlTag().withName("componentPackage")))), new PsiReferenceProvider() { @NotNull public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull final ProcessingContext context) { TextRange myRange = ElementManipulators.getValueTextRange(element); if (myRange.getStartOffset() == 0) return PsiReference.EMPTY_ARRAY; final String attrValue = ((XmlAttributeValue)element).getValue(); return new FlexConfigXmlReferenceSet(element, attrValue, myRange.getStartOffset()).getReferences(); } }); } static class FlexConfigXmlReferenceSet extends JSReferenceSet { public FlexConfigXmlReferenceSet(@NotNull PsiElement element, String text, int offset) { super(element, text, offset, false, true); } @Override protected int findSeparatorPosition(String s, int fromIndex) { int pos = s.indexOf('.', fromIndex); // no more than one ':' and '#' symbol after last '.' if (pos == -1 && s.indexOf(":") >= fromIndex) pos = s.indexOf(":", fromIndex); if (pos == -1 && s.indexOf("#") >= fromIndex) pos = s.indexOf("#", fromIndex); return pos; } } }