From f2c7ea80f64726087e6a091f4d25513c807fa55c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 17 Jul 2013 20:00:14 +0200 Subject: [PATCH] no XSL in invalid tags --- .../intellij/lang/xpath/xslt/XsltSupport.java | 595 +++++++++--------- 1 file changed, 304 insertions(+), 291 deletions(-) diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java index cfda401e359f..e36fbc7d0143 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java @@ -43,334 +43,347 @@ import java.util.Set; public class XsltSupport { - public static final String XALAN_EXTENSION_PREFIX = "http://xml.apache.org/xalan/"; - public static final String XSLT_NS = "http://www.w3.org/1999/XSL/Transform"; - public static final String PLUGIN_EXTENSIONS_NS = "urn:idea:xslt-plugin#extensions"; - public static final Key> FORCE_XSLT_KEY = Key.create("FORCE_XSLT"); + public static final String XALAN_EXTENSION_PREFIX = "http://xml.apache.org/xalan/"; + public static final String XSLT_NS = "http://www.w3.org/1999/XSL/Transform"; + public static final String PLUGIN_EXTENSIONS_NS = "urn:idea:xslt-plugin#extensions"; + public static final Key> FORCE_XSLT_KEY = Key.create("FORCE_XSLT"); - private static final Map XPATH_ATTR_MAP = new THashMap(10); - private static final Map> XPATH_AVT_MAP = new THashMap>(10); + private static final Map XPATH_ATTR_MAP = new THashMap(10); + private static final Map> XPATH_AVT_MAP = new THashMap>(10); - static { - XPATH_ATTR_MAP.put("select", ""); - XPATH_ATTR_MAP.put("match", ""); - XPATH_ATTR_MAP.put("test", ""); - XPATH_ATTR_MAP.put("use-when", ""); - XPATH_ATTR_MAP.put("group-by", ""); - XPATH_ATTR_MAP.put("group-adjacent", ""); - XPATH_ATTR_MAP.put("count", "number"); - XPATH_ATTR_MAP.put("from", "number"); - XPATH_ATTR_MAP.put("value", "number"); - XPATH_ATTR_MAP.put("use", "key"); + static { + XPATH_ATTR_MAP.put("select", ""); + XPATH_ATTR_MAP.put("match", ""); + XPATH_ATTR_MAP.put("test", ""); + XPATH_ATTR_MAP.put("use-when", ""); + XPATH_ATTR_MAP.put("group-by", ""); + XPATH_ATTR_MAP.put("group-adjacent", ""); + XPATH_ATTR_MAP.put("count", "number"); + XPATH_ATTR_MAP.put("from", "number"); + XPATH_ATTR_MAP.put("value", "number"); + XPATH_ATTR_MAP.put("use", "key"); - XPATH_AVT_MAP.put("element", new THashSet(Arrays.asList("name", "namespace"))); - XPATH_AVT_MAP.put("attribute", new THashSet(Arrays.asList("name", "namespace"))); - XPATH_AVT_MAP.put("namespace", new THashSet(Arrays.asList("name"))); - XPATH_AVT_MAP.put("processing-instruction", new THashSet(Arrays.asList("name"))); + XPATH_AVT_MAP.put("element", new THashSet(Arrays.asList("name", "namespace"))); + XPATH_AVT_MAP.put("attribute", new THashSet(Arrays.asList("name", "namespace"))); + XPATH_AVT_MAP.put("namespace", new THashSet(Arrays.asList("name"))); + XPATH_AVT_MAP.put("processing-instruction", new THashSet(Arrays.asList("name"))); - XPATH_AVT_MAP.put("number", new THashSet(Arrays.asList("format", "lang", "letter-value", "grouping-separator", "grouping-size", "ordinal"))); - XPATH_AVT_MAP.put("sort", new THashSet(Arrays.asList("lang", "data-type", "order", "case-order", "collation"))); + XPATH_AVT_MAP.put("number", new THashSet( + Arrays.asList("format", "lang", "letter-value", "grouping-separator", "grouping-size", "ordinal"))); + XPATH_AVT_MAP.put("sort", new THashSet(Arrays.asList("lang", "data-type", "order", "case-order", "collation"))); - XPATH_AVT_MAP.put("message", new THashSet(Arrays.asList("terminate"))); - XPATH_AVT_MAP.put("value-of", new THashSet(Arrays.asList("separator"))); + XPATH_AVT_MAP.put("message", new THashSet(Arrays.asList("terminate"))); + XPATH_AVT_MAP.put("value-of", new THashSet(Arrays.asList("separator"))); - XPATH_AVT_MAP.put("result-document", new THashSet(Arrays.asList("format", "href", "method", "byte-order-mark", - "cdata-section-elements", "doctype-public", "doctype-system", "encoding", "escape-uri-attributes", "include-content-type", - "indent", "media-type", "normalization-form", "omit-xml-declaration", "standalone", "undeclare-prefixes", "output-version"))); - } + XPATH_AVT_MAP.put("result-document", new THashSet(Arrays.asList("format", "href", "method", "byte-order-mark", + "cdata-section-elements", "doctype-public", "doctype-system", + "encoding", "escape-uri-attributes", "include-content-type", + "indent", "media-type", "normalization-form", + "omit-xml-declaration", "standalone", "undeclare-prefixes", + "output-version"))); + } - private XsltSupport() { - } + private XsltSupport() { + } - @NotNull - public static PsiFile[] getFiles(XmlAttribute attribute) { - final XmlAttributeValue value = attribute.getValueElement(); - if (value != null) { - final List files = new SmartList(); - InjectedLanguageUtil.enumerate(value, new PsiLanguageInjectionHost.InjectedPsiVisitor() { - public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { - if (injectedPsi instanceof XPathFile) { - files.add(injectedPsi); - } + @NotNull + public static PsiFile[] getFiles(XmlAttribute attribute) { + final XmlAttributeValue value = attribute.getValueElement(); + if (value != null) { + final List files = new SmartList(); + InjectedLanguageUtil.enumerate(value, new PsiLanguageInjectionHost.InjectedPsiVisitor() { + public void visit(@NotNull PsiFile injectedPsi, @NotNull List places) { + if (injectedPsi instanceof XPathFile) { + files.add(injectedPsi); } - }); - return files.isEmpty() ? PsiFile.EMPTY_ARRAY : PsiUtilCore.toPsiFileArray(files); + } + }); + return files.isEmpty() ? PsiFile.EMPTY_ARRAY : PsiUtilCore.toPsiFileArray(files); + } + return PsiFile.EMPTY_ARRAY; + } + + public static boolean isXsltAttribute(@NotNull XmlAttribute attribute) { + return isXsltTag(attribute.getParent()); + } + + public static boolean isXsltTag(@NotNull XmlTag tag) { + if (!tag.isValid()) return false; + final String s = tag.getNamespace(); + return XSLT_NS.equals(s) || s.startsWith(XALAN_EXTENSION_PREFIX); + } + + private static boolean isXsltCoreTag(@NotNull XmlTag tag) { + return tag.isValid() && XSLT_NS.equals(tag.getNamespace()); + } + + public static boolean isXPathAttribute(@NotNull XmlAttribute attribute) { + if (attribute.getValueElement() == null) return false; + + final String name = attribute.getName(); + if (isXsltAttribute(attribute)) { + final String tagName = attribute.getParent().getLocalName(); + final String s = XPATH_ATTR_MAP.get(name); + if ((s == null || s.length() > 0) && !tagName.equals(s)) { + if (!isAttributeValueTemplate(attribute, true)) { + return false; + } } - return PsiFile.EMPTY_ARRAY; } - - public static boolean isXsltAttribute(@NotNull XmlAttribute attribute) { - return isXsltTag(attribute.getParent()); - } - - public static boolean isXsltTag(@NotNull XmlTag tag) { - final String s = tag.getNamespace(); - return XSLT_NS.equals(s) || s.startsWith(XALAN_EXTENSION_PREFIX); - } - - private static boolean isXsltCoreTag(@NotNull XmlTag tag) { - return tag.isValid() && XSLT_NS.equals(tag.getNamespace()); - } - - public static boolean isXPathAttribute(@NotNull XmlAttribute attribute) { - if (attribute.getValueElement() == null) return false; - - final String name = attribute.getName(); - if (isXsltAttribute(attribute)) { - final String tagName = attribute.getParent().getLocalName(); - final String s = XPATH_ATTR_MAP.get(name); - if ((s == null || s.length() > 0) && !tagName.equals(s)) { - if (!isAttributeValueTemplate(attribute, true)) { - return false; - } - } - } else { - if (!isAttributeValueTemplate(attribute, false)) { - return false; - } - } - - final PsiFile file = attribute.getContainingFile(); - if (file != null) { - XsltChecker.LanguageLevel level = getXsltLanguageLevel(file); - if (level != XsltChecker.LanguageLevel.NONE) { - return true; - } - } - return false; - } - - private static boolean isAttributeValueTemplate(@NotNull XmlAttribute attribute, boolean isXsltAttribute) { - return (!isXsltAttribute || mayBeAVT(attribute)) && getAVTOffset(attribute.getValue(), 0) != -1; - } - - public static boolean isVariableOrParamName(@NotNull XmlAttribute attribute) { - return isXsltNameAttribute(attribute) && isVariableOrParam(attribute.getParent()); - } - - public static boolean isVariableOrParam(@NotNull XmlTag tag) { - final String localName = tag.getLocalName(); - return ("variable".equals(localName) || "param".equals(localName)) && isXsltCoreTag(tag); - } - - public static boolean isVariable(@NotNull XmlAttribute attribute) { - return isXsltNameAttribute(attribute) && isVariable(attribute.getParent()); - } - - public static boolean isVariable(@NotNull XmlTag tag) { - final String localName = tag.getLocalName(); - return "variable".equals(localName) && isXsltCoreTag(tag); - } - - public static boolean isParam(@NotNull XmlAttribute attribute) { - return isXsltNameAttribute(attribute) && isParam(attribute.getParent()); - } - - public static boolean isParam(@NotNull XmlTag tag) { - final String localName = tag.getLocalName(); - return "param".equals(localName) && isXsltCoreTag(tag); - } - - public static boolean isPatternAttribute(@NotNull XmlAttribute attribute) { - if (!isXsltAttribute(attribute)) return false; - - final String name = attribute.getName(); - if ("match".equals(name)) { - return true; - } else if ("count".equals(name) || "from".equals(name)) { - return "number".equals(attribute.getParent().getLocalName()); - } + else { + if (!isAttributeValueTemplate(attribute, false)) { return false; + } } - public static boolean isTemplateCall(@NotNull XmlTag tag) { - return "call-template".equals(tag.getLocalName()) && hasNameAttribute(tag) && isXsltCoreTag(tag); + final PsiFile file = attribute.getContainingFile(); + if (file != null) { + XsltChecker.LanguageLevel level = getXsltLanguageLevel(file); + if (level != XsltChecker.LanguageLevel.NONE) { + return true; + } } + return false; + } - public static boolean isFunction(@NotNull XmlTag tag) { - return "function".equals(tag.getLocalName()) && hasNameAttribute(tag) && isXsltCoreTag(tag); + private static boolean isAttributeValueTemplate(@NotNull XmlAttribute attribute, boolean isXsltAttribute) { + return (!isXsltAttribute || mayBeAVT(attribute)) && getAVTOffset(attribute.getValue(), 0) != -1; + } + + public static boolean isVariableOrParamName(@NotNull XmlAttribute attribute) { + return isXsltNameAttribute(attribute) && isVariableOrParam(attribute.getParent()); + } + + public static boolean isVariableOrParam(@NotNull XmlTag tag) { + final String localName = tag.getLocalName(); + return ("variable".equals(localName) || "param".equals(localName)) && isXsltCoreTag(tag); + } + + public static boolean isVariable(@NotNull XmlAttribute attribute) { + return isXsltNameAttribute(attribute) && isVariable(attribute.getParent()); + } + + public static boolean isVariable(@NotNull XmlTag tag) { + final String localName = tag.getLocalName(); + return "variable".equals(localName) && isXsltCoreTag(tag); + } + + public static boolean isParam(@NotNull XmlAttribute attribute) { + return isXsltNameAttribute(attribute) && isParam(attribute.getParent()); + } + + public static boolean isParam(@NotNull XmlTag tag) { + final String localName = tag.getLocalName(); + return "param".equals(localName) && isXsltCoreTag(tag); + } + + public static boolean isPatternAttribute(@NotNull XmlAttribute attribute) { + if (!isXsltAttribute(attribute)) return false; + + final String name = attribute.getName(); + if ("match".equals(name)) { + return true; } - - public static boolean isApplyTemplates(@NotNull XmlTag tag) { - final String localName = tag.getLocalName(); - return "apply-templates".equals(localName) && isXsltCoreTag(tag); + else if ("count".equals(name) || "from".equals(name)) { + return "number".equals(attribute.getParent().getLocalName()); } + return false; + } - private static boolean hasNameAttribute(@NotNull XmlTag tag) { - return tag.getAttribute("name", null) != null; + public static boolean isTemplateCall(@NotNull XmlTag tag) { + return "call-template".equals(tag.getLocalName()) && hasNameAttribute(tag) && isXsltCoreTag(tag); + } + + public static boolean isFunction(@NotNull XmlTag tag) { + return "function".equals(tag.getLocalName()) && hasNameAttribute(tag) && isXsltCoreTag(tag); + } + + public static boolean isApplyTemplates(@NotNull XmlTag tag) { + final String localName = tag.getLocalName(); + return "apply-templates".equals(localName) && isXsltCoreTag(tag); + } + + private static boolean hasNameAttribute(@NotNull XmlTag tag) { + return tag.getAttribute("name", null) != null; + } + + public static boolean isTemplateCallName(@NotNull XmlAttribute attribute) { + return isXsltNameAttribute(attribute) && isTemplateCall(attribute.getParent()); + } + + private static boolean isXsltNameAttribute(@NotNull XmlAttribute attribute) { + return "name".equals(attribute.getName()) && isXsltAttribute(attribute); + } + + public static boolean isTemplateName(@NotNull XmlAttribute attribute) { + return isXsltNameAttribute(attribute) && isTemplate(attribute.getParent()); + } + + public static boolean isFunctionName(@NotNull XmlAttribute attribute) { + return isXsltNameAttribute(attribute) && isFunction(attribute.getParent()); + } + + public static boolean isTemplate(@NotNull XmlTag element) { + return isTemplate(element, true); + } + + public static boolean isTemplate(@NotNull XmlTag element, boolean requireName) { + return "template".equals(element.getLocalName()) && (!requireName || hasNameAttribute(element)) && isXsltCoreTag(element); + } + + public static boolean isXsltFile(@NotNull PsiFile psiFile) { + if (psiFile.getFileType() != StdFileTypes.XML) return false; + + if (!(psiFile instanceof XmlFile)) return false; + + final XsltChecker.LanguageLevel level = getXsltLanguageLevel(psiFile); + return level != XsltChecker.LanguageLevel.NONE; + } + + public static XsltChecker.LanguageLevel getXsltLanguageLevel(@NotNull PsiFile psiFile) { + final CachedValuesManager mgr = CachedValuesManager.getManager(psiFile.getProject()); + return mgr.getParameterizedCachedValue(psiFile, FORCE_XSLT_KEY, XsltSupportProvider.INSTANCE, false, psiFile); + } + + public static boolean isXsltRootTag(@NotNull XmlTag tag) { + final String localName = tag.getLocalName(); + return ("stylesheet".equals(localName) || "transform".equals(localName)) && isXsltCoreTag(tag); + } + + public static boolean isTemplateCallParamName(@NotNull XmlAttribute attribute) { + return isXsltNameAttribute(attribute) && isTemplateCallParam(attribute.getParent()); + } + + private static boolean isTemplateCallParam(@NotNull XmlTag parent) { + return "with-param".equals(parent.getLocalName()) && hasNameAttribute(parent) && isXsltCoreTag(parent); + } + + public static boolean isTopLevelElement(XmlTag tag) { + XmlTag p = tag; + // not really necessary, XSLT doesn't allow literal result elements on top level anyway + while ((p = p.getParentTag()) != null) { + if (isXsltTag(p)) { + return isXsltRootTag(p); + } } + return false; + } - public static boolean isTemplateCallName(@NotNull XmlAttribute attribute) { - return isXsltNameAttribute(attribute) && isTemplateCall(attribute.getParent()); + public static boolean isIncludeOrImportHref(XmlAttribute xmlattribute) { + if (xmlattribute == null || !isXsltAttribute(xmlattribute)) return false; + final String localName = xmlattribute.getParent().getLocalName(); + return isIncludeOrImport(localName) && "href".equals(xmlattribute.getName()); + } + + private static boolean isIncludeOrImport(String localName) { + // treat import and include the same. right now it doesn't seem necessary to distinguish them + return ("import".equals(localName) || "include".equals(localName)); + } + + public static boolean isIncludeOrImport(XmlTag tag) { + if (tag == null) return false; + return isIncludeOrImport(tag.getLocalName()) && isXsltCoreTag(tag) && tag.getAttribute("href", null) != null; + } + + public static boolean isImport(XmlTag tag) { + if (tag == null) return false; + return "import".equals(tag.getLocalName()) && isXsltCoreTag(tag) && tag.getAttribute("href", null) != null; + } + + @Nullable + public static PsiElement getAttValueToken(@NotNull XmlAttribute attribute) { + final XmlAttributeValue valueElement = attribute.getValueElement(); + if (valueElement != null) { + final PsiElement firstChild = valueElement.getFirstChild(); + if (firstChild != null) { + final PsiElement nextSibling = firstChild.getNextSibling(); + return nextSibling instanceof XmlToken && ((XmlToken)nextSibling).getTokenType() == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN + ? nextSibling + : null; + } } + return null; + } - private static boolean isXsltNameAttribute(@NotNull XmlAttribute attribute) { - return "name".equals(attribute.getName()) && isXsltAttribute(attribute); + public static boolean isMode(XmlAttribute xmlattribute) { + if ("mode".equals(xmlattribute.getName())) { + final XmlTag parent = xmlattribute.getParent(); + return isApplyTemplates(parent) || isTemplate(parent, false); } + return false; + } - public static boolean isTemplateName(@NotNull XmlAttribute attribute) { - return isXsltNameAttribute(attribute) && isTemplate(attribute.getParent()); + public static int getAVTOffset(String value, int i) { + do { + i = value.indexOf('{', i); + if (i != -1 && i == value.indexOf("{{", i)) { + i += 2; + } + else { + break; + } } + while (i != -1); + return i; + } - public static boolean isFunctionName(@NotNull XmlAttribute attribute) { - return isXsltNameAttribute(attribute) && isFunction(attribute.getParent()); + public static boolean mayBeAVT(@NotNull XmlAttribute attribute) { + if (isXsltAttribute(attribute)) { + final String tagName = attribute.getParent().getLocalName(); + + final Set allowedAttrs = XPATH_AVT_MAP.get(tagName); + if (allowedAttrs == null) return isExtensionAvtAttribute(attribute); + + return allowedAttrs.contains(attribute.getName()); } - - public static boolean isTemplate(@NotNull XmlTag element) { - return isTemplate(element, true); + else { + return true; } + } - public static boolean isTemplate(@NotNull XmlTag element, boolean requireName) { - return "template".equals(element.getLocalName()) && (!requireName || hasNameAttribute(element)) && isXsltCoreTag(element); - } + private static boolean isExtensionAvtAttribute(XmlAttribute attribute) { + final String namespace = attribute.getParent().getNamespace(); + return namespace.startsWith(XALAN_EXTENSION_PREFIX) && "file".equals(attribute.getName()); + } - public static boolean isXsltFile(@NotNull PsiFile psiFile) { - if (psiFile.getFileType() != StdFileTypes.XML) return false; + public static Icon createXsltIcon(Icon icon) { + return LayeredIcon.create(icon, XpathIcons.Xslt_filetype_overlay); + } - if (!(psiFile instanceof XmlFile)) return false; + private static class XsltSupportProvider implements ParameterizedCachedValueProvider { + public static final ParameterizedCachedValueProvider INSTANCE = new XsltSupportProvider(); - final XsltChecker.LanguageLevel level = getXsltLanguageLevel(psiFile); - return level != XsltChecker.LanguageLevel.NONE; - } + public CachedValueProvider.Result compute(PsiFile psiFile) { + if (!(psiFile instanceof XmlFile)) { + return CachedValueProvider.Result.create(XsltChecker.LanguageLevel.NONE); + } - public static XsltChecker.LanguageLevel getXsltLanguageLevel(@NotNull PsiFile psiFile) { - final CachedValuesManager mgr = CachedValuesManager.getManager(psiFile.getProject()); - return mgr.getParameterizedCachedValue(psiFile, FORCE_XSLT_KEY, XsltSupportProvider.INSTANCE, false, psiFile); - } - - public static boolean isXsltRootTag(@NotNull XmlTag tag) { - final String localName = tag.getLocalName(); - return ("stylesheet".equals(localName) || "transform".equals(localName)) && isXsltCoreTag(tag); - } - - public static boolean isTemplateCallParamName(@NotNull XmlAttribute attribute) { - return isXsltNameAttribute(attribute) && isTemplateCallParam(attribute.getParent()); - } - - private static boolean isTemplateCallParam(@NotNull XmlTag parent) { - return "with-param".equals(parent.getLocalName()) && hasNameAttribute(parent) && isXsltCoreTag(parent); - } - - public static boolean isTopLevelElement(XmlTag tag) { - XmlTag p = tag; - // not really necessary, XSLT doesn't allow literal result elements on top level anyway - while ((p = p.getParentTag()) != null) { - if (isXsltTag(p)) { - return isXsltRootTag(p); - } - } - return false; - } - - public static boolean isIncludeOrImportHref(XmlAttribute xmlattribute) { - if (xmlattribute == null || !isXsltAttribute(xmlattribute)) return false; - final String localName = xmlattribute.getParent().getLocalName(); - return isIncludeOrImport(localName) && "href".equals(xmlattribute.getName()); - } - - private static boolean isIncludeOrImport(String localName) { - // treat import and include the same. right now it doesn't seem necessary to distinguish them - return ("import".equals(localName) || "include".equals(localName)); - } - - public static boolean isIncludeOrImport(XmlTag tag) { - if (tag == null) return false; - return isIncludeOrImport(tag.getLocalName()) && isXsltCoreTag(tag) && tag.getAttribute("href", null) != null; - } - - public static boolean isImport(XmlTag tag) { - if (tag == null) return false; - return "import".equals(tag.getLocalName()) && isXsltCoreTag(tag) && tag.getAttribute("href", null) != null; - } - - @Nullable - public static PsiElement getAttValueToken(@NotNull XmlAttribute attribute) { - final XmlAttributeValue valueElement = attribute.getValueElement(); - if (valueElement != null) { - final PsiElement firstChild = valueElement.getFirstChild(); - if (firstChild != null) { - final PsiElement nextSibling = firstChild.getNextSibling(); - return nextSibling instanceof XmlToken && ((XmlToken)nextSibling).getTokenType() == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN ? nextSibling : null; - } - } - return null; - } - - public static boolean isMode(XmlAttribute xmlattribute) { - if ("mode".equals(xmlattribute.getName())) { - final XmlTag parent = xmlattribute.getParent(); - return isApplyTemplates(parent) || isTemplate(parent, false); - } - return false; - } - - public static int getAVTOffset(String value, int i) { - do { - i = value.indexOf('{', i); - if (i != -1 && i == value.indexOf("{{", i)) { - i += 2; - } else { - break; - } - } while (i != -1); - return i; - } - - public static boolean mayBeAVT(@NotNull XmlAttribute attribute) { - if (isXsltAttribute(attribute)) { - final String tagName = attribute.getParent().getLocalName(); - - final Set allowedAttrs = XPATH_AVT_MAP.get(tagName); - if (allowedAttrs == null) return isExtensionAvtAttribute(attribute); - - return allowedAttrs.contains(attribute.getName()); - } else { - return true; - } - } - - private static boolean isExtensionAvtAttribute(XmlAttribute attribute) { - final String namespace = attribute.getParent().getNamespace(); - return namespace.startsWith(XALAN_EXTENSION_PREFIX) && "file".equals(attribute.getName()); - } - - public static Icon createXsltIcon(Icon icon) { - return LayeredIcon.create(icon, XpathIcons.Xslt_filetype_overlay); - } - - private static class XsltSupportProvider implements ParameterizedCachedValueProvider { - public static final ParameterizedCachedValueProvider INSTANCE = new XsltSupportProvider(); - - public CachedValueProvider.Result compute(PsiFile psiFile) { - if (!(psiFile instanceof XmlFile)) { - return CachedValueProvider.Result.create(XsltChecker.LanguageLevel.NONE); - } - - final XmlFile xmlFile = (XmlFile)psiFile; - if (psiFile instanceof PsiFileEx) { - if (((PsiFileEx)psiFile).isContentsLoaded()) { - final XmlDocument doc = xmlFile.getDocument(); - if (doc != null) { - final XmlTag rootTag = doc.getRootTag(); - if (rootTag != null) { - XmlAttribute v; - XsltChecker.LanguageLevel level; - if (isXsltRootTag(rootTag)) { - v = rootTag.getAttribute("version"); - level = v != null ? XsltChecker.getLanguageLevel(v.getValue()) : XsltChecker.LanguageLevel.NONE; - } else { - v = rootTag.getAttribute("version", XSLT_NS); - level = v != null ? XsltChecker.getLanguageLevel(v.getValue()) : XsltChecker.LanguageLevel.NONE; - } - return CachedValueProvider.Result.create(level, rootTag); - } + final XmlFile xmlFile = (XmlFile)psiFile; + if (psiFile instanceof PsiFileEx) { + if (((PsiFileEx)psiFile).isContentsLoaded()) { + final XmlDocument doc = xmlFile.getDocument(); + if (doc != null) { + final XmlTag rootTag = doc.getRootTag(); + if (rootTag != null) { + XmlAttribute v; + XsltChecker.LanguageLevel level; + if (isXsltRootTag(rootTag)) { + v = rootTag.getAttribute("version"); + level = v != null ? XsltChecker.getLanguageLevel(v.getValue()) : XsltChecker.LanguageLevel.NONE; } + else { + v = rootTag.getAttribute("version", XSLT_NS); + level = v != null ? XsltChecker.getLanguageLevel(v.getValue()) : XsltChecker.LanguageLevel.NONE; + } + return CachedValueProvider.Result.create(level, rootTag); } } - - final XsltChecker xsltChecker = new XsltChecker(); - NanoXmlUtil.parseFile(psiFile, xsltChecker); - return CachedValueProvider.Result.create(xsltChecker.getLanguageLevel(), psiFile); } + } + + final XsltChecker xsltChecker = new XsltChecker(); + NanoXmlUtil.parseFile(psiFile, xsltChecker); + return CachedValueProvider.Result.create(xsltChecker.getLanguageLevel(), psiFile); } + } }