aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-ide/src/main/java/tools/refinery/language
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language-ide/src/main/java/tools/refinery/language')
-rw-r--r--subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java44
-rw-r--r--subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java10
-rw-r--r--subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java49
3 files changed, 83 insertions, 20 deletions
diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java
index 166b4400..a09a475b 100644
--- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java
+++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java
@@ -1,5 +1,5 @@
1/* 1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> 2 * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/>
3 * 3 *
4 * SPDX-License-Identifier: EPL-2.0 4 * SPDX-License-Identifier: EPL-2.0
5 */ 5 */
@@ -15,14 +15,16 @@ import org.eclipse.xtext.EcoreUtil2;
15import org.eclipse.xtext.GrammarUtil; 15import org.eclipse.xtext.GrammarUtil;
16import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; 16import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext;
17import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; 17import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider;
18import org.eclipse.xtext.naming.QualifiedName;
19import org.eclipse.xtext.nodemodel.util.NodeModelUtils; 18import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
20import org.eclipse.xtext.resource.IEObjectDescription; 19import org.eclipse.xtext.resource.IEObjectDescription;
21import org.eclipse.xtext.scoping.IScope; 20import org.eclipse.xtext.scoping.IScope;
22import org.eclipse.xtext.xtext.CurrentTypeFinder; 21import org.eclipse.xtext.xtext.CurrentTypeFinder;
23import org.jetbrains.annotations.Nullable; 22import org.jetbrains.annotations.Nullable;
24import tools.refinery.language.model.problem.*; 23import tools.refinery.language.model.problem.*;
24import tools.refinery.language.naming.NamingUtil;
25import tools.refinery.language.naming.ProblemQualifiedNameConverter;
25import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; 26import tools.refinery.language.resource.ProblemResourceDescriptionStrategy;
27import tools.refinery.language.scoping.imports.ImportCollector;
26import tools.refinery.language.utils.BuiltinSymbols; 28import tools.refinery.language.utils.BuiltinSymbols;
27import tools.refinery.language.utils.ProblemDesugarer; 29import tools.refinery.language.utils.ProblemDesugarer;
28import tools.refinery.language.utils.ProblemUtil; 30import tools.refinery.language.utils.ProblemUtil;
@@ -43,17 +45,18 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider
43 @Inject 45 @Inject
44 private ProblemDesugarer desugarer; 46 private ProblemDesugarer desugarer;
45 47
48 @Inject
49 private ImportCollector importCollector;
50
46 @Override 51 @Override
47 protected Iterable<IEObjectDescription> queryScope(IScope scope, CrossReference crossReference, 52 protected Iterable<IEObjectDescription> queryScope(IScope scope, CrossReference crossReference,
48 ContentAssistContext context) { 53 ContentAssistContext context) {
49 var eObjectDescriptionsByName = new HashMap<QualifiedName, List<IEObjectDescription>>(); 54 var eObjectDescriptionsByName = new HashMap<ProblemResourceDescriptionStrategy.ShadowingKey,
55 List<IEObjectDescription>>();
50 for (var candidate : super.queryScope(scope, crossReference, context)) { 56 for (var candidate : super.queryScope(scope, crossReference, context)) {
51 if (isExistingObject(candidate, crossReference, context)) { 57 if (isExistingObject(candidate, crossReference, context)) {
52 // {@code getQualifiedName()} will refer to the full name for objects that are loaded from the global 58 var shadowingKey = ProblemResourceDescriptionStrategy.getShadowingKey(candidate);
53 // scope, but {@code getName()} returns the qualified name that we set in 59 var candidateList = eObjectDescriptionsByName.computeIfAbsent(shadowingKey,
54 // {@code ProblemResourceDescriptionStrategy}.
55 var qualifiedName = candidate.getName();
56 var candidateList = eObjectDescriptionsByName.computeIfAbsent(qualifiedName,
57 ignored -> new ArrayList<>()); 60 ignored -> new ArrayList<>());
58 candidateList.add(candidate); 61 candidateList.add(candidate);
59 } 62 }
@@ -61,7 +64,7 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider
61 var eObjectDescriptions = new ArrayList<IEObjectDescription>(); 64 var eObjectDescriptions = new ArrayList<IEObjectDescription>();
62 for (var candidates : eObjectDescriptionsByName.values()) { 65 for (var candidates : eObjectDescriptionsByName.values()) {
63 if (candidates.size() == 1) { 66 if (candidates.size() == 1) {
64 var candidate = candidates.get(0); 67 var candidate = candidates.getFirst();
65 if (shouldBeVisible(candidate, crossReference, context)) { 68 if (shouldBeVisible(candidate, crossReference, context)) {
66 eObjectDescriptions.add(candidate); 69 eObjectDescriptions.add(candidate);
67 } 70 }
@@ -96,6 +99,11 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider
96 99
97 protected boolean shouldBeVisible(IEObjectDescription candidate, CrossReference crossReference, 100 protected boolean shouldBeVisible(IEObjectDescription candidate, CrossReference crossReference,
98 ContentAssistContext context) { 101 ContentAssistContext context) {
102 if (NamingUtil.isFullyQualified(candidate.getName()) &&
103 !context.getPrefix().startsWith(ProblemQualifiedNameConverter.DELIMITER)) {
104 // Do not propose names with a root prefix unless explicitly asked for.
105 return false;
106 }
99 var errorPredicate = candidate.getUserData(ProblemResourceDescriptionStrategy.ERROR_PREDICATE); 107 var errorPredicate = candidate.getUserData(ProblemResourceDescriptionStrategy.ERROR_PREDICATE);
100 if (ProblemResourceDescriptionStrategy.ERROR_PREDICATE_TRUE.equals(errorPredicate)) { 108 if (ProblemResourceDescriptionStrategy.ERROR_PREDICATE_TRUE.equals(errorPredicate)) {
101 return false; 109 return false;
@@ -106,6 +114,10 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider
106 return true; 114 return true;
107 } 115 }
108 116
117 if (eReference == ProblemPackage.Literals.IMPORT_STATEMENT__IMPORTED_MODULE) {
118 return importedModuleShouldBeVisible(candidate, context);
119 }
120
109 var candidateEObjectOrProxy = candidate.getEObjectOrProxy(); 121 var candidateEObjectOrProxy = candidate.getEObjectOrProxy();
110 122
111 if (eReference.equals(ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) && 123 if (eReference.equals(ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) &&
@@ -123,6 +135,20 @@ public class ProblemCrossrefProposalProvider extends IdeCrossrefProposalProvider
123 candidateEObjectOrProxy); 135 candidateEObjectOrProxy);
124 } 136 }
125 137
138 private boolean importedModuleShouldBeVisible(IEObjectDescription candidate, ContentAssistContext context) {
139 var moduleKind = candidate.getUserData(ProblemResourceDescriptionStrategy.MODULE_KIND);
140 if (!ModuleKind.MODULE.getName().equals(moduleKind)) {
141 return false;
142 }
143 var resource = context.getResource();
144 var candidateResourceUri = candidate.getEObjectURI().trimFragment();
145 if (candidateResourceUri.equals(resource.getURI())) {
146 return false;
147 }
148 var imports = importCollector.getDirectImports(resource);
149 return !imports.toUriSet().contains(candidateResourceUri);
150 }
151
126 private static boolean oppositeShouldBeVisible(ReferenceDeclaration candidateReferenceDeclaration, 152 private static boolean oppositeShouldBeVisible(ReferenceDeclaration candidateReferenceDeclaration,
127 ContentAssistContext context) { 153 ContentAssistContext context) {
128 var referenceDeclaration = EcoreUtil2.getContainerOfType(context.getCurrentModel(), 154 var referenceDeclaration = EcoreUtil2.getContainerOfType(context.getCurrentModel(),
diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
index f64d4066..891c73c7 100644
--- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
+++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java
@@ -29,7 +29,7 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
29 private static final String CONTAINMENT_CLASS = "containment"; 29 private static final String CONTAINMENT_CLASS = "containment";
30 private static final String ERROR_CLASS = "error"; 30 private static final String ERROR_CLASS = "error";
31 private static final String NODE_CLASS = "node"; 31 private static final String NODE_CLASS = "node";
32 private static final String INDIVIDUAL_NODE_CLASS = "individual"; 32 private static final String ATOM_NODE_CLASS = "atom";
33 private static final String NEW_NODE_CLASS = "new"; 33 private static final String NEW_NODE_CLASS = "new";
34 34
35 @Inject 35 @Inject
@@ -99,7 +99,7 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
99 99
100 protected String[] getHighlightClass(EObject eObject, EReference reference) { 100 protected String[] getHighlightClass(EObject eObject, EReference reference) {
101 boolean isError = ProblemUtil.isError(eObject); 101 boolean isError = ProblemUtil.isError(eObject);
102 if (ProblemUtil.isBuiltIn(eObject)) { 102 if (ProblemUtil.isBuiltIn(eObject) && !(eObject instanceof Problem)) {
103 var className = isError ? ERROR_CLASS : BUILTIN_CLASS; 103 var className = isError ? ERROR_CLASS : BUILTIN_CLASS;
104 return new String[]{className}; 104 return new String[]{className};
105 } 105 }
@@ -137,10 +137,10 @@ public class ProblemSemanticHighlightingCalculator extends DefaultSemanticHighli
137 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE) { 137 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE) {
138 classesBuilder.add(NODE_CLASS); 138 classesBuilder.add(NODE_CLASS);
139 } 139 }
140 if (ProblemUtil.isIndividualNode(node)) { 140 if (ProblemUtil.isAtomNode(node)) {
141 classesBuilder.add(INDIVIDUAL_NODE_CLASS); 141 classesBuilder.add(ATOM_NODE_CLASS);
142 } 142 }
143 if (ProblemUtil.isNewNode(node)) { 143 if (ProblemUtil.isMultiNode(node)) {
144 classesBuilder.add(NEW_NODE_CLASS); 144 classesBuilder.add(NEW_NODE_CLASS);
145 } 145 }
146 } 146 }
diff --git a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java
index f75ecdb2..dd9f1053 100644
--- a/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java
+++ b/subprojects/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/TypeHashProvider.java
@@ -11,10 +11,13 @@ import com.google.inject.Singleton;
11import org.eclipse.xtext.EcoreUtil2; 11import org.eclipse.xtext.EcoreUtil2;
12import org.eclipse.xtext.naming.IQualifiedNameConverter; 12import org.eclipse.xtext.naming.IQualifiedNameConverter;
13import org.eclipse.xtext.naming.IQualifiedNameProvider; 13import org.eclipse.xtext.naming.IQualifiedNameProvider;
14import org.eclipse.xtext.resource.IResourceDescription;
14import org.eclipse.xtext.scoping.IScopeProvider; 15import org.eclipse.xtext.scoping.IScopeProvider;
16import org.eclipse.xtext.scoping.impl.GlobalResourceDescriptionProvider;
15import org.eclipse.xtext.util.IResourceScopeCache; 17import org.eclipse.xtext.util.IResourceScopeCache;
16import tools.refinery.language.model.problem.*; 18import tools.refinery.language.model.problem.*;
17import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; 19import tools.refinery.language.resource.ProblemResourceDescriptionStrategy;
20import tools.refinery.language.scoping.imports.ImportCollector;
18import tools.refinery.language.utils.ProblemUtil; 21import tools.refinery.language.utils.ProblemUtil;
19 22
20import java.util.*; 23import java.util.*;
@@ -36,6 +39,12 @@ public class TypeHashProvider {
36 @Inject 39 @Inject
37 private IQualifiedNameConverter qualifiedNameConverter; 40 private IQualifiedNameConverter qualifiedNameConverter;
38 41
42 @Inject
43 private ImportCollector importCollector;
44
45 @Inject
46 private GlobalResourceDescriptionProvider globalResourceDescriptionProvider;
47
39 public String getTypeHash(Relation relation) { 48 public String getTypeHash(Relation relation) {
40 if (!(relation instanceof ClassDeclaration || relation instanceof EnumDeclaration) || 49 if (!(relation instanceof ClassDeclaration || relation instanceof EnumDeclaration) ||
41 ProblemUtil.isBuiltIn(relation)) { 50 ProblemUtil.isBuiltIn(relation)) {
@@ -55,13 +64,15 @@ public class TypeHashProvider {
55 } 64 }
56 65
57 private Map<String, String> computeHashes(Problem problem) { 66 private Map<String, String> computeHashes(Problem problem) {
67 var resourceDescriptions = getResourceDescriptions(problem);
58 var qualifiedNameStrings = new TreeSet<String>(); 68 var qualifiedNameStrings = new TreeSet<String>();
59 var scope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__RELATION); 69 for (var resourceDescription : resourceDescriptions) {
60 for (var description : scope.getAllElements()) { 70 for (var description : resourceDescription.getExportedObjectsByType(ProblemPackage.Literals.RELATION)) {
61 if (ProblemResourceDescriptionStrategy.COLOR_RELATION_TRUE.equals( 71 if (ProblemResourceDescriptionStrategy.COLOR_RELATION_TRUE.equals(
62 description.getUserData(ProblemResourceDescriptionStrategy.COLOR_RELATION))) { 72 description.getUserData(ProblemResourceDescriptionStrategy.COLOR_RELATION))) {
63 var qualifiedNameString = qualifiedNameConverter.toString(description.getQualifiedName()); 73 var qualifiedNameString = qualifiedNameConverter.toString(description.getQualifiedName());
64 qualifiedNameStrings.add(qualifiedNameString); 74 qualifiedNameStrings.add(qualifiedNameString);
75 }
65 } 76 }
66 } 77 }
67 var stringList = new ArrayList<>(qualifiedNameStrings); 78 var stringList = new ArrayList<>(qualifiedNameStrings);
@@ -90,4 +101,30 @@ public class TypeHashProvider {
90 } 101 }
91 return mapBuilder.build(); 102 return mapBuilder.build();
92 } 103 }
104
105 private List<IResourceDescription> getResourceDescriptions(Problem problem) {
106 var resource = problem.eResource();
107 if (resource == null) {
108 return List.of();
109 }
110 var resourceDescriptions = new ArrayList<IResourceDescription>();
111 var resourceDescription = globalResourceDescriptionProvider.getResourceDescription(resource);
112 if (resourceDescription != null) {
113 resourceDescriptions.add(resourceDescription);
114 }
115 var resourceSet = resource.getResourceSet();
116 if (resourceSet != null) {
117 for (var importedUri : importCollector.getAllImports(resource).toUriSet()) {
118 var importedResource = resourceSet.getResource(importedUri, false);
119 if (importedResource != null) {
120 var importedResourceDescription = globalResourceDescriptionProvider.getResourceDescription(
121 importedResource);
122 if (importedResourceDescription != null) {
123 resourceDescriptions.add(importedResourceDescription);
124 }
125 }
126 }
127 }
128 return resourceDescriptions;
129 }
93} 130}