KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > editor > codegen > GeneratorUtils


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.java.editor.codegen;
20
21 import com.sun.source.tree.AnnotationTree;
22 import com.sun.source.tree.AssignmentTree;
23 import com.sun.source.tree.BlockTree;
24 import com.sun.source.tree.ClassTree;
25 import com.sun.source.tree.ExpressionTree;
26 import com.sun.source.tree.IdentifierTree;
27 import com.sun.source.tree.MemberSelectTree;
28 import com.sun.source.tree.MethodInvocationTree;
29 import com.sun.source.tree.MethodTree;
30 import com.sun.source.tree.ModifiersTree;
31 import com.sun.source.tree.NewClassTree;
32 import com.sun.source.tree.StatementTree;
33 import com.sun.source.tree.Tree;
34 import com.sun.source.tree.TypeParameterTree;
35 import com.sun.source.tree.VariableTree;
36 import com.sun.source.util.TreePath;
37 import com.sun.source.util.TreePathScanner;
38 import com.sun.source.util.Trees;
39 import java.util.ArrayList JavaDoc;
40 import java.util.Collection JavaDoc;
41 import java.util.Collections JavaDoc;
42 import java.util.EnumSet JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.HashSet JavaDoc;
45 import java.util.Iterator JavaDoc;
46 import java.util.List JavaDoc;
47 import java.util.Map JavaDoc;
48 import java.util.Set JavaDoc;
49 import javax.lang.model.element.Element;
50 import javax.lang.model.element.ElementKind;
51 import javax.lang.model.element.ExecutableElement;
52 import javax.lang.model.element.Modifier;
53 import javax.lang.model.element.PackageElement;
54 import javax.lang.model.element.TypeElement;
55 import javax.lang.model.element.TypeParameterElement;
56 import javax.lang.model.element.VariableElement;
57 import javax.lang.model.type.DeclaredType;
58 import javax.lang.model.type.ExecutableType;
59 import javax.lang.model.type.TypeKind;
60 import javax.lang.model.type.TypeMirror;
61 import javax.lang.model.util.ElementFilter;
62 import javax.lang.model.util.Types;
63 import javax.lang.model.util.Types;
64 import org.netbeans.api.java.queries.SourceLevelQuery;
65 import org.netbeans.api.java.source.CompilationInfo;
66 import org.netbeans.api.java.source.ElementUtilities;
67 import org.netbeans.api.java.source.SourceUtils;
68 import org.netbeans.api.java.source.TreeMaker;
69 import org.netbeans.api.java.source.WorkingCopy;
70 import org.openide.ErrorManager;
71 import org.openide.filesystems.FileObject;
72
73 /**
74  *
75  * @author Jan Lahoda, Dusan Balek
76  */

77 public class GeneratorUtils {
78     
79     private static final ErrorManager ERR = ErrorManager.getDefault().getInstance(GeneratorUtils.class.getName());
80     public static final int GETTERS_ONLY = 1;
81     public static final int SETTERS_ONLY = 2;
82     
83     private GeneratorUtils() {
84     }
85     
86     public static ClassTree insertClassMember(WorkingCopy copy, ClassTree clazz, Tree member) {
87         int idx = 0;
88         for (Tree tree : clazz.getMembers()) {
89             if (ClassMemberComparator.compare(member, tree) < 0)
90                 break;
91             idx++;
92         }
93         return copy.getTreeMaker().insertClassMember(clazz, idx, member);
94     }
95     
96     public static List JavaDoc<? extends ExecutableElement> findUndefs(CompilationInfo info, TypeElement impl) {
97         if (ERR.isLoggable(ErrorManager.INFORMATIONAL))
98             ERR.log(ErrorManager.INFORMATIONAL, "findUndefs(" + info + ", " + impl + ")");
99         List JavaDoc<? extends ExecutableElement> undef = findUndefs(info, impl, impl);
100         if (ERR.isLoggable(ErrorManager.INFORMATIONAL))
101             ERR.log(ErrorManager.INFORMATIONAL, "undef=" + undef);
102         return undef;
103     }
104     
105     public static List JavaDoc<? extends ExecutableElement> findOverridable(CompilationInfo info, TypeElement impl) {
106         List JavaDoc<ExecutableElement> overridable = new ArrayList JavaDoc<ExecutableElement>();
107         List JavaDoc<TypeElement> classes = getAllClasses(impl);
108         
109         if (ERR.isLoggable(ErrorManager.INFORMATIONAL))
110             ERR.log(ErrorManager.INFORMATIONAL, "classes=" + classes);
111         
112         for (TypeElement te : classes.subList(1, classes.size())) {
113             for (ExecutableElement ee : ElementFilter.methodsIn(te.getEnclosedElements())) {
114                 Set JavaDoc<Modifier> set = EnumSet.copyOf(NOT_OVERRIDABLE);
115                 
116                 set.removeAll(ee.getModifiers());
117                 
118                 if (set.size() != NOT_OVERRIDABLE.size())
119                     continue;
120                 
121                 //TODO: cannot override a package private method outside the package
122

123                 int thisElement = classes.indexOf(te);
124                 
125                 if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) {
126                     ERR.log(ErrorManager.INFORMATIONAL, "ee=" + ee);
127                     ERR.log(ErrorManager.INFORMATIONAL, "thisElement = " + thisElement);
128                     ERR.log(ErrorManager.INFORMATIONAL, "classes.subList(0, thisElement + 1)=" + classes.subList(0, thisElement + 1));
129                     ERR.log(ErrorManager.INFORMATIONAL, "isOverriden(info, ee, classes.subList(0, thisElement + 1))=" + isOverriden(info, ee, classes.subList(0, thisElement + 1)));
130                 }
131                 
132                 if (!isOverriden(info, ee, classes.subList(0, thisElement + 1))) {
133                     overridable.add(ee);
134                 }
135             }
136         }
137         
138         return overridable;
139     }
140
141     public static Map JavaDoc<? extends TypeElement, ? extends List JavaDoc<? extends VariableElement>> findAllAccessibleFields(CompilationInfo info, TypeElement clazz) {
142         Map JavaDoc<TypeElement, List JavaDoc<? extends VariableElement>> result = new HashMap JavaDoc<TypeElement, List JavaDoc<? extends VariableElement>>();
143
144         result.put(clazz, findAllAccessibleFields(info, clazz, clazz));
145
146         for (TypeElement te : getAllParents(clazz)) {
147             result.put(te, findAllAccessibleFields(info, clazz, te));
148         }
149
150         return result;
151     }
152     
153     public static void scanForFieldsAndConstructors(CompilationInfo info, final TreePath clsPath, final Set JavaDoc<VariableElement> initializedFields, final Set JavaDoc<VariableElement> uninitializedFields, final List JavaDoc<ExecutableElement> constructors) {
154         final Trees trees = info.getTrees();
155         new TreePathScanner<Void JavaDoc, Boolean JavaDoc>() {
156             @Override JavaDoc
157             public Void JavaDoc visitVariable(VariableTree node, Boolean JavaDoc p) {
158                 Element el = trees.getElement(getCurrentPath());
159                 if (el != null && el.getKind() == ElementKind.FIELD && !el.getModifiers().contains(Modifier.STATIC) && node.getInitializer() == null && !initializedFields.remove(el))
160                     uninitializedFields.add((VariableElement)el);
161                 return null;
162             }
163             @Override JavaDoc
164             public Void JavaDoc visitAssignment(AssignmentTree node, Boolean JavaDoc p) {
165                 Element el = trees.getElement(new TreePath(getCurrentPath(), node.getVariable()));
166                 if (el != null && el.getKind() == ElementKind.FIELD && !uninitializedFields.remove(el))
167                     initializedFields.add((VariableElement)el);
168                 return null;
169             }
170             @Override JavaDoc
171             public Void JavaDoc visitClass(ClassTree node, Boolean JavaDoc p) {
172                 //do not analyse the inner classes:
173
return p ? super.visitClass(node, false) : null;
174             }
175             @Override JavaDoc
176             public Void JavaDoc visitMethod(MethodTree node, Boolean JavaDoc p) {
177                 Element el = trees.getElement(getCurrentPath());
178                 if (el != null && el.getKind() == ElementKind.CONSTRUCTOR)
179                     constructors.add((ExecutableElement)el);
180                 return null;
181             }
182         }.scan(clsPath, Boolean.TRUE);
183     }
184
185     public static void generateAllAbstractMethodImplementations(WorkingCopy wc, TreePath path) {
186         assert path.getLeaf().getKind() == Tree.Kind.CLASS;
187         TypeElement te = (TypeElement)wc.getTrees().getElement(path);
188         if (te != null) {
189             TreeMaker make = wc.getTreeMaker();
190             ClassTree clazz = (ClassTree)path.getLeaf();
191             List JavaDoc<Tree> members = new ArrayList JavaDoc<Tree>(clazz.getMembers());
192             for(ExecutableElement element : findUndefs(wc, te, te))
193                 members.add(createMethodImplementation(wc, element, (DeclaredType)te.asType()));
194             ClassTree nue = make.Class(clazz.getModifiers(), clazz.getSimpleName(), clazz.getTypeParameters(), clazz.getExtendsClause(), (List JavaDoc<ExpressionTree>)clazz.getImplementsClause(), members);
195             wc.rewrite(clazz, nue);
196         }
197     }
198     
199     public static void generateAbstractMethodImplementations(WorkingCopy wc, TreePath path, List JavaDoc<? extends ExecutableElement> elements, int index) {
200         assert path.getLeaf().getKind() == Tree.Kind.CLASS;
201         TypeElement te = (TypeElement)wc.getTrees().getElement(path);
202         if (te != null) {
203             TreeMaker make = wc.getTreeMaker();
204             ClassTree clazz = (ClassTree)path.getLeaf();
205             List JavaDoc<Tree> members = new ArrayList JavaDoc<Tree>(clazz.getMembers());
206             List JavaDoc<Tree> methods = new ArrayList JavaDoc<Tree>();
207             for(ExecutableElement element : elements)
208                 methods.add(createMethodImplementation(wc, element, (DeclaredType)te.asType()));
209             members.addAll(index, methods);
210             ClassTree nue = make.Class(clazz.getModifiers(), clazz.getSimpleName(), clazz.getTypeParameters(), clazz.getExtendsClause(), (List JavaDoc<ExpressionTree>)clazz.getImplementsClause(), members);
211             wc.rewrite(clazz, nue);
212         }
213     }
214     
215     public static void generateAbstractMethodImplementation(WorkingCopy wc, TreePath path, ExecutableElement element, int index) {
216         assert path.getLeaf().getKind() == Tree.Kind.CLASS;
217         TypeElement te = (TypeElement)wc.getTrees().getElement(path);
218         if (te != null) {
219             ClassTree decl = wc.getTreeMaker().insertClassMember((ClassTree)path.getLeaf(), index, createMethodImplementation(wc, element, (DeclaredType)te.asType()));
220             wc.rewrite(path.getLeaf(), decl);
221         }
222     }
223     
224     public static void generateMethodOverrides(WorkingCopy wc, TreePath path, List JavaDoc<? extends ExecutableElement> elements, int index) {
225         assert path.getLeaf().getKind() == Tree.Kind.CLASS;
226         TypeElement te = (TypeElement)wc.getTrees().getElement(path);
227         if (te != null) {
228             TreeMaker make = wc.getTreeMaker();
229             ClassTree clazz = (ClassTree)path.getLeaf();
230             List JavaDoc<Tree> members = new ArrayList JavaDoc<Tree>(clazz.getMembers());
231             List JavaDoc<Tree> methods = new ArrayList JavaDoc<Tree>();
232             for(ExecutableElement element : elements)
233                 methods.add(createMethodImplementation(wc, element, (DeclaredType)te.asType()));
234             members.addAll(index, methods);
235             ClassTree nue = make.Class(clazz.getModifiers(), clazz.getSimpleName(), clazz.getTypeParameters(), clazz.getExtendsClause(), (List JavaDoc<ExpressionTree>)clazz.getImplementsClause(), members);
236             wc.rewrite(clazz, nue);
237         }
238     }
239     
240     public static void generateMethodOverride(WorkingCopy wc, TreePath path, ExecutableElement element, int index) {
241         assert path.getLeaf().getKind() == Tree.Kind.CLASS;
242         TypeElement te = (TypeElement)wc.getTrees().getElement(path);
243         if (te != null) {
244             ClassTree decl = wc.getTreeMaker().insertClassMember((ClassTree)path.getLeaf(), index, createMethodImplementation(wc, element, (DeclaredType)te.asType()));
245             wc.rewrite(path.getLeaf(), decl);
246         }
247     }
248
249     public static void generateConstructor(WorkingCopy wc, TreePath path, Iterable JavaDoc<? extends VariableElement> initFields, ExecutableElement inheritedConstructor, int index) {
250         TreeMaker make = wc.getTreeMaker();
251         ClassTree clazz = (ClassTree)path.getLeaf();
252         List JavaDoc<VariableTree> parameters = new ArrayList JavaDoc<VariableTree>();
253         List JavaDoc<StatementTree> statements = new ArrayList JavaDoc<StatementTree>();
254         ModifiersTree parameterModifiers = make.Modifiers(EnumSet.noneOf(Modifier.class));
255         if (inheritedConstructor != null && !inheritedConstructor.getParameters().isEmpty()) {
256             List JavaDoc<ExpressionTree> arguments = new ArrayList JavaDoc<ExpressionTree>();
257             for (VariableElement ve : inheritedConstructor.getParameters()) {
258                 parameters.add(make.Variable(parameterModifiers, ve.getSimpleName(), make.Type(ve.asType()), null));
259                 arguments.add(make.Identifier(ve.getSimpleName())); //NOI18N
260
}
261             statements.add(make.ExpressionStatement(make.MethodInvocation(Collections.<ExpressionTree>emptyList(), make.Identifier("super"), arguments)));
262         }
263         for (VariableElement ve : initFields) {
264             parameters.add(make.Variable(parameterModifiers, ve.getSimpleName(), make.Type(ve.asType()), null));
265             statements.add(make.ExpressionStatement(make.Assignment(make.MemberSelect(make.Identifier("this"), ve.getSimpleName()), make.Identifier(ve.getSimpleName())))); //NOI18N
266
}
267         BlockTree body = make.Block(statements, false);
268         ClassTree decl = make.insertClassMember(clazz, index, make.Method(make.Modifiers(EnumSet.of(wc.getTreeUtilities().isEnum(clazz) ? Modifier.PRIVATE : Modifier.PUBLIC)), "<init>", null, Collections.<TypeParameterTree> emptyList(), parameters, Collections.<ExpressionTree>emptyList(), body, null)); //NOI18N
269
wc.rewrite(path.getLeaf(), decl);
270     }
271     
272     public static void generateGettersAndSetters(WorkingCopy wc, TreePath path, Iterable JavaDoc<? extends VariableElement> fields, int type, int index) {
273         assert path.getLeaf().getKind() == Tree.Kind.CLASS;
274         TypeElement te = (TypeElement)wc.getTrees().getElement(path);
275         if (te != null) {
276             TreeMaker make = wc.getTreeMaker();
277             ClassTree clazz = (ClassTree)path.getLeaf();
278             List JavaDoc<Tree> members = new ArrayList JavaDoc<Tree>(clazz.getMembers());
279             List JavaDoc<Tree> methods = new ArrayList JavaDoc<Tree>();
280             for(VariableElement element : fields) {
281                 if (type != SETTERS_ONLY)
282                     methods.add(createGetterMethod(wc, element, (DeclaredType)te.asType()));
283                 if (type != GETTERS_ONLY)
284                     methods.add(createSetterMethod(wc, element, (DeclaredType)te.asType()));
285             }
286             members.addAll(index, methods);
287             ClassTree nue = make.Class(clazz.getModifiers(), clazz.getSimpleName(), clazz.getTypeParameters(), clazz.getExtendsClause(), (List JavaDoc<ExpressionTree>)clazz.getImplementsClause(), members);
288             wc.rewrite(clazz, nue);
289         }
290     }
291     
292     public static boolean hasGetter(CompilationInfo info, VariableElement field, Map JavaDoc<String JavaDoc, List JavaDoc<ExecutableElement>> methods) {
293         CharSequence JavaDoc name = field.getSimpleName();
294         assert name.length() > 0;
295         TypeMirror type = field.asType();
296         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
297         sb.append(type.getKind() == TypeKind.BOOLEAN ? "is" : "get").append(Character.toUpperCase(name.charAt(0))).append(name.subSequence(1, name.length())); //NOI18N
298
Types types = info.getTypes();
299         List JavaDoc<ExecutableElement> candidates = methods.get(sb.toString());
300         if (candidates != null) {
301             for (ExecutableElement candidate : candidates) {
302                 if (candidate.getParameters().isEmpty() && types.isSameType(candidate.getReturnType(), type))
303                     return true;
304             }
305         }
306         return false;
307     }
308     
309     public static boolean hasSetter(CompilationInfo info, VariableElement field, Map JavaDoc<String JavaDoc, List JavaDoc<ExecutableElement>> methods) {
310         CharSequence JavaDoc name = field.getSimpleName();
311         assert name.length() > 0;
312         TypeMirror type = field.asType();
313         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
314         sb.append("set").append(Character.toUpperCase(name.charAt(0))).append(name.subSequence(1, name.length())); //NOI18N
315
Types types = info.getTypes();
316         List JavaDoc<ExecutableElement> candidates = methods.get(sb.toString());
317         if (candidates != null) {
318             for (ExecutableElement candidate : candidates) {
319                 if (candidate.getReturnType().getKind() == TypeKind.VOID && candidate.getParameters().size() == 1 && types.isSameType(candidate.getParameters().get(0).asType(), type))
320                     return true;
321             }
322         }
323         return false;
324     }
325     
326     private static MethodTree createMethodImplementation(WorkingCopy wc, ExecutableElement element, DeclaredType type) {
327         TreeMaker make = wc.getTreeMaker();
328         Set JavaDoc<Modifier> mods = element.getModifiers();
329         Set JavaDoc<Modifier> flags = mods.isEmpty() ? EnumSet.noneOf(Modifier.class) : EnumSet.copyOf(mods);
330         boolean isAbstract = flags.remove(Modifier.ABSTRACT);
331         flags.remove(Modifier.NATIVE);
332         
333         ExecutableType et = (ExecutableType)wc.getTypes().asMemberOf(type, element);
334         List JavaDoc<TypeParameterTree> typeParams = new ArrayList JavaDoc<TypeParameterTree>();
335         for (TypeParameterElement tpe: element.getTypeParameters()) {
336             List JavaDoc<ExpressionTree> bounds = new ArrayList JavaDoc<ExpressionTree>();
337             for (TypeMirror bound : tpe.getBounds()) {
338                 if (bound.getKind() != TypeKind.NULL) {
339                     //if the bound is java.lang.Object, do not generate the extends clause:
340
if (bound.getKind() != TypeKind.DECLARED || !"java.lang.Object".contentEquals(((TypeElement)((DeclaredType)bound).asElement()).getQualifiedName())) //NOI18N
341
bounds.add((ExpressionTree)make.Type(bound));
342                 }
343             }
344             typeParams.add(make.TypeParameter(tpe.getSimpleName(), bounds));
345         }
346
347         Tree returnType = make.Type(et.getReturnType());
348
349         List JavaDoc<VariableTree> params = new ArrayList JavaDoc<VariableTree>();
350         boolean isVarArgs = element.isVarArgs();
351         Iterator JavaDoc<? extends VariableElement> formArgNames = element.getParameters().iterator();
352         Iterator JavaDoc<? extends TypeMirror> formArgTypes = et.getParameterTypes().iterator();
353         ModifiersTree parameterModifiers = make.Modifiers(EnumSet.noneOf(Modifier.class));
354         while (formArgNames.hasNext() && formArgTypes.hasNext()) {
355             VariableElement formArgName = formArgNames.next();
356             TypeMirror formArgType = formArgTypes.next();
357             if (isVarArgs && !formArgNames.hasNext())
358                 parameterModifiers = make.Modifiers(1L<<34, Collections.<AnnotationTree>emptyList());
359             params.add(make.Variable(parameterModifiers, formArgName.getSimpleName(), make.Type(formArgType), null));
360         }
361
362         List JavaDoc<ExpressionTree> throwsList = new ArrayList JavaDoc<ExpressionTree>();
363         for (TypeMirror tm : et.getThrownTypes()) {
364             throwsList.add((ExpressionTree)make.Type(tm));
365         }
366         
367         BlockTree body;
368         List JavaDoc<AnnotationTree> annotations = new ArrayList JavaDoc<AnnotationTree>();
369         if (isAbstract) {
370             List JavaDoc<StatementTree> blockStatements = new ArrayList JavaDoc<StatementTree>();
371             TypeElement uoe = wc.getElements().getTypeElement("java.lang.UnsupportedOperationException"); //NOI18N
372
//TODO: if uoe == null: cannot resolve UnsupportedOperationException for some reason, create a different body in such a case
373
if (uoe != null) {
374                 NewClassTree nue = make.NewClass(null, Collections.<ExpressionTree>emptyList(), make.QualIdent(uoe), Collections.singletonList(make.Literal("Not supported yet.")), null);
375                 blockStatements.add(make.Throw(nue));
376             }
377             body = make.Block(blockStatements, false);
378         } else {
379             List JavaDoc<ExpressionTree> arguments = new ArrayList JavaDoc<ExpressionTree>();
380             for (VariableElement ve : element.getParameters()) {
381                 arguments.add(make.Identifier(ve.getSimpleName()));
382             }
383             MethodInvocationTree inv = make.MethodInvocation(Collections.<ExpressionTree>emptyList(), make.MemberSelect(make.Identifier("super"), element.getSimpleName()), arguments); //NOI18N
384
StatementTree statement = wc.getTypes().getNoType(TypeKind.VOID) == element.getReturnType() ?
385                 make.ExpressionStatement(inv) : make.Return(inv);
386             body = make.Block(Collections.singletonList(statement), false);
387             
388             //add @Override annotation if developing for 1.5:
389
if (GeneratorUtils.supportsOverride(wc.getFileObject())) {
390                 annotations.add(make.Annotation(make.Identifier("Override"), Collections.<ExpressionTree>emptyList())); //NOI18N
391
}
392         }
393
394         return make.Method(make.Modifiers(flags, annotations), element.getSimpleName(), returnType, typeParams, params, throwsList, body, null);
395     }
396     
397     private static MethodTree createGetterMethod(WorkingCopy wc, VariableElement element, DeclaredType type) {
398         TreeMaker make = wc.getTreeMaker();
399         Set JavaDoc<Modifier> mods = EnumSet.of(Modifier.PUBLIC);
400         if (element.getModifiers().contains(Modifier.STATIC))
401             mods.add(Modifier.STATIC);
402         CharSequence JavaDoc name = element.getSimpleName();
403         assert name.length() > 0;
404         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
405         sb.append(element.asType().getKind() == TypeKind.BOOLEAN ? "is" : "get").append(Character.toUpperCase(name.charAt(0))).append(name.subSequence(1, name.length())); //NOI18N
406
BlockTree body = make.Block(Collections.singletonList(make.Return(make.Identifier(element.getSimpleName()))), false);
407         return make.Method(make.Modifiers(mods), sb, make.Type(element.asType()), Collections.<TypeParameterTree>emptyList(), Collections.<VariableTree>emptyList(), Collections.<ExpressionTree>emptyList(), body, null);
408     }
409     
410     private static MethodTree createSetterMethod(WorkingCopy wc, VariableElement element, DeclaredType type) {
411         TreeMaker make = wc.getTreeMaker();
412         Set JavaDoc<Modifier> mods = EnumSet.of(Modifier.PUBLIC);
413         boolean isStatic = element.getModifiers().contains(Modifier.STATIC);
414         if (isStatic)
415             mods.add(Modifier.STATIC);
416         CharSequence JavaDoc name = element.getSimpleName();
417         assert name.length() > 0;
418         StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
419         sb.append("set").append(Character.toUpperCase(name.charAt(0))).append(name.subSequence(1, name.length())); //NOI18N
420
List JavaDoc<VariableTree> params = Collections.singletonList(make.Variable(make.Modifiers(EnumSet.noneOf(Modifier.class)), element.getSimpleName(), make.Type(element.asType()), null));
421         BlockTree body = make.Block(Collections.singletonList(make.ExpressionStatement(make.Assignment(make.MemberSelect(isStatic? make.Identifier(element.getEnclosingElement().getSimpleName()) : make.Identifier("this"), element.getSimpleName()), make.Identifier(element.getSimpleName())))), false); //NOI18N
422
return make.Method(make.Modifiers(mods), sb, make.Type(wc.getTypes().getNoType(TypeKind.VOID)), Collections.<TypeParameterTree>emptyList(), params, Collections.<ExpressionTree>emptyList(), body, null);
423     }
424     
425     private static List JavaDoc<? extends ExecutableElement> findUndefs(CompilationInfo info, TypeElement impl, TypeElement element) {
426         List JavaDoc<ExecutableElement> undef = new ArrayList JavaDoc<ExecutableElement>();
427         ElementUtilities eu = info.getElementUtilities();
428         if (element.getModifiers().contains(Modifier.ABSTRACT)) {
429             for (Element e : element.getEnclosedElements()) {
430                 if (e.getKind() == ElementKind.METHOD && e.getModifiers().contains(Modifier.ABSTRACT)) {
431                     ExecutableElement ee = (ExecutableElement)e;
432                     Element eeImpl = eu.getImplementationOf(ee, impl);
433                     if (eeImpl == null || eeImpl == ee)
434                         undef.add(ee);
435                 }
436             }
437         }
438         Types types = info.getTypes();
439         DeclaredType implType = (DeclaredType)impl.asType();
440         for (TypeMirror t : types.directSupertypes(element.asType())) {
441             for (ExecutableElement ee : findUndefs(info, impl, (TypeElement)((DeclaredType)t).asElement())) {
442                 //check if "the same" method has already been added:
443
boolean exists = false;
444                 TypeMirror eeType = types.asMemberOf(implType, ee);
445                 for (ExecutableElement existing : undef) {
446                     if (existing.getSimpleName().contentEquals(ee.getSimpleName())) {
447                         TypeMirror existingType = types.asMemberOf(implType, existing);
448                         if (types.isSameType(eeType, existingType)) {
449                             exists = true;
450                             break;
451                         }
452                     }
453                 }
454                 if (!exists)
455                     undef.add(ee);
456             }
457         }
458         return undef;
459     }
460     
461     private static List JavaDoc<? extends VariableElement> findAllAccessibleFields(CompilationInfo info, TypeElement accessibleFrom, TypeElement toScan) {
462         List JavaDoc<VariableElement> result = new ArrayList JavaDoc<VariableElement>();
463
464         for (VariableElement ve : ElementFilter.fieldsIn(toScan.getEnclosedElements())) {
465             //check if ve is accessible from accessibleFrom:
466
if (ve.getModifiers().contains(Modifier.PUBLIC)) {
467                 result.add(ve);
468                 continue;
469             }
470             if (ve.getModifiers().contains(Modifier.PRIVATE)) {
471                 if (accessibleFrom == toScan)
472                     result.add(ve);
473                 continue;
474             }
475             if (ve.getModifiers().contains(Modifier.PROTECTED)) {
476                 if (getAllParents(accessibleFrom).contains(toScan))
477                     result.add(ve);
478                 continue;
479             }
480             //TODO:package private:
481
}
482
483         return result;
484     }
485     
486     public static Collection JavaDoc<TypeElement> getAllParents(TypeElement of) {
487         Set JavaDoc<TypeElement> result = new HashSet JavaDoc<TypeElement>();
488         
489         for (TypeMirror t : of.getInterfaces()) {
490             TypeElement te = (TypeElement) ((DeclaredType)t).asElement();
491             
492             if (te != null) {
493                 result.add(te);
494                 result.addAll(getAllParents(te));
495             } else {
496                 if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) {
497                     ERR.log(ErrorManager.INFORMATIONAL, "te=null, t=" + t);
498                 }
499             }
500         }
501         
502         TypeMirror sup = of.getSuperclass();
503         TypeElement te = sup.getKind() == TypeKind.DECLARED ? (TypeElement) ((DeclaredType)sup).asElement() : null;
504         
505         if (te != null) {
506             result.add(te);
507             result.addAll(getAllParents(te));
508         } else {
509             if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) {
510                 ERR.log(ErrorManager.INFORMATIONAL, "te=null, t=" + of);
511             }
512         }
513         
514         return result;
515     }
516
517     public static boolean supportsOverride(FileObject file) {
518         return SUPPORTS_OVERRIDE_SOURCE_LEVELS.contains(SourceLevelQuery.getSourceLevel(file));
519     }
520     
521     private static final Set JavaDoc<String JavaDoc> SUPPORTS_OVERRIDE_SOURCE_LEVELS;
522     
523     static {
524         SUPPORTS_OVERRIDE_SOURCE_LEVELS = new HashSet JavaDoc();
525         
526         SUPPORTS_OVERRIDE_SOURCE_LEVELS.add("1.5");
527         SUPPORTS_OVERRIDE_SOURCE_LEVELS.add("1.6");
528     }
529     
530     private static List JavaDoc<TypeElement> getAllClasses(TypeElement of) {
531         List JavaDoc<TypeElement> result = new ArrayList JavaDoc<TypeElement>();
532         TypeMirror sup = of.getSuperclass();
533         TypeElement te = sup.getKind() == TypeKind.DECLARED ? (TypeElement) ((DeclaredType)sup).asElement() : null;
534         
535         result.add(of);
536         
537         if (te != null) {
538             result.addAll(getAllClasses(te));
539         } else {
540             if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) {
541                 ERR.log(ErrorManager.INFORMATIONAL, "te=null, t=" + of);
542             }
543         }
544         
545         return result;
546     }
547     
548     private static boolean isOverriden(CompilationInfo info, ExecutableElement methodBase, List JavaDoc<TypeElement> classes) {
549         if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) {
550             ERR.log(ErrorManager.INFORMATIONAL, "isOverriden(" + info + ", " + methodBase + ", " + classes + ")");
551         }
552         
553         for (TypeElement impl : classes) {
554             for (ExecutableElement methodImpl : ElementFilter.methodsIn(impl.getEnclosedElements())) {
555                 if ( ERR.isLoggable(ErrorManager.INFORMATIONAL)
556                 && info.getElements().overrides(methodImpl, methodBase, impl)) {
557                     ERR.log(ErrorManager.INFORMATIONAL, "overrides:");
558                     ERR.log(ErrorManager.INFORMATIONAL, "impl=" + impl);
559                     ERR.log(ErrorManager.INFORMATIONAL, "methodImpl=" + methodImpl);
560                 }
561                 
562                 if (info.getElements().overrides(methodImpl, methodBase, impl))
563                     return true;
564             }
565         }
566         
567         if (ERR.isLoggable(ErrorManager.INFORMATIONAL)) {
568             ERR.log(ErrorManager.INFORMATIONAL, "no overriding methods overrides:");
569         }
570         
571         return false;
572     }
573
574     private static final Set JavaDoc<Modifier> NOT_OVERRIDABLE = /*EnumSet.noneOf(Modifier.class);/*/EnumSet.of(Modifier.ABSTRACT, Modifier.STATIC, Modifier.FINAL);
575
576     public static boolean isAccessible(TypeElement from, Element what) {
577         if (what.getModifiers().contains(Modifier.PUBLIC))
578             return true;
579
580         TypeElement fromTopLevel = SourceUtils.getOutermostEnclosingTypeElement(from);
581         TypeElement whatTopLevel = SourceUtils.getOutermostEnclosingTypeElement(what);
582
583         if (fromTopLevel.equals(whatTopLevel))
584             return true;
585
586         if (what.getModifiers().contains(Modifier.PRIVATE))
587             return false;
588
589         if (what.getModifiers().contains(Modifier.PROTECTED)) {
590             if (getAllClasses(fromTopLevel).contains(SourceUtils.getEnclosingTypeElement(what)))
591                 return true;
592         }
593
594         //package private:
595
return ((PackageElement) fromTopLevel.getEnclosingElement()).getQualifiedName().toString().contentEquals(((PackageElement) whatTopLevel.getEnclosingElement()).getQualifiedName());
596     }
597     
598     private static class ClassMemberComparator {
599         
600         public static int compare(Tree tree1, Tree tree2) {
601             if (tree1 == tree2)
602                 return 0;
603             int importanceDiff = getSortPriority(tree1) - getSortPriority(tree2);
604             if (importanceDiff != 0)
605                 return importanceDiff;
606             int alphabeticalDiff = getSortText(tree1).compareTo(getSortText(tree2));
607             if (alphabeticalDiff != 0)
608                 return alphabeticalDiff;
609             return -1;
610         }
611         
612         private static int getSortPriority(Tree tree) {
613             int ret = 0;
614             ModifiersTree modifiers = null;
615             switch (tree.getKind()) {
616             case CLASS:
617                 ret = 400;
618                 modifiers = ((ClassTree)tree).getModifiers();
619                 break;
620             case METHOD:
621                 MethodTree mt = (MethodTree)tree;
622                 if (mt.getName().contentEquals("<init>"))
623                     ret = 200;
624                 else
625                     ret = 300;
626                 modifiers = mt.getModifiers();
627                 break;
628             case VARIABLE:
629                 ret = 100;
630                 modifiers = ((VariableTree)tree).getModifiers();
631                 break;
632             }
633             if (modifiers != null) {
634                 if (!modifiers.getFlags().contains(Modifier.STATIC))
635                     ret += 1000;
636                 if (modifiers.getFlags().contains(Modifier.PUBLIC))
637                     ret += 10;
638                 else if (modifiers.getFlags().contains(Modifier.PROTECTED))
639                     ret += 20;
640                 else if (modifiers.getFlags().contains(Modifier.PRIVATE))
641                     ret += 40;
642                 else
643                     ret += 30;
644             }
645             return ret;
646         }
647         
648         private static String JavaDoc getSortText(Tree tree) {
649             switch (tree.getKind()) {
650             case CLASS:
651                 return ((ClassTree)tree).getSimpleName().toString();
652             case METHOD:
653                 MethodTree mt = (MethodTree)tree;
654                 StringBuilder JavaDoc sortParams = new StringBuilder JavaDoc();
655                 sortParams.append('(');
656                 int cnt = 0;
657                 for(Iterator JavaDoc<? extends VariableTree> it = mt.getParameters().iterator(); it.hasNext();) {
658                     VariableTree param = it.next();
659                     if (param.getType().getKind() == Tree.Kind.IDENTIFIER)
660                         sortParams.append(((IdentifierTree)param.getType()).getName().toString());
661                     else if (param.getType().getKind() == Tree.Kind.MEMBER_SELECT)
662                         sortParams.append(((MemberSelectTree)param.getType()).getIdentifier().toString());
663                     if (it.hasNext()) {
664                         sortParams.append(',');
665                     }
666                     cnt++;
667                 }
668                 sortParams.append(')');
669                 return mt.getName().toString() + "#" + ((cnt < 10 ? "0" : "") + cnt) + "#" + sortParams.toString(); //NOI18N
670
case VARIABLE:
671                 return ((VariableTree)tree).getName().toString();
672             }
673             return ""; //NOI18N
674
}
675     }
676 }
677
Popular Tags