IDEA-69031: XmlUnusedNamespaceDeclaration - Does not take element content into account: QName in attribute values support

This commit is contained in:
Dmitry Avdeev
2011-05-23 12:10:22 +04:00
parent c8a9c6fcb8
commit 5733197e65
5 changed files with 78 additions and 6 deletions
@@ -24,6 +24,7 @@ import com.intellij.codeInspection.XmlSuppressableInspectionTool;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.xml.SchemaPrefixReference;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.xml.*;
import com.intellij.xml.XmlBundle;
@@ -96,6 +97,19 @@ public class XmlUnboundNsPrefixInspection extends XmlSuppressableInspectionTool
checkUnboundNamespacePrefix(attribute, tag, XmlUtil.findPrefixByQualifiedName(name), null, holder, isOnTheFly);
}
@Override
public void visitXmlAttributeValue(XmlAttributeValue value) {
PsiReference[] references = value.getReferences();
for (PsiReference reference : references) {
if (reference instanceof SchemaPrefixReference) {
if (!XML.equals(((SchemaPrefixReference)reference).getNamespacePrefix()) && reference.resolve() == null) {
holder.registerProblem(reference, XmlErrorMessages.message("unbound.namespace",
((SchemaPrefixReference)reference).getNamespacePrefix()), ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
}
}
}
}
};
}
@@ -76,7 +76,7 @@ public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor impl
}
private boolean hasSimpleSchemaType(@NonNls String type) {
final String attributeValue = myTag.getAttributeValue("type");
final String attributeValue = getType();
if (attributeValue != null) {
if (attributeValue.endsWith(type)) {
@@ -93,6 +93,11 @@ public class XmlAttributeDescriptorImpl extends BasicXmlAttributeDescriptor impl
return false;
}
@Nullable
public String getType() {
return myTag.getAttributeValue("type");
}
public boolean hasIdType() {
return hasSimpleSchemaType("ID");
}
@@ -379,13 +379,13 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptor,Validator<XmlDocumen
return XSD_PREFIX.equals(XmlUtil.findPrefixByQualifiedName(name));
}
private static boolean checkSchemaNamespace(String namespace) {
public static boolean checkSchemaNamespace(String namespace) {
return XmlUtil.XML_SCHEMA_URI.equals(namespace) ||
XmlUtil.XML_SCHEMA_URI2.equals(namespace) ||
XmlUtil.XML_SCHEMA_URI3.equals(namespace);
}
static boolean checkSchemaNamespace(XmlTag context){
public static boolean checkSchemaNamespace(XmlTag context){
final String namespace = context.getNamespace();
if(namespace.length() > 0){
return checkSchemaNamespace(namespace);
@@ -0,0 +1,50 @@
package com.intellij.xml.util;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.impl.source.xml.SchemaPrefixReference;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ProcessingContext;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.impl.schema.XmlAttributeDescriptorImpl;
import com.intellij.xml.impl.schema.XmlNSDescriptorImpl;
import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
*/
public class XmlPrefixReferenceProvider extends PsiReferenceProvider {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
XmlAttributeValue attributeValue = (XmlAttributeValue)element;
PsiElement parent = attributeValue.getParent();
if (parent instanceof XmlAttribute && !XmlNSDescriptorImpl.checkSchemaNamespace(((XmlAttribute)parent).getParent())) {
XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor();
if (descriptor instanceof XmlAttributeDescriptorImpl) {
String type = ((XmlAttributeDescriptorImpl)descriptor).getType();
if (type != null && type.endsWith(":QName")) {
String prefix = XmlUtil.findPrefixByQualifiedName(type);
String ns = ((XmlTag)descriptor.getDeclaration()).getNamespaceByPrefix(prefix);
if (XmlNSDescriptorImpl.checkSchemaNamespace(ns)) {
String value = attributeValue.getValue();
if (value != null) {
int i = value.indexOf(':');
if (i > 0) {
return new PsiReference[] {
new SchemaPrefixReference(attributeValue, TextRange.from(1, i), value.substring(0, i), null)
};
}
}
}
}
}
}
return PsiReference.EMPTY_ARRAY;
}
}
@@ -2,10 +2,8 @@ package com.intellij.xml.util;
import com.intellij.codeInsight.daemon.impl.analysis.encoding.XmlEncodingReferenceProvider;
import com.intellij.patterns.PlatformPatterns;
import static com.intellij.patterns.StandardPatterns.string;
import static com.intellij.patterns.XmlPatterns.*;
import com.intellij.patterns.XmlPatterns;
import com.intellij.psi.PsiReferenceContributor;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.PsiReferenceRegistrar;
import com.intellij.psi.filters.*;
import com.intellij.psi.filters.position.NamespaceFilter;
@@ -16,6 +14,9 @@ import com.intellij.psi.impl.source.resolve.reference.impl.providers.SchemaRefer
import com.intellij.psi.impl.source.resolve.reference.impl.providers.URIReferenceProvider;
import com.intellij.psi.xml.*;
import static com.intellij.patterns.StandardPatterns.string;
import static com.intellij.patterns.XmlPatterns.*;
/**
* @author peter
*/
@@ -79,5 +80,7 @@ public class XmlReferenceContributor extends PsiReferenceContributor {
XmlUtil.registerXmlAttributeValueReferenceProvider(registrar, new String[] {"encoding"}, new ScopeFilter(new ParentElementFilter(new ClassFilter(XmlProcessingInstruction.class))), true,
new XmlEncodingReferenceProvider());
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue(), new XmlPrefixReferenceProvider());
}
}