/*******************************************************************************
* Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Eicher <eclipse@tom.eicher.name> - [content assist] prefix complete casted method proposals - https://bugs.eclipse
* .org/bugs/show_bug.cgi?id=247547
*******************************************************************************/
package org.eclipse.che.ide.ext.java.jdt.codeassistant;
import org.eclipse.che.ide.ext.java.jdt.Images;
import org.eclipse.che.ide.ext.java.jdt.codeassistant.ui.StyledString;
import org.eclipse.che.ide.ext.java.jdt.core.CompletionProposal;
import org.eclipse.che.ide.ext.java.jdt.core.JavaCore;
import org.eclipse.che.ide.ext.java.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.che.ide.ext.java.jdt.text.Document;
import org.eclipse.che.ide.runtime.Assert;
public class LazyJavaCompletionProposal extends AbstractJavaCompletionProposal {
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$
protected static final class FormatterPrefs {
/* Methods & constructors */
public final boolean beforeOpeningParen;
public final boolean afterOpeningParen;
public final boolean beforeComma;
public final boolean afterComma;
public final boolean beforeClosingParen;
public final boolean inEmptyList;
/* type parameters */
public final boolean beforeOpeningBracket;
public final boolean afterOpeningBracket;
public final boolean beforeTypeArgumentComma;
public final boolean afterTypeArgumentComma;
public final boolean beforeClosingBracket;
FormatterPrefs() {
beforeOpeningParen =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION, false);
afterOpeningParen =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION, false);
beforeComma =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS, false);
afterComma =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS, true);
beforeClosingParen =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION, false);
inEmptyList =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION, false);
beforeOpeningBracket =
getCoreOption(
DefaultCodeFormatterConstants
.FORMATTER_INSERT_SPACE_BEFORE_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE,
false);
afterOpeningBracket =
getCoreOption(
DefaultCodeFormatterConstants
.FORMATTER_INSERT_SPACE_AFTER_OPENING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE,
false);
beforeTypeArgumentComma =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE, false);
afterTypeArgumentComma =
getCoreOption(
DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_PARAMETERIZED_TYPE_REFERENCE, true);
beforeClosingBracket =
getCoreOption(
DefaultCodeFormatterConstants
.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_ANGLE_BRACKET_IN_PARAMETERIZED_TYPE_REFERENCE,
false);
}
protected final boolean getCoreOption(String key, boolean def) {
String option = getCoreOption(key);
if (JavaCore.INSERT.equals(option)) {
return true;
}
if (JavaCore.DO_NOT_INSERT.equals(option)) {
return false;
}
return def;
}
protected final String getCoreOption(String key) {
return JavaCore.getOption(key);
}
}
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;
private FormatterPrefs fFormatterPrefs;
/** The core proposal wrapped by this completion proposal. */
protected final CompletionProposal fProposal;
protected int fContextInformationPosition;
public LazyJavaCompletionProposal(CompletionProposal proposal, JavaContentAssistInvocationContext context) {
super(context);
Assert.isNotNull(proposal);
Assert.isNotNull(context);
Assert.isNotNull(context.getCoreContext());
fProposal = proposal;
}
protected CompletionProposal getProposal() {
return fProposal;
}
/*
* @see ICompletionProposalExtension#getTriggerCharacters()
*/
@Override
public final char[] getTriggerCharacters() {
if (!fTriggerCharactersComputed) {
setTriggerCharacters(computeTriggerCharacters());
}
return super.getTriggerCharacters();
}
protected char[] computeTriggerCharacters() {
return new char[0];
}
/**
* 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(ProposalInfo 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
protected final ProposalInfo getProposalInfo() {
if (!fProposalInfoComputed) {
setProposalInfo(computeProposalInfo());
}
return super.getProposalInfo();
}
protected ProposalInfo 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
public final int getCursorPosition() {
if (!fCursorPositionComputed) {
setCursorPosition(computeCursorPosition());
}
return super.getCursorPosition();
}
protected int computeCursorPosition() {
return getReplacementString().length();
}
/*
* @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#isInJavadoc()
*/
@Override
protected final boolean isInJavadoc() {
return fInvocationContext.getCoreContext().isInJavadoc();
}
// /*
// * @see ICompletionProposal#getContextInformation()
// */
// @Override
// public final ContextInformation getContextInformation()
// {
// if (!fContextInformationComputed)
// setContextInformation(computeContextInformation());
// return super.getContextInformation();
// }
//
// protected ContextInformation computeContextInformation()
// {
// return null;
// }
// /**
// * Sets the context information.
// *
// * @param contextInformation The context information associated with this proposal
// */
// @Override
// public final void setContextInformation(ContextInformation contextInformation)
// {
// fContextInformationComputed = true;
// super.setContextInformation(contextInformation);
// }
/*
* @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#getStyledDisplayString()
* @since 3.4
*/
@Override
public StyledString getStyledDisplayString() {
if (!fDisplayStringComputed) {
setStyledDisplayString(computeDisplayString());
}
return super.getStyledDisplayString();
}
@Override
public String getDisplayString() {
if (!fDisplayStringComputed) {
setStyledDisplayString(computeDisplayString());
}
return super.getDisplayString();
}
@Override
protected final void setDisplayString(String string) {
fDisplayStringComputed = true;
super.setDisplayString(string);
}
@Override
public void setStyledDisplayString(StyledString text) {
fDisplayStringComputed = true;
super.setStyledDisplayString(text);
}
protected StyledString computeDisplayString() {
return fInvocationContext.getLabelProvider().createStyledLabel(fProposal);
}
/**
* 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);
}
/*
* @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getCompletionOffset()
*/
@Override
public int getPrefixCompletionStart(Document 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 String.valueOf(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);
}
/*
* @see ICompletionProposal#getImage()
*/
@Override
public final Images getImage() {
if (!fImageComputed) {
setImage(computeImage());
}
return super.getImage();
}
protected Images computeImage() {
return fInvocationContext.getLabelProvider().createImageDescriptor(fProposal);
}
/**
* Sets the image.
*
* @param image
* The image to set
*/
@Override
public final void setImage(Images image) {
fImageComputed = true;
super.setImage(image);
}
// /*
// * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#isValidPrefix(java.lang.String)
// */
// @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(Signature.toCharArray(fProposal.getDeclarationSignature()));
// buf.append('.');
// buf.append(TextProcessor.deprocess(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);
}
protected int computeRelevance() {
final int baseRelevance = fProposal.getRelevance() * 16;
switch (fProposal.getKind()) {
case CompletionProposal.PACKAGE_REF:
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;
default:
return baseRelevance;
}
}
@Override
public final String getSortString() {
if (!fSortStringComputed) {
setSortString(computeSortString());
}
return super.getSortString();
}
@Override
protected final void setSortString(String string) {
fSortStringComputed = true;
super.setSortString(string);
}
protected String computeSortString() {
return getDisplayString();
}
protected FormatterPrefs getFormatterPrefs() {
if (fFormatterPrefs == null) {
fFormatterPrefs = new FormatterPrefs();
}
return fFormatterPrefs;
}
/**
* Overrides the default context information position. Ignored if set to zero.
*
* @param contextInformationPosition
* the replaced position.
*/
public void setContextInformationPosition(int contextInformationPosition) {
fContextInformationPosition = contextInformationPosition;
}
//
// /*
// * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#apply(org.eclipse.jface.text.ITextViewer, char,
// int, int)
// * @since 3.7
// */
// @Override
// public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
// Point selection= viewer.getSelectedRange();
// boolean smartToggle= (stateMask & SWT.CTRL) != 0;
// if (!(insertCompletion() ^ smartToggle) && selection.y > 0)
// fReplacementLengthComputed= false;
// super.apply(viewer, trigger, stateMask, offset);
// }
/** {@inheritDoc} */
@Override
public boolean isAutoInsertable() {
return false;
}
// /*
// * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#selected(org.eclipse.jface.text.ITextViewer,
// boolean)
// * @since 3.7
// */
// @Override
// public void selected(ITextViewer viewer, boolean smartToggle) {
// Point selection= viewer.getSelectedRange();
// if (!(insertCompletion() ^ smartToggle) && selection.y > 0)
// fReplacementLengthComputed= false;
// super.selected(viewer, smartToggle);
// }
}