| author | mclay | 2008-11-03 15:37:07 (EST) |
|---|---|---|
| committer | sefftinge | 2008-11-03 15:37:07 (EST) |
| commit | b718fa96ce01401bef03b39142f7664a5e9b81ef (patch) (side-by-side diff) | |
| tree | c5ca3fa3e5c28cfe8a1557012357ba4033f96668 | |
| parent | 0fdafbff2da29e3b0ea70fa01239df2b2d09e4da (diff) | |
| download | org.eclipse.xtext-b718fa96ce01401bef03b39142f7664a5e9b81ef.zip org.eclipse.xtext-b718fa96ce01401bef03b39142f7664a5e9b81ef.tar.gz org.eclipse.xtext-b718fa96ce01401bef03b39142f7664a5e9b81ef.tar.bz2 | |
ASSIGNED - bug 250383: Implementation of org.eclipse.xtext.ui.common.editor.codecompletion.DefaultContentAssistProcessor
https://bugs.eclipse.org/bugs/show_bug.cgi?id=250383
2 files changed, 84 insertions, 65 deletions
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 dfbb354..af6c188 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 @@ -33,7 +33,10 @@ import org.eclipse.xtext.util.Pair; * @see IProposalProvider */ public abstract class AbstractProposalProvider implements IProposalProvider { + // constants protected static final String LEXER_RULE_ID = "ID"; + protected static final String LEXER_RULE_INT = "INT"; + protected static final String LEXER_RULE_STRING = "STRING"; // logger available to subclasses protected final Logger logger = Logger.getLogger(getClass()); @@ -42,10 +45,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) { @@ -57,14 +57,10 @@ public abstract class AbstractProposalProvider implements IProposalProvider { return Collections.singletonList(createCompletionProposal(text, offset)); } - + /* * (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) { @@ -81,17 +77,16 @@ public abstract class AbstractProposalProvider implements IProposalProvider { return Collections.emptyList(); } - + /* * (non-Javadoc) * - * @seeorg.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider# - * sortAndFilter(java.util.List) + * @seeorg.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#sortAndFilter(java.util.List) */ public List<? extends ICompletionProposal> sortAndFilter(List<? extends ICompletionProposal> completionProposalList) { return doSortAndFilter(completionProposalList); } - + /** * Concrete subclasses can override this for custom sort and filter * behavior. Gets called after all completion proposals have been collected. @@ -100,14 +95,15 @@ 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) + * of the given LexerRule (e.i. ParserRuleName+AssignmentFeatureName+LexerRuleName) or {@link #getDefaultIntegerValue()} + * if its <i>INT</i> based LexerRule. * * @param lexerRule the 'called' LexerRule instance * @param ruleCall the ruleCall for the provided lexerRule @@ -117,12 +113,26 @@ public abstract class AbstractProposalProvider implements IProposalProvider { 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(); + + String defaultDisplayString = containingParserRule.getName() + + (null != containingAssignment ? firstLetterCapitalized(containingAssignment.getFeature()) : "") + lexerRule.getName(); + + if (LEXER_RULE_INT.equalsIgnoreCase(lexerRule.getName())) { + defaultDisplayString=String.valueOf(getDefaultIntegerValue()); + } else if (LEXER_RULE_STRING.equalsIgnoreCase(lexerRule.getName())) { + defaultDisplayString="\""+defaultDisplayString+"\""; + } + return Collections.singletonList(createCompletionProposal(defaultDisplayString, offset)); } - + + /** + * @return the default integer value for ecore::EInt <code>RuleCall<> + */ + protected int getDefaultIntegerValue() { + return 0; + } + /** * * @return the id of the plug-in containing the image files; @@ -156,10 +166,11 @@ public abstract class AbstractProposalProvider implements IProposalProvider { List<ICompletionProposal> completionProposalList = new ArrayList<ICompletionProposal>(); if (linkingService != null) { - EObject semanticModel = NodeUtil.getNearestSemanticObject((AbstractNode) model); + EObject semanticModel = model instanceof AbstractNode ? NodeUtil.getNearestSemanticObject((AbstractNode) model) : model; List<Pair<String, URI>> candidates = linkingService.getLinkCandidates(semanticModel, crossReference, ""); - for (Pair<String, URI> candidate : candidates) + for (Pair<String, URI> candidate : candidates) { completionProposalList.add(createCompletionProposal(candidate.getFirstElement(), offset)); + } } return completionProposalList; 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 e8d2a1a..8e3cd66 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 @@ -53,7 +53,7 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { @Inject private IProposalProvider proposalProvider; - + private final Map<String, Method> methodLookupMap = new HashMap<String, Method>(); /** @@ -76,6 +76,7 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { }); Assert.isNotNull(rootNode); + // last COMPLETE node element with associated grammar element AbstractNode lastCompleteNode = ParseTreeUtil.getLastCompleteNodeByOffset(rootNode, offset); // node at CURRENT cursor pos. with or without grammar element @@ -83,7 +84,9 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { // get associated grammar element AbstractElement grammarElement = ParseTreeUtil.getGrammarElementFromNode(lastCompleteNode); - String prefix = viewer.getTextWidget().getText(currentLeafNode.getOffset(), offset); + String prefix = viewer.getTextWidget().getCharCount()>0 ? + viewer.getTextWidget().getText(currentLeafNode.getOffset(), offset<viewer.getTextWidget().getCharCount()?offset : + viewer.getTextWidget().getCharCount()-1) : ""; List<ICompletionProposal> completionProposalList = new ArrayList<ICompletionProposal>(); @@ -179,38 +182,6 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { return elementList; } - protected void handleReflectionException(Exception ex) { - if (ex instanceof NoSuchMethodException) { - throw new IllegalStateException("Method not found: " + ex.getMessage()); - } - if (ex instanceof IllegalAccessException) { - throw new IllegalStateException("Could not access method: " + ex.getMessage()); - } - if (ex instanceof InvocationTargetException) { - rethrowRuntimeException(((InvocationTargetException) ex).getTargetException()); - } - if (ex instanceof RuntimeException) { - throw (RuntimeException) ex; - } - handleUnexpectedException(ex); - } - - private final void rethrowRuntimeException(Throwable ex) { - if (ex instanceof RuntimeException) { - throw (RuntimeException) ex; - } - if (ex instanceof Error) { - throw (Error) ex; - } - handleUnexpectedException(ex); - } - - protected void handleUnexpectedException(Throwable ex) { - IllegalStateException isex = new IllegalStateException("Unexpected exception thrown"); - isex.initCause(ex); - throw isex; - } - protected final Set<AbstractElement> calculatePossibleElementSet(AbstractNode contextNode, AbstractElement grammarElement) { @@ -329,15 +300,17 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { ParserRule parserRule = GrammarUtil.containingParserRule(assignment); - EObject model = ((CompositeNode) currentLeafNode.eContainer()).getElement(); + EObject model = null==((CompositeNode) currentLeafNode.eContainer()).getElement() ? + currentLeafNode.eContainer() + : ((CompositeNode) currentLeafNode.eContainer()).getElement(); Method method = findMethod(proposalProvider.getClass(), "complete" + firstLetterCapitalized(parserRule.getName()) - + firstLetterCapitalized(assignment.getFeature()), Assignment.class, null==model.getClass() ? EObject.class : model.getClass(), - String.class, document.getClass(), int.class); + + firstLetterCapitalized(assignment.getFeature()), Assignment.class, model.getClass(),String.class, document.getClass(), int.class); - Collection<? extends ICompletionProposal> assignmentProposalList = invokeMethod(method, - proposalProvider, assignment, model, prefix, document, offset); + Collection<? extends ICompletionProposal> assignmentProposalList = null==method ? + null : + invokeMethod(method,proposalProvider, assignment, model, prefix, document, offset); if (null != assignmentProposalList) { completionProposalList.addAll(assignmentProposalList); @@ -346,7 +319,9 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { } else if (abstractElement instanceof RuleCall) { - EObject model = ((CompositeNode) currentLeafNode.eContainer()).getElement(); + EObject model = null==((CompositeNode) currentLeafNode.eContainer()).getElement() ? + currentLeafNode.eContainer() + : ((CompositeNode) currentLeafNode.eContainer()).getElement(); List<? extends ICompletionProposal> ruleCallProposalList = this.proposalProvider.completeRuleCall( (RuleCall) abstractElement, model, prefix, document, offset); @@ -363,10 +338,11 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { Method method = findMethod(proposalProvider.getClass(), "complete" + firstLetterCapitalized(typeRef.getAlias()) + firstLetterCapitalized(typeRef.getName()), - RuleCall.class, null==model.getClass() ? EObject.class : model.getClass(), String.class, document.getClass(), int.class); + RuleCall.class, model.getClass(), String.class, document.getClass(), int.class); - Collection<? extends ICompletionProposal> proposalList = invokeMethod(method, proposalProvider, - abstractElement, model, prefix, document, offset); + Collection<? extends ICompletionProposal> proposalList = null==method ? + null : + invokeMethod(method, proposalProvider, abstractElement, model, prefix, document, offset); if (null != proposalList) { completionProposalList.addAll(proposalList); @@ -402,6 +378,38 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor { } return result; } + + private void handleReflectionException(Exception ex) { + if (ex instanceof NoSuchMethodException) { + throw new IllegalStateException("Method not found: " + ex.getMessage()); + } + if (ex instanceof IllegalAccessException) { + throw new IllegalStateException("Could not access method: " + ex.getMessage()); + } + if (ex instanceof InvocationTargetException) { + rethrowRuntimeException(((InvocationTargetException) ex).getTargetException()); + } + if (ex instanceof RuntimeException) { + throw (RuntimeException) ex; + } + handleUnexpectedException(ex); + } + + private void handleUnexpectedException(Throwable ex) { + IllegalStateException isex = new IllegalStateException("Unexpected exception thrown"); + isex.initCause(ex); + throw isex; + } + + private final void rethrowRuntimeException(Throwable ex) { + if (ex instanceof RuntimeException) { + throw (RuntimeException) ex; + } + if (ex instanceof Error) { + throw (Error) ex; + } + handleUnexpectedException(ex); + } @SuppressWarnings("unchecked") private final Collection<ICompletionProposal> invokeMethod(Method method, Object target, Object... args) { |

