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);
}
}