diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java index 22de04f053b9..cfd68e9eeac2 100644 --- a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java @@ -109,6 +109,9 @@ public abstract class CodeInsightTestCase extends PsiTestCase { configureByFile(filePath, null); } + /** + * @param files the first file will be loaded in editor + */ protected VirtualFile configureByFiles(@Nullable String projectRoot,String... files) throws Exception { if (files.length == 0) return null; final VirtualFile[] vFiles = new VirtualFile[files.length]; diff --git a/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java b/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java index 476e91b40970..51e0ff29c816 100644 --- a/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java +++ b/xml/tests/src/com/intellij/codeInsight/daemon/XmlHighlightingTest.java @@ -1992,6 +1992,11 @@ public class XmlHighlightingTest extends DaemonAnalyzerTestCase { doTest(getFullRelativeTestName(".html"), true, true); } + public void testAnyAttribute() throws Exception { + configureByFiles(null, BASE_PATH + "anyAttribute.xml", BASE_PATH + "services-1.0.xsd"); + doDoTest(true, false); + } + @Override protected void setUp() throws Exception { super.setUp(); diff --git a/xml/tests/testData/xml/anyAttribute.xml b/xml/tests/testData/xml/anyAttribute.xml new file mode 100644 index 000000000000..56835ab524bb --- /dev/null +++ b/xml/tests/testData/xml/anyAttribute.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/xml/tests/testData/xml/services-1.0.xsd b/xml/tests/testData/xml/services-1.0.xsd new file mode 100644 index 000000000000..f1c2003c6225 --- /dev/null +++ b/xml/tests/testData/xml/services-1.0.xsd @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java index a6a2b1a540ed..c2005fa4ba41 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/ComplexTypeDescriptor.java @@ -382,7 +382,7 @@ public class ComplexTypeDescriptor extends TypeDescriptor { } enum CanContainAttributeType { - CanContainButSkip, CanContainButDoNotSkip, CanNotContain + CanContainButSkip, CanContainButDoNotSkip, CanContainAny, CanNotContain } private CanContainAttributeType _canContainAttribute(String namespace, @@ -401,6 +401,9 @@ public class ComplexTypeDescriptor extends TypeDescriptor { if (OTHER_NAMESPACE_ATTR_VALUE.equals(ns)) { return !namespace.equals(myDocumentDescriptor.getDefaultNamespace()) ? canContainAttributeType : CanContainAttributeType.CanNotContain; } + else if ("##any".equals(ns)) { + return CanContainAttributeType.CanContainAny; + } return canContainAttributeType; } else if (XmlNSDescriptorImpl.equalsToSchemaName(tag, "attributeGroup")) { diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java index ac00589000d2..91b8f60009a4 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlElementDescriptorImpl.java @@ -306,19 +306,21 @@ public class XmlElementDescriptorImpl implements XmlElementDescriptor, PsiWritab XmlAttributeDescriptor attribute = getAttribute(localName, namespace, context, attributeName); - if (attribute instanceof AnyXmlAttributeDescriptor && namespace.length() > 0) { - final XmlNSDescriptor candidateNSDescriptor = context.getNSDescriptor(namespace, true); + if (attribute instanceof AnyXmlAttributeDescriptor) { + final ComplexTypeDescriptor.CanContainAttributeType containAttributeType = + ((AnyXmlAttributeDescriptor)attribute).getCanContainAttributeType(); + if (containAttributeType != ComplexTypeDescriptor.CanContainAttributeType.CanContainAny && !namespace.isEmpty()) { + final XmlNSDescriptor candidateNSDescriptor = context.getNSDescriptor(namespace, true); - if (candidateNSDescriptor instanceof XmlNSDescriptorImpl) { - final XmlNSDescriptorImpl nsDescriptor = (XmlNSDescriptorImpl)candidateNSDescriptor; + if (candidateNSDescriptor instanceof XmlNSDescriptorImpl) { + final XmlNSDescriptorImpl nsDescriptor = (XmlNSDescriptorImpl)candidateNSDescriptor; - final XmlAttributeDescriptor xmlAttributeDescriptor = nsDescriptor.getAttribute(localName, namespace, context); - if (xmlAttributeDescriptor != null) return xmlAttributeDescriptor; - else { - final ComplexTypeDescriptor.CanContainAttributeType containAttributeType = - ((AnyXmlAttributeDescriptor)attribute).getCanContainAttributeType(); - if (containAttributeType == ComplexTypeDescriptor.CanContainAttributeType.CanContainButDoNotSkip) { - attribute = null; + final XmlAttributeDescriptor xmlAttributeDescriptor = nsDescriptor.getAttribute(localName, namespace, context); + if (xmlAttributeDescriptor != null) return xmlAttributeDescriptor; + else { + if (containAttributeType == ComplexTypeDescriptor.CanContainAttributeType.CanContainButDoNotSkip) { + attribute = null; + } } } }