/*
* 12/22/2008
*
* FunctionCompletion.java - A completion representing a function.
*
* This library is distributed under a modified BSD license. See the included
* RSyntaxTextArea.License.txt file for details.
*/
package org.fife.ui.autocomplete;
import java.util.ArrayList;
import java.util.List;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
/**
* A completion choice representing a function.
*
* @author Robert Futrell
* @version 1.0
*/
public class FunctionCompletion extends VariableCompletion
implements ParameterizedCompletion {
/**
* Parameters to the function.
*/
private List<Parameter> params;
/**
* A description of the return value of this function.
*/
private String returnValDesc;
/**
* Constructor.
*
* @param provider The parent provider.
* @param name The name of this function.
* @param returnType The return type of this function.
*/
public FunctionCompletion(CompletionProvider provider, String name,
String returnType) {
super(provider, name, returnType);
}
@Override
protected void addDefinitionString(StringBuilder sb) {
sb.append("<html><b>");
sb.append(getDefinitionString());
sb.append("</b>");
}
/**
* Adds HTML describing the parameters to this function to a buffer.
*
* @param sb The buffer to append to.
*/
protected void addParameters(StringBuilder sb) {
// TODO: Localize me
int paramCount = getParamCount();
if (paramCount>0) {
sb.append("<b>Parameters:</b><br>");
sb.append("<center><table width='90%'><tr><td>");
for (int i=0; i<paramCount; i++) {
Parameter param = getParam(i);
sb.append("<b>");
sb.append(param.getName()!=null ? param.getName() :
param.getType());
sb.append("</b> ");
String desc = param.getDescription();
if (desc!=null) {
sb.append(desc);
}
sb.append("<br>");
}
sb.append("</td></tr></table></center><br><br>");
}
if (returnValDesc!=null) {
sb.append("<b>Returns:</b><br><center><table width='90%'><tr><td>");
sb.append(returnValDesc);
sb.append("</td></tr></table></center><br><br>");
}
}
/**
* Returns the "definition string" for this function completion. For
* example, for the C "<code>printf</code>" function, this would return
* "<code>int printf(const char *, ...)</code>".
*
* @return The definition string.
*/
@Override
public String getDefinitionString() {
StringBuilder sb = new StringBuilder();
// Add the return type if applicable (C macros like NULL have no type).
String type = getType();
if (type!=null) {
sb.append(type).append(' ');
}
// Add the item being described's name.
sb.append(getName());
// Add parameters for functions.
CompletionProvider provider = getProvider();
char start = provider.getParameterListStart();
if (start!=0) {
sb.append(start);
}
for (int i=0; i<getParamCount(); i++) {
Parameter param = getParam(i);
type = param.getType();
String name = param.getName();
if (type!=null) {
sb.append(type);
if (name!=null) {
sb.append(' ');
}
}
if (name!=null) {
sb.append(name);
}
if (i<params.size()-1) {
sb.append(provider.getParameterListSeparator());
}
}
char end = provider.getParameterListEnd();
if (end!=0) {
sb.append(end);
}
return sb.toString();
}
public ParameterizedCompletionInsertionInfo getInsertionInfo(
JTextComponent tc, boolean replaceTabsWithSpaces) {
ParameterizedCompletionInsertionInfo info =
new ParameterizedCompletionInsertionInfo();
StringBuilder sb = new StringBuilder();
char paramListStart = getProvider().getParameterListStart();
if (paramListStart!='\0') {
sb.append(paramListStart);
}
int dot = tc.getCaretPosition() + sb.length();
int paramCount = getParamCount();
// Get the range in which the caret can move before we hide
// this tool tip.
int minPos = dot;
Position maxPos = null;
try {
maxPos = tc.getDocument().createPosition(dot-sb.length()+1);
} catch (BadLocationException ble) {
ble.printStackTrace(); // Never happens
}
info.setCaretRange(minPos, maxPos);
int firstParamLen = 0;
// Create the text to insert (keep it one completion for
// performance and simplicity of undo/redo).
int start = dot;
for (int i=0; i<paramCount; i++) {
Parameter param = getParam(i);
String paramText = getParamText(param);
if (i==0) {
firstParamLen = paramText.length();
}
sb.append(paramText);
int end = start + paramText.length();
info.addReplacementLocation(start, end);
// Patch for param. list separators with length > 2 -
// thanks to Matthew Adereth!
String sep = getProvider().getParameterListSeparator();
if (i<paramCount-1 && sep!=null) {
sb.append(sep);
start = end + sep.length();
}
}
sb.append(getProvider().getParameterListEnd());
int endOffs = dot + sb.length();
endOffs -= 1;//getProvider().getParameterListStart().length();
info.addReplacementLocation(endOffs, endOffs); // offset after function
info.setDefaultEndOffs(endOffs);
int selectionEnd = paramCount>0 ? (dot+firstParamLen) : dot;
info.setInitialSelection(dot, selectionEnd);
info.setTextToInsert(sb.toString());
return info;
}
/**
* {@inheritDoc}
*/
public Parameter getParam(int index) {
return params.get(index);
}
/**
* Returns the number of parameters to this function.
*
* @return The number of parameters to this function.
* @see #getParam(int)
*/
public int getParamCount() {
return params==null ? 0 : params.size();
}
/**
* {@inheritDoc}
*/
public boolean getShowParameterToolTip() {
return true;
}
/**
* Returns the text to insert for a parameter.
*
* @param param The parameter.
* @return The text.
*/
private String getParamText(ParameterizedCompletion.Parameter param) {
String text = param.getName();
if (text==null) {
text = param.getType();
if (text==null) { // Shouldn't ever happen
text = "arg";
}
}
return text;
}
/**
* Returns the description of the return value of this function.
*
* @return The description, or <code>null</code> if there is none.
* @see #setReturnValueDescription(String)
*/
public String getReturnValueDescription() {
return returnValDesc;
}
/**
* {@inheritDoc}
*/
@Override
public String getSummary() {
StringBuilder sb = new StringBuilder();
addDefinitionString(sb);
if (!possiblyAddDescription(sb)) {
sb.append("<br><br><br>");
}
addParameters(sb);
possiblyAddDefinedIn(sb);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public String getToolTipText() {
String text = getSummary();
if (text==null) {
text = getDefinitionString();
}
return text;
}
/**
* Sets the parameters to this function.
*
* @param params The parameters. This should be a list of
* {@link ParameterizedCompletion.Parameter}s.
* @see #getParam(int)
* @see #getParamCount()
*/
public void setParams(List<Parameter> params) {
if (params!=null) {
// Deep copy so parsing can re-use its array.
this.params = new ArrayList<Parameter>(params);
}
}
/**
* Sets the description of the return value of this function.
*
* @param desc The description.
* @see #getReturnValueDescription()
*/
public void setReturnValueDescription(String desc) {
this.returnValDesc = desc;
}
}