blob: 916f1a755c829d1dc9a7644c9a33eeca65d8627a [file] [log] [blame]
package org.eclipse.dltk.javascript.internal.ui.text;
import java.io.StringReader;
import java.util.List;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.compiler.env.IModuleSource;
import org.eclipse.dltk.javascript.ast.Expression;
import org.eclipse.dltk.javascript.ast.ForEachInStatement;
import org.eclipse.dltk.javascript.ast.GetMethod;
import org.eclipse.dltk.javascript.ast.Identifier;
import org.eclipse.dltk.javascript.ast.Keyword;
import org.eclipse.dltk.javascript.ast.Method;
import org.eclipse.dltk.javascript.ast.PropertyInitializer;
import org.eclipse.dltk.javascript.ast.RegExpLiteral;
import org.eclipse.dltk.javascript.ast.Script;
import org.eclipse.dltk.javascript.ast.SetMethod;
import org.eclipse.dltk.javascript.ast.StringLiteral;
import org.eclipse.dltk.javascript.ast.XmlFragment;
import org.eclipse.dltk.javascript.ast.XmlLiteral;
import org.eclipse.dltk.javascript.ast.XmlTextFragment;
import org.eclipse.dltk.javascript.internal.ui.JavaScriptUI;
import org.eclipse.dltk.javascript.parser.JavaScriptParserUtil;
import org.eclipse.dltk.ui.editor.highlighting.AbortSemanticHighlightingException;
import org.eclipse.dltk.ui.editor.highlighting.ISemanticHighlighter;
import org.eclipse.dltk.ui.editor.highlighting.ISemanticHighlightingRequestor;
public class JavaScriptXmlHighlighter extends AbstractJavaScriptHighlighter
implements ISemanticHighlighter {
private static final String HL_XML_TAG = JavascriptColorConstants.JS_XML_TAG_NAME;
private static final String HL_XML_ATTRIBUTE = JavascriptColorConstants.JS_XML_ATTR_NAME;
private static final String HL_XML_COMMENT = JavascriptColorConstants.JS_XML_COMMENT_NAME;
private static final String HL_KEYWORD = JavascriptColorConstants.JS_KEYWORD;
private static final String HL_REGEXP = JavascriptColorConstants.JS_REGEXP;
private static final String HL_PROPERTY = JavascriptColorConstants.JS_PROPERTY;
public String[] getHighlightingKeys() {
return new String[] { HL_XML_TAG, HL_XML_ATTRIBUTE, HL_XML_COMMENT,
HL_KEYWORD, HL_REGEXP, HL_PROPERTY };
}
public void process(IModuleSource code,
ISemanticHighlightingRequestor requestor) {
final Script declaration = JavaScriptParserUtil.parse(code, null);
if (declaration == null) {
throw new AbortSemanticHighlightingException();
}
try {
declaration.traverse(new HighlightingVisitor(requestor));
} catch (Exception e) {
JavaScriptUI.log(e);
}
}
static class HighlightingVisitor extends ASTVisitor {
final ISemanticHighlightingRequestor requestor;
final boolean bPropertyNames = isSemanticHighlightingEnabled(HL_PROPERTY);
public HighlightingVisitor(ISemanticHighlightingRequestor requestor) {
this.requestor = requestor;
}
@Override
public boolean visitGeneral(ASTNode node) throws Exception {
if (node instanceof XmlLiteral) {
handleXML((XmlLiteral) node);
} else if (node instanceof Method) {
handleMethod((Method) node);
} else if (node instanceof RegExpLiteral) {
handleRegExp((RegExpLiteral) node);
} else if (node instanceof PropertyInitializer) {
if (bPropertyNames) {
handlePropertyInitializer((PropertyInitializer) node);
}
} else if (node instanceof ForEachInStatement) {
handleForEachIn((ForEachInStatement) node);
}
return true;
}
private void handleXML(XmlLiteral literal) {
for (XmlFragment fragment : literal.getFragments()) {
if (fragment instanceof XmlTextFragment) {
final XMLTokenizer tokenizer = new XMLTokenizer(
new StringReader(
((XmlTextFragment) fragment).getXml()));
final int offset = fragment.sourceStart();
@SuppressWarnings("unchecked")
final List<Token> tokens = tokenizer.getRegions();
for (Token token : tokens) {
if (token.context == XMLTokenizer.XML_TAG_NAME) {
addRange(requestor, offset, token, HL_XML_TAG);
} else if (token.context == XMLTokenizer.XML_TAG_ATTRIBUTE_NAME) {
addRange(requestor, offset, token, HL_XML_ATTRIBUTE);
} else if (token.context == XMLTokenizer.XML_COMMENT_OPEN
|| token.context == XMLTokenizer.XML_COMMENT_TEXT
|| token.context == XMLTokenizer.XML_COMMENT_CLOSE) {
addRange(requestor, offset, token, HL_XML_COMMENT);
} else if (token.context == XMLTokenizer.XML_TAG_ATTRIBUTE_VALUE) {
//
}
}
}
}
}
private void handleMethod(Method method) {
Keyword keyword;
if (method instanceof GetMethod) {
keyword = ((GetMethod) method).getGetKeyword();
} else if (method instanceof SetMethod) {
keyword = ((SetMethod) method).getSetKeyword();
} else {
return;
}
requestor.addPosition(keyword.sourceStart(), keyword.sourceEnd(),
HL_KEYWORD);
}
private void handleForEachIn(ForEachInStatement forEach) {
final Keyword keyword = forEach.getEachKeyword();
requestor.addPosition(keyword.sourceStart(), keyword.sourceEnd(),
HL_KEYWORD);
}
private void handleRegExp(RegExpLiteral regExp) {
requestor.addPosition(regExp.sourceStart(), regExp.sourceEnd(),
HL_REGEXP);
}
private void handlePropertyInitializer(PropertyInitializer property) {
final Expression name = property.getName();
if (name instanceof Identifier || name instanceof StringLiteral) {
requestor.addPosition(name.sourceStart(), name.sourceEnd(),
HL_PROPERTY);
}
}
private static void addRange(ISemanticHighlightingRequestor requestor,
int start, Token token, String highlightingKey) {
requestor.addPosition(start + token.start, start + token.start
+ token.textLength, highlightingKey);
}
}
}