summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormclay2008-12-21 14:45:03 (EST)
committer sefftinge2008-12-21 14:45:03 (EST)
commitdd1c9e1f8db4096b4afef0c0f68d1f4c8e2e6c3c (patch)
treec5f850fceb4ede82d3e24b23849af448ab5f48f8
parent2329526861387056ac65c24e322de51efaf51135 (diff)
downloadorg.eclipse.xtext-dd1c9e1f8db4096b4afef0c0f68d1f4c8e2e6c3c.zip
org.eclipse.xtext-dd1c9e1f8db4096b4afef0c0f68d1f4c8e2e6c3c.tar.gz
org.eclipse.xtext-dd1c9e1f8db4096b4afef0c0f68d1f4c8e2e6c3c.tar.bz2
ASSIGNED - bug 241897: [Content Assist] Implement template proposals for Xtext CA
https://bugs.eclipse.org/bugs/show_bug.cgi?id=241897
-rw-r--r--devtools/org.eclipse.xtext.reference.ui/src-gen/org/eclipse/xtext/reference/ReferenceGrammarGenProposalProvider.java139
-rw-r--r--examples/org.eclipse.xtext.example.fowlerdsl.ui/META-INF/MANIFEST.MF9
-rw-r--r--examples/org.eclipse.xtext.example.fowlerdsl.ui/plugin.xml28
-rw-r--r--examples/org.eclipse.xtext.example.fowlerdsl.ui/src-gen/org/eclipse/xtext/example/FowlerDslGenProposalProvider.java99
-rw-r--r--examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/Activator.java198
-rw-r--r--examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslProposalProvider.java28
-rw-r--r--examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslUiConfig.java11
-rw-r--r--examples/org.eclipse.xtext.example.fowlerdsl.ui/templates/templates.xml51
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/AbstractProposalProvider.java91
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistContextAdapter.java150
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/DefaultContentAssistProcessor.java268
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistCalculator.java29
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistContext.java56
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IProposalProvider.java65
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ITemplateContentAssistProcessor.java32
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ProposalCandidateResolverSwitch.java137
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistCalculator.java193
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistContext.java129
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultTemplateContentAssistProcessor.java100
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/ProposalProviderInvokerSwitch.java (renamed from plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ProposalProviderInvokerSwitch.java)127
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextCompletionProposal.java (renamed from plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/XtextCompletionProposal.java)218
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContext.java62
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContextType.java97
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextSourceViewer.java50
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java2
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewer.java164
-rw-r--r--tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/XtextGrammarTestLanguageGenProposalProvider.java182
-rw-r--r--tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ContentAssistTestLanguageGenProposalProvider.java54
-rw-r--r--tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ReferenceGrammarTestLanguageGenProposalProvider.java113
-rw-r--r--tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/TreeTestLanguageGenProposalProvider.java44
-rw-r--r--tests/org.eclipse.xtext.ui.common.tests/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistProcessorTestBuilder.java23
31 files changed, 1836 insertions, 1113 deletions
diff --git a/devtools/org.eclipse.xtext.reference.ui/src-gen/org/eclipse/xtext/reference/ReferenceGrammarGenProposalProvider.java b/devtools/org.eclipse.xtext.reference.ui/src-gen/org/eclipse/xtext/reference/ReferenceGrammarGenProposalProvider.java
index c702b0a..6fcc47c 100644
--- a/devtools/org.eclipse.xtext.reference.ui/src-gen/org/eclipse/xtext/reference/ReferenceGrammarGenProposalProvider.java
+++ b/devtools/org.eclipse.xtext.reference.ui/src-gen/org/eclipse/xtext/reference/ReferenceGrammarGenProposalProvider.java
@@ -6,239 +6,210 @@ package org.eclipse.xtext.reference;
import java.util.Collections;
import java.util.List;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ui.common.editor.codecompletion.AbstractProposalProvider;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
/**
* Represents a generated, default implementation of interface {@link IProposalProvider}.
*
- * In addition to the declared methods, the framework tries to call grammar dependent methods for assignments using reflection.
- * The signature of such methods invoked reflectively follows the following pattern:
- *
- * public List<ICompletionProposal> complete[Typename][featureName](Assignment ele, EObject model, String prefix)
- *
- * <b>Example</b>
- * Given the following grammar :
- * <code>
- * RuleA returns MyType :
- * "myType" name=ID;
- * </code>
- *
- * One could provide the following method in an implementation of this interface:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, EObject model, String prefix, IDocument doc) {...}
- * </code>
- * Note that if you have generated Java classes for your domain model (meta model) you can alternatively declare the second parameter using
- * a specific type:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, MyType model, String prefix, IDocument doc) {...}
- * </code>
- *
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider
*/
public class ReferenceGrammarGenProposalProvider extends AbstractProposalProvider {
// constants
private static final String UI_PLUGIN_ID = "org.eclipse.xtext.reference.ui";
- public List<? extends ICompletionProposal> completeSpielplatzGroesse(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzGroesse(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzGroesse feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"1", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "1", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielplatzBeschreibung(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzBeschreibung(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzBeschreibung feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"\"SpielplatzBeschreibung\"", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "\"SpielplatzBeschreibung\"", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielplatzKinder(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzKinder(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzKinder feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSpielplatzErzieher(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzErzieher(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzErzieher feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSpielplatzSpielzeuge(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzSpielzeuge(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzSpielzeuge feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSpielplatzFamilie(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzFamilie(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzFamilie feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSpielplatzTypes(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzTypes(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzTypes feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeKindName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeKindName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeKindName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"KindName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "KindName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeKindAge(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeKindAge(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeKindAge feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"1", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "1", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeErwachsenerName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeErwachsenerName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeErwachsenerName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"ErwachsenerName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "ErwachsenerName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeErwachsenerAge(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeErwachsenerAge(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeErwachsenerAge feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"1", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "1", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielzeugName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielzeugName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielzeugName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"SpielzeugName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "SpielzeugName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielzeugFarbe(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielzeugFarbe(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielzeugFarbe feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeFamilieName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeFamilieMutter(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieMutter(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieMutter feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeFamilieVater(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieVater(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieVater feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeFamilieKinder(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieKinder(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieKinder feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeFarbeWert(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFarbeWert(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFarbeWert feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeCustomTypeParserRuleName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeCustomTypeParserRuleName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeCustomTypeParserRuleName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"CustomTypeParserRuleName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "CustomTypeParserRuleName", contentAssistContext));
}
- public List<? extends ICompletionProposal> complete(RuleCall ruleCall, EObject model, String prefix,
- IDocument doc, int offset) {
+ public List<? extends ICompletionProposal> complete(RuleCall ruleCall, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("complete '" + ruleCall.getRule().getName() + "' cardinality '" + ruleCall.getCardinality()
- + "' for model '" + model + "' and prefix '" + prefix.trim() + "'");
+ + "' for model '" + contentAssistContext.getModel() + "' and prefix '" + contentAssistContext.getMatchString() + "'");
}
return Collections.emptyList();
}
-
-
-
-
-
- public List<? extends ICompletionProposal> completeReferenceModelCustomType(RuleCall ruleCall, EObject model, String prefix,
- IDocument doc, int offset) {
+ public List<? extends ICompletionProposal> completeReferenceModelCustomType(RuleCall ruleCall, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeReferenceModelCustomType '" + ruleCall.getRule().getName() + "' cardinality '" + ruleCall.getCardinality()
- + "' for model '" + model + "' and prefix '" + prefix.trim() + "'");
+ + "' for model '" + contentAssistContext.getModel() + "' and prefix '" + contentAssistContext.getMatchString() + "'");
}
return Collections.emptyList();
}
diff --git a/examples/org.eclipse.xtext.example.fowlerdsl.ui/META-INF/MANIFEST.MF b/examples/org.eclipse.xtext.example.fowlerdsl.ui/META-INF/MANIFEST.MF
index c58410d..79fd3ce 100644
--- a/examples/org.eclipse.xtext.example.fowlerdsl.ui/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.xtext.example.fowlerdsl.ui/META-INF/MANIFEST.MF
@@ -4,10 +4,13 @@ Bundle-Name: Xtext DSL Example UI (Incubation)
Bundle-SymbolicName: org.eclipse.xtext.example.fowlerdsl.ui;singleton:=true
Bundle-Vendor: Eclipse.org
Bundle-Version: 0.7.0.qualifier
-Eclipse-RegisterBuddy: org.eclipse.xtext.log4j
+Eclipse-RegisterBuddy: org.eclipse.xtext.log4j,org.eclipse.xtext.service.ui,org.eclipse.xtext.service
Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.xtext.example
Require-Bundle: org.eclipse.xtext.example.fowlerdsl,
org.eclipse.xtext.ui.core,
- org.eclipse.xtext.ui.common
+ org.eclipse.xtext.ui.common,
+ org.eclipse.xtext.service.ui,
+ org.eclipse.xtext.service
+Bundle-Activator: org.eclipse.xtext.example.Activator
+Bundle-ActivationPolicy: lazy
diff --git a/examples/org.eclipse.xtext.example.fowlerdsl.ui/plugin.xml b/examples/org.eclipse.xtext.example.fowlerdsl.ui/plugin.xml
index 550f42e..9cd6e7c 100644
--- a/examples/org.eclipse.xtext.example.fowlerdsl.ui/plugin.xml
+++ b/examples/org.eclipse.xtext.example.fowlerdsl.ui/plugin.xml
@@ -49,4 +49,32 @@
label="Task Tags">
</keyword>
</extension>
+ <extension point="org.eclipse.ui.editors.templates">
+ <contextType name="templatesContextTypeEventsName"
+ class="org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextTemplateContextType"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.events">
+ </contextType>
+ <contextType name="templatesContextTypeActionsName"
+ class="org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextTemplateContextType"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.actions">
+ </contextType>
+ <contextType name="templatesContextTypeStateName"
+ class="org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextTemplateContextType"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.state">
+ </contextType>
+ <contextType name="templatesContextTypeEventName"
+ class="org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextTemplateContextType"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.Event">
+ </contextType>
+ <contextType name="templatesContextTypeCommandName"
+ class="org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextTemplateContextType"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.Command">
+ </contextType>
+ <contextType name="templatesContextTypeTransitionName"
+ class="org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextTemplateContextType"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.Transition">
+ </contextType>
+ <include file="templates/templates.xml" />
+ </extension>
+
</plugin>
diff --git a/examples/org.eclipse.xtext.example.fowlerdsl.ui/src-gen/org/eclipse/xtext/example/FowlerDslGenProposalProvider.java b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src-gen/org/eclipse/xtext/example/FowlerDslGenProposalProvider.java
index 9fc04fe..ff38345 100644
--- a/examples/org.eclipse.xtext.example.fowlerdsl.ui/src-gen/org/eclipse/xtext/example/FowlerDslGenProposalProvider.java
+++ b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src-gen/org/eclipse/xtext/example/FowlerDslGenProposalProvider.java
@@ -6,169 +6,146 @@ package org.eclipse.xtext.example;
import java.util.Collections;
import java.util.List;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ui.common.editor.codecompletion.AbstractProposalProvider;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
/**
* Represents a generated, default implementation of interface {@link IProposalProvider}.
*
- * In addition to the declared methods, the framework tries to call grammar dependent methods for assignments using reflection.
- * The signature of such methods invoked reflectively follows the following pattern:
- *
- * public List<ICompletionProposal> complete[Typename][featureName](Assignment ele, EObject model, String prefix)
- *
- * <b>Example</b>
- * Given the following grammar :
- * <code>
- * RuleA returns MyType :
- * "myType" name=ID;
- * </code>
- *
- * One could provide the following method in an implementation of this interface:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, EObject model, String prefix, IDocument doc) {...}
- * </code>
- * Note that if you have generated Java classes for your domain model (meta model) you can alternatively declare the second parameter using
- * a specific type:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, MyType model, String prefix, IDocument doc) {...}
- * </code>
- *
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider
*/
public class FowlerDslGenProposalProvider extends AbstractProposalProvider {
// constants
private static final String UI_PLUGIN_ID = "org.eclipse.xtext.example.fowlerdsl.ui";
- public List<? extends ICompletionProposal> completeStatemachineEvents(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeStatemachineEvents(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeStatemachineEvents feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeStatemachineCommands(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeStatemachineCommands(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeStatemachineCommands feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeStatemachineStates(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeStatemachineStates(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeStatemachineStates feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeEventResetting(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeEventResetting(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeEventResetting feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeEventName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeEventName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeEventName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"EventName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "EventName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeEventCode(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeEventCode(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeEventCode feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"EventCode", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "EventCode", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeCommandName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeCommandName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeCommandName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"CommandName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "CommandName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeCommandCode(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeCommandCode(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeCommandCode feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"CommandCode", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "CommandCode", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeStateName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeStateName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeStateName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"StateName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "StateName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeStateActions(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeStateActions(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeStateActions feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeStateTransitions(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeStateTransitions(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeStateTransitions feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeTransitionEvent(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeTransitionEvent(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeTransitionEvent feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeTransitionState(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeTransitionState(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeTransitionState feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> complete(RuleCall ruleCall, EObject model, String prefix,
- IDocument doc, int offset) {
+ public List<? extends ICompletionProposal> complete(RuleCall ruleCall, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("complete '" + ruleCall.getRule().getName() + "' cardinality '" + ruleCall.getCardinality()
- + "' for model '" + model + "' and prefix '" + prefix.trim() + "'");
+ + "' for model '" + contentAssistContext.getModel() + "' and prefix '" + contentAssistContext.getMatchString() + "'");
}
return Collections.emptyList();
}
diff --git a/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/Activator.java b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/Activator.java
new file mode 100644
index 0000000..c7ec9b0
--- /dev/null
+++ b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/Activator.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.example;
+
+import java.io.IOException;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry;
+import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ Logger logger = Logger.getLogger(Activator.class);
+
+ // The plug-in ID
+ public static final String PLUGIN_ID = "org.eclipse.xtext.example.fowlerdsl.ui";
+
+ private static final String RESOURCE_NAME = PLUGIN_ID + ".messages";
+
+
+ /** Key to store our templates. */
+ private static final String TEMPLATES_KEY = PLUGIN_ID + ".templates";
+
+ public static final String PREFIX = Activator.PLUGIN_ID + ".templates.contextType.";
+
+ public static final String EVENTS = PREFIX + "events";
+ public static final String EVENT = PREFIX + "Event";
+ public static final String COMMAND = PREFIX + "Command";
+ public static final String TRANSITION = PREFIX + "Transition";
+ public static final String ACTIONS = PREFIX + "actions";
+ public static final String STATE = PREFIX + "state";
+ // The shared instance
+ private static Activator plugin;
+
+ private ResourceBundle resourceBundle;
+ private ContextTypeRegistry contextTypeRegistry;
+ private TemplateStore templateStore;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ try {
+ resourceBundle = ResourceBundle.getBundle(RESOURCE_NAME);
+ } catch (MissingResourceException e) {
+ resourceBundle = null;
+ }
+
+ }
+
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
+ * )
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ setDefault(this);
+ logger.debug("Starting fowlerdsl.ui activator: " + this.getClass().getName());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
+ * )
+ */
+ public void stop(BundleContext context) throws Exception {
+ setDefault(null);
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ private static void setDefault(Activator activator) {
+ plugin = activator;
+ }
+
+ /**
+ * Returns the template context type registry for the Fowler-Dsl editor.
+ *
+ * @return the template context type registry for the Fowler-Dsl editor
+ */
+ public ContextTypeRegistry getTemplateContextRegistry() {
+ if (contextTypeRegistry == null) {
+ ContributionContextTypeRegistry registry = new ContributionContextTypeRegistry();
+ registry.addContextType(EVENTS);
+ registry.addContextType(ACTIONS);
+ registry.addContextType(TRANSITION);
+ registry.addContextType(EVENT);
+ registry.addContextType(COMMAND);
+ registry.addContextType(STATE);
+ contextTypeRegistry = registry;
+ }
+ return contextTypeRegistry;
+ }
+
+ /**
+ * Returns the template store for the Fowler-Dsl editor.
+ *
+ * @return the template store for the Fowler-Dsl editor
+ */
+ public TemplateStore getTemplateStore() {
+ if (templateStore == null) {
+ templateStore = new ContributionTemplateStore(getTemplateContextRegistry(), getPreferenceStore(),
+ TEMPLATES_KEY);
+ try {
+ templateStore.load();
+ }
+ catch (IOException e) {
+ logger.error(e);
+ }
+ }
+ return templateStore;
+ }
+
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+
+ /**
+ * Writes the message to the plug-in's log
+ *
+ * @param message the text to write to the log
+ */
+ public static void log(String message, Throwable exception) {
+ IStatus status = createErrorStatus(message, exception);
+ getDefault().getLog().log(status);
+ }
+
+ public static void log(Throwable exception) {
+ getDefault().getLog().log(createErrorStatus(
+ getResourceString("Plugin.internal_error"), exception));
+ }
+ /**
+ * Returns a new <code>IStatus</code> for this plug-in
+ */
+ public static IStatus createErrorStatus(String message,
+ Throwable exception) {
+ if (message == null) {
+ message= "";
+ }
+ return new Status(Status.ERROR, PLUGIN_ID, 0, message, exception);
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ */
+ public static String getResourceString(String key) {
+ String bundleString;
+ ResourceBundle bundle = getDefault().getResourceBundle();
+ if (bundle != null) {
+ try {
+ bundleString = bundle.getString(key);
+ } catch (MissingResourceException e) {
+ log(e);
+ bundleString = "!" + key + "!";
+ }
+ } else {
+ bundleString = "!" + key + "!";
+ }
+ return bundleString;
+ }
+
+
+}
diff --git a/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslProposalProvider.java b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslProposalProvider.java
new file mode 100644
index 0000000..2fd2394
--- /dev/null
+++ b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslProposalProvider.java
@@ -0,0 +1,28 @@
+package org.eclipse.xtext.example;
+
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.xtext.Keyword;
+import org.eclipse.xtext.RuleCall;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
+
+public class FowlerDslProposalProvider extends FowlerDslGenProposalProvider {
+
+ @Override
+ public Template[] getTemplates(String contextTypeId) {
+ return Activator.getDefault().getTemplateStore().getTemplates(contextTypeId);
+ }
+
+ @Override
+ public TemplateContextType getTemplateContextType(Keyword keyword, IContentAssistContext contentAssistContext) {
+ return Activator.getDefault().getTemplateContextRegistry()
+ .getContextType(Activator.PREFIX + keyword.getValue());
+ }
+
+ @Override
+ public TemplateContextType getTemplateContextType(RuleCall ruleCall, IContentAssistContext contentAssistContext) {
+ return Activator.getDefault().getTemplateContextRegistry().getContextType(
+ Activator.PREFIX + ruleCall.getRule().getName());
+ }
+
+}
diff --git a/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslUiConfig.java b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslUiConfig.java
index 6caf1f7..f25f3e2 100644
--- a/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslUiConfig.java
+++ b/examples/org.eclipse.xtext.example.fowlerdsl.ui/src/org/eclipse/xtext/example/FowlerDslUiConfig.java
@@ -1,11 +1,11 @@
/*
Generated with Xtext
-*/
+ */
package org.eclipse.xtext.example;
import java.util.Set;
-import org.eclipse.xtext.service.AbstractServiceRegistrationFactory;
+import org.eclipse.xtext.service.ServiceRegistry;
/**
* used to register components to be used within the IDE.
@@ -13,7 +13,12 @@ import org.eclipse.xtext.service.AbstractServiceRegistrationFactory;
public class FowlerDslUiConfig extends org.eclipse.xtext.example.GenFowlerDslUiConfig {
public Set<IServiceRegistration> registrations() {
- return super.registrations();
+ Set<IServiceRegistration> registrations = super.registrations();
+ registrations.addAll(scope(org.eclipse.xtext.example.IFowlerDsl.SCOPE).with(
+ org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider.class,
+ org.eclipse.xtext.example.FowlerDslProposalProvider.class, ServiceRegistry.PRIORITY_MAX)
+ .registrations());
+ return registrations;
}
}
diff --git a/examples/org.eclipse.xtext.example.fowlerdsl.ui/templates/templates.xml b/examples/org.eclipse.xtext.example.fowlerdsl.ui/templates/templates.xml
new file mode 100644
index 0000000..d8bc2b1
--- /dev/null
+++ b/examples/org.eclipse.xtext.example.fowlerdsl.ui/templates/templates.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates>
+ <template name="empty Statemachine" description="template for an empty Statemachine"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.events"
+ context="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.events"
+ enabled="true">events
+ startEvent START1
+ stopEvent STOP2
+ ${cursor}
+end
+
+commands
+end
+
+state start
+ startEvent => start
+end
+
+state stop
+ stopEvent => stop
+end
+ </template>
+
+ <template name="state" description="state definition"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.state"
+ context="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.state"
+ enabled="true">state ${name}
+ ${cursor}
+end</template>
+
+ <template name="transition" description="event transition"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.transition"
+ context="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.Transition"
+ enabled="true">${event:CrossReference('Transition.event')} => ${state:CrossReference('Transition.state')}</template>
+
+ <template name="event" description="event definition"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.event"
+ context="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.Event"
+ enabled="true">${event} ${shortCode}</template>
+
+ <template name="command" description="command definition"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.command"
+ context="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.Command"
+ enabled="true">${command} ${shortCode}</template>
+
+ <template name="actions" description="action definition"
+ id="org.eclipse.xtext.example.fowlerdsl.ui.templates.actions"
+ context="org.eclipse.xtext.example.fowlerdsl.ui.templates.contextType.actions"
+ enabled="true">actions {${action:CrossReference('State.actions')} ${cursor}}</template>
+
+</templates>
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/AbstractProposalProvider.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/AbstractProposalProvider.java
index a9ce3a4..b2e4779 100644
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/AbstractProposalProvider.java
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/AbstractProposalProvider.java
@@ -21,7 +21,8 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
-import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Assignment;
@@ -35,6 +36,7 @@ import org.eclipse.xtext.crossref.IScopedElement;
import org.eclipse.xtext.parsetree.AbstractNode;
import org.eclipse.xtext.parsetree.LeafNode;
import org.eclipse.xtext.service.Inject;
+import org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextCompletionProposal;
import org.eclipse.xtext.util.Strings;
/**
@@ -60,49 +62,67 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
/*
* (non-Javadoc)
- *
- * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#completeKeyword(org.eclipse.xtext.Keyword,org.eclipse.emf.ecore.EObject, java.lang.String, org.eclipse.jface.text.IDocument, int)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#completeKeyword(org.eclipse.xtext.Keyword, org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext)
*/
- public List<? extends ICompletionProposal> completeKeyword(Keyword keyword, EObject model, String prefix,
- IDocument doc, int offset) {
+ public List<? extends ICompletionProposal> completeKeyword(Keyword keyword, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
- logger.debug("completeKeyword '" + keyword.getValue() + "' for model '" + model + "' and prefix '"
- + prefix.trim() + "'");
+ logger.debug("completeKeyword '" + keyword.getValue() + "' for model '" + contentAssistContext.getModel() + "' and prefix '"
+ + contentAssistContext.getMatchString().trim() + "'");
}
String text = keyword.getValue().length() == 1 ? keyword.getValue() : keyword.getValue() + " ";
- return Collections.singletonList(createCompletionProposal(keyword, model, text, offset));
+ return Collections.singletonList(createCompletionProposal(keyword, text, contentAssistContext));
}
/*
* (non-Javadoc)
- *
- * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#completeRuleCall(org.eclipse.xtext.RuleCall, org.eclipse.emf.ecore.EObject, java.lang.String, org.eclipse.jface.text.IDocument, int)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#completeRuleCall(org.eclipse.xtext.RuleCall, org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext)
*/
- public List<? extends ICompletionProposal> completeRuleCall(RuleCall ruleCall, EObject model, String prefix,
- IDocument doc, int offset) {
+ public List<? extends ICompletionProposal> completeRuleCall(RuleCall ruleCall, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeRuleCall '" + ruleCall.getRule().getName() + "' cardinality '" + ruleCall.getCardinality()
- + "' for model '" + model + "' and prefix '" + prefix.trim() + "'");
+ + "' for model '" + contentAssistContext.getModel() + "' and prefix '" + contentAssistContext.getMatchString().trim().trim() + "'");
}
AbstractRule calledRule = ruleCall.getRule();
if (calledRule instanceof LexerRule) {
- return doCompleteLexerRuleRuleCall((LexerRule) calledRule, ruleCall, model, offset);
+ return doCompleteLexerRuleRuleCall((LexerRule) calledRule, ruleCall, contentAssistContext);
}
return Collections.emptyList();
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#getTemplateContextType(org.eclipse.xtext.Keyword, org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext)
+ */
+ public TemplateContextType getTemplateContextType(Keyword keyword, IContentAssistContext contentAssistContext) {
+ return null;
+ }
/*
* (non-Javadoc)
- *
- * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#sortAndFilter(java.util.List, org.eclipse.emf.ecore.EObject, java.lang.String, org.eclipse.jface.text.IDocument, int, org.eclipse.xtext.parsetree.AbstractNode, org.eclipse.xtext.parsetree.LeafNode)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#getTemplateContextType(org.eclipse.xtext.RuleCall, org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext)
+ */
+ public TemplateContextType getTemplateContextType(RuleCall ruleCall, IContentAssistContext contentAssistContext) {
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#getTemplates(java.lang.String)
+ */
+ public Template[] getTemplates(String contextTypeId) {
+ return new Template[]{};
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#sortAndFilter(java.util.List, org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext)
*/
public List<? extends ICompletionProposal> sortAndFilter(
- List<? extends ICompletionProposal> completionProposalList, EObject model, String prefix,
- IDocument document, int offset) {
- return doSortAndFilter(completionProposalList, model, prefix, document, offset);
+ List<? extends ICompletionProposal> completionProposalList, IContentAssistContext contentAssistContext) {
+ return doSortAndFilter(completionProposalList,contentAssistContext);
}
/**
@@ -120,7 +140,7 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
* @return a computed list of <code>ICompletionProposal</code> for the given <code>LexerRule</code>
*/
protected List<? extends ICompletionProposal> doCompleteLexerRuleRuleCall(LexerRule lexerRule, RuleCall ruleCall,
- EObject model, int offset) {
+ IContentAssistContext contentAssistContext) {
ParserRule containingParserRule = GrammarUtil.containingParserRule(ruleCall);
Assignment containingAssignment = GrammarUtil.containingAssignment(ruleCall);
@@ -135,8 +155,7 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
defaultDisplayString = "\"" + defaultDisplayString + "\"";
}
- return Collections.singletonList(createCompletionProposal(containingAssignment, model, defaultDisplayString,
- offset));
+ return Collections.singletonList(createCompletionProposal(containingAssignment, defaultDisplayString, contentAssistContext));
}
/**
@@ -169,8 +188,7 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
*
* @return a list of <code>ICompletionProposal</code> matching the given assignment
*/
- protected List<? extends ICompletionProposal> lookupCrossReference(CrossReference crossReference, EObject model,
- String prefix, int offset) {
+ protected List<? extends ICompletionProposal> lookupCrossReference(CrossReference crossReference, IContentAssistContext contentAssistContext) {
List<ICompletionProposal> completionProposalList = new ArrayList<ICompletionProposal>();
@@ -179,12 +197,12 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
if (!GrammarUtil.isDatatypeRule(containingParserRule)) {
final EClass eClass = (EClass) containingParserRule.getType().getType();
final EReference ref = GrammarUtil.getReference(crossReference, eClass);
- final String trimmedPrefix = prefix.trim();
- final Iterable<IScopedElement> candidates = linkingCandidatesService.getLinkingCandidates(model, ref);
+ final String trimmedPrefix = contentAssistContext.getMatchString().trim();
+ final Iterable<IScopedElement> candidates = linkingCandidatesService.getLinkingCandidates(contentAssistContext.getModel(), ref);
for (IScopedElement candidate : candidates) {
- if (candidate.name() != null && isCandidateMatchingPrefix(model, ref, candidate, trimmedPrefix)) {
+ if (candidate.name() != null && isCandidateMatchingPrefix(contentAssistContext.getModel(), ref, candidate, trimmedPrefix)) {
completionProposalList.add(
- createCompletionProposal(crossReference, model, candidate.name(), offset));
+ createCompletionProposal(crossReference, candidate.name(), contentAssistContext));
}
}
}
@@ -202,10 +220,8 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
/**
* @return a new <code>XtextCompletionProposal</code> for the given text and offset.
*/
- protected final XtextCompletionProposal createCompletionProposal(AbstractElement abstractElement, EObject model,
- String text, int offset) {
- return new XtextCompletionProposal(abstractElement, model, text, new StyledString(text), text,
- getDefaultImageFilePath(), getPluginId(), offset);
+ protected ICompletionProposal createCompletionProposal(AbstractElement abstractElement, String displayString,IContentAssistContext contentAssistContext) {
+ return new XtextCompletionProposal(abstractElement,displayString,contentAssistContext);
}
/**
@@ -218,8 +234,7 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
* @see #sortAndFilter(List, EObject, String, IDocument, int, AbstractNode, LeafNode)
*/
protected List<? extends ICompletionProposal> doSortAndFilter(
- List<? extends ICompletionProposal> completionProposalList, EObject model, String prefix,
- IDocument document, int offset) {
+ List<? extends ICompletionProposal> completionProposalList, IContentAssistContext contentAssistContext) {
Map<String, ICompletionProposal> displayString2ICompletionProposalMap = new HashMap<String, ICompletionProposal>();
@@ -233,7 +248,7 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
displayString2ICompletionProposalMap.put(completionProposal.getDisplayString(), completionProposal);
// filter by prefix
- if (isFiltered(model, prefix, completionProposal)) {
+ if (isFiltered(completionProposal)) {
if (logger.isDebugEnabled()) {
logger.debug("filter completionProposal '" + completionProposal + "'");
}
@@ -257,18 +272,16 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
* The default behaviour of this method delegates to {@link XtextCompletionProposal#matches(String)} to
* test if the given prefix string matches or not.
*
- * @param model the last semtantically complete object
- * @param prefix
* @param completionProposal contains information used to present the proposed completion to the user
* @return true or false whether the given prefix matches the text of this completion proposal
*/
- protected boolean isFiltered(EObject model, String prefix, ICompletionProposal completionProposal) {
+ protected boolean isFiltered(ICompletionProposal completionProposal) {
if (completionProposal instanceof XtextCompletionProposal) {
XtextCompletionProposal xtextCompletionProposal = (XtextCompletionProposal) completionProposal;
- return !xtextCompletionProposal.matches(prefix);
+ return !xtextCompletionProposal.matches();
}
return false;
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistContextAdapter.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistContextAdapter.java
deleted file mode 100644
index 615ca53..0000000
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistContextAdapter.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
- * 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
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-package org.eclipse.xtext.ui.common.editor.codecompletion;
-
-import org.eclipse.emf.common.notify.impl.AdapterImpl;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.GrammarUtil;
-import org.eclipse.xtext.ParserRule;
-import org.eclipse.xtext.parsetree.AbstractNode;
-import org.eclipse.xtext.parsetree.CompositeNode;
-
-/**
- * Represents a custom emf adapter to adapt or extend the behaviour of emf
- * models used to provide CA related context information.
- *
- * @author Michael Clay - Initial contribution and API
- * @see org.eclipse.emf.common.notify.Adapter
- */
-public class ContentAssistContextAdapter extends AdapterImpl {
-
- private CompositeNode rootNode;
-
- private AbstractNode lastCompleteNode;
-
- private AbstractNode currentNode;
-
- private String prefix;
-
- private int offset;
-
- public ContentAssistContextAdapter(CompositeNode rootNode, AbstractNode currentNode, AbstractNode lastCompleteNode,
- int offset, String prefix) {
- super();
- this.rootNode = rootNode;
- this.currentNode = currentNode;
- this.lastCompleteNode = lastCompleteNode;
- this.offset = offset;
- this.prefix = prefix;
- }
-
- /**
- * @return true or false wheter the cursor is at the the last complete node
- */
- public boolean isCusorAtEndOfLastCompleteNode() {
- return lastCompleteNode == currentNode;
- }
-
- /**
- * @return the grammar element of the current node
- */
- public EObject getCurrentGrammarElement() {
-
- EObject grammarElement = GrammarUtil.containingAssignment(currentNode.getGrammarElement());
-
- if (null == grammarElement) {
- grammarElement = (currentNode.getGrammarElement() instanceof ParserRule ? ((ParserRule) currentNode
- .getGrammarElement()).getAlternatives()
- : currentNode.getGrammarElement());
- }
-
- return grammarElement;
- }
-
- @Override
- public boolean isAdapterForType(Object type) {
- return type == ContentAssistContextAdapter.class;
- }
-
- /**
- * @return the rootNode
- */
- public CompositeNode getRootNode() {
- return rootNode;
- }
-
- /**
- * @param rootNode
- * the rootNode to set
- */
- public void setRootNode(CompositeNode rootNode) {
- this.rootNode = rootNode;
- }
-
- /**
- * @return the lastCompleteNode
- */
- public AbstractNode getLastCompleteNode() {
- return lastCompleteNode;
- }
-
- /**
- * @param lastCompleteNode
- * the lastCompleteNode to set
- */
- public void setLastCompleteNode(AbstractNode lastCompleteNode) {
- this.lastCompleteNode = lastCompleteNode;
- }
-
- /**
- * @return the currentNode
- */
- public AbstractNode getCurrentNode() {
- return currentNode;
- }
-
- /**
- * @param currentNode
- * the currentNode to set
- */
- public void setCurrentNode(AbstractNode currentNode) {
- this.currentNode = currentNode;
- }
-
- /**
- * @return the prefix
- */
- public String getPrefix() {
- return prefix;
- }
-
- /**
- * @param prefix
- * the prefix to set
- */
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
-
- /**
- * @return the offset
- */
- public int getOffset() {
- return offset;
- }
-
- /**
- * @param offset
- * the offset to set
- */
- public void setOffset(int offset) {
- this.offset = offset;
- }
-
-}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/DefaultContentAssistProcessor.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/DefaultContentAssistProcessor.java
index a5a3f75..f685444 100644
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/DefaultContentAssistProcessor.java
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/DefaultContentAssistProcessor.java
@@ -1,234 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
package org.eclipse.xtext.ui.common.editor.codecompletion;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
+import java.util.Arrays;
import java.util.List;
-import java.util.Set;
import org.apache.log4j.Logger;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.emf.common.notify.Adapter;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ContextInformationValidator;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
-import org.eclipse.swt.custom.StyledText;
+import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.xtext.AbstractElement;
-import org.eclipse.xtext.Assignment;
-import org.eclipse.xtext.CrossReference;
-import org.eclipse.xtext.EcoreUtil2;
-import org.eclipse.xtext.GrammarUtil;
-import org.eclipse.xtext.Keyword;
-import org.eclipse.xtext.ParserRule;
-import org.eclipse.xtext.RuleCall;
-import org.eclipse.xtext.crossref.ILinkingService;
-import org.eclipse.xtext.parser.IParseResult;
-import org.eclipse.xtext.parsetree.AbstractNode;
-import org.eclipse.xtext.parsetree.CompositeNode;
-import org.eclipse.xtext.parsetree.LeafNode;
-import org.eclipse.xtext.parsetree.NodeUtil;
-import org.eclipse.xtext.parsetree.ParseTreeUtil;
-import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.service.IServiceScope;
import org.eclipse.xtext.service.Inject;
-import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
-import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
+import org.eclipse.xtext.service.ServiceRegistry;
+import org.eclipse.xtext.ui.common.editor.codecompletion.impl.DefaultContentAssistContext;
+import org.eclipse.xtext.ui.common.editor.codecompletion.impl.DefaultTemplateContentAssistProcessor;
+import org.eclipse.xtext.ui.common.editor.codecompletion.impl.DefaultContentAssistCalculator;
+import org.eclipse.xtext.ui.common.editor.codecompletion.impl.ProposalProviderInvokerSwitch;
/**
+ * The default implementation of interface {@link IContentAssistProcessor} provided with Xtext.
+ *
* @author Michael Clay - Initial contribution and API
- * @author Dennis Hübner - Initial contribution and API
* @author Heiko Behrens
*/
public class DefaultContentAssistProcessor implements IContentAssistProcessor {
// logger available to subclasses
protected final Logger logger = Logger.getLogger(getClass());
+
+ @Inject (optional=true)
+ private ITemplateContentAssistProcessor templateContentAssistProcessor;
+ @Inject (optional=true)
+ private IContentAssistCalculator contentAssistCalculator;
+
@Inject
private IProposalProvider proposalProvider;
@Inject
- private ILinkingService linkingService;
-
+ protected IServiceScope serviceScope;
/**
- * computes the possible grammar elements following the one at the given offset and calls the respective methods on
+ * Computes the possible grammar elements following the one at the given offset and calls the respective methods on
* the proposal provider.
*/
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, final int offset) {
ICompletionProposal[] completionProposals = null;
- IDocument document = viewer.getDocument();
-
- if (document instanceof IXtextDocument) {
-
- List<ICompletionProposal> completionProposalList = new ArrayList<ICompletionProposal>();
-
- IXtextDocument xtextDocument = (IXtextDocument) document;
-
- CompositeNode rootNode = xtextDocument.readOnly(new UnitOfWork<CompositeNode>() {
- public CompositeNode exec(XtextResource resource) throws Exception {
- IParseResult parseResult = resource.getParseResult();
- Assert.isNotNull(parseResult);
- return parseResult.getRootNode();
- }
- });
-
- Assert.isNotNull(rootNode);
-
- AbstractNode lastCompleteNode = ParseTreeUtil.getLastCompleteNodeByOffset(rootNode, offset);
-
- AbstractNode currentNode = ParseTreeUtil.getCurrentOrFollowingNodeByOffset(rootNode, offset);
-
- String prefix = calculatePrefix(viewer, offset, currentNode);
-
- EObject model = lastCompleteNode instanceof AbstractNode ? NodeUtil
- .getNearestSemanticObject((AbstractNode) lastCompleteNode) : lastCompleteNode;
-
- addOrReplaceCaContextAdapter(model, new ContentAssistContextAdapter(rootNode,currentNode,lastCompleteNode,offset,prefix));
-
- Set<AbstractElement> nextValidElementSet = new LinkedHashSet<AbstractElement>();
- /**
- * in case of a crossreference which isnt linked properly we evaluate or propose it again
- */
- if (lastCompleteNode.getGrammarElement() instanceof CrossReference && !isLinked(lastCompleteNode)) {
- nextValidElementSet.add(getAbstractElement(lastCompleteNode));
- nextValidElementSet.addAll(ParseTreeUtil.getElementSetValidFromOffset(rootNode, lastCompleteNode,
- offset));
- }
- /**
- * in case of 'at-the-end' of the previous,completed element we evaluate it again for
- * 'right-to-left-backtracking' cases (e.g. for keyword 'kind' kind>|< |=cursorpos)
- */
- else if (lastCompleteNode == currentNode) {
-
- Assignment containingAssignment = GrammarUtil
- .containingAssignment(lastCompleteNode.getGrammarElement());
-
- if (lastCompleteNode.getGrammarElement() instanceof RuleCall && containingAssignment != null) {
- nextValidElementSet.add(containingAssignment);
- nextValidElementSet.addAll(ParseTreeUtil.getElementSetValidFromOffset(rootNode, lastCompleteNode,
- offset));
- }
- else {
- nextValidElementSet = ParseTreeUtil.getElementSetValidFromOffset(rootNode, lastCompleteNode, offset);
- nextValidElementSet.add(getAbstractElement(lastCompleteNode));
- }
- }
- else {
- nextValidElementSet = ParseTreeUtil.getElementSetValidFromOffset(rootNode, lastCompleteNode, offset);
- }
-
- ProposalProviderInvokerSwitch proposalProviderInvokerSwitch = new ProposalProviderInvokerSwitch(model,
- document, offset, prefix, proposalProvider);
-
- for (List<EObject> resolvedElementOrRuleList : new ProposalCandidateResolverSwitch(nextValidElementSet)) {
-
- List<ICompletionProposal> collectedCompletionProposalList = proposalProviderInvokerSwitch
- .collectCompletionProposalList(resolvedElementOrRuleList);
-
- completionProposalList.addAll(collectedCompletionProposalList);
- }
-
- if (completionProposalList != null) {
- List<? extends ICompletionProposal> processedCompletionProposalList = proposalProvider.sortAndFilter(
- completionProposalList, model, prefix, document, offset);
- completionProposals = processedCompletionProposalList.toArray(
- new ICompletionProposal[processedCompletionProposalList.size()]);
- }
-
+ IContentAssistContext contentAssistContext = getContentAssistContext(viewer, offset);
+
+ List<AbstractElement> computeProposalElements = getContentAssistCalculator().computeProposalElements(
+ contentAssistContext);
+
+ ProposalProviderInvokerSwitch proposalProviderInvokerSwitch = new ProposalProviderInvokerSwitch(
+ contentAssistContext, proposalProvider);
+
+ List<ICompletionProposal> completionProposalList = proposalProviderInvokerSwitch
+ .collectCompletionProposalList(computeProposalElements);
+
+ for (TemplateContextType templateContextType : proposalProviderInvokerSwitch.getTemplateContextTypeList()) {
+ addTemplates(viewer, offset, contentAssistContext, templateContextType, completionProposalList);
}
+ List<? extends ICompletionProposal> processedCompletionProposalList = proposalProvider.sortAndFilter(
+ completionProposalList, contentAssistContext);
+
+ completionProposals = processedCompletionProposalList
+ .toArray(new ICompletionProposal[processedCompletionProposalList.size()]);
+
return completionProposals;
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+ */
public char[] getCompletionProposalAutoActivationCharacters() {
return null;
}
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
+ */
public String getErrorMessage() {
return null;
}
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
+ */
public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
return null;
}
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+ */
public char[] getContextInformationAutoActivationCharacters() {
return null;
}
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
+ */
public IContextInformationValidator getContextInformationValidator() {
return new ContextInformationValidator(this);
}
- protected String calculatePrefix(ITextViewer viewer, final int offset, AbstractNode abstractNode) {
-
- if (abstractNode == null)
- return "";
-
- String prefix = "";
- StyledText textWidget = viewer.getTextWidget();
- if (textWidget.getCharCount() > 0) {
- int boundedOffset = Math.min(offset, textWidget.getCharCount()) - 1;
- if (abstractNode.getTotalOffset() <= boundedOffset)
- prefix = textWidget.getText(abstractNode.getTotalOffset(), boundedOffset);
- }
-
- // if cursor is behind a complete keyword, accept any input => empty
- // prefix
- // TODO: Find a way to distinguish between keywords like "+" or "-" and
- // "extends" or "class"
- // in the latter case, the prefix "" would not always be sufficient
- if (abstractNode.getGrammarElement() instanceof Keyword && (abstractNode instanceof LeafNode && ((LeafNode)abstractNode).getText().equals(prefix))) {
- prefix = "";
+ /**
+ * adds templates to the list of proposals
+ *
+ * @param viewer the viewer whose document is used to compute the proposals
+ * @param offset an offset within the document for which completions should be computed
+ * @param contentAssistContext the current context of the content assist proposal request
+ * @param templateContextType within which templates are resolved
+ * @param completionProposalList list of proposal to add to
+ */
+ protected void addTemplates(ITextViewer viewer, int offset, IContentAssistContext contentAssistContext,
+ TemplateContextType templateContextType, List<ICompletionProposal> completionProposalList) {
+ if (getTemplateContentAssistProcessor() != null) {
+ getTemplateContentAssistProcessor().setContentAssistContext(contentAssistContext);
+ getTemplateContentAssistProcessor().setContextType(templateContextType);
+ completionProposalList.addAll(Arrays.asList(getTemplateContentAssistProcessor().computeCompletionProposals(
+ viewer, offset)));
}
-
- return prefix;
}
-
- private void addOrReplaceCaContextAdapter(EObject model, ContentAssistContextAdapter contentAssistContextAdapter) {
+ /**
+ * @param viewer the viewer whose document is used to compute the proposals
+ * @param offset an offset within the document for which completions should be computed
+ * @return an implementation of <code>IContentAssistContext</code>
+ */
+ protected IContentAssistContext getContentAssistContext(ITextViewer textViewer,int offset) {
+ return new DefaultContentAssistContext(textViewer,offset);
- if (model != null) {
-
- Adapter existingAdapter = EcoreUtil.getAdapter(model.eAdapters(), ContentAssistContextAdapter.class);
-
- if (existingAdapter != null) {
- model.eAdapters().remove(existingAdapter);
- }
-
- model.eAdapters().add(contentAssistContextAdapter);
- }
}
-
- private boolean isLinked(AbstractNode lastCompleteNode) {
- EObject semanticModel = NodeUtil.getNearestSemanticObject(lastCompleteNode);
- CrossReference crossReference = (CrossReference) lastCompleteNode.getGrammarElement();
- EReference eReference = GrammarUtil.getReference(crossReference, semanticModel.eClass());
-
- List<EObject> referencedObjects = EcoreUtil2.getAllReferencedObjects(semanticModel, eReference);
-
- if (referencedObjects.isEmpty())
- return false;
- else {
- List<EObject> linkCandidates = linkingService.getLinkedObjects(semanticModel, eReference,
- (LeafNode) lastCompleteNode);
- return !linkCandidates.isEmpty() && referencedObjects.containsAll(linkCandidates);
+ /**
+ * @return an implementation of <code>ITemplateContentAssistProcessor</code>
+ */
+ protected ITemplateContentAssistProcessor getTemplateContentAssistProcessor() {
+ if (templateContentAssistProcessor == null) {
+ templateContentAssistProcessor = new DefaultTemplateContentAssistProcessor();
+ ServiceRegistry.injectServices(this.serviceScope, templateContentAssistProcessor);
}
+ return templateContentAssistProcessor;
}
- private AbstractElement getAbstractElement(AbstractNode lastCompleteNode) {
- return (AbstractElement) (lastCompleteNode.getGrammarElement() instanceof ParserRule ?
- ((ParserRule)lastCompleteNode.getGrammarElement()).getAlternatives(): lastCompleteNode.getGrammarElement());
+ /**
+ * @return an implementation of <code>IContentAssistCalculator</code>
+ */
+ protected IContentAssistCalculator getContentAssistCalculator() {
+ if (this.contentAssistCalculator == null) {
+ contentAssistCalculator = new DefaultContentAssistCalculator();
+ ServiceRegistry.injectServices(this.serviceScope, contentAssistCalculator);
+ }
+ return contentAssistCalculator;
}
+
+
}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistCalculator.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistCalculator.java
new file mode 100644
index 0000000..9a265de
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistCalculator.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion;
+
+import java.util.List;
+
+import org.eclipse.xtext.AbstractElement;
+
+/**
+ * Strategy interface for calculating a list of <code>AbstractElement</code> elements which are applicable for
+ * the provided <code>IContentAssistContext</code>.
+ *
+ * @author Michael Clay - Initial contribution and API
+ */
+public interface IContentAssistCalculator {
+
+ /**
+ * Calculate a list of <code>AbstractElement</code> matching the provided <code>IContentAssistContext</code>.
+ *
+ * @param contentAssistContext the current context of the content assist proposal request
+ * @return the list of <code>AbstractElement</code> matching the provided <code>IContentAssistContext</code>.
+ */
+ List<AbstractElement> computeProposalElements(IContentAssistContext contentAssistContext);
+}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistContext.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistContext.java
new file mode 100644
index 0000000..1bb6e44
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IContentAssistContext.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.parsetree.AbstractNode;
+import org.eclipse.xtext.parsetree.CompositeNode;
+import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
+
+/**
+ * Abstraction of a commonly used set of attributes related to the current content assist request.
+ *
+ * @author Michael Clay - Initial contribution and API
+ */
+public interface IContentAssistContext {
+ /**
+ * @return the root node of the document which is used to compute the proposals
+ */
+ CompositeNode getRootNode();
+
+ /**
+ * @return the string that is already entered by the user prior to requesting content assist
+ */
+ String getMatchString();
+
+ /**
+ * @return the last node (on a none hidden channel) that starts at or spans across the cursor position the user requested content assist for
+ */
+ AbstractNode getNode();
+
+ /**
+ * @return the nearest node with an existing grammar element set (i.e. valid according to the underlying grammar)
+ */
+ AbstractNode getReferenceNode();
+
+ /**
+ * @return the most specific model element under the cursor the user requested content assist for
+ */
+ EObject getModel();
+
+ /**
+ * @return the <code>XtextDocument</code> used to compute the proposals
+ */
+ IXtextDocument getDocument();
+
+ /**
+ * @return the position in the document described by this context.
+ */
+ int getOffSet();
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IProposalProvider.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IProposalProvider.java
index c4d35f9..b86423f 100644
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IProposalProvider.java
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IProposalProvider.java
@@ -2,13 +2,12 @@ package org.eclipse.xtext.ui.common.editor.codecompletion;
import java.util.List;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.RuleCall;
-
/**
*
* This is just a marker interface.
@@ -44,38 +43,60 @@ public interface IProposalProvider {
* Is invoked by the framework if (with respect to the grammar) it is possible that the keyword passed as first parameter
* can occur next up.
*
- * @param keyword - the keyword to be completed
- * @param model - the most specific model element under the cursor.
- * @param prefix - the prefix under the cursor or null if there is no prefix
- * @param document - the IDocument instance used by the editor
- * @param offset - an offset within the document for which completions should be computed
+ * @param keyword the <code>Keyword</code> to be completed
+ * @param contentAssistContext the current context of the content assist
* @return a list of matching {@link ICompletionProposal}
*/
- public List<? extends ICompletionProposal> completeKeyword(Keyword keyword, EObject model, String prefix, IDocument document,int offset);
+ List<? extends ICompletionProposal> completeKeyword(Keyword keyword, IContentAssistContext contentAssistContext);
/**
* Is invoked by the framework if (with respect to the grammar) it is possible that the keyword passed as first parameter
* can occure next up.
*
- * @param ruleCall - the keyword to be completed
- * @param model - the most specific model element under the cursor.
- * @param prefix - the prefix under the cursor or null if there is no prefix
- * @param document - the IDocument instance used by the editor
- * @param offset - an offset within the document for which completions should be computed
+ * @param ruleCall the <code>RuleCall</code> to be completed
+ * @param contentAssistContext the current context of the content assist
* @return a list of matching {@link ICompletionProposal}
*/
- public List<? extends ICompletionProposal> completeRuleCall(RuleCall ruleCall, EObject model, String prefix, IDocument document,int offset);
-
+ List<? extends ICompletionProposal> completeRuleCall(RuleCall ruleCall, IContentAssistContext contentAssistContext);
+
+ /**
+ * Returns the context type that can handle template insertion at the given region
+ * in the viewer's document.
+ *
+ * @param keyword the <code>Keyword</code> to be completed
+ * @param contentAssistContext the current context of the content assist
+ * @return the context type that can handle template expansion for the given location, or <code>null</code> if none exists
+ */
+ TemplateContextType getTemplateContextType(Keyword keyword, IContentAssistContext contentAssistContext);
+
+ /**
+ * Returns the context type that can handle template insertion at the given region
+ * in the viewer's document.
+ *
+ * @param ruleCall the <code>RuleCall</code>
+ * @param contentAssistContext the current context of the content assist
+ * @return the context type that can handle template expansion for the given location, or <code>null</code> if none exists
+ */
+ TemplateContextType getTemplateContextType(RuleCall ruleCall, IContentAssistContext contentAssistContext);
+
+ /**
+ * Returns the templates valid for the context type specified by <code>contextTypeId</code>.
+ *
+ * @param contextTypeId the context type id
+ * @return the templates valid for this context type id
+ */
+ Template[] getTemplates(String contextTypeId);
+
+
/**
* Used to filter and sort a list of completion proposals.
* This method is invoked by the framework after all possible completions have been collected.
* @param completionProposalList matching {@link ICompletionProposal} to sort and filter
- * @param model - the most specific model element under the cursor.
- * @param prefix - the prefix under the cursor or null if there is no prefix
- * @param document - the IDocument instance used by the editor
- * @param offset - an offset within the document for which completions should be computed
+ * @param contentAssistContext the current context of the content assist
* @return the sorted and filtered <code>ICompletionProposal</code> list.
- *
*/
- public List<? extends ICompletionProposal> sortAndFilter(List<? extends ICompletionProposal> completionProposalList,EObject model, String prefix, IDocument document,int offset);
+ List<? extends ICompletionProposal> sortAndFilter(List<? extends ICompletionProposal> completionProposalList,IContentAssistContext contentAssistContext);
+
+
+
}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ITemplateContentAssistProcessor.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ITemplateContentAssistProcessor.java
new file mode 100644
index 0000000..0dd0605
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ITemplateContentAssistProcessor.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion;
+
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+/**
+ * Strategy interface for computing template proposals matching the given <code>TemplateContextType</code> and
+ * <code>IContentAssistContext</code>.
+ *
+ * @author Michael Clay - Initial contribution and API
+ */
+public interface ITemplateContentAssistProcessor extends IContentAssistProcessor {
+
+ /**
+ * @param contextType the context type that can handle template expansion for the given contentAssistContext (must not be null)
+ */
+ void setContextType(TemplateContextType contextType);
+
+ /**
+ * @param contentAssistContext the current context of the content assist proposal request (must not be null)
+ */
+ void setContentAssistContext(IContentAssistContext contentAssistContext);
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ProposalCandidateResolverSwitch.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ProposalCandidateResolverSwitch.java
deleted file mode 100644
index 91f1a09..0000000
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ProposalCandidateResolverSwitch.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
- * 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
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-package org.eclipse.xtext.ui.common.editor.codecompletion;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.AbstractElement;
-import org.eclipse.xtext.AbstractRule;
-import org.eclipse.xtext.Alternatives;
-import org.eclipse.xtext.Assignment;
-import org.eclipse.xtext.CrossReference;
-import org.eclipse.xtext.GrammarUtil;
-import org.eclipse.xtext.Group;
-import org.eclipse.xtext.ParserRule;
-import org.eclipse.xtext.RuleCall;
-import org.eclipse.xtext.util.XtextSwitch;
-
-/**
- * Represents a <b>Switch</b> for the Xtext model's inheritance hierarchy to
- * resolve (or flatten) 'container' level elements like <code>Group</code> or
- * <code>Alternatives</code> to gather potential completion proposal candidates.
- *
- * It supports the call {@link #doSwitch(EObject) doSwitch(object)} instead of
- * typical <code>if (x instanceof y)</code> code blocks.
- *
- * @author Michael Clay - Initial contribution and API
- * @see org.eclipse.xtext.util.XtextSwitch
- */
-public class ProposalCandidateResolverSwitch extends XtextSwitch<List<EObject>> implements Iterable<List<EObject>> {
-
- private Iterator<? extends EObject> delegatingIterator;
-
- /**
- * @param elementCollection
- * to iterate and resolve
- */
- public ProposalCandidateResolverSwitch(Collection<? extends EObject> elementCollection) {
- this.delegatingIterator = elementCollection.iterator();
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Iterable#iterator()
- */
- public Iterator<List<EObject>> iterator() {
- return new Iterator<List<EObject>>() {
- public boolean hasNext() {
- return delegatingIterator.hasNext();
- }
-
- public List<EObject> next() {
- return doSwitch(delegatingIterator.next());
- }
-
- public void remove() {
- delegatingIterator.remove();
- }
-
- };
- }
-
- @Override
- public List<EObject> caseAlternatives(Alternatives alternatives) {
- List<EObject> elementList = new ArrayList<EObject>();
- for (AbstractElement alternativeElement : alternatives.getGroups()) {
- addWithNullCheck(elementList, doSwitch(alternativeElement));
- }
- return elementList;
- }
-
- @Override
- public List<EObject> caseGroup(Group group) {
- List<EObject> elementList = new ArrayList<EObject>();
- boolean includeNext = true;
- for (Iterator<AbstractElement> iterator = group.getAbstractTokens().iterator(); iterator.hasNext()
- && includeNext;) {
- AbstractElement groupElement = iterator.next();
- addWithNullCheck(elementList, doSwitch(groupElement));
- includeNext = GrammarUtil.isOptionalCardinality(groupElement);
- }
- return elementList;
- }
-
- @Override
- public List<EObject> caseAssignment(Assignment assignment) {
- List<EObject> elementList = new ArrayList<EObject>();
- if (assignment.getTerminal() instanceof RuleCall) {
- addWithNullCheck(elementList, doSwitch(assignment.getTerminal()));
- }
- else if (assignment.getTerminal() instanceof Alternatives) {
- addWithNullCheck(elementList, doSwitch(assignment.getTerminal()));
- }
- elementList.add(assignment);
- return elementList;
- }
-
- @Override
- public List<EObject> caseRuleCall(RuleCall ruleCall) {
- List<EObject> elementList = new ArrayList<EObject>();
- elementList.add(ruleCall);
-
- AbstractRule abstractRule = ruleCall.getRule();
-
- if (abstractRule instanceof ParserRule) {
- addWithNullCheck(elementList, doSwitch(((ParserRule) abstractRule).getAlternatives()));
- }
- return elementList;
- }
-
- @Override
- public List<EObject> caseCrossReference(CrossReference crossReference) {
- return Collections.singletonList(crossReference.eContainer());
- }
-
- @Override
- public List<EObject> defaultCase(EObject object) {
- return Collections.singletonList(object);
- }
-
- private void addWithNullCheck(List<EObject> source, List<EObject> list) {
- if (null != list) {
- source.addAll(list);
- }
- }
-
-}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistCalculator.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistCalculator.java
new file mode 100644
index 0000000..6cc28e8
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistCalculator.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.xtext.AbstractElement;
+import org.eclipse.xtext.AbstractRule;
+import org.eclipse.xtext.Alternatives;
+import org.eclipse.xtext.Assignment;
+import org.eclipse.xtext.CrossReference;
+import org.eclipse.xtext.EcoreUtil2;
+import org.eclipse.xtext.GrammarUtil;
+import org.eclipse.xtext.Group;
+import org.eclipse.xtext.ParserRule;
+import org.eclipse.xtext.RuleCall;
+import org.eclipse.xtext.crossref.ILinkingService;
+import org.eclipse.xtext.parsetree.AbstractNode;
+import org.eclipse.xtext.parsetree.LeafNode;
+import org.eclipse.xtext.parsetree.NodeUtil;
+import org.eclipse.xtext.parsetree.ParseTreeUtil;
+import org.eclipse.xtext.service.Inject;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistCalculator;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
+import org.eclipse.xtext.util.XtextSwitch;
+
+/**
+ * Provides a default implementation of interface {@link IContentAssistContext} designed as <b>Switch</b> over the
+ * Xtext ecore inheritance hierarchy to calculate and resolve (or flatten) 'container' level elements like
+ * <code>Group</code> or <code>Alternatives</code> to gather potential completion proposal candidates.
+ *
+ * It supports the call {@link #doSwitch(EObject) doSwitch(object)} instead of
+ * typical <code>if (x instanceof y)</code> code blocks.
+ *
+ * @author Michael Clay - Initial contribution and API
+ * @see org.eclipse.xtext.util.XtextSwitch
+ */
+public class DefaultContentAssistCalculator extends XtextSwitch<List<AbstractElement>> implements IContentAssistCalculator {
+
+ @Inject
+ private ILinkingService linkingService;
+
+ public List<AbstractElement> computeProposalElements(IContentAssistContext contentAssistContext) {
+
+ List<AbstractElement> computedElementList = new ArrayList<AbstractElement>();
+
+ Set<AbstractElement> nextValidElementSet = new LinkedHashSet<AbstractElement>();
+
+ AbstractNode referenceNode=contentAssistContext.getReferenceNode();
+ /**
+ * in case of a crossreference which isnt linked properly we evaluate or
+ * propose it again
+ */
+ if (referenceNode.getGrammarElement() instanceof CrossReference && !isLinked(referenceNode)) {
+ nextValidElementSet.add(getAbstractElement(referenceNode));
+ nextValidElementSet.addAll(ParseTreeUtil.getElementSetValidFromOffset(contentAssistContext.getRootNode(),
+ referenceNode, contentAssistContext.getOffSet()));
+ }
+ /**
+ * in case of 'at-the-end' of the previous,completed element we evaluate
+ * it again for 'right-to-left-backtracking' cases (e.g. for keyword
+ * 'kind' kind>|< |=cursorpos)
+ */
+ else if (referenceNode == contentAssistContext.getNode()) {
+
+ Assignment containingAssignment = GrammarUtil.containingAssignment(referenceNode.getGrammarElement());
+
+ if (referenceNode.getGrammarElement() instanceof RuleCall && containingAssignment != null) {
+ nextValidElementSet.add(containingAssignment);
+ nextValidElementSet.addAll(ParseTreeUtil.getElementSetValidFromOffset(contentAssistContext
+ .getRootNode(), referenceNode, contentAssistContext.getOffSet()));
+ }
+ else {
+ nextValidElementSet = ParseTreeUtil.getElementSetValidFromOffset(contentAssistContext.getRootNode(),
+ referenceNode, contentAssistContext.getOffSet());
+ nextValidElementSet.add(getAbstractElement(referenceNode));
+ }
+ }
+ else {
+ nextValidElementSet = ParseTreeUtil.getElementSetValidFromOffset(contentAssistContext.getRootNode(),
+ referenceNode, contentAssistContext.getOffSet());
+ }
+
+ for (Iterator<AbstractElement> iterator = nextValidElementSet.iterator(); iterator.hasNext();) {
+ AbstractElement abstractElement = (AbstractElement) iterator.next();
+ computedElementList.addAll(doSwitch(abstractElement));
+ }
+
+ return computedElementList;
+ }
+
+
+ @Override
+ public List<AbstractElement> caseAlternatives(Alternatives alternatives) {
+ List<AbstractElement> elementList = new ArrayList<AbstractElement>();
+ for (AbstractElement alternativeElement : alternatives.getGroups()) {
+ addWithNullCheck(elementList, doSwitch(alternativeElement));
+ }
+ return elementList;
+ }
+
+ @Override
+ public List<AbstractElement> caseGroup(Group group) {
+ List<AbstractElement> elementList = new ArrayList<AbstractElement>();
+ boolean includeNext = true;
+ for (Iterator<AbstractElement> iterator = group.getAbstractTokens().iterator(); iterator.hasNext()
+ && includeNext;) {
+ AbstractElement groupElement = iterator.next();
+ addWithNullCheck(elementList, doSwitch(groupElement));
+ includeNext = GrammarUtil.isOptionalCardinality(groupElement);
+ }
+ return elementList;
+ }
+
+ @Override
+ public List<AbstractElement> caseAssignment(Assignment assignment) {
+ List<AbstractElement> elementList = new ArrayList<AbstractElement>();
+ if (assignment.getTerminal() instanceof RuleCall) {
+ addWithNullCheck(elementList, doSwitch(assignment.getTerminal()));
+ }
+ else if (assignment.getTerminal() instanceof Alternatives) {
+ addWithNullCheck(elementList, doSwitch(assignment.getTerminal()));
+ }
+ elementList.add(assignment);
+ return elementList;
+ }
+
+ @Override
+ public List<AbstractElement> caseRuleCall(RuleCall ruleCall) {
+ List<AbstractElement> elementList = new ArrayList<AbstractElement>();
+
+ elementList.add(ruleCall);
+
+ AbstractRule abstractRule = ruleCall.getRule();
+
+ if (abstractRule instanceof ParserRule) {
+ addWithNullCheck(elementList, doSwitch(((ParserRule) abstractRule).getAlternatives()));
+ }
+ return elementList;
+ }
+
+ @Override
+ public List<AbstractElement> caseCrossReference(CrossReference crossReference) {
+ return Collections.singletonList(((AbstractElement)crossReference.eContainer()));
+ }
+
+ @Override
+ public List<AbstractElement> defaultCase(EObject object) {
+ return Collections.singletonList(((AbstractElement)object));
+ }
+
+ private void addWithNullCheck(List<AbstractElement> source, List<AbstractElement> list) {
+ if (null != list) {
+ source.addAll(list);
+ }
+ }
+
+ private AbstractElement getAbstractElement(AbstractNode lastCompleteNode) {
+ return (AbstractElement) (lastCompleteNode.getGrammarElement() instanceof ParserRule ?
+ ((ParserRule)lastCompleteNode.getGrammarElement()).getAlternatives(): lastCompleteNode.getGrammarElement());
+ }
+
+ private boolean isLinked(AbstractNode lastCompleteNode) {
+ EObject semanticModel = NodeUtil.getNearestSemanticObject(lastCompleteNode);
+ CrossReference crossReference = (CrossReference) lastCompleteNode.getGrammarElement();
+ EReference eReference = GrammarUtil.getReference(crossReference, semanticModel.eClass());
+
+ List<EObject> referencedObjects = EcoreUtil2.getAllReferencedObjects(semanticModel, eReference);
+
+ if (referencedObjects.isEmpty())
+ return false;
+ else {
+ List<EObject> linkCandidates = linkingService.getLinkedObjects(semanticModel, eReference,
+ (LeafNode) lastCompleteNode);
+ return !linkCandidates.isEmpty() && referencedObjects.containsAll(linkCandidates);
+ }
+ }
+
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistContext.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistContext.java
new file mode 100644
index 0000000..ac1d29d
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultContentAssistContext.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion.impl;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.xtext.Keyword;
+import org.eclipse.xtext.parsetree.AbstractNode;
+import org.eclipse.xtext.parsetree.CompositeNode;
+import org.eclipse.xtext.parsetree.LeafNode;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
+import org.eclipse.xtext.ui.core.editor.IXtextSourceViewer;
+import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
+
+/**
+ * Provides a default implementation of interface {@link IContentAssistContext}.
+ *
+ * @author Michael Clay - Initial contribution and API
+ * @see IContentAssistContext
+ */
+public class DefaultContentAssistContext implements IContentAssistContext {
+
+ private IXtextSourceViewer xtextSourceViewer;
+ private IXtextDocument xtextDocument;
+ private ITextViewer textViewer;
+ private String matchString;
+ private int offset;
+
+ public DefaultContentAssistContext(ITextViewer textViewer, int offset) {
+ this.xtextSourceViewer = ((IXtextSourceViewer) textViewer);
+ this.xtextDocument = (IXtextDocument) textViewer.getDocument();
+ this.textViewer = textViewer;
+ this.offset = offset;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext#getDocument()
+ */
+ public IXtextDocument getDocument() {
+ return this.xtextDocument;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext#getMatchString()
+ */
+ public String getMatchString() {
+ if (this.matchString == null) {
+ this.matchString = calculateMatchString(this.textViewer, this.offset);
+ }
+ return this.matchString;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext#getModel()
+ */
+ public EObject getModel() {
+ return this.xtextSourceViewer.getModel(this.offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext#getReferenceNode()
+ */
+ public AbstractNode getReferenceNode() {
+ return this.xtextSourceViewer.getReferenceNode(this.offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext#getNode()
+ */
+ public AbstractNode getNode() {
+ return this.xtextSourceViewer.getNode(this.offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext#getOffSet()
+ */
+ public int getOffSet() {
+ return this.offset;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext#getRootNode()
+ */
+ public CompositeNode getRootNode() {
+ return this.xtextSourceViewer.getRootNode();
+ }
+
+ protected String calculateMatchString(ITextViewer viewer, final int offset) {
+
+ if (getNode() == null)
+ return "";
+
+ String prefix = "";
+
+ StyledText textWidget = viewer.getTextWidget();
+
+ if (textWidget.getCharCount() > 0) {
+ int boundedOffset = Math.min(offset, textWidget.getCharCount()) - 1;
+ if (getNode().getTotalOffset() <= boundedOffset)
+ prefix = textWidget.getText(getNode().getTotalOffset(), boundedOffset).trim();
+ }
+
+ // if cursor is behind a complete keyword, accept any input => empty
+ // prefix
+ // TODO: Find a way to distinguish between keywords like "+" or "-"
+ // and"extends" or "class" in the latter case,
+ // the prefix "" would not always be sufficient
+ if (getNode().getGrammarElement() instanceof Keyword
+ && (getNode() instanceof LeafNode && ((LeafNode) getNode()).getText().equals(prefix))) {
+ prefix = "";
+ }
+
+ return prefix;
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultTemplateContentAssistProcessor.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultTemplateContentAssistProcessor.java
new file mode 100644
index 0000000..9a42ecb
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/DefaultTemplateContentAssistProcessor.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion.impl;
+
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateCompletionProcessor;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.xtext.IMetamodelAccess;
+import org.eclipse.xtext.service.Inject;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
+import org.eclipse.xtext.ui.common.editor.codecompletion.ILinkingCandidatesService;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
+import org.eclipse.xtext.ui.common.editor.codecompletion.ITemplateContentAssistProcessor;
+
+/**
+ * Provides a default implementation of interface {@link ITemplateContentAssistProcessor}.
+ *
+ * @author Michael Clay - Initial contribution and API
+ */
+public class DefaultTemplateContentAssistProcessor extends TemplateCompletionProcessor implements ITemplateContentAssistProcessor {
+
+ @Inject
+ private IProposalProvider proposalProvider;
+
+ @Inject
+ private ILinkingCandidatesService linkingCandidatesService;
+
+ @Inject
+ private IMetamodelAccess metamodelAccess;
+
+ private TemplateContextType contextType;
+
+ private IContentAssistContext contentAssistContext;
+
+ @Override
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+ return super.computeCompletionProposals(viewer, offset);
+ }
+
+ @Override
+ protected TemplateContextType getContextType(ITextViewer viewer, IRegion region) {
+ return this.contextType;
+ }
+
+ @Override
+ protected Image getImage(Template template) {
+ return null;
+ }
+
+ @Override
+ protected Template[] getTemplates(String contextTypeId) {
+ return this.proposalProvider.getTemplates(contextTypeId);
+ }
+
+ @Override
+ protected TemplateContext createContext(ITextViewer viewer, IRegion region) {
+
+ TemplateContextType contextType = getContextType(viewer, region);
+
+ if (contextType != null) {
+
+ return new XtextTemplateContext(contextType, viewer.getDocument(),
+ new Position(region.getOffset(), region.getLength()),
+ this.contentAssistContext,
+ this.linkingCandidatesService,
+ this.metamodelAccess);
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.ITemplateContentAssistProcessor#setContextType(org.eclipse.jface.text.templates.TemplateContextType)
+ */
+ public void setContextType(TemplateContextType contextType) {
+ this.contextType = contextType;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.ITemplateContentAssistProcessor#setContentAssistContext(org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext)
+ */
+ public void setContentAssistContext(IContentAssistContext contentAssistContext) {
+ this.contentAssistContext = contentAssistContext;
+ }
+
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ProposalProviderInvokerSwitch.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/ProposalProviderInvokerSwitch.java
index bb58a4a..643390e 100644
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/ProposalProviderInvokerSwitch.java
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/ProposalProviderInvokerSwitch.java
@@ -6,11 +6,12 @@
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
-package org.eclipse.xtext.ui.common.editor.codecompletion;
+package org.eclipse.xtext.ui.common.editor.codecompletion.impl;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -19,8 +20,9 @@ import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.GrammarUtil;
@@ -28,12 +30,14 @@ import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.TypeRef;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.util.XtextSwitch;
/**
* Represents a <b>Switch</b> for the Xtext model's inheritance hierarchy to
- * callback and invoke the completion methods of <code>IProposalProvider</code>
+ * callback and invoke the proposal completion methods of interface <code>IProposalProvider</code>
* implementations to gather and collect <code>ICompletionProposal</code> to be
* displayed for Content Assist.
*
@@ -47,39 +51,32 @@ import org.eclipse.xtext.util.XtextSwitch;
public class ProposalProviderInvokerSwitch extends XtextSwitch<List<ICompletionProposal>> {
private List<ICompletionProposal> completionProposalList = new ArrayList<ICompletionProposal>();
+
+ private List<TemplateContextType> templateContextTypeList = new ArrayList<TemplateContextType>();
private final IProposalProvider proposalProvider;
- private final IDocument document;
-
- private final EObject model;
-
- private final String prefix;
-
- private int offset;
+ private IContentAssistContext contentAssistContext;
private static final Map<String, Method> methodLookupMap = new HashMap<String, Method>();
+
+
+ /**
+ * @return the templateContextTypeList
+ */
+ public List<TemplateContextType> getTemplateContextTypeList() {
+ return templateContextTypeList;
+ }
/**
*
- * @param model the most specific model element under the cursor.
- * @param document
- * the document itself
- * @param offset
- * the position in the offset from which CA was triggered
- * @param prefix
- * the prefix normally consisting of the text content of the
- * currentLeafNode
+ * @param contentAssistContext the actual contentAssistContext
+ *
* @param proposalProvider
* the proposalProvider to callback and invoke
*/
- public ProposalProviderInvokerSwitch(EObject model, IDocument document, int offset, String prefix,
- IProposalProvider proposalProvider) {
- super();
- this.model = model;
- this.document = document;
- this.offset = offset;
- this.prefix = prefix;
+ public ProposalProviderInvokerSwitch(IContentAssistContext contentAssistContext, IProposalProvider proposalProvider) {
+ this.contentAssistContext = contentAssistContext;
this.proposalProvider = proposalProvider;
}
@@ -93,11 +90,11 @@ public class ProposalProviderInvokerSwitch extends XtextSwitch<List<ICompletionP
* <code>ICompletionProposal</code> for
* @return a list of matching <code>ICompletionProposal</code>
*/
- public List<ICompletionProposal> collectCompletionProposalList(List<EObject> elementList) {
+ public List<ICompletionProposal> collectCompletionProposalList(List<AbstractElement> elementList) {
completionProposalList = new ArrayList<ICompletionProposal>();
- for (Iterator<EObject> elementOrRuleIterator = elementList.iterator(); elementOrRuleIterator.hasNext();) {
+ for (Iterator<AbstractElement> elementOrRuleIterator = elementList.iterator(); elementOrRuleIterator.hasNext();) {
EObject abstractElement = elementOrRuleIterator.next();
doSwitch(abstractElement);
}
@@ -106,38 +103,50 @@ public class ProposalProviderInvokerSwitch extends XtextSwitch<List<ICompletionP
}
+ @SuppressWarnings("unchecked")
@Override
public List<ICompletionProposal> caseAssignment(Assignment assignment) {
+
ParserRule parserRule = GrammarUtil.containingParserRule(assignment);
- Method method = findMethod(proposalProvider.getClass(), "complete"
- + firstLetterCapitalized(parserRule.getName()) + firstLetterCapitalized(assignment.getFeature()),
- Assignment.class, model==null? EObject.class : model.getClass(), String.class, document.getClass(), int.class);
-
- Collection<? extends ICompletionProposal> assignmentProposalList = null == method ? null : invokeMethod(method,
- proposalProvider, assignment, model, prefix, document, offset);
-
- if (null != assignmentProposalList) {
- completionProposalList.addAll(assignmentProposalList);
- }
-
+ invokeProposalProvider(
+ "complete"+ firstLetterCapitalized(parserRule.getName()) + firstLetterCapitalized(assignment.getFeature()),
+ Arrays.asList(Assignment.class, IContentAssistContext.class),
+ Arrays.asList(assignment, this.contentAssistContext));
+
return null;
}
+
+
+
@Override
public List<ICompletionProposal> caseKeyword(Keyword keyword) {
- completionProposalList.addAll(proposalProvider.completeKeyword(keyword, model, prefix, document,offset));
+
+ nullSafeAddAll(completionProposalList, proposalProvider.completeKeyword(keyword, this.contentAssistContext));
+
+ TemplateContextType contextType = this.proposalProvider.getTemplateContextType(keyword,
+ this.contentAssistContext);
+
+ if (null != contextType) {
+ this.templateContextTypeList.add(contextType);
+ }
+
return null;
}
+ @SuppressWarnings("unchecked")
@Override
public List<ICompletionProposal> caseRuleCall(RuleCall ruleCall) {
-
- List<? extends ICompletionProposal> ruleCallProposalList = this.proposalProvider.completeRuleCall(ruleCall,
- model, prefix, document, offset);
- if (null != ruleCallProposalList) {
- completionProposalList.addAll(ruleCallProposalList);
+ nullSafeAddAll(completionProposalList, this.proposalProvider.completeRuleCall(ruleCall,
+ this.contentAssistContext));
+
+ TemplateContextType contextType = this.proposalProvider.getTemplateContextType(ruleCall,
+ this.contentAssistContext);
+
+ if (null != contextType) {
+ this.templateContextTypeList.add(contextType);
}
AbstractRule calledRule = ruleCall.getRule();
@@ -146,19 +155,23 @@ public class ProposalProviderInvokerSwitch extends XtextSwitch<List<ICompletionP
TypeRef typeRef = calledRule.getType();
- Method method = findMethod(proposalProvider.getClass(), "complete"
- + firstLetterCapitalized(typeRef.getMetamodel().getAlias()) + firstLetterCapitalized(typeRef.getType().getName()),
- RuleCall.class, model==null? EObject.class : model.getClass(), String.class, document.getClass(), int.class);
+ invokeProposalProvider(
+ "complete"+ firstLetterCapitalized(typeRef.getMetamodel().getAlias())+ firstLetterCapitalized(typeRef.getType().getName()),
+ Arrays.asList(RuleCall.class, this.contentAssistContext.getModel() == null ? EObject.class : this.contentAssistContext.getModel().getClass(),IContentAssistContext.class),
+ Arrays.asList(ruleCall, this.contentAssistContext.getModel(),this.contentAssistContext));
+ }
+ return null;
+ }
- Collection<? extends ICompletionProposal> proposalList = null == method ? null : invokeMethod(method,
- proposalProvider, ruleCall, model, prefix, document, offset);
+ private void invokeProposalProvider(String methodName,List<Class<?>> parameterTypes,List<?> parameterValues) {
+
+ Method method = findMethod(proposalProvider.getClass(),methodName,parameterTypes.toArray(new Class[]{}));
- if (null != proposalList) {
- completionProposalList.addAll(proposalList);
- }
+ Collection<? extends ICompletionProposal> assignmentProposalList = null == method ? null : invokeMethod(method,
+ proposalProvider, parameterValues.toArray(new Object[]{}));
- }
- return null;
+ nullSafeAddAll(completionProposalList, assignmentProposalList);
+
}
private final Method findMethod(Class<?> clazz, String name, Class<?>... paramTypes) {
@@ -258,4 +271,10 @@ public class ProposalProviderInvokerSwitch extends XtextSwitch<List<ICompletionP
return Strings.toFirstUpper(name);
}
+ private void nullSafeAddAll(List<ICompletionProposal> source, Collection<? extends ICompletionProposal> list) {
+ if (null != list) {
+ source.addAll(list);
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/XtextCompletionProposal.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextCompletionProposal.java
index 1e3228a..7bab759 100644
--- a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/XtextCompletionProposal.java
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextCompletionProposal.java
@@ -1,9 +1,7 @@
-package org.eclipse.xtext.ui.common.editor.codecompletion;
+package org.eclipse.xtext.ui.common.editor.codecompletion.impl;
import org.apache.log4j.Logger;
-import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
@@ -22,9 +20,11 @@ import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.Keyword;
+import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.parsetree.AbstractNode;
import org.eclipse.xtext.parsetree.LeafNode;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
/**
* Default Xtext implementation of interface <code>ICompletionProposal</code>.
@@ -41,113 +41,28 @@ public class XtextCompletionProposal implements ICompletionProposal,
protected final Logger logger = Logger.getLogger(XtextCompletionProposal.class);
- private EObject model;
private AbstractElement abstractElement;
private String text;
private String description;
private Image image;
private final StyledString label;
- private final int offset;
private String pluginIdentifier;
+ private IContentAssistContext contentAssistContext;
- /**
- * @param element
- * the element for which this CompletionProposal is created for
- * @param model the last semtantically complete object
- * @param text the text value to be replaced/inserted
- * @param label the label to be displayed
- * @param description some additional description for the tooltip
- * @param imageFilePath the relative path of the image file, relative to the root of
- * the plug-in; the path must be legal
- * @param pluginId the id of the plug-in containing the image file;
- * @param offset the offset of the text
- */
- public XtextCompletionProposal(AbstractElement element,EObject model,String text, StyledString label,
- String description, String imageFilePath, String pluginIdentifier,
- int offset) {
- Assert.isNotNull(text, "parameter 'text' must not be null");
- Assert.isNotNull(pluginIdentifier,
- "pluginIdentifier 'text' must not be null");
- this.abstractElement = element;
- this.model = model;
- this.text = text;
- this.description = description;
- this.offset = offset;
- this.pluginIdentifier = pluginIdentifier;
-
- if (label != null) {
- this.label = label;
- } else {
- this.label = new StyledString(this.text);
- }
- if (imageFilePath != null) {
- initializeImage(imageFilePath);
- }
- }
- /**
- *
- * Getter for model property.
- *
- * @return the associated model object
- */
- public EObject getModel() {
- return model;
- }
-
- /**
- * Setter for model property.
- *
- * @param model to set
- */
- public void setModel(EObject model) {
- this.model = model;
- }
-
-
- /**
- * Getter for abstractElement property.
- *
- * @return the associated element
- */
- public AbstractElement getAbstractElement() {
- return abstractElement;
- }
-
-
- /**
- * Setter for abstractElement property.
- * @param abstractElement to set
- */
- public void setAbstractElement(AbstractElement abstractElement) {
+ public XtextCompletionProposal(AbstractElement abstractElement, String displayString,
+ IContentAssistContext contentAssistContext) {
this.abstractElement = abstractElement;
+ this.text = displayString;
+ this.description = displayString;
+ this.label = new StyledString(displayString);
+ this.contentAssistContext = contentAssistContext;
}
- /**
- * Setter for the text to insert
- *
- * @param text
- */
- public void setText(String text) {
- this.text = text;
- }
-
-
- /**
- * Getter for the text to insert
- * @return the text to insert
- */
- public String getText() {
- return text;
- }
-
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse
- * .jface.text.IDocument)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
*/
public void apply(IDocument document) {
@@ -155,9 +70,7 @@ public class XtextCompletionProposal implements ICompletionProposal,
/*
* (non-Javadoc)
- *
- * @seeorg.eclipse.jface.text.contentassist.ICompletionProposal#
- * getAdditionalProposalInfo()
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
*/
public String getAdditionalProposalInfo() {
return this.description == null ? null : this.description
@@ -166,9 +79,7 @@ public class XtextCompletionProposal implements ICompletionProposal,
/*
* (non-Javadoc)
- *
- * @seeorg.eclipse.jface.text.contentassist.ICompletionProposal#
- * getContextInformation()
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
*/
public IContextInformation getContextInformation() {
if (this.description != null)
@@ -179,10 +90,7 @@ public class XtextCompletionProposal implements ICompletionProposal,
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString
- * ()
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
*/
public String getDisplayString() {
return this.label.getString();
@@ -199,10 +107,7 @@ public class XtextCompletionProposal implements ICompletionProposal,
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply
- * (org.eclipse.jface.text.ITextViewer, char, int, int)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#apply(org.eclipse.jface.text.ITextViewer, char, int, int)
*/
public void apply(ITextViewer viewer, char trigger, int stateMask,
int offset) {
@@ -211,38 +116,37 @@ public class XtextCompletionProposal implements ICompletionProposal,
IDocument document = viewer.getDocument();
- if (model != null) {
+ if (this.contentAssistContext.getModel() != null) {
- ContentAssistContextAdapter contentAssistContextAdapter = getContextAdapater();
- AbstractNode abstractNode = contentAssistContextAdapter.getCurrentNode();
+ AbstractNode abstractNode = this.contentAssistContext.getNode();
if (abstractNode instanceof LeafNode) {
LeafNode currentLeafNode = (LeafNode) abstractNode;
if (getDisplayString().toUpperCase().startsWith(currentLeafNode.getText().toUpperCase())) {
- setText(getText().substring(this.offset - currentLeafNode.getTotalOffset()));
- } else if (contentAssistContextAdapter.isCusorAtEndOfLastCompleteNode()) {
+ this.text = this.text.substring(this.contentAssistContext.getOffSet() - currentLeafNode.getTotalOffset());
+ } else if (isCusorAtEndOfLastCompleteNode()) {
if (currentLeafNode.getGrammarElement() instanceof CrossReference
&& abstractElement instanceof CrossReference) {
- setText(" " + getText());
+ this.text = " " + this.text;
}
else if (currentLeafNode.getGrammarElement() instanceof RuleCall
&& currentLeafNode.getGrammarElement().eContainer() instanceof Assignment
&& abstractElement instanceof Assignment) {
- setText(" " + getText());
+ this.text = " " + this.text;
}
else if (!GrammarUtil.containingParserRule(abstractElement).equals(
GrammarUtil.containingParserRule(currentLeafNode.getGrammarElement()))) {
- setText(" " + getText());
+ this.text = " " + this.text;
}
}
}
}
- document.replace(this.offset, document.getLength()<(this.offset+getText().length()) ? 0:getText().length() , getText());
+ document.replace(this.contentAssistContext.getOffSet(), 0, this.text);
} catch (BadLocationException e) {
logger.error(e);
@@ -251,36 +155,26 @@ public class XtextCompletionProposal implements ICompletionProposal,
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected
- * (org.eclipse.jface.text.ITextViewer, boolean)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#selected(org.eclipse.jface.text.ITextViewer, boolean)
*/
public void selected(ITextViewer viewer, boolean smartToggle) {
}
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected
- * (org.eclipse.jface.text.ITextViewer)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#unselected(org.eclipse.jface.text.ITextViewer)
*/
public void unselected(ITextViewer viewer) {
}
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate
- * (org.eclipse.jface.text.IDocument, int,
- * org.eclipse.jface.text.DocumentEvent)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension2#validate(org.eclipse.jface.text.IDocument, int, org.eclipse.jface.text.DocumentEvent)
*/
public boolean validate(IDocument document, int offset, DocumentEvent event) {
boolean startsWith = false;
try {
- String prefix = document.get(this.offset, offset - this.offset);
+ String prefix = document.get(this.contentAssistContext.getOffSet(), offset - this.contentAssistContext.getOffSet());
startsWith = getDisplayString().toLowerCase().startsWith(
prefix.toLowerCase());
} catch (BadLocationException e) {
@@ -301,51 +195,46 @@ public class XtextCompletionProposal implements ICompletionProposal,
/*
* (non-Javadoc)
- *
- * @see
- * org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection
- * (org.eclipse.jface.text.IDocument)
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
*/
public Point getSelection(IDocument document) {
- return new Point(offset + this.text.length(), 0);
+ return new Point(this.contentAssistContext.getOffSet() + this.text.length(), 0);
}
/**
*
- * @param prefix to match
* @return true or false whether the given prefix matches the text of this completion proposal
*/
- public boolean matches(String prefix) {
+ public boolean matches() {
boolean matches = true;
- if (model != null) {
+ if (this.contentAssistContext.getModel() != null) {
AbstractElement abstractElement = null;
- if (getAbstractElement() instanceof Keyword ||
- getAbstractElement() instanceof CrossReference) {
- abstractElement = GrammarUtil.containingAssignment(getAbstractElement());
+ if (this.abstractElement instanceof Keyword ||
+ this.abstractElement instanceof CrossReference) {
+ abstractElement = GrammarUtil.containingAssignment(this.abstractElement);
}
if (null==abstractElement) {
- abstractElement = getAbstractElement();
+ abstractElement = this.abstractElement;
}
- ContentAssistContextAdapter contentAssistContextAdapter = getContextAdapater();
boolean candidateToCompare = false;
// means if we are at the end of a complete token we want to filter only equal grammarelements (not the 'next' ones)
- if (contentAssistContextAdapter.isCusorAtEndOfLastCompleteNode() &&
- abstractElement.equals(contentAssistContextAdapter.getCurrentGrammarElement())) {
+ if (isCusorAtEndOfLastCompleteNode() &&
+ abstractElement.equals(getCurrentGrammarElement())) {
candidateToCompare = true;
- } else if (!contentAssistContextAdapter.isCusorAtEndOfLastCompleteNode() ) {
+ } else if (!isCusorAtEndOfLastCompleteNode() ) {
candidateToCompare = true;
}
- if ( candidateToCompare && (!"".equals(prefix.trim()) &&
- !getDisplayString().toUpperCase().trim().startsWith(prefix.toUpperCase().trim()))) {
+ if ( candidateToCompare && (!"".equals(this.contentAssistContext.getMatchString().trim()) &&
+ !getDisplayString().toUpperCase().trim().startsWith(this.contentAssistContext.getMatchString().toUpperCase().trim()))) {
matches = false;
}
}
@@ -356,7 +245,7 @@ public class XtextCompletionProposal implements ICompletionProposal,
@Override
public String toString() {
- return "XtextCompletionPoposal[text='"+getText()+"']";
+ return "XtextCompletionPoposal[text='"+this.text+"']";
}
private void initializeImage(String imageName) {
@@ -374,9 +263,26 @@ public class XtextCompletionProposal implements ICompletionProposal,
this.image = newImage;
}
- private ContentAssistContextAdapter getContextAdapater() {
- ContentAssistContextAdapter contentAssistContextAdapter = (ContentAssistContextAdapter)
- EcoreUtil.getAdapter(model.eAdapters(), ContentAssistContextAdapter.class);
- return contentAssistContextAdapter;
+
+ /**
+ * @return true or false wheter the cursor is at the the last complete node
+ */
+ public boolean isCusorAtEndOfLastCompleteNode() {
+ return this.contentAssistContext.getNode() == this.contentAssistContext.getReferenceNode();
+ }
+
+ /**
+ * @return the grammar element of the current node
+ */
+ public EObject getCurrentGrammarElement() {
+
+ EObject grammarElement = GrammarUtil.containingAssignment(this.contentAssistContext.getNode().getGrammarElement());
+
+ if (null == grammarElement) {
+ grammarElement = (this.contentAssistContext.getNode().getGrammarElement() instanceof ParserRule ? ((ParserRule) this.contentAssistContext.getNode()
+ .getGrammarElement()).getAlternatives() : this.contentAssistContext.getNode().getGrammarElement());
+ }
+
+ return grammarElement;
}
}
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContext.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContext.java
new file mode 100644
index 0000000..1c6ffa5
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContext.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion.impl;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.templates.DocumentTemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.xtext.IMetamodelAccess;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
+import org.eclipse.xtext.ui.common.editor.codecompletion.ILinkingCandidatesService;
+
+/**
+ * Represents an extended version of class {@link DocumentTemplateContext} to provide additional Xtext related
+ * information and services for resolving a <code>Template</code>.
+ *
+ * @author Michael Clay - Initial contribution and API
+ */
+public class XtextTemplateContext extends DocumentTemplateContext {
+
+ private IContentAssistContext contentAssistContext;
+
+ private ILinkingCandidatesService linkingCandidatesService;
+
+ private IMetamodelAccess metamodelAccess;
+
+ public XtextTemplateContext(TemplateContextType type, IDocument document, Position position,
+ IContentAssistContext contentAssistContext, ILinkingCandidatesService linkingCandidatesService,
+ IMetamodelAccess metamodelAccess) {
+ super(type, document, position);
+ this.contentAssistContext = contentAssistContext;
+ this.linkingCandidatesService = linkingCandidatesService;
+ this.metamodelAccess = metamodelAccess;
+ }
+
+ /**
+ * @return the contentAssistContext
+ */
+ public IContentAssistContext getContentAssistContext() {
+ return contentAssistContext;
+ }
+
+ /**
+ * @return the linkingCandidatesService
+ */
+ public ILinkingCandidatesService getLinkingCandidatesService() {
+ return linkingCandidatesService;
+ }
+
+ /**
+ * @return the metamodelAccess
+ */
+ public IMetamodelAccess getMetamodelAccess() {
+ return metamodelAccess;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContextType.java b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContextType.java
new file mode 100644
index 0000000..1ae6691
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/impl/XtextTemplateContextType.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.ui.common.editor.codecompletion.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+import org.eclipse.xtext.IMetamodelAccess;
+import org.eclipse.xtext.crossref.IScopedElement;
+import org.eclipse.xtext.ui.common.editor.codecompletion.impl.XtextTemplateContext;
+
+/**
+ * Provides a convenience base type for <code>TemplateContextType's</code> preconfigured with several handy
+ * Xtext <code>TemplateVariableResolver</code> .
+ *
+ * @author Michael Clay - Initial contribution and API
+ */
+public class XtextTemplateContextType extends TemplateContextType {
+
+ public XtextTemplateContextType() {
+ addResolver(new CrossReferenceTemplateVariableResolver());
+ addResolver(new GlobalTemplateVariables.WordSelection());
+ addResolver(new GlobalTemplateVariables.LineSelection());
+ addResolver(new GlobalTemplateVariables.Date());
+ addResolver(new GlobalTemplateVariables.Year());
+ addResolver(new GlobalTemplateVariables.Time());
+ addResolver(new GlobalTemplateVariables.Dollar());
+ addResolver(new GlobalTemplateVariables.User());
+ addResolver(new GlobalTemplateVariables.Cursor());
+ }
+
+ public static class CrossReferenceTemplateVariableResolver extends TemplateVariableResolver {
+
+ public CrossReferenceTemplateVariableResolver() {
+ super("CrossReference", "TemplateVariableResolver for CrossReferences");
+ }
+
+ public void resolve(TemplateVariable variable, TemplateContext context) {
+
+ XtextTemplateContext xtextTemplateContext = (XtextTemplateContext) context;
+
+ String abbreviatedCrossReference = (String) variable.getVariableType().getParams().iterator().next();
+
+ String[] classReferencePair = abbreviatedCrossReference.split("\\.");
+
+ EReference reference = getReference(classReferencePair[0], classReferencePair[1], xtextTemplateContext
+ .getMetamodelAccess());
+
+ Iterable<IScopedElement> linkingCandidates = xtextTemplateContext.getLinkingCandidatesService()
+ .getLinkingCandidates(xtextTemplateContext.getContentAssistContext().getModel(), reference);
+
+ List<String> names = new ArrayList<String>();
+
+ for (IScopedElement scopedElement : linkingCandidates) {
+ names.add(scopedElement.name());
+ }
+
+ String[] bindings = (String[]) names.toArray(new String[] {});
+
+ if (bindings.length != 0)
+ variable.setValues(bindings);
+ if (bindings.length > 1)
+ variable.setUnambiguous(false);
+ else
+ variable.setUnambiguous(isUnambiguous(context));
+
+ variable.setResolved(true);
+ }
+
+ private EReference getReference(String eClassName, String eReferenceName, IMetamodelAccess metamodelAccess) {
+ EPackage[] allEPackages = metamodelAccess.getAllEPackages();
+ for (int i = 0; i < allEPackages.length; i++) {
+ EPackage ePackage = allEPackages[i];
+ EClass eClass = (EClass) ePackage.getEClassifier(eClassName);
+ if (eClass != null) {
+ return (EReference) eClass.getEStructuralFeature(eReferenceName);
+ }
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextSourceViewer.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextSourceViewer.java
new file mode 100644
index 0000000..99b2fac
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextSourceViewer.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.editor;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.parsetree.AbstractNode;
+import org.eclipse.xtext.parsetree.CompositeNode;
+
+/**
+ * Source viewer interface with a 'node-centric' view of the underlying document.
+ *
+ * @author Michael Clay - Initial contribution and API
+ */
+public interface IXtextSourceViewer {
+
+ /**
+ * @return the root node of the underlying document
+ */
+ CompositeNode getRootNode();
+
+ /**
+ * @param offset
+ * matching position for the reference node
+ * @return the nearest node with an existing grammar element set (i.e. valid
+ * according to the underlying grammar)
+ */
+ AbstractNode getReferenceNode(int offset);
+
+ /**
+ * @param offset
+ * matching position for the node
+ * @return the last node (on a none hidden channel) that starts at or spans
+ * across the given offset position
+ */
+ AbstractNode getNode(int offset);
+
+ /**
+ * @param offset
+ * matching position for the model
+ * @return the most specific model element for the given offset position
+ */
+ EObject getModel(int offset);
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
index 332820f..0a02e7d 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
@@ -175,7 +175,7 @@ public class XtextEditor extends TextEditor implements IExecutableExtension {
// overwrite superclass implementation to allow folding
fAnnotationAccess = createAnnotationAccess();
fOverviewRuler = createOverviewRuler(getSharedColors());
- ISourceViewer projectionViewer = new ProjectionViewer(parent, ruler, getOverviewRuler(),
+ ISourceViewer projectionViewer = new XtextSourceViewer(parent, ruler, getOverviewRuler(),
isOverviewRulerVisible(), styles);
getSourceViewerDecorationSupport(projectionViewer);
return projectionViewer;
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewer.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewer.java
new file mode 100644
index 0000000..122ddde
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewer.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2008 itemis AG (http://www.itemis.eu) and others.
+ * 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.editor;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IOverviewRuler;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.xtext.parser.IParseResult;
+import org.eclipse.xtext.parsetree.AbstractNode;
+import org.eclipse.xtext.parsetree.CompositeNode;
+import org.eclipse.xtext.parsetree.NodeUtil;
+import org.eclipse.xtext.parsetree.ParseTreeUtil;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
+import org.eclipse.xtext.ui.core.editor.model.IXtextModelListener;
+import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
+import org.eclipse.xtext.util.Function;
+import org.eclipse.xtext.util.SimpleCache;
+
+/**
+ * Provides a default implementation of interface <code>IXtextSourceViewer</code>.
+ *
+ * @author Michael Clay - Initial contribution and API
+ *
+ * @see IXtextSourceViewer
+ */
+public class XtextSourceViewer extends ProjectionViewer implements IXtextSourceViewer, IXtextModelListener {
+
+ private CompositeNode rootNode;
+
+ private SimpleCache<Integer, AbstractNode> referenceNodeCache;
+
+ private SimpleCache<Integer, AbstractNode> nodeCache;
+
+ public XtextSourceViewer(Composite parent, IVerticalRuler ruler, IOverviewRuler overviewRuler,
+ boolean showsAnnotationOverview, int styles) {
+ super(parent, ruler, overviewRuler, showsAnnotationOverview, styles);
+ init();
+ }
+
+ @Override
+ protected void createControl(Composite parent, int styles) {
+ // required for 'headless' standalone unit tests
+ if (parent != null) {
+ super.createControl(parent, styles);
+ }
+ }
+
+ @Override
+ public void setDocument(IDocument document, IAnnotationModel annotationModel) {
+ super.setDocument(document, annotationModel);
+ ((IXtextDocument) getDocument()).addModelListener(this);
+ }
+
+ @Override
+ public void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset,
+ int modelRangeLength) {
+ super.setDocument(document, annotationModel, modelRangeOffset, modelRangeLength);
+ ((IXtextDocument) getDocument()).addModelListener(this);
+ }
+
+ @Override
+ public void setDocument(IDocument document, int visibleRegionOffset, int visibleRegionLength) {
+ super.setDocument(document, visibleRegionOffset, visibleRegionLength);
+ ((IXtextDocument) getDocument()).addModelListener(this);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.xtext.ui.core.editor.IXtextSourceViewer#getRootNode()
+ */
+ public CompositeNode getRootNode() {
+
+ if (null == rootNode) {
+
+ IXtextDocument xtextDocument = (IXtextDocument) getDocument();
+
+ this.rootNode = xtextDocument.readOnly(new UnitOfWork<CompositeNode>() {
+ public CompositeNode exec(XtextResource resource) throws Exception {
+ IParseResult parseResult = resource.getParseResult();
+ Assert.isNotNull(parseResult);
+ return parseResult.getRootNode();
+ }
+ });
+ }
+ return rootNode;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.core.editor.model.IXtextModelListener#modelChanged(org.eclipse.xtext.resource.XtextResource)
+ */
+ public void modelChanged(XtextResource resource) {
+ init();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.xtext.ui.core.editor.IXtextSourceViewer#getReferenceNode(int)
+ */
+ public AbstractNode getReferenceNode(int offset) {
+ return this.referenceNodeCache.get(offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.xtext.ui.core.editor.IXtextSourceViewer#getNode(int)
+ */
+ public AbstractNode getNode(int offset) {
+ return this.nodeCache.get(offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.xtext.ui.core.editor.IXtextSourceViewer#getModel(int)
+ */
+ public EObject getModel(int offset) {
+ AbstractNode lastCompleteNode = getReferenceNode(offset);
+
+ return lastCompleteNode instanceof AbstractNode ? NodeUtil
+ .getNearestSemanticObject((AbstractNode) lastCompleteNode) : lastCompleteNode;
+ }
+
+ private SimpleCache<Integer, AbstractNode> createReferenceNodeCache() {
+ return new SimpleCache<Integer, AbstractNode>(new Function<Integer, AbstractNode>() {
+
+ public AbstractNode exec(Integer offset) {
+ return ParseTreeUtil.getLastCompleteNodeByOffset(getRootNode(), offset);
+ }
+
+ });
+ }
+
+ private SimpleCache<Integer, AbstractNode> createNodeCache() {
+ return new SimpleCache<Integer, AbstractNode>(new Function<Integer, AbstractNode>() {
+
+ public AbstractNode exec(Integer offset) {
+ return ParseTreeUtil.getCurrentOrFollowingNodeByOffset(getRootNode(), offset);
+ }
+
+ });
+ }
+
+ private void init() {
+ referenceNodeCache = createReferenceNodeCache();
+ nodeCache = createNodeCache();
+ this.rootNode = null;
+ }
+
+}
diff --git a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/XtextGrammarTestLanguageGenProposalProvider.java b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/XtextGrammarTestLanguageGenProposalProvider.java
index be0c8f7..c251b3f 100644
--- a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/XtextGrammarTestLanguageGenProposalProvider.java
+++ b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/XtextGrammarTestLanguageGenProposalProvider.java
@@ -14,317 +14,297 @@ import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ui.common.editor.codecompletion.AbstractProposalProvider;
import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
/**
* Represents a generated, default implementation of interface {@link IProposalProvider}.
*
- * In addition to the declared methods, the framework tries to call grammar dependent methods for assignments using reflection.
- * The signature of such methods invoked reflectively follows the following pattern:
- *
- * public List<ICompletionProposal> complete[Typename][featureName](Assignment ele, EObject model, String prefix)
- *
- * <b>Example</b>
- * Given the following grammar :
- * <code>
- * RuleA returns MyType :
- * "myType" name=ID;
- * </code>
- *
- * One could provide the following method in an implementation of this interface:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, EObject model, String prefix, IDocument doc) {...}
- * </code>
- * Note that if you have generated Java classes for your domain model (meta model) you can alternatively declare the second parameter using
- * a specific type:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, MyType model, String prefix, IDocument doc) {...}
- * </code>
- *
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider
*/
public class XtextGrammarTestLanguageGenProposalProvider extends AbstractProposalProvider {
// constants
private static final String UI_PLUGIN_ID = ".";
- public List<? extends ICompletionProposal> completeGrammarAbstract(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGrammarAbstract(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGrammarAbstract feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeGrammarIdElements(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGrammarIdElements(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGrammarIdElements feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"GrammarIdElements", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "GrammarIdElements", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeGrammarSuperGrammarIdElements(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGrammarSuperGrammarIdElements(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGrammarSuperGrammarIdElements feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"GrammarSuperGrammarIdElements", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "GrammarSuperGrammarIdElements", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeGrammarMetamodelDeclarations(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGrammarMetamodelDeclarations(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGrammarMetamodelDeclarations feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeGrammarRules(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGrammarRules(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGrammarRules feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeGeneratedMetamodelName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGeneratedMetamodelName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGeneratedMetamodelName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"GeneratedMetamodelName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "GeneratedMetamodelName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeGeneratedMetamodelNsURI(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGeneratedMetamodelNsURI(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGeneratedMetamodelNsURI feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"\"GeneratedMetamodelNsURI\"", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "\"GeneratedMetamodelNsURI\"", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeGeneratedMetamodelAlias(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGeneratedMetamodelAlias(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGeneratedMetamodelAlias feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"GeneratedMetamodelAlias", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "GeneratedMetamodelAlias", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeReferencedMetamodelUri(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeReferencedMetamodelUri(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeReferencedMetamodelUri feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"\"ReferencedMetamodelUri\"", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "\"ReferencedMetamodelUri\"", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeReferencedMetamodelAlias(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeReferencedMetamodelAlias(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeReferencedMetamodelAlias feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"ReferencedMetamodelAlias", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "ReferencedMetamodelAlias", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeLexerRuleName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeLexerRuleName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeLexerRuleName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"LexerRuleName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "LexerRuleName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeLexerRuleType(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeLexerRuleType(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeLexerRuleType feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeLexerRuleBody(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeLexerRuleBody(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeLexerRuleBody feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"\"LexerRuleBody\"", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "\"LexerRuleBody\"", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeParserRuleName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeParserRuleName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeParserRuleName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"ParserRuleName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "ParserRuleName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeParserRuleType(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeParserRuleType(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeParserRuleType feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeParserRuleAlternatives(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeParserRuleAlternatives(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeParserRuleAlternatives feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeTypeRefMetamodel(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeTypeRefMetamodel(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeTypeRefMetamodel feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeTypeRefType(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeTypeRefType(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeTypeRefType feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeAlternativesGroups(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeAlternativesGroups(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeAlternativesGroups feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeGroupAbstractTokens(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeGroupAbstractTokens(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeGroupAbstractTokens feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeAbstractTokenCardinality(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeAbstractTokenCardinality(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeAbstractTokenCardinality feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeAssignmentFeature(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeAssignmentFeature(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeAssignmentFeature feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"AssignmentFeature", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "AssignmentFeature", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeAssignmentOperator(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeAssignmentOperator(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeAssignmentOperator feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeAssignmentTerminal(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeAssignmentTerminal(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeAssignmentTerminal feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeActionTypeName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeActionTypeName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeActionTypeName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeActionFeature(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeActionFeature(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeActionFeature feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"ActionFeature", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "ActionFeature", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeActionOperator(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeActionOperator(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeActionOperator feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeCrossReferenceType(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeCrossReferenceType(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeCrossReferenceType feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeCrossReferenceRule(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeCrossReferenceRule(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeCrossReferenceRule feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeKeywordValue(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeKeywordValue(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeKeywordValue feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"\"KeywordValue\"", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "\"KeywordValue\"", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeRuleCallRule(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeRuleCallRule(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeRuleCallRule feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
diff --git a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ContentAssistTestLanguageGenProposalProvider.java b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ContentAssistTestLanguageGenProposalProvider.java
index 49e8efd..3b7e773 100644
--- a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ContentAssistTestLanguageGenProposalProvider.java
+++ b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ContentAssistTestLanguageGenProposalProvider.java
@@ -14,90 +14,70 @@ import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ui.common.editor.codecompletion.AbstractProposalProvider;
import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
/**
* Represents a generated, default implementation of interface {@link IProposalProvider}.
*
- * In addition to the declared methods, the framework tries to call grammar dependent methods for assignments using reflection.
- * The signature of such methods invoked reflectively follows the following pattern:
- *
- * public List<ICompletionProposal> complete[Typename][featureName](Assignment ele, EObject model, String prefix)
- *
- * <b>Example</b>
- * Given the following grammar :
- * <code>
- * RuleA returns MyType :
- * "myType" name=ID;
- * </code>
- *
- * One could provide the following method in an implementation of this interface:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, EObject model, String prefix, IDocument doc) {...}
- * </code>
- * Note that if you have generated Java classes for your domain model (meta model) you can alternatively declare the second parameter using
- * a specific type:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, MyType model, String prefix, IDocument doc) {...}
- * </code>
- *
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider
*/
public class ContentAssistTestLanguageGenProposalProvider extends AbstractProposalProvider {
// constants
private static final String UI_PLUGIN_ID = ".";
- public List<? extends ICompletionProposal> completeStartRules(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeStartRules(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeStartRules feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeFirstAbstractRuleChildName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFirstAbstractRuleChildName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFirstAbstractRuleChildName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"FirstAbstractRuleChildName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "FirstAbstractRuleChildName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeFirstAbstractRuleChildElements(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFirstAbstractRuleChildElements(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFirstAbstractRuleChildElements feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSecondAbstractRuleChildName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSecondAbstractRuleChildName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSecondAbstractRuleChildName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"SecondAbstractRuleChildName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "SecondAbstractRuleChildName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSecondAbstractRuleChildRule(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSecondAbstractRuleChildRule(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSecondAbstractRuleChildRule feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeAbstractRuleCallRule(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeAbstractRuleCallRule(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeAbstractRuleCallRule feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
diff --git a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ReferenceGrammarTestLanguageGenProposalProvider.java b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ReferenceGrammarTestLanguageGenProposalProvider.java
index 36cd59d..6868a90 100644
--- a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ReferenceGrammarTestLanguageGenProposalProvider.java
+++ b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/ReferenceGrammarTestLanguageGenProposalProvider.java
@@ -14,189 +14,168 @@ import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ui.common.editor.codecompletion.AbstractProposalProvider;
import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
/**
* Represents a generated, default implementation of interface {@link IProposalProvider}.
*
- * In addition to the declared methods, the framework tries to call grammar dependent methods for assignments using reflection.
- * The signature of such methods invoked reflectively follows the following pattern:
- *
- * public List<ICompletionProposal> complete[Typename][featureName](Assignment ele, EObject model, String prefix)
- *
- * <b>Example</b>
- * Given the following grammar :
- * <code>
- * RuleA returns MyType :
- * "myType" name=ID;
- * </code>
- *
- * One could provide the following method in an implementation of this interface:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, EObject model, String prefix, IDocument doc) {...}
- * </code>
- * Note that if you have generated Java classes for your domain model (meta model) you can alternatively declare the second parameter using
- * a specific type:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, MyType model, String prefix, IDocument doc) {...}
- * </code>
- *
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider
*/
public class ReferenceGrammarTestLanguageGenProposalProvider extends AbstractProposalProvider {
// constants
private static final String UI_PLUGIN_ID = ".";
- public List<? extends ICompletionProposal> completeSpielplatzGroesse(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzGroesse(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzGroesse feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"1", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "1", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielplatzBeschreibung(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzBeschreibung(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzBeschreibung feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"\"SpielplatzBeschreibung\"", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "\"SpielplatzBeschreibung\"", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielplatzKinder(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzKinder(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzKinder feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSpielplatzErzieher(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzErzieher(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzErzieher feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSpielplatzSpielzeuge(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzSpielzeuge(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzSpielzeuge feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeSpielplatzFamilie(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielplatzFamilie(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielplatzFamilie feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeKindName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeKindName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeKindName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"KindName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "KindName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeKindAge(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeKindAge(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeKindAge feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"1", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "1", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeErwachsenerName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeErwachsenerName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeErwachsenerName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"ErwachsenerName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "ErwachsenerName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeErwachsenerAge(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeErwachsenerAge(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeErwachsenerAge feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"1", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "1", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielzeugName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielzeugName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielzeugName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"SpielzeugName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "SpielzeugName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeSpielzeugFarbe(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeSpielzeugFarbe(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeSpielzeugFarbe feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeFamilieName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeFamilieMutter(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieMutter(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieMutter feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeFamilieVater(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieVater(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieVater feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> completeFamilieKinder(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeFamilieKinder(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeFamilieKinder feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return lookupCrossReference(((CrossReference)assignment.getTerminal()), model, prefix, offset);
+ return lookupCrossReference(((CrossReference)assignment.getTerminal()), contentAssistContext);
}
- public List<? extends ICompletionProposal> complete(RuleCall ruleCall, EObject model, String prefix,
- IDocument doc, int offset) {
+ public List<? extends ICompletionProposal> complete(RuleCall ruleCall, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("complete '" + ruleCall.getRule().getName() + "' cardinality '" + ruleCall.getCardinality()
- + "' for model '" + model + "' and prefix '" + prefix.trim() + "'");
+ + "' for model '" + contentAssistContext.getModel() + "' and prefix '" + contentAssistContext.getMatchString() + "'");
}
return Collections.emptyList();
}
diff --git a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/TreeTestLanguageGenProposalProvider.java b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/TreeTestLanguageGenProposalProvider.java
index 8f6732c..b7704da 100644
--- a/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/TreeTestLanguageGenProposalProvider.java
+++ b/tests/org.eclipse.xtext.ui.common.tests/src-gen/org/eclipse/xtext/testlanguages/TreeTestLanguageGenProposalProvider.java
@@ -14,70 +14,50 @@ import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ui.common.editor.codecompletion.AbstractProposalProvider;
import org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider;
+import org.eclipse.xtext.ui.common.editor.codecompletion.IContentAssistContext;
/**
* Represents a generated, default implementation of interface {@link IProposalProvider}.
*
- * In addition to the declared methods, the framework tries to call grammar dependent methods for assignments using reflection.
- * The signature of such methods invoked reflectively follows the following pattern:
- *
- * public List<ICompletionProposal> complete[Typename][featureName](Assignment ele, EObject model, String prefix)
- *
- * <b>Example</b>
- * Given the following grammar :
- * <code>
- * RuleA returns MyType :
- * "myType" name=ID;
- * </code>
- *
- * One could provide the following method in an implementation of this interface:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, EObject model, String prefix, IDocument doc) {...}
- * </code>
- * Note that if you have generated Java classes for your domain model (meta model) you can alternatively declare the second parameter using
- * a specific type:
- * <code>
- * public List<ICompletionProposal> completeMyTypeName(Assignment ele, MyType model, String prefix, IDocument doc) {...}
- * </code>
- *
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider
*/
public class TreeTestLanguageGenProposalProvider extends AbstractProposalProvider {
// constants
private static final String UI_PLUGIN_ID = ".";
- public List<? extends ICompletionProposal> completeModelChildren(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeModelChildren(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeModelChildren feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
- public List<? extends ICompletionProposal> completeNodeName(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeNodeName(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeNodeName feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"NodeName", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "NodeName", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeNodeAttrib(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeNodeAttrib(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeNodeAttrib feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
- return Collections.singletonList(createCompletionProposal(assignment,model,"\"NodeAttrib\"", offset));
+ return Collections.singletonList(createCompletionProposal(assignment, "\"NodeAttrib\"", contentAssistContext));
}
- public List<? extends ICompletionProposal> completeNodeChildren(Assignment assignment, EObject model, String prefix, IDocument doc,int offset) {
+ public List<? extends ICompletionProposal> completeNodeChildren(Assignment assignment, IContentAssistContext contentAssistContext) {
if (logger.isDebugEnabled()) {
logger.debug("completeNodeChildren feature '" + assignment.getFeature() + "' terminal '"
+ assignment.getTerminal() + "' cardinality '" + assignment.getCardinality() + "' and prefix '"
- + prefix.trim() + "'");
+ + contentAssistContext.getMatchString().trim() + "'");
}
return Collections.emptyList();
}
diff --git a/tests/org.eclipse.xtext.ui.common.tests/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistProcessorTestBuilder.java b/tests/org.eclipse.xtext.ui.common.tests/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistProcessorTestBuilder.java
index 1f6d416..cb1d1bc 100644
--- a/tests/org.eclipse.xtext.ui.common.tests/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistProcessorTestBuilder.java
+++ b/tests/org.eclipse.xtext.ui.common.tests/src/org/eclipse/xtext/ui/common/editor/codecompletion/ContentAssistProcessorTestBuilder.java
@@ -27,6 +27,7 @@ import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
@@ -39,6 +40,7 @@ import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.service.IServiceScope;
import org.eclipse.xtext.service.ServiceRegistry;
+import org.eclipse.xtext.ui.core.editor.XtextSourceViewer;
import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.core.editor.model.UnitOfWork;
import org.eclipse.xtext.util.StringInputStream;
@@ -178,20 +180,31 @@ public class ContentAssistProcessorTestBuilder {
return this;
}
- public ICompletionProposal[] computeCompletionProposals(String currentModelToParse, int cursorPosition)
+ public ICompletionProposal[] computeCompletionProposals(final String currentModelToParse, int cursorPosition)
throws Exception {
CompositeNode rootNode = getRootNode(currentModelToParse);
org.easymock.EasyMock.reset(textViewerMock, xtextDocumentMock, textViewerMock);
- expect(textViewerMock.getDocument()).andReturn(xtextDocumentMock);
+ //expect(textViewerMock.getDocument()).andReturn(xtextDocumentMock);
expect(xtextDocumentMock.readOnly((UnitOfWork<CompositeNode>) anyObject())).andReturn(rootNode);
- expect(textViewerMock.getTextWidget()).andReturn(newStyledTextWidgetMock(currentModelToParse));
+ //expect(textViewerMock.getTextWidget()).andReturn(newStyledTextWidgetMock(currentModelToParse));
- replay(textViewerMock, xtextDocumentMock);
+ replay(xtextDocumentMock);
ICompletionProposal[] computeCompletionProposals = this.contentAssistProcessor.computeCompletionProposals(
- textViewerMock, cursorPosition);
+ new XtextSourceViewer(null,null,null,false,0) {
+ @Override
+ public IDocument getDocument() {
+ return xtextDocumentMock;
+ }
+
+ @Override
+ public StyledText getTextWidget() {
+ return newStyledTextWidgetMock(currentModelToParse);
+ }
+
+ }, cursorPosition);
return computeCompletionProposals;
}