blob: c4769aa73e8c2cf01658a09f8a5e117e102f44a9 [file] [log] [blame]
package org.intellij.lang.xpath.xslt.validation.inspections;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.lang.LanguageNamesValidation;
import com.intellij.lang.refactoring.NamesValidator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.XmlElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import org.intellij.lang.xpath.XPathFileType;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.psi.XsltElementFactory;
import org.intellij.lang.xpath.xslt.psi.XsltNamedElement;
import org.intellij.lang.xpath.xslt.psi.XsltTemplate;
import org.intellij.lang.xpath.xslt.validation.DeclarationChecker;
import org.jetbrains.annotations.NotNull;
/*
* Created by IntelliJ IDEA.
* User: sweinreuter
* Date: 24.01.2008
*/
public class XsltDeclarationInspection extends XsltInspection {
private XsltElementFactory myXsltElementFactory;
private NamesValidator myNamesValidator;
@NotNull
public String getDisplayName() {
return "Declaration Problems";
}
@NotNull
public String getShortName() {
return "XsltDeclarations";
}
@NotNull
public HighlightDisplayLevel getDefaultLevel() {
return HighlightDisplayLevel.ERROR;
}
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
return new XmlElementVisitor() {
@Override
public void visitXmlTag(final XmlTag tag) {
final XmlAttribute nameAttr = tag.getAttribute("name", null);
if (nameAttr == null || PsiTreeUtil.hasErrorElements(nameAttr)) return;
if (XsltSupport.isVariableOrParam(tag)) {
final XsltNamedElement instance = getXsltElementFactory().wrapElement(tag, XsltNamedElement.class);
checkDeclaration(instance, nameAttr.getValue(), holder);
} else if (XsltSupport.isTemplate(tag)) {
final XsltTemplate tmpl = getXsltElementFactory().wrapElement(tag, XsltTemplate.class);
checkDeclaration(tmpl, nameAttr.getValue(), holder);
}
}
private void checkDeclaration(final XsltNamedElement element, final String name, ProblemsHolder holder) {
final XmlTag tag = element.getTag();
final PsiElement token = element.getNameIdentifier();
if (name == null || name.length() == 0) {
if (token != null) {
holder.registerProblem(token, "Empty name not permitted");
} else {
final XmlAttribute attribute = element.getNameAttribute();
if (attribute != null) {
final XmlAttributeValue e = attribute.getValueElement();
if (e != null) {
holder.registerProblem(e, "Empty name not permitted");
}
}
}
} else if (!isLegalName(name, holder.getManager().getProject())) {
assert token != null;
holder.registerProblem(token, "Illegal name");
} else {
assert token != null;
final XmlFile file = (XmlFile)tag.getContainingFile();
final XmlTag duplicatedSymbol = DeclarationChecker.getInstance(file).getDuplicatedSymbol(tag);
if (duplicatedSymbol != null) {
if (duplicatedSymbol.getContainingFile() == file) {
holder.registerProblem(token, "Duplicate declaration");
} else {
holder.registerProblem(token, "Duplicates declaration from '" + duplicatedSymbol.getContainingFile().getName() + "'");
}
}
}
}
private boolean isLegalName(String value, Project project) {
return getNamesValidator().isIdentifier(value, project);
}
};
}
public XsltElementFactory getXsltElementFactory() {
if (myXsltElementFactory == null) {
myXsltElementFactory = XsltElementFactory.getInstance();
}
return myXsltElementFactory;
}
public NamesValidator getNamesValidator() {
if (myNamesValidator == null) {
myNamesValidator = LanguageNamesValidation.INSTANCE.forLanguage(XPathFileType.XPATH.getLanguage());
}
return myNamesValidator;
}
}