diff options
author | Kristóf Marussy <marussy@mit.bme.hu> | 2021-06-28 18:51:07 +0200 |
---|---|---|
committer | Kristóf Marussy <marussy@mit.bme.hu> | 2021-06-28 18:51:07 +0200 |
commit | 2ef7194ce2f36a04443c0eca032bab8daaf675a8 (patch) | |
tree | 17c6528e25b5657f78784eef3edc4a90338ba305 /language | |
parent | Fix real literals (diff) | |
download | refinery-2ef7194ce2f36a04443c0eca032bab8daaf675a8.tar.gz refinery-2ef7194ce2f36a04443c0eca032bab8daaf675a8.tar.zst refinery-2ef7194ce2f36a04443c0eca032bab8daaf675a8.zip |
Fix derived state computer idempotency
Diffstat (limited to 'language')
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 @@ | |||
1 | package org.eclipse.viatra.solver.language.resource; | 1 | package org.eclipse.viatra.solver.language.resource; |
2 | 2 | ||
3 | import java.util.HashMap; | ||
3 | import java.util.HashSet; | 4 | import java.util.HashSet; |
4 | import java.util.List; | 5 | import java.util.List; |
6 | import java.util.Map; | ||
5 | import java.util.Set; | 7 | import java.util.Set; |
6 | import java.util.function.Predicate; | 8 | import java.util.function.Predicate; |
7 | import java.util.regex.Pattern; | 9 | import java.util.regex.Pattern; |
8 | 10 | ||
11 | import org.eclipse.emf.common.notify.impl.AdapterImpl; | ||
9 | import org.eclipse.emf.ecore.EObject; | 12 | import org.eclipse.emf.ecore.EObject; |
10 | import org.eclipse.emf.ecore.EStructuralFeature; | 13 | import org.eclipse.emf.ecore.EStructuralFeature; |
14 | import org.eclipse.emf.ecore.resource.Resource; | ||
15 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
11 | import org.eclipse.viatra.solver.language.ProblemUtil; | 16 | import org.eclipse.viatra.solver.language.ProblemUtil; |
12 | import org.eclipse.viatra.solver.language.model.problem.Argument; | 17 | import org.eclipse.viatra.solver.language.model.problem.Argument; |
13 | import org.eclipse.viatra.solver.language.model.problem.Assertion; | 18 | import org.eclipse.viatra.solver.language.model.problem.Assertion; |
@@ -29,6 +34,7 @@ import org.eclipse.viatra.solver.language.model.problem.ProblemFactory; | |||
29 | import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; | 34 | import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; |
30 | import org.eclipse.viatra.solver.language.model.problem.Statement; | 35 | import org.eclipse.viatra.solver.language.model.problem.Statement; |
31 | import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument; | 36 | import org.eclipse.viatra.solver.language.model.problem.VariableOrNodeArgument; |
37 | import org.eclipse.xtext.Constants; | ||
32 | import org.eclipse.xtext.linking.impl.LinkingHelper; | 38 | import org.eclipse.xtext.linking.impl.LinkingHelper; |
33 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 39 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
34 | import org.eclipse.xtext.naming.QualifiedName; | 40 | import org.eclipse.xtext.naming.QualifiedName; |
@@ -36,6 +42,7 @@ import org.eclipse.xtext.nodemodel.INode; | |||
36 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | 42 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; |
37 | import org.eclipse.xtext.resource.DerivedStateAwareResource; | 43 | import org.eclipse.xtext.resource.DerivedStateAwareResource; |
38 | import org.eclipse.xtext.resource.IDerivedStateComputer; | 44 | import org.eclipse.xtext.resource.IDerivedStateComputer; |
45 | import org.eclipse.xtext.resource.XtextResource; | ||
39 | import org.eclipse.xtext.scoping.IScope; | 46 | import org.eclipse.xtext.scoping.IScope; |
40 | import org.eclipse.xtext.scoping.IScopeProvider; | 47 | import org.eclipse.xtext.scoping.IScopeProvider; |
41 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | 48 | import 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(''' |