diff options
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.java | 44 |
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; | |||
15 | import org.eclipse.xtext.GrammarUtil; | 15 | import org.eclipse.xtext.GrammarUtil; |
16 | import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; | 16 | import org.eclipse.xtext.ide.editor.contentassist.ContentAssistContext; |
17 | import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; | 17 | import org.eclipse.xtext.ide.editor.contentassist.IdeCrossrefProposalProvider; |
18 | import org.eclipse.xtext.naming.QualifiedName; | ||
19 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | 18 | import org.eclipse.xtext.nodemodel.util.NodeModelUtils; |
20 | import org.eclipse.xtext.resource.IEObjectDescription; | 19 | import org.eclipse.xtext.resource.IEObjectDescription; |
21 | import org.eclipse.xtext.scoping.IScope; | 20 | import org.eclipse.xtext.scoping.IScope; |
22 | import org.eclipse.xtext.xtext.CurrentTypeFinder; | 21 | import org.eclipse.xtext.xtext.CurrentTypeFinder; |
23 | import org.jetbrains.annotations.Nullable; | 22 | import org.jetbrains.annotations.Nullable; |
24 | import tools.refinery.language.model.problem.*; | 23 | import tools.refinery.language.model.problem.*; |
24 | import tools.refinery.language.naming.NamingUtil; | ||
25 | import tools.refinery.language.naming.ProblemQualifiedNameConverter; | ||
25 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; | 26 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; |
27 | import tools.refinery.language.scoping.imports.ImportCollector; | ||
26 | import tools.refinery.language.utils.BuiltinSymbols; | 28 | import tools.refinery.language.utils.BuiltinSymbols; |
27 | import tools.refinery.language.utils.ProblemDesugarer; | 29 | import tools.refinery.language.utils.ProblemDesugarer; |
28 | import tools.refinery.language.utils.ProblemUtil; | 30 | import 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(), |