| /******************************************************************************* |
| * Copyright (c) 2000, 2018 IBM Corporation and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| *******************************************************************************/ |
| package org.eclipse.dltk.ui.text.completion; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.dltk.compiler.CharOperation; |
| import org.eclipse.dltk.core.CompletionContext; |
| import org.eclipse.dltk.core.CompletionProposal; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.contentassist.IContextInformation; |
| import org.eclipse.jface.viewers.StyledString; |
| import org.eclipse.swt.graphics.Image; |
| |
| public abstract class LazyScriptCompletionProposal |
| extends AbstractScriptCompletionProposal { |
| |
| protected static final String LPAREN = "("; //$NON-NLS-1$ |
| protected static final String RPAREN = ")"; //$NON-NLS-1$ |
| protected static final String COMMA = ","; //$NON-NLS-1$ |
| protected static final String SPACE = " "; //$NON-NLS-1$ |
| |
| private boolean fDisplayStringComputed; |
| private boolean fReplacementStringComputed; |
| private boolean fReplacementOffsetComputed; |
| private boolean fReplacementLengthComputed; |
| private boolean fCursorPositionComputed; |
| private boolean fImageComputed; |
| private boolean fContextInformationComputed; |
| private boolean fProposalInfoComputed; |
| private boolean fTriggerCharactersComputed; |
| // private boolean fSortStringComputed; |
| private boolean fRelevanceComputed; |
| |
| /** |
| * The core proposal wrapped by this completion proposal. |
| */ |
| protected final CompletionProposal fProposal; |
| |
| /** |
| * The invocation context of this completion proposal. |
| */ |
| protected final ScriptContentAssistInvocationContext fInvocationContext; |
| private boolean fDisplayStyledStringComputed; |
| |
| public LazyScriptCompletionProposal(CompletionProposal proposal, |
| ScriptContentAssistInvocationContext context) { |
| Assert.isNotNull(proposal); |
| Assert.isNotNull(context); |
| // FIXME it should not be null but it is |
| // Assert.isNotNull(context.getCoreContext()); |
| |
| fInvocationContext = context; |
| fProposal = proposal; |
| } |
| |
| @Override |
| public final char[] getTriggerCharacters() { |
| if (!fTriggerCharactersComputed) { |
| setTriggerCharacters(computeTriggerCharacters()); |
| } |
| |
| return super.getTriggerCharacters(); |
| } |
| |
| protected char[] computeTriggerCharacters() { |
| return CharOperation.NO_CHAR; |
| } |
| |
| /** |
| * Sets the trigger characters. |
| * |
| * @param triggerCharacters |
| * The set of characters which can trigger the |
| * application of this completion proposal |
| */ |
| @Override |
| public final void setTriggerCharacters(char[] triggerCharacters) { |
| fTriggerCharactersComputed = true; |
| super.setTriggerCharacters(triggerCharacters); |
| } |
| |
| /** |
| * Sets the proposal info. |
| * |
| * @param proposalInfo |
| * The additional information associated with this |
| * proposal or <code>null</code> |
| */ |
| @Override |
| public final void setProposalInfo(ICompletionProposalInfo proposalInfo) { |
| fProposalInfoComputed = true; |
| super.setProposalInfo(proposalInfo); |
| } |
| |
| /** |
| * Returns the additional proposal info, or <code>null</code> if none |
| * exists. |
| * |
| * @return the additional proposal info, or <code>null</code> if none exists |
| */ |
| @Override |
| public final ICompletionProposalInfo getProposalInfo() { |
| if (!fProposalInfoComputed) { |
| setProposalInfo(computeProposalInfo()); |
| } |
| |
| return super.getProposalInfo(); |
| } |
| |
| protected ICompletionProposalInfo computeProposalInfo() { |
| return null; |
| } |
| |
| /** |
| * Sets the cursor position relative to the insertion offset. By default |
| * this is the length of the completion string (Cursor positioned after the |
| * completion) |
| * |
| * @param cursorPosition |
| * The cursorPosition to set |
| */ |
| @Override |
| public final void setCursorPosition(int cursorPosition) { |
| fCursorPositionComputed = true; |
| super.setCursorPosition(cursorPosition); |
| } |
| |
| @Override |
| protected final int getCursorPosition() { |
| if (!fCursorPositionComputed) { |
| setCursorPosition(computeCursorPosition()); |
| } |
| return super.getCursorPosition(); |
| } |
| |
| protected int computeCursorPosition() { |
| return getReplacementString().length(); |
| } |
| |
| @Override |
| protected boolean isInDoc() { |
| final CompletionContext coreContext = fInvocationContext |
| .getCoreContext(); |
| // FIXME it should not be null but it is |
| return coreContext != null && coreContext.isInDoc(); |
| } |
| |
| @Override |
| public final IContextInformation getContextInformation() { |
| if (!fContextInformationComputed) { |
| setContextInformation(computeContextInformation()); |
| } |
| return super.getContextInformation(); |
| } |
| |
| protected IContextInformation computeContextInformation() { |
| return null; |
| } |
| |
| /** |
| * Sets the context information. |
| * |
| * @param contextInformation |
| * The context information associated with |
| * this proposal |
| */ |
| @Override |
| public final void setContextInformation( |
| IContextInformation contextInformation) { |
| fContextInformationComputed = true; |
| super.setContextInformation(contextInformation); |
| } |
| |
| /* |
| * @see ICompletionProposal#getDisplayString() |
| */ |
| @Override |
| public final String getDisplayString() { |
| if (!fDisplayStringComputed) { |
| setDisplayString(computeDisplayString()); |
| } |
| return super.getDisplayString(); |
| } |
| |
| @Override |
| protected final void setDisplayString(String string) { |
| fDisplayStringComputed = true; |
| super.setDisplayString(string); |
| } |
| |
| protected String computeDisplayString() { |
| return fInvocationContext.getLabelProvider().createLabel(fProposal); |
| } |
| |
| @Override |
| public StyledString getStyledDisplayString() { |
| if (!fDisplayStyledStringComputed) { |
| setStyledDisplayString(computeStyledDisplayString()); |
| } |
| return super.getStyledDisplayString(); |
| } |
| |
| @Override |
| public final void setStyledDisplayString(StyledString string) { |
| fDisplayStyledStringComputed = true; |
| super.setStyledDisplayString(string); |
| } |
| |
| /** |
| * @since 5.2 |
| */ |
| protected StyledString computeStyledDisplayString() { |
| CompletionProposalLabelProvider labelProvider = fInvocationContext |
| .getLabelProvider(); |
| if (labelProvider instanceof ICompletionProposalLabelProviderExtension) { |
| return ((ICompletionProposalLabelProviderExtension) labelProvider) |
| .createStyledLabel(fProposal); |
| } |
| return new StyledString(labelProvider.createLabel(fProposal)); |
| } |
| |
| @Override |
| public final String getAdditionalProposalInfo() { |
| return super.getAdditionalProposalInfo(); |
| } |
| |
| @Override |
| public final int getContextInformationPosition() { |
| if (getContextInformation() == null) { |
| return getReplacementOffset() - 1; |
| } |
| return getReplacementOffset() + getCursorPosition(); |
| } |
| |
| /** |
| * Gets the replacement offset. |
| * |
| * @return Returns a int |
| */ |
| @Override |
| public final int getReplacementOffset() { |
| if (!fReplacementOffsetComputed) { |
| setReplacementOffset(fProposal.getReplaceStart()); |
| } |
| return super.getReplacementOffset(); |
| } |
| |
| /** |
| * Sets the replacement offset. |
| * |
| * @param replacementOffset |
| * The replacement offset to set |
| */ |
| @Override |
| public final void setReplacementOffset(int replacementOffset) { |
| fReplacementOffsetComputed = true; |
| super.setReplacementOffset(replacementOffset); |
| } |
| |
| @Override |
| public int getPrefixCompletionStart(IDocument document, |
| int completionOffset) { |
| return getReplacementOffset(); |
| } |
| |
| /** |
| * Gets the replacement length. |
| * |
| * @return Returns a int |
| */ |
| @Override |
| public final int getReplacementLength() { |
| if (!fReplacementLengthComputed) |
| setReplacementLength( |
| fProposal.getReplaceEnd() - fProposal.getReplaceStart()); |
| return super.getReplacementLength(); |
| } |
| |
| /** |
| * Sets the replacement length. |
| * |
| * @param replacementLength |
| * The replacementLength to set |
| */ |
| @Override |
| public final void setReplacementLength(int replacementLength) { |
| fReplacementLengthComputed = true; |
| super.setReplacementLength(replacementLength); |
| } |
| |
| /** |
| * Gets the replacement string. |
| * |
| * @return Returns a String |
| */ |
| @Override |
| public final String getReplacementString() { |
| if (!fReplacementStringComputed) |
| setReplacementString(computeReplacementString()); |
| return super.getReplacementString(); |
| } |
| |
| protected String computeReplacementString() { |
| return fProposal.getCompletion(); |
| } |
| |
| /** |
| * Sets the replacement string. |
| * |
| * @param replacementString |
| * The replacement string to set |
| */ |
| @Override |
| public final void setReplacementString(String replacementString) { |
| fReplacementStringComputed = true; |
| super.setReplacementString(replacementString); |
| } |
| |
| @Override |
| public final Image getImage() { |
| if (!fImageComputed) |
| setImage(computeImage()); |
| return super.getImage(); |
| } |
| |
| protected Image computeImage() { |
| return DLTKUIPlugin.getImageDescriptorRegistry().get(fInvocationContext |
| .getLabelProvider().createImageDescriptor(fProposal)); |
| } |
| |
| /** |
| * Sets the image. |
| * |
| * @param image |
| * The image to set |
| */ |
| @Override |
| public final void setImage(Image image) { |
| fImageComputed = true; |
| super.setImage(image); |
| } |
| |
| @Override |
| protected boolean isValidPrefix(String prefix) { |
| if (super.isValidPrefix(prefix)) |
| return true; |
| |
| if (fProposal.getKind() == CompletionProposal.METHOD_NAME_REFERENCE) { |
| // static imports - includes package & type name |
| StringBuffer buf = new StringBuffer(); |
| buf.append('.'); |
| buf.append(getDisplayString()); |
| return isPrefix(prefix, buf.toString()); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Gets the proposal's relevance. |
| * |
| * @return Returns a int |
| */ |
| @Override |
| public final int getRelevance() { |
| if (!fRelevanceComputed) |
| setRelevance(computeRelevance()); |
| return super.getRelevance(); |
| } |
| |
| /** |
| * Sets the proposal's relevance. |
| * |
| * @param relevance |
| * The relevance to set |
| */ |
| @Override |
| public final void setRelevance(int relevance) { |
| fRelevanceComputed = true; |
| super.setRelevance(relevance); |
| } |
| |
| /** |
| * TODO (alex) avoid duplicated code. |
| * |
| * @see ScriptCompletionProposalCollector#computeRelevance(CompletionProposal) |
| */ |
| protected int computeRelevance() { |
| final int baseRelevance = fProposal.getRelevance() * 16; |
| switch (fProposal.getKind()) { |
| case CompletionProposal.LABEL_REF: |
| return baseRelevance + 0; |
| case CompletionProposal.KEYWORD: |
| return baseRelevance + 1; |
| case CompletionProposal.PACKAGE_REF: |
| return baseRelevance + 1; |
| case CompletionProposal.TYPE_REF: |
| return baseRelevance + 2; |
| case CompletionProposal.METHOD_REF: |
| case CompletionProposal.METHOD_NAME_REFERENCE: |
| case CompletionProposal.METHOD_DECLARATION: |
| return baseRelevance + 3; |
| case CompletionProposal.POTENTIAL_METHOD_DECLARATION: |
| return baseRelevance + 3 /* + 99 */; |
| case CompletionProposal.FIELD_REF: |
| return baseRelevance + 4; |
| case CompletionProposal.LOCAL_VARIABLE_REF: |
| case CompletionProposal.VARIABLE_DECLARATION: |
| return baseRelevance + 5; |
| default: |
| return baseRelevance; |
| } |
| } |
| |
| @Override |
| public final void setSortString(String string) { |
| // fSortStringComputed = true; |
| super.setSortString(string); |
| } |
| } |