/**
* This file Copyright (c) 2005-2008 Aptana, Inc. This program is
* dual-licensed under both the Aptana Public License and the GNU General
* Public license. You may elect to use one or the other of these licenses.
*
* This program is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. Redistribution, except as permitted by whichever of
* the GPL or APL you select, is prohibited.
*
* 1. For the GPL license (GPL), you can redistribute and/or modify this
* program under the terms of the GNU General Public License,
* Version 3, as published by the Free Software Foundation. You should
* have received a copy of the GNU General Public License, Version 3 along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Aptana provides a special exception to allow redistribution of this file
* with certain other free and open source software ("FOSS") code and certain additional terms
* pursuant to Section 7 of the GPL. You may view the exception and these
* terms on the web at http://www.aptana.com/legal/gpl/.
*
* 2. For the Aptana Public License (APL), this program and the
* accompanying materials are made available under the terms of the APL
* v1.0 which accompanies this distribution, and is available at
* http://www.aptana.com/legal/apl/.
*
* You may view the GPL, Aptana's exception and additional terms, and the
* APL in the file titled license.html at the root of the corresponding
* plugin containing this source file.
*
* Any modifications to this file must keep this entire header intact.
*/
package com.aptana.ide.editor.scriptdoc;
import java.io.IOException;
import java.io.StringReader;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
import com.aptana.ide.core.StringUtils;
import com.aptana.ide.editor.js.JSOffsetMapper;
import com.aptana.ide.editor.js.runtime.IObject;
import com.aptana.ide.editor.js.runtime.IScope;
import com.aptana.ide.editor.js.runtime.JSFunction;
import com.aptana.ide.editor.scriptdoc.parsing.FunctionDocumentation;
import com.aptana.ide.editor.scriptdoc.parsing.PropertyDocumentation;
import com.aptana.ide.editor.scriptdoc.parsing.TypedDescription;
import com.aptana.ide.editors.unified.UnifiedConfiguration;
import com.aptana.ide.editors.unified.utils.LineBreakingReader;
import com.aptana.ide.lexer.Lexeme;
import com.aptana.ide.lexer.TokenCategories;
import com.aptana.ide.metadata.IDocumentation;
import com.aptana.ide.metadata.UserAgent;
/**
* Helper for generating various forms of the JS documentation.
* @author Spike Washburn
*
*/
public final class ScriptDocHelper {
private ScriptDocHelper(){
//static utility, no instances allowed
}
/**
* DEFAULT_DELIMITER
*/
public static final String DEFAULT_DELIMITER = System.getProperty("line.separator", "\r\n") + "\u2022\t"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
/**
* Creates a HTML version of the method documentation (suitable for displaying in documentation popups)
* @param identifier The string "name" of the item
* @param fDoc the method documentation object (usually the same as doc parameter)
* @param obj Object used to read actual params on a function
* @return string
*/
public static String createMethodDocumentationHTML(String identifier, FunctionDocumentation fDoc, IObject obj) {
return createMethodDocumentationHTML(identifier, fDoc, obj, true, false);
}
/**
* Creates a HTML version of the method documentation (suitable for displaying in documentation popups)
* @param identifier The string "name" of the item
* @param fDoc the method documentation object (usually the same as doc parameter)
* @param obj Object used to read actual params on a function
* @param addReturnTypes true if return type info should be added to the information
* @param extended
* @return string
*/
public static String createMethodDocumentationHTML(String identifier, FunctionDocumentation fDoc, IObject obj, boolean addReturnTypes, boolean extended) {
StringBuffer sb = new StringBuffer();
TypedDescription[] pDocs = fDoc.getParams();
if(pDocs.length == 0)
{
sb.append(ScriptDocHelper.createMethodSignatureString(identifier, fDoc, obj, true, addReturnTypes));
if(fDoc.getDescription().trim() != "") //$NON-NLS-1$
{
sb.append("<br><br>" + fDoc.getDescription()); //$NON-NLS-1$
}
}
else
{
sb.append(ScriptDocHelper.createMethodSignatureString(identifier, fDoc, obj, true, addReturnTypes));
sb.append("<br><br>" + fDoc.getDescription()); //$NON-NLS-1$
}
UserAgent[] agents = fDoc.getUserAgents();
if(agents.length > 0)
{
sb.append(Messages.ScriptDocHelper_Supported1);
for(int i = 0; i < agents.length; i++)
{
UserAgent ua = agents[i];
sb.append(ua.getPlatform() + " " + ua.getVersion()); //$NON-NLS-1$
if(i < agents.length - 1)
{
sb.append(", "); //$NON-NLS-1$
}
}
}
if(extended)
{
String[] examples = fDoc.getExamples();
if(examples.length > 0) //$NON-NLS-1$
{
for (int i = 0; i < examples.length; i++)
{
String example = examples[i];
if(!example.startsWith("<b>Example:")) //$NON-NLS-1$
{
example = "<b>Example:</b><br>" + example; //$NON-NLS-1$
}
sb.append("<br><br>" + example); //$NON-NLS-1$
}
}
if(fDoc.getRemarks().trim() != "") //$NON-NLS-1$
{
sb.append("<br><br>" + fDoc.getRemarks()); //$NON-NLS-1$
}
if(fDoc.getAliases() != null && fDoc.getAliases().getTypes().length > 0)
{
sb.append("<br><br><b>Also known as:</b> " + StringUtils.join(", ", fDoc.getAliases().getTypes())); //$NON-NLS-1$ //$NON-NLS-2$
}
}
return sb.toString();
}
/**
* Generates the return string for the method documentation
* <b>methodName</b>(type argName, type argName) : return types
* @param identifier The string "name" of the item
* @param mDoc The method to document
* @param obj Object used to read actual params on a function
* @param asHTML Do we use HTML?
* @return string
*/
public static String createMethodSignatureString(String identifier, FunctionDocumentation mDoc, IObject obj, boolean asHTML)
{
return createMethodSignatureString( identifier, mDoc, obj, asHTML, true );
}
/**
* Generates the return string for the method documentation
* <b>methodName</b>(type argName, type argName) : return types
* @param identifier The string "name" of the item
* @param mDoc The method to document
* @param asHTML Do we use HTML?
* @param obj Object used to read actual params on a function
* @param addReturnTypes true if return type info should be added to the information
* @return string
*/
public static String createMethodSignatureString(String identifier, FunctionDocumentation mDoc, IObject obj, boolean asHTML, boolean addReturnTypes)
{
StringBuffer methodSignature = new StringBuffer();
// if(mDoc.getIsStatic().equals("static"))
// methodSignature.append(mDoc.getIsStatic() + " ");
methodSignature.append("<b>" + identifier + "</b>"); //$NON-NLS-1$ //$NON-NLS-2$
TypedDescription[] pDocs = mDoc.getParams();
String[] objParams = null;
if(obj != null && obj instanceof JSFunction)
{
objParams = ((JSFunction)obj).getParameterNames();
}
int objLen = objParams == null ? 0 : objParams.length;
int docLen = pDocs == null ? 0 : pDocs.length;
int maxLen = Math.max(objLen, docLen);
if(maxLen > 0)
{
methodSignature.append("("); //$NON-NLS-1$
}
for(int k = 0; k < maxLen; k++)
{
String docName = (k < docLen) ? pDocs[k].getName() : ""; //$NON-NLS-1$
String docCmpr = docName.replaceAll("\\[(.*)\\]", "$1"); //$NON-NLS-1$ //$NON-NLS-2$
String objName = (k < objLen) ? objParams[k] : ""; //$NON-NLS-1$
String name = (objName.equals("")) ? docName : objName; //$NON-NLS-1$
name = (docCmpr.equals(name)) ? docName : name;
String types = ""; //$NON-NLS-1$
if(k < docLen)
{
types = StringUtils.join( "|" , pDocs[k].getTypes() ) ; //$NON-NLS-1$
}
if(!types.equals("")) //$NON-NLS-1$
{
methodSignature.append("<b>" + name + "</b>: " + types); //$NON-NLS-1$ //$NON-NLS-2$
}
else
{
methodSignature.append("<b>" + name + "</b>: Object"); //$NON-NLS-1$ //$NON-NLS-2$
}
if(k < maxLen - 1)
{
methodSignature.append(", "); //$NON-NLS-1$
}
}
if(maxLen > 0)
{
methodSignature.append(")"); //$NON-NLS-1$
}
if(addReturnTypes)
{
if(mDoc.getReturn().getTypes().length > 0)
{
methodSignature.append(" : " + StringUtils.join(", ", mDoc.getReturn().getTypes() )); //$NON-NLS-1$ //$NON-NLS-2$
}
else
{
methodSignature.append(Messages.ScriptDocHelper_None1);
}
}
if(!asHTML)
{
return StringUtils.stripHTML(methodSignature.toString());
}
else
{
return methodSignature.toString();
}
}
/**
*
* @param offsetMapper
* @param lexeme
* @param extended Do we show "extended" information?
* @return Returns
*/
public static String getInformationForLexeme(JSOffsetMapper offsetMapper, Lexeme lexeme, boolean extended)
{
// String result = "";
//
// /*
// if(jsFileEnvironment.getJSContextAwareness().isEnvironmentLoaderEnabled())
// {
return getInformationForLexemeSimple(offsetMapper, lexeme, extended);
// }
// */
//
// if(lexeme.getToken().getCategoryIndex() == JSTokenCategories.KEYWORD)
// return " The javascript keyword <b>" + lexeme.getText() + "</b>. ";
//
// if(lexeme.getToken().getCategoryIndex() == JSTokenCategories.LITERAL)
// return " The javascript literal <b>" + lexeme.getText() + "</b>. ";
//
// if(lexeme.getToken().getCategoryIndex() != JSTokenCategories.IDENTIFIER)
// return result;
//
// // find docs if there are any
// IDocumentation doc = null;
//
// //int offset = lexeme.getRootCommandNode().getEndingOffset();
// // use offset by semicolon to make this workable without commandnodes
// int offset = jsFileEnvironment.getFilter().getSource().indexOf(";", lexeme.offset);
// if(offset == -1) offset = lexeme.getEndingOffset();
//
// // find if this is a property that is doc'd - if so, just use those docs
// // (property docs are attached to the property object, not the IObject instances).
// int curIndex = offsetMapper.getLexemeIndexFromDocumentOffset(lexeme.offset + lexeme.length);
//
// IScope scope = lexeme.getCommandNode().getParentScope();
// if (scope == null) scope = (IScope)jsFileEnvironment.getGlobal();
//
// IScope scope = jsFileEnvironment.getScope(lexeme, (IScope)jsFileEnvironment.getGlobal());
//
// Property prop = JSFileEnvironment.lookupTypeFromNameHash(fullName, scope, offset, jsFileEnvironment);
// if(prop != null)
// {
// doc = prop.getDocumentation();
// if(doc != null && doc instanceof PropertyDocumentation)
// {
// return createPropertyDocumentationHTML(lexeme.getText(), (PropertyDocumentation)doc, true);
// }
// }
//
// //int offset = lexeme.offset;
// CommandNode cmdNode = lexeme.getCommandNode();
// CommandNode parent = cmdNode.getParentNode();
// boolean isParameter = false;
// if(cmdNode instanceof IdentifierNode)
// {
// if(parent instanceof GetPropertyNode)
// {
// if( ((GetPropertyNode)parent).getIdentifier() == cmdNode )
// cmdNode = parent;
// }
// else if(parent instanceof FunctionNode)
// {
// cmdNode = parent;
// }
// else if(parent instanceof ParametersNode)
// {
// cmdNode = parent.getParentNode();
// isParameter = true;
// }
// }
// // end special cases TODO: move these to method when we've found them all
// Environment env = jsFileEnvironment.getEnvironment().environment;
// IObject objectNode = cmdNode.getInstance(env, jsFileEnvironment.getFileIndex(), offset);
//
// if(objectNode != null)
// {
// doc = objectNode.getDocumentation();
//
// if( doc == null &&
// objectNode instanceof ObjectBase &&
// ((ObjectBase)objectNode).getRange() instanceof ConstructNode )
// {
// ConstructNode cNode = (ConstructNode)((ObjectBase)objectNode).getRange();
// IObject cObj = cNode.getInstance(env, jsFileEnvironment.getFileIndex(), offset);
// doc = objectNode.getDocumentation();
// }
//
// if(doc != null)
// {
// if(isParameter)
// {
// result = createParameterDocumentationHTML(lexeme.getText(), (FunctionDocumentation)doc);
// }
// else if(doc instanceof FunctionDocumentation)
// result = createMethodDocumentationHTML(lexeme.getText(), (FunctionDocumentation)doc, objectNode);
// else if (objectNode instanceof FunctionNode)
// {
// JSFileEnvironment functionFileEnvironment = jsFileEnvironment.getEnvironment().findFileEnvironment(cmdNode.getStartingLexeme(), jsFileEnvironment);
// result = createFunctionDocs((FunctionNode)objectNode, functionFileEnvironment);
// }
// }else
// {
// if(objectNode instanceof IFunction)
// {
// IFunction fn = (IFunction)objectNode;
// result = "function(";
// String comma = "";
// String[] params = fn.getParameterNames();
// for (int i = 0; i < params.length; i++)
// {
// result += comma + params[i];
// comma = ", ";
// }
// result += ")";
// }
// else
// {
// IObject type = objectNode.getPropertyValue("constructor", jsFileEnvironment.getFileIndex(), offset);
// if(type != null)
// {
// IDocumentation typeDoc = type.getDocumentation();
// if(typeDoc != null && typeDoc instanceof PropertyDocumentation)
// {
// //retval = typeDoc.
// TypedDescription retval = ((PropertyDocumentation)typeDoc).getReturn();
// if(retval.getTypes().length > 0)
// {
// result = retval.getTypes()[0];
// }
// }
// }
// }
// }
// }
// return result;
}
/**
* The non-commandNode version of getting info by lexeme for hover etc.
* @param extended
* @return String
*/
private static String getInformationForLexemeSimple(JSOffsetMapper offsetMapper, Lexeme lexeme, boolean extended)
{
String result = ""; //$NON-NLS-1$
if(lexeme.getCategoryIndex() == TokenCategories.KEYWORD)
{
return Messages.ScriptDocHelper_JSKeyword + lexeme.getText() + "</b>. "; //$NON-NLS-1$
}
if(lexeme.getCategoryIndex() == TokenCategories.LITERAL)
{
return Messages.ScriptDocHelper_JSLiteral + lexeme.getText() + "</b>. "; //$NON-NLS-1$
}
if(lexeme.getCategoryIndex() != TokenCategories.IDENTIFIER)
{
return result;
}
IDocumentation doc = null;
// get offset after current position so locally assigned objects get picked up.
//int offset = lexeme.getEndingOffset();
// TODO: getFilter() no longer exists
//int offset = offsetMapper.getFilter().getSource().indexOf(";" + lexeme.offset);
//if(offset == -1) offset = lexeme.getEndingOffset(); // guard for eof before ';'
// get lexeme index
int curIndex = offsetMapper.getLexemeIndexFromDocumentOffset(lexeme.offset + lexeme.length);
// get full string name
String fullName = JSOffsetMapper.getIdentName(curIndex, offsetMapper.getLexemeList());
IScope scope = offsetMapper.getScope(lexeme, offsetMapper.getGlobal());
IObject obj = offsetMapper.lookupReturnTypeFromNameHash(fullName, scope, true);
if(obj != null)
{
doc = obj.getDocumentation();
// // not sure why this is here, we no longer put docs on properties
// if(doc == null)
// {
// Property prop = JSOffsetMapper.lookupTypeFromNameHash(fullName, scope, lexeme.offset, offsetMapper);
// if(prop != null)
// doc = prop.getDocumentation();
// }
if(doc != null && doc instanceof FunctionDocumentation)
{
return createMethodDocumentationHTML(lexeme.getText(), (FunctionDocumentation)doc, obj, true, extended);
}
else if(doc != null && doc instanceof PropertyDocumentation)
{
return createPropertyDocumentationHTML(lexeme.getText(), (PropertyDocumentation)doc, true, true, extended);
}
else if(obj instanceof JSFunction)
{
// Create new function documentation object if we have no documentation otherwise
doc = new FunctionDocumentation();
doc.setName(fullName);
return createMethodDocumentationHTML(lexeme.getText(), (FunctionDocumentation)doc, obj, true, extended);
}
}
return result;
}
// private static String createParameterDocumentationHTML(String text, FunctionDocumentation fDoc)
// {
// String result = "<b>" + text + "</b> parameter: ";
// TypedDescription[] params = fDoc.getParams();
// for(int i = 0; i < params.length; i++)
// {
// if(params[i].getName().equals(text))
// {
// result += " " + params[i].getDescription();
// break;
// }
// }
// return result;
// }
/**
* Get the signature of the function as an unformatted string
* @param node
* @param list
* @return String
*/
// private static String getFunctionSignature(FunctionNode node, LexemeList list) {
// StringBuffer sb = new StringBuffer();
// int startIndex = list.getLexemeIndex(node.getStartingOffset());
//
// //add function
// sb.append(list.get(startIndex).getText());
// if(node.hasIdentifier())
// {
// //add function name
// sb.append(" ");
// sb.append(node.getIdentifier().getName());
// }
// sb.append("(");
// if(node.hasParameters())
// {
// ParametersNode params = node.getParameters();
// sb.append(StringUtils.join(", ", params.getParameterNames()));
// }
// sb.append(")");
//
// return sb.toString();
// }
// private static String createFunctionDocs(FunctionNode functionNode, JSFileEnvironment fileEnvironment) {
// String result;
// result = "<b>" + getFunctionSignature(functionNode, fileEnvironment.getLexemeList()) + "</b>";
// if(functionNode.hasDocumentation()){
// String description = functionNode.getDocumentation().getDescription();
// if(description != null)
// result += "<p><p>" + description + "</p>";
// }
// return result;
// }
/**
* Generates the return string for the property documentation
* <b>propertyName</b>(type argName, type argName) : return types
* @param identifier The string "name" of the item
* @param pDoc The property to document
* @param asHTML Do we use HTML?
* @return String
*/
public static String createPropertyDocumentationHTML(String identifier, PropertyDocumentation pDoc, boolean asHTML)
{
return createPropertyDocumentationHTML(identifier, pDoc, asHTML, true, false);
}
/**
* Generates the return string for the property documentation
* <b>propertyName</b>(type argName, type argName) : return types
* @param identifier The string "name" of the item
* @param pDoc The property to document
* @param asHTML Do we use HTML?
* @param addReturnTypes true if return type info should be added to the information
* @param extended
* @return String
*/
public static String createPropertyDocumentationHTML(String identifier, PropertyDocumentation pDoc, boolean asHTML, boolean addReturnTypes, boolean extended)
{
StringBuffer propertySignature = new StringBuffer();
// if(pDoc.getScope().equals("static"))
// propertySignature.append(pDoc.getScope() + " ");
propertySignature.append("<b>" + identifier + "</b>"); //$NON-NLS-1$ //$NON-NLS-2$
if(addReturnTypes)
{
if(pDoc.getReturn().getTypes().length > 0)
{
propertySignature.append(" : " + StringUtils.join(", ", pDoc.getReturn().getTypes())); //$NON-NLS-1$ //$NON-NLS-2$
}
else
{
propertySignature.append(Messages.ScriptDocHelper_None2);
}
}
propertySignature.append("<br><br>" + pDoc.getDescription() + "<br>"); //$NON-NLS-1$ //$NON-NLS-2$
UserAgent[] agents = pDoc.getUserAgents();
if(agents.length > 0)
{
propertySignature.append(Messages.ScriptDocHelper_Supported2);
for(int i = 0; i < agents.length; i++)
{
UserAgent ua = agents[i];
propertySignature.append(ua.getPlatform() + " " + ua.getVersion()); //$NON-NLS-1$
if(i < agents.length - 1)
{
propertySignature.append(", "); //$NON-NLS-1$
}
}
}
if(extended)
{
String[] examples = pDoc.getExamples();
if(examples.length > 0) //$NON-NLS-1$
{
for (int i = 0; i < examples.length; i++)
{
String example = examples[i];
if(!example.startsWith("<b>Example:")) //$NON-NLS-1$
{
example = "<b>Example:</b><br>" + example; //$NON-NLS-1$
}
propertySignature.append("<br><br>" + example + "<br>"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
if(pDoc.getRemarks().trim() != "") //$NON-NLS-1$
{
propertySignature.append("<br><br>" + pDoc.getRemarks() + "<br>"); //$NON-NLS-1$ //$NON-NLS-2$
}
}
String propString = propertySignature.toString();
if(asHTML)
{
return propString;
}
else
{
return StringUtils.stripHTML(propString);
}
}
/**
* Generates the return string for the property documentation withou
* <b>propertyName</b>(type argName, type argName) : return types
* @param identifier The string "name" of the item
* @param pDoc The property to document
* @param asHTML Do we use HTML?
* @return String
*/
public static String createPropertyDocumentationHTMLSimple(String identifier, PropertyDocumentation pDoc, boolean asHTML)
{
StringBuffer propertySignature = new StringBuffer();
propertySignature.append("<b>" + identifier + "</b>"); //$NON-NLS-1$ //$NON-NLS-2$
if(pDoc.getReturn().getTypes().length > 0)
{
propertySignature.append(" : " + StringUtils.join(", ", pDoc.getReturn().getTypes())); //$NON-NLS-1$ //$NON-NLS-2$
}
propertySignature.append("<br><br>" + pDoc.getDescription() + "<br>"); //$NON-NLS-1$ //$NON-NLS-2$
UserAgent[] agents = pDoc.getUserAgents();
if(agents.length > 0)
{
propertySignature.append(Messages.ScriptDocHelper_Supported3);
for(int i = 0; i < agents.length; i++)
{
UserAgent ua = agents[i];
propertySignature.append(ua.getPlatform() + " " + ua.getVersion()); //$NON-NLS-1$
if(i < agents.length - 1)
{
propertySignature.append(", "); //$NON-NLS-1$
}
}
}
String propString = propertySignature.toString();
if(asHTML)
{
return propString;
}
else
{
return StringUtils.stripHTML(propString);
}
}
/**
* Generates the return string for the a documentation type, if there is no other type available
* @param identifier The string "name" of the item
* @param pDoc The item to document
* @param asHTML Do we use HTML?
* @return return string for the a documentation type, if there is no other type available
*/
public static String createGenericDocumentationHTML(String identifier, IDocumentation pDoc, boolean asHTML)
{
StringBuffer propertySignature = new StringBuffer();
propertySignature.append("<b>" + identifier + "</b>"); //$NON-NLS-1$ //$NON-NLS-2$
propertySignature.append(" : " + propertySignature.append(pDoc.getClass().getName())); //$NON-NLS-1$
String propString = propertySignature.toString();
if(asHTML)
{
return propString;
}
else
{
return StringUtils.stripHTML(propString);
}
}
/**
* Creates a formatted documentation string for the arg insight parameter listing
* @param parameterDocs
* @param obj
* @return The argument insight with carriage reutrns between lines
*/
public static String createParameterDocumentationList(TypedDescription[] parameterDocs, IObject obj)
{
StringBuffer paramText = new StringBuffer();
String[] parameterNames = null;
if(obj != null && obj instanceof JSFunction)
{
parameterNames = ((JSFunction)obj).getParameterNames();
}
if(containsNonEmptyDescription(parameterDocs) == false)
{
return null;
}
// sort by name of actually call site order, if available
if(parameterNames != null)
{
for(int i = 0; i < parameterNames.length; i++)
{
String parameterName = parameterNames[i];
TypedDescription curResult = findMatchingParameterDocumentation(parameterName, parameterDocs);
paramText.append(createParameterDocumentation(curResult));
if(i < parameterDocs.length - 1)
{
paramText.append(DEFAULT_DELIMITER);
}
}
}
else // call site function args not available (as in core objects) so use docs only
{
for(int i = 0; i < parameterDocs.length; i++)
{
TypedDescription parameter = parameterDocs[i];
paramText.append(createParameterDocumentation(parameter));
if(i < parameterDocs.length - 1)
{
paramText.append(DEFAULT_DELIMITER);
}
}
}
return wrapString(paramText.toString(), 420, UnifiedConfiguration.getNewlineString());
}
/**
*
* @param parameterDoc
* @param showDescriptions
* @return String
*/
private static String createParameterDocumentation(TypedDescription parameterDoc) {
String paramInfo = ""; //$NON-NLS-1$
String name = ""; //$NON-NLS-1$
if(parameterDoc != null)
{
paramInfo = wrapString(StringUtils.formatAsPlainText(parameterDoc.getDescription()), 370, UnifiedConfiguration.getNewlineString() + "\t"); //$NON-NLS-1$
name = parameterDoc.getName();
}
return name + ":" + UnifiedConfiguration.getNewlineString() + "\t" + paramInfo; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Find the parameter documentation matching the name passed in. Currently, it
* correctly strips any [] from the name to resolve conficts with optional named characters
* @param parameterName
* @param parameterDocs
* @return TypedDescription
*/
private static TypedDescription findMatchingParameterDocumentation(String parameterName, TypedDescription[] parameterDocs) {
TypedDescription curResult = null;
for (int j = 0; j < parameterDocs.length; j++)
{
TypedDescription param = parameterDocs[j];
String name = StringUtils.trimBrackets(param.getName().toUpperCase());
if(name.equals(parameterName.toUpperCase()))
{
curResult = param;
break;
}
else if(j == parameterDocs.length - 1 && name.equals("...")) //$NON-NLS-1$
{
curResult = param;
break;
}
}
return curResult;
}
/**
* Do any aprameters contain a valid, non-null description
* @param params The list of parameters
* @return True if yes, false if no
*/
private static boolean containsNonEmptyDescription(TypedDescription[] params) {
boolean foundDescription = false;
for (int j = 0; j < params.length; j++)
{
TypedDescription param = params[j];
if(param.getDescription() != null && !"".equals(param.getDescription())) //$NON-NLS-1$
{
foundDescription = true;
}
}
return foundDescription;
}
private static String wrapString(String s, int maxWidth, String delimiter)
{
StringReader sr = new StringReader(s);
GC gc= new GC(Display.getCurrent());
String result = ""; //$NON-NLS-1$
com.aptana.ide.editors.unified.utils.LineBreakingReader r = new LineBreakingReader(sr, gc, maxWidth);
try
{
String line = r.readLine();
while(line != null)
{
result += line;
line = r.readLine();
if(line != null)
{
result += delimiter;
}
}
}
catch (IOException e)
{
}
gc.dispose();
return result;
}
}