/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
package net.sourceforge.phpdt.internal.corext.codemanipulation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.jar.Attributes.Name;
import net.sourceforge.phpdt.core.Flags;
import net.sourceforge.phpdt.core.IBuffer;
import net.sourceforge.phpdt.core.ICodeFormatter;
import net.sourceforge.phpdt.core.ICompilationUnit;
import net.sourceforge.phpdt.core.IJavaElement;
import net.sourceforge.phpdt.core.IJavaProject;
import net.sourceforge.phpdt.core.IMethod;
import net.sourceforge.phpdt.core.IPackageFragment;
import net.sourceforge.phpdt.core.IType;
import net.sourceforge.phpdt.core.JavaCore;
import net.sourceforge.phpdt.core.JavaModelException;
import net.sourceforge.phpdt.core.Signature;
import net.sourceforge.phpdt.core.ToolFactory;
import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContext;
import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
import net.sourceforge.phpdt.internal.corext.util.Strings;
import net.sourceforge.phpdt.internal.ui.PHPUIStatus;
import net.sourceforge.phpeclipse.PHPeclipsePlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.templates.Template;
import org.eclipse.jface.text.templates.TemplateBuffer;
import org.eclipse.jface.text.templates.TemplateException;
import org.eclipse.jface.text.templates.TemplateVariable;
import org.eclipse.swt.SWT;
public class StubUtility {
public static class GenStubSettings extends CodeGenerationSettings {
public boolean callSuper;
public boolean methodOverwrites;
public boolean noBody;
public int methodModifiers;
public GenStubSettings(CodeGenerationSettings settings) {
settings.setSettings(this);
methodModifiers= -1;
}
}
private static final String[] EMPTY= new String[0];
/**
* Generates a method stub including the method comment. Given a template
* method, a stub with the same signature will be constructed so it can be
* added to a type. The method body will be empty or contain a return or
* super call.
* @param destTypeName The name of the type to which the method will be
* added to
* @param method A method template (method belongs to different type than the parent)
* @param definingType The type that defines the method.
* @param settings Options as defined above (GenStubSettings
)
* @param imports Imports required by the stub are added to the imports structure. If imports structure is null
* all type names are qualified.
* @throws JavaModelException
*/
public static String genStub(ICompilationUnit cu, String destTypeName, IMethod method, IType definingType, GenStubSettings settings) throws CoreException {
//IImportsStructure imports) throws CoreException {
String methName= method.getElementName();
String[] paramNames= suggestArgumentNames(method.getJavaProject(), method.getParameterNames());
String returnType= method.isConstructor() ? null : method.getReturnType();
String lineDelimiter= String.valueOf('\n'); // reformatting required
StringBuffer buf= new StringBuffer();
// add method comment
if (settings.createComments && cu != null) {
IMethod overridden= null;
if (settings.methodOverwrites && returnType != null) {
overridden= JavaModelUtil.findMethod(methName, method.getParameterTypes(), false, definingType.getMethods());
}
String comment= getMethodComment(cu, destTypeName, methName, paramNames, method.getExceptionTypes(), returnType, overridden, lineDelimiter);
if (comment != null) {
buf.append(comment);
} else {
buf.append("/**").append(lineDelimiter); //$NON-NLS-1$
buf.append(" *").append(lineDelimiter); //$NON-NLS-1$
buf.append(" */").append(lineDelimiter); //$NON-NLS-1$
}
buf.append(lineDelimiter);
}
// add method declaration
String bodyContent= null;
if (!settings.noBody) {
String bodyStatement= getDefaultMethodBodyStatement(methName, paramNames, returnType, settings.callSuper);
bodyContent= getMethodBodyContent(returnType == null, method.getJavaProject(), destTypeName, methName, bodyStatement, lineDelimiter);
if (bodyContent == null) {
bodyContent= ""; //$NON-NLS-1$
}
}
int flags= settings.methodModifiers;
if (flags == -1) {
flags= method.getFlags();
}
genMethodDeclaration(destTypeName, method, flags, bodyContent, buf); // imports, buf);
return buf.toString();
}
/**
* Generates a method stub not including the method comment. Given a
* template method and the body content, a stub with the same signature will
* be constructed so it can be added to a type.
* @param destTypeName The name of the type to which the method will be
* added to
* @param method A method template (method belongs to different type than the parent)
* @param bodyContent Content of the body
* @param imports Imports required by the stub are added to the imports
* structure. If imports structure is null
all type names are
* qualified.
* @param buf The buffer to append the gerenated code.
* @throws JavaModelException
*/
public static void genMethodDeclaration(String destTypeName, IMethod method, String bodyContent, StringBuffer buf) throws CoreException { // IImportsStructure imports, StringBuffer buf) throws CoreException {
genMethodDeclaration(destTypeName, method, method.getFlags(), bodyContent, buf);
}
/**
* Generates a method stub not including the method comment. Given a
* template method and the body content, a stub with the same signature will
* be constructed so it can be added to a type.
* @param destTypeName The name of the type to which the method will be
* added to
* @param method A method template (method belongs to different type than the parent)
* @param bodyContent Content of the body
* @param imports Imports required by the stub are added to the imports
* structure. If imports structure is null
all type names are
* qualified.
* @param buf The buffer to append the gerenated code.
* @throws JavaModelException
*/
public static void genMethodDeclaration(String destTypeName, IMethod method, int flags, String bodyContent, StringBuffer buf) throws CoreException {
//IImportsStructure imports, StringBuffer buf) throws CoreException {
IType parentType= method.getDeclaringType();
String methodName= method.getElementName();
String[] paramTypes= method.getParameterTypes();
String[] paramNames= suggestArgumentNames(parentType.getJavaProject(), method.getParameterNames());
String[] excTypes= method.getExceptionTypes();
boolean isConstructor= method.isConstructor();
String retTypeSig= isConstructor ? null : method.getReturnType();
int lastParam= paramTypes.length -1;
if (Flags.isPublic(flags) || (parentType.isInterface() && bodyContent != null)) {
buf.append("public "); //$NON-NLS-1$
} else if (Flags.isProtected(flags)) {
buf.append("protected "); //$NON-NLS-1$
} else if (Flags.isPrivate(flags)) {
buf.append("private "); //$NON-NLS-1$
}
// if (Flags.isSynchronized(flags)) {
// buf.append("synchronized "); //$NON-NLS-1$
// }
// if (Flags.isVolatile(flags)) {
// buf.append("volatile "); //$NON-NLS-1$
// }
// if (Flags.isStrictfp(flags)) {
// buf.append("strictfp "); //$NON-NLS-1$
// }
if (Flags.isStatic(flags)) {
buf.append("static "); //$NON-NLS-1$
}
if (isConstructor) {
buf.append(destTypeName);
} else {
String retTypeFrm;
if (!isPrimitiveType(retTypeSig)) {
retTypeFrm= resolveAndAdd(retTypeSig, parentType);
} else {
retTypeFrm= Signature.toString(retTypeSig);
}
buf.append(retTypeFrm);
buf.append(' ');
buf.append(methodName);
}
buf.append('(');
for (int i= 0; i <= lastParam; i++) {
String paramTypeSig= paramTypes[i];
String paramTypeFrm;
if (!isPrimitiveType(paramTypeSig)) {
paramTypeFrm= resolveAndAdd(paramTypeSig, parentType);
} else {
paramTypeFrm= Signature.toString(paramTypeSig);
}
buf.append(paramTypeFrm);
buf.append(' ');
buf.append(paramNames[i]);
if (i < lastParam) {
buf.append(", "); //$NON-NLS-1$
}
}
buf.append(')');
int lastExc= excTypes.length - 1;
if (lastExc >= 0) {
buf.append(" throws "); //$NON-NLS-1$
for (int i= 0; i <= lastExc; i++) {
String excTypeSig= excTypes[i];
String excTypeFrm= resolveAndAdd(excTypeSig, parentType);
buf.append(excTypeFrm);
if (i < lastExc) {
buf.append(", "); //$NON-NLS-1$
}
}
}
if (bodyContent == null) {
buf.append(";\n\n"); //$NON-NLS-1$
} else {
buf.append(" {\n\t"); //$NON-NLS-1$
if ((bodyContent != null) && (bodyContent.length() > 0)) {
buf.append(bodyContent);
buf.append('\n');
}
buf.append("}\n"); //$NON-NLS-1$
}
}
public static String getDefaultMethodBodyStatement(String methodName, String[] paramNames, String retTypeSig, boolean callSuper) {
StringBuffer buf= new StringBuffer();
if (callSuper) {
if (retTypeSig != null) {
if (!Signature.SIG_VOID.equals(retTypeSig)) {
buf.append("return "); //$NON-NLS-1$
}
buf.append("super."); //$NON-NLS-1$
buf.append(methodName);
} else {
buf.append("super"); //$NON-NLS-1$
}
buf.append('(');
for (int i= 0; i < paramNames.length; i++) {
if (i > 0) {
buf.append(", "); //$NON-NLS-1$
}
buf.append(paramNames[i]);
}
buf.append(");"); //$NON-NLS-1$
} else {
if (retTypeSig != null && !retTypeSig.equals(Signature.SIG_VOID)) {
if (!isPrimitiveType(retTypeSig) || Signature.getArrayCount(retTypeSig) > 0) {
buf.append("return null;"); //$NON-NLS-1$
} else if (retTypeSig.equals(Signature.SIG_BOOLEAN)) {
buf.append("return false;"); //$NON-NLS-1$
} else {
buf.append("return 0;"); //$NON-NLS-1$
}
}
}
return buf.toString();
}
public static String getMethodBodyContent(boolean isConstructor, IJavaProject project, String destTypeName, String methodName, String bodyStatement, String lineDelimiter) throws CoreException {
String templateName= isConstructor ? CodeTemplateContextType.CONSTRUCTORSTUB : CodeTemplateContextType.METHODSTUB;
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
if (template == null) {
return bodyStatement;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
context.setVariable(CodeTemplateContextType.BODY_STATEMENT, bodyStatement);
String str= evaluateTemplate(context, template);
if (str == null && !Strings.containsOnlyWhitespaces(bodyStatement)) {
return bodyStatement;
}
return str;
}
public static String getGetterMethodBodyContent(IJavaProject project, String destTypeName, String methodName, String fieldName, String lineDelimiter) throws CoreException {
String templateName= CodeTemplateContextType.GETTERSTUB;
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
context.setVariable(CodeTemplateContextType.FIELD, fieldName);
return evaluateTemplate(context, template);
}
public static String getSetterMethodBodyContent(IJavaProject project, String destTypeName, String methodName, String fieldName, String paramName, String lineDelimiter) throws CoreException {
String templateName= CodeTemplateContextType.SETTERSTUB;
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName);
context.setVariable(CodeTemplateContextType.FIELD, fieldName);
context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldName);
context.setVariable(CodeTemplateContextType.PARAM, paramName);
return evaluateTemplate(context, template);
}
public static String getCatchBodyContent(ICompilationUnit cu, String exceptionType, String variableName, String lineDelimiter) throws CoreException {
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.CATCHBLOCK);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
context.setVariable(CodeTemplateContextType.EXCEPTION_TYPE, exceptionType);
context.setVariable(CodeTemplateContextType.EXCEPTION_VAR, variableName); //$NON-NLS-1$
return evaluateTemplate(context, template);
}
/**
* @see org.eclipse.jdt.ui.CodeGeneration#getTypeComment(ICompilationUnit, String, String)
*/
public static String getCompilationUnitContent(ICompilationUnit cu, String typeComment, String typeContent, String lineDelimiter) throws CoreException {
IPackageFragment pack= (IPackageFragment) cu.getParent();
String packDecl= pack.isDefaultPackage() ? "" : "package " + pack.getElementName() + ';'; //$NON-NLS-1$ //$NON-NLS-2$
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.NEWTYPE);
if (template == null) {
return null;
}
IJavaProject project= cu.getJavaProject();
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter);
context.setCompilationUnitVariables(cu);
context.setVariable(CodeTemplateContextType.PACKAGE_DECLARATION, packDecl);
context.setVariable(CodeTemplateContextType.TYPE_COMMENT, typeComment != null ? typeComment : ""); //$NON-NLS-1$
context.setVariable(CodeTemplateContextType.TYPE_DECLARATION, typeContent);
context.setVariable(CodeTemplateContextType.TYPENAME, Signature.getQualifier(cu.getElementName()));
return evaluateTemplate(context, template);
}
/*
* @see org.eclipse.jdt.ui.CodeGeneration#getTypeComment(ICompilationUnit, String, String)
*/
public static String getTypeComment(ICompilationUnit cu, String typeQualifiedName, String lineDelim) throws CoreException {
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.TYPECOMMENT);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelim);
context.setCompilationUnitVariables(cu);
context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, Signature.getQualifier(typeQualifiedName));
context.setVariable(CodeTemplateContextType.TYPENAME, Signature.getSimpleName(typeQualifiedName));
return evaluateTemplate(context, template);
}
// private static String[] getParameterTypesQualifiedNames(IMethodBinding binding) {
// ITypeBinding[] typeBindings= binding.getParameterTypes();
// String[] result= new String[typeBindings.length];
// for (int i= 0; i < result.length; i++) {
// result[i]= typeBindings[i].getQualifiedName();
// }
// return result;
// }
private static String getSeeTag(String declaringClassQualifiedName, String methodName, String[] parameterTypesQualifiedNames) {
StringBuffer buf= new StringBuffer();
buf.append("@see "); //$NON-NLS-1$
buf.append(declaringClassQualifiedName);
buf.append('#');
buf.append(methodName);
buf.append('(');
for (int i= 0; i < parameterTypesQualifiedNames.length; i++) {
if (i > 0) {
buf.append(", "); //$NON-NLS-1$
}
buf.append(parameterTypesQualifiedNames[i]);
}
buf.append(')');
return buf.toString();
}
private static String getSeeTag(IMethod overridden) throws JavaModelException {
IType declaringType= overridden.getDeclaringType();
StringBuffer buf= new StringBuffer();
buf.append("@see "); //$NON-NLS-1$
buf.append(declaringType.getFullyQualifiedName('.'));
buf.append('#');
buf.append(overridden.getElementName());
buf.append('(');
String[] paramTypes= overridden.getParameterTypes();
for (int i= 0; i < paramTypes.length; i++) {
if (i > 0) {
buf.append(", "); //$NON-NLS-1$
}
String curr= paramTypes[i];
buf.append(JavaModelUtil.getResolvedTypeName(curr, declaringType));
int arrayCount= Signature.getArrayCount(curr);
while (arrayCount > 0) {
buf.append("[]"); //$NON-NLS-1$
arrayCount--;
}
}
buf.append(')');
return buf.toString();
}
/**
* @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(IMethod,IMethod,String)
*/
public static String getMethodComment(IMethod method, IMethod overridden, String lineDelimiter) throws CoreException {
String retType= method.isConstructor() ? null : method.getReturnType();
String[] paramNames= method.getParameterNames();
return getMethodComment(method.getCompilationUnit(), method.getDeclaringType().getElementName(),
method.getElementName(), paramNames, method.getExceptionTypes(), retType, overridden, lineDelimiter);
}
/**
* @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, String, String[], String[], String, IMethod, String)
*/
public static String getMethodComment(ICompilationUnit cu, String typeName, String methodName, String[] paramNames, String[] excTypeSig, String retTypeSig, IMethod overridden, String lineDelimiter) throws CoreException {
String templateName= CodeTemplateContextType.METHODCOMMENT;
if (retTypeSig == null) {
templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT;
} else if (overridden != null) {
templateName= CodeTemplateContextType.OVERRIDECOMMENT;
}
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
context.setCompilationUnitVariables(cu);
context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
if (retTypeSig != null) {
context.setVariable(CodeTemplateContextType.RETURN_TYPE, Signature.toString(retTypeSig));
}
if (overridden != null) {
context.setVariable(CodeTemplateContextType.SEE_TAG, getSeeTag(overridden));
}
TemplateBuffer buffer;
try {
buffer= context.evaluate(template);
} catch (BadLocationException e) {
throw new CoreException(Status.CANCEL_STATUS);
} catch (TemplateException e) {
throw new CoreException(Status.CANCEL_STATUS);
}
if (buffer == null) {
return null;
}
String str= buffer.getString();
if (Strings.containsOnlyWhitespaces(str)) {
return null;
}
TemplateVariable position= findTagVariable(buffer); // look if Javadoc tags have to be added
if (position == null) {
return str;
}
IDocument textBuffer= new Document(str);
String[] exceptionNames= new String[excTypeSig.length];
for (int i= 0; i < excTypeSig.length; i++) {
exceptionNames[i]= Signature.toString(excTypeSig[i]);
}
String returnType= retTypeSig != null ? Signature.toString(retTypeSig) : null;
int[] tagOffsets= position.getOffsets();
for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
try {
insertTag(textBuffer, tagOffsets[i], position.getLength(), paramNames, exceptionNames, returnType, false, lineDelimiter);
} catch (BadLocationException e) {
throw new CoreException(PHPUIStatus.createError(IStatus.ERROR, e));
}
}
return textBuffer.get();
}
public static String getFieldComment(ICompilationUnit cu, String typeName, String fieldName, String lineDelimiter) throws CoreException {
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(CodeTemplateContextType.FIELDCOMMENT);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
context.setCompilationUnitVariables(cu);
context.setVariable(CodeTemplateContextType.FIELD_TYPE, typeName);
context.setVariable(CodeTemplateContextType.FIELD, fieldName);
return evaluateTemplate(context, template);
}
/**
* @see org.eclipse.jdt.ui.CodeGeneration#getSetterComment(ICompilationUnit, String, String, String, String, String, String, String)
*/
public static String getSetterComment(ICompilationUnit cu, String typeName, String methodName, String fieldName, String fieldType, String paramName, String bareFieldName, String lineDelimiter) throws CoreException {
String templateName= CodeTemplateContextType.SETTERCOMMENT;
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
context.setCompilationUnitVariables(cu);
context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
context.setVariable(CodeTemplateContextType.FIELD, fieldName);
context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME, bareFieldName);
context.setVariable(CodeTemplateContextType.PARAM, paramName);
return evaluateTemplate(context, template);
}
/**
* @see org.eclipse.jdt.ui.CodeGeneration#getGetterComment(ICompilationUnit, String, String, String, String, String, String)
*/
public static String getGetterComment(ICompilationUnit cu, String typeName, String methodName, String fieldName, String fieldType, String bareFieldName, String lineDelimiter) throws CoreException {
String templateName= CodeTemplateContextType.GETTERCOMMENT;
Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
if (template == null) {
return null;
}
CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
context.setCompilationUnitVariables(cu);
context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName);
context.setVariable(CodeTemplateContextType.FIELD, fieldName);
context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME, bareFieldName);
return evaluateTemplate(context, template);
}
public static String evaluateTemplate(CodeTemplateContext context, Template template) throws CoreException {
TemplateBuffer buffer;
try {
buffer= context.evaluate(template);
} catch (BadLocationException e) {
throw new CoreException(Status.CANCEL_STATUS);
} catch (TemplateException e) {
throw new CoreException(Status.CANCEL_STATUS);
}
if (buffer == null)
return null;
String str= buffer.getString();
if (Strings.containsOnlyWhitespaces(str)) {
return null;
}
return str;
}
/**
* @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, MethodDeclaration, IMethodBinding, String)
*/
// public static String getMethodComment(ICompilationUnit cu, String typeName, IMethodBinding overridden, String lineDelimiter) throws CoreException {
// if (overridden != null) {
// String declaringClassQualifiedName= overridden.getDeclaringClass().getQualifiedName();
// String[] parameterTypesQualifiedNames= getParameterTypesQualifiedNames(overridden);
// return getMethodComment(cu, typeName, decl, true, overridden.isDeprecated(), declaringClassQualifiedName, parameterTypesQualifiedNames, lineDelimiter);
// } else {
// return getMethodComment(cu, typeName, decl, false, false, null, null, lineDelimiter);
// }
// }
/**
* Returns the comment for a method using the comment code templates.
* null
is returned if the template is empty.
* @param cu The compilation unit to which the method belongs
* @param typeName Name of the type to which the method belongs.
* @param decl The AST MethodDeclaration node that will be added as new
* method.
* @param isOverridden true
iff decl overrides another method
* @param isDeprecated true
iff the method that decl overrides is deprecated.
* Note: it must not be true
if isOverridden is false
.
* @param declaringClassQualifiedName Fully qualified name of the type in which the overriddden
* method (if any exists) in declared. If isOverridden is false
, this is ignored.
* @param parameterTypesQualifiedNames Fully qualified names of parameter types of the type in which the overriddden
* method (if any exists) in declared. If isOverridden is false
, this is ignored.
* @return String Returns the method comment or null
if the
* configured template is empty.
* (formatting required)
* @throws CoreException
*/
// public static String getMethodComment(ICompilationUnit cu, String typeName, MethodDeclaration decl, boolean isOverridden, boolean isDeprecated, String declaringClassQualifiedName, String[] parameterTypesQualifiedNames, String lineDelimiter) throws CoreException {
// String templateName= CodeTemplateContextType.METHODCOMMENT;
// if (decl.isConstructor()) {
// templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT;
// } else if (isOverridden) {
// templateName= CodeTemplateContextType.OVERRIDECOMMENT;
// }
// Template template= PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
// if (template == null) {
// return null;
// }
// CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter);
// context.setCompilationUnitVariables(cu);
// context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
// context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, decl.getName().getIdentifier());
// if (!decl.isConstructor()) {
// context.setVariable(CodeTemplateContextType.RETURN_TYPE, ASTNodes.asString(decl.getReturnType()));
// }
// if (isOverridden) {
// String methodName= decl.getName().getIdentifier();
// context.setVariable(CodeTemplateContextType.SEE_TAG, getSeeTag(declaringClassQualifiedName, methodName, parameterTypesQualifiedNames));
// }
//
// TemplateBuffer buffer;
// try {
// buffer= context.evaluate(template);
// } catch (BadLocationException e) {
// throw new CoreException(Status.CANCEL_STATUS);
// } catch (TemplateException e) {
// throw new CoreException(Status.CANCEL_STATUS);
// }
// if (buffer == null)
// return null;
// String str= buffer.getString();
// if (Strings.containsOnlyWhitespaces(str)) {
// return null;
// }
// TemplateVariable position= findTagVariable(buffer); // look if Javadoc tags have to be added
// if (position == null) {
// return str;
// }
//
// IDocument textBuffer= new Document(str);
// List params= decl.parameters();
// String[] paramNames= new String[params.size()];
// for (int i= 0; i < params.size(); i++) {
// SingleVariableDeclaration elem= (SingleVariableDeclaration) params.get(i);
// paramNames[i]= elem.getName().getIdentifier();
// }
// List exceptions= decl.thrownExceptions();
// String[] exceptionNames= new String[exceptions.size()];
// for (int i= 0; i < exceptions.size(); i++) {
// exceptionNames[i]= ASTNodes.getSimpleNameIdentifier((Name) exceptions.get(i));
// }
// String returnType= !decl.isConstructor() ? ASTNodes.asString(decl.getReturnType()) : null;
// int[] tagOffsets= position.getOffsets();
// for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
// try {
// insertTag(textBuffer, tagOffsets[i], position.getLength(), paramNames, exceptionNames, returnType, isDeprecated, lineDelimiter);
// } catch (BadLocationException e) {
// throw new CoreException(PHPUIStatus.createError(IStatus.ERROR, e));
// }
// }
// return textBuffer.get();
// }
private static TemplateVariable findTagVariable(TemplateBuffer buffer) {
TemplateVariable[] positions= buffer.getVariables();
for (int i= 0; i < positions.length; i++) {
TemplateVariable curr= positions[i];
if (CodeTemplateContextType.TAGS.equals(curr.getType())) {
return curr;
}
}
return null;
}
private static void insertTag(IDocument textBuffer, int offset, int length, String[] paramNames, String[] exceptionNames, String returnType, boolean isDeprecated, String lineDelimiter) throws BadLocationException {
IRegion region= textBuffer.getLineInformationOfOffset(offset);
if (region == null) {
return;
}
String lineStart= textBuffer.get(region.getOffset(), offset - region.getOffset());
StringBuffer buf= new StringBuffer();
for (int i= 0; i < paramNames.length; i++) {
if (buf.length() > 0) {
buf.append(lineDelimiter); buf.append(lineStart);
}
buf.append("@param "); buf.append(paramNames[i]); //$NON-NLS-1$
}
if (returnType != null && !returnType.equals("void")) { //$NON-NLS-1$
if (buf.length() > 0) {
buf.append(lineDelimiter); buf.append(lineStart);
}
buf.append("@return"); //$NON-NLS-1$
}
if (exceptionNames != null) {
for (int i= 0; i < exceptionNames.length; i++) {
if (buf.length() > 0) {
buf.append(lineDelimiter); buf.append(lineStart);
}
buf.append("@throws "); buf.append(exceptionNames[i]); //$NON-NLS-1$
}
}
if (isDeprecated) {
if (buf.length() > 0) {
buf.append(lineDelimiter); buf.append(lineStart);
}
buf.append("@deprecated"); //$NON-NLS-1$
}
textBuffer.replace(offset, length, buf.toString());
}
private static boolean isPrimitiveType(String typeName) {
char first= Signature.getElementType(typeName).charAt(0);
return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED);
}
private static String resolveAndAdd(String refTypeSig, IType declaringType) throws JavaModelException {//, IImportsStructure imports) throws JavaModelException {
String resolvedTypeName= JavaModelUtil.getResolvedTypeName(refTypeSig, declaringType);
if (resolvedTypeName != null) {
StringBuffer buf= new StringBuffer();
// if (imports != null) {
// buf.append(imports.addImport(resolvedTypeName));
// } else {
buf.append(resolvedTypeName);
// }
int arrayCount= Signature.getArrayCount(refTypeSig);
for (int i= 0; i < arrayCount; i++) {
buf.append("[]"); //$NON-NLS-1$
}
return buf.toString();
}
return Signature.toString(refTypeSig);
}
/**
* Finds a method in a list of methods.
* @return The found method or null, if nothing found
*/
private static IMethod findMethod(IMethod method, List allMethods) throws JavaModelException {
String name= method.getElementName();
String[] paramTypes= method.getParameterTypes();
boolean isConstructor= method.isConstructor();
for (int i= allMethods.size() - 1; i >= 0; i--) {
IMethod curr= (IMethod) allMethods.get(i);
if (JavaModelUtil.isSameMethodSignature(name, paramTypes, isConstructor, curr)) {
return curr;
}
}
return null;
}
/**
* Creates needed constructors for a type.
* @param type The type to create constructors for
* @param supertype The type's super type
* @param settings Options for comment generation
* @param imports Required imports are added to the import structure. Structure can be null
, types are qualified then.
* @return Returns the generated stubs or null
if the creation has been canceled
*/
// public static String[] evalConstructors(IType type, IType supertype, IImportsStructure imports) throws CoreException {
// IMethod[] superMethods= supertype.getMethods();
// String typeName= type.getElementName();
// ICompilationUnit cu= type.getCompilationUnit();
// IMethod[] methods= type.getMethods();
// GenStubSettings genStubSettings= new GenStubSettings(settings);
// genStubSettings.callSuper= true;
//
// ArrayList newMethods= new ArrayList(superMethods.length);
// for (int i= 0; i < superMethods.length; i++) {
// IMethod curr= superMethods[i];
// if (curr.isConstructor() && (JavaModelUtil.isVisibleInHierarchy(curr, type.getPackageFragment()))) {
// if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true, methods) == null) {
// genStubSettings.methodModifiers= Flags.AccPublic | JdtFlags.clearAccessModifiers(curr.getFlags());
// String newStub= genStub(cu, typeName, curr, curr.getDeclaringType(), genStubSettings, imports);
// newMethods.add(newStub);
// }
// }
// }
// return (String[]) newMethods.toArray(new String[newMethods.size()]);
// }
/**
* Returns all unimplemented constructors of a type including root type default
* constructors if there are no other superclass constructors unimplemented.
* @param type The type to create constructors for
* @return Returns the generated stubs or null
if the creation has been canceled
*/
// public static IMethod[] getOverridableConstructors(IType type) throws CoreException {
// List constructorMethods= new ArrayList();
// ITypeHierarchy hierarchy= type.newSupertypeHierarchy(null);
// IType supertype= hierarchy.getSuperclass(type);
// if (supertype == null)
// return (new IMethod[0]);
//
// IMethod[] superMethods= supertype.getMethods();
// boolean constuctorFound= false;
// String typeName= type.getElementName();
// IMethod[] methods= type.getMethods();
// for (int i= 0; i < superMethods.length; i++) {
// IMethod curr= superMethods[i];
// if (curr.isConstructor()) {
// constuctorFound= true;
// if (JavaModelUtil.isVisibleInHierarchy(curr, type.getPackageFragment()))
// if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true, methods) == null)
// constructorMethods.add(curr);
//
// }
// }
//
// // http://bugs.eclipse.org/bugs/show_bug.cgi?id=38487
// if (!constuctorFound) {
// IType objectType= type.getJavaProject().findType("java.lang.Object"); //$NON-NLS-1$
// IMethod curr= objectType.getMethod("Object", EMPTY); //$NON-NLS-1$
// if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true, methods) == null) {
// constructorMethods.add(curr);
// }
// }
// return (IMethod[]) constructorMethods.toArray(new IMethod[constructorMethods.size()]);
// }
/**
* Returns all overridable methods of a type
* @param type The type to search the overridable methods for
* @param hierarchy The type hierarchy of the type
* @param isSubType If set, the result can include methods of the passed type, if not only methods from super
* types are considered
* @return Returns the all methods that can be overridden
*/
// public static IMethod[] getOverridableMethods(IType type, ITypeHierarchy hierarchy, boolean isSubType) throws JavaModelException {
// List allMethods= new ArrayList();
//
// IMethod[] typeMethods= type.getMethods();
// for (int i= 0; i < typeMethods.length; i++) {
// IMethod curr= typeMethods[i];
// if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) && !Flags.isPrivate(curr.getFlags())) {
// allMethods.add(curr);
// }
// }
//
// IType[] superTypes= hierarchy.getAllSuperclasses(type);
// for (int i= 0; i < superTypes.length; i++) {
// IMethod[] methods= superTypes[i].getMethods();
// for (int k= 0; k < methods.length; k++) {
// IMethod curr= methods[k];
// if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) && !Flags.isPrivate(curr.getFlags())) {
// if (findMethod(curr, allMethods) == null) {
// allMethods.add(curr);
// }
// }
// }
// }
//
// IType[] superInterfaces= hierarchy.getAllSuperInterfaces(type);
// for (int i= 0; i < superInterfaces.length; i++) {
// IMethod[] methods= superInterfaces[i].getMethods();
// for (int k= 0; k < methods.length; k++) {
// IMethod curr= methods[k];
//
// // binary interfaces can contain static initializers (variable intializations)
// // 1G4CKUS
// if (!Flags.isStatic(curr.getFlags())) {
// IMethod impl= findMethod(curr, allMethods);
// if (impl == null || !JavaModelUtil.isVisibleInHierarchy(impl, type.getPackageFragment()) || prefereInterfaceMethod(hierarchy, curr, impl)) {
// if (impl != null) {
// allMethods.remove(impl);
// }
// // implement an interface method when it does not exist in the hierarchy
// // or when it throws less exceptions that the implemented
// allMethods.add(curr);
// }
// }
// }
// }
// if (!isSubType) {
// allMethods.removeAll(Arrays.asList(typeMethods));
// }
// // remove finals
// for (int i= allMethods.size() - 1; i >= 0; i--) {
// IMethod curr= (IMethod) allMethods.get(i);
// if (Flags.isFinal(curr.getFlags())) {
// allMethods.remove(i);
// }
// }
// return (IMethod[]) allMethods.toArray(new IMethod[allMethods.size()]);
// }
// private static boolean prefereInterfaceMethod(ITypeHierarchy hierarchy, IMethod interfaceMethod, IMethod curr) throws JavaModelException {
// if (Flags.isFinal(curr.getFlags())) {
// return false;
// }
// IType interfaceType= interfaceMethod.getDeclaringType();
// IType[] interfaces= hierarchy.getAllSuperInterfaces(curr.getDeclaringType());
// for (int i= 0; i < interfaces.length; i++) {
// if (interfaces[i] == interfaceType) {
// return false;
// }
// }
// return curr.getExceptionTypes().length > interfaceMethod.getExceptionTypes().length;
// }
/**
* Generate method stubs for methods to overrride
* @param type The type to search the overridable methods for
* @param hierarchy The type hierarchy of the type
* @param methodsToImplement Methods to override or implement
* @param settings Options for comment generation
* @param imports Required imports are added to the import structure. Structure can be null
, types are qualified then.
* @return Returns the generated stubs
*/
// public static String[] genOverrideStubs(IMethod[] methodsToImplement, IType type, ITypeHierarchy hierarchy, CodeGenerationSettings settings, IImportsStructure imports) throws CoreException {
// GenStubSettings genStubSettings= new GenStubSettings(settings);
// genStubSettings.methodOverwrites= true;
// ICompilationUnit cu= type.getCompilationUnit();
// String[] result= new String[methodsToImplement.length];
// for (int i= 0; i < methodsToImplement.length; i++) {
// IMethod curr= methodsToImplement[i];
// IMethod overrides= JavaModelUtil.findMethodImplementationInHierarchy(hierarchy, type, curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
// if (overrides != null) {
// genStubSettings.callSuper= true;
// curr= overrides;
// }
// genStubSettings.methodModifiers= curr.getFlags();
// IMethod desc= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy, type, curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
// if (desc == null) {
// desc= curr;
// }
// result[i]= genStub(cu, type.getElementName(), curr, desc.getDeclaringType(), genStubSettings, imports);
// }
// return result;
// }
/**
* Searches for unimplemented methods of a type.
* @param isSubType If set, the evaluation is for a subtype of the given type. If not set, the
* evaluation is for the type itself.
* @param settings Options for comment generation
* @param imports Required imports are added to the import structure. Structure can be null
, types are qualified then.
* @return Returns the generated stubs or null
if the creation has been canceled
*/
// public static String[] evalUnimplementedMethods(IType type, ITypeHierarchy hierarchy, boolean isSubType, CodeGenerationSettings settings,
// IImportsStructure imports) throws CoreException {
//
// IMethod[] inheritedMethods= getOverridableMethods(type, hierarchy, isSubType);
//
// List toImplement= new ArrayList();
// for (int i= 0; i < inheritedMethods.length; i++) {
// IMethod curr= inheritedMethods[i];
// if (JdtFlags.isAbstract(curr)) {
// toImplement.add(curr);
// }
// }
// IMethod[] toImplementArray= (IMethod[]) toImplement.toArray(new IMethod[toImplement.size()]);
// return genOverrideStubs(toImplementArray, type, hierarchy, settings, imports);
// }
/**
* Examines a string and returns the first line delimiter found.
*/
public static String getLineDelimiterUsed(IJavaElement elem) throws JavaModelException {
ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
if (cu != null && cu.exists()) {
IBuffer buf= cu.getBuffer();
int length= buf.getLength();
for (int i= 0; i < length; i++) {
char ch= buf.getChar(i);
if (ch == SWT.CR) {
if (i + 1 < length) {
if (buf.getChar(i + 1) == SWT.LF) {
return "\r\n"; //$NON-NLS-1$
}
}
return "\r"; //$NON-NLS-1$
} else if (ch == SWT.LF) {
return "\n"; //$NON-NLS-1$
}
}
}
return System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Embodies the policy which line delimiter to use when inserting into
* a document.
*/
public static String getLineDelimiterFor(IDocument doc) {
// new for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in php editor inserts lines in wrong format
String lineDelim= null;
try {
lineDelim= doc.getLineDelimiter(0);
} catch (BadLocationException e) {
}
if (lineDelim == null) {
String systemDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
String[] lineDelims= doc.getLegalLineDelimiters();
for (int i= 0; i < lineDelims.length; i++) {
if (lineDelims[i].equals(systemDelimiter)) {
lineDelim= systemDelimiter;
break;
}
}
if (lineDelim == null) {
lineDelim= lineDelims.length > 0 ? lineDelims[0] : systemDelimiter;
}
}
return lineDelim;
}
/**
* Evaluates the indention used by a Java element. (in tabulators)
*/
// public static int getIndentUsed(IJavaElement elem) throws JavaModelException {
// if (elem instanceof ISourceReference) {
// ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
// if (cu != null) {
// IBuffer buf= cu.getBuffer();
// int offset= ((ISourceReference)elem).getSourceRange().getOffset();
// int i= offset;
// // find beginning of line
// while (i > 0 && !Strings.isLineDelimiterChar(buf.getChar(i - 1)) ){
// i--;
// }
// return Strings.computeIndent(buf.getText(i, offset - i), CodeFormatterUtil.getTabWidth());
// }
// }
// return 0;
// }
public static String codeFormat(String sourceString, int initialIndentationLevel, String lineDelim) {
ICodeFormatter formatter= ToolFactory.createDefaultCodeFormatter(null);
return formatter.format(sourceString, initialIndentationLevel, null, lineDelim);
}
/**
* Returns the element after the give element.
*/
// public static IJavaElement findNextSibling(IJavaElement member) throws JavaModelException {
// IJavaElement parent= member.getParent();
// if (parent instanceof IParent) {
// IJavaElement[] elements= ((IParent)parent).getChildren();
// for (int i= elements.length - 2; i >= 0 ; i--) {
// if (member.equals(elements[i])) {
// return elements[i+1];
// }
// }
// }
// return null;
// }
//
public static String getTodoTaskTag(IJavaProject project) {
String markers= null;
if (project == null) {
markers= JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS);
} else {
markers= project.getOption(JavaCore.COMPILER_TASK_TAGS, true);
}
if (markers != null && markers.length() > 0) {
int idx= markers.indexOf(',');
if (idx == -1) {
return markers;
} else {
return markers.substring(0, idx);
}
}
return null;
}
/*
* Workarounds for bug 38111
*/
// public static String[] getArgumentNameSuggestions(IJavaProject project, String baseName, int dimensions, String[] excluded) {
// String name= workaround38111(baseName);
// String[] res= NamingConventions.suggestArgumentNames(project, "", name, dimensions, excluded); //$NON-NLS-1$
// return sortByLength(res); // longest first
// }
//
// public static String[] getFieldNameSuggestions(IJavaProject project, String baseName, int dimensions, int modifiers, String[] excluded) {
// String name= workaround38111(baseName);
// String[] res= NamingConventions.suggestFieldNames(project, "", name, dimensions, modifiers, excluded); //$NON-NLS-1$
// return sortByLength(res); // longest first
// }
//
// public static String[] getLocalNameSuggestions(IJavaProject project, String baseName, int dimensions, String[] excluded) {
// String name= workaround38111(baseName);
// String[] res= NamingConventions.suggestLocalVariableNames(project, "", name, dimensions, excluded); //$NON-NLS-1$
// return sortByLength(res); // longest first
// }
private static String[] sortByLength(String[] proposals) {
Arrays.sort(proposals, new Comparator() {
public int compare(Object o1, Object o2) {
return ((String) o2).length() - ((String) o1).length();
}
});
return proposals;
}
private static String workaround38111(String baseName) {
if (BASE_TYPES.contains(baseName))
return baseName;
return Character.toUpperCase(baseName.charAt(0)) + baseName.substring(1);
}
private static final List BASE_TYPES= Arrays.asList(
new String[] {"boolean", "byte", "char", "double", "float", "int", "long", "short"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
public static String suggestArgumentName(IJavaProject project, String baseName, String[] excluded) {
// String[] argnames= getArgumentNameSuggestions(project, baseName, 0, excluded);
// if (argnames.length > 0) {
// return argnames[0];
// }
return baseName;
}
public static String[] suggestArgumentNames(IJavaProject project, String[] paramNames) {
String prefixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
String suffixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
if (prefixes.length() + suffixes.length() == 0) {
return paramNames;
}
String[] newNames= new String[paramNames.length];
// Ensure that the codegeneration preferences are respected
for (int i= 0; i < paramNames.length; i++) {
String curr= paramNames[i];
if (!hasPrefixOrSuffix(prefixes, suffixes, curr)) {
newNames[i]= suggestArgumentName(project, paramNames[i], null);
} else {
newNames[i]= curr;
}
}
return newNames;
}
public static boolean hasFieldName(IJavaProject project, String name) {
String prefixes= project.getOption(JavaCore.CODEASSIST_FIELD_PREFIXES, true);
String suffixes= project.getOption(JavaCore.CODEASSIST_FIELD_SUFFIXES, true);
String staticPrefixes= project.getOption(JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, true);
String staticSuffixes= project.getOption(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, true);
return hasPrefixOrSuffix(prefixes, suffixes, name)
|| hasPrefixOrSuffix(staticPrefixes, staticSuffixes, name);
}
public static boolean hasParameterName(IJavaProject project, String name) {
String prefixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
String suffixes= project.getOption(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
return hasPrefixOrSuffix(prefixes, suffixes, name);
}
public static boolean hasLocalVariableName(IJavaProject project, String name) {
String prefixes= project.getOption(JavaCore.CODEASSIST_LOCAL_PREFIXES, true);
String suffixes= project.getOption(JavaCore.CODEASSIST_LOCAL_SUFFIXES, true);
return hasPrefixOrSuffix(prefixes, suffixes, name);
}
public static boolean hasConstantName(String name) {
return Character.isUpperCase(name.charAt(0));
}
private static boolean hasPrefixOrSuffix(String prefixes, String suffixes, String name) {
final String listSeparartor= ","; //$NON-NLS-1$
StringTokenizer tok= new StringTokenizer(prefixes, listSeparartor);
while (tok.hasMoreTokens()) {
String curr= tok.nextToken();
if (name.startsWith(curr)) {
return true;
}
}
tok= new StringTokenizer(suffixes, listSeparartor);
while (tok.hasMoreTokens()) {
String curr= tok.nextToken();
if (name.endsWith(curr)) {
return true;
}
}
return false;
}
}