1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
package tools.refinery.language.ide.syntaxcoloring;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.ide.editor.syntaxcoloring.DefaultSemanticHighlightingCalculator;
import org.eclipse.xtext.ide.editor.syntaxcoloring.IHighlightedPositionAcceptor;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.service.OperationCanceledManager;
import org.eclipse.xtext.util.CancelIndicator;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import tools.refinery.language.model.ProblemUtil;
import tools.refinery.language.model.problem.ClassDeclaration;
import tools.refinery.language.model.problem.NamedElement;
import tools.refinery.language.model.problem.Node;
import tools.refinery.language.model.problem.PredicateDefinition;
import tools.refinery.language.model.problem.ProblemPackage;
import tools.refinery.language.model.problem.ReferenceDeclaration;
public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighlightingCalculator {
private static final String BUILTIN_CLASS = "builtin";
private static final String ABSTRACT_CLASS = "abstract";
private static final String CONTAINMENT_CLASS = "containment";
private static final String ERROR_CLASS = "error";
private static final String NODE_CLASS = "node";
private static final String UNIQUE_NODE_CLASS = "unique";
private static final String NEW_NODE_CLASS = "new";
@Inject
private OperationCanceledManager operationCanceledManager;
@Override
protected boolean highlightElement(EObject object, IHighlightedPositionAcceptor acceptor,
CancelIndicator cancelIndicator) {
highlightName(object, acceptor);
highlightCrossReferences(object, acceptor, cancelIndicator);
return false;
}
protected void highlightName(EObject object, IHighlightedPositionAcceptor acceptor) {
if (!(object instanceof NamedElement)) {
return;
}
String[] highlightClass = getHighlightClass(object, null);
if (highlightClass.length > 0) {
highlightFeature(acceptor, object, ProblemPackage.Literals.NAMED_ELEMENT__NAME, highlightClass);
}
}
protected void highlightCrossReferences(EObject object, IHighlightedPositionAcceptor acceptor,
CancelIndicator cancelIndicator) {
for (EReference reference : object.eClass().getEAllReferences()) {
if (reference.isContainment()) {
continue;
}
operationCanceledManager.checkCanceled(cancelIndicator);
if (reference.isMany()) {
highlightManyValues(object, reference, acceptor);
} else {
highlightSingleValue(object, reference, acceptor);
}
}
}
protected void highlightSingleValue(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
EObject valueObj = (EObject) object.eGet(reference);
String[] highlightClass = getHighlightClass(valueObj, reference);
if (highlightClass.length > 0) {
highlightFeature(acceptor, object, reference, highlightClass);
}
}
protected void highlightManyValues(EObject object, EReference reference, IHighlightedPositionAcceptor acceptor) {
@SuppressWarnings("unchecked")
EList<? extends EObject> values = (EList<? extends EObject>) object.eGet(reference);
List<INode> nodes = NodeModelUtils.findNodesForFeature(object, reference);
int size = Math.min(values.size(), nodes.size());
for (var i = 0; i < size; i++) {
EObject valueInList = values.get(i);
INode node = nodes.get(i);
String[] highlightClass = getHighlightClass(valueInList, reference);
if (highlightClass.length > 0) {
highlightNode(acceptor, node, highlightClass);
}
}
}
protected String[] getHighlightClass(EObject eObject, EReference reference) {
if (ProblemUtil.isBuiltIn(eObject)) {
return new String[] { BUILTIN_CLASS };
}
ImmutableList.Builder<String> classesBuilder = ImmutableList.builder();
if (eObject instanceof ClassDeclaration classDeclaration) {
if (classDeclaration.isAbstract()) {
classesBuilder.add(ABSTRACT_CLASS);
}
}
if (eObject instanceof ReferenceDeclaration referenceDeclaration) {
if (referenceDeclaration.isContainment()) {
classesBuilder.add(CONTAINMENT_CLASS);
}
}
if (eObject instanceof PredicateDefinition predicateDefinition) {
if (predicateDefinition.isError()) {
classesBuilder.add(ERROR_CLASS);
}
}
if (eObject instanceof Node node) {
if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE) {
classesBuilder.add(NODE_CLASS);
}
if (ProblemUtil.isUniqueNode(node)) {
classesBuilder.add(UNIQUE_NODE_CLASS);
}
if (ProblemUtil.isNewNode(node)) {
classesBuilder.add(NEW_NODE_CLASS);
}
}
List<String> classes = classesBuilder.build();
return classes.toArray(new String[0]);
}
}
|