/*******************************************************************************
* Copyright (c) 2014, 2017 itemis AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Alexander Nyßen (itemis AG) - initial API and implementation
* Tamas Miklossy (itemis AG) - improve support for html-label highlighting
*
*******************************************************************************/
package org.eclipse.gef.dot.internal.ui.language.highlighting;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.dot.internal.language.dot.Attribute;
import org.eclipse.gef.dot.internal.language.dot.DotGraph;
import org.eclipse.gef.dot.internal.language.dot.NodeId;
import org.eclipse.gef.dot.internal.language.dot.NodeStmt;
import org.eclipse.gef.dot.internal.language.dot.Port;
import org.eclipse.gef.dot.internal.ui.language.internal.DotActivator;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator;
import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightedPositionAcceptor;
public class DotSemanticHighlightingCalculator
extends DefaultSemanticHighlightingCalculator {
@Override
public void doProvideHighlightingFor(XtextResource resource,
IHighlightedPositionAcceptor acceptor) {
// It gets a node model.
INode root = resource.getParseResult().getRootNode();
for (INode node : root.getAsTreeIterable()) {
EObject grammarElement = node.getGrammarElement();
if (grammarElement instanceof RuleCall) {
RuleCall rc = (RuleCall) grammarElement;
AbstractRule r = rc.getRule();
EObject c = grammarElement.eContainer();
// handle ID elements specifically
if (r.getName().equals("ID") //$NON-NLS-1$
&& ((Assignment) c).getFeature().equals("name")) { //$NON-NLS-1$
EObject semanticElement = node.getSemanticElement();
if (semanticElement instanceof DotGraph) {
acceptor.addPosition(node.getOffset(), node.getLength(),
DotHighlightingConfiguration.GRAPH_NAME_ID);
} else if (semanticElement instanceof NodeStmt
|| semanticElement instanceof NodeId) {
acceptor.addPosition(node.getOffset(), node.getLength(),
DotHighlightingConfiguration.NODE_NAME_ID);
} else if (semanticElement instanceof Attribute) {
acceptor.addPosition(node.getOffset(), node.getLength(),
DotHighlightingConfiguration.ATTRIBUTE_NAME_ID);
} else if (semanticElement instanceof Port) {
acceptor.addPosition(node.getOffset(), node.getLength(),
DotHighlightingConfiguration.PORT_NAME_ID);
}
}
if (r.getName().equals("EdgeOp")) { //$NON-NLS-1$
acceptor.addPosition(node.getOffset(), node.getLength(),
DotHighlightingConfiguration.EDGE_OP_ID);
}
if (r.getName().equals("HTML_STRING")) { //$NON-NLS-1$
provideHighlightingForHtmlString(node, acceptor);
}
}
}
}
private void provideHighlightingForHtmlString(INode node,
IHighlightedPositionAcceptor acceptor) {
// highlight the leading '<' symbol
int openingSymbolOffset = node.getOffset();
acceptor.addPosition(openingSymbolOffset, 1,
DotHighlightingConfiguration.HTML_TAG);
// highlight the trailing '>' symbol
int closingSymbolOffset = node.getOffset() + node.getText().length()
- 1;
acceptor.addPosition(closingSymbolOffset, 1,
DotHighlightingConfiguration.HTML_TAG);
// trim the leading '<' and trailing '>' symbols
String htmlString = node.getText().substring(1,
node.getText().length() - 1);
// delegate the highlighting of the the html-label substring to the
// corresponding sub-grammar highlighter
DotSubgrammarHighlighter htmlLabelHighlighter = new DotSubgrammarHighlighter(
DotActivator.ORG_ECLIPSE_GEF_DOT_INTERNAL_LANGUAGE_DOTHTMLLABEL);
htmlLabelHighlighter.provideHightlightingFor(htmlString,
node.getOffset() + 1, acceptor);
}
}