diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java index f05231089ca5..d40ee8bd8143 100644 --- a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlHighlightVisitor.java @@ -249,22 +249,17 @@ public class XmlHighlightVisitor extends XmlElementVisitor implements HighlightV private void checkTagByDescriptor(final XmlTag tag) { String name = tag.getName(); - XmlElementDescriptor elementDescriptor = null; + XmlElementDescriptor elementDescriptor; final PsiElement parent = tag.getParent(); if (parent instanceof XmlTag) { XmlTag parentTag = (XmlTag)parent; + + elementDescriptor = XmlUtil.getDescriptorFromContext(tag); + final XmlElementDescriptor parentDescriptor = parentTag.getDescriptor(); - if (parentDescriptor != null) { - elementDescriptor = XmlExtension.getExtension(tag.getContainingFile()).getElementDescriptor(tag, parentTag, parentDescriptor); - } - - if (parentDescriptor != null && - elementDescriptor == null && - !skipValidation(parentTag) && - !XmlUtil.tagFromTemplateFramework(tag) - ) { + if (parentDescriptor != null && elementDescriptor == null && shouldBeValidated(tag)) { if (tag instanceof HtmlTag) { //XmlEntitiesInspection inspection = getInspectionProfile(tag, HtmlStyleLocalInspection.SHORT_NAME); //if (inspection != null /*&& isAdditionallyDeclared(inspection.getAdditionalEntries(XmlEntitiesInspection.UNKNOWN_TAG), name)*/) { @@ -765,4 +760,12 @@ public class XmlHighlightVisitor extends XmlElementVisitor implements HighlightV return unquotedValue; } + + public static boolean shouldBeValidated(@NotNull XmlTag tag) { + PsiElement parent = tag.getParent(); + if (parent instanceof XmlTag) { + return !skipValidation(parent) && !XmlUtil.tagFromTemplateFramework(tag); + } + return true; + } } diff --git a/xml/impl/src/com/intellij/codeInspection/htmlInspections/HtmlUnknownTagInspection.java b/xml/impl/src/com/intellij/codeInspection/htmlInspections/HtmlUnknownTagInspection.java index 7532162f3db9..58b614aef041 100644 --- a/xml/impl/src/com/intellij/codeInspection/htmlInspections/HtmlUnknownTagInspection.java +++ b/xml/impl/src/com/intellij/codeInspection/htmlInspections/HtmlUnknownTagInspection.java @@ -36,6 +36,7 @@ import com.intellij.xml.XmlElementDescriptor; import com.intellij.xml.impl.schema.AnyXmlElementDescriptor; import com.intellij.xml.util.HtmlUtil; import com.intellij.xml.util.XmlTagUtil; +import com.intellij.xml.util.XmlUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -195,33 +196,26 @@ public class HtmlUnknownTagInspection extends HtmlLocalInspectionTool { return myCustomValuesEnabled; } - private static boolean isInRightPlace(@NotNull XmlTag tag, @NotNull XmlElementDescriptor tagDescriptor) { - XmlTag parentTag = tag.getParentTag(); - if (parentTag == null) { - return true; - } - XmlElementDescriptor parentDescriptor = parentTag.getDescriptor(); - if (parentDescriptor == null) { - return true; - } - XmlElementDescriptor[] suitableChildDescriptors = parentDescriptor.getElementsDescriptors(parentTag); - for (XmlElementDescriptor descriptor : suitableChildDescriptors) { - if (descriptor.getName().equalsIgnoreCase(tagDescriptor.getName())) { - return true; - } - } - return false; + private static boolean isAbstractDescriptor(XmlElementDescriptor descriptor) { + return descriptor == null || descriptor instanceof AnyXmlElementDescriptor; } protected void checkTag(@NotNull final XmlTag tag, @NotNull final ProblemsHolder holder, final boolean isOnTheFly) { - PsiElement parentTag = tag.getParentTag() ; - if (parentTag != null && XmlHighlightVisitor.skipValidation(parentTag)) { + if (!(tag instanceof HtmlTag) || !XmlHighlightVisitor.shouldBeValidated(tag)) { return; } - final XmlElementDescriptor descriptor = tag.getDescriptor(); - if (tag instanceof HtmlTag && - (descriptor == null || descriptor instanceof AnyXmlElementDescriptor || - (descriptor instanceof HtmlElementDescriptorImpl && !isInRightPlace(tag, descriptor)))) { + + XmlElementDescriptor descriptorFromContext = XmlUtil.getDescriptorFromContext(tag); + + XmlElementDescriptor ownDescriptor = isAbstractDescriptor(descriptorFromContext) + ? tag.getDescriptor() + : descriptorFromContext; + + if (isAbstractDescriptor(ownDescriptor) || + (ownDescriptor instanceof HtmlElementDescriptorImpl && + isAbstractDescriptor(descriptorFromContext) && + tag.getParent() instanceof XmlTag)) { + final String name = tag.getName(); if (!isCustomValuesEnabled() || !isCustomValue(name)) { @@ -230,7 +224,7 @@ public class HtmlUnknownTagInspection extends HtmlLocalInspectionTool { // todo: support "element is not allowed" message for html5 // some tags in html5 cannot be found in xhtml5.xsd if they are located in incorrect context, so they get any-element descriptor (ex. "canvas: tag) - final String message = descriptor == null || descriptor instanceof AnyXmlElementDescriptor + final String message = isAbstractDescriptor(ownDescriptor) ? XmlErrorMessages.message("unknown.html.tag", name) : XmlErrorMessages.message("element.is.not.allowed.here", name); diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index e678ac64f21b..14f7bab98943 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -17,6 +17,7 @@ package com.intellij.xml.util; import com.intellij.codeInsight.completion.CompletionUtil; import com.intellij.codeInsight.daemon.Validator; +import com.intellij.codeInsight.daemon.impl.analysis.XmlHighlightVisitor; import com.intellij.javaee.ExternalResourceManager; import com.intellij.javaee.ExternalResourceManagerEx; import com.intellij.javaee.ExternalResourceManagerImpl; @@ -34,10 +35,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Trinity; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.LocalFileSystem; @@ -571,6 +569,20 @@ public class XmlUtil { } } + @Nullable + public static XmlElementDescriptor getDescriptorFromContext(@NotNull XmlTag tag) { + PsiElement parent = tag.getParent(); + if (parent instanceof XmlTag) { + XmlTag parentTag = (XmlTag)parent; + final XmlElementDescriptor parentDescriptor = parentTag.getDescriptor(); + + if (parentDescriptor != null) { + return XmlExtension.getExtension(tag.getContainingFile()).getElementDescriptor(tag, parentTag, parentDescriptor); + } + } + return null; + } + private static class XmlElementProcessor { private final PsiElementProcessor processor; private final PsiFile targetFile;