aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormclay2008-11-07 19:55:33 (EST)
committersefftinge2008-11-07 19:55:33 (EST)
commit6dc60517828857262bffb2d93186ff85844dfdd2 (patch)
treefe1cdaac7294b23a69b457cf21793d5a83ee5bdb
parent28c35dc131252f7516ea14a52919ad56600c6892 (diff)
downloadorg.eclipse.xtext-6dc60517828857262bffb2d93186ff85844dfdd2.zip
org.eclipse.xtext-6dc60517828857262bffb2d93186ff85844dfdd2.tar.gz
org.eclipse.xtext-6dc60517828857262bffb2d93186ff85844dfdd2.tar.bz2
upd: keep working on CA enhancements
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/AbstractProposalProvider.java59
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/DefaultContentAssistProcessor.java72
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/IProposalProvider.java6
-rw-r--r--plugins/org.eclipse.xtext.ui.common/src/org/eclipse/xtext/ui/common/editor/codecompletion/XtextCompletionProposal.java21
4 files changed, 134 insertions, 24 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 3193616..0eda0d4 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
@@ -2,7 +2,10 @@ package org.eclipse.xtext.ui.common.editor.codecompletion;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.URI;
@@ -20,6 +23,7 @@ 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.service.Inject;
import org.eclipse.xtext.util.Pair;
@@ -54,7 +58,6 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
+ prefix.trim() + "'");
}
String text = keyword.getValue().length() == 1 ? keyword.getValue() : keyword.getValue() + " ";
-
return Collections.singletonList(createCompletionProposal(text, offset));
}
@@ -80,19 +83,63 @@ public abstract class AbstractProposalProvider implements IProposalProvider {
/*
* (non-Javadoc)
- *
- * @seeorg.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#sortAndFilter(java.util.List)
+ * @see org.eclipse.xtext.ui.common.editor.codecompletion.IProposalProvider#sortAndFilter(java.util.List, org.eclipse.emf.ecore.EObject, java.lang.String)
*/
- public List<? extends ICompletionProposal> sortAndFilter(List<? extends ICompletionProposal> completionProposalList) {
- return doSortAndFilter(completionProposalList);
+ public List<? extends ICompletionProposal> sortAndFilter(
+ List<? extends ICompletionProposal> completionProposalList, EObject model, String prefix) {
+ return doSortAndFilter(completionProposalList,model,prefix);
}
/**
* Concrete subclasses can override this for custom sort and filter
* behavior. Gets called after all completion proposals have been collected.
+ *
+ * The default behavior of this implementation is to sort duplicates and to trim
+ * matching <code>ICompletionProposal#displayString</code> with matching prefix values.
+ *
+ * @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
+ * @return the sorted and filtered <code>ICompletionProposal</code> list.
+ *
*/
protected List<? extends ICompletionProposal> doSortAndFilter(
- List<? extends ICompletionProposal> completionProposalList) {
+ List<? extends ICompletionProposal> completionProposalList,EObject model,String prefix) {
+
+ if (model instanceof LeafNode) {
+
+ LeafNode leafNode = (LeafNode) model;
+
+ Map<String,ICompletionProposal> displayString2ICompletionProposalMap = new HashMap<String,ICompletionProposal>();
+
+ for (Iterator<? extends ICompletionProposal> iterator = completionProposalList.iterator(); iterator.hasNext();) {
+
+ ICompletionProposal completionProposal = iterator.next();
+
+ // filter duplicate displayString
+ if (!displayString2ICompletionProposalMap.containsKey(completionProposal.getDisplayString())) {
+
+ displayString2ICompletionProposalMap.put(completionProposal.getDisplayString(), completionProposal);
+
+ // trim displayString
+ if (leafNode.isHidden() && !"".equals(leafNode.getText().trim()) ) {
+
+ if (completionProposal.getDisplayString().startsWith(leafNode.getText()) &&
+ completionProposal instanceof XtextCompletionProposal) {
+
+ XtextCompletionProposal xtextCompletionProposal = (XtextCompletionProposal) completionProposal;
+
+ xtextCompletionProposal.setText(xtextCompletionProposal.getText().replaceFirst(leafNode.getText(), ""));
+ } else {
+ iterator.remove();
+ }
+ }
+ } else {
+ iterator.remove();
+ }
+ }
+ }
+
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 53fed4e..7b3c99e 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
@@ -12,7 +12,11 @@ import java.util.Set;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.Assert;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.EcoreEList;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ContextInformationValidator;
@@ -20,10 +24,11 @@ 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.xtext.AbstractElement;
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.ParserRule;
@@ -33,6 +38,7 @@ 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.Inject;
@@ -64,7 +70,6 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor {
if (proposalProvider != null) {
-
IDocument document = viewer.getDocument();
if (document instanceof XtextDocument) {
@@ -85,17 +90,17 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor {
AbstractNode lastCompleteNode = ParseTreeUtil.getLastCompleteNodeByOffset(rootNode, offset);
- LeafNode currentLeafNode = (LeafNode) ParseTreeUtil.getCurrentNodeByOffset(rootNode, offset);
+ LeafNode currentLeafNode = ParseTreeUtil.getCurrentNodeByOffset(rootNode, offset);
- String prefix = "";
- StyledText textWidget = viewer.getTextWidget();
- if (textWidget.getCharCount() > 0) {
- int boundedOffset = Math.min(offset, textWidget.getCharCount()) -1;
- if(currentLeafNode.getOffset() <= boundedOffset)
- prefix = textWidget.getText(currentLeafNode.getOffset(), boundedOffset);
- }
+ String prefix = null==currentLeafNode ? "" : currentLeafNode.getText();
Set<AbstractElement> nextValidElementSet = ParseTreeUtil.getElementSetValidFromOffset(rootNode,lastCompleteNode, offset);
+ /**
+ * in the case of a non linked crossreference we delegate to proposalProvider (again)
+ */
+ if (lastCompleteNode.getGrammarElement() instanceof CrossReference && !isLinked(lastCompleteNode) ) {
+ nextValidElementSet.add((AbstractElement) lastCompleteNode.getGrammarElement().eContainer());
+ }
for (List<EObject> resolvedElementOrRuleList : new ProposalCandidateResolverSwitch(nextValidElementSet)) {
@@ -106,10 +111,8 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor {
}
if (completionProposalList != null) {
- List<? extends ICompletionProposal> sortAndFilter = proposalProvider
- .sortAndFilter(completionProposalList);
+ List<? extends ICompletionProposal> sortAndFilter = proposalProvider.sortAndFilter(completionProposalList,currentLeafNode,prefix);
completionProposals = sortAndFilter.toArray(new ICompletionProposal[] {});
-
}
}
}
@@ -304,6 +307,49 @@ public class DefaultContentAssistProcessor implements IContentAssistProcessor {
private final String firstLetterCapitalized(String name) {
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
+
+ @SuppressWarnings("unchecked")
+ private boolean isLinked(AbstractNode lastCompleteNode) {
+
+ EObject semanticModel = NodeUtil.getNearestSemanticObject(lastCompleteNode);
+
+ EReference eReference = getReference((CrossReference) lastCompleteNode.getGrammarElement(), semanticModel.eClass());
+
+ if (eReference.getUpperBound() == 1 ) {
+
+ if (null!=semanticModel.eGet(eReference)) {
+ return true;
+ }
+ }
+ else {
+
+ EcoreEList<EObject> ecoreEList = (EcoreEList<EObject>) semanticModel.eGet(eReference);
+
+ for (Iterator<EObject> iterator = ecoreEList.iterator(); iterator.hasNext();) {
+
+ EObject object = iterator.next();
+
+ if (EcoreUtil2.getURIFragment(object).equalsIgnoreCase(((LeafNode)lastCompleteNode).getText())) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private EReference getReference(CrossReference ref, EClass class1) {
+
+ EList<EReference> references = class1.getEAllReferences();
+
+ String feature = GrammarUtil.containingAssignment(ref).getFeature();
+
+ for (EReference reference : references) {
+ if (!reference.isContainment() && reference.getName().equals(feature))
+ return reference;
+ }
+ return null;
+ }
}
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 d622fdd..394988f 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
@@ -69,8 +69,10 @@ public interface IProposalProvider {
/**
* 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
+ * @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
* @return the sorted and filtered <code>ICompletionProposal</code> list.
*/
- public List<? extends ICompletionProposal> sortAndFilter(List<? extends ICompletionProposal> completionProposalList);
+ public List<? extends ICompletionProposal> sortAndFilter(List<? extends ICompletionProposal> completionProposalList,EObject model,String prefix);
}
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/XtextCompletionProposal.java
index 56856c4..9428dbd 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/XtextCompletionProposal.java
@@ -2,9 +2,6 @@ package org.eclipse.xtext.ui.common.editor.codecompletion;
import org.apache.log4j.Logger;
import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
@@ -75,6 +72,24 @@ public class XtextCompletionProposal implements ICompletionProposal,
initializeImage(imageFilePath);
}
}
+
+ /**
+ * 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)