/******************************************************************************* * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH 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 *******************************************************************************/ package de.gebit.integrity.ui.highlighting; import org.eclipse.emf.ecore.EObject; import org.eclipse.xtext.CrossReference; import org.eclipse.xtext.nodemodel.INode; import org.eclipse.xtext.resource.XtextResource; import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightedPositionAcceptor; import org.eclipse.xtext.ui.editor.syntaxcoloring.ISemanticHighlightingCalculator; import com.google.inject.Inject; import de.gebit.integrity.dsl.ArbitraryParameterOrResultName; import de.gebit.integrity.dsl.BooleanValue; import de.gebit.integrity.dsl.Call; import de.gebit.integrity.dsl.DateAndTimeValue; import de.gebit.integrity.dsl.DateValue; import de.gebit.integrity.dsl.DecimalValue; import de.gebit.integrity.dsl.EnumValue; import de.gebit.integrity.dsl.FixedParameterName; import de.gebit.integrity.dsl.FixedResultName; import de.gebit.integrity.dsl.IntegerValue; import de.gebit.integrity.dsl.JavaClassReference; import de.gebit.integrity.dsl.MethodReference; import de.gebit.integrity.dsl.NamedResult; import de.gebit.integrity.dsl.NestedObject; import de.gebit.integrity.dsl.NullValue; import de.gebit.integrity.dsl.Operation; import de.gebit.integrity.dsl.Parameter; import de.gebit.integrity.dsl.ParameterName; import de.gebit.integrity.dsl.ParameterTableHeader; import de.gebit.integrity.dsl.ResultTableHeader; import de.gebit.integrity.dsl.StringValue; import de.gebit.integrity.dsl.SuiteParameter; import de.gebit.integrity.dsl.TableTest; import de.gebit.integrity.dsl.Test; import de.gebit.integrity.dsl.TimeValue; import de.gebit.integrity.dsl.Variable; import de.gebit.integrity.services.DSLGrammarAccess; import de.gebit.integrity.utils.IntegrityDSLUtil; /** * The semantic highlight calculator is responsible for performing the more complex syntax highlighting. * * @author Rene Schneider - initial API and implementation * */ public class DSLSemanticHighlightingCalculator implements ISemanticHighlightingCalculator { /** * The grammar access. */ @Inject private DSLGrammarAccess grammarAccess; @Override public void provideHighlightingFor(XtextResource aResource, IHighlightedPositionAcceptor anAcceptor) { if (aResource == null || aResource.getParseResult() == null) { return; } INode tempRoot = aResource.getParseResult().getRootNode(); EObject tempLastSemanticElement = null; for (INode tempNode : tempRoot.getAsTreeIterable()) { EObject tempSemanticElement = tempNode.getSemanticElement(); EObject tempGrammarElement = tempNode.getGrammarElement(); if (tempGrammarElement instanceof CrossReference) { // There are different cross references which we want to highlight if (tempSemanticElement instanceof SuiteParameter) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.PARAMETER_NAME_ID); } else if (tempSemanticElement instanceof ParameterName) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.PARAMETER_NAME_ID); } else if (tempSemanticElement instanceof Test || tempSemanticElement instanceof Call || tempSemanticElement instanceof TableTest) { int tempIndex = tempNode.getText().lastIndexOf('.'); if (tempIndex >= 0) { anAcceptor.addPosition(tempNode.getOffset(), tempIndex, DSLHighlightingConfiguration.PACKAGE_PREFIX_ID); } } else if (tempSemanticElement instanceof Operation) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_OPERATION_IDENTIFIER_ID : DSLHighlightingConfiguration.PARAMETER_OPERATION_IDENTIFIER_ID); } } } else if (tempGrammarElement == grammarAccess.getCustomOperationAccess().getWithKeyword_4_1()) { // Special case for the "with" keyword in operations Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_OPERATION_IDENTIFIER_ID : DSLHighlightingConfiguration.PARAMETER_OPERATION_IDENTIFIER_ID); } } else if (tempGrammarElement == grammarAccess.getKeyValuePairAccess() .getIdentifierIDTerminalRuleCall_0_0_0() || tempGrammarElement == grammarAccess.getKeyValuePairAccess() .getStringIdentifierSTRINGTerminalRuleCall_0_1_0()) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult == null ? DSLHighlightingConfiguration.NESTED_OBJECT_KEY_ID : (tempIsResult ? DSLHighlightingConfiguration.RESULT_NESTED_OBJECT_KEY_ID : DSLHighlightingConfiguration.PARAMETER_NESTED_OBJECT_KEY_ID)); } else { // All other cases highlight entire semantic elements at once if (tempSemanticElement != null && tempLastSemanticElement != tempSemanticElement) { tempLastSemanticElement = tempSemanticElement; if (tempSemanticElement instanceof MethodReference) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.JAVA_CLASS_ID); int tempLastDotIndex = tempNode.getText().lastIndexOf('.'); int tempHashIndex = tempNode.getText().lastIndexOf('#'); if (tempLastDotIndex >= 0) { int tempStart = tempNode.getOffset() + tempLastDotIndex; int tempEnd = tempNode.getOffset() + (tempHashIndex >= tempLastDotIndex ? tempHashIndex - 1 : tempNode.getLength()); anAcceptor.addPosition(tempStart, tempEnd - tempStart, DSLHighlightingConfiguration.JAVA_CLASS_HIGHLIGHT_ID); } if (tempHashIndex >= 0) { int tempStart = tempNode.getOffset() + tempHashIndex; int tempEnd = tempNode.getOffset() + tempNode.getLength(); anAcceptor.addPosition(tempStart, tempEnd - tempStart, DSLHighlightingConfiguration.JAVA_METHOD_HIGHLIGHT_ID); } } else if (tempSemanticElement instanceof JavaClassReference) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.JAVA_CLASS_ID); int tempLastDotIndex = tempNode.getText().lastIndexOf('.'); if (tempLastDotIndex >= 0) { int tempStart = tempNode.getOffset() + tempLastDotIndex; int tempEnd = tempNode.getOffset() + tempNode.getLength(); anAcceptor.addPosition(tempStart, tempEnd - tempStart, DSLHighlightingConfiguration.JAVA_CLASS_HIGHLIGHT_ID); } } else if (tempSemanticElement instanceof ArbitraryParameterOrResultName) { if (tempSemanticElement.eContainer() instanceof Parameter) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.PARAMETER_NAME_ID); } else if (tempSemanticElement.eContainer() instanceof ParameterTableHeader) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.PARAMETER_NAME_ID); } else if (tempSemanticElement.eContainer() instanceof ResultTableHeader) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.RESULT_NAME_ID); } else if (tempSemanticElement.eContainer() instanceof NamedResult) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.RESULT_NAME_ID); } } else if (tempSemanticElement instanceof FixedParameterName) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.PARAMETER_NAME_ID); } else if (tempSemanticElement instanceof FixedResultName) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), DSLHighlightingConfiguration.RESULT_NAME_ID); } else { if (tempSemanticElement instanceof IntegerValue || tempSemanticElement instanceof DecimalValue) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_NUMBER_ID : DSLHighlightingConfiguration.PARAMETER_NUMBER_ID); } } else if (tempSemanticElement instanceof StringValue) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_STRING_ID : DSLHighlightingConfiguration.PARAMETER_STRING_ID); } } else if (tempSemanticElement instanceof DateValue || tempSemanticElement instanceof TimeValue || tempSemanticElement instanceof DateAndTimeValue) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_DATE_TIME_ID : DSLHighlightingConfiguration.PARAMETER_DATE_TIME_ID); } } else if (tempSemanticElement instanceof Variable) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_VARIABLE_VALUE_ID : DSLHighlightingConfiguration.PARAMETER_VARIABLE_VALUE_ID); } } else if (tempSemanticElement instanceof NullValue || tempSemanticElement instanceof EnumValue || tempSemanticElement instanceof BooleanValue) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_CONSTANT_VALUE_ID : DSLHighlightingConfiguration.PARAMETER_CONSTANT_VALUE_ID); } } else if (tempSemanticElement instanceof Operation) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_OPERATION_ID : DSLHighlightingConfiguration.PARAMETER_OPERATION_ID); } } else if (tempSemanticElement instanceof NestedObject) { Boolean tempIsResult = IntegrityDSLUtil.isResult(tempSemanticElement); if (tempIsResult != null) { anAcceptor.addPosition(tempNode.getOffset(), tempNode.getLength(), tempIsResult ? DSLHighlightingConfiguration.RESULT_NESTED_OBJECT_ID : DSLHighlightingConfiguration.PARAMETER_NESTED_OBJECT_ID); } } } } } } } }