/**
  * 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);
 }