Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Fasani2018-01-05 17:21:43 +0000
committerPierre-Charles David2018-01-30 16:19:52 +0000
commita3393ba4f56b52a4dc6b16f4119b1d84b96ba80c (patch)
tree0330479c26212420201f00e51bfef51fc4fd4ce4
parent627b435006fc5793783233f2f1a419dc5c86599d (diff)
downloadorg.eclipse.sirius-a3393ba4f56b52a4dc6b16f4119b1d84b96ba80c.tar.gz
org.eclipse.sirius-a3393ba4f56b52a4dc6b16f4119b1d84b96ba80c.tar.xz
org.eclipse.sirius-a3393ba4f56b52a4dc6b16f4119b1d84b96ba80c.zip
[484858] Fix completion in aql expression on domain types
* leverage ICompletionResult API to provide the right proposal * distinguish PROPOSAL_REPLACE and PROPOSAL_INSERT modes in AQLProposalProvider * add a test in AcceleoQueryLanguageCompletionTests Bug:484858 Change-Id: Ic90eb4f8c2170d427c63d07341408e9687b078c1 Signed-off-by: Laurent Fasani <laurent.fasani@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.common.acceleo.aql.ide/src/org/eclipse/sirius/common/acceleo/aql/ide/proposal/AQLProposalProvider.java49
-rw-r--r--plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/contentassist/IProposalProvider.java23
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/aql/AcceleoQueryLanguageCompletionTests.java63
3 files changed, 121 insertions, 14 deletions
diff --git a/plugins/org.eclipse.sirius.common.acceleo.aql.ide/src/org/eclipse/sirius/common/acceleo/aql/ide/proposal/AQLProposalProvider.java b/plugins/org.eclipse.sirius.common.acceleo.aql.ide/src/org/eclipse/sirius/common/acceleo/aql/ide/proposal/AQLProposalProvider.java
index 919f0aeeb8..3efda4cb22 100644
--- a/plugins/org.eclipse.sirius.common.acceleo.aql.ide/src/org/eclipse/sirius/common/acceleo/aql/ide/proposal/AQLProposalProvider.java
+++ b/plugins/org.eclipse.sirius.common.acceleo.aql.ide/src/org/eclipse/sirius/common/acceleo/aql/ide/proposal/AQLProposalProvider.java
@@ -73,7 +73,8 @@ public class AQLProposalProvider implements IProposalProvider {
setupInterpreter(context, aqlInterpreter);
Map<String, Set<IType>> variableTypes = TypesUtil.createAQLVariableTypesFromInterpreterContext(context.getInterpreterContext(), aqlInterpreter.getQueryEnvironment());
- return ImmutableList.copyOf(getProposals(trimer, context.getPosition(), aqlInterpreter.getQueryEnvironment(), variableTypes));
+ return ImmutableList.copyOf(getProposals(trimer, context.getPosition(), aqlInterpreter.getQueryEnvironment(), variableTypes,
+ ProposalAcceptanceStyle.PROPOSAL_INSERT));
}
}
return Collections.<ContentProposal> emptyList();
@@ -98,21 +99,48 @@ public class AQLProposalProvider implements IProposalProvider {
}
}
- private Set<ContentProposal> getProposals(ExpressionTrimmer trimmer, int position, IQueryEnvironment queryEnvironment, Map<String, Set<IType>> variableTypes) {
+ /**
+ * Evaluates the content proposals for a given expression and returns the result as a list.
+ *
+ * @param trimmer
+ * the trimmer.
+ * @param position
+ * position of the cursor.
+ * @param queryEnvironment
+ * the IQueryEnvironment.
+ * @param variableTypes
+ * the variable Types.
+ * @param proposalAcceptanceStyle
+ * Integer that indicates how an accepted proposal should affect the global string.</br>
+ * The possible values are ContentProposalAdapter.PROPOSAL_INSERT or
+ * ContentProposalAdapter.PROPOSAL_REPLACE
+ * @return content proposal list.
+ */
+ private Set<ContentProposal> getProposals(ExpressionTrimmer trimmer, int position, IQueryEnvironment queryEnvironment, Map<String, Set<IType>> variableTypes,
+ ProposalAcceptanceStyle proposalAcceptanceStyle) {
Set<ContentProposal> proposals = new LinkedHashSet<>();
IQueryCompletionEngine engine = QueryCompletion.newEngine(queryEnvironment);
final ICompletionResult completionResult = engine.getCompletion(trimmer.getExpression(), trimmer.getPositionWithinAQL(position), variableTypes);
/*
* completionResult.sort(new ProposalComparator());
*/
- final Set<ICompletionProposal> proposal = Sets.newLinkedHashSet(completionResult.getProposals(QueryCompletion.createBasicFilter(completionResult)));
+ final Set<ICompletionProposal> aqlProposals = Sets.newLinkedHashSet(completionResult.getProposals(QueryCompletion.createBasicFilter(completionResult)));
- for (ICompletionProposal propFromAQL : proposal) {
- int offset = position - completionResult.getPrefix().length();
- int length = completionResult.getPrefix().length() + completionResult.getRemaining().length();
-
- ContentProposal contentProposal = ContentProposalBuilder.proposal(propFromAQL.getProposal(), propFromAQL.toString(), propFromAQL.getDescription(), propFromAQL.getCursorOffset())
- .withReplacement(offset, length).build();
+ for (ICompletionProposal propFromAQL : aqlProposals) {
+ int offset = trimmer.getPositionInExpression(completionResult.getReplacementOffset());
+ String proposal = ""; //$NON-NLS-1$
+ ContentProposal contentProposal = null;
+ if (proposalAcceptanceStyle.equals(ProposalAcceptanceStyle.PROPOSAL_INSERT)) {
+ // as the TextContentProposalProvider uses the ContentProposalAdapter.PROPOSAL_INSERT style, we remove a
+ // part of the proposal
+ proposal = propFromAQL.getProposal().substring(completionResult.getReplacementLength());
+ contentProposal = ContentProposalBuilder.proposal(proposal, propFromAQL.toString(), propFromAQL.getDescription(), propFromAQL.getCursorOffset()).build();
+ } else if (proposalAcceptanceStyle.equals(ProposalAcceptanceStyle.PROPOSAL_REPLACE)) {
+ int length = completionResult.getReplacementLength() + completionResult.getRemaining().length();
+ proposal = propFromAQL.getProposal();
+ contentProposal = ContentProposalBuilder.proposal(proposal, propFromAQL.toString(), propFromAQL.getDescription(), propFromAQL.getCursorOffset()).withReplacement(offset, length)
+ .build();
+ }
proposals.add(contentProposal);
}
return proposals;
@@ -133,7 +161,8 @@ public class AQLProposalProvider implements IProposalProvider {
ExpressionTrimmer trimer = new ExpressionTrimmer(context.getTextSoFar());
if (trimer.positionIsWithinAQL(context.getCursorPosition())) {
- return ImmutableList.copyOf(getProposals(trimer, context.getCursorPosition(), queryEnvironment, variableTypes));
+ return ImmutableList.copyOf(getProposals(trimer, context.getCursorPosition(), queryEnvironment, variableTypes,
+ ProposalAcceptanceStyle.PROPOSAL_REPLACE));
}
}
diff --git a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/contentassist/IProposalProvider.java b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/contentassist/IProposalProvider.java
index 3f0007a1bd..0e5d169d3b 100644
--- a/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/contentassist/IProposalProvider.java
+++ b/plugins/org.eclipse.sirius.common/src/org/eclipse/sirius/common/tools/api/contentassist/IProposalProvider.java
@@ -22,6 +22,29 @@ import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter;
public interface IProposalProvider {
/**
+ * Indicates how an accepted proposal should affect the string being completed. These enum corresponds to
+ * ContentProposalAdapter.PROPOSAL_INSERT and ContentProposalAdapter.PROPOSAL_REPLACE. Default value is
+ * PROPOSAL_INSERT.
+ *
+ * @author lfasani
+ *
+ */
+ enum ProposalAcceptanceStyle {
+
+ /**
+ * If the proposal is to be inserted in a string.</br>
+ * Corresponds to ContentProposalAdapter.PROPOSAL_INSERT
+ */
+ PROPOSAL_INSERT,
+
+ /**
+ * If the proposal is to be replacing another string in the global string.</br>
+ * Corresponds to ContentProposalAdapter.PROPOSAL_REPLACE
+ */
+ PROPOSAL_REPLACE
+ }
+
+ /**
* Evaluates the content proposals for a given expression and returns the
* result as a list.
*
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/aql/AcceleoQueryLanguageCompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/aql/AcceleoQueryLanguageCompletionTests.java
index 008cf7c131..241e2f179c 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/aql/AcceleoQueryLanguageCompletionTests.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/acceleo/aql/AcceleoQueryLanguageCompletionTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 Obeo.
+ * Copyright (c) 2015, 2018 Obeo.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -16,6 +16,7 @@ import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.sirius.common.acceleo.aql.business.internal.AQLSiriusInterpreter;
import org.eclipse.sirius.common.acceleo.aql.ide.proposal.AQLProposalProvider;
+import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal;
import org.eclipse.sirius.common.tools.api.contentassist.ContentProposalWithReplacement;
@@ -83,8 +84,62 @@ public class AcceleoQueryLanguageCompletionTests extends AbstractCompletionTestC
}
/**
- * Test the completion with replacement of a part of the expression after
- * the cursor.
+ * Test the completion with insertion at the end of the expression where the cursor is.</br>
+ * The inserted string is a part of a method name.
+ */
+ public void testAQLProposalForMethodName_ContentProposal() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("FirstEClass");
+ ContentContext contentContext = createContentContext("aql:self.na", "aql:self.na".length(), c, "EClass");
+
+ List<ContentProposal> proposals = getProposals(contentContext);
+
+ assertEquals(1, proposals.size());
+
+ ContentProposal proposal = proposals.get(0);
+ assertEquals("me", proposal.getProposal());
+ }
+
+ /**
+ * Test the completion with replacement of a part of the expression before the cursor.</br>
+ * The replaced string is a part of a domain type.
+ */
+ public void testAQLProposalWithPreviousReplacementOnDomainType() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ c.setName("FirstEClass");
+
+ ContentInstanceContext cic = new ContentInstanceContext(c, "aql:self.eAllContents(ecore::E)", 30);
+ List<ContentProposal> proposals = this.getProposals(cic);
+
+ assertEquals(53, proposals.size());
+
+ if (proposals.get(0) instanceof ContentProposalWithReplacement) {
+ ContentProposalWithReplacement proposalWithReplacement = (ContentProposalWithReplacement) proposals.get(0);
+ assertEquals("ecore::EAttribute", proposalWithReplacement.getProposal());
+ assertEquals(8, proposalWithReplacement.getReplacementLength());
+ assertEquals(22, proposalWithReplacement.getReplacementOffset());
+ }
+ }
+
+ /**
+ * Test the completion with insertion at the end of the expression where the cursor is.</br>
+ * The inserted string is a part of a domain type.
+ */
+ public void testAQLProposalForDomainType_ContentProposal() {
+ EClass c = EcoreFactory.eINSTANCE.createEClass();
+ ContentContext contentContext = createContentContext("aql:self.eAllContents(ecore::E)", 30, c, "");
+
+ List<ContentProposal> proposals = getProposals(contentContext);
+
+ assertEquals(53, proposals.size());
+
+ ContentProposal proposal = proposals.get(0);
+ assertEquals("Attribute", proposal.getProposal());
+ }
+
+
+ /**
+ * Test the completion with replacement of a part of the expression after the cursor.
*/
public void testAQLWithAfterReplacement() {
EClass c = EcoreFactory.eINSTANCE.createEClass();
@@ -112,7 +167,7 @@ public class AcceleoQueryLanguageCompletionTests extends AbstractCompletionTestC
EClass c = EcoreFactory.eINSTANCE.createEClass();
c.setName("FirstEClass");
- ContentInstanceContext cic = new ContentInstanceContext(c, "aql:self.nam", 11);
+ ContentInstanceContext cic = new ContentInstanceContext(c, "aql:self.nam", "aql:self.na".length());
List<ContentProposal> proposals = this.getProposals(cic);
assertEquals(1, proposals.size());

Back to the top