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