aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-web/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-01-03 02:13:15 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-01-03 13:33:55 +0100
commit2fe65e414ff3194cdddde01bea6818bbab5290e9 (patch)
treea597343718059a2ee8727a296e817f997876f248 /subprojects/language-web/src
parentrefactor: matching node names in CLI and web (diff)
downloadrefinery-2fe65e414ff3194cdddde01bea6818bbab5290e9.tar.gz
refinery-2fe65e414ff3194cdddde01bea6818bbab5290e9.tar.zst
refinery-2fe65e414ff3194cdddde01bea6818bbab5290e9.zip
feat(web): color identifiers and nodes
We use a palette-based coloring strategy, where each class and enum gets a color from
Diffstat (limited to 'subprojects/language-web/src')
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java46
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadata.java4
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java89
3 files changed, 99 insertions, 40 deletions
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java
index 67ef82ce..f05abc45 100644
--- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java
@@ -13,9 +13,7 @@ import org.eclipse.xtext.naming.IQualifiedNameProvider;
13import org.eclipse.xtext.naming.QualifiedName; 13import org.eclipse.xtext.naming.QualifiedName;
14import org.eclipse.xtext.scoping.IScope; 14import org.eclipse.xtext.scoping.IScope;
15import org.eclipse.xtext.scoping.IScopeProvider; 15import org.eclipse.xtext.scoping.IScopeProvider;
16import org.jetbrains.annotations.NotNull;
17import tools.refinery.language.model.problem.*; 16import tools.refinery.language.model.problem.*;
18import tools.refinery.language.semantics.NodeNameProvider;
19import tools.refinery.language.semantics.ProblemTrace; 17import tools.refinery.language.semantics.ProblemTrace;
20import tools.refinery.language.semantics.TracedException; 18import tools.refinery.language.semantics.TracedException;
21import tools.refinery.language.utils.ProblemUtil; 19import tools.refinery.language.utils.ProblemUtil;
@@ -23,14 +21,11 @@ import tools.refinery.store.model.Model;
23import tools.refinery.store.reasoning.ReasoningAdapter; 21import tools.refinery.store.reasoning.ReasoningAdapter;
24import tools.refinery.store.reasoning.literal.Concreteness; 22import tools.refinery.store.reasoning.literal.Concreteness;
25import tools.refinery.store.reasoning.representation.PartialRelation; 23import tools.refinery.store.reasoning.representation.PartialRelation;
26import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchyTranslator;
27import tools.refinery.store.tuple.Tuple;
28 24
29import java.util.ArrayList; 25import java.util.ArrayList;
30import java.util.Collections; 26import java.util.Collections;
31import java.util.Comparator; 27import java.util.Comparator;
32import java.util.List; 28import java.util.List;
33import java.util.function.IntFunction;
34 29
35public class MetadataCreator { 30public class MetadataCreator {
36 @Inject 31 @Inject
@@ -43,7 +38,7 @@ public class MetadataCreator {
43 private IQualifiedNameConverter qualifiedNameConverter; 38 private IQualifiedNameConverter qualifiedNameConverter;
44 39
45 @Inject 40 @Inject
46 private Provider<NodeNameProvider> nodeNameProviderProvider; 41 private Provider<NodeMetadataFactory> nodeMetadataFactoryProvider;
47 42
48 private ProblemTrace problemTrace; 43 private ProblemTrace problemTrace;
49 private IScope nodeScope; 44 private IScope nodeScope;
@@ -63,56 +58,31 @@ public class MetadataCreator {
63 int nodeCount = model.getAdapter(ReasoningAdapter.class).getNodeCount(); 58 int nodeCount = model.getAdapter(ReasoningAdapter.class).getNodeCount();
64 var nodeTrace = problemTrace.getNodeTrace(); 59 var nodeTrace = problemTrace.getNodeTrace();
65 var nodes = new NodeMetadata[Math.max(nodeTrace.size(), nodeCount)]; 60 var nodes = new NodeMetadata[Math.max(nodeTrace.size(), nodeCount)];
66 var getName = makeGetName(model, concreteness); 61 var nodeMetadataFactory = nodeMetadataFactoryProvider.get();
62 nodeMetadataFactory.initialize(problemTrace, concreteness, model);
67 boolean preserveNewNodes = concreteness == Concreteness.PARTIAL; 63 boolean preserveNewNodes = concreteness == Concreteness.PARTIAL;
68 for (var entry : nodeTrace.keyValuesView()) { 64 for (var entry : nodeTrace.keyValuesView()) {
69 var node = entry.getOne(); 65 var node = entry.getOne();
70 var id = entry.getTwo(); 66 var id = entry.getTwo();
71 nodes[id] = getNodeMetadata(id, node, preserveNewNodes, getName); 67 nodes[id] = getNodeMetadata(id, node, preserveNewNodes, nodeMetadataFactory);
72 } 68 }
73 for (int i = 0; i < nodes.length; i++) { 69 for (int i = 0; i < nodes.length; i++) {
74 if (nodes[i] == null) { 70 if (nodes[i] == null) {
75 var nodeName = getName.apply(i); 71 nodes[i] = nodeMetadataFactory.createFreshlyNamedMetadata(i);
76 nodes[i] = new NodeMetadata(nodeName, nodeName, NodeKind.IMPLICIT);
77 } 72 }
78 } 73 }
79 return List.of(nodes); 74 return List.of(nodes);
80 } 75 }
81 76
82 @NotNull
83 private IntFunction<String> makeGetName(Model model, Concreteness concreteness) {
84 var nodeNameProvider = nodeNameProviderProvider.get();
85 nodeNameProvider.setProblem(problemTrace.getProblem());
86 var typeInterpretation = model.getInterpretation(TypeHierarchyTranslator.TYPE_SYMBOL);
87 var existsInterpretation = model.getAdapter(ReasoningAdapter.class).getPartialInterpretation(concreteness,
88 ReasoningAdapter.EXISTS_SYMBOL);
89 return nodeId -> {
90 var key = Tuple.of(nodeId);
91 var inferredType = typeInterpretation.get(key);
92 if (inferredType == null || inferredType.candidateType() == null) {
93 return nodeNameProvider.getNextName(null);
94 }
95 if (concreteness == Concreteness.CANDIDATE && !existsInterpretation.get(key).may()) {
96 // Do not increment the node name counter for non-existent nodes in the candidate interpretation.
97 // While non-existent nodes may appear in the partial interpretation, they are never displayed in the
98 // candidate interpretation.
99 return "::" + nodeId;
100 }
101 var relation = problemTrace.getRelation(inferredType.candidateType());
102 return nodeNameProvider.getNextName(relation.getName());
103 };
104 }
105
106 private NodeMetadata getNodeMetadata(int nodeId, Node node, boolean preserveNewNodes, 77 private NodeMetadata getNodeMetadata(int nodeId, Node node, boolean preserveNewNodes,
107 IntFunction<String> getName) { 78 NodeMetadataFactory nodeMetadataFactory) {
108 var kind = getNodeKind(node); 79 var kind = getNodeKind(node);
109 if (!preserveNewNodes && kind == NodeKind.NEW) { 80 if (!preserveNewNodes && kind == NodeKind.NEW) {
110 var nodeName = getName.apply(nodeId); 81 return nodeMetadataFactory.createFreshlyNamedMetadata(nodeId);
111 return new NodeMetadata(nodeName, nodeName, NodeKind.IMPLICIT);
112 } 82 }
113 var qualifiedName = getQualifiedName(node); 83 var qualifiedName = getQualifiedName(node);
114 var simpleName = getSimpleName(node, qualifiedName, nodeScope); 84 var simpleName = getSimpleName(node, qualifiedName, nodeScope);
115 return new NodeMetadata(qualifiedNameConverter.toString(qualifiedName), 85 return nodeMetadataFactory.doCreateMetadata(nodeId, qualifiedNameConverter.toString(qualifiedName),
116 qualifiedNameConverter.toString(simpleName), getNodeKind(node)); 86 qualifiedNameConverter.toString(simpleName), getNodeKind(node));
117 } 87 }
118 88
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadata.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadata.java
index 5da28acf..f3347eac 100644
--- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadata.java
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadata.java
@@ -1,9 +1,9 @@
1/* 1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> 2 * SPDX-FileCopyrightText: 2023-2023 The Refinery Authors <https://refinery.tools/>
3 * 3 *
4 * SPDX-License-Identifier: EPL-2.0 4 * SPDX-License-Identifier: EPL-2.0
5 */ 5 */
6package tools.refinery.language.web.semantics.metadata; 6package tools.refinery.language.web.semantics.metadata;
7 7
8public record NodeMetadata(String name, String simpleName, NodeKind kind) implements Metadata { 8public record NodeMetadata(String name, String simpleName, String typeHash, NodeKind kind) implements Metadata {
9} 9}
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java
new file mode 100644
index 00000000..ce0e50c1
--- /dev/null
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadataFactory.java
@@ -0,0 +1,89 @@
1/*
2 * SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.web.semantics.metadata;
7
8import com.google.inject.Inject;
9import tools.refinery.language.ide.syntaxcoloring.TypeHashProvider;
10import tools.refinery.language.semantics.NodeNameProvider;
11import tools.refinery.language.semantics.ProblemTrace;
12import tools.refinery.store.model.Interpretation;
13import tools.refinery.store.model.Model;
14import tools.refinery.store.reasoning.ReasoningAdapter;
15import tools.refinery.store.reasoning.interpretation.PartialInterpretation;
16import tools.refinery.store.reasoning.literal.Concreteness;
17import tools.refinery.store.reasoning.representation.PartialRelation;
18import tools.refinery.store.reasoning.translator.typehierarchy.InferredType;
19import tools.refinery.store.reasoning.translator.typehierarchy.TypeHierarchyTranslator;
20import tools.refinery.store.representation.TruthValue;
21import tools.refinery.store.tuple.Tuple;
22
23public class NodeMetadataFactory {
24 @Inject
25 private NodeNameProvider nodeNameProvider;
26
27 @Inject
28 private TypeHashProvider typeHashProvider;
29
30 private ProblemTrace problemTrace;
31 private Concreteness concreteness;
32 private Interpretation<InferredType> typeInterpretation;
33 private PartialInterpretation<TruthValue, Boolean> existsInterpretation;
34
35 public void initialize(ProblemTrace problemTrace, Concreteness concreteness, Model model) {
36 this.problemTrace = problemTrace;
37 this.concreteness = concreteness;
38 typeInterpretation = model.getInterpretation(TypeHierarchyTranslator.TYPE_SYMBOL);
39 existsInterpretation = model.getAdapter(ReasoningAdapter.class).getPartialInterpretation(concreteness,
40 ReasoningAdapter.EXISTS_SYMBOL);
41 nodeNameProvider.setProblem(problemTrace.getProblem());
42 }
43
44 public NodeMetadata doCreateMetadata(int nodeId, String name, String simpleName, NodeKind kind) {
45 var type = getType(nodeId);
46 return doCreateMetadata(name, simpleName, type, kind);
47 }
48
49 public NodeMetadata createFreshlyNamedMetadata(int nodeId) {
50 var type = getType(nodeId);
51 var name = getName(type, nodeId);
52 return doCreateMetadata(name, name, type, NodeKind.IMPLICIT);
53 }
54
55 private PartialRelation getType(int nodeId) {
56 var inferredType = typeInterpretation.get(Tuple.of(nodeId));
57 if (inferredType == null) {
58 return null;
59 }
60 return inferredType.candidateType();
61 }
62
63 private String getName(PartialRelation type, int nodeId) {
64 if (concreteness == Concreteness.CANDIDATE && !existsInterpretation.get(Tuple.of(nodeId)).may()) {
65 // Do not increment the node name counter for non-existent nodes in the candidate interpretation.
66 // While non-existent nodes may appear in the partial interpretation, they are never displayed in the
67 // candidate interpretation.
68 return "::" + nodeId;
69 }
70 if (type == null) {
71 return nodeNameProvider.getNextName(null);
72 }
73 var relation = problemTrace.getRelation(type);
74 return nodeNameProvider.getNextName(relation.getName());
75 }
76
77 private NodeMetadata doCreateMetadata(String name, String simpleName, PartialRelation type, NodeKind kind) {
78 var typeHash = getTypeHash(type);
79 return new NodeMetadata(name, simpleName, typeHash, kind);
80 }
81
82 private String getTypeHash(PartialRelation type) {
83 if (type == null) {
84 return null;
85 }
86 var relation = problemTrace.getRelation(type);
87 return typeHashProvider.getTypeHash(relation);
88 }
89}