blob: 4f92da29e128d0dd4168f767de8a0f29ae1b11d6 [file] [log] [blame]
package org.intellij.lang.xpath.xslt.validation.inspections;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.XmlElementVisitor;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NotNull;
import org.intellij.lang.xpath.xslt.XsltSupport;
import org.intellij.lang.xpath.xslt.psi.XsltApplyTemplates;
import org.intellij.lang.xpath.xslt.psi.XsltCallTemplate;
import org.intellij.lang.xpath.xslt.psi.XsltElementFactory;
import org.intellij.lang.xpath.xslt.psi.XsltParameter;
import org.intellij.lang.xpath.xslt.psi.XsltTemplate;
import org.intellij.lang.xpath.xslt.psi.XsltTemplateInvocation;
import org.intellij.lang.xpath.xslt.psi.XsltWithParam;
import org.intellij.lang.xpath.xslt.quickfix.AddParameterFix;
import org.intellij.lang.xpath.xslt.quickfix.AddWithParamFix;
import org.intellij.lang.xpath.xslt.quickfix.RemoveParamFix;
import org.intellij.lang.xpath.xslt.quickfix.AbstractFix;
import java.util.HashMap;
import java.util.Map;
/*
* Created by IntelliJ IDEA.
* User: sweinreuter
* Date: 24.01.2008
*/
public class TemplateInvocationInspection extends XsltInspection {
@NotNull
public HighlightDisplayLevel getDefaultLevel() {
return HighlightDisplayLevel.ERROR;
}
@NotNull
public String getDisplayName() {
return "Template Invocation Problems";
}
@NotNull
public String getShortName() {
return "XsltTemplateInvocation";
}
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
final XsltElementFactory xsltElementFactory = XsltElementFactory.getInstance();
return new XmlElementVisitor() {
@Override
public void visitXmlTag(XmlTag tag) {
if (XsltSupport.isTemplateCall(tag)) {
final XsltCallTemplate call = xsltElementFactory.wrapElement(tag, XsltCallTemplate.class);
checkTemplateInvocation(call, holder, isOnTheFly);
} else if (XsltSupport.isApplyTemplates(tag)) {
final XsltApplyTemplates call = xsltElementFactory.wrapElement(tag, XsltApplyTemplates.class);
checkTemplateInvocation(call, holder, isOnTheFly);
}
}
};
}
private static void checkTemplateInvocation(XsltTemplateInvocation call, ProblemsHolder holder, boolean onTheFly) {
final XsltWithParam[] arguments = call.getArguments();
final Map<String, XsltWithParam> argNames = new HashMap<String, XsltWithParam>();
for (XsltWithParam arg : arguments) {
final XmlAttribute attr = arg.getNameAttribute();
if (attr != null) {
final String name = attr.getValue();
if (argNames.containsKey(name)) {
final PsiElement token = arg.getNameIdentifier();
assert token != null;
holder.registerProblem(token, "Duplicate Argument '" + name + "'");
}
argNames.put(name, arg);
}
}
if (call instanceof XsltCallTemplate) {
final XsltCallTemplate ct = ((XsltCallTemplate)call);
final PsiElement nameToken = ct.getNameIdentifier();
final XsltTemplate template = ct.getTemplate();
if (template != null) {
if (nameToken != null) {
final XsltParameter[] parameters = template.getParameters();
for (XsltParameter parameter : parameters) {
if (!argNames.containsKey(parameter.getName()) && !parameter.hasDefault()) {
final LocalQuickFix fix = new AddWithParamFix(parameter, call.getTag()).createQuickFix(onTheFly);
holder.registerProblem(nameToken, "Missing template parameter: " + parameter.getName(),
AbstractFix.createFixes(fix));
}
}
}
for (String s : argNames.keySet()) {
final XmlAttribute argAttribute = argNames.get(s).getNameAttribute();
assert argAttribute != null;
final XmlAttributeValue valueElement = argAttribute.getValueElement();
final PsiElement valueToken = XsltSupport.getAttValueToken(argAttribute);
if (valueToken != null && s.trim().length() > 0) {
if (template.getParameter(s) == null) {
final LocalQuickFix fix1 = new AddParameterFix(s, template).createQuickFix(onTheFly);
final LocalQuickFix fix2 = new RemoveParamFix(argNames.get(s).getTag(), s).createQuickFix(onTheFly);
holder.registerProblem(valueToken, "Undeclared template parameter: " + s,
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, AbstractFix.createFixes(fix1, fix2));
}
} else if (valueElement != null) {
holder.registerProblem(valueElement, "Parameter name expected");
}
}
}
}
}
}