aboutsummaryrefslogtreecommitdiffstats
path: root/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
diff options
context:
space:
mode:
Diffstat (limited to 'language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java')
-rw-r--r--language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java151
1 files changed, 151 insertions, 0 deletions
diff --git a/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
new file mode 100644
index 00000000..b2e3c90b
--- /dev/null
+++ b/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
@@ -0,0 +1,151 @@
1package tools.refinery.language.ide.syntaxcoloring;
2
3import java.util.List;
4
5import org.eclipse.emf.common.util.EList;
6import org.eclipse.emf.ecore.EObject;
7import org.eclipse.emf.ecore.EReference;
8import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator;
9import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor;
10import org.eclipse.xtext.nodemodel.INode;
11import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
12import org.eclipse.xtext.service.OperationCanceledManager;
13import org.eclipse.xtext.util.CancelIndicator;
14
15import com.google.common.collect.ImmutableList;
16import com.google.inject.Inject;
17
18import tools.refinery.language.ProblemUtil;
19import tools.refinery.language.model.problem.ClassDeclaration;
20import tools.refinery.language.model.problem.EnumDeclaration;
21import tools.refinery.language.model.problem.NamedElement;
22import tools.refinery.language.model.problem.Node;
23import tools.refinery.language.model.problem.Parameter;
24import tools.refinery.language.model.problem.PredicateDefinition;
25import tools.refinery.language.model.problem.ProblemPackage;
26import tools.refinery.language.model.problem.ReferenceDeclaration;
27import tools.refinery.language.model.problem.Variable;
28
29public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighlightingCalculator {
30 private static final String BUILTIN_CLASS = "cm-keyword";
31 private static final String CLASS_CLASS = "problem-class";
32 private static final String ABSTRACT_CLASS = "problem-abstract";
33 private static final String ENUM_CLASS = "problem-enum";
34 private static final String REFERENCE_CLASS = "problem-reference";
35 private static final String CONTAINMENT_CLASS = "problem-containment";
36 private static final String PREDICATE_CLASS = "problem-predicate";
37 private static final String ERROR_CLASS = "problem-error";
38 private static final String NODE_CLASS = "problem-node";
39 private static final String UNIQUE_NODE_CLASS = "problem-unique-node";
40 private static final String NEW_NODE_CLASS = "problem-new-node";
41 private static final String PARAMETER_CLASS = "problem-parameter";
42 private static final String VARIABLE_CLASS = "problem-variable";
43 private static final String SINGLETON_VARIABLE_CLASS = "problem-singleton-variable";
44
45 @Inject
46 private OperationCanceledManager operationCanceledManager;
47
48 @Override
49 protected boolean highlightElement(EObject object, IHighlightedPositionAcceptor acceptor,
50 CancelIndicator cancelIndicator) {
51 highlightName(object, acceptor);
52 highlightCrossReferences(object, acceptor, cancelIndicator);
53 return false;
54 }
55
56 protected void highlightName(EObject object, IHighlightedPositionAcceptor acceptor) {
57 if (!(object instanceof NamedElement)) {
58 return;
59 }
60 String[] highlightClass = getHighlightClass(object);
61 if (highlightClass.length > 0) {
62 highlightFeature(acceptor, object, ProblemPackage.Literals.NAMED_ELEMENT__NAME, highlightClass);
63 }
64 }
65
66 protected void highlightCrossReferences(EObject object, IHighlightedPositionAcceptor acceptor,
67 CancelIndicator cancelIndicator) {
68 for (EReference reference : object.eClass().getEAllReferences()) {
69 if (reference.isContainment()) {
70 continue;
71 }
72 operationCanceledManager.checkCanceled(cancelIndicator);
73 if (reference.isMany()) {
74 highlightManyValues(object, reference, acceptor);
75 } else {
76 highlightSingleValue(object, reference, acceptor);
77 }
78 }
79 }
80
81 protected void highlightSingleValue(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
82 EObject valueObj = (EObject) object.eGet(reference);
83 String[] highlightClass = getHighlightClass(valueObj);
84 if (highlightClass.length > 0) {
85 highlightFeature(acceptor, object, reference, highlightClass);
86 }
87 }
88
89 protected void highlightManyValues(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
90 @SuppressWarnings("unchecked")
91 EList<? extends EObject> values = (EList<? extends EObject>) object.eGet(reference);
92 List<INode> nodes = NodeModelUtils.findNodesForFeature(object, reference);
93 int size = Math.min(values.size(), nodes.size());
94 for (var i = 0; i < size; i++) {
95 EObject valueInList = values.get(i);
96 INode node = nodes.get(i);
97 String[] highlightClass = getHighlightClass(valueInList);
98 if (highlightClass.length > 0) {
99 highlightNode(acceptor, node, highlightClass);
100 }
101 }
102 }
103
104 protected String[] getHighlightClass(EObject eObject) {
105 if (ProblemUtil.isBuiltIn(eObject)) {
106 return new String[] { BUILTIN_CLASS };
107 }
108 ImmutableList.Builder<String> classesBuilder = ImmutableList.builder();
109 if (eObject instanceof ClassDeclaration classDeclaration) {
110 classesBuilder.add(CLASS_CLASS);
111 if (classDeclaration.isAbstract()) {
112 classesBuilder.add(ABSTRACT_CLASS);
113 }
114 }
115 if (eObject instanceof EnumDeclaration) {
116 classesBuilder.add(ENUM_CLASS);
117 }
118 if (eObject instanceof ReferenceDeclaration referenceDeclaration) {
119 classesBuilder.add(REFERENCE_CLASS);
120 if (referenceDeclaration.isContainment()) {
121 classesBuilder.add(CONTAINMENT_CLASS);
122 }
123 }
124 if (eObject instanceof PredicateDefinition predicateDefinition) {
125 classesBuilder.add(PREDICATE_CLASS);
126 if (predicateDefinition.isError()) {
127 classesBuilder.add(ERROR_CLASS);
128 }
129 }
130 if (eObject instanceof Node node) {
131 classesBuilder.add(NODE_CLASS);
132 if (ProblemUtil.isUniqueNode(node)) {
133 classesBuilder.add(UNIQUE_NODE_CLASS);
134 }
135 if (ProblemUtil.isNewNode(node)) {
136 classesBuilder.add(NEW_NODE_CLASS);
137 }
138 }
139 if (eObject instanceof Parameter) {
140 classesBuilder.add(PARAMETER_CLASS);
141 }
142 if (eObject instanceof Variable variable) {
143 classesBuilder.add(VARIABLE_CLASS);
144 if (ProblemUtil.isSingletonVariable(variable)) {
145 classesBuilder.add(SINGLETON_VARIABLE_CLASS);
146 }
147 }
148 List<String> classes = classesBuilder.build();
149 return classes.toArray(new String[0]);
150 }
151}