blob: 683bd8fef63dcab1b44e601354e801fcca205465 [file] [log] [blame]
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.ant.validation;
import com.intellij.lang.ant.AntBundle;
import com.intellij.lang.ant.dom.*;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.highlighting.DomElementAnnotationHolder;
import com.intellij.util.xml.highlighting.DomElementsAnnotator;
import java.util.List;
public class AntAnnotator implements DomElementsAnnotator {
public void annotate(DomElement element, final DomElementAnnotationHolder holder) {
element.accept(new AntDomRecursiveVisitor() {
public void visitTypeDef(AntDomTypeDef typedef) {
final List<String> errors = typedef.getErrorDescriptions();
if (!errors.isEmpty()) {
final StringBuilder builder = StringBuilderSpinAllocator.alloc();
try {
builder.append(AntBundle.message("failed.to.load.types")).append(":");
for (String error : errors) {
builder.append("\n").append(error);
}
createAnnotationOnTag(typedef, builder.toString(), holder);
}
finally {
StringBuilderSpinAllocator.dispose(builder);
}
}
super.visitTypeDef(typedef);
}
public void visitAntDomCustomElement(AntDomCustomElement custom) {
if (custom.getDefinitionClass() == null) {
final AntDomNamedElement declaringElement = custom.getDeclaringElement();
if (declaringElement instanceof AntDomTypeDef) {
String failedMessage = AntBundle.message("using.definition.which.type.failed.to.load");
final String error = custom.getLoadError();
if (error != null) {
failedMessage = failedMessage + ": " + error;
}
createAnnotationOnTag(custom, failedMessage, holder);
}
}
super.visitAntDomCustomElement(custom);
}
public void visitAntDomElement(AntDomElement element) {
//for (GenericDomValue child : DomUtil.getDefinedChildrenOfType(element, GenericDomValue.class, false, true)) {
// final XmlElement valueElement = DomUtil.getValueElement(child);
// if (valueElement != null) {
// checkReferences(valueElement, holder, child);
// }
//}
super.visitAntDomElement(element);
}
});
}
private static void createAnnotationOnTag(AntDomElement custom, String failedMessage, DomElementAnnotationHolder holder) {
final XmlTag tag = custom.getXmlTag();
if (tag == null) {
return;
}
final String name = custom.getXmlElementName();
final TextRange absoluteRange = new TextRange(0, name.length()).shiftRight(tag.getTextRange().getStartOffset() + 1);
holder.createProblem(custom, failedMessage);
//holder.createErrorAnnotation(absoluteRange, failedMessage);
}
//private static void addDefinitionQuickFixes(final Annotation annotation, final AntStructuredElement se) {
// if (se.getSourceElement().getName().length() == 0) return;
//
// final AntProject project = se.getAntProject();
// annotation.registerFix(new AntCreateMacroDefFix(se));
// annotation.registerFix(new AntCreatePresetDefFix(se));
// for (final AntFile antFile : project.getImportedFiles()) {
// annotation.registerFix(new AntCreateMacroDefFix(se, antFile));
// annotation.registerFix(new AntCreatePresetDefFix(se, antFile));
// }
//}
//private static void checkValidAttributes(final AntStructuredElement se, final AntTypeDefinition def, final @NonNls AnnotationHolder holder) {
// final XmlTag sourceElement = se.getSourceElement();
// for (final XmlAttribute attr : sourceElement.getAttributes()) {
// @NonNls final String name = attr.getName();
// if (name.startsWith("xmlns")) continue;
// final AntAttributeType type = def.getAttributeType(name);
// final PsiElement attrName = attr.getFirstChild();
// if (attrName != null) {
// if (type == null) {
// if (!isSuccessorOfUndefinedElement(se)) {
// holder.createErrorAnnotation(attrName, AntBundle.message("attribute.is.not.allowed.here", name));
// }
// }
// else {
// final String attrValue = attr.getValue();
// if (type == AntAttributeType.INTEGER) {
// try {
// Integer.parseInt(se.computeAttributeValue(attrValue));
// }
// catch (NumberFormatException e) {
// holder.createErrorAnnotation(attrName, AntBundle.message("integer.attribute.has.invalid.value", name));
// }
// }
// else if (type == AntAttributeType.STRING) {
// if (attrValue != null && AntProperty.TSTAMP_PATTERN_ATTRIBUTE_NAME.equalsIgnoreCase(name)) {
// final PsiElement parent = se.getParent();
// if (parent instanceof AntProperty && ((AntProperty)parent).isTstamp()) {
// try {
// new SimpleDateFormat(attrValue);
// }
// catch (IllegalArgumentException e) {
// holder.createErrorAnnotation(attr.getValueElement(), e.getMessage());
// }
// }
// }
// }
// }
// }
// }
//}
//private static void checkReferences(final XmlElement xmlElement, final @NonNls DomElementAnnotationHolder holder, DomElement domElement) {
// if (xmlElement == null) {
// return;
// }
// Set<PsiReference> processed = null;
// for (final PsiReference ref : xmlElement.getReferences()) {
// if (!(ref instanceof AntDomReference)) {
// continue;
// }
// final AntDomReference antDomRef = (AntDomReference)ref;
// if (antDomRef.shouldBeSkippedByAnnotator()) {
// continue;
// }
// if (processed != null && processed.contains(ref)) {
// continue;
// }
// if (ref.resolve() == null) {
// final TextRange absoluteRange = ref.getRangeInElement().shiftRight(ref.getElement().getTextRange().getStartOffset());
// final Annotation annotation = holder.createProblem(absoluteRange, antDomRef.getUnresolvedMessagePattern());
// annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
// if (ref instanceof AntDomFileReference) {
// if (processed == null) {
// processed = new HashSet<PsiReference>();
// }
// ContainerUtil.addAll(processed, ((AntDomFileReference)ref).getFileReferenceSet().getAllReferences());
// }
//
// //final IntentionAction[] intentionActions = antRef.getFixes();
// //for (final IntentionAction action : intentionActions) {
// // annotation.registerFix(action);
// //}
// }
// }
//}
}