diff options
Diffstat (limited to 'subprojects/language/src/main/java/tools/refinery/language/resource')
10 files changed, 292 insertions, 23 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/LoadOnDemandResourceDescriptionProvider.java b/subprojects/language/src/main/java/tools/refinery/language/resource/LoadOnDemandResourceDescriptionProvider.java new file mode 100644 index 00000000..ccadb42d --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/LoadOnDemandResourceDescriptionProvider.java | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.language.resource; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import org.eclipse.emf.common.util.URI; | ||
10 | import org.eclipse.emf.ecore.resource.Resource; | ||
11 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
12 | import org.eclipse.xtext.EcoreUtil2; | ||
13 | import org.eclipse.xtext.resource.IResourceDescription; | ||
14 | import org.eclipse.xtext.resource.IResourceDescriptions; | ||
15 | import org.eclipse.xtext.resource.IResourceDescriptionsProvider; | ||
16 | import org.eclipse.xtext.scoping.impl.GlobalResourceDescriptionProvider; | ||
17 | |||
18 | public class LoadOnDemandResourceDescriptionProvider { | ||
19 | @Inject | ||
20 | private IResourceDescriptionsProvider resourceDescriptionsProvider; | ||
21 | |||
22 | @Inject | ||
23 | private GlobalResourceDescriptionProvider globalResourceDescriptionProvider; | ||
24 | |||
25 | private Resource context; | ||
26 | private IResourceDescriptions resourceDescriptions; | ||
27 | |||
28 | public void setContext(Resource context) { | ||
29 | if (this.context != null) { | ||
30 | throw new IllegalStateException("Context was already set"); | ||
31 | } | ||
32 | this.context = context; | ||
33 | resourceDescriptions = resourceDescriptionsProvider.getResourceDescriptions(context.getResourceSet()); | ||
34 | } | ||
35 | |||
36 | public IResourceDescription getResourceDescription(URI uri) { | ||
37 | if (this.context == null) { | ||
38 | throw new IllegalStateException("Context was not set"); | ||
39 | } | ||
40 | var resourceDescription = resourceDescriptions.getResourceDescription(uri); | ||
41 | if (resourceDescription != null) { | ||
42 | return resourceDescription; | ||
43 | } | ||
44 | var importedResource = EcoreUtil2.getResource(context, uri.toString()); | ||
45 | if (importedResource == null) { | ||
46 | return null; | ||
47 | } | ||
48 | // Force the {@code importedResource} to have all of its derived resource state installed. | ||
49 | EcoreUtil.resolveAll(importedResource); | ||
50 | return globalResourceDescriptionProvider.getResourceDescription(importedResource); | ||
51 | } | ||
52 | } | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java index 29eaad84..c81431e5 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java | |||
@@ -25,10 +25,10 @@ public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider | |||
25 | } | 25 | } |
26 | 26 | ||
27 | protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) { | 27 | protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) { |
28 | if (ProblemUtil.isIndividualNode(node)) { | 28 | if (ProblemUtil.isDeclaredNode(node)) { |
29 | return super.doGetTextRegion(node, query); | 29 | return super.doGetTextRegion(node, query); |
30 | } | 30 | } |
31 | if (ProblemUtil.isNewNode(node)) { | 31 | if (ProblemUtil.isMultiNode(node)) { |
32 | EObject container = node.eContainer(); | 32 | EObject container = node.eContainer(); |
33 | return doGetTextRegion(container, query); | 33 | return doGetTextRegion(container, query); |
34 | } | 34 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResource.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResource.java index 43239ffe..440a238e 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResource.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResource.java | |||
@@ -20,9 +20,12 @@ import org.eclipse.xtext.linking.impl.IllegalNodeException; | |||
20 | import org.eclipse.xtext.linking.impl.XtextLinkingDiagnostic; | 20 | import org.eclipse.xtext.linking.impl.XtextLinkingDiagnostic; |
21 | import org.eclipse.xtext.linking.lazy.LazyLinkingResource; | 21 | import org.eclipse.xtext.linking.lazy.LazyLinkingResource; |
22 | import org.eclipse.xtext.nodemodel.INode; | 22 | import org.eclipse.xtext.nodemodel.INode; |
23 | import org.eclipse.xtext.parser.IParseResult; | ||
23 | import org.eclipse.xtext.resource.DerivedStateAwareResource; | 24 | import org.eclipse.xtext.resource.DerivedStateAwareResource; |
24 | import org.eclipse.xtext.util.Triple; | 25 | import org.eclipse.xtext.util.Triple; |
25 | import org.jetbrains.annotations.Nullable; | 26 | import org.jetbrains.annotations.Nullable; |
27 | import tools.refinery.language.model.problem.Problem; | ||
28 | import tools.refinery.language.utils.ProblemUtil; | ||
26 | 29 | ||
27 | import java.util.Arrays; | 30 | import java.util.Arrays; |
28 | import java.util.List; | 31 | import java.util.List; |
@@ -40,6 +43,30 @@ public class ProblemResource extends DerivedStateAwareResource { | |||
40 | */ | 43 | */ |
41 | private int cyclicLinkingDetectionCounter = 0; | 44 | private int cyclicLinkingDetectionCounter = 0; |
42 | 45 | ||
46 | @Override | ||
47 | protected void updateInternalState(IParseResult oldParseResult, IParseResult newParseResult) { | ||
48 | if (isNewRootElement(oldParseResult, newParseResult) && | ||
49 | newParseResult.getRootASTElement() instanceof Problem newRootProblem && | ||
50 | !newRootProblem.isExplicitKind()) { | ||
51 | // Post-process the parsed model to set its URI-dependent module kind. | ||
52 | // We can't set the default module kind in {@link tools.refinery.language.serializer | ||
53 | // .ProblemTransientValueService}, because the {@link Problem} does not get added into the EMF resource | ||
54 | // before parsing is fully completed. | ||
55 | var defaultModuleKind = ProblemUtil.getDefaultModuleKind(getURI()); | ||
56 | newRootProblem.setKind(defaultModuleKind); | ||
57 | } | ||
58 | super.updateInternalState(oldParseResult, newParseResult); | ||
59 | } | ||
60 | |||
61 | private boolean isNewRootElement(IParseResult oldParseResult, IParseResult newParseResult) { | ||
62 | if (oldParseResult == null) { | ||
63 | return true; | ||
64 | } | ||
65 | var oldRootAstElement = oldParseResult.getRootASTElement(); | ||
66 | var newRootAstElement = newParseResult.getRootASTElement(); | ||
67 | return oldRootAstElement != newRootAstElement; | ||
68 | } | ||
69 | |||
43 | /** | 70 | /** |
44 | * Tries to resolve a reference and emits a diagnostic if the reference is unresolvable or ambiguous. | 71 | * Tries to resolve a reference and emits a diagnostic if the reference is unresolvable or ambiguous. |
45 | * <p> | 72 | * <p> |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescription.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescription.java new file mode 100644 index 00000000..498a7c57 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescription.java | |||
@@ -0,0 +1,106 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2009, 2011 itemis AG (http://www.itemis.eu) and others. | ||
3 | * Copyright (c) 2024 The Refinery Authors <https://refinery.tools/> | ||
4 | * This program and the accompanying materials are made available under the | ||
5 | * terms of the Eclipse Public License 2.0 which is available at | ||
6 | * http://www.eclipse.org/legal/epl-2.0. | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | package tools.refinery.language.resource; | ||
10 | |||
11 | import org.apache.log4j.Logger; | ||
12 | import org.eclipse.emf.common.util.TreeIterator; | ||
13 | import org.eclipse.emf.ecore.EObject; | ||
14 | import org.eclipse.emf.ecore.resource.Resource; | ||
15 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
16 | import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; | ||
17 | import org.eclipse.xtext.resource.IEObjectDescription; | ||
18 | import org.eclipse.xtext.resource.impl.DefaultResourceDescription; | ||
19 | import org.eclipse.xtext.resource.impl.EObjectDescriptionLookUp; | ||
20 | import org.eclipse.xtext.util.IAcceptor; | ||
21 | import tools.refinery.language.naming.NamingUtil; | ||
22 | |||
23 | import java.io.IOException; | ||
24 | import java.util.*; | ||
25 | |||
26 | /** | ||
27 | * A resource description that takes {@link ProblemResourceDescriptionStrategy#SHADOWING_KEY} into account when | ||
28 | * describing EObjects. | ||
29 | * <p> | ||
30 | * Based on {@link DefaultResourceDescription}. | ||
31 | */ | ||
32 | public class ProblemResourceDescription extends DefaultResourceDescription { | ||
33 | private static final Logger log = Logger.getLogger(ProblemResourceDescription.class); | ||
34 | |||
35 | private final IDefaultResourceDescriptionStrategy strategy; | ||
36 | |||
37 | public ProblemResourceDescription(Resource resource, IDefaultResourceDescriptionStrategy strategy) { | ||
38 | super(resource, strategy); | ||
39 | this.strategy = strategy; | ||
40 | } | ||
41 | |||
42 | /** | ||
43 | * Based on {@link DefaultResourceDescription#computeExportedObjects()}. | ||
44 | * | ||
45 | * @return The computed exported objects, taking shadowing into account. | ||
46 | */ | ||
47 | @Override | ||
48 | protected List<IEObjectDescription> computeExportedObjects() { | ||
49 | if (!getResource().isLoaded()) { | ||
50 | try { | ||
51 | getResource().load(null); | ||
52 | } catch (IOException e) { | ||
53 | log.error(e.getMessage(), e); | ||
54 | return Collections.emptyList(); | ||
55 | } | ||
56 | } | ||
57 | final Map<ProblemResourceDescriptionStrategy.ShadowingKey, List<IEObjectDescription>> nameToDescriptionsMap = | ||
58 | new LinkedHashMap<>(); | ||
59 | IAcceptor<IEObjectDescription> acceptor = eObjectDescription -> { | ||
60 | var key = ProblemResourceDescriptionStrategy.getShadowingKey(eObjectDescription); | ||
61 | var descriptions = nameToDescriptionsMap.computeIfAbsent(key, ignored -> new ArrayList<>()); | ||
62 | descriptions.add(eObjectDescription); | ||
63 | }; | ||
64 | TreeIterator<EObject> allProperContents = EcoreUtil.getAllProperContents(getResource(), false); | ||
65 | while (allProperContents.hasNext()) { | ||
66 | EObject content = allProperContents.next(); | ||
67 | if (!strategy.createEObjectDescriptions(content, acceptor)) { | ||
68 | allProperContents.prune(); | ||
69 | } | ||
70 | } | ||
71 | return omitShadowedNames(nameToDescriptionsMap); | ||
72 | } | ||
73 | |||
74 | private static List<IEObjectDescription> omitShadowedNames( | ||
75 | Map<ProblemResourceDescriptionStrategy.ShadowingKey, List<IEObjectDescription>> nameToDescriptionsMap) { | ||
76 | final List<IEObjectDescription> exportedEObjects = new ArrayList<>(); | ||
77 | for (var entry : nameToDescriptionsMap.entrySet()) { | ||
78 | var descriptions = entry.getValue(); | ||
79 | if (NamingUtil.isFullyQualified(entry.getKey().name())) { | ||
80 | exportedEObjects.addAll(descriptions); | ||
81 | } else { | ||
82 | boolean foundPreferred = false; | ||
83 | for (var description : descriptions) { | ||
84 | if (ProblemResourceDescriptionStrategy.PREFERRED_NAME_TRUE.equals( | ||
85 | description.getUserData(ProblemResourceDescriptionStrategy.PREFERRED_NAME))) { | ||
86 | exportedEObjects.add(description); | ||
87 | foundPreferred = true; | ||
88 | } | ||
89 | } | ||
90 | if (!foundPreferred) { | ||
91 | exportedEObjects.addAll(descriptions); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | return exportedEObjects; | ||
96 | } | ||
97 | |||
98 | // Based on {@code DerivedStateAwareResourceDescriptionManager#createResourceDescription}. | ||
99 | @Override | ||
100 | protected EObjectDescriptionLookUp getLookUp() { | ||
101 | if (lookup == null) { | ||
102 | lookup = new EObjectDescriptionLookUp(computeExportedObjects()); | ||
103 | } | ||
104 | return lookup; | ||
105 | } | ||
106 | } | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionManager.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionManager.java new file mode 100644 index 00000000..23ca139a --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionManager.java | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.language.resource; | ||
7 | |||
8 | import org.eclipse.emf.ecore.resource.Resource; | ||
9 | import org.eclipse.xtext.resource.DerivedStateAwareResourceDescriptionManager; | ||
10 | import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; | ||
11 | import org.eclipse.xtext.resource.IResourceDescription; | ||
12 | |||
13 | public class ProblemResourceDescriptionManager extends DerivedStateAwareResourceDescriptionManager { | ||
14 | @Override | ||
15 | protected IResourceDescription createResourceDescription(Resource resource, | ||
16 | IDefaultResourceDescriptionStrategy strategy) { | ||
17 | return new ProblemResourceDescription(resource, strategy); | ||
18 | } | ||
19 | } | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java index c04c7d09..3080a78e 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java | |||
@@ -8,44 +8,70 @@ package tools.refinery.language.resource; | |||
8 | import com.google.common.collect.ImmutableMap; | 8 | import com.google.common.collect.ImmutableMap; |
9 | import com.google.inject.Inject; | 9 | import com.google.inject.Inject; |
10 | import com.google.inject.Singleton; | 10 | import com.google.inject.Singleton; |
11 | import com.google.inject.name.Named; | ||
11 | import org.eclipse.emf.ecore.EObject; | 12 | import org.eclipse.emf.ecore.EObject; |
12 | import org.eclipse.xtext.EcoreUtil2; | 13 | import org.eclipse.xtext.EcoreUtil2; |
13 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 14 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
15 | import org.eclipse.xtext.naming.IQualifiedNameProvider; | ||
14 | import org.eclipse.xtext.naming.QualifiedName; | 16 | import org.eclipse.xtext.naming.QualifiedName; |
15 | import org.eclipse.xtext.resource.EObjectDescription; | 17 | import org.eclipse.xtext.resource.EObjectDescription; |
16 | import org.eclipse.xtext.resource.IEObjectDescription; | 18 | import org.eclipse.xtext.resource.IEObjectDescription; |
17 | import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy; | 19 | import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy; |
18 | import org.eclipse.xtext.util.IAcceptor; | 20 | import org.eclipse.xtext.util.IAcceptor; |
21 | import tools.refinery.language.naming.ProblemQualifiedNameProvider; | ||
22 | import tools.refinery.language.scoping.imports.ImportCollector; | ||
19 | import tools.refinery.language.model.problem.*; | 23 | import tools.refinery.language.model.problem.*; |
20 | import tools.refinery.language.naming.NamingUtil; | 24 | import tools.refinery.language.naming.NamingUtil; |
21 | import tools.refinery.language.utils.ProblemUtil; | 25 | import tools.refinery.language.utils.ProblemUtil; |
22 | 26 | ||
23 | import java.util.Map; | 27 | import java.util.Map; |
28 | import java.util.stream.Collectors; | ||
24 | 29 | ||
25 | @Singleton | 30 | @Singleton |
26 | public class ProblemResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { | 31 | public class ProblemResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { |
27 | private static final String DATA_PREFIX = "tools.refinery.language.resource.ProblemResourceDescriptionStrategy."; | 32 | private static final String DATA_PREFIX = "tools.refinery.language.resource.ProblemResourceDescriptionStrategy."; |
33 | |||
28 | public static final String ARITY = DATA_PREFIX + "ARITY"; | 34 | public static final String ARITY = DATA_PREFIX + "ARITY"; |
29 | public static final String ERROR_PREDICATE = DATA_PREFIX + "ERROR_PREDICATE"; | 35 | public static final String ERROR_PREDICATE = DATA_PREFIX + "ERROR_PREDICATE"; |
30 | public static final String ERROR_PREDICATE_TRUE = "true"; | 36 | public static final String ERROR_PREDICATE_TRUE = "true"; |
37 | public static final String SHADOWING_KEY = DATA_PREFIX + "SHADOWING_KEY"; | ||
38 | public static final String SHADOWING_KEY_PROBLEM = "problem"; | ||
39 | public static final String SHADOWING_KEY_NODE = "node"; | ||
40 | public static final String SHADOWING_KEY_RELATION = "relation"; | ||
41 | public static final String PREFERRED_NAME = DATA_PREFIX + "PREFERRED_NAME"; | ||
42 | public static final String PREFERRED_NAME_TRUE = "true"; | ||
43 | public static final String IMPORTS = DATA_PREFIX + "IMPORTS"; | ||
44 | public static final String IMPORTS_SEPARATOR = "|"; | ||
45 | public static final String MODULE_KIND = DATA_PREFIX + "MODULE_KIND"; | ||
31 | public static final String COLOR_RELATION = DATA_PREFIX + "COLOR_RELATION"; | 46 | public static final String COLOR_RELATION = DATA_PREFIX + "COLOR_RELATION"; |
32 | public static final String COLOR_RELATION_TRUE = "true"; | 47 | public static final String COLOR_RELATION_TRUE = "true"; |
33 | 48 | ||
34 | @Inject | 49 | @Inject |
35 | private IQualifiedNameConverter qualifiedNameConverter; | 50 | private IQualifiedNameConverter qualifiedNameConverter; |
36 | 51 | ||
52 | @Inject | ||
53 | @Named(ProblemQualifiedNameProvider.NAMED_DELEGATE) | ||
54 | private IQualifiedNameProvider delegateQualifiedNameProvider; | ||
55 | |||
56 | @Inject | ||
57 | private ImportCollector importCollector; | ||
58 | |||
37 | @Override | 59 | @Override |
38 | public boolean createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) { | 60 | public boolean createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) { |
39 | if (!shouldExport(eObject)) { | 61 | if (!shouldExport(eObject)) { |
40 | return false; | 62 | return false; |
41 | } | 63 | } |
64 | var problem = EcoreUtil2.getContainerOfType(eObject, Problem.class); | ||
65 | var problemQualifiedName = getProblemQualifiedName(problem); | ||
66 | var userData = getUserData(eObject); | ||
67 | if (eObject.equals(problem)) { | ||
68 | acceptEObjectDescription(eObject, problemQualifiedName, QualifiedName.EMPTY, userData, true, acceptor); | ||
69 | return true; | ||
70 | } | ||
42 | var qualifiedName = getNameAsQualifiedName(eObject); | 71 | var qualifiedName = getNameAsQualifiedName(eObject); |
43 | if (qualifiedName == null) { | 72 | if (qualifiedName == null) { |
44 | return true; | 73 | return true; |
45 | } | 74 | } |
46 | var problem = EcoreUtil2.getContainerOfType(eObject, Problem.class); | ||
47 | var problemQualifiedName = getNameAsQualifiedName(problem); | ||
48 | var userData = getUserData(eObject); | ||
49 | QualifiedName lastQualifiedNameToExport = null; | 75 | QualifiedName lastQualifiedNameToExport = null; |
50 | if (shouldExportSimpleName(eObject)) { | 76 | if (shouldExportSimpleName(eObject)) { |
51 | lastQualifiedNameToExport = qualifiedName; | 77 | lastQualifiedNameToExport = qualifiedName; |
@@ -82,24 +108,46 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
82 | if (NamingUtil.isNullOrEmpty(name)) { | 108 | if (NamingUtil.isNullOrEmpty(name)) { |
83 | return null; | 109 | return null; |
84 | } | 110 | } |
85 | return qualifiedNameConverter.toQualifiedName(name); | 111 | var qualifiedName = qualifiedNameConverter.toQualifiedName(name); |
112 | if (eObject instanceof Problem) { | ||
113 | return NamingUtil.stripRootPrefix(qualifiedName); | ||
114 | } | ||
115 | return qualifiedName; | ||
86 | } | 116 | } |
87 | 117 | ||
88 | protected boolean shouldExport(EObject eObject) { | 118 | protected QualifiedName getProblemQualifiedName(Problem problem) { |
119 | if (problem == null) { | ||
120 | return QualifiedName.EMPTY; | ||
121 | } | ||
122 | var qualifiedName = delegateQualifiedNameProvider.getFullyQualifiedName(problem); | ||
123 | return qualifiedName == null ? QualifiedName.EMPTY : qualifiedName; | ||
124 | } | ||
125 | |||
126 | public static boolean shouldExport(EObject eObject) { | ||
89 | if (eObject instanceof Variable) { | 127 | if (eObject instanceof Variable) { |
90 | // Variables are always private to the containing predicate definition. | 128 | // Variables are always private to the containing predicate definition. |
91 | return false; | 129 | return false; |
92 | } | 130 | } |
93 | if (eObject instanceof Node node) { | 131 | if (eObject instanceof Node node) { |
94 | // Only enum literals and new nodes are visible across problem files. | 132 | return !ProblemUtil.isImplicitNode(node); |
95 | return ProblemUtil.isIndividualNode(node) || ProblemUtil.isNewNode(node); | ||
96 | } | 133 | } |
97 | return true; | 134 | return true; |
98 | } | 135 | } |
99 | 136 | ||
100 | protected Map<String, String> getUserData(EObject eObject) { | 137 | protected Map<String, String> getUserData(EObject eObject) { |
101 | var builder = ImmutableMap.<String, String>builder(); | 138 | var builder = ImmutableMap.<String, String>builder(); |
102 | if (eObject instanceof Relation relation) { | 139 | if (eObject instanceof Problem problem) { |
140 | builder.put(SHADOWING_KEY, SHADOWING_KEY_PROBLEM); | ||
141 | var explicitImports = importCollector.getDirectImports(eObject.eResource()); | ||
142 | var importsString = explicitImports.toList().stream() | ||
143 | .map(importEntry -> importEntry.uri().toString()) | ||
144 | .collect(Collectors.joining(IMPORTS_SEPARATOR)); | ||
145 | builder.put(IMPORTS, importsString); | ||
146 | builder.put(MODULE_KIND, problem.getKind().getName()); | ||
147 | } else if (eObject instanceof Node) { | ||
148 | builder.put(SHADOWING_KEY, SHADOWING_KEY_NODE); | ||
149 | } else if (eObject instanceof Relation relation) { | ||
150 | builder.put(SHADOWING_KEY, SHADOWING_KEY_RELATION); | ||
103 | int arity = ProblemUtil.getArity(relation); | 151 | int arity = ProblemUtil.getArity(relation); |
104 | builder.put(ARITY, Integer.toString(arity)); | 152 | builder.put(ARITY, Integer.toString(arity)); |
105 | } | 153 | } |
@@ -111,7 +159,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
111 | 159 | ||
112 | protected boolean shouldExportSimpleName(EObject eObject) { | 160 | protected boolean shouldExportSimpleName(EObject eObject) { |
113 | if (eObject instanceof Node node) { | 161 | if (eObject instanceof Node node) { |
114 | return !ProblemUtil.isNewNode(node); | 162 | return !ProblemUtil.isMultiNode(node); |
115 | } | 163 | } |
116 | if (eObject instanceof PredicateDefinition predicateDefinition) { | 164 | if (eObject instanceof PredicateDefinition predicateDefinition) { |
117 | return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition); | 165 | return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition); |
@@ -125,20 +173,31 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
125 | } | 173 | } |
126 | 174 | ||
127 | private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName, | 175 | private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName, |
128 | Map<String, String> userData, boolean fullyQualified, | 176 | Map<String, String> userData, boolean preferredName, |
129 | IAcceptor<IEObjectDescription> acceptor) { | 177 | IAcceptor<IEObjectDescription> acceptor) { |
130 | var qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName); | 178 | var qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName); |
131 | Map<String, String> userDataWithFullyQualified; | 179 | var userDataWithPreference = userData; |
132 | if (fullyQualified && shouldColorRelation(eObject)) { | 180 | if (preferredName) { |
133 | userDataWithFullyQualified = ImmutableMap.<String, String>builder() | 181 | userDataWithPreference = ImmutableMap.<String, String>builder() |
134 | .putAll(userData) | 182 | .putAll(userData) |
135 | .put(COLOR_RELATION, COLOR_RELATION_TRUE) | 183 | .put(PREFERRED_NAME, PREFERRED_NAME_TRUE) |
136 | .build(); | 184 | .build(); |
137 | } else { | ||
138 | userDataWithFullyQualified = userData; | ||
139 | } | 185 | } |
140 | var description = EObjectDescription.create(qualifiedNameWithPrefix, eObject, userDataWithFullyQualified); | 186 | var description = EObjectDescription.create(qualifiedNameWithPrefix, eObject, userDataWithPreference); |
141 | acceptor.accept(description); | 187 | acceptor.accept(description); |
188 | if (!preferredName) { | ||
189 | return; | ||
190 | } | ||
191 | var userDataWithFullyQualified = userDataWithPreference; | ||
192 | if (shouldColorRelation(eObject)) { | ||
193 | userDataWithFullyQualified = ImmutableMap.<String, String>builder() | ||
194 | .putAll(userDataWithPreference) | ||
195 | .put(COLOR_RELATION, COLOR_RELATION_TRUE) | ||
196 | .build(); | ||
197 | } | ||
198 | var rootQualifiedName = NamingUtil.addRootPrefix(qualifiedNameWithPrefix); | ||
199 | var rootDescription = EObjectDescription.create(rootQualifiedName, eObject, userDataWithFullyQualified); | ||
200 | acceptor.accept(rootDescription); | ||
142 | } | 201 | } |
143 | 202 | ||
144 | private boolean shouldColorRelation(EObject eObject) { | 203 | private boolean shouldColorRelation(EObject eObject) { |
@@ -146,6 +205,12 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
146 | return false; | 205 | return false; |
147 | } | 206 | } |
148 | return eObject instanceof ClassDeclaration || eObject instanceof EnumDeclaration; | 207 | return eObject instanceof ClassDeclaration || eObject instanceof EnumDeclaration; |
208 | } | ||
209 | |||
210 | public static ShadowingKey getShadowingKey(IEObjectDescription description) { | ||
211 | return new ShadowingKey(description.getName(), description.getUserData(SHADOWING_KEY)); | ||
212 | } | ||
149 | 213 | ||
214 | public record ShadowingKey(QualifiedName name, String shadowingKey) { | ||
150 | } | 215 | } |
151 | } | 216 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java index 07c5da41..f0baf35f 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.resource; | 6 | package tools.refinery.language.resource.state; |
7 | 7 | ||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import com.google.inject.Singleton; | 9 | import com.google.inject.Singleton; |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ImplicitVariableScope.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java index e97c8287..e25887ad 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ImplicitVariableScope.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.resource; | 6 | package tools.refinery.language.resource.state; |
7 | 7 | ||
8 | import org.eclipse.emf.ecore.EObject; | 8 | import org.eclipse.emf.ecore.EObject; |
9 | import org.eclipse.xtext.linking.impl.LinkingHelper; | 9 | import org.eclipse.xtext.linking.impl.LinkingHelper; |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/NodeNameCollector.java index e5deca4d..de4a607c 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/NodeNameCollector.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.resource; | 6 | package tools.refinery.language.resource.state; |
7 | 7 | ||
8 | import com.google.common.collect.ImmutableSet; | 8 | import com.google.common.collect.ImmutableSet; |
9 | import com.google.inject.Inject; | 9 | import com.google.inject.Inject; |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java index 31eb55a6..d905aa9a 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.resource; | 6 | package tools.refinery.language.resource.state; |
7 | 7 | ||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import com.google.inject.Provider; | 9 | import com.google.inject.Provider; |