/** * Computes the relevance for a given <code>CompletionProposal</code>. * * <p>Subclasses may replace, but usually should not need to. * * @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; } }
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.getElement(), getInvocationContext()); // TODO(scheglov) implement documentation comment // if (fDartProject != null) { // dartProposal.setProposalInfo(new FieldProposalInfo(fDartProject, proposal)); // } dartProposal.setTriggerCharacters(VAR_TRIGGER); return dartProposal; }
/** * Resolves the member described by the receiver and returns it if found. Returns <code>null * </code> if no corresponding member can be found. * * @return the resolved member or <code>null</code> if none is found * @throws DartModelException if accessing the Dart model fails */ @SuppressWarnings("deprecation") protected Type resolveType() throws DartModelException { String typeName = String.valueOf(proposal.getSignature()); Type type = project.findType(typeName); if (type == null) { type = project.findType(new String(proposal.getCompletion())); } return type; }
/** * 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. * * @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); }
/** * 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; }
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.getElement()); }
/** * 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>METHOD_NAME_REFERENCE * <li>METHOD_REF * <li>ANNOTATION_ATTRIBUTE_REF * <li>POTENTIAL_METHOD_DECLARATION * <li>ANONYMOUS_CLASS_DECLARATION * <li>FIELD_REF * <li>PACKAGE_REF (returns the package, but no type) * <li>TYPE_REF * </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; } }
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.getElement()); }
/** * Tells whether required proposals are supported by this proposal. * * @return <code>true</code> if required proposals are supported by this proposal */ protected boolean isSupportingRequiredProposals() { if (fInvocationContext == null) { return false; } ProposalInfo proposalInfo = getProposalInfo(); if (!(proposalInfo instanceof MemberProposalInfo)) { return false; } CompletionProposal proposal = ((MemberProposalInfo) proposalInfo).fProposal; return proposal != null && (proposal.getKind() == CompletionProposal.METHOD_REF || proposal.getKind() == CompletionProposal.FIELD_REF || proposal.getKind() == CompletionProposal.TYPE_REF // || proposal.getKind() == // CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION || proposal.getKind() == CompletionProposal.CONSTRUCTOR_INVOCATION); }
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.getElement()); }
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.getElement()); dartProposal.setTriggerCharacters(VAR_TRIGGER); return dartProposal; }
/** * 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>Implementations may return <code>null</code> if a proposal should not be included in the * list presented to the user. * * <p>Subclasses may extend or replace this method. * * @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 createMethodDeclarationProposal(proposal); // 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; } }
/** * {@inheritDoc} * * <p>Subclasses may replace, but usually should not need to. Consider replacing {@linkplain * #createDartCompletionProposal(CompletionProposal) createDartCompletionProposal} instead. */ @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) { acceptPotentialMethodDeclaration(proposal); } 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; } }
private IDartCompletionProposal createMethodDeclarationProposal(CompletionProposal proposal) { if (fCompilationUnit == null || fDartProject == null) { return null; } String name = String.valueOf(proposal.getName()); String[] paramTypes = Signature.getParameterTypes(String.valueOf(proposal.getSignature())); for (int index = 0; index < paramTypes.length; index++) { paramTypes[index] = Signature.toString(paramTypes[index]); } int start = proposal.getReplaceStart(); int length = getLength(proposal); StyledString label = new StyledString( fLabelProvider.createOverrideMethodProposalLabel(proposal)); // TODO(messick) DartCompletionProposal dartProposal = new OverrideCompletionProposal( fDartProject, fCompilationUnit, name, paramTypes, start, length, getLengthIdentifier(proposal), label, String.valueOf(proposal.getCompletion())); dartProposal.setImage(getImage(fLabelProvider.createMethodImageDescriptor(proposal))); // TODO(scheglov) implement documentation comment // dartProposal.setProposalInfo(new MethodProposalInfo(fDartProject, proposal)); dartProposal.setRelevance(computeRelevance(proposal)); fSuggestedMethodNames.add(new String(name)); return dartProposal; }
private void acceptPotentialMethodDeclaration(CompletionProposal proposal) { try { DartElement enclosingElement = null; if (getContext().isExtended()) { enclosingElement = getContext().getEnclosingElement(); } else if (fCompilationUnit != null) { enclosingElement = fCompilationUnit.getElementAt(proposal.getCompletionLocation() + 1); } if (enclosingElement == null) { return; } Type type = enclosingElement.getAncestor(Type.class); if (type != null) { String prefix = String.valueOf(proposal.getName()); int completionStart = proposal.getReplaceStart(); int completionEnd = proposal.getReplaceEnd(); int relevance = computeRelevance(proposal); GetterSetterCompletionProposal.evaluateProposals( type, prefix, completionStart, completionEnd - completionStart, proposal.getReplaceEndIdentifier() - completionStart, relevance + 2, fSuggestedMethodNames, fDartProposals); MethodDeclarationCompletionProposal.evaluateProposals( type, prefix, completionStart, completionEnd - completionStart, proposal.getReplaceEndIdentifier() - completionStart, relevance, fSuggestedMethodNames, fDartProposals); } } catch (CoreException e) { DartToolsPlugin.log(e); } }
@Override public void apply(IDocument document, char trigger, int offset) { InstrumentationBuilder instrumentation = Instrumentation.builder("CompletionProposal-Apply"); instrumentation.metric("Trigger", trigger); try { if (isSupportingRequiredProposals()) { CompletionProposal coreProposal = ((MemberProposalInfo) getProposalInfo()).fProposal; CompletionProposal[] requiredProposals = coreProposal.getRequiredProposals(); for (int i = 0; requiredProposals != null && i < requiredProposals.length; i++) { int oldLen = document.getLength(); if (requiredProposals[i].getKind() == CompletionProposal.TYPE_REF) { LazyDartCompletionProposal proposal = createRequiredTypeCompletionProposal(requiredProposals[i], fInvocationContext); proposal.apply(document); setReplacementOffset(getReplacementOffset() + document.getLength() - oldLen); } else { /* * we only support the above required proposals, see * CompletionProposal#getRequiredProposals() */ Assert.isTrue(false); } } } try { boolean isSmartTrigger = isSmartTrigger(trigger); instrumentation.metric("isSmartTrigger", isSmartTrigger); String replacement; if (isSmartTrigger || trigger == (char) 0) { replacement = getReplacementString(); } else { StringBuffer buffer = new StringBuffer(getReplacementString()); // fix for PR #5533. Assumes that no eating takes place. if ((getCursorPosition() > 0 && getCursorPosition() <= buffer.length() && buffer.charAt(getCursorPosition() - 1) != trigger)) { buffer.insert(getCursorPosition(), trigger); setCursorPosition(getCursorPosition() + 1); } replacement = buffer.toString(); setReplacementString(replacement); } instrumentation.data("Replacement", replacement); // reference position just at the end of the document change. int referenceOffset = getReplacementOffset() + getReplacementLength(); final ReferenceTracker referenceTracker = new ReferenceTracker(); referenceTracker.preReplace(document, referenceOffset); replace(document, getReplacementOffset(), getReplacementLength(), replacement); referenceOffset = referenceTracker.postReplace(document); int delta = replacement == null ? 0 : replacement.length(); if (delta > 0 && replacement.charAt(replacement.length() - 1) == ']') { delta += 1; } setReplacementOffset(referenceOffset - delta); // PR 47097 if (isSmartTrigger) { handleSmartTrigger(document, trigger, referenceOffset); } } catch (BadLocationException x) { instrumentation.metric("Problem", "BadLocationException"); // ignore } } finally { instrumentation.log(); } }
private int getLengthIdentifier(CompletionProposal proposal) { return proposal.getReplaceEndIdentifier() - proposal.getReplaceStart(); }
/** * 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); }