blob: 8d0efc1ee723ce689fc15a95397fe75decbb8d34 [file] [log] [blame]
/*******************************************************************************
* 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);
}
}