aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java')
-rw-r--r--subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java122
1 files changed, 122 insertions, 0 deletions
diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
new file mode 100644
index 00000000..01ac33f7
--- /dev/null
+++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
@@ -0,0 +1,122 @@
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.model.ProblemUtil;
19import tools.refinery.language.model.problem.ClassDeclaration;
20import tools.refinery.language.model.problem.NamedElement;
21import tools.refinery.language.model.problem.Node;
22import tools.refinery.language.model.problem.PredicateDefinition;
23import tools.refinery.language.model.problem.ProblemPackage;
24import tools.refinery.language.model.problem.ReferenceDeclaration;
25
26public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighlightingCalculator {
27 private static final String BUILTIN_CLASS = "builtin";
28 private static final String ABSTRACT_CLASS = "abstract";
29 private static final String CONTAINMENT_CLASS = "containment";
30 private static final String ERROR_CLASS = "error";
31 private static final String NODE_CLASS = "node";
32 private static final String INDIVIDUAL_NODE_CLASS = "individual";
33 private static final String NEW_NODE_CLASS = "new";
34
35 @Inject
36 private OperationCanceledManager operationCanceledManager;
37
38 @Override
39 protected boolean highlightElement(EObject object, IHighlightedPositionAcceptor acceptor,
40 CancelIndicator cancelIndicator) {
41 highlightName(object, acceptor);
42 highlightCrossReferences(object, acceptor, cancelIndicator);
43 return false;
44 }
45
46 protected void highlightName(EObject object, IHighlightedPositionAcceptor acceptor) {
47 if (!(object instanceof NamedElement)) {
48 return;
49 }
50 String[] highlightClass = getHighlightClass(object, null);
51 if (highlightClass.length > 0) {
52 highlightFeature(acceptor, object, ProblemPackage.Literals.NAMED_ELEMENT__NAME, highlightClass);
53 }
54 }
55
56 protected void highlightCrossReferences(EObject object, IHighlightedPositionAcceptor acceptor,
57 CancelIndicator cancelIndicator) {
58 for (EReference reference : object.eClass().getEAllReferences()) {
59 if (reference.isContainment()) {
60 continue;
61 }
62 operationCanceledManager.checkCanceled(cancelIndicator);
63 if (reference.isMany()) {
64 highlightManyValues(object, reference, acceptor);
65 } else {
66 highlightSingleValue(object, reference, acceptor);
67 }
68 }
69 }
70
71 protected void highlightSingleValue(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
72 EObject valueObj = (EObject) object.eGet(reference);
73 String[] highlightClass = getHighlightClass(valueObj, reference);
74 if (highlightClass.length > 0) {
75 highlightFeature(acceptor, object, reference, highlightClass);
76 }
77 }
78
79 protected void highlightManyValues(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
80 @SuppressWarnings("unchecked")
81 EList<? extends EObject> values = (EList<? extends EObject>) object.eGet(reference);
82 List<INode> nodes = NodeModelUtils.findNodesForFeature(object, reference);
83 int size = Math.min(values.size(), nodes.size());
84 for (var i = 0; i < size; i++) {
85 EObject valueInList = values.get(i);
86 INode node = nodes.get(i);
87 String[] highlightClass = getHighlightClass(valueInList, reference);
88 if (highlightClass.length > 0) {
89 highlightNode(acceptor, node, highlightClass);
90 }
91 }
92 }
93
94 protected String[] getHighlightClass(EObject eObject, EReference reference) {
95 if (ProblemUtil.isBuiltIn(eObject)) {
96 return new String[] { BUILTIN_CLASS };
97 }
98 ImmutableList.Builder<String> classesBuilder = ImmutableList.builder();
99 if (eObject instanceof ClassDeclaration classDeclaration && classDeclaration.isAbstract()) {
100 classesBuilder.add(ABSTRACT_CLASS);
101 }
102 if (eObject instanceof ReferenceDeclaration referenceDeclaration && referenceDeclaration.isContainment()) {
103 classesBuilder.add(CONTAINMENT_CLASS);
104 }
105 if (eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError()) {
106 classesBuilder.add(ERROR_CLASS);
107 }
108 if (eObject instanceof Node node) {
109 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE) {
110 classesBuilder.add(NODE_CLASS);
111 }
112 if (ProblemUtil.isIndividualNode(node)) {
113 classesBuilder.add(INDIVIDUAL_NODE_CLASS);
114 }
115 if (ProblemUtil.isNewNode(node)) {
116 classesBuilder.add(NEW_NODE_CLASS);
117 }
118 }
119 List<String> classes = classesBuilder.build();
120 return classes.toArray(new String[0]);
121 }
122}