10b0b089b6e8f43692331c22d44f4b08607543a6
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / corext / codemanipulation / StubUtility.java
1 /*
2  * (c) Copyright IBM Corp. 2000, 2001.
3  * All Rights Reserved.
4  */
5 package net.sourceforge.phpdt.internal.corext.codemanipulation;
6
7 import java.util.Arrays;
8 import java.util.Comparator;
9 import java.util.List;
10 import java.util.StringTokenizer;
11
12 import net.sourceforge.phpdt.core.Flags;
13 import net.sourceforge.phpdt.core.IBuffer;
14 import net.sourceforge.phpdt.core.ICodeFormatter;
15 import net.sourceforge.phpdt.core.ICompilationUnit;
16 import net.sourceforge.phpdt.core.IJavaElement;
17 import net.sourceforge.phpdt.core.IJavaProject;
18 import net.sourceforge.phpdt.core.IMethod;
19 import net.sourceforge.phpdt.core.IPackageFragment;
20 import net.sourceforge.phpdt.core.IType;
21 import net.sourceforge.phpdt.core.JavaCore;
22 import net.sourceforge.phpdt.core.JavaModelException;
23 import net.sourceforge.phpdt.core.Signature;
24 import net.sourceforge.phpdt.core.ToolFactory;
25 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContext;
26 import net.sourceforge.phpdt.internal.corext.template.php.CodeTemplateContextType;
27 import net.sourceforge.phpdt.internal.corext.util.JavaModelUtil;
28 import net.sourceforge.phpdt.internal.corext.util.Strings;
29 import net.sourceforge.phpdt.internal.ui.PHPUIStatus;
30 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
31
32 import org.eclipse.core.runtime.CoreException;
33 import org.eclipse.core.runtime.IStatus;
34 import org.eclipse.core.runtime.Status;
35 import org.eclipse.jface.text.BadLocationException;
36 import org.eclipse.jface.text.Document;
37 import org.eclipse.jface.text.IDocument;
38 import org.eclipse.jface.text.IRegion;
39 import org.eclipse.jface.text.templates.Template;
40 import org.eclipse.jface.text.templates.TemplateBuffer;
41 import org.eclipse.jface.text.templates.TemplateException;
42 import org.eclipse.jface.text.templates.TemplateVariable;
43 import org.eclipse.swt.SWT;
44
45 public class StubUtility {
46
47         public static class GenStubSettings extends CodeGenerationSettings {
48
49                 public boolean callSuper;
50
51                 public boolean methodOverwrites;
52
53                 public boolean noBody;
54
55                 public int methodModifiers;
56
57                 public GenStubSettings(CodeGenerationSettings settings) {
58                         settings.setSettings(this);
59                         methodModifiers = -1;
60                 }
61
62         }
63
64         private static final String[] EMPTY = new String[0];
65
66         /**
67          * Generates a method stub including the method comment. Given a template
68          * method, a stub with the same signature will be constructed so it can be
69          * added to a type. The method body will be empty or contain a return or
70          * super call.
71          * 
72          * @param destTypeName
73          *            The name of the type to which the method will be added to
74          * @param method
75          *            A method template (method belongs to different type than the
76          *            parent)
77          * @param definingType
78          *            The type that defines the method.
79          * @param settings
80          *            Options as defined above (<code>GenStubSettings</code>)
81          * @param imports
82          *            Imports required by the stub are added to the imports
83          *            structure. If imports structure is <code>null</code> all
84          *            type names are qualified.
85          * @throws JavaModelException
86          */
87         public static String genStub(ICompilationUnit cu, String destTypeName,
88                         IMethod method, IType definingType, GenStubSettings settings)
89                         throws CoreException {
90                 // IImportsStructure imports) throws CoreException {
91                 String methName = method.getElementName();
92                 String[] paramNames = suggestArgumentNames(method.getJavaProject(),
93                                 method.getParameterNames());
94                 String returnType = method.isConstructor() ? null : method
95                                 .getReturnType();
96                 String lineDelimiter = String.valueOf('\n'); // reformatting required
97
98                 StringBuffer buf = new StringBuffer();
99                 // add method comment
100                 if (settings.createComments && cu != null) {
101                         IMethod overridden = null;
102                         if (settings.methodOverwrites && returnType != null) {
103                                 overridden = JavaModelUtil.findMethod(methName, method
104                                                 .getParameterTypes(), false, definingType.getMethods());
105                         }
106                         String comment = getMethodComment(cu, destTypeName, methName,
107                                         paramNames, method.getExceptionTypes(), returnType,
108                                         overridden, lineDelimiter);
109                         if (comment != null) {
110                                 buf.append(comment);
111                         } else {
112                                 buf.append("/**").append(lineDelimiter); //$NON-NLS-1$
113                                 buf.append(" *").append(lineDelimiter); //$NON-NLS-1$
114                                 buf.append(" */").append(lineDelimiter); //$NON-NLS-1$                                                  
115                         }
116                         buf.append(lineDelimiter);
117                 }
118                 // add method declaration
119                 String bodyContent = null;
120                 if (!settings.noBody) {
121                         String bodyStatement = getDefaultMethodBodyStatement(methName,
122                                         paramNames, returnType, settings.callSuper);
123                         bodyContent = getMethodBodyContent(returnType == null, method
124                                         .getJavaProject(), destTypeName, methName, bodyStatement,
125                                         lineDelimiter);
126                         if (bodyContent == null) {
127                                 bodyContent = ""; //$NON-NLS-1$
128                         }
129                 }
130                 int flags = settings.methodModifiers;
131                 if (flags == -1) {
132                         flags = method.getFlags();
133                 }
134
135                 genMethodDeclaration(destTypeName, method, flags, bodyContent, buf); // imports,
136                                                                                                                                                                 // buf);
137                 return buf.toString();
138         }
139
140         /**
141          * Generates a method stub not including the method comment. Given a
142          * template method and the body content, a stub with the same signature will
143          * be constructed so it can be added to a type.
144          * 
145          * @param destTypeName
146          *            The name of the type to which the method will be added to
147          * @param method
148          *            A method template (method belongs to different type than the
149          *            parent)
150          * @param bodyContent
151          *            Content of the body
152          * @param imports
153          *            Imports required by the stub are added to the imports
154          *            structure. If imports structure is <code>null</code> all
155          *            type names are qualified.
156          * @param buf
157          *            The buffer to append the gerenated code.
158          * @throws JavaModelException
159          */
160         public static void genMethodDeclaration(String destTypeName,
161                         IMethod method, String bodyContent, StringBuffer buf)
162                         throws CoreException { // IImportsStructure imports, StringBuffer
163                                                                         // buf) throws CoreException {
164                 genMethodDeclaration(destTypeName, method, method.getFlags(),
165                                 bodyContent, buf);
166         }
167
168         /**
169          * Generates a method stub not including the method comment. Given a
170          * template method and the body content, a stub with the same signature will
171          * be constructed so it can be added to a type.
172          * 
173          * @param destTypeName
174          *            The name of the type to which the method will be added to
175          * @param method
176          *            A method template (method belongs to different type than the
177          *            parent)
178          * @param bodyContent
179          *            Content of the body
180          * @param imports
181          *            Imports required by the stub are added to the imports
182          *            structure. If imports structure is <code>null</code> all
183          *            type names are qualified.
184          * @param buf
185          *            The buffer to append the gerenated code.
186          * @throws JavaModelException
187          */
188         public static void genMethodDeclaration(String destTypeName,
189                         IMethod method, int flags, String bodyContent, StringBuffer buf)
190                         throws CoreException {
191                 // IImportsStructure imports, StringBuffer buf) throws CoreException {
192                 IType parentType = method.getDeclaringType();
193                 String methodName = method.getElementName();
194                 String[] paramTypes = method.getParameterTypes();
195                 String[] paramNames = suggestArgumentNames(parentType.getJavaProject(),
196                                 method.getParameterNames());
197
198                 String[] excTypes = method.getExceptionTypes();
199
200                 boolean isConstructor = method.isConstructor();
201                 String retTypeSig = isConstructor ? null : method.getReturnType();
202
203                 int lastParam = paramTypes.length - 1;
204
205                 if (Flags.isPublic(flags)
206                                 || (parentType.isInterface() && bodyContent != null)) {
207                         buf.append("public "); //$NON-NLS-1$
208                 } else if (Flags.isProtected(flags)) {
209                         buf.append("protected "); //$NON-NLS-1$
210                 } else if (Flags.isPrivate(flags)) {
211                         buf.append("private "); //$NON-NLS-1$
212                 }
213                 // if (Flags.isSynchronized(flags)) {
214                 // buf.append("synchronized "); //$NON-NLS-1$
215                 // }
216                 // if (Flags.isVolatile(flags)) {
217                 // buf.append("volatile "); //$NON-NLS-1$
218                 // }
219                 // if (Flags.isStrictfp(flags)) {
220                 // buf.append("strictfp "); //$NON-NLS-1$
221                 // }
222                 if (Flags.isStatic(flags)) {
223                         buf.append("static "); //$NON-NLS-1$
224                 }
225
226                 if (isConstructor) {
227                         buf.append(destTypeName);
228                 } else {
229                         String retTypeFrm;
230                         if (!isPrimitiveType(retTypeSig)) {
231                                 retTypeFrm = resolveAndAdd(retTypeSig, parentType);
232                         } else {
233                                 retTypeFrm = Signature.toString(retTypeSig);
234                         }
235                         buf.append(retTypeFrm);
236                         buf.append(' ');
237                         buf.append(methodName);
238                 }
239                 buf.append('(');
240                 for (int i = 0; i <= lastParam; i++) {
241                         String paramTypeSig = paramTypes[i];
242                         String paramTypeFrm;
243
244                         if (!isPrimitiveType(paramTypeSig)) {
245                                 paramTypeFrm = resolveAndAdd(paramTypeSig, parentType);
246                         } else {
247                                 paramTypeFrm = Signature.toString(paramTypeSig);
248                         }
249                         buf.append(paramTypeFrm);
250                         buf.append(' ');
251                         buf.append(paramNames[i]);
252                         if (i < lastParam) {
253                                 buf.append(", "); //$NON-NLS-1$
254                         }
255                 }
256                 buf.append(')');
257
258                 int lastExc = excTypes.length - 1;
259                 if (lastExc >= 0) {
260                         buf.append(" throws "); //$NON-NLS-1$
261                         for (int i = 0; i <= lastExc; i++) {
262                                 String excTypeSig = excTypes[i];
263                                 String excTypeFrm = resolveAndAdd(excTypeSig, parentType);
264                                 buf.append(excTypeFrm);
265                                 if (i < lastExc) {
266                                         buf.append(", "); //$NON-NLS-1$
267                                 }
268                         }
269                 }
270                 if (bodyContent == null) {
271                         buf.append(";\n\n"); //$NON-NLS-1$
272                 } else {
273                         buf.append(" {\n\t"); //$NON-NLS-1$
274                         if ((bodyContent != null) && (bodyContent.length() > 0)) {
275                                 buf.append(bodyContent);
276                                 buf.append('\n');
277                         }
278                         buf.append("}\n"); //$NON-NLS-1$
279                 }
280         }
281
282         public static String getDefaultMethodBodyStatement(String methodName,
283                         String[] paramNames, String retTypeSig, boolean callSuper) {
284                 StringBuffer buf = new StringBuffer();
285                 if (callSuper) {
286                         if (retTypeSig != null) {
287                                 if (!Signature.SIG_VOID.equals(retTypeSig)) {
288                                         buf.append("return "); //$NON-NLS-1$
289                                 }
290                                 buf.append("super."); //$NON-NLS-1$
291                                 buf.append(methodName);
292                         } else {
293                                 buf.append("super"); //$NON-NLS-1$
294                         }
295                         buf.append('(');
296                         for (int i = 0; i < paramNames.length; i++) {
297                                 if (i > 0) {
298                                         buf.append(", "); //$NON-NLS-1$
299                                 }
300                                 buf.append(paramNames[i]);
301                         }
302                         buf.append(");"); //$NON-NLS-1$
303                 } else {
304                         if (retTypeSig != null && !retTypeSig.equals(Signature.SIG_VOID)) {
305                                 if (!isPrimitiveType(retTypeSig)
306                                                 || Signature.getArrayCount(retTypeSig) > 0) {
307                                         buf.append("return null;"); //$NON-NLS-1$
308                                 } else if (retTypeSig.equals(Signature.SIG_BOOLEAN)) {
309                                         buf.append("return false;"); //$NON-NLS-1$
310                                 } else {
311                                         buf.append("return 0;"); //$NON-NLS-1$
312                                 }
313                         }
314                 }
315                 return buf.toString();
316         }
317
318         public static String getMethodBodyContent(boolean isConstructor,
319                         IJavaProject project, String destTypeName, String methodName,
320                         String bodyStatement, String lineDelimiter) throws CoreException {
321                 String templateName = isConstructor ? CodeTemplateContextType.CONSTRUCTORSTUB
322                                 : CodeTemplateContextType.METHODSTUB;
323                 Template template = PHPeclipsePlugin.getDefault()
324                                 .getCodeTemplateStore().findTemplate(templateName);
325                 if (template == null) {
326                         return bodyStatement;
327                 }
328                 CodeTemplateContext context = new CodeTemplateContext(template
329                                 .getContextTypeId(), project, lineDelimiter);
330                 context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
331                                 methodName);
332                 context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
333                                 destTypeName);
334                 context.setVariable(CodeTemplateContextType.BODY_STATEMENT,
335                                 bodyStatement);
336                 String str = evaluateTemplate(context, template);
337                 if (str == null && !Strings.containsOnlyWhitespaces(bodyStatement)) {
338                         return bodyStatement;
339                 }
340                 return str;
341         }
342
343         public static String getGetterMethodBodyContent(IJavaProject project,
344                         String destTypeName, String methodName, String fieldName,
345                         String lineDelimiter) throws CoreException {
346                 String templateName = CodeTemplateContextType.GETTERSTUB;
347                 Template template = PHPeclipsePlugin.getDefault()
348                                 .getCodeTemplateStore().findTemplate(templateName);
349                 if (template == null) {
350                         return null;
351                 }
352                 CodeTemplateContext context = new CodeTemplateContext(template
353                                 .getContextTypeId(), project, lineDelimiter);
354                 context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
355                                 methodName);
356                 context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
357                                 destTypeName);
358                 context.setVariable(CodeTemplateContextType.FIELD, fieldName);
359
360                 return evaluateTemplate(context, template);
361         }
362
363         public static String getSetterMethodBodyContent(IJavaProject project,
364                         String destTypeName, String methodName, String fieldName,
365                         String paramName, String lineDelimiter) throws CoreException {
366                 String templateName = CodeTemplateContextType.SETTERSTUB;
367                 Template template = PHPeclipsePlugin.getDefault()
368                                 .getCodeTemplateStore().findTemplate(templateName);
369                 if (template == null) {
370                         return null;
371                 }
372                 CodeTemplateContext context = new CodeTemplateContext(template
373                                 .getContextTypeId(), project, lineDelimiter);
374                 context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
375                                 methodName);
376                 context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE,
377                                 destTypeName);
378                 context.setVariable(CodeTemplateContextType.FIELD, fieldName);
379                 context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldName);
380                 context.setVariable(CodeTemplateContextType.PARAM, paramName);
381
382                 return evaluateTemplate(context, template);
383         }
384
385         public static String getCatchBodyContent(ICompilationUnit cu,
386                         String exceptionType, String variableName, String lineDelimiter)
387                         throws CoreException {
388                 Template template = PHPeclipsePlugin.getDefault()
389                                 .getCodeTemplateStore().findTemplate(
390                                                 CodeTemplateContextType.CATCHBLOCK);
391                 if (template == null) {
392                         return null;
393                 }
394
395                 CodeTemplateContext context = new CodeTemplateContext(template
396                                 .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
397                 context.setVariable(CodeTemplateContextType.EXCEPTION_TYPE,
398                                 exceptionType);
399                 context
400                                 .setVariable(CodeTemplateContextType.EXCEPTION_VAR,
401                                                 variableName); //$NON-NLS-1$
402                 return evaluateTemplate(context, template);
403         }
404
405         /**
406          * @see net.sourceforge.phpdt.ui.CodeGeneration#getTypeComment(ICompilationUnit,
407          *      String, String)
408          */
409         public static String getCompilationUnitContent(ICompilationUnit cu,
410                         String typeComment, String typeContent, String lineDelimiter)
411                         throws CoreException {
412                 IPackageFragment pack = (IPackageFragment) cu.getParent();
413                 String packDecl = pack.isDefaultPackage() ? "" : "package " + pack.getElementName() + ';'; //$NON-NLS-1$ //$NON-NLS-2$
414
415                 Template template = PHPeclipsePlugin.getDefault()
416                                 .getCodeTemplateStore().findTemplate(
417                                                 CodeTemplateContextType.NEWTYPE);
418                 if (template == null) {
419                         return null;
420                 }
421
422                 IJavaProject project = cu.getJavaProject();
423                 CodeTemplateContext context = new CodeTemplateContext(template
424                                 .getContextTypeId(), project, lineDelimiter);
425                 context.setCompilationUnitVariables(cu);
426                 context.setVariable(CodeTemplateContextType.PACKAGE_DECLARATION,
427                                 packDecl);
428                 context.setVariable(CodeTemplateContextType.TYPE_COMMENT,
429                                 typeComment != null ? typeComment : ""); //$NON-NLS-1$
430                 context.setVariable(CodeTemplateContextType.TYPE_DECLARATION,
431                                 typeContent);
432                 context.setVariable(CodeTemplateContextType.TYPENAME, Signature
433                                 .getQualifier(cu.getElementName()));
434                 return evaluateTemplate(context, template);
435         }
436
437         /*
438          * @see net.sourceforge.phpdt.ui.CodeGeneration#getTypeComment(ICompilationUnit,
439          *      String, String)
440          */
441         public static String getTypeComment(ICompilationUnit cu,
442                         String typeQualifiedName, String lineDelim) throws CoreException {
443                 Template template = PHPeclipsePlugin.getDefault()
444                                 .getCodeTemplateStore().findTemplate(
445                                                 CodeTemplateContextType.TYPECOMMENT);
446                 if (template == null) {
447                         return null;
448                 }
449                 CodeTemplateContext context = new CodeTemplateContext(template
450                                 .getContextTypeId(), cu.getJavaProject(), lineDelim);
451                 context.setCompilationUnitVariables(cu);
452                 context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, Signature
453                                 .getQualifier(typeQualifiedName));
454                 context.setVariable(CodeTemplateContextType.TYPENAME, Signature
455                                 .getSimpleName(typeQualifiedName));
456                 return evaluateTemplate(context, template);
457         }
458
459         // private static String[] getParameterTypesQualifiedNames(IMethodBinding
460         // binding) {
461         // ITypeBinding[] typeBindings= binding.getParameterTypes();
462         // String[] result= new String[typeBindings.length];
463         // for (int i= 0; i < result.length; i++) {
464         // result[i]= typeBindings[i].getQualifiedName();
465         // }
466         // return result;
467         // }
468
469         private static String getSeeTag(String declaringClassQualifiedName,
470                         String methodName, String[] parameterTypesQualifiedNames) {
471                 StringBuffer buf = new StringBuffer();
472                 buf.append("@see "); //$NON-NLS-1$
473                 buf.append(declaringClassQualifiedName);
474                 buf.append('#');
475                 buf.append(methodName);
476                 buf.append('(');
477                 for (int i = 0; i < parameterTypesQualifiedNames.length; i++) {
478                         if (i > 0) {
479                                 buf.append(", "); //$NON-NLS-1$
480                         }
481                         buf.append(parameterTypesQualifiedNames[i]);
482                 }
483                 buf.append(')');
484                 return buf.toString();
485         }
486
487         private static String getSeeTag(IMethod overridden)
488                         throws JavaModelException {
489                 IType declaringType = overridden.getDeclaringType();
490                 StringBuffer buf = new StringBuffer();
491                 buf.append("@see "); //$NON-NLS-1$
492                 buf.append(declaringType.getFullyQualifiedName('.'));
493                 buf.append('#');
494                 buf.append(overridden.getElementName());
495                 buf.append('(');
496                 String[] paramTypes = overridden.getParameterTypes();
497                 for (int i = 0; i < paramTypes.length; i++) {
498                         if (i > 0) {
499                                 buf.append(", "); //$NON-NLS-1$
500                         }
501                         String curr = paramTypes[i];
502                         buf.append(JavaModelUtil.getResolvedTypeName(curr, declaringType));
503                         int arrayCount = Signature.getArrayCount(curr);
504                         while (arrayCount > 0) {
505                                 buf.append("[]"); //$NON-NLS-1$
506                                 arrayCount--;
507                         }
508                 }
509                 buf.append(')');
510                 return buf.toString();
511         }
512
513         /**
514          * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(IMethod,IMethod,String)
515          */
516         public static String getMethodComment(IMethod method, IMethod overridden,
517                         String lineDelimiter) throws CoreException {
518                 String retType = method.isConstructor() ? null : method.getReturnType();
519                 String[] paramNames = method.getParameterNames();
520
521                 return getMethodComment(method.getCompilationUnit(), method
522                                 .getDeclaringType().getElementName(), method.getElementName(),
523                                 paramNames, method.getExceptionTypes(), retType, overridden,
524                                 lineDelimiter);
525         }
526
527         /**
528          * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(ICompilationUnit,
529          *      String, String, String[], String[], String, IMethod, String)
530          */
531         public static String getMethodComment(ICompilationUnit cu, String typeName,
532                         String methodName, String[] paramNames, String[] excTypeSig,
533                         String retTypeSig, IMethod overridden, String lineDelimiter)
534                         throws CoreException {
535                 String templateName = CodeTemplateContextType.METHODCOMMENT;
536                 if (retTypeSig == null) {
537                         templateName = CodeTemplateContextType.CONSTRUCTORCOMMENT;
538                 } else if (overridden != null) {
539                         templateName = CodeTemplateContextType.OVERRIDECOMMENT;
540                 }
541                 Template template = PHPeclipsePlugin.getDefault()
542                                 .getCodeTemplateStore().findTemplate(templateName);
543                 if (template == null) {
544                         return null;
545                 }
546                 CodeTemplateContext context = new CodeTemplateContext(template
547                                 .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
548                 context.setCompilationUnitVariables(cu);
549                 context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
550                 context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
551                                 methodName);
552
553                 if (retTypeSig != null) {
554                         context.setVariable(CodeTemplateContextType.RETURN_TYPE, Signature
555                                         .toString(retTypeSig));
556                 }
557                 if (overridden != null) {
558                         context.setVariable(CodeTemplateContextType.SEE_TAG,
559                                         getSeeTag(overridden));
560                 }
561                 TemplateBuffer buffer;
562                 try {
563                         buffer = context.evaluate(template);
564                 } catch (BadLocationException e) {
565                         throw new CoreException(Status.CANCEL_STATUS);
566                 } catch (TemplateException e) {
567                         throw new CoreException(Status.CANCEL_STATUS);
568                 }
569                 if (buffer == null) {
570                         return null;
571                 }
572
573                 String str = buffer.getString();
574                 if (Strings.containsOnlyWhitespaces(str)) {
575                         return null;
576                 }
577                 TemplateVariable position = findTagVariable(buffer); // look if
578                                                                                                                                 // Javadoc tags
579                                                                                                                                 // have to be
580                                                                                                                                 // added
581                 if (position == null) {
582                         return str;
583                 }
584
585                 IDocument textBuffer = new Document(str);
586                 String[] exceptionNames = new String[excTypeSig.length];
587                 for (int i = 0; i < excTypeSig.length; i++) {
588                         exceptionNames[i] = Signature.toString(excTypeSig[i]);
589                 }
590                 String returnType = retTypeSig != null ? Signature.toString(retTypeSig)
591                                 : null;
592                 int[] tagOffsets = position.getOffsets();
593                 for (int i = tagOffsets.length - 1; i >= 0; i--) { // from last to
594                                                                                                                         // first
595                         try {
596                                 insertTag(textBuffer, tagOffsets[i], position.getLength(),
597                                                 paramNames, exceptionNames, returnType, false,
598                                                 lineDelimiter);
599                         } catch (BadLocationException e) {
600                                 throw new CoreException(PHPUIStatus.createError(IStatus.ERROR,
601                                                 e));
602                         }
603                 }
604                 return textBuffer.get();
605         }
606
607         public static String getFieldComment(ICompilationUnit cu, String typeName,
608                         String fieldName, String lineDelimiter) throws CoreException {
609                 Template template = PHPeclipsePlugin.getDefault()
610                                 .getCodeTemplateStore().findTemplate(
611                                                 CodeTemplateContextType.FIELDCOMMENT);
612                 if (template == null) {
613                         return null;
614                 }
615                 CodeTemplateContext context = new CodeTemplateContext(template
616                                 .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
617                 context.setCompilationUnitVariables(cu);
618                 context.setVariable(CodeTemplateContextType.FIELD_TYPE, typeName);
619                 context.setVariable(CodeTemplateContextType.FIELD, fieldName);
620
621                 return evaluateTemplate(context, template);
622         }
623
624         /**
625          * @see net.sourceforge.phpdt.ui.CodeGeneration#getSetterComment(ICompilationUnit,
626          *      String, String, String, String, String, String, String)
627          */
628         public static String getSetterComment(ICompilationUnit cu, String typeName,
629                         String methodName, String fieldName, String fieldType,
630                         String paramName, String bareFieldName, String lineDelimiter)
631                         throws CoreException {
632                 String templateName = CodeTemplateContextType.SETTERCOMMENT;
633                 Template template = PHPeclipsePlugin.getDefault()
634                                 .getCodeTemplateStore().findTemplate(templateName);
635                 if (template == null) {
636                         return null;
637                 }
638
639                 CodeTemplateContext context = new CodeTemplateContext(template
640                                 .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
641                 context.setCompilationUnitVariables(cu);
642                 context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
643                 context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
644                                 methodName);
645                 context.setVariable(CodeTemplateContextType.FIELD, fieldName);
646                 context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
647                 context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME,
648                                 bareFieldName);
649                 context.setVariable(CodeTemplateContextType.PARAM, paramName);
650
651                 return evaluateTemplate(context, template);
652         }
653
654         /**
655          * @see net.sourceforge.phpdt.ui.CodeGeneration#getGetterComment(ICompilationUnit,
656          *      String, String, String, String, String, String)
657          */
658         public static String getGetterComment(ICompilationUnit cu, String typeName,
659                         String methodName, String fieldName, String fieldType,
660                         String bareFieldName, String lineDelimiter) throws CoreException {
661                 String templateName = CodeTemplateContextType.GETTERCOMMENT;
662                 Template template = PHPeclipsePlugin.getDefault()
663                                 .getCodeTemplateStore().findTemplate(templateName);
664                 if (template == null) {
665                         return null;
666                 }
667                 CodeTemplateContext context = new CodeTemplateContext(template
668                                 .getContextTypeId(), cu.getJavaProject(), lineDelimiter);
669                 context.setCompilationUnitVariables(cu);
670                 context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
671                 context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
672                                 methodName);
673                 context.setVariable(CodeTemplateContextType.FIELD, fieldName);
674                 context.setVariable(CodeTemplateContextType.FIELD_TYPE, fieldType);
675                 context.setVariable(CodeTemplateContextType.BARE_FIELD_NAME,
676                                 bareFieldName);
677
678                 return evaluateTemplate(context, template);
679         }
680
681         public static String evaluateTemplate(CodeTemplateContext context,
682                         Template template) throws CoreException {
683                 TemplateBuffer buffer;
684                 try {
685                         buffer = context.evaluate(template);
686                 } catch (BadLocationException e) {
687                         throw new CoreException(Status.CANCEL_STATUS);
688                 } catch (TemplateException e) {
689                         throw new CoreException(Status.CANCEL_STATUS);
690                 }
691                 if (buffer == null)
692                         return null;
693                 String str = buffer.getString();
694                 if (Strings.containsOnlyWhitespaces(str)) {
695                         return null;
696                 }
697                 return str;
698         }
699
700         /**
701          * @see net.sourceforge.phpdt.ui.CodeGeneration#getMethodComment(ICompilationUnit,
702          *      String, MethodDeclaration, IMethodBinding, String)
703          */
704         // public static String getMethodComment(ICompilationUnit cu, String
705         // typeName, IMethodBinding overridden, String lineDelimiter) throws
706         // CoreException {
707         // if (overridden != null) {
708         // String declaringClassQualifiedName=
709         // overridden.getDeclaringClass().getQualifiedName();
710         // String[] parameterTypesQualifiedNames=
711         // getParameterTypesQualifiedNames(overridden);
712         // return getMethodComment(cu, typeName, decl, true,
713         // overridden.isDeprecated(), declaringClassQualifiedName,
714         // parameterTypesQualifiedNames, lineDelimiter);
715         // } else {
716         // return getMethodComment(cu, typeName, decl, false, false, null, null,
717         // lineDelimiter);
718         // }
719         // }
720         /**
721          * Returns the comment for a method using the comment code templates.
722          * <code>null</code> is returned if the template is empty.
723          * 
724          * @param cu
725          *            The compilation unit to which the method belongs
726          * @param typeName
727          *            Name of the type to which the method belongs.
728          * @param decl
729          *            The AST MethodDeclaration node that will be added as new
730          *            method.
731          * @param isOverridden
732          *            <code>true</code> iff decl overrides another method
733          * @param isDeprecated
734          *            <code>true</code> iff the method that decl overrides is
735          *            deprecated. Note: it must not be <code>true</code> if
736          *            isOverridden is <code>false</code>.
737          * @param declaringClassQualifiedName
738          *            Fully qualified name of the type in which the overriddden
739          *            method (if any exists) in declared. If isOverridden is
740          *            <code>false</code>, this is ignored.
741          * @param parameterTypesQualifiedNames
742          *            Fully qualified names of parameter types of the type in which
743          *            the overriddden method (if any exists) in declared. If
744          *            isOverridden is <code>false</code>, this is ignored.
745          * @return String Returns the method comment or <code>null</code> if the
746          *         configured template is empty. (formatting required)
747          * @throws CoreException
748          */
749         // public static String getMethodComment(ICompilationUnit cu, String
750         // typeName, MethodDeclaration decl, boolean isOverridden, boolean
751         // isDeprecated, String declaringClassQualifiedName, String[]
752         // parameterTypesQualifiedNames, String lineDelimiter) throws CoreException
753         // {
754         // String templateName= CodeTemplateContextType.METHODCOMMENT;
755         // if (decl.isConstructor()) {
756         // templateName= CodeTemplateContextType.CONSTRUCTORCOMMENT;
757         // } else if (isOverridden) {
758         // templateName= CodeTemplateContextType.OVERRIDECOMMENT;
759         // }
760         // Template template=
761         // PHPeclipsePlugin.getDefault().getCodeTemplateStore().findTemplate(templateName);
762         // if (template == null) {
763         // return null;
764         // }
765         // CodeTemplateContext context= new
766         // CodeTemplateContext(template.getContextTypeId(), cu.getJavaProject(),
767         // lineDelimiter);
768         // context.setCompilationUnitVariables(cu);
769         // context.setVariable(CodeTemplateContextType.ENCLOSING_TYPE, typeName);
770         // context.setVariable(CodeTemplateContextType.ENCLOSING_METHOD,
771         // decl.getName().getIdentifier());
772         // if (!decl.isConstructor()) {
773         // context.setVariable(CodeTemplateContextType.RETURN_TYPE,
774         // ASTNodes.asString(decl.getReturnType()));
775         // }
776         // if (isOverridden) {
777         // String methodName= decl.getName().getIdentifier();
778         // context.setVariable(CodeTemplateContextType.SEE_TAG,
779         // getSeeTag(declaringClassQualifiedName, methodName,
780         // parameterTypesQualifiedNames));
781         // }
782         //                      
783         // TemplateBuffer buffer;
784         // try {
785         // buffer= context.evaluate(template);
786         // } catch (BadLocationException e) {
787         // throw new CoreException(Status.CANCEL_STATUS);
788         // } catch (TemplateException e) {
789         // throw new CoreException(Status.CANCEL_STATUS);
790         // }
791         // if (buffer == null)
792         // return null;
793         // String str= buffer.getString();
794         // if (Strings.containsOnlyWhitespaces(str)) {
795         // return null;
796         // }
797         // TemplateVariable position= findTagVariable(buffer); // look if Javadoc
798         // tags have to be added
799         // if (position == null) {
800         // return str;
801         // }
802         //                              
803         // IDocument textBuffer= new Document(str);
804         // List params= decl.parameters();
805         // String[] paramNames= new String[params.size()];
806         // for (int i= 0; i < params.size(); i++) {
807         // SingleVariableDeclaration elem= (SingleVariableDeclaration)
808         // params.get(i);
809         // paramNames[i]= elem.getName().getIdentifier();
810         // }
811         // List exceptions= decl.thrownExceptions();
812         // String[] exceptionNames= new String[exceptions.size()];
813         // for (int i= 0; i < exceptions.size(); i++) {
814         // exceptionNames[i]= ASTNodes.getSimpleNameIdentifier((Name)
815         // exceptions.get(i));
816         // }
817         // String returnType= !decl.isConstructor() ?
818         // ASTNodes.asString(decl.getReturnType()) : null;
819         // int[] tagOffsets= position.getOffsets();
820         // for (int i= tagOffsets.length - 1; i >= 0; i--) { // from last to first
821         // try {
822         // insertTag(textBuffer, tagOffsets[i], position.getLength(), paramNames,
823         // exceptionNames, returnType, isDeprecated, lineDelimiter);
824         // } catch (BadLocationException e) {
825         // throw new CoreException(PHPUIStatus.createError(IStatus.ERROR, e));
826         // }
827         // }
828         // return textBuffer.get();
829         // }
830         private static TemplateVariable findTagVariable(TemplateBuffer buffer) {
831                 TemplateVariable[] positions = buffer.getVariables();
832                 for (int i = 0; i < positions.length; i++) {
833                         TemplateVariable curr = positions[i];
834                         if (CodeTemplateContextType.TAGS.equals(curr.getType())) {
835                                 return curr;
836                         }
837                 }
838                 return null;
839         }
840
841         private static void insertTag(IDocument textBuffer, int offset, int length,
842                         String[] paramNames, String[] exceptionNames, String returnType,
843                         boolean isDeprecated, String lineDelimiter)
844                         throws BadLocationException {
845                 IRegion region = textBuffer.getLineInformationOfOffset(offset);
846                 if (region == null) {
847                         return;
848                 }
849                 String lineStart = textBuffer.get(region.getOffset(), offset
850                                 - region.getOffset());
851
852                 StringBuffer buf = new StringBuffer();
853                 for (int i = 0; i < paramNames.length; i++) {
854                         if (buf.length() > 0) {
855                                 buf.append(lineDelimiter);
856                                 buf.append(lineStart);
857                         }
858                         buf.append("@param ");buf.append(paramNames[i]); //$NON-NLS-1$
859                 }
860                 if (returnType != null && !returnType.equals("void")) { //$NON-NLS-1$
861                         if (buf.length() > 0) {
862                                 buf.append(lineDelimiter);
863                                 buf.append(lineStart);
864                         }
865                         buf.append("@return"); //$NON-NLS-1$
866                 }
867                 if (exceptionNames != null) {
868                         for (int i = 0; i < exceptionNames.length; i++) {
869                                 if (buf.length() > 0) {
870                                         buf.append(lineDelimiter);
871                                         buf.append(lineStart);
872                                 }
873                                 buf.append("@throws ");buf.append(exceptionNames[i]); //$NON-NLS-1$
874                         }
875                 }
876                 if (isDeprecated) {
877                         if (buf.length() > 0) {
878                                 buf.append(lineDelimiter);
879                                 buf.append(lineStart);
880                         }
881                         buf.append("@deprecated"); //$NON-NLS-1$
882                 }
883                 textBuffer.replace(offset, length, buf.toString());
884         }
885
886         private static boolean isPrimitiveType(String typeName) {
887                 char first = Signature.getElementType(typeName).charAt(0);
888                 return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED);
889         }
890
891         private static String resolveAndAdd(String refTypeSig, IType declaringType)
892                         throws JavaModelException {// , IImportsStructure imports) throws
893                                                                                 // JavaModelException {
894                 String resolvedTypeName = JavaModelUtil.getResolvedTypeName(refTypeSig,
895                                 declaringType);
896                 if (resolvedTypeName != null) {
897                         StringBuffer buf = new StringBuffer();
898                         // if (imports != null) {
899                         // buf.append(imports.addImport(resolvedTypeName));
900                         // } else {
901                         buf.append(resolvedTypeName);
902                         // }
903                         int arrayCount = Signature.getArrayCount(refTypeSig);
904                         for (int i = 0; i < arrayCount; i++) {
905                                 buf.append("[]"); //$NON-NLS-1$
906                         }
907                         return buf.toString();
908                 }
909                 return Signature.toString(refTypeSig);
910         }
911
912         /**
913          * Finds a method in a list of methods.
914          * 
915          * @return The found method or null, if nothing found
916          */
917         private static IMethod findMethod(IMethod method, List allMethods)
918                         throws JavaModelException {
919                 String name = method.getElementName();
920                 String[] paramTypes = method.getParameterTypes();
921                 boolean isConstructor = method.isConstructor();
922
923                 for (int i = allMethods.size() - 1; i >= 0; i--) {
924                         IMethod curr = (IMethod) allMethods.get(i);
925                         if (JavaModelUtil.isSameMethodSignature(name, paramTypes,
926                                         isConstructor, curr)) {
927                                 return curr;
928                         }
929                 }
930                 return null;
931         }
932
933         /**
934          * Creates needed constructors for a type.
935          * 
936          * @param type
937          *            The type to create constructors for
938          * @param supertype
939          *            The type's super type
940          * @param settings
941          *            Options for comment generation
942          * @param imports
943          *            Required imports are added to the import structure. Structure
944          *            can be <code>null</code>, types are qualified then.
945          * @return Returns the generated stubs or <code>null</code> if the
946          *         creation has been canceled
947          */
948         // public static String[] evalConstructors(IType type, IType supertype,
949         // IImportsStructure imports) throws CoreException {
950         // IMethod[] superMethods= supertype.getMethods();
951         // String typeName= type.getElementName();
952         // ICompilationUnit cu= type.getCompilationUnit();
953         // IMethod[] methods= type.getMethods();
954         // GenStubSettings genStubSettings= new GenStubSettings(settings);
955         // genStubSettings.callSuper= true;
956         //                      
957         // ArrayList newMethods= new ArrayList(superMethods.length);
958         // for (int i= 0; i < superMethods.length; i++) {
959         // IMethod curr= superMethods[i];
960         // if (curr.isConstructor() && (JavaModelUtil.isVisibleInHierarchy(curr,
961         // type.getPackageFragment()))) {
962         // if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true,
963         // methods) == null) {
964         // genStubSettings.methodModifiers= Flags.AccPublic |
965         // JdtFlags.clearAccessModifiers(curr.getFlags());
966         // String newStub= genStub(cu, typeName, curr, curr.getDeclaringType(),
967         // genStubSettings, imports);
968         // newMethods.add(newStub);
969         // }
970         // }
971         // }
972         // return (String[]) newMethods.toArray(new String[newMethods.size()]);
973         // }
974         /**
975          * Returns all unimplemented constructors of a type including root type
976          * default constructors if there are no other superclass constructors
977          * unimplemented.
978          * 
979          * @param type
980          *            The type to create constructors for
981          * @return Returns the generated stubs or <code>null</code> if the
982          *         creation has been canceled
983          */
984         // public static IMethod[] getOverridableConstructors(IType type) throws
985         // CoreException {
986         // List constructorMethods= new ArrayList();
987         // ITypeHierarchy hierarchy= type.newSupertypeHierarchy(null);
988         // IType supertype= hierarchy.getSuperclass(type);
989         // if (supertype == null)
990         // return (new IMethod[0]);
991         //
992         // IMethod[] superMethods= supertype.getMethods();
993         // boolean constuctorFound= false;
994         // String typeName= type.getElementName();
995         // IMethod[] methods= type.getMethods();
996         // for (int i= 0; i < superMethods.length; i++) {
997         // IMethod curr= superMethods[i];
998         // if (curr.isConstructor()) {
999         // constuctorFound= true;
1000         // if (JavaModelUtil.isVisibleInHierarchy(curr, type.getPackageFragment()))
1001         // if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true,
1002         // methods) == null)
1003         // constructorMethods.add(curr);
1004         //                      
1005         // }
1006         // }
1007         //                      
1008         // // http://bugs.eclipse.org/bugs/show_bug.cgi?id=38487
1009         // if (!constuctorFound) {
1010         // IType objectType= type.getJavaProject().findType("java.lang.Object");
1011         // //$NON-NLS-1$
1012         // IMethod curr= objectType.getMethod("Object", EMPTY); //$NON-NLS-1$
1013         // if (JavaModelUtil.findMethod(typeName, curr.getParameterTypes(), true,
1014         // methods) == null) {
1015         // constructorMethods.add(curr);
1016         // }
1017         // }
1018         // return (IMethod[]) constructorMethods.toArray(new
1019         // IMethod[constructorMethods.size()]);
1020         // }
1021         /**
1022          * Returns all overridable methods of a type
1023          * 
1024          * @param type
1025          *            The type to search the overridable methods for
1026          * @param hierarchy
1027          *            The type hierarchy of the type
1028          * @param isSubType
1029          *            If set, the result can include methods of the passed type, if
1030          *            not only methods from super types are considered
1031          * @return Returns the all methods that can be overridden
1032          */
1033         // public static IMethod[] getOverridableMethods(IType type, ITypeHierarchy
1034         // hierarchy, boolean isSubType) throws JavaModelException {
1035         // List allMethods= new ArrayList();
1036         //
1037         // IMethod[] typeMethods= type.getMethods();
1038         // for (int i= 0; i < typeMethods.length; i++) {
1039         // IMethod curr= typeMethods[i];
1040         // if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) &&
1041         // !Flags.isPrivate(curr.getFlags())) {
1042         // allMethods.add(curr);
1043         // }
1044         // }
1045         //
1046         // IType[] superTypes= hierarchy.getAllSuperclasses(type);
1047         // for (int i= 0; i < superTypes.length; i++) {
1048         // IMethod[] methods= superTypes[i].getMethods();
1049         // for (int k= 0; k < methods.length; k++) {
1050         // IMethod curr= methods[k];
1051         // if (!curr.isConstructor() && !Flags.isStatic(curr.getFlags()) &&
1052         // !Flags.isPrivate(curr.getFlags())) {
1053         // if (findMethod(curr, allMethods) == null) {
1054         // allMethods.add(curr);
1055         // }
1056         // }
1057         // }
1058         // }
1059         //
1060         // IType[] superInterfaces= hierarchy.getAllSuperInterfaces(type);
1061         // for (int i= 0; i < superInterfaces.length; i++) {
1062         // IMethod[] methods= superInterfaces[i].getMethods();
1063         // for (int k= 0; k < methods.length; k++) {
1064         // IMethod curr= methods[k];
1065         //
1066         // // binary interfaces can contain static initializers (variable
1067         // intializations)
1068         // // 1G4CKUS
1069         // if (!Flags.isStatic(curr.getFlags())) {
1070         // IMethod impl= findMethod(curr, allMethods);
1071         // if (impl == null || !JavaModelUtil.isVisibleInHierarchy(impl,
1072         // type.getPackageFragment()) || prefereInterfaceMethod(hierarchy, curr,
1073         // impl)) {
1074         // if (impl != null) {
1075         // allMethods.remove(impl);
1076         // }
1077         // // implement an interface method when it does not exist in the hierarchy
1078         // // or when it throws less exceptions that the implemented
1079         // allMethods.add(curr);
1080         // }
1081         // }
1082         // }
1083         // }
1084         // if (!isSubType) {
1085         // allMethods.removeAll(Arrays.asList(typeMethods));
1086         // }
1087         // // remove finals
1088         // for (int i= allMethods.size() - 1; i >= 0; i--) {
1089         // IMethod curr= (IMethod) allMethods.get(i);
1090         // if (Flags.isFinal(curr.getFlags())) {
1091         // allMethods.remove(i);
1092         // }
1093         // }
1094         // return (IMethod[]) allMethods.toArray(new IMethod[allMethods.size()]);
1095         // }
1096         // private static boolean prefereInterfaceMethod(ITypeHierarchy hierarchy,
1097         // IMethod interfaceMethod, IMethod curr) throws JavaModelException {
1098         // if (Flags.isFinal(curr.getFlags())) {
1099         // return false;
1100         // }
1101         // IType interfaceType= interfaceMethod.getDeclaringType();
1102         // IType[] interfaces=
1103         // hierarchy.getAllSuperInterfaces(curr.getDeclaringType());
1104         // for (int i= 0; i < interfaces.length; i++) {
1105         // if (interfaces[i] == interfaceType) {
1106         // return false;
1107         // }
1108         // }
1109         // return curr.getExceptionTypes().length >
1110         // interfaceMethod.getExceptionTypes().length;
1111         // }
1112         /**
1113          * Generate method stubs for methods to overrride
1114          * 
1115          * @param type
1116          *            The type to search the overridable methods for
1117          * @param hierarchy
1118          *            The type hierarchy of the type
1119          * @param methodsToImplement
1120          *            Methods to override or implement
1121          * @param settings
1122          *            Options for comment generation
1123          * @param imports
1124          *            Required imports are added to the import structure. Structure
1125          *            can be <code>null</code>, types are qualified then.
1126          * @return Returns the generated stubs
1127          */
1128         // public static String[] genOverrideStubs(IMethod[] methodsToImplement,
1129         // IType type, ITypeHierarchy hierarchy, CodeGenerationSettings settings,
1130         // IImportsStructure imports) throws CoreException {
1131         // GenStubSettings genStubSettings= new GenStubSettings(settings);
1132         // genStubSettings.methodOverwrites= true;
1133         // ICompilationUnit cu= type.getCompilationUnit();
1134         // String[] result= new String[methodsToImplement.length];
1135         // for (int i= 0; i < methodsToImplement.length; i++) {
1136         // IMethod curr= methodsToImplement[i];
1137         // IMethod overrides=
1138         // JavaModelUtil.findMethodImplementationInHierarchy(hierarchy, type,
1139         // curr.getElementName(), curr.getParameterTypes(), curr.isConstructor());
1140         // if (overrides != null) {
1141         // genStubSettings.callSuper= true;
1142         // curr= overrides;
1143         // }
1144         // genStubSettings.methodModifiers= curr.getFlags();
1145         // IMethod desc= JavaModelUtil.findMethodDeclarationInHierarchy(hierarchy,
1146         // type, curr.getElementName(), curr.getParameterTypes(),
1147         // curr.isConstructor());
1148         // if (desc == null) {
1149         // desc= curr;
1150         // }
1151         // result[i]= genStub(cu, type.getElementName(), curr,
1152         // desc.getDeclaringType(), genStubSettings, imports);
1153         // }
1154         // return result;
1155         // }
1156         /**
1157          * Searches for unimplemented methods of a type.
1158          * 
1159          * @param isSubType
1160          *            If set, the evaluation is for a subtype of the given type. If
1161          *            not set, the evaluation is for the type itself.
1162          * @param settings
1163          *            Options for comment generation
1164          * @param imports
1165          *            Required imports are added to the import structure. Structure
1166          *            can be <code>null</code>, types are qualified then.
1167          * @return Returns the generated stubs or <code>null</code> if the
1168          *         creation has been canceled
1169          */
1170         // public static String[] evalUnimplementedMethods(IType type,
1171         // ITypeHierarchy hierarchy, boolean isSubType, CodeGenerationSettings
1172         // settings,
1173         // IImportsStructure imports) throws CoreException {
1174         //                                              
1175         // IMethod[] inheritedMethods= getOverridableMethods(type, hierarchy,
1176         // isSubType);
1177         //                      
1178         // List toImplement= new ArrayList();
1179         // for (int i= 0; i < inheritedMethods.length; i++) {
1180         // IMethod curr= inheritedMethods[i];
1181         // if (JdtFlags.isAbstract(curr)) {
1182         // toImplement.add(curr);
1183         // }
1184         // }
1185         // IMethod[] toImplementArray= (IMethod[]) toImplement.toArray(new
1186         // IMethod[toImplement.size()]);
1187         // return genOverrideStubs(toImplementArray, type, hierarchy, settings,
1188         // imports);
1189         // }
1190         /**
1191          * Examines a string and returns the first line delimiter found.
1192          */
1193         public static String getLineDelimiterUsed(IJavaElement elem)
1194                         throws JavaModelException {
1195                 ICompilationUnit cu = (ICompilationUnit) elem
1196                                 .getAncestor(IJavaElement.COMPILATION_UNIT);
1197                 if (cu != null && cu.exists()) {
1198                         IBuffer buf = cu.getBuffer();
1199                         int length = buf.getLength();
1200                         for (int i = 0; i < length; i++) {
1201                                 char ch = buf.getChar(i);
1202                                 if (ch == SWT.CR) {
1203                                         if (i + 1 < length) {
1204                                                 if (buf.getChar(i + 1) == SWT.LF) {
1205                                                         return "\r\n"; //$NON-NLS-1$
1206                                                 }
1207                                         }
1208                                         return "\r"; //$NON-NLS-1$
1209                                 } else if (ch == SWT.LF) {
1210                                         return "\n"; //$NON-NLS-1$
1211                                 }
1212                         }
1213                 }
1214                 return System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
1215         }
1216
1217         /**
1218          * Embodies the policy which line delimiter to use when inserting into a
1219          * document.
1220          */
1221         public static String getLineDelimiterFor(IDocument doc) {
1222                 // new for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in php editor
1223                 // inserts lines in wrong format
1224                 String lineDelim = null;
1225                 try {
1226                         lineDelim = doc.getLineDelimiter(0);
1227                 } catch (BadLocationException e) {
1228                 }
1229                 if (lineDelim == null) {
1230                         String systemDelimiter = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
1231                         String[] lineDelims = doc.getLegalLineDelimiters();
1232                         for (int i = 0; i < lineDelims.length; i++) {
1233                                 if (lineDelims[i].equals(systemDelimiter)) {
1234                                         lineDelim = systemDelimiter;
1235                                         break;
1236                                 }
1237                         }
1238                         if (lineDelim == null) {
1239                                 lineDelim = lineDelims.length > 0 ? lineDelims[0]
1240                                                 : systemDelimiter;
1241                         }
1242                 }
1243                 return lineDelim;
1244         }
1245
1246         /**
1247          * Evaluates the indention used by a Java element. (in tabulators)
1248          */
1249         // public static int getIndentUsed(IJavaElement elem) throws
1250         // JavaModelException {
1251         // if (elem instanceof ISourceReference) {
1252         // ICompilationUnit cu= (ICompilationUnit)
1253         // elem.getAncestor(IJavaElement.COMPILATION_UNIT);
1254         // if (cu != null) {
1255         // IBuffer buf= cu.getBuffer();
1256         // int offset= ((ISourceReference)elem).getSourceRange().getOffset();
1257         // int i= offset;
1258         // // find beginning of line
1259         // while (i > 0 && !Strings.isLineDelimiterChar(buf.getChar(i - 1)) ){
1260         // i--;
1261         // }
1262         // return Strings.computeIndent(buf.getText(i, offset - i),
1263         // CodeFormatterUtil.getTabWidth());
1264         // }
1265         // }
1266         // return 0;
1267         // }
1268         public static String codeFormat(String sourceString,
1269                         int initialIndentationLevel, String lineDelim) {
1270                 ICodeFormatter formatter = ToolFactory.createDefaultCodeFormatter(null);
1271                 return formatter.format(sourceString, initialIndentationLevel, null,
1272                                 lineDelim);
1273         }
1274
1275         /**
1276          * Returns the element after the give element.
1277          */
1278         // public static IJavaElement findNextSibling(IJavaElement member) throws
1279         // JavaModelException {
1280         // IJavaElement parent= member.getParent();
1281         // if (parent instanceof IParent) {
1282         // IJavaElement[] elements= ((IParent)parent).getChildren();
1283         // for (int i= elements.length - 2; i >= 0 ; i--) {
1284         // if (member.equals(elements[i])) {
1285         // return elements[i+1];
1286         // }
1287         // }
1288         // }
1289         // return null;
1290         // }
1291         //      
1292         public static String getTodoTaskTag(IJavaProject project) {
1293                 String markers = null;
1294                 if (project == null) {
1295                         markers = JavaCore.getOption(JavaCore.COMPILER_TASK_TAGS);
1296                 } else {
1297                         markers = project.getOption(JavaCore.COMPILER_TASK_TAGS, true);
1298                 }
1299
1300                 if (markers != null && markers.length() > 0) {
1301                         int idx = markers.indexOf(',');
1302                         if (idx == -1) {
1303                                 return markers;
1304                         } else {
1305                                 return markers.substring(0, idx);
1306                         }
1307                 }
1308                 return null;
1309         }
1310
1311         /*
1312          * Workarounds for bug 38111
1313          */
1314         // public static String[] getArgumentNameSuggestions(IJavaProject project,
1315         // String baseName, int dimensions, String[] excluded) {
1316         // String name= workaround38111(baseName);
1317         // String[] res= NamingConventions.suggestArgumentNames(project, "", name,
1318         // dimensions, excluded); //$NON-NLS-1$
1319         // return sortByLength(res); // longest first
1320         // }
1321         //               
1322         // public static String[] getFieldNameSuggestions(IJavaProject project,
1323         // String baseName, int dimensions, int modifiers, String[] excluded) {
1324         // String name= workaround38111(baseName);
1325         // String[] res= NamingConventions.suggestFieldNames(project, "", name,
1326         // dimensions, modifiers, excluded); //$NON-NLS-1$
1327         // return sortByLength(res); // longest first
1328         // }
1329         //      
1330         // public static String[] getLocalNameSuggestions(IJavaProject project,
1331         // String baseName, int dimensions, String[] excluded) {
1332         // String name= workaround38111(baseName);
1333         // String[] res= NamingConventions.suggestLocalVariableNames(project, "",
1334         // name, dimensions, excluded); //$NON-NLS-1$
1335         // return sortByLength(res); // longest first
1336         // }
1337         private static String[] sortByLength(String[] proposals) {
1338                 Arrays.sort(proposals, new Comparator() {
1339                         public int compare(Object o1, Object o2) {
1340                                 return ((String) o2).length() - ((String) o1).length();
1341                         }
1342                 });
1343                 return proposals;
1344         }
1345
1346         private static String workaround38111(String baseName) {
1347                 if (BASE_TYPES.contains(baseName))
1348                         return baseName;
1349                 return Character.toUpperCase(baseName.charAt(0))
1350                                 + baseName.substring(1);
1351         }
1352
1353         private static final List BASE_TYPES = Arrays
1354                         .asList(new String[] {
1355                                         "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$
1356
1357         public static String suggestArgumentName(IJavaProject project,
1358                         String baseName, String[] excluded) {
1359                 // String[] argnames= getArgumentNameSuggestions(project, baseName, 0,
1360                 // excluded);
1361                 // if (argnames.length > 0) {
1362                 // return argnames[0];
1363                 // }
1364                 return baseName;
1365         }
1366
1367         public static String[] suggestArgumentNames(IJavaProject project,
1368                         String[] paramNames) {
1369                 String prefixes = project.getOption(
1370                                 JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
1371                 String suffixes = project.getOption(
1372                                 JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
1373                 if (prefixes.length() + suffixes.length() == 0) {
1374                         return paramNames;
1375                 }
1376
1377                 String[] newNames = new String[paramNames.length];
1378                 // Ensure that the codegeneration preferences are respected
1379                 for (int i = 0; i < paramNames.length; i++) {
1380                         String curr = paramNames[i];
1381                         if (!hasPrefixOrSuffix(prefixes, suffixes, curr)) {
1382                                 newNames[i] = suggestArgumentName(project, paramNames[i], null);
1383                         } else {
1384                                 newNames[i] = curr;
1385                         }
1386                 }
1387                 return newNames;
1388         }
1389
1390         public static boolean hasFieldName(IJavaProject project, String name) {
1391                 String prefixes = project.getOption(JavaCore.CODEASSIST_FIELD_PREFIXES,
1392                                 true);
1393                 String suffixes = project.getOption(JavaCore.CODEASSIST_FIELD_SUFFIXES,
1394                                 true);
1395                 String staticPrefixes = project.getOption(
1396                                 JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, true);
1397                 String staticSuffixes = project.getOption(
1398                                 JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, true);
1399
1400                 return hasPrefixOrSuffix(prefixes, suffixes, name)
1401                                 || hasPrefixOrSuffix(staticPrefixes, staticSuffixes, name);
1402         }
1403
1404         public static boolean hasParameterName(IJavaProject project, String name) {
1405                 String prefixes = project.getOption(
1406                                 JavaCore.CODEASSIST_ARGUMENT_PREFIXES, true);
1407                 String suffixes = project.getOption(
1408                                 JavaCore.CODEASSIST_ARGUMENT_SUFFIXES, true);
1409                 return hasPrefixOrSuffix(prefixes, suffixes, name);
1410         }
1411
1412         public static boolean hasLocalVariableName(IJavaProject project, String name) {
1413                 String prefixes = project.getOption(JavaCore.CODEASSIST_LOCAL_PREFIXES,
1414                                 true);
1415                 String suffixes = project.getOption(JavaCore.CODEASSIST_LOCAL_SUFFIXES,
1416                                 true);
1417                 return hasPrefixOrSuffix(prefixes, suffixes, name);
1418         }
1419
1420         public static boolean hasConstantName(String name) {
1421                 return Character.isUpperCase(name.charAt(0));
1422         }
1423
1424         private static boolean hasPrefixOrSuffix(String prefixes, String suffixes,
1425                         String name) {
1426                 final String listSeparartor = ","; //$NON-NLS-1$
1427
1428                 StringTokenizer tok = new StringTokenizer(prefixes, listSeparartor);
1429                 while (tok.hasMoreTokens()) {
1430                         String curr = tok.nextToken();
1431                         if (name.startsWith(curr)) {
1432                                 return true;
1433                         }
1434                 }
1435
1436                 tok = new StringTokenizer(suffixes, listSeparartor);
1437                 while (tok.hasMoreTokens()) {
1438                         String curr = tok.nextToken();
1439                         if (name.endsWith(curr)) {
1440                                 return true;
1441                         }
1442                 }
1443                 return false;
1444         }
1445 }