diff options
author | 2021-06-26 22:12:19 +0200 | |
---|---|---|
committer | 2021-06-26 22:12:19 +0200 | |
commit | 86a21430ec40c5f44973ceab3815f52e73b93980 (patch) | |
tree | a5c1c7a33b1727903b322d293796db79baf9ecaf /org.eclipse.viatra.solver.language.parent | |
parent | FIx scoping, extend grammar (diff) | |
download | refinery-86a21430ec40c5f44973ceab3815f52e73b93980.tar.gz refinery-86a21430ec40c5f44973ceab3815f52e73b93980.tar.zst refinery-86a21430ec40c5f44973ceab3815f52e73b93980.zip |
Opposite reference scope
Diffstat (limited to 'org.eclipse.viatra.solver.language.parent')
2 files changed, 78 insertions, 1 deletions
diff --git a/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java b/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java index 0151e0c0..3e7d515f 100644 --- a/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java +++ b/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java | |||
@@ -1,17 +1,37 @@ | |||
1 | package org.eclipse.viatra.solver.language; | 1 | package org.eclipse.viatra.solver.language; |
2 | 2 | ||
3 | import java.util.ArrayDeque; | ||
4 | import java.util.Collection; | ||
5 | import java.util.Deque; | ||
6 | import java.util.HashSet; | ||
7 | import java.util.Optional; | ||
8 | import java.util.Set; | ||
9 | |||
10 | import org.eclipse.emf.ecore.EObject; | ||
11 | import org.eclipse.emf.ecore.resource.Resource; | ||
12 | import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration; | ||
3 | import org.eclipse.viatra.solver.language.model.problem.Node; | 13 | import org.eclipse.viatra.solver.language.model.problem.Node; |
14 | import org.eclipse.viatra.solver.language.model.problem.Problem; | ||
4 | import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; | 15 | import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; |
16 | import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration; | ||
5 | import org.eclipse.viatra.solver.language.model.problem.Variable; | 17 | import org.eclipse.viatra.solver.language.model.problem.Variable; |
18 | import org.eclipse.viatra.solver.language.scoping.ProblemGlobalScopeProvider; | ||
6 | 19 | ||
20 | import com.google.common.collect.ImmutableList; | ||
7 | import com.google.inject.Singleton; | 21 | import com.google.inject.Singleton; |
8 | 22 | ||
9 | @Singleton | 23 | @Singleton |
10 | public class ProblemUtil { | 24 | public final class ProblemUtil { |
25 | private ProblemUtil() { | ||
26 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | ||
27 | } | ||
28 | |||
11 | public static final String SINGLETON_VARIABLE_PREFIX = "_"; | 29 | public static final String SINGLETON_VARIABLE_PREFIX = "_"; |
12 | 30 | ||
13 | public static final String ENUM_NODE_NAME_QUOTE = "'"; | 31 | public static final String ENUM_NODE_NAME_QUOTE = "'"; |
14 | 32 | ||
33 | public static final String NODE_CLASS_NAME = "node"; | ||
34 | |||
15 | public static boolean isSingletonVariableName(String name) { | 35 | public static boolean isSingletonVariableName(String name) { |
16 | return name != null && name.startsWith(SINGLETON_VARIABLE_PREFIX); | 36 | return name != null && name.startsWith(SINGLETON_VARIABLE_PREFIX); |
17 | } | 37 | } |
@@ -28,4 +48,40 @@ public class ProblemUtil { | |||
28 | public static boolean isNewNode(Node node) { | 48 | public static boolean isNewNode(Node node) { |
29 | return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE; | 49 | return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE; |
30 | } | 50 | } |
51 | |||
52 | public static Optional<Problem> getBuiltInLibrary(EObject context) { | ||
53 | return Optional.ofNullable(context.eResource()).map(Resource::getResourceSet) | ||
54 | .map(resourceSet -> resourceSet.getResource(ProblemGlobalScopeProvider.BULTIN_LIBRARY_URI, true)) | ||
55 | .map(Resource::getContents).filter(contents -> !contents.isEmpty()).map(contents -> contents.get(0)) | ||
56 | .filter(Problem.class::isInstance).map(Problem.class::cast); | ||
57 | } | ||
58 | |||
59 | public static Optional<ClassDeclaration> getNodeClassDeclaration(EObject context) { | ||
60 | return getBuiltInLibrary(context).flatMap(problem -> problem.getStatements().stream() | ||
61 | .filter(ClassDeclaration.class::isInstance).map(ClassDeclaration.class::cast) | ||
62 | .filter(declaration -> NODE_CLASS_NAME.equals(declaration.getName())).findFirst()); | ||
63 | } | ||
64 | |||
65 | public static Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) { | ||
66 | Set<ClassDeclaration> found = new HashSet<>(); | ||
67 | getNodeClassDeclaration(classDeclaration).ifPresent(found::add); | ||
68 | Deque<ClassDeclaration> queue = new ArrayDeque<>(); | ||
69 | queue.addLast(classDeclaration); | ||
70 | while (!queue.isEmpty()) { | ||
71 | ClassDeclaration current = queue.removeFirst(); | ||
72 | if (!found.contains(current)) { | ||
73 | found.add(current); | ||
74 | queue.addAll(current.getSuperTypes()); | ||
75 | } | ||
76 | } | ||
77 | return found; | ||
78 | } | ||
79 | |||
80 | public static Collection<ReferenceDeclaration> getAllReferenceDeclarations(ClassDeclaration classDeclaration) { | ||
81 | ImmutableList.Builder<ReferenceDeclaration> builder = ImmutableList.builder(); | ||
82 | for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { | ||
83 | builder.addAll(superclass.getReferenceDeclarations()); | ||
84 | } | ||
85 | return builder.build(); | ||
86 | } | ||
31 | } | 87 | } |
diff --git a/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java b/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java index 1849e647..c639f24c 100644 --- a/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java +++ b/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java | |||
@@ -4,15 +4,20 @@ | |||
4 | package org.eclipse.viatra.solver.language.scoping; | 4 | package org.eclipse.viatra.solver.language.scoping; |
5 | 5 | ||
6 | import java.util.ArrayList; | 6 | import java.util.ArrayList; |
7 | import java.util.Collection; | ||
7 | import java.util.List; | 8 | import java.util.List; |
8 | 9 | ||
9 | import org.eclipse.emf.ecore.EObject; | 10 | import org.eclipse.emf.ecore.EObject; |
10 | import org.eclipse.emf.ecore.EReference; | 11 | import org.eclipse.emf.ecore.EReference; |
12 | import org.eclipse.viatra.solver.language.ProblemUtil; | ||
11 | import org.eclipse.viatra.solver.language.model.problem.Argument; | 13 | import org.eclipse.viatra.solver.language.model.problem.Argument; |
14 | import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration; | ||
12 | import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier; | 15 | import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier; |
13 | import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition; | 16 | import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition; |
14 | import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; | 17 | import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; |
18 | import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration; | ||
15 | import org.eclipse.viatra.solver.language.model.problem.Variable; | 19 | import org.eclipse.viatra.solver.language.model.problem.Variable; |
20 | import org.eclipse.xtext.EcoreUtil2; | ||
16 | import org.eclipse.xtext.scoping.IScope; | 21 | import org.eclipse.xtext.scoping.IScope; |
17 | import org.eclipse.xtext.scoping.Scopes; | 22 | import org.eclipse.xtext.scoping.Scopes; |
18 | 23 | ||
@@ -30,6 +35,8 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
30 | IScope scope = super.getScope(context, reference); | 35 | IScope scope = super.getScope(context, reference); |
31 | if (reference == ProblemPackage.Literals.ARGUMENT__VARIABLE) { | 36 | if (reference == ProblemPackage.Literals.ARGUMENT__VARIABLE) { |
32 | return getVariableScope(context, scope); | 37 | return getVariableScope(context, scope); |
38 | } else if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { | ||
39 | return getOppositeScope(context, scope); | ||
33 | } | 40 | } |
34 | return scope; | 41 | return scope; |
35 | } | 42 | } |
@@ -57,4 +64,18 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
57 | } | 64 | } |
58 | return Scopes.scopeFor(variables); | 65 | return Scopes.scopeFor(variables); |
59 | } | 66 | } |
67 | |||
68 | protected IScope getOppositeScope(EObject context, IScope delegateScope) { | ||
69 | ReferenceDeclaration referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class); | ||
70 | if (referenceDeclaration == null) { | ||
71 | return delegateScope; | ||
72 | } | ||
73 | ClassDeclaration classDeclaration = referenceDeclaration.getReferenceType(); | ||
74 | if (classDeclaration == null) { | ||
75 | return delegateScope; | ||
76 | } | ||
77 | Collection<ReferenceDeclaration> referenceDeclarations = ProblemUtil | ||
78 | .getAllReferenceDeclarations(classDeclaration); | ||
79 | return Scopes.scopeFor(referenceDeclarations, delegateScope); | ||
80 | } | ||
60 | } | 81 | } |