/******************************************************************************* * 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 * John Kaplan, johnkaplantech@gmail.com - 108071 [code templates] template for body of newly created class *******************************************************************************/ package org.eclipse.che.ide.ext.java.jdt.internal.corext.codemanipulation; import org.eclipse.che.ide.ext.java.jdt.JavaUIStatus; import org.eclipse.che.ide.ext.java.jdt.core.Flags; import org.eclipse.che.ide.ext.java.jdt.core.JavaCore; import org.eclipse.che.ide.ext.java.jdt.core.NamingConventions; import org.eclipse.che.ide.ext.java.jdt.core.Signature; import org.eclipse.che.ide.ext.java.jdt.core.compiler.CharOperation; import org.eclipse.che.ide.ext.java.jdt.core.dom.AST; import org.eclipse.che.ide.ext.java.jdt.core.dom.ASTNode; import org.eclipse.che.ide.ext.java.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.che.ide.ext.java.jdt.core.dom.ArrayType; import org.eclipse.che.ide.ext.java.jdt.core.dom.CastExpression; import org.eclipse.che.ide.ext.java.jdt.core.dom.ClassInstanceCreation; import org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit; import org.eclipse.che.ide.ext.java.jdt.core.dom.ConstructorInvocation; import org.eclipse.che.ide.ext.java.jdt.core.dom.Expression; import org.eclipse.che.ide.ext.java.jdt.core.dom.FieldAccess; import org.eclipse.che.ide.ext.java.jdt.core.dom.IBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.IMethodBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.ITypeBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.IVariableBinding; import org.eclipse.che.ide.ext.java.jdt.core.dom.MethodDeclaration; import org.eclipse.che.ide.ext.java.jdt.core.dom.MethodInvocation; import org.eclipse.che.ide.ext.java.jdt.core.dom.Modifier; import org.eclipse.che.ide.ext.java.jdt.core.dom.Name; import org.eclipse.che.ide.ext.java.jdt.core.dom.NumberLiteral; import org.eclipse.che.ide.ext.java.jdt.core.dom.ParameterizedType; import org.eclipse.che.ide.ext.java.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.che.ide.ext.java.jdt.core.dom.StringLiteral; import org.eclipse.che.ide.ext.java.jdt.core.dom.StructuralPropertyDescriptor; import org.eclipse.che.ide.ext.java.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.che.ide.ext.java.jdt.core.dom.SuperMethodInvocation; import org.eclipse.che.ide.ext.java.jdt.core.dom.Type; import org.eclipse.che.ide.ext.java.jdt.core.dom.TypeParameter; import org.eclipse.che.ide.ext.java.jdt.core.dom.rewrite.ImportRewrite; import org.eclipse.che.ide.ext.java.jdt.core.util.CharUtil; import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.ASTNodes; import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.Bindings; import org.eclipse.che.ide.ext.java.jdt.internal.corext.util.Strings; import org.eclipse.che.ide.ext.java.jdt.templates.CodeTemplateContext; import org.eclipse.che.ide.ext.java.jdt.templates.CodeTemplateContextType; import org.eclipse.che.ide.ext.java.jdt.templates.TemplateStore; import org.eclipse.che.ide.ext.java.jdt.templates.api.Template; import org.eclipse.che.ide.ext.java.jdt.templates.api.TemplateBuffer; import org.eclipse.che.ide.ext.java.jdt.templates.api.TemplateException; import org.eclipse.che.ide.ext.java.jdt.templates.api.TemplateVariable; import org.eclipse.che.ide.ext.java.worker.WorkerDocument; import org.eclipse.che.ide.ext.java.worker.WorkerMessageHandler; import org.eclipse.che.ide.ext.java.jdt.text.Document; import org.eclipse.che.ide.ext.java.jdt.text.edits.DeleteEdit; import org.eclipse.che.ide.ext.java.jdt.text.edits.MalformedTreeException; import org.eclipse.che.ide.ext.java.jdt.text.edits.MultiTextEdit; import org.eclipse.che.ide.runtime.CoreException; import org.eclipse.che.ide.runtime.IStatus; import org.eclipse.che.ide.runtime.Status; import org.eclipse.che.ide.api.text.BadLocationException; import org.eclipse.che.ide.api.text.Region; import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; public class StubUtility { /** Default eXo import order */ private static final String[] ORDER = new String[]{"#", "*", "org", "java", "javax"}; private static final String[] EMPTY = new String[0]; private static final Set<String> VALID_TYPE_BODY_TEMPLATES; static { VALID_TYPE_BODY_TEMPLATES = new HashSet<String>(); // VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.CLASSBODY_ID); // VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.INTERFACEBODY_ID); // VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.ENUMBODY_ID); // VALID_TYPE_BODY_TEMPLATES.add(CodeTemplateContextType.ANNOTATIONBODY_ID); } /* * // * Don't use this method directly, use CodeGeneration. // */ public static String getMethodBodyContent(boolean isConstructor, String destTypeName, String methodName, String bodyStatement, String lineDelimiter) throws CoreException { String templateName = isConstructor ? CodeTemplateContextType.CONSTRUCTORSTUB_ID : CodeTemplateContextType.METHODSTUB_ID; Template template = getCodeTemplate(templateName); if (template == null) { return bodyStatement; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName); context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName); context.setVariable(CodeTemplateContextType.BODY_STATEMENT, bodyStatement); String str = evaluateTemplate(context, template, new String[]{CodeTemplateContextType.BODY_STATEMENT}); if (str == null && !Strings.containsOnlyWhitespaces(bodyStatement)) { return bodyStatement; } return str; } /* * Don't use this method directly, use CodeGeneration. */ public static String getGetterMethodBodyContent(String destTypeName, String methodName, String fieldName, String lineDelimiter) throws CoreException { String templateName = CodeTemplateContextType.GETTERSTUB_ID; Template template = getCodeTemplate(templateName); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName); context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, destTypeName); context.setVariable(CodeTemplateContextType.FIELD, fieldName); return evaluateTemplate(context, template); } /* * Don't use this method directly, use CodeGeneration. */ public static String getSetterMethodBodyContent(String destTypeName, String methodName, String fieldName, String paramName, String lineDelimiter) throws CoreException { String templateName = CodeTemplateContextType.SETTERSTUB_ID; Template template = getCodeTemplate(templateName); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), 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(String exceptionType, String variableName, ASTNode locationInAST, String lineDelimiter) throws CoreException { String enclosingType = ""; //$NON-NLS-1$ String enclosingMethod = ""; //$NON-NLS-1$ if (locationInAST != null) { MethodDeclaration parentMethod = ASTResolving.findParentMethodDeclaration(locationInAST); if (parentMethod != null) { enclosingMethod = parentMethod.getName().getIdentifier(); locationInAST = parentMethod; } ASTNode parentType = ASTResolving.findParentType(locationInAST); if (parentType instanceof AbstractTypeDeclaration) { enclosingType = ((AbstractTypeDeclaration)parentType).getName().getIdentifier(); } } return getCatchBodyContent(exceptionType, variableName, enclosingType, enclosingMethod, lineDelimiter); } public static String getCatchBodyContent(String exceptionType, String variableName, String enclosingType, String enclosingMethod, String lineDelimiter) throws CoreException { Template template = getCodeTemplate(CodeTemplateContextType.CATCHBLOCK_ID); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, enclosingType); context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, enclosingMethod); context.setVariable(CodeTemplateContextType.EXCEPTION_TYPE, exceptionType); context.setVariable(CodeTemplateContextType.EXCEPTION_VAR, variableName); return evaluateTemplate(context, template); } // // public static String getCatchBodyContent(ICompilationUnit cu, String exceptionType, String variableName, ASTNode // locationInAST, String lineDelimiter) throws CoreException { // String enclosingType= ""; //$NON-NLS-1$ // String enclosingMethod= ""; //$NON-NLS-1$ // // if (locationInAST != null) { // MethodDeclaration parentMethod= ASTResolving.findParentMethodDeclaration(locationInAST); // if (parentMethod != null) { // enclosingMethod= parentMethod.getName().getIdentifier(); // locationInAST= parentMethod; // } // ASTNode parentType= ASTResolving.findParentType(locationInAST); // if (parentType instanceof AbstractTypeDeclaration) { // enclosingType= ((AbstractTypeDeclaration)parentType).getName().getIdentifier(); // } // } // return getCatchBodyContent(cu, exceptionType, variableName, enclosingType, enclosingMethod, lineDelimiter); // } // // // public static String getCatchBodyContent(ICompilationUnit cu, String exceptionType, String variableName, String // enclosingType, String enclosingMethod, String lineDelimiter) throws CoreException { // Template template= getCodeTemplate(CodeTemplateContextType.CATCHBLOCK_ID, cu.getJavaProject()); // if (template == null) { // return null; // } // // CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelimiter); // context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, enclosingType); // context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, enclosingMethod); // context.setVariable(CodeTemplateContextType.EXCEPTION_TYPE, exceptionType); // context.setVariable(CodeTemplateContextType.EXCEPTION_VAR, variableName); // return evaluateTemplate(context, template); // } // // /* // * Don't use this method directly, use CodeGeneration. // * @see org.eclipse.jdt.ui.CodeGeneration#getCompilationUnitContent(ICompilationUnit, String, String, String, String) // */ // public static String getCompilationUnitContent(ICompilationUnit cu, String fileComment, 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$ // return getCompilationUnitContent(cu, packDecl, fileComment, typeComment, typeContent, lineDelimiter); // } // // public static String getCompilationUnitContent(ICompilationUnit cu, String packDecl, String fileComment, String typeComment, // String typeContent, String lineDelimiter) throws CoreException { // Template template= getCodeTemplate(CodeTemplateContextType.NEWTYPE_ID, cu.getJavaProject()); // 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.FILE_COMMENT, fileComment != null ? fileComment : ""); //$NON-NLS-1$ // context.setVariable(CodeTemplateContextType.TYPE_DECLARATION, typeContent); // context.setVariable(CodeTemplateContextType.TYPENAME, JavaCore.removeJavaLikeExtension(cu.getElementName())); // // String[] fullLine= { CodeTemplateContextType.PACKAGE_DECLARATION, CodeTemplateContextType.FILE_COMMENT, // CodeTemplateContextType.TYPE_COMMENT }; // return evaluateTemplate(context, template, fullLine); // } // // // /* // * Don't use this method directly, use CodeGeneration. // * @see org.eclipse.jdt.ui.CodeGeneration#getFileComment(ICompilationUnit, String) // */ // public static String getFileComment(ICompilationUnit cu, String lineDelimiter) throws CoreException { // Template template= getCodeTemplate(CodeTemplateContextType.FILECOMMENT_ID, cu.getJavaProject()); // if (template == null) { // return null; // } // // IJavaProject project= cu.getJavaProject(); // CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), project, lineDelimiter); // context.setCompilationUnitVariables(cu); // context.setVariable(CodeTemplateContextType.TYPENAME, JavaCore.removeJavaLikeExtension(cu.getElementName())); // return evaluateTemplate(context, template); // } // /* * Don't use this method directly, use CodeGeneration. * @see org.eclipse.jdt.ui.CodeGeneration#getTypeComment(ICompilationUnit, String, String[], String) */ public static String getTypeComment(String typeQualifiedName, String[] typeParameterNames, String lineDelim) throws CoreException { Template template = getCodeTemplate(CodeTemplateContextType.TYPECOMMENT_ID); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelim); context.setCompilationUnitVariables(WorkerMessageHandler.get().getCUVariables()); context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, Signature.getQualifier(typeQualifiedName)); context.setVariable(CodeTemplateContextType.TYPENAME, Signature.getSimpleName(typeQualifiedName)); 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); } String str = buffer.getString(); if (Strings.containsOnlyWhitespaces(str)) { return null; } TemplateVariable position = findVariable(buffer, CodeTemplateContextType.TAGS); // look if Javadoc tags have to be added if (position == null) { return str; } Document document = new WorkerDocument(str); int[] tagOffsets = position.getOffsets(); for (int i = tagOffsets.length - 1; i >= 0; i--) { // from last to first try { insertTag(document, tagOffsets[i], position.getLength(), EMPTY, EMPTY, null, typeParameterNames, false, lineDelim); } catch (BadLocationException e) { throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); } } return document.get(); } /* * Returns the parameters type names used in see tags. Currently, these are always fully qualified. */ public static String[] getParameterTypeNamesForSeeTag(IMethodBinding binding) { ITypeBinding[] typeBindings = binding.getParameterTypes(); String[] result = new String[typeBindings.length]; for (int i = 0; i < result.length; i++) { ITypeBinding curr = typeBindings[i]; if (curr.isTypeVariable()) { curr = curr.getErasure(); // in Javadoc only use type variable erasure } curr = curr.getTypeDeclaration(); // no parameterized types result[i] = curr.getQualifiedName(); } return result; } // // /* // * Returns the parameters type names used in see tags. Currently, these are always fully qualified. // */ // private static String[] getParameterTypeNamesForSeeTag(IMethod overridden) { // try { // ASTParser parser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL); // parser.setProject(overridden.getJavaProject()); // IBinding[] bindings= parser.createBindings(new IJavaElement[] { overridden }, null); // if (bindings.length == 1 && bindings[0] instanceof IMethodBinding) { // return getParameterTypeNamesForSeeTag((IMethodBinding)bindings[0]); // } // } catch (IllegalStateException e) { // // method does not exist // } // // fall back code. Not good for generic methods! // String[] paramTypes= overridden.getParameterTypes(); // String[] paramTypeNames= new String[paramTypes.length]; // for (int i= 0; i < paramTypes.length; i++) { // paramTypeNames[i]= Signature.toString(Signature.getTypeErasure(paramTypes[i])); // } // return paramTypeNames; // } // 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(); } // // /** // * Don't use this method directly, use CodeGeneration. // * // * @param templateID the template id of the type body to get. Valid id's are // * {@link CodeTemplateContextType#CLASSBODY_ID}, // * {@link CodeTemplateContextType#INTERFACEBODY_ID}, // * {@link CodeTemplateContextType#ENUMBODY_ID}, // * {@link CodeTemplateContextType#ANNOTATIONBODY_ID}, // * @param cu the compilation unit to which the template is added // * @param typeName the type name // * @param lineDelim the line delimiter to use // * @return return the type body template or <code>null</code> // * @throws CoreException thrown if the template could not be evaluated // * @see org.eclipse.jdt.ui.CodeGeneration#getTypeBody(String, ICompilationUnit, String, String) // */ // public static String getTypeBody(String templateID, ICompilationUnit cu, String typeName, String lineDelim) throws // CoreException { // if (!VALID_TYPE_BODY_TEMPLATES.contains(templateID)) { // throw new IllegalArgumentException("Invalid code template ID: " + templateID); //$NON-NLS-1$ // } // // Template template= getCodeTemplate(templateID, cu.getJavaProject()); // if (template == null) { // return null; // } // CodeTemplateContext context= new CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(), lineDelim); // context.setCompilationUnitVariables(cu); // context.setVariable(CodeTemplateContextType.TYPENAME, typeName); // // return evaluateTemplate(context, template); // } // /* * Don't use this method directly, use CodeGeneration. * @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, String, String[], String[], String, String[], IMethod, String) */ public static String getMethodComment(String typeName, String methodName, String[] paramNames, String[] excTypeSig, String retTypeSig, String[] typeParameterNames, boolean delegate, String lineDelimiter) throws CoreException { String templateName = CodeTemplateContextType.METHODCOMMENT_ID; if (retTypeSig == null) { templateName = CodeTemplateContextType.CONSTRUCTORCOMMENT_ID; } //TODO // else if (target != null) // { // if (delegate) // templateName = CodeTemplateContextType.DELEGATECOMMENT_ID; // else // templateName = CodeTemplateContextType.OVERRIDECOMMENT_ID; // } Template template = getCodeTemplate(templateName); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setCompilationUnitVariables(WorkerMessageHandler.get().getCUVariables()); context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName); context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, methodName); if (retTypeSig != null) { context.setVariable(CodeTemplateContextType.RETURN_TYPE, Signature.toString(retTypeSig)); } //TODO // if (target != null) // { // String targetTypeName = target.getDeclaringType().getFullyQualifiedName('.'); // String[] targetParamTypeNames = getParameterTypeNamesForSeeTag(target); // if (delegate) // context.setVariable(CodeTemplateContextType.SEE_TO_TARGET_TAG, // getSeeTag(targetTypeName, methodName, targetParamTypeNames)); // else // context.setVariable(CodeTemplateContextType.SEE_TO_OVERRIDDEN_TAG, // getSeeTag(targetTypeName, methodName, targetParamTypeNames)); // } 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 = findVariable(buffer, CodeTemplateContextType.TAGS); // look if Javadoc tags have to be added if (position == null) { return str; } Document document = new WorkerDocument(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(document, tagOffsets[i], position.getLength(), paramNames, exceptionNames, returnType, typeParameterNames, false, lineDelimiter); } catch (BadLocationException e) { throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); } } return document.get(); } // remove lines for empty variables private static String fixEmptyVariables(TemplateBuffer buffer, String[] variables) throws MalformedTreeException, BadLocationException { Document doc = new WorkerDocument(buffer.getString()); int nLines = doc.getNumberOfLines(); MultiTextEdit edit = new MultiTextEdit(); HashSet<Integer> removedLines = new HashSet<Integer>(); for (int i = 0; i < variables.length; i++) { TemplateVariable position = findVariable(buffer, variables[i]); // look if Javadoc tags have to be added if (position == null || position.getLength() > 0) { continue; } int[] offsets = position.getOffsets(); for (int k = 0; k < offsets.length; k++) { int line = doc.getLineOfOffset(offsets[k]); Region lineInfo = doc.getLineInformation(line); int offset = lineInfo.getOffset(); String str = doc.get(offset, lineInfo.getLength()); if (Strings.containsOnlyWhitespaces(str) && nLines > line + 1 && removedLines.add(new Integer(line))) { int nextStart = doc.getLineOffset(line + 1); edit.addChild(new DeleteEdit(offset, nextStart - offset)); } } } edit.apply(doc, 0); return doc.get(); } /* * Don't use this method directly, use CodeGeneration. * @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, MethodDeclaration, boolean, String, String[], * String) */ public static String getMethodComment(String typeName, MethodDeclaration decl, boolean isDeprecated, String targetName, String targetMethodDeclaringTypeName, String[] targetMethodParameterTypeNames, boolean delegate, String lineDelimiter) throws CoreException { boolean needsTarget = targetMethodDeclaringTypeName != null && targetMethodParameterTypeNames != null; String templateName = CodeTemplateContextType.METHODCOMMENT_ID; if (decl.isConstructor()) { templateName = CodeTemplateContextType.CONSTRUCTORCOMMENT_ID; } else if (needsTarget) { if (delegate) templateName = CodeTemplateContextType.DELEGATECOMMENT_ID; else templateName = CodeTemplateContextType.OVERRIDECOMMENT_ID; } Template template = getCodeTemplate(templateName); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setCompilationUnitVariables(WorkerMessageHandler.get().getCUVariables()); context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName); context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD, decl.getName().getIdentifier()); if (!decl.isConstructor()) { context.setVariable(CodeTemplateContextType.RETURN_TYPE, ASTNodes.asString(getReturnType(decl))); } if (needsTarget) { if (delegate) context.setVariable(CodeTemplateContextType.SEE_TO_TARGET_TAG, getSeeTag(targetMethodDeclaringTypeName, targetName, targetMethodParameterTypeNames)); else context.setVariable(CodeTemplateContextType.SEE_TO_OVERRIDDEN_TAG, getSeeTag(targetMethodDeclaringTypeName, targetName, targetMethodParameterTypeNames)); } 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 = findVariable(buffer, CodeTemplateContextType.TAGS); // look if Javadoc tags have to be added if (position == null) { return str; } Document textBuffer = new WorkerDocument(str); List<TypeParameter> typeParams = decl.typeParameters(); //TODO //shouldGenerateMethodTypeParameterTags(cu.getJavaProject()) ? decl.typeParameters() : Collections.emptyList(); String[] typeParamNames = new String[typeParams.size()]; for (int i = 0; i < typeParamNames.length; i++) { TypeParameter elem = typeParams.get(i); typeParamNames[i] = elem.getName().getIdentifier(); } List<SingleVariableDeclaration> params = decl.parameters(); String[] paramNames = new String[params.size()]; for (int i = 0; i < paramNames.length; i++) { SingleVariableDeclaration elem = params.get(i); paramNames[i] = elem.getName().getIdentifier(); } List<Name> exceptions = decl.thrownExceptions(); String[] exceptionNames = new String[exceptions.size()]; for (int i = 0; i < exceptionNames.length; i++) { exceptionNames[i] = ASTNodes.getSimpleNameIdentifier(exceptions.get(i)); } String returnType = null; if (!decl.isConstructor()) { returnType = ASTNodes.asString(getReturnType(decl)); } 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, typeParamNames, isDeprecated, lineDelimiter); } catch (BadLocationException e) { throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); } } return textBuffer.get(); } /* * Don't use this method directly, use CodeGeneration. */ public static String getFieldComment(String typeName, String fieldName, String lineDelimiter) throws CoreException { Template template = getCodeTemplate(CodeTemplateContextType.FIELDCOMMENT_ID); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setCompilationUnitVariables(WorkerMessageHandler.get().getCUVariables()); context.setVariable(CodeTemplateContextType.FIELD_TYPE, typeName); context.setVariable(CodeTemplateContextType.FIELD, fieldName); return evaluateTemplate(context, template); } /* * Don't use this method directly, use CodeGeneration. * @see org.eclipse.jdt.ui.CodeGeneration#getSetterComment(ICompilationUnit, String, String, String, String, String, String, String) */ public static String getSetterComment(String typeName, String methodName, String fieldName, String fieldType, String paramName, String bareFieldName, String lineDelimiter) throws CoreException { String templateName = CodeTemplateContextType.SETTERCOMMENT_ID; Template template = getCodeTemplate(templateName); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setCompilationUnitVariables(WorkerMessageHandler.get().getCUVariables()); 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); } /* */ public static String getGetterComment(String typeName, String methodName, String fieldName, String fieldType, String bareFieldName, String lineDelimiter) throws CoreException { String templateName = CodeTemplateContextType.GETTERCOMMENT_ID; Template template = getCodeTemplate(templateName); if (template == null) { return null; } CodeTemplateContext context = new CodeTemplateContext(template.getContextTypeId(), lineDelimiter); context.setCompilationUnitVariables(WorkerMessageHandler.get().getCUVariables()); 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); } private 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; } private static String evaluateTemplate(CodeTemplateContext context, Template template, String[] fullLineVariables) throws CoreException { TemplateBuffer buffer; try { buffer = context.evaluate(template); if (buffer == null) return null; String str = fixEmptyVariables(buffer, fullLineVariables); if (Strings.containsOnlyWhitespaces(str)) { return null; } return str; } catch (BadLocationException e) { throw new CoreException(Status.CANCEL_STATUS); } catch (TemplateException e) { throw new CoreException(Status.CANCEL_STATUS); } } // // /* // * Don't use this method directly, use CodeGeneration. // * @see org.eclipse.jdt.ui.CodeGeneration#getMethodComment(ICompilationUnit, String, MethodDeclaration, boolean, String, // String[], String) // */ // public static String getMethodComment(ICompilationUnit cu, String typeName, MethodDeclaration decl, boolean isDeprecated, // String targetName, String targetMethodDeclaringTypeName, // String[] targetMethodParameterTypeNames, boolean delegate, String lineDelimiter) throws CoreException { // boolean needsTarget= targetMethodDeclaringTypeName != null && targetMethodParameterTypeNames != null; // String templateName= CodeTemplateContextType.METHODCOMMENT_ID; // if (decl.isConstructor()) { // templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT_ID; // } else if (needsTarget) { // if (delegate) // templateName= CodeTemplateContextType.DELEGATECOMMENT_ID; // else // templateName= CodeTemplateContextType.OVERRIDECOMMENT_ID; // } // Template template= getCodeTemplate(templateName, cu.getJavaProject()); // 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(getReturnType(decl))); // } // if (needsTarget) { // if (delegate) // context.setVariable(CodeTemplateContextType.SEE_TO_TARGET_TAG, getSeeTag(targetMethodDeclaringTypeName, targetName, // targetMethodParameterTypeNames)); // else // context.setVariable(CodeTemplateContextType.SEE_TO_OVERRIDDEN_TAG, getSeeTag(targetMethodDeclaringTypeName, targetName, // targetMethodParameterTypeNames)); // } // // 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= findVariable(buffer, CodeTemplateContextType.TAGS); // look if Javadoc tags have to be added // if (position == null) { // return str; // } // // IDocument textBuffer= new Document(str); // List<TypeParameter> typeParams= shouldGenerateMethodTypeParameterTags(cu.getJavaProject()) ? decl.typeParameters() : // Collections.emptyList(); // String[] typeParamNames= new String[typeParams.size()]; // for (int i= 0; i < typeParamNames.length; i++) { // TypeParameter elem= typeParams.get(i); // typeParamNames[i]= elem.getName().getIdentifier(); // } // List<SingleVariableDeclaration> params= decl.parameters(); // String[] paramNames= new String[params.size()]; // for (int i= 0; i < paramNames.length; i++) { // SingleVariableDeclaration elem= params.get(i); // paramNames[i]= elem.getName().getIdentifier(); // } // List<Name> exceptions= decl.thrownExceptions(); // String[] exceptionNames= new String[exceptions.size()]; // for (int i= 0; i < exceptionNames.length; i++) { // exceptionNames[i]= ASTNodes.getSimpleNameIdentifier(exceptions.get(i)); // } // // String returnType= null; // if (!decl.isConstructor()) { // returnType= ASTNodes.asString(getReturnType(decl)); // } // 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, typeParamNames, // isDeprecated, lineDelimiter); // } catch (BadLocationException e) { // throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); // } // } // return textBuffer.get(); // } // public static boolean shouldGenerateMethodTypeParameterTags() { //TODO return JavaCore.ENABLED.equals(JavaCore .getOption(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_METHOD_TYPE_PARAMETERS)); } /** * @param decl * the method declaration * @return the return type * @deprecated Deprecated to avoid deprecated warnings */ private static ASTNode getReturnType(MethodDeclaration decl) { // used from API, can't eliminate return decl.getAST().apiLevel() == AST.JLS2 ? decl.getReturnType() : decl.getReturnType2(); } private static TemplateVariable findVariable(TemplateBuffer buffer, String variable) { TemplateVariable[] positions = buffer.getVariables(); for (int i = 0; i < positions.length; i++) { TemplateVariable curr = positions[i]; if (variable.equals(curr.getType())) { return curr; } } return null; } private static void insertTag(Document textBuffer, int offset, int length, String[] paramNames, String[] exceptionNames, String returnType, String[] typeParameterNames, boolean isDeprecated, String lineDelimiter) throws BadLocationException { Region 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 < typeParameterNames.length; i++) { if (buf.length() > 0) { buf.append(lineDelimiter).append(lineStart); } buf.append("@param <").append(typeParameterNames[i]).append('>'); //$NON-NLS-1$ } for (int i = 0; i < paramNames.length; i++) { if (buf.length() > 0) { buf.append(lineDelimiter).append(lineStart); } buf.append("@param ").append(paramNames[i]); //$NON-NLS-1$ } if (returnType != null && !returnType.equals("void")) { //$NON-NLS-1$ if (buf.length() > 0) { buf.append(lineDelimiter).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).append(lineStart); } buf.append("@throws ").append(exceptionNames[i]); //$NON-NLS-1$ } } if (isDeprecated) { if (buf.length() > 0) { buf.append(lineDelimiter).append(lineStart); } buf.append("@deprecated"); //$NON-NLS-1$ } if (buf.length() == 0 && isAllCommentWhitespace(lineStart)) { int prevLine = textBuffer.getLineOfOffset(offset) - 1; if (prevLine > 0) { Region prevRegion = textBuffer.getLineInformation(prevLine); int prevLineEnd = prevRegion.getOffset() + prevRegion.getLength(); // clear full line textBuffer.replace(prevLineEnd, offset + length - prevLineEnd, ""); //$NON-NLS-1$ return; } } textBuffer.replace(offset, length, buf.toString()); } private static boolean isAllCommentWhitespace(String lineStart) { for (int i = 0; i < lineStart.length(); i++) { char ch = lineStart.charAt(i); if (!CharOperation.isWhitespace(ch) && ch != '*') { return false; } } return true; } // public static boolean shouldGenerateMethodTypeParameterTags(IJavaProject project) { // return JavaCore.ENABLED.equals(project.getOption(JavaCore.COMPILER_PB_MISSING_JAVADOC_TAGS_METHOD_TYPE_PARAMETERS, true)); // } // // /** // * @param decl the method declaration // * @return the return type // * @deprecated Deprecated to avoid deprecated warnings // */ // private static ASTNode getReturnType(MethodDeclaration decl) { // // used from API, can't eliminate // return decl.getAST().apiLevel() == AST.JLS2 ? decl.getReturnType() : decl.getReturnType2(); // } // // // private static TemplateVariable findVariable(TemplateBuffer buffer, String variable) { // TemplateVariable[] positions= buffer.getVariables(); // for (int i= 0; i < positions.length; i++) { // TemplateVariable curr= positions[i]; // if (variable.equals(curr.getType())) { // return curr; // } // } // return null; // } // // private static void insertTag(IDocument textBuffer, int offset, int length, String[] paramNames, String[] exceptionNames, // String returnType, String[] typeParameterNames, 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 < typeParameterNames.length; i++) { // if (buf.length() > 0) { // buf.append(lineDelimiter).append(lineStart); // } // buf.append("@param <").append(typeParameterNames[i]).append('>'); //$NON-NLS-1$ // } // for (int i= 0; i < paramNames.length; i++) { // if (buf.length() > 0) { // buf.append(lineDelimiter).append(lineStart); // } // buf.append("@param ").append(paramNames[i]); //$NON-NLS-1$ // } // if (returnType != null && !returnType.equals("void")) { //$NON-NLS-1$ // if (buf.length() > 0) { // buf.append(lineDelimiter).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).append(lineStart); // } // buf.append("@throws ").append(exceptionNames[i]); //$NON-NLS-1$ // } // } // if (isDeprecated) { // if (buf.length() > 0) { // buf.append(lineDelimiter).append(lineStart); // } // buf.append("@deprecated"); //$NON-NLS-1$ // } // if (buf.length() == 0 && isAllCommentWhitespace(lineStart)) { // int prevLine= textBuffer.getLineOfOffset(offset) - 1; // if (prevLine > 0) { // IRegion prevRegion= textBuffer.getLineInformation(prevLine); // int prevLineEnd= prevRegion.getOffset() + prevRegion.getLength(); // // clear full line // textBuffer.replace(prevLineEnd, offset + length - prevLineEnd, ""); //$NON-NLS-1$ // return; // } // } // textBuffer.replace(offset, length, buf.toString()); // } // // private static boolean isAllCommentWhitespace(String lineStart) { // for (int i= 0; i < lineStart.length(); i++) { // char ch= lineStart.charAt(i); // if (!Character.isWhitespace(ch) && ch != '*') { // return false; // } // } // return true; // } // /** * Returns the line delimiter which is used in the specified project. * * @return the used line delimiter */ public static String getLineDelimiterUsed() { return "\n"; } // // private static String getProjectLineDelimiter(IJavaProject javaProject) { // IProject project= null; // if (javaProject != null) // project= javaProject.getProject(); // // String lineDelimiter= getLineDelimiterPreference(project); // if (lineDelimiter != null) // return lineDelimiter; // // return System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ // } // // public static String getLineDelimiterPreference(IProject project) { // IScopeContext[] scopeContext; // if (project != null) { // // project preference // scopeContext= new IScopeContext[] { new ProjectScope(project) }; // String lineDelimiter= Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null, // scopeContext); // if (lineDelimiter != null) // return lineDelimiter; // } // // workspace preference // scopeContext= new IScopeContext[] { InstanceScope.INSTANCE }; // String platformDefault= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ // return Platform.getPreferencesService().getString(Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, platformDefault, // scopeContext); // } // // /** // * Examines a string and returns the first line delimiter found. // * // * @param elem the element // * @return the line delimiter used for the element // */ // public static String getLineDelimiterUsed(IJavaElement elem) { // IOpenable openable= elem.getOpenable(); // if (openable instanceof ITypeRoot) { // try { // return openable.findRecommendedLineSeparator(); // } catch (JavaModelException exception) { // // Use project setting // } // } // IJavaProject project= elem.getJavaProject(); // return getProjectLineDelimiter(project.exists() ? project : null); // } // // /** // * Evaluates the indentation used by a Java element. (in tabulators) // * // * @param elem the element to get the indent of // * @return return the indent unit // * @throws JavaModelException thrown if the element could not be accessed // */ // public static int getIndentUsed(IJavaElement elem) throws JavaModelException { // IOpenable openable= elem.getOpenable(); // if (openable instanceof ITypeRoot) { // IBuffer buf= openable.getBuffer(); // if (buf != null) { // int offset= ((ISourceReference)elem).getSourceRange().getOffset(); // return getIndentUsed(buf, offset, elem.getJavaProject()); // } // } // return 0; // } // // public static int getIndentUsed(IBuffer buffer, int offset, IJavaProject project) { // int i= offset; // // find beginning of line // while (i > 0 && !IndentManipulation.isLineDelimiterChar(buffer.getChar(i - 1))) { // i--; // } // return Strings.computeIndentUnits(buffer.getText(i, offset - i), project); // } // // // // /** // * Returns the element after the give element. // * // * @param member a Java element // * @return the next sibling of the given element or <code>null</code> // * @throws JavaModelException thrown if the element could not be accessed // */ // 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() { String markers = null; markers = JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS); if (markers != null && markers.length() > 0) { int idx = markers.indexOf(','); if (idx == -1) { return markers; } else { return markers.substring(0, idx); } } return null; } private static String removeTypeArguments(String baseName) { int idx = baseName.indexOf('<'); if (idx != -1) { return baseName.substring(0, idx); } return baseName; } // // // --------------------------- name suggestions -------------------------- // public static String[] getVariableNameSuggestions(int variableKind, ITypeBinding expectedType, Expression assignedExpression, Collection<String> excluded) { LinkedHashSet<String> res = new LinkedHashSet<String>(); // avoid duplicates but keep order if (assignedExpression != null) { String nameFromExpression = getBaseNameFromExpression(assignedExpression, variableKind); if (nameFromExpression != null) { add(getVariableNameSuggestions(variableKind, nameFromExpression, 0, excluded, false), res); // pass 0 as dimension, // base name already contains plural. } String nameFromParent = getBaseNameFromLocationInParent(assignedExpression); if (nameFromParent != null) { add(getVariableNameSuggestions(variableKind, nameFromParent, 0, excluded, false), res); // pass 0 as // dimension, // base name already contains plural. } } if (expectedType != null) { expectedType = Bindings.normalizeTypeBinding(expectedType); if (expectedType != null) { int dim = 0; if (expectedType.isArray()) { dim = expectedType.getDimensions(); expectedType = expectedType.getElementType(); } if (expectedType.isParameterizedType()) { expectedType = expectedType.getTypeDeclaration(); } String typeName = expectedType.getName(); if (typeName.length() > 0) { add(getVariableNameSuggestions(variableKind, typeName, dim, excluded, false), res); } } } if (res.isEmpty()) { return getDefaultVariableNameSuggestions(variableKind, excluded); } return res.toArray(new String[res.size()]); } public static String[] getVariableNameSuggestions(int variableKind, Type expectedType, Expression assignedExpression, Collection<String> excluded) { LinkedHashSet<String> res = new LinkedHashSet<String>(); // avoid duplicates but keep order if (assignedExpression != null) { String nameFromExpression = getBaseNameFromExpression(assignedExpression, variableKind); if (nameFromExpression != null) { add(getVariableNameSuggestions(variableKind, nameFromExpression, 0, excluded, false), res); // pass 0 as dimension, // base name already contains plural. } String nameFromParent = getBaseNameFromLocationInParent(assignedExpression); if (nameFromParent != null) { add(getVariableNameSuggestions(variableKind, nameFromParent, 0, excluded, false), res); // pass 0 as dimension, // base name already contains plural. } } if (expectedType != null) { String[] names = getVariableNameSuggestions(variableKind, expectedType, excluded, false); for (int i = 0; i < names.length; i++) { res.add(names[i]); } } if (res.isEmpty()) { return getDefaultVariableNameSuggestions(variableKind, excluded); } return res.toArray(new String[res.size()]); } private static String[] getVariableNameSuggestions(int variableKind, Type expectedType, Collection<String> excluded, boolean evaluateDefault) { int dim = 0; if (expectedType.isArrayType()) { ArrayType arrayType = (ArrayType)expectedType; dim = arrayType.getDimensions(); expectedType = arrayType.getElementType(); } if (expectedType.isParameterizedType()) { expectedType = ((ParameterizedType)expectedType).getType(); } String typeName = ASTNodes.getTypeName(expectedType); if (typeName.length() > 0) { return getVariableNameSuggestions(variableKind, typeName, dim, excluded, evaluateDefault); } return EMPTY; } private static String[] getDefaultVariableNameSuggestions(int variableKind, Collection<String> excluded) { String prop = variableKind == NamingConventions.VK_STATIC_FINAL_FIELD ? "X" : "x"; //$NON-NLS-1$//$NON-NLS-2$ String name = prop; int i = 1; while (excluded.contains(name)) { name = prop + i++; } return new String[]{name}; } /** * Returns variable name suggestions for the given base name. This is a layer over the JDT.Core NamingConventions API to fix * its shortcomings. JDT UI code should only use this API. * * @param variableKind * specifies what type the variable is: {@link NamingConventions#VK_LOCAL}, * {@link NamingConventions#VK_PARAMETER}, {@link NamingConventions#VK_STATIC_FIELD}, * {@link NamingConventions#VK_INSTANCE_FIELD}, or {@link NamingConventions#VK_STATIC_FINAL_FIELD}. * @param project * the current project * @param baseName * the base name to make a suggestion on. The base name is expected to be a name without any pre- or suffixes * in singular form. Type name are accepted as well. * @param dimensions * if greater than 0, the resulting name will be in plural form * @param excluded * a collection containing all excluded names or <code>null</code> if no names are excluded * @param evaluateDefault * if set, the result is guaranteed to contain at least one result. If not, the result can be an empty * array. * @return the name suggestions sorted by relevance (best proposal first). If <code>evaluateDefault</code> is set to true, the * returned array is never empty. If <code>evaluateDefault</code> is set to false, an empty array is returned if there * is no good suggestion for the given base name. */ public static String[] getVariableNameSuggestions(int variableKind, String baseName, int dimensions, Collection<String> excluded, boolean evaluateDefault) { return NamingConventions.suggestVariableNames(variableKind, NamingConventions.BK_TYPE_NAME, removeTypeArguments(baseName), dimensions, getExcludedArray(excluded), evaluateDefault); } private static String[] getExcludedArray(Collection<String> excluded) { if (excluded == null) { return null; } else if (excluded instanceof ExcludedCollection) { return ((ExcludedCollection)excluded).getExcludedArray(); } return excluded.toArray(new String[excluded.size()]); } private static final String[] KNOWN_METHOD_NAME_PREFIXES = {"get", "is", "to"}; //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-1$ private static void add(String[] names, Set<String> result) { for (int i = 0; i < names.length; i++) { result.add(names[i]); } } private static String getBaseNameFromExpression(Expression assignedExpression, int variableKind) { String name = null; if (assignedExpression instanceof CastExpression) { assignedExpression = ((CastExpression)assignedExpression).getExpression(); } if (assignedExpression instanceof Name) { Name simpleNode = (Name)assignedExpression; IBinding binding = simpleNode.resolveBinding(); if (binding instanceof IVariableBinding) return getBaseName((IVariableBinding)binding); return ASTNodes.getSimpleNameIdentifier(simpleNode); } else if (assignedExpression instanceof MethodInvocation) { name = ((MethodInvocation)assignedExpression).getName().getIdentifier(); } else if (assignedExpression instanceof SuperMethodInvocation) { name = ((SuperMethodInvocation)assignedExpression).getName().getIdentifier(); } else if (assignedExpression instanceof FieldAccess) { return ((FieldAccess)assignedExpression).getName().getIdentifier(); } else if (variableKind == NamingConventions.VK_STATIC_FINAL_FIELD && (assignedExpression instanceof StringLiteral || assignedExpression instanceof NumberLiteral)) { String string = assignedExpression instanceof StringLiteral ? ((StringLiteral)assignedExpression).getLiteralValue() : ((NumberLiteral)assignedExpression).getToken(); StringBuffer res = new StringBuffer(); boolean needsUnderscore = false; for (int i = 0; i < string.length(); i++) { char ch = string.charAt(i); if (CharUtil.isJavaIdentifierPart(ch)) { if (res.length() == 0 && !CharUtil.isJavaIdentifierStart(ch) || needsUnderscore) { res.append('_'); } res.append(ch); needsUnderscore = false; } else { needsUnderscore = res.length() > 0; } } if (res.length() > 0) { return res.toString(); } } if (name != null) { for (int i = 0; i < KNOWN_METHOD_NAME_PREFIXES.length; i++) { String curr = KNOWN_METHOD_NAME_PREFIXES[i]; if (name.startsWith(curr)) { if (name.equals(curr)) { return null; // don't suggest 'get' as variable name } else if (Character.isUpperCase(name.charAt(curr.length()))) { return name.substring(curr.length()); } } } } return name; } private static String getBaseNameFromLocationInParent(Expression assignedExpression, List<Expression> arguments, IMethodBinding binding) { if (binding == null) return null; ITypeBinding[] parameterTypes = binding.getParameterTypes(); if (parameterTypes.length != arguments.size()) // beware of guessed method bindings return null; int index = arguments.indexOf(assignedExpression); if (index == -1) return null; ITypeBinding expressionBinding = assignedExpression.resolveTypeBinding(); if (expressionBinding != null && !expressionBinding.isAssignmentCompatible(parameterTypes[index])) return null; // TODO // try // { // IJavaElement javaElement = binding.getJavaElement(); // if (javaElement instanceof IMethod) // { // IMethod method = (IMethod)javaElement; // if (method.getOpenable().getBuffer() != null) // { // avoid dummy names and lookup from Javadoc // String[] parameterNames = method.getParameterNames(); // if (index < parameterNames.length) // { // return NamingConventions.getBaseName(NamingConventions.VK_PARAMETER, parameterNames[index], // method.getJavaProject()); // } // } // } // } // catch (JavaModelException e) // { // // ignore // } return null; } private static String getBaseNameFromLocationInParent(Expression assignedExpression) { StructuralPropertyDescriptor location = assignedExpression.getLocationInParent(); if (location == MethodInvocation.ARGUMENTS_PROPERTY) { MethodInvocation parent = (MethodInvocation)assignedExpression.getParent(); return getBaseNameFromLocationInParent(assignedExpression, parent.arguments(), parent.resolveMethodBinding()); } else if (location == ClassInstanceCreation.ARGUMENTS_PROPERTY) { ClassInstanceCreation parent = (ClassInstanceCreation)assignedExpression.getParent(); return getBaseNameFromLocationInParent(assignedExpression, parent.arguments(), parent.resolveConstructorBinding()); } else if (location == SuperMethodInvocation.ARGUMENTS_PROPERTY) { SuperMethodInvocation parent = (SuperMethodInvocation)assignedExpression.getParent(); return getBaseNameFromLocationInParent(assignedExpression, parent.arguments(), parent.resolveMethodBinding()); } else if (location == ConstructorInvocation.ARGUMENTS_PROPERTY) { ConstructorInvocation parent = (ConstructorInvocation)assignedExpression.getParent(); return getBaseNameFromLocationInParent(assignedExpression, parent.arguments(), parent.resolveConstructorBinding()); } else if (location == SuperConstructorInvocation.ARGUMENTS_PROPERTY) { SuperConstructorInvocation parent = (SuperConstructorInvocation)assignedExpression.getParent(); return getBaseNameFromLocationInParent(assignedExpression, parent.arguments(), parent.resolveConstructorBinding()); } return null; } // // public static String[] getArgumentNameSuggestions(IType type, String[] excluded) { // return getVariableNameSuggestions(NamingConventions.VK_PARAMETER, type.getJavaProject(), type.getElementName(), 0, new // ExcludedCollection(excluded), true); // } public static String[] getArgumentNameSuggestions(Type type, String[] excluded) { return getVariableNameSuggestions(NamingConventions.VK_PARAMETER, type, new ExcludedCollection(excluded), true); } // // public static String[] getArgumentNameSuggestions(IJavaProject project, ITypeBinding binding, String[] excluded) { // return getVariableNameSuggestions(NamingConventions.VK_PARAMETER, project, binding, null, new ExcludedCollection(excluded)); // } // public static String[] getArgumentNameSuggestions(String baseName, int dimensions, String[] excluded) { return getVariableNameSuggestions(NamingConventions.VK_PARAMETER, baseName, dimensions, new ExcludedCollection( excluded), true); } public static String[] getFieldNameSuggestions(String baseName, int dimensions, int modifiers, String[] excluded) { if (Flags.isFinal(modifiers) && Flags.isStatic(modifiers)) { return getVariableNameSuggestions(NamingConventions.VK_STATIC_FINAL_FIELD, baseName, dimensions, new ExcludedCollection(excluded), true); } else if (Flags.isStatic(modifiers)) { return getVariableNameSuggestions(NamingConventions.VK_STATIC_FIELD, baseName, dimensions, new ExcludedCollection(excluded), true); } return getVariableNameSuggestions(NamingConventions.VK_INSTANCE_FIELD, baseName, dimensions, new ExcludedCollection(excluded), true); } public static String[] getLocalNameSuggestions(String baseName, int dimensions, String[] excluded) { return getVariableNameSuggestions(NamingConventions.VK_LOCAL, baseName, dimensions, new ExcludedCollection( excluded), true); } public static String suggestArgumentName(String baseName, String[] excluded) { return suggestVariableName(NamingConventions.VK_PARAMETER, baseName, 0, excluded); } private static String suggestVariableName(int varKind, String baseName, int dimension, String[] excluded) { return getVariableNameSuggestions(varKind, baseName, dimension, new ExcludedCollection(excluded), true)[0]; } public static String[][] suggestArgumentNamesWithProposals(String[] paramNames) { String[][] newNames = new String[paramNames.length][]; ArrayList<String> takenNames = new ArrayList<String>(); // Ensure that the code generation preferences are respected for (int i = 0; i < paramNames.length; i++) { String curr = paramNames[i]; String baseName = NamingConventions.getBaseName(NamingConventions.VK_PARAMETER, curr); String[] proposedNames = getVariableNameSuggestions(NamingConventions.VK_PARAMETER, curr, 0, takenNames, true); if (!curr.equals(baseName)) { // make the existing name to favorite LinkedHashSet<String> updatedNames = new LinkedHashSet<String>(); updatedNames.add(curr); for (int k = 0; k < proposedNames.length; k++) { updatedNames.add(proposedNames[k]); } proposedNames = updatedNames.toArray(new String[updatedNames.size()]); } newNames[i] = proposedNames; takenNames.add(proposedNames[0]); } return newNames; } // // public static String[][] suggestArgumentNamesWithProposals(IJavaProject project, IMethodBinding binding) { // int nParams= binding.getParameterTypes().length; // if (nParams > 0) { // try { // IMethod method= (IMethod)binding.getMethodDeclaration().getJavaElement(); // if (method != null) { // String[] parameterNames= method.getParameterNames(); // if (parameterNames.length == nParams) { // return suggestArgumentNamesWithProposals(project, parameterNames); // } // } // } catch (JavaModelException e) { // // ignore // } // } // String[][] names= new String[nParams][]; // for (int i= 0; i < names.length; i++) { // names[i]= new String[] { "arg" + i }; //$NON-NLS-1$ // } // return names; // } // // public static String[] suggestArgumentNames(IMethodBinding binding) { int nParams = binding.getParameterTypes().length; if (nParams > 0) { // TODO // try // { // IMethod method = (IMethod)binding.getMethodDeclaration().getJavaElement(); // if (method != null) // { // String[] paramNames = method.getParameterNames(); // if (paramNames.length == nParams) // { // String[] namesArray = EMPTY; // ArrayList<String> newNames = new ArrayList<String>(paramNames.length); // // Ensure that the code generation preferences are respected // for (int i = 0; i < paramNames.length; i++) // { // String curr = paramNames[i]; // String baseName = // NamingConventions.getBaseName(NamingConventions.VK_PARAMETER, curr, method.getJavaProject()); // if (!curr.equals(baseName)) // { // // make the existing name the favorite // newNames.add(curr); // } // else // { // newNames.add(suggestArgumentName(project, curr, namesArray)); // } // namesArray = newNames.toArray(new String[newNames.size()]); // } // return namesArray; // } // } // } // catch (JavaModelException e) // { // // ignore // } } String[] names = new String[nParams]; for (int i = 0; i < names.length; i++) { names[i] = "arg" + i; //$NON-NLS-1$ } return names; } // // public static String getBaseName(IField field) throws JavaModelException { // return NamingConventions.getBaseName(getFieldKind(field.getFlags()), field.getElementName(), field.getJavaProject()); // } // public static String getBaseName(IVariableBinding binding) { return NamingConventions.getBaseName(getKind(binding), binding.getName()); } /** * Returns the kind of the given binding. * * @param binding * variable binding * @return one of the <code>NamingConventions.VK_*</code> constants * @since 3.5 */ private static int getKind(IVariableBinding binding) { if (binding.isField()) return getFieldKind(binding.getModifiers()); if (binding.isParameter()) return NamingConventions.VK_PARAMETER; return NamingConventions.VK_LOCAL; } private static int getFieldKind(int modifiers) { if (!Modifier.isStatic(modifiers)) return NamingConventions.VK_INSTANCE_FIELD; if (!Modifier.isFinal(modifiers)) return NamingConventions.VK_STATIC_FIELD; return NamingConventions.VK_STATIC_FINAL_FIELD; } private static class ExcludedCollection extends AbstractList<String> { private String[] fExcluded; public ExcludedCollection(String[] excluded) { fExcluded = excluded; } public String[] getExcludedArray() { return fExcluded; } @Override public int size() { return fExcluded.length; } @Override public String get(int index) { return fExcluded[index]; } @Override public int indexOf(Object o) { if (o instanceof String) { for (int i = 0; i < fExcluded.length; i++) { if (o.equals(fExcluded[i])) return i; } } return -1; } @Override public boolean contains(Object o) { return indexOf(o) != -1; } } public static boolean hasFieldName(String name) { //TODO // 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); return false; } public static boolean hasParameterName(String name) { //TODO // String prefixes = project.getOption(JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true); // String suffixes = project.getOption(JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true); // return hasPrefixOrSuffix(prefixes, suffixes, name); return false; } public static boolean hasLocalVariableName(String name) { //TODO // String prefixes = project.getOption(JavaCore.CODEASSIST_LOCAL_PREFIXES, true); // String suffixes = project.getOption(JavaCore.CODEASSIST_LOCAL_SUFFIXES, true); // return hasPrefixOrSuffix(prefixes, suffixes, name); return false; } public static boolean hasConstantName(String name) { //TODO if (Character.isUpperCase(name.charAt(0))) return true; // String prefixes = project.getOption(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_PREFIXES, true); // String suffixes = project.getOption(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES, true); // return hasPrefixOrSuffix(prefixes, suffixes, name); return false; } // // 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; // } // 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(IJavaProject project, String name) { // if (Character.isUpperCase(name.charAt(0))) // return true; // String prefixes= project.getOption(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_PREFIXES, true); // String suffixes= project.getOption(JavaCore.CODEASSIST_STATIC_FINAL_FIELD_SUFFIXES, true); // return hasPrefixOrSuffix(prefixes, suffixes, name); // } // // // 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; // } // // // -------------------- preference access ----------------------- // // public static boolean useThisForFieldAccess(IJavaProject project) { // return Boolean.valueOf(PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_KEYWORD_THIS, project)).booleanValue(); // } public static boolean useIsForBooleanGetters() { //TODO return true; // return Boolean.valueOf(PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_IS_FOR_GETTERS, project)) // .booleanValue(); } // public static String getExceptionVariableName() { return "e"; //PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_EXCEPTION_VAR_NAME, project); } public static boolean doAddComments() { //TODO return true; // return Boolean.valueOf(PreferenceConstants.getPreference(PreferenceConstants.CODEGEN_ADD_COMMENTS, project)) // .booleanValue(); } /** * Only to be used by tests * * @param templateId * the template id * @param pattern * the new pattern * @param project * not used */ public static void setCodeTemplate(String templateId, String pattern) { TemplateStore codeTemplateStore = WorkerMessageHandler.get().getTemplateStore(); Template orig = codeTemplateStore.findTemplateById(templateId); orig.setPattern(pattern); // TemplatePersistenceData data = codeTemplateStore.getTemplateData(templateId); // Template orig = data.getTemplate(); // Template copy = new Template(orig.getName(), orig.getDescription(), orig.getContextTypeId(), pattern, true); // data.setTemplate(copy); } private static Template getCodeTemplate(String id) { // if (project == null) return WorkerMessageHandler.get().getTemplateStore().findTemplateById(id); // ProjectTemplateStore projectStore = new ProjectTemplateStore(project.getProject()); // try // { // projectStore.load(); // } // catch (IOException e) // { // JavaPlugin.log(e); // } // return projectStore.findTemplateById(id); } // public static ImportRewrite createImportRewrite(ICompilationUnit cu, boolean restoreExistingImports) throws // JavaModelException { // return CodeStyleConfiguration.createImportRewrite(cu, restoreExistingImports); // } // /** * Returns a {@link ImportRewrite} using {@link ImportRewrite#create(CompilationUnit, boolean)} and configures the rewriter * with the settings as specified in the JDT UI preferences. * <p> * This method sets {@link ImportRewrite#setUseContextToFilterImplicitImports(boolean)} to <code>true</code> iff the given AST * has been resolved with bindings. Clients should always supply a context when they call one of the * <code>addImport(...)</code> methods. * </p> * * @param astRoot * the AST root to create the rewriter on * @param restoreExistingImports * specifies if the existing imports should be kept or removed. * @return the new rewriter configured with the settings as specified in the JDT UI preferences. * @see ImportRewrite#create(CompilationUnit, boolean) */ public static ImportRewrite createImportRewrite(Document document, CompilationUnit astRoot, boolean restoreExistingImports) { ImportRewrite rewrite = ImportRewrite.create(document, astRoot, restoreExistingImports); rewrite.setOnDemandImportThreshold(99); rewrite.setStaticOnDemandImportThreshold(99); //TODO configure order rewrite.setImportOrder(ORDER); if (astRoot.getAST().hasResolvedBindings()) { rewrite.setUseContextToFilterImplicitImports(true); } return rewrite; } /** @return */ public static boolean useThisForFieldAccess() { //TODO return false; } }