aboutsummaryrefslogtreecommitdiffstats
path: root/language
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-06-28 18:51:07 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-06-28 18:51:07 +0200
commit2ef7194ce2f36a04443c0eca032bab8daaf675a8 (patch)
tree17c6528e25b5657f78784eef3edc4a90338ba305 /language
parentFix real literals (diff)
downloadrefinery-2ef7194ce2f36a04443c0eca032bab8daaf675a8.tar.gz
refinery-2ef7194ce2f36a04443c0eca032bab8daaf675a8.tar.zst
refinery-2ef7194ce2f36a04443c0eca032bab8daaf675a8.zip
Fix derived state computer idempotency
Diffstat (limited to 'language')
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java83
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java2
-rw-r--r--language/src/test/java/org/eclipse/viatra/solver/language/tests/ProblemScopingTest.xtend1
3 files changed, 69 insertions, 17 deletions
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
index 56d8ad71..42e53534 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
@@ -1,13 +1,18 @@
1package org.eclipse.viatra.solver.language.resource; 1package org.eclipse.viatra.solver.language.resource;
2 2
3import java.util.HashMap;
3import java.util.HashSet; 4import java.util.HashSet;
4import java.util.List; 5import java.util.List;
6import java.util.Map;
5import java.util.Set; 7import java.util.Set;
6import java.util.function.Predicate; 8import java.util.function.Predicate;
7import java.util.regex.Pattern; 9import java.util.regex.Pattern;
8 10
11import org.eclipse.emf.common.notify.impl.AdapterImpl;
9import org.eclipse.emf.ecore.EObject; 12import org.eclipse.emf.ecore.EObject;
10import org.eclipse.emf.ecore.EStructuralFeature; 13import org.eclipse.emf.ecore.EStructuralFeature;
14import org.eclipse.emf.ecore.resource.Resource;
15import org.eclipse.emf.ecore.util.EcoreUtil;
11import org.eclipse.viatra.solver.language.ProblemUtil; 16import org.eclipse.viatra.solver.language.ProblemUtil;
12import org.eclipse.viatra.solver.language.model.problem.Argument; 17import org.eclipse.viatra.solver.language.model.problem.Argument;
13import org.eclipse.viatra.solver.language.model.problem.Assertion; 18import org.eclipse.viatra.solver.language.model.problem.Assertion;
@@ -29,6 +34,7 @@ import org.eclipse.viatra.solver.language.model.problem.ProblemFactory;
29import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; 34import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
30import org.eclipse.viatra.solver.language.model.problem.Statement; 35import org.eclipse.viatra.solver.language.model.problem.Statement;
31import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument; 36import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument;
37import org.eclipse.xtext.Constants;
32import org.eclipse.xtext.linking.impl.LinkingHelper; 38import org.eclipse.xtext.linking.impl.LinkingHelper;
33import org.eclipse.xtext.naming.IQualifiedNameConverter; 39import org.eclipse.xtext.naming.IQualifiedNameConverter;
34import org.eclipse.xtext.naming.QualifiedName; 40import org.eclipse.xtext.naming.QualifiedName;
@@ -36,6 +42,7 @@ import org.eclipse.xtext.nodemodel.INode;
36import org.eclipse.xtext.nodemodel.util.NodeModelUtils; 42import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
37import org.eclipse.xtext.resource.DerivedStateAwareResource; 43import org.eclipse.xtext.resource.DerivedStateAwareResource;
38import org.eclipse.xtext.resource.IDerivedStateComputer; 44import org.eclipse.xtext.resource.IDerivedStateComputer;
45import org.eclipse.xtext.resource.XtextResource;
39import org.eclipse.xtext.scoping.IScope; 46import org.eclipse.xtext.scoping.IScope;
40import org.eclipse.xtext.scoping.IScopeProvider; 47import org.eclipse.xtext.scoping.IScopeProvider;
41import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; 48import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
@@ -53,6 +60,10 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
53 private static final Pattern QUOTED_ID_REGEX = Pattern.compile("'(\\\\.|[^\\'])*'"); 60 private static final Pattern QUOTED_ID_REGEX = Pattern.compile("'(\\\\.|[^\\'])*'");
54 61
55 @Inject 62 @Inject
63 @Named(Constants.LANGUAGE_NAME)
64 private String languageName;
65
66 @Inject
56 private LinkingHelper linkingHelper; 67 private LinkingHelper linkingHelper;
57 68
58 @Inject 69 @Inject
@@ -64,15 +75,27 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
64 75
65 @Override 76 @Override
66 public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) { 77 public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) {
67 for (EObject object : resource.getContents()) { 78 Problem problem = getProblem(resource);
68 if (object instanceof Problem) { 79 if (problem != null) {
69 installDerivedProblemState((Problem) object, preLinkingPhase); 80 Adapter adapter = getOrInstallAdapter(resource);
70 } 81 installDerivedProblemState(problem, adapter, preLinkingPhase);
82 }
83 }
84
85 protected Problem getProblem(Resource resource) {
86 List<EObject> contents = resource.getContents();
87 if (contents.isEmpty()) {
88 return null;
89 }
90 EObject object = contents.get(0);
91 if (object instanceof Problem) {
92 return (Problem) object;
71 } 93 }
94 return null;
72 } 95 }
73 96
74 protected void installDerivedProblemState(Problem problem, boolean preLinkingPhase) { 97 protected void installDerivedProblemState(Problem problem, Adapter adapter, boolean preLinkingPhase) {
75 installNewNodes(problem); 98 installNewNodes(problem, adapter);
76 if (preLinkingPhase) { 99 if (preLinkingPhase) {
77 return; 100 return;
78 } 101 }
@@ -85,12 +108,12 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
85 } 108 }
86 } 109 }
87 110
88 protected void installNewNodes(Problem problem) { 111 protected void installNewNodes(Problem problem, Adapter adapter) {
89 for (Statement statement : problem.getStatements()) { 112 for (Statement statement : problem.getStatements()) {
90 if (statement instanceof ClassDeclaration) { 113 if (statement instanceof ClassDeclaration) {
91 ClassDeclaration declaration = (ClassDeclaration) statement; 114 ClassDeclaration declaration = (ClassDeclaration) statement;
92 if (!declaration.isAbstract() && declaration.getNewNode() == null) { 115 if (!declaration.isAbstract() && declaration.getNewNode() == null) {
93 Node newNode = createNode(NEW_NODE); 116 Node newNode = adapter.newNodes.computeIfAbsent(declaration, key -> createNode(NEW_NODE));
94 declaration.setNewNode(newNode); 117 declaration.setNewNode(newNode);
95 } 118 }
96 } 119 }
@@ -264,18 +287,22 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
264 287
265 @Override 288 @Override
266 public void discardDerivedState(DerivedStateAwareResource resource) { 289 public void discardDerivedState(DerivedStateAwareResource resource) {
267 for (EObject object : resource.getContents()) { 290 Problem problem = getProblem(resource);
268 if (object instanceof Problem) { 291 if (problem != null) {
269 discardDerivedProblemState((Problem) object); 292 Adapter adapter = getOrInstallAdapter(resource);
270 } 293 discardDerivedProblemState(problem, adapter);
271 } 294 }
272 } 295 }
273 296
274 protected void discardDerivedProblemState(Problem problem) { 297 protected void discardDerivedProblemState(Problem problem, Adapter adapter) {
298 Set<ClassDeclaration> classDeclarations = new HashSet<>();
275 problem.getNodes().clear(); 299 problem.getNodes().clear();
276 for (Statement statement : problem.getStatements()) { 300 for (Statement statement : problem.getStatements()) {
277 // We deliberately don't clean up {@link ClassDeclaration#getNewNode()} nodes, 301 if (statement instanceof ClassDeclaration) {
278 // because they have already been exported to the Xtext index. 302 ClassDeclaration classDeclaration = (ClassDeclaration) statement;
303 classDeclaration.setNewNode(null);
304 classDeclarations.add(classDeclaration);
305 }
279 if (statement instanceof PredicateDefinition) { 306 if (statement instanceof PredicateDefinition) {
280 PredicateDefinition definition = (PredicateDefinition) statement; 307 PredicateDefinition definition = (PredicateDefinition) statement;
281 for (Conjunction body : definition.getBodies()) { 308 for (Conjunction body : definition.getBodies()) {
@@ -293,6 +320,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
293 } 320 }
294 } 321 }
295 } 322 }
323 adapter.newNodes.keySet().retainAll(classDeclarations);
296 } 324 }
297 325
298 protected void discardDerivedAtomState(Atom atom) { 326 protected void discardDerivedAtomState(Atom atom) {
@@ -318,4 +346,29 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
318 protected static boolean validNodeName(String name) { 346 protected static boolean validNodeName(String name) {
319 return validId(name) || validQuotedId(name); 347 return validId(name) || validQuotedId(name);
320 } 348 }
349
350 public Adapter getOrInstallAdapter(Resource resource) {
351 if (!(resource instanceof XtextResource)) {
352 return new Adapter();
353 }
354 String resourceLanguageName = ((XtextResource) resource).getLanguageName();
355 if (!languageName.equals(resourceLanguageName)) {
356 return new Adapter();
357 }
358 Adapter adapter = (Adapter) EcoreUtil.getAdapter(resource.eAdapters(), Adapter.class);
359 if (adapter == null) {
360 adapter = new Adapter();
361 resource.eAdapters().add(adapter);
362 }
363 return adapter;
364 }
365
366 private static class Adapter extends AdapterImpl {
367 public Map<ClassDeclaration, Node> newNodes = new HashMap<>();
368
369 @Override
370 public boolean isAdapterForType(Object type) {
371 return Adapter.class == type;
372 }
373 }
321} 374}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
index 4d932a92..686e54df 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
@@ -87,7 +87,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
87 } 87 }
88 return true; 88 return true;
89 } 89 }
90 90
91 protected boolean shouldExportSimpleName(EObject eObject) { 91 protected boolean shouldExportSimpleName(EObject eObject) {
92 if (eObject instanceof Node) { 92 if (eObject instanceof Node) {
93 return !ProblemUtil.isNewNode((Node) eObject); 93 return !ProblemUtil.isNewNode((Node) eObject);
diff --git a/language/src/test/java/org/eclipse/viatra/solver/language/tests/ProblemScopingTest.xtend b/language/src/test/java/org/eclipse/viatra/solver/language/tests/ProblemScopingTest.xtend
index 7686e39e..7fc1c44d 100644
--- a/language/src/test/java/org/eclipse/viatra/solver/language/tests/ProblemScopingTest.xtend
+++ b/language/src/test/java/org/eclipse/viatra/solver/language/tests/ProblemScopingTest.xtend
@@ -109,7 +109,6 @@ class ProblemScopingTest {
109 assertThat(assertion(0).arg(0).node, equalTo(findClass('Foo').newNode)) 109 assertThat(assertion(0).arg(0).node, equalTo(findClass('Foo').newNode))
110 } 110 }
111 111
112
113 @Test 112 @Test
114 def void qualifiedClassNewNodeTest() { 113 def void qualifiedClassNewNodeTest() {
115 val it = parseHelper.parse(''' 114 val it = parseHelper.parse('''