aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java')
-rw-r--r--subprojects/language-ide/src/main/java/tools/refinery/language/ide/contentassist/ProblemCrossrefProposalProvider.java44
1 files changed, 35 insertions, 9 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(),