KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > java > source > TypeMirrorHandle


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.api.java.source;
20
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.List JavaDoc;
24 import javax.lang.model.element.Element;
25 import javax.lang.model.element.TypeElement;
26 import javax.lang.model.element.TypeParameterElement;
27 import javax.lang.model.type.ArrayType;
28 import javax.lang.model.type.DeclaredType;
29 import javax.lang.model.type.ErrorType;
30 import javax.lang.model.type.TypeKind;
31 import javax.lang.model.type.TypeMirror;
32 import javax.lang.model.type.TypeVariable;
33 import javax.lang.model.type.WildcardType;
34 import org.netbeans.api.java.source.CompilationInfo;
35
36 /**
37  * Represents a handle for {@link TypeMirror} which can be kept and later resolved
38  * by another javac. The Javac {@link TypeMirror}s are valid only in the single
39  * {@link javax.tools.CompilationTask} or single run of the
40  * {@link org.netbeans.api.java.source.CancellableTask}. If the client needs to
41  * keep a reference to the {@link TypeMirror} and use it in the other CancellableTask
42  * he has to serialize it into the {@link TypeMirrorHandle}.
43  * <div class="nonnormative">
44  * <p>
45  ** Typical usage of TypeMirrorHandle is:
46  * </p>
47  * <pre>
48  * final TypeMirrorHandle[] typeMirrorHandle = new TypeMirrorHandle[1];
49  * javaSource.runCompileControlTask(new CancellableTask<CompilationController>() {
50  * public void run(CompilationController compilationController) {
51  * parameter.toPhase(Phase.RESOLVED);
52  * CompilationUnitTree cu = compilationController.getTree ();
53  * TypeMirror type = getInterestingType(cu);
54  * typeMirrorHandle[0] = TypeMirrorHandle.create (type);
55  * }
56  * },priority);
57  *
58  * otherJavaSource.runCompileControlTask(new CancellableTask<CompilationController>() {
59  * public void run(CompilationController compilationController) {
60  * parameter.toPhase(Phase.RESOLVED);
61  * TypeMirror type = typeMirrorHandle[0].resolve (compilationController);
62  * ....
63  * }
64  * },priority);
65  * </pre>
66  * </div>
67  * Currently, not all the {@link TypeMirror} {@link TypeKind kinds} are supported by handle.
68  * The unsupported {@link TykeKind kinds} are: {@link TypeKind#EXECUTABLE}, {@link TypeKind#OTHER},
69  * and {@link TypeKind#PACKAGE}.
70  *
71  * @author Jan Lahoda, Dusan Balek
72  */

73 public final class TypeMirrorHandle<T extends TypeMirror> {
74
75     private TypeKind kind;
76     private ElementHandle<? extends Element> element;
77     private List JavaDoc<TypeMirrorHandle<? extends TypeMirror>> typeMirrors;
78     
79     private TypeMirrorHandle(TypeKind kind, ElementHandle<? extends Element> element, List JavaDoc<TypeMirrorHandle<? extends TypeMirror>> typeArguments) {
80         this.kind = kind;
81         this.element = element;
82         this.typeMirrors = typeArguments;
83     }
84
85     /**
86      * Factory method for creating {@link TypeMirrorHandle}.
87      * @param {@link TypeMirror} for which the {@link TypeMirrorHandle} should be created.
88      * Not all the {@link TypeMirror} {@link TypeKind kinds} are currently supported.
89      * The unsupported {@link TykeKind kinds} are: {@link TypeKind#EXECUTABLE}, {@link TypeKind#OTHER},
90      * and {@link TypeKind#PACKAGE}.
91      * @return a new {@link TypeMirrorHandle}
92      * @throws {@link IllegalArgumentException} if the {@link TypeMirror} is of an unsupported
93      * {@link TypeKind}.
94      */

95     public static <T extends TypeMirror> TypeMirrorHandle<T> create(T tm) {
96         TypeKind kind = tm.getKind();
97         ElementHandle<? extends Element> element = null;
98         List JavaDoc<TypeMirrorHandle<? extends TypeMirror>> typeMirrors = null;
99         switch (kind) {
100             case BOOLEAN:
101             case BYTE:
102             case CHAR:
103             case DOUBLE:
104             case FLOAT:
105             case INT:
106             case LONG:
107             case NONE:
108             case NULL:
109             case SHORT:
110             case VOID:
111                 break;
112             case DECLARED:
113                 DeclaredType dt = (DeclaredType)tm;
114                 TypeElement te = (TypeElement)dt.asElement();
115                 element = ElementHandle.create(te);
116                 if (te.getTypeParameters().isEmpty())
117                     break;
118                 List JavaDoc<? extends TypeMirror> targs = dt.getTypeArguments();
119                 if (!targs.isEmpty()) {
120                     TypeMirror targ = targs.get(0);
121                     if (targ.getKind() == TypeKind.TYPEVAR) {
122                         TypeParameterElement tpe = (TypeParameterElement)((TypeVariable)targ).asElement();
123                         if (tpe.getGenericElement() == dt.asElement())
124                             break;
125                     }
126                 }
127                 typeMirrors = new ArrayList JavaDoc<TypeMirrorHandle<? extends TypeMirror>>(targs.size());
128                 for (TypeMirror ta : targs)
129                     typeMirrors.add(create(ta));
130                 break;
131             case ARRAY:
132                 typeMirrors = Collections.<TypeMirrorHandle<? extends TypeMirror>>singletonList(TypeMirrorHandle.create(((ArrayType)tm).getComponentType()));
133                 break;
134             case TYPEVAR:
135                 TypeVariable tv = (TypeVariable)tm;
136                 element = ElementHandle.create(tv.asElement());
137                 typeMirrors = new ArrayList JavaDoc<TypeMirrorHandle<? extends TypeMirror>>();
138                 typeMirrors.add(tv.getLowerBound() != null ? TypeMirrorHandle.create(tv.getLowerBound()) : null);
139                 typeMirrors.add(tv.getUpperBound() != null ? TypeMirrorHandle.create(tv.getUpperBound()) : null);
140                 break;
141             case WILDCARD:
142                 WildcardType wt = (WildcardType)tm;
143                 typeMirrors = new ArrayList JavaDoc<TypeMirrorHandle<? extends TypeMirror>>();
144                 typeMirrors.add(wt.getExtendsBound() != null ? TypeMirrorHandle.create(wt.getExtendsBound()) : null);
145                 typeMirrors.add(wt.getSuperBound() != null ? TypeMirrorHandle.create(wt.getSuperBound()) : null);
146                 break;
147             case ERROR:
148                 ErrorType et = (ErrorType)tm;
149                 element = ElementHandle.create(et.asElement());
150                 break;
151             default:
152                 throw new IllegalArgumentException JavaDoc("Currently unsupported TypeKind: " + tm.getKind());
153         }
154         return new TypeMirrorHandle(kind, element, typeMirrors);
155     }
156     
157     /**
158      * Resolves an {@link TypeMirror} from the {@link TypeMirrorHandle}.
159      * @param {@link CompilationInfo} representing the {@link javax.tools.CompilationTask}
160      * in which the {@link TypeMirror} should be resolved.
161      * @return resolved subclass of {@link TypeMirror} or null if the type cannot be
162      * resolved in this {@link javax.tools.CompilationTask}.
163      */

164     public T resolve(CompilationInfo info) {
165         switch (kind) {
166             case BOOLEAN:
167             case BYTE:
168             case CHAR:
169             case DOUBLE:
170             case FLOAT:
171             case INT:
172             case LONG:
173             case SHORT:
174                 return (T)info.getTypes().getPrimitiveType(kind);
175             case NONE:
176             case VOID:
177                 return (T)info.getTypes().getNoType(kind);
178             case NULL:
179                 return (T)info.getTypes().getNullType();
180             case DECLARED:
181                 TypeElement te = (TypeElement)element.resolve(info);
182                 if (te == null)
183                     return null;
184                 if (typeMirrors == null)
185                     return (T)te.asType();
186                 List JavaDoc<TypeMirror> resolvedTypeArguments = new ArrayList JavaDoc<TypeMirror>();
187                 for (TypeMirrorHandle t : typeMirrors) {
188                     TypeMirror resolved = t.resolve(info);
189                     if (resolved == null)
190                         return null;
191                     resolvedTypeArguments.add(resolved);
192                 }
193                 return (T)info.getTypes().getDeclaredType(te, resolvedTypeArguments.toArray(new TypeMirror[resolvedTypeArguments.size()]));
194             case ARRAY:
195                 TypeMirror resolved = typeMirrors.get(0).resolve(info);
196                 if (resolved == null)
197                     return null;
198                 return (T)info.getTypes().getArrayType(resolved);
199             case TYPEVAR:
200                 Element e = element.resolve(info);
201                 if (!(e instanceof com.sun.tools.javac.code.Symbol.TypeSymbol))
202                     return null;
203                 TypeMirrorHandle<? extends TypeMirror> lBound = typeMirrors.get(0);
204                 TypeMirror lowerBound = lBound != null ? lBound.resolve(info) : null;
205                 TypeMirrorHandle<? extends TypeMirror> uBound = typeMirrors.get(1);
206                 TypeMirror upperBound = uBound != null ? uBound.resolve(info) : null;
207                 return (T)new com.sun.tools.javac.code.Type.TypeVar((com.sun.tools.javac.code.Symbol.TypeSymbol)e,
208                         (com.sun.tools.javac.code.Type)lowerBound, (com.sun.tools.javac.code.Type)upperBound);
209             case WILDCARD:
210                 TypeMirrorHandle<? extends TypeMirror> eBound = typeMirrors.get(0);
211                 TypeMirror extendsBound = eBound != null ? eBound.resolve(info) : null;
212                 TypeMirrorHandle<? extends TypeMirror> sBound = typeMirrors.get(1);
213                 TypeMirror superBound = sBound != null ? sBound.resolve(info) : null;
214                 return (T)info.getTypes().getWildcardType(extendsBound, superBound);
215             case ERROR:
216                 e = element.resolve(info);
217                 if (!(e instanceof com.sun.tools.javac.code.Symbol.ClassSymbol))
218                     return null;
219                 return (T)new com.sun.tools.javac.code.Type.ErrorType((com.sun.tools.javac.code.Symbol.ClassSymbol)e);
220             default:
221                 throw new IllegalStateException JavaDoc("Internal error: unknown TypeHandle kind: " + kind);
222         }
223     }
224     
225     /**
226      * Returns the {@link TypeKind} of this handle,
227      * it is the kind of the {@link TypeMirror} from which the handle
228      * was created.
229      * @return {@link TypeKind}
230      */

231     public TypeKind getKind () {
232         return this.kind;
233     }
234 }
235
Popular Tags