summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormclay2008-10-29 17:18:00 (EDT)
committer sefftinge2008-10-29 17:18:00 (EDT)
commit34b462e9d321767cba589318ed38ad32f0191b84 (patch)
tree647614db23b71e74aa3c221f669ab6a786247df9
parent0164a2e1985a375aae5857e9f91568cd0664cbc0 (diff)
downloadorg.eclipse.xtext-34b462e9d321767cba589318ed38ad32f0191b84.zip
org.eclipse.xtext-34b462e9d321767cba589318ed38ad32f0191b84.tar.gz
org.eclipse.xtext-34b462e9d321767cba589318ed38ad32f0191b84.tar.bz2
add: extend generated ProposalProvider to include callback methods for AbstractRules with associated TypeRef
-rw-r--r--devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceGrammar.xtext58
-rw-r--r--devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceModel.ecore9
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/AbstractProposalProvider.java72
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/DefaultContentAssistProcessor.java26
4 files changed, 124 insertions, 41 deletions
diff --git a/devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceGrammar.xtext b/devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceGrammar.xtext
index edb1d9e..4aaaba4 100644
--- a/devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceGrammar.xtext
+++ b/devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceGrammar.xtext
@@ -3,29 +3,37 @@
* 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
-*
+* http://www.eclipse.org/legal/epl-v10.html
+*
*******************************************************************************/
-language org. eclipse. xtext. reference. ReferenceGrammar
-generate ReferenceGrammar "http://eclipse.org/xtext/reference/ReferenceGrammar"
-
- Spielplatz :
- ( "spielplatz" groesse = INT ( beschreibung = STRING ) ? "{" ( kinder += Kind | erzieher += Erwachsener | spielzeuge += Spielzeug | familie += Familie ) * "}" ) ? ;
-
- Person :
- Kind | Erwachsener ;
-
- Kind :
- "kind" "(" name = ID age = INT ")" ;
-
- Erwachsener :
- "erwachsener" "(" name = ID age = INT ")" ;
-
- Spielzeug :
- "spielzeug" "(" name = ID farbe = Farbe ")" ;
-
- Familie :
- "familie" "(" mutter=[Erwachsener] vater=[Erwachsener] kinder+=[Kind] ("," kinder+=[Kind])* ")" ;
-
- Farbe :
- wert=("ROT" | "BLAU" | "GELB" | "GRÜN"); \ No newline at end of file
+language org.eclipse.xtext.reference.ReferenceGrammar
+generate ReferenceGrammar "http://eclipse.org/xtext/reference/ReferenceGrammar"
+import "classpath:/org/eclipse/xtext/reference/ReferenceModel.ecore" as ReferenceModel
+
+
+Spielplatz :
+ ( "spielplatz" groesse = INT ( beschreibung = STRING ) ? "{"
+ ( kinder += Kind | erzieher += Erwachsener | spielzeuge += Spielzeug | familie += Familie
+ | types += CustomTypeParserRule ) * "}"
+ ) ? ;
+
+Person :
+ Kind | Erwachsener ;
+
+Kind :
+ "kind" "(" name = ID age = INT ")" ;
+
+Erwachsener :
+ "erwachsener" "(" name = ID age = INT ")" ;
+
+Spielzeug :
+ "spielzeug" "(" name = ID farbe = Farbe ")" ;
+
+Familie :
+ "familie" "(" name=("keyword" | STRING | ID) mutter=[Erwachsener] vater=[Erwachsener] kinder+=[Kind] ("," kinder+=[Kind])* ")" ;
+
+Farbe :
+ wert=("ROT" | "BLAU" | "GELB" | "GRÜN");
+
+CustomTypeParserRule returns ReferenceModel::CustomType :
+ 'type' name=ID;
diff --git a/devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceModel.ecore b/devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceModel.ecore
new file mode 100644
index 0000000..489921f
--- /dev/null
+++ b/devtools/org.eclipse.xtext.reference/src/org/eclipse/xtext/reference/ReferenceModel.ecore
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0"
+ xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ReferenceModel"
+ nsURI="http://eclipse.org/xtext/reference/ReferenceModel" nsPrefix="ReferenceModel">
+ <eClassifiers xsi:type="ecore:EClass" name="CustomType">
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+ </eClassifiers>
+</ecore:EPackage>
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 1830bd6..9023603 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
@@ -9,9 +9,14 @@ import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.viewers.StyledString;
+import org.eclipse.xtext.AbstractRule;
+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.LexerRule;
+import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.parsetree.CompositeNode;
import org.eclipse.xtext.parsetree.LeafNode;
@@ -31,10 +36,7 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
/*
* (non-Javadoc)
- *
- * @seeorg.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.emf.ecore.EObject, java.lang.String, org.eclipse.jface.text.IDocument, int)
*/
public List<? extends ICompletionProposal> completeKeyword(Keyword keyword, EObject model, String prefix,
IDocument doc, int offset) {
@@ -49,11 +51,7 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
/*
* (non-Javadoc)
- *
- * @seeorg.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.emf.ecore.EObject, java.lang.String, org.eclipse.jface.text.IDocument, int)
*/
public List<? extends ICompletionProposal> completeRuleCall(RuleCall ruleCall, EObject model, String prefix,
IDocument doc, int offset) {
@@ -61,6 +59,12 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
logger.debug("completeRuleCall '" + ruleCall.getName() + "' cardinality '" + ruleCall.getCardinality()
+ "' for model '" + model + "' and prefix '" + prefix.trim() + "'");
}
+ AbstractRule calledRule = GrammarUtil.calledRule(ruleCall);
+
+ if (calledRule instanceof LexerRule) {
+ return doCompleteLexerRuleRuleCall((LexerRule) calledRule, ruleCall, offset);
+ }
+
return Collections.emptyList();
}
@@ -82,10 +86,32 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
List<? extends ICompletionProposal> completionProposalList) {
return completionProposalList;
}
+
+ /**
+ * Concrete subclasses can override this to provide a more meaningful and sophisticated behaviour
+ * whenever a list of ICompletionProposal's should be computed for simple <code>LexerRule</code> call's.
+ *
+ * This implementation returns one <code>ICompletionProposal</code> with a displayString composed
+ * of the name of the containing rule plus the featurename of an optional assignment and at the end the name
+ * of the given LexerRule. (e.i. ParserRuleName+AssignmentFeatureName+LexerRuleName)
+ *
+ * @param lexerRule the 'called' LexerRule instance
+ * @param ruleCall the ruleCall for the provided lexerRule
+ * @param offset an offset within the document for which completions should be computed
+ * @return a computed list of <code>ICompletionProposal</code> for the given <code>LexerRule</code>
+ */
+ protected List<? extends ICompletionProposal> doCompleteLexerRuleRuleCall(LexerRule lexerRule,RuleCall ruleCall, int offset) {
+ ParserRule containingParserRule = GrammarUtil.containingParserRule(ruleCall);
+ Assignment containingAssignment = GrammarUtil.containingAssignment(ruleCall);
+ String defaultDisplayString = containingParserRule.getName()
+ + (null != containingAssignment ? firstLetterCapitalized(containingAssignment.getFeature()) : "")
+ + lexerRule.getName();
+ return Collections.singletonList(createCompletionProposal(defaultDisplayString, offset));
+ }
/**
*
- * @return the id of the plug-in containing the image file;
+ * @return the id of the plug-in containing the image files;
* <code>null</code> is returned if the plug-in does not exist
*/
protected abstract String getPluginId();
@@ -93,7 +119,8 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
/**
* Returns the the relative path of the default image file, relative to the
* root of the containing plug-in; the path must be legal The image would
- * typically be shown to the left of the display string.
+ * typically be shown to the left of the <code>ICompletionProposal</code>
+ * display string.
*
* @return the image file path of the default image to be shown or
* <code>null</code> if no image is desired
@@ -103,14 +130,17 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
/**
* Concrete subclasses can override this to provide custom lookup behaviour
- * for <code>CrossReference</code>. The default behaviour of this method is
- * to lookup all <code>RuleCall</code> within the current parsetree matching
- * the type of the given CrossReference.
+ * for <code>CrossReference</code>.
+ *
+ * The default behaviour of this method is to lookup all
+ * <code>RuleCall</code> within the current parsetree matching the type of
+ * the given CrossReference.
*
* @return a list of <code>ICompletionProposal</code> matching the given
* assignment
*/
- protected List<? extends ICompletionProposal> lookupCrossReference(CrossReference crossReference, EObject model, int offset) {
+ protected List<? extends ICompletionProposal> lookupCrossReference(CrossReference crossReference, EObject model,
+ int offset) {
List<ICompletionProposal> completionProposalList = new ArrayList<ICompletionProposal>();
for (CompositeNode compositeNode : EcoreUtil2.getAllContentsOfType(EcoreUtil2.getRootContainer(model),
CompositeNode.class)) {
@@ -136,5 +166,17 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
return new XtextCompletionProposal(text, new StyledString(text), text, getDefaultImageFilePath(),
getPluginId(), offset);
}
+
+ /**
+ * @param text to apply
+ * @return the provided string with the first letter capitalized
+ */
+ protected final String firstLetterCapitalized(String text) {
+ if (text == null || text.length() == 0) {
+ return text;
+ }
+ return text.substring(0, 1).toUpperCase() + text.substring(1, text.length());
+ }
+
}
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 b907c82..9ab1f03 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
@@ -31,6 +31,7 @@ import org.eclipse.xtext.Group;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
+import org.eclipse.xtext.TypeRef;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.parsetree.AbstractNode;
import org.eclipse.xtext.parsetree.CompositeNode;
@@ -83,7 +84,8 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor {
List<ICompletionProposal> completionProposalList = new ArrayList<ICompletionProposal>();
- for (Iterator<AbstractElement> iterator = calculatePossibleElementSet(lastCompleteNode, grammarElement)
+ Set<AbstractElement> calculatePossibleElementSet = calculatePossibleElementSet(lastCompleteNode, grammarElement);
+ for (Iterator<AbstractElement> iterator = calculatePossibleElementSet
.iterator(); iterator.hasNext();) {
AbstractElement nextElement = iterator.next();
@@ -141,6 +143,27 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor {
if (null != ruleCallProposalList) {
completionProposalList.addAll(ruleCallProposalList);
}
+
+ AbstractRule calledRule = GrammarUtil.calledRule((RuleCall) abstractElement);
+
+ if (calledRule.getType()!=null) {
+
+ TypeRef typeRef = calledRule.getType();
+
+ Method method = findMethod(proposalProvider.getClass(),
+ "complete" + firstLetterCapitalized(typeRef.getAlias())
+ + firstLetterCapitalized(typeRef.getName()), RuleCall.class, EObject.class,
+ String.class, IDocument.class, int.class);
+
+ Collection<? extends ICompletionProposal> proposalList = invokeMethod(method, proposalProvider,
+ abstractElement, currentLeafNode, prefix, xtextDocument, offset);
+
+ if (null != proposalList) {
+ completionProposalList.addAll(proposalList);
+ }
+
+ }
+
}
}
}
@@ -378,6 +401,7 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor {
@SuppressWarnings("unchecked")
private final Collection<ICompletionProposal> invokeMethod(Method method, Object target, Object... args) {
+
try {
return (Collection<ICompletionProposal>) method.invoke(target, args);
}