/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.ui.text.dart; import com.google.dart.tools.core.completion.CompletionContext; import com.google.dart.tools.core.completion.CompletionProposal; import com.google.dart.tools.core.completion.CompletionRequestor; import com.google.dart.tools.core.problem.Problem; import com.google.dart.tools.ui.DartToolsPlugin; import com.google.dart.tools.ui.internal.text.completion.DartCompletionProposal; import com.google.dart.tools.ui.internal.text.completion.DartMethodCompletionProposal; import com.google.dart.tools.ui.internal.text.completion.LazyDartCompletionProposal; import com.google.dart.tools.ui.internal.text.completion.LazyDartTypeCompletionProposal; import com.google.dart.tools.ui.internal.text.completion.NamedArgumentCompletionProposal; import com.google.dart.tools.ui.internal.text.completion.OptionalArgumentCompletionProposal; import com.google.dart.tools.ui.internal.text.dart.ProposalContextInformation; import com.google.dart.tools.ui.internal.util.TypeFilter; import com.google.dart.tools.ui.internal.viewsupport.ImageDescriptorRegistry; import com.google.dart.tools.ui.text.editor.tmp.Signature; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.text.contentassist.IContextInformation; import org.eclipse.jface.viewers.StyledString; import org.eclipse.swt.graphics.Image; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Dart UI implementation of <code>CompletionRequestor</code>. Produces * {@link IDartCompletionProposal}s from the proposal descriptors received via the * <code>CompletionRequestor</code> interface. * <p> * The lifecycle of a <code>CompletionProposalCollector</code> instance is very simple: * * <pre> * CompilationUnit unit= ... * int offset= ... * * CompletionProposalCollector collector= new CompletionProposalCollector(unit); * unit.codeComplete(offset, collector); * IDartCompletionProposal[] proposals= collector.getDartCompletionProposals(); * String errorMessage= collector.getErrorMessage(); * * // display / process proposals * </pre> * Note that after a code completion operation, the collector will store any received proposals, * which may require a considerable amount of memory, so the collector should not be kept as a * reference after a completion operation. * </p> * <p> * Clients may instantiate or subclass. */ public class CompletionProposalCollector extends CompletionRequestor { /** Tells whether this class is in debug mode. */ private static final boolean DEBUG = "true".equalsIgnoreCase(Platform.getDebugOption("com.google.dart.tools.core/debug/ResultCollector")); //$NON-NLS-1$//$NON-NLS-2$ /** Triggers for method proposals without parameters. Do not modify. */ protected final static char[] METHOD_TRIGGERS = new char[] {';', ',', '.', '\t', '[', ' '}; /** Triggers for method proposals. Do not modify. */ protected final static char[] METHOD_WITH_ARGUMENTS_TRIGGERS = new char[] {'(', '-', ' '}; /** Triggers for types. Do not modify. */ protected final static char[] TYPE_TRIGGERS = new char[] {'.', '\t', '[', '(', ' '}; /** Triggers for variables. Do not modify. */ protected final static char[] VAR_TRIGGER = new char[] {'\t', ' ', '=', ';', '.'}; /** * Returns an array containing all of the elements in the given collection. This is a compile-time * type-safe alternative to {@link Collection#toArray(Object[])}. * * @param collection the source collection * @param clazz the type of the array elements * @param <A> the type of the array elements * @return an array of type <code>A</code> containing all of the elements in the given collection * @throws NullPointerException if the specified collection or class is null */ public static <A> A[] toArray(Collection<? extends A> collection, Class<A> clazz) { Object array = Array.newInstance(clazz, collection.size()); @SuppressWarnings("unchecked") A[] typedArray = collection.toArray((A[]) array); return typedArray; } private final CompletionProposalLabelProvider fLabelProvider = new CompletionProposalLabelProvider(); private final ImageDescriptorRegistry fRegistry = DartToolsPlugin.getImageDescriptorRegistry(); private final List<IDartCompletionProposal> fDartProposals = new ArrayList<IDartCompletionProposal>(); private final List<IDartCompletionProposal> fKeywords = new ArrayList<IDartCompletionProposal>(); private final Set<String> fSuggestedMethodNames = new HashSet<String>(); private int fUserReplacementLength; private CompletionContext fContext; private Problem fLastProblem; /* performance instrumentation */ private long fStartTime; private long fUITime; /** * The UI invocation context or <code>null</code>. */ private DartContentAssistInvocationContext fInvocationContext; /** * Creates a new instance ready to collect proposals. If the passed <code>CompilationUnit</code> * is not contained in an {@link DartProject}, no Dart doc will be available as * {@link org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo() * additional info} on the created proposals. * * @param ignoreAll <code>true</code> to ignore all kinds of completion proposals */ public CompletionProposalCollector(boolean ignoreAll) { super(ignoreAll); fUserReplacementLength = -1; if (!ignoreAll) { setRequireExtendedContext(true); } } /** * {@inheritDoc} * <p> * Subclasses may replace, but usually should not need to. Consider replacing * {@linkplain #createDartCompletionProposal(CompletionProposal) createDartCompletionProposal} * instead. * </p> */ @Override public void accept(CompletionProposal proposal) { long start = DEBUG ? System.currentTimeMillis() : 0; try { if (isFiltered(proposal)) { return; } DartContentAssistInvocationContext ctxt = getInvocationContext(); proposal.applyPartitionOffset(ctxt.getPartitionOffset()); if (proposal.getKind() == CompletionProposal.POTENTIAL_METHOD_DECLARATION) { } else { IDartCompletionProposal dartProposal = createDartCompletionProposal(proposal); if (dartProposal != null) { fDartProposals.add(dartProposal); if (proposal.getKind() == CompletionProposal.KEYWORD) { fKeywords.add(dartProposal); } } } } catch (IllegalArgumentException e) { // all signature processing method may throw IAEs // https://bugs.eclipse.org/bugs/show_bug.cgi?id=84657 // don't abort, but log and show all the valid proposals DartToolsPlugin.log(new Status( IStatus.ERROR, DartToolsPlugin.getPluginId(), IStatus.OK, "Exception when processing proposal for: " + String.valueOf(proposal.getCompletion()), e)); //$NON-NLS-1$ } if (DEBUG) { fUITime += System.currentTimeMillis() - start; } } /** * {@inheritDoc} * <p> * Subclasses may extend, but usually should not need to. */ @Override public void acceptContext(CompletionContext context) { fContext = context; fLabelProvider.setContext(context); } /** * {@inheritDoc} Subclasses may extend, but must call the super implementation. */ @Override public void beginReporting() { if (DEBUG) { fStartTime = System.currentTimeMillis(); fUITime = 0; } fLastProblem = null; fDartProposals.clear(); fKeywords.clear(); fSuggestedMethodNames.clear(); } /** * {@inheritDoc} Subclasses may extend, but must call the super implementation. */ @Override public void completionFailure(Problem problem) { fLastProblem = problem; } /** * {@inheritDoc} Subclasses may extend, but must call the super implementation. */ @Override public void endReporting() { if (DEBUG) { long total = System.currentTimeMillis() - fStartTime; System.err.println("Core Collector (core):\t" + (total - fUITime)); //$NON-NLS-1$ System.err.println("Core Collector (ui):\t" + fUITime); //$NON-NLS-1$ } } /** * Returns the unsorted list of received proposals. * * @return the unsorted list of received proposals */ public final IDartCompletionProposal[] getDartCompletionProposals() { return toArray(fDartProposals, IDartCompletionProposal.class); } /** * Returns an error message about any error that may have occurred during code completion, or the * empty string if none. * <p> * Subclasses may replace or extend. * </p> * * @return an error message or the empty string */ public String getErrorMessage() { if (fLastProblem != null) { return fLastProblem.getMessage(); } return ""; //$NON-NLS-1$ } @Override public com.google.dart.engine.ast.CompilationUnit getInputUnit() { return fInvocationContext.getInputUnit(); } /** * Returns the unsorted list of received keyword proposals. * * @return the unsorted list of received keyword proposals */ public final IDartCompletionProposal[] getKeywordCompletionProposals() { return toArray(fKeywords, IDartCompletionProposal.class); } @Override public void setIgnored(int completionProposalKind, boolean ignore) { super.setIgnored(completionProposalKind, ignore); if (completionProposalKind == CompletionProposal.METHOD_DECLARATION && !ignore) { setRequireExtendedContext(true); } } /** * Sets the invocation context. * <p> * Subclasses may extend. * </p> * * @param context the invocation context */ public void setInvocationContext(DartContentAssistInvocationContext context) { Assert.isNotNull(context); fInvocationContext = context; context.setCollector(this); } /** * If the replacement length is set, it overrides the length returned from the content assist * infrastructure. Use this setting if code assist is called with a none empty selection. * * @param length the new replacement length, relative to the code assist offset. Must be equal to * or greater than zero. */ public final void setReplacementLength(int length) { Assert.isLegal(length >= 0); fUserReplacementLength = length; } /** * Computes the relevance for a given <code>CompletionProposal</code>. * <p> * Subclasses may replace, but usually should not need to. * </p> * * @param proposal the proposal to compute the relevance for * @return the relevance for <code>proposal</code> */ protected int computeRelevance(CompletionProposal proposal) { final int baseRelevance = proposal.getRelevance() * 16; switch (proposal.getKind()) { case CompletionProposal.LIBRARY_PREFIX: return baseRelevance + 0; case CompletionProposal.LABEL_REF: return baseRelevance + 1; case CompletionProposal.KEYWORD: return baseRelevance + 2; case CompletionProposal.TYPE_REF: // case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: // case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION: return baseRelevance + 3; case CompletionProposal.METHOD_REF: case CompletionProposal.CONSTRUCTOR_INVOCATION: case CompletionProposal.METHOD_NAME_REFERENCE: case CompletionProposal.METHOD_DECLARATION: // case CompletionProposal.ANNOTATION_ATTRIBUTE_REF: return baseRelevance + 4; case CompletionProposal.POTENTIAL_METHOD_DECLARATION: return baseRelevance + 4 /* + 99 */; case CompletionProposal.FIELD_REF: return baseRelevance + 5; case CompletionProposal.LOCAL_VARIABLE_REF: case CompletionProposal.VARIABLE_DECLARATION: return baseRelevance + 6; case CompletionProposal.ARGUMENT_LIST: return baseRelevance + 7; default: return baseRelevance; } } /** * Creates a new Dart completion proposal from a core proposal. This may involve computing the * display label and setting up some context. * <p> * This method is called for every proposal that will be displayed to the user, which may be * hundreds. Implementations should therefore defer as much work as possible: Labels should be * computed lazily to leverage virtual table usage, and any information only needed when * <em>applying</em> a proposal should not be computed yet. * </p> * <p> * Implementations may return <code>null</code> if a proposal should not be included in the list * presented to the user. * </p> * <p> * Subclasses may extend or replace this method. * </p> * * @param proposal the core completion proposal to create a UI proposal for * @return the created Dart completion proposal, or <code>null</code> if no proposal should be * displayed */ protected IDartCompletionProposal createDartCompletionProposal(CompletionProposal proposal) { switch (proposal.getKind()) { case CompletionProposal.KEYWORD: return createKeywordProposal(proposal); case CompletionProposal.LIBRARY_PREFIX: return createLibraryPrefixProposal(proposal); case CompletionProposal.TYPE_REF: return createTypeProposal(proposal); // case CompletionProposal.JAVADOC_TYPE_REF: // return createJavadocLinkTypeProposal(proposal); case CompletionProposal.FIELD_REF: // case CompletionProposal.JAVADOC_FIELD_REF: // case CompletionProposal.JAVADOC_VALUE_REF: return createFieldProposal(proposal); // case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER: // return createFieldWithCastedReceiverProposal(proposal); case CompletionProposal.ARGUMENT_LIST: case CompletionProposal.METHOD_REF: case CompletionProposal.CONSTRUCTOR_INVOCATION: // case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER: case CompletionProposal.METHOD_NAME_REFERENCE: // case CompletionProposal.JAVADOC_METHOD_REF: return createMethodReferenceProposal(proposal); case CompletionProposal.METHOD_DECLARATION: return null; // case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION: // return createAnonymousTypeProposal(proposal, getInvocationContext()); // case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: // return createAnonymousTypeProposal(proposal, null); case CompletionProposal.LABEL_REF: return createLabelProposal(proposal); case CompletionProposal.LOCAL_VARIABLE_REF: case CompletionProposal.VARIABLE_DECLARATION: return createLocalVariableProposal(proposal); case CompletionProposal.TYPE_IMPORT: return createImportProposal(proposal); case CompletionProposal.OPTIONAL_ARGUMENT: return new OptionalArgumentCompletionProposal(proposal); case CompletionProposal.NAMED_ARGUMENT: return new NamedArgumentCompletionProposal(proposal); // case CompletionProposal.ANNOTATION_ATTRIBUTE_REF: // return createAnnotationAttributeReferenceProposal(proposal); // case CompletionProposal.JAVADOC_BLOCK_TAG: // case CompletionProposal.JAVADOC_PARAM_REF: // return createJavadocSimpleProposal(proposal); // case CompletionProposal.JAVADOC_INLINE_TAG: // return createJavadocInlineTagProposal(proposal); case CompletionProposal.POTENTIAL_METHOD_DECLARATION: default: return null; } } /** * Creates the context information for a given method reference proposal. The passed proposal must * be of kind {@link CompletionProposal#METHOD_REF}. * * @param methodProposal the method proposal for which to create context information * @return the context information for <code>methodProposal</code> */ protected final IContextInformation createMethodContextInformation( CompletionProposal methodProposal) { Assert.isTrue(methodProposal.getKind() == CompletionProposal.METHOD_REF); return new ProposalContextInformation(methodProposal); } /** * Returns the <code>CompletionContext</code> for this completion operation. * * @return the <code>CompletionContext</code> for this completion operation */ protected final CompletionContext getContext() { return fContext; } /** * Returns the type signature of the declaring type of a <code>CompletionProposal</code>, or * <code>null</code> for proposals that do not have a declaring type. The return value is * <em>not</em> <code>null</code> for proposals of the following kinds: * <ul> * <li>METHOD_DECLARATION</li> * <li>METHOD_NAME_REFERENCE</li> * <li>METHOD_REF</li> * <li>ANNOTATION_ATTRIBUTE_REF</li> * <li>POTENTIAL_METHOD_DECLARATION</li> * <li>ANONYMOUS_CLASS_DECLARATION</li> * <li>FIELD_REF</li> * <li>PACKAGE_REF (returns the package, but no type)</li> * <li>TYPE_REF</li> * </ul> * * @param proposal the completion proposal to get the declaring type for * @return the type signature of the declaring type, or <code>null</code> if there is none */ protected final char[] getDeclaringType(CompletionProposal proposal) { switch (proposal.getKind()) { case CompletionProposal.METHOD_DECLARATION: case CompletionProposal.METHOD_NAME_REFERENCE: // case CompletionProposal.JAVADOC_METHOD_REF: case CompletionProposal.METHOD_REF: case CompletionProposal.ARGUMENT_LIST: case CompletionProposal.CONSTRUCTOR_INVOCATION: // case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION: // case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER: // case CompletionProposal.ANNOTATION_ATTRIBUTE_REF: case CompletionProposal.POTENTIAL_METHOD_DECLARATION: // case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: case CompletionProposal.FIELD_REF: // case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER: // case CompletionProposal.JAVADOC_FIELD_REF: // case CompletionProposal.JAVADOC_VALUE_REF: char[] declaration = proposal.getDeclarationSignature(); // special methods may not have a declaring type: methods defined on arrays etc. // Currently known: class literals don't have a declaring type - use Object // if (declaration == null) { // return "java.lang.Object".toCharArray(); //$NON-NLS-1$ // } return Signature.toCharArray(declaration); case CompletionProposal.LIBRARY_PREFIX: return proposal.getDeclarationSignature(); // case CompletionProposal.JAVADOC_TYPE_REF: case CompletionProposal.TYPE_REF: return Signature.toCharArray(proposal.getSignature()); case CompletionProposal.LOCAL_VARIABLE_REF: case CompletionProposal.VARIABLE_DECLARATION: case CompletionProposal.KEYWORD: case CompletionProposal.LABEL_REF: case CompletionProposal.TYPE_IMPORT: case CompletionProposal.OPTIONAL_ARGUMENT: case CompletionProposal.NAMED_ARGUMENT: // case CompletionProposal.JAVADOC_BLOCK_TAG: // case CompletionProposal.JAVADOC_INLINE_TAG: // case CompletionProposal.JAVADOC_PARAM_REF: return null; default: Assert.isTrue(false); return null; } } /** * Returns a cached image for the given descriptor. * * @param descriptor the image descriptor to get an image for, may be <code>null</code> * @return the image corresponding to <code>descriptor</code> */ protected final Image getImage(ImageDescriptor descriptor) { return (descriptor == null) ? null : fRegistry.get(descriptor); } /** * Returns the invocation context. If none has been set via * {@link #setInvocationContext(DartContentAssistInvocationContext)}, a new one is created. * * @return invocationContext the invocation context */ protected final DartContentAssistInvocationContext getInvocationContext() { if (fInvocationContext == null) { setInvocationContext(new DartContentAssistInvocationContext()); } return fInvocationContext; } /** * Returns the proposal label provider used by the receiver. * * @return the proposal label provider used by the receiver */ protected final CompletionProposalLabelProvider getLabelProvider() { return fLabelProvider; } /** * Returns the replacement length of a given completion proposal. The replacement length is * usually the difference between the return values of <code>proposal.getReplaceEnd</code> and * <code>proposal.getReplaceStart</code>, but this behavior may be overridden by calling * {@link #setReplacementLength(int)}. * * @param proposal the completion proposal to get the replacement length for * @return the replacement length for <code>proposal</code> */ protected final int getLength(CompletionProposal proposal) { int start = proposal.getReplaceStart(); int end = proposal.getReplaceEnd(); int length; if (fUserReplacementLength == -1) { length = end - start; } else { length = fUserReplacementLength; // extend length to begin at start int behindCompletion = proposal.getCompletionLocation() + 1; if (start < behindCompletion) { length += behindCompletion - start; } } return length; } /** * Returns <code>true</code> if <code>proposal</code> is filtered, e.g. should not be proposed to * the user, <code>false</code> if it is valid. * <p> * Subclasses may extends this method. The default implementation filters proposals set to be * ignored via {@linkplain CompletionRequestor#setIgnored(int, boolean) setIgnored} and types set * to be ignored in the preferences. * </p> * * @param proposal the proposal to filter * @return <code>true</code> to filter <code>proposal</code>, <code>false</code> to let it pass */ protected boolean isFiltered(CompletionProposal proposal) { if (isIgnored(proposal.getKind())) { return true; } char[] declaringType = getDeclaringType(proposal); return declaringType != null && TypeFilter.isFiltered(declaringType); } private void adaptLength(LazyDartCompletionProposal proposal, CompletionProposal coreProposal) { if (fUserReplacementLength != -1) { proposal.setReplacementLength(getLength(coreProposal)); } } // private IDartCompletionProposal createAnnotationAttributeReferenceProposal( // CompletionProposal proposal) { // StyledString displayString= fLabelProvider.createLabelWithTypeAndDeclaration(proposal); // ImageDescriptor descriptor= fLabelProvider.createMethodImageDescriptor(proposal); // String completion= String.valueOf(proposal.getCompletion()); // DartCompletionProposal javaProposal= new DartCompletionProposal(completion, proposal.getReplaceStart(), getLength(proposal), getImage(descriptor), displayString, computeRelevance(proposal)); // if (fJavaProject != null) // javaProposal.setProposalInfo(new AnnotationAtttributeProposalInfo(fJavaProject, proposal)); // return javaProposal; // } // private IDartCompletionProposal createAnonymousTypeProposal(CompletionProposal proposal, // DartContentAssistInvocationContext invocationContext) { // if (fCompilationUnit == null || fJavaProject == null) // return null; // // char[] declarationKey= proposal.getDeclarationKey(); // if (declarationKey == null) // return null; // // try { // DartElement element= fJavaProject.findElement(new String(declarationKey), null); // if (!(element instanceof Type)) // return null; // // Type type= (Type) element; // // String completion= String.valueOf(proposal.getCompletion()); // int start= proposal.getReplaceStart(); // int length= getLength(proposal); // int relevance= computeRelevance(proposal); // // StyledString label= fLabelProvider.createAnonymousTypeLabel(proposal); // // DartCompletionProposal javaProposal= new AnonymousTypeCompletionProposal(fJavaProject, fCompilationUnit, invocationContext, start, length, completion, label, String.valueOf(proposal // .getDeclarationSignature()), type, relevance); // javaProposal.setProposalInfo(new AnonymousTypeProposalInfo(fJavaProject, proposal)); // return javaProposal; // } catch (DartModelException e) { // return null; // } // } private IDartCompletionProposal createFieldProposal(CompletionProposal proposal) { String completion = String.valueOf(proposal.getCompletion()); int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString label = fLabelProvider.createStyledLabel(proposal); Image image = getImage(fLabelProvider.createFieldImageDescriptor(proposal)); int relevance = computeRelevance(proposal); @SuppressWarnings("deprecation") DartCompletionProposal dartProposal = new DartCompletionProposal( completion, start, length, getLengthIdentifier(proposal), image, label, relevance, getContext().isInJavadoc(), proposal.getElementDocSummary(), proposal.getElementDocDetails(), getInvocationContext()); // TODO(scheglov) implement documentation comment // if (fDartProject != null) { // dartProposal.setProposalInfo(new FieldProposalInfo(fDartProject, proposal)); // } dartProposal.setTriggerCharacters(VAR_TRIGGER); return dartProposal; } private IDartCompletionProposal createImportProposal(CompletionProposal proposal) { String completion = String.valueOf(proposal.getCompletion()); int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString label = new StyledString(fLabelProvider.createSimpleLabel(proposal));//TODO(messick) int relevance = computeRelevance(proposal); ImageDescriptor imageDesc = fLabelProvider.createImageDescriptor(proposal); Image image = DartToolsPlugin.getImageDescriptorRegistry().get(imageDesc); return new DartCompletionProposal( completion, start, length, getLengthIdentifier(proposal), image, label, relevance, proposal.getElementDocSummary(), proposal.getElementDocDetails()); } // /** // * Creates the Java completion proposal for the JDT Core // * {@link CompletionProposal#FIELD_REF_WITH_CASTED_RECEIVER} proposal. // * // * @param proposal the JDT Core proposal // * @return the Java completion proposal // */ // private IDartCompletionProposal createFieldWithCastedReceiverProposal(CompletionProposal proposal) { // String completion= String.valueOf(proposal.getCompletion()); // completion= CodeFormatterUtil.format(CodeFormatter.K_EXPRESSION, completion, 0, "\n", fJavaProject); //$NON-NLS-1$ // int start= proposal.getReplaceStart(); // int length= getLength(proposal); // StyledString label= fLabelProvider.createStyledLabel(proposal); // Image image= getImage(fLabelProvider.createFieldImageDescriptor(proposal)); // int relevance= computeRelevance(proposal); // // DartCompletionProposal javaProposal= new DartFieldWithCastedReceiverCompletionProposal(completion, start, length, image, label, relevance, getContext().isInJavadoc(), getInvocationContext(), proposal); // if (fJavaProject != null) // javaProposal.setProposalInfo(new FieldProposalInfo(fJavaProject, proposal)); // // javaProposal.setTriggerCharacters(VAR_TRIGGER); // // return javaProposal; // } // private IDartCompletionProposal createJavadocInlineTagProposal(CompletionProposal javadocProposal) { // LazyDartCompletionProposal proposal= new JavadocInlineTagCompletionProposal(javadocProposal, getInvocationContext()); // adaptLength(proposal, javadocProposal); // return proposal; // } // private IDartCompletionProposal createJavadocLinkTypeProposal(CompletionProposal typeProposal) { // LazyDartCompletionProposal proposal= new JavadocLinkTypeCompletionProposal(typeProposal, getInvocationContext()); // adaptLength(proposal, typeProposal); // return proposal; // } // private IDartCompletionProposal createJavadocSimpleProposal(CompletionProposal javadocProposal) { // TODO do better with javadoc proposals // String completion= String.valueOf(proposal.getCompletion()); // int start= proposal.getReplaceStart(); // int length= getLength(proposal); // String label= fLabelProvider.createSimpleLabel(proposal); // Image image= getImage(fLabelProvider.createImageDescriptor(proposal)); // int relevance= computeRelevance(proposal); // // DartCompletionProposal javaProposal= new DartCompletionProposal(completion, start, length, image, label, relevance); // if (fJavaProject != null) // javaProposal.setProposalInfo(new FieldProposalInfo(fJavaProject, proposal)); // // javaProposal.setTriggerCharacters(VAR_TRIGGER); // // return javaProposal; // LazyDartCompletionProposal proposal = new LazyDartCompletionProposal(javadocProposal, // getInvocationContext()); // adaptLength(proposal, javadocProposal); // return proposal; // } private IDartCompletionProposal createKeywordProposal(CompletionProposal proposal) { String completion = String.valueOf(proposal.getCompletion()); int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString label = new StyledString(fLabelProvider.createSimpleLabel(proposal));//TODO(messick) int relevance = computeRelevance(proposal); return new DartCompletionProposal( completion, start, length, getLengthIdentifier(proposal), null, label, relevance, proposal.getElementDocSummary(), proposal.getElementDocDetails()); } private IDartCompletionProposal createLabelProposal(CompletionProposal proposal) { String completion = String.valueOf(proposal.getCompletion()); int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString label = new StyledString(fLabelProvider.createSimpleLabel(proposal));//TODO(messick) int relevance = computeRelevance(proposal); return new DartCompletionProposal( completion, start, length, getLengthIdentifier(proposal), null, label, relevance, proposal.getElementDocSummary(), proposal.getElementDocDetails()); } private IDartCompletionProposal createLibraryPrefixProposal(CompletionProposal proposal) { String completion = String.valueOf(proposal.getCompletion()); int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString label = new StyledString(fLabelProvider.createSimpleLabel(proposal));//TODO(messick) Image image = getImage(fLabelProvider.createLibraryImageDescriptor(proposal)); int relevance = computeRelevance(proposal); return new DartCompletionProposal( completion, start, length, getLengthIdentifier(proposal), image, label, relevance, proposal.getElementDocSummary(), proposal.getElementDocDetails()); } private IDartCompletionProposal createLocalVariableProposal(CompletionProposal proposal) { String completion = String.valueOf(proposal.getCompletion()); int start = proposal.getReplaceStart(); int length = getLength(proposal); Image image = getImage(fLabelProvider.createLocalImageDescriptor(proposal)); StyledString label = fLabelProvider.createLabelWithType(proposal); int relevance = computeRelevance(proposal); final DartCompletionProposal dartProposal = new DartCompletionProposal( completion, start, length, getLengthIdentifier(proposal), image, label, relevance, proposal.getElementDocSummary(), proposal.getElementDocDetails()); dartProposal.setTriggerCharacters(VAR_TRIGGER); return dartProposal; } private IDartCompletionProposal createMethodReferenceProposal(CompletionProposal methodProposal) { LazyDartCompletionProposal proposal = new DartMethodCompletionProposal( methodProposal, getInvocationContext()); adaptLength(proposal, methodProposal); return proposal; } private IDartCompletionProposal createTypeProposal(CompletionProposal typeProposal) { LazyDartCompletionProposal proposal = new LazyDartTypeCompletionProposal( typeProposal, getInvocationContext()); adaptLength(proposal, typeProposal); return proposal; } private int getLengthIdentifier(CompletionProposal proposal) { return proposal.getReplaceEndIdentifier() - proposal.getReplaceStart(); } }