package com.intellij.lang.javascript.flex.presentation; import com.intellij.ide.structureView.*; import com.intellij.ide.structureView.impl.xml.XmlStructureViewTreeModel; import com.intellij.ide.structureView.xml.XmlStructureViewBuilderProvider; import com.intellij.ide.util.treeView.smartTree.Sorter; import com.intellij.lang.javascript.JavaScriptSupportLoader; import com.intellij.lang.javascript.flex.XmlBackedJSClassImpl; import com.intellij.lang.javascript.psi.JSQualifiedName; import com.intellij.lang.javascript.psi.ecmal4.JSClass; import com.intellij.lang.javascript.psi.resolve.ResolveProcessor; import com.intellij.lang.javascript.structureView.JSStructureViewElement; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.ResolveState; import com.intellij.psi.XmlRecursiveElementVisitor; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.containers.ContainerUtil; import com.intellij.xml.util.HtmlUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * @author Maxim.Mossienko * Date: Jul 17, 2008 * Time: 10:31:43 PM */ public class FlexStructureViewProvider implements XmlStructureViewBuilderProvider { @Override public StructureViewBuilder createStructureViewBuilder(@NotNull final XmlFile file) { if (!JavaScriptSupportLoader.isFlexMxmFile(file)) return null; return new TreeBasedStructureViewBuilder() { @Override @NotNull public StructureViewModel createStructureViewModel(@Nullable Editor editor) { return new XmlStructureViewTreeModel(file, editor) { @Override @NotNull public Sorter[] getSorters() { return Sorter.EMPTY_ARRAY; } }; } }; } static class FlexStructureViewElement extends JSStructureViewElement { private final XmlFile myFile; public FlexStructureViewElement(final JSClass clazz, final XmlFile file, final boolean includeInherited) { super(clazz, includeInherited, true); myFile = file; } @Override protected List<StructureViewTreeElement> collectMyElements(final THashSet<String> referencedNamedIds, final JSQualifiedName ns, final PsiFile contextFile) { final List<StructureViewTreeElement> result = new ArrayList<>(); final ResolveProcessor processor = new ResolveProcessor(null) { @Override public boolean execute(@NotNull final PsiElement element, @NotNull final ResolveState state) { result.add(new JSStructureViewElement(element, true, true)); return true; } }; processor.setLocalResolve(true); myElement.processDeclarations(processor, ResolveState.initial(), myElement, myElement); myFile.acceptChildren(new XmlRecursiveElementVisitor() { @Override public void visitXmlTag(final XmlTag tag) { if (HtmlUtil.STYLE_TAG_NAME.equalsIgnoreCase(tag.getLocalName())) { for(StructureViewExtension ext: StructureViewFactoryEx.getInstanceEx(myFile.getProject()).getAllExtensions(XmlTag.class)) { final StructureViewTreeElement[] structureViewTreeElements = ext.getChildren(tag); if (structureViewTreeElements != null && structureViewTreeElements.length > 0) { ContainerUtil.addAll(result, structureViewTreeElements); } } } else { super.visitXmlTag(tag); } } }); return result; } @Override protected JSStructureViewElement createStructureViewElement(final PsiElement element, Set<String> parentReferencedNames) { if (element instanceof XmlBackedJSClassImpl) { PsiFile file = element.getContainingFile(); return new FlexStructureViewElement((JSClass)element, (XmlFile)file, myIncludeInherited); } else { return super.createStructureViewElement(element, parentReferencedNames); } } } }