diff --git a/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java b/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java index 05eb6a341b17..e53821560604 100644 --- a/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java +++ b/xml/tests/src/com/intellij/codeInsight/completion/XmlCompletionTest.java @@ -17,6 +17,7 @@ import com.intellij.psi.statistics.StatisticsManager; import com.intellij.psi.statistics.impl.StatisticsManagerImpl; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import com.intellij.xml.util.XmlUtil; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -67,7 +68,7 @@ public class XmlCompletionTest extends LightCodeInsightFixtureTestCase { protected void runTest() throws Throwable { new WriteCommandAction(getProject()) { @Override - protected void run(Result result) throws Throwable { + protected void run(@NotNull Result result) throws Throwable { XmlCompletionTest.super.runTest(); } }.execute(); @@ -686,5 +687,15 @@ public class XmlCompletionTest extends LightCodeInsightFixtureTestCase { myFixture.testCompletionVariants("tagValue/completeEnum.xml", "none", "standard"); myFixture.testCompletionVariants("tagValue/completeBoolean.xml", "false", "true"); } + + public void testInheritedAttribute() throws Exception { + myFixture.configureByFiles("InheritedAttr/test.xsd", "InheritedAttr/library.xsd"); + myFixture.testCompletionVariants("InheritedAttr/test.xml", "buz", + "library:boo", + "xml:base", + "xml:id", + "xml:lang", + "xml:space"); + } } diff --git a/xml/tests/testData/completion/InheritedAttr/library.xsd b/xml/tests/testData/completion/InheritedAttr/library.xsd new file mode 100644 index 000000000000..6381dd0b729f --- /dev/null +++ b/xml/tests/testData/completion/InheritedAttr/library.xsd @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/xml/tests/testData/completion/InheritedAttr/test.xml b/xml/tests/testData/completion/InheritedAttr/test.xml new file mode 100644 index 000000000000..dfa5afac32b5 --- /dev/null +++ b/xml/tests/testData/completion/InheritedAttr/test.xml @@ -0,0 +1,4 @@ + +/> \ No newline at end of file diff --git a/xml/tests/testData/completion/InheritedAttr/test.xsd b/xml/tests/testData/completion/InheritedAttr/test.xsd new file mode 100644 index 000000000000..bb9e9824cf51 --- /dev/null +++ b/xml/tests/testData/completion/InheritedAttr/test.xsd @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file 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 f4d468edf759..31fd2d385364 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 @@ -233,6 +233,9 @@ public class ComplexTypeDescriptor extends TypeDescriptor { else { XmlAttributeDescriptorImpl descriptor = myDocumentDescriptor.createAttributeDescriptor(tag); descriptor.myUse = use; + if (ref != null) { + descriptor.myReferenceName = ref.getAttributeValue(REF_ATTR_NAME); + } addAttributeDescriptor(result, descriptor); } } diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java index ce3d6485705c..4447ed2bd5eb 100644 --- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlAttributeDescriptorImpl.java @@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable; public class XmlAttributeDescriptorImpl extends XsdEnumerationDescriptor implements PsiWritableMetaData, XmlAttributeDescriptor { private XmlTag myTag; String myUse; + String myReferenceName; @NonNls public static final String REQUIRED_ATTR_VALUE = "required"; @@ -114,8 +115,6 @@ public class XmlAttributeDescriptorImpl extends XsdEnumerationDescriptor impleme if (context == null) { return name; } - final String form = myTag.getAttributeValue("form"); - boolean isQualifiedAttr = QUALIFIED_ATTR_VALUE.equals(form); final XmlTag rootTag = (((XmlFile) myTag.getContainingFile())).getRootTag(); assert rootTag != null; @@ -123,6 +122,19 @@ public class XmlAttributeDescriptorImpl extends XsdEnumerationDescriptor impleme if (targetNs == null) return name; XmlTag contextTag = (XmlTag)context; + if (QUALIFIED_ATTR_VALUE.equals(myTag.getAttributeValue("form")) || + QUALIFIED_ATTR_VALUE.equals(rootTag.getAttributeValue("attributeFormDefault")) || + shouldBeQualified(targetNs, contextTag)) { + final String prefixByNamespace = contextTag.getPrefixByNamespace(targetNs); + if (prefixByNamespace!= null && prefixByNamespace.length() > 0) { + name = prefixByNamespace + ":" + name; + } + } + + return name; + } + + private boolean shouldBeQualified(String targetNs, XmlTag contextTag) { boolean attributeShouldBeQualified = false; String contextNs = contextTag.getNamespace(); @@ -135,6 +147,10 @@ public class XmlAttributeDescriptorImpl extends XsdEnumerationDescriptor impleme if (type instanceof ComplexTypeDescriptor) { final ComplexTypeDescriptor typeDescriptor = (ComplexTypeDescriptor)type; + XmlAttributeDescriptor[] attributes = ((ComplexTypeDescriptor)type).getAttributes(contextTag); + if ((myReferenceName == null || myReferenceName.indexOf(':') == -1) && ArrayUtil.contains(this, attributes)) { + return false; + } attributeShouldBeQualified = typeDescriptor.canContainAttribute(targetNs, null) != ComplexTypeDescriptor.CanContainAttributeType.CanNotContain; } @@ -143,17 +159,7 @@ public class XmlAttributeDescriptorImpl extends XsdEnumerationDescriptor impleme } } } - - if (isQualifiedAttr || - QUALIFIED_ATTR_VALUE.equals(rootTag.getAttributeValue("attributeFormDefault")) || - attributeShouldBeQualified) { - final String prefixByNamespace = contextTag.getPrefixByNamespace(targetNs); - if (prefixByNamespace!= null && prefixByNamespace.length() > 0) { - name = prefixByNamespace + ":" + name; - } - } - - return name; + return attributeShouldBeQualified; } public void setName(String name) throws IncorrectOperationException { 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 974e2e7cfb97..3c75d9efcbf8 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 @@ -377,11 +377,6 @@ public class XmlElementDescriptorImpl extends XsdEnumerationDescriptor final ComplexTypeDescriptor.CanContainAttributeType containAttributeType = descriptor.canContainAttribute(namespace, qName); if (containAttributeType != ComplexTypeDescriptor.CanContainAttributeType.CanNotContain) { - for (XmlAttributeDescriptor attributeDescriptor : descriptors) { - if (attributeDescriptor.getName().equals(attributeName)) { - return attributeDescriptor; - } - } return new AnyXmlAttributeDescriptor(attributeName, containAttributeType); } }