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