KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > apt > model > TypesImpl


1 /*******************************************************************************
2  * Copyright (c) 2007 BEA Systems, Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * wharley@bea.com - initial API and implementation
10  *
11  *******************************************************************************/

12
13 package org.eclipse.jdt.internal.compiler.apt.model;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.Collections JavaDoc;
17 import java.util.List JavaDoc;
18
19 import javax.lang.model.element.Element;
20 import javax.lang.model.element.TypeElement;
21 import javax.lang.model.type.ArrayType;
22 import javax.lang.model.type.DeclaredType;
23 import javax.lang.model.type.ExecutableType;
24 import javax.lang.model.type.NoType;
25 import javax.lang.model.type.NullType;
26 import javax.lang.model.type.PrimitiveType;
27 import javax.lang.model.type.TypeKind;
28 import javax.lang.model.type.TypeMirror;
29 import javax.lang.model.type.WildcardType;
30 import javax.lang.model.util.Types;
31
32 import org.eclipse.jdt.core.compiler.CharOperation;
33 import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
34 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
35 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
36 import org.eclipse.jdt.internal.compiler.lookup.Binding;
37 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
38 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
39 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
40 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
41 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
42
43 /**
44  * Utilities for working with types (as opposed to elements).
45  * There is one of these for every ProcessingEnvironment.
46  */

47 public class TypesImpl implements Types {
48
49     private final BaseProcessingEnvImpl _env;
50
51     /*
52      * The processing env creates and caches a TypesImpl. Other clients should
53      * not create their own; they should ask the env for it.
54      */

55     public TypesImpl(BaseProcessingEnvImpl env) {
56         _env = env;
57     }
58
59     /* (non-Javadoc)
60      * @see javax.lang.model.util.Types#asElement(javax.lang.model.type.TypeMirror)
61      */

62     @Override JavaDoc
63     public Element asElement(TypeMirror t) {
64         switch(t.getKind()) {
65             case DECLARED :
66             case TYPEVAR :
67                 return _env.getFactory().newElement(((TypeMirrorImpl)t).binding());
68         }
69         return null;
70     }
71
72     /* (non-Javadoc)
73      * @see javax.lang.model.util.Types#asMemberOf(javax.lang.model.type.DeclaredType, javax.lang.model.element.Element)
74      */

75     @Override JavaDoc
76     public TypeMirror asMemberOf(DeclaredType containing, Element element) {
77         // TODO Auto-generated method stub
78
// throw new UnsupportedOperationException("NYI: TypesImpl.asMemberOf(" + containing + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
79
ElementImpl elementImpl = (ElementImpl) element;
80         DeclaredTypeImpl declaredTypeImpl = (DeclaredTypeImpl) containing;
81         ReferenceBinding referenceBinding = (ReferenceBinding) declaredTypeImpl._binding;
82         switch(element.getKind()) {
83             case CONSTRUCTOR :
84             case METHOD :
85                 MethodBinding methodBinding = (MethodBinding) elementImpl._binding;
86                 if (methodBinding.declaringClass != referenceBinding) {
87                     throw new IllegalArgumentException JavaDoc("element is not valid for the containing declared type"); //$NON-NLS-1$
88
}
89                 for (MethodBinding method : referenceBinding.methods()) {
90                     if (CharOperation.equals(method.selector, methodBinding.selector)
91                             && method.areParameterErasuresEqual(methodBinding)) {
92                         return this._env.getFactory().newTypeMirror(method);
93                     }
94                 }
95                 break;
96             case FIELD :
97             case ENUM_CONSTANT:
98                 FieldBinding fieldBinding = (FieldBinding) elementImpl._binding;
99                 if (fieldBinding.declaringClass != referenceBinding) {
100                     throw new IllegalArgumentException JavaDoc("element is not valid for the containing declared type"); //$NON-NLS-1$
101
}
102                 for (FieldBinding field : referenceBinding.fields()) {
103                     if (CharOperation.equals(field.name, fieldBinding.name)) {
104                         return this._env.getFactory().newTypeMirror(field);
105                     }
106                 }
107                 break;
108             case ENUM :
109             case ANNOTATION_TYPE :
110             case INTERFACE :
111             case CLASS :
112                 ReferenceBinding referenceBinding2 = (ReferenceBinding) elementImpl._binding;
113                 if (referenceBinding2.enclosingType() != referenceBinding) {
114                     throw new IllegalArgumentException JavaDoc("element is not valid for the containing declared type"); //$NON-NLS-1$
115
}
116                 for (ReferenceBinding referenceBinding3 : referenceBinding.memberTypes()) {
117                     if (CharOperation.equals(referenceBinding3.compoundName, referenceBinding3.compoundName)) {
118                         return this._env.getFactory().newTypeMirror(referenceBinding3);
119                     }
120                 }
121                 break;
122         }
123         throw new IllegalArgumentException JavaDoc("element is not valid for the containing declared type: element kind " + element.getKind()); //$NON-NLS-1$
124
}
125
126     /* (non-Javadoc)
127      * @see javax.lang.model.util.Types#boxedClass(javax.lang.model.type.PrimitiveType)
128      */

129     @Override JavaDoc
130     public TypeElement boxedClass(PrimitiveType p) {
131         PrimitiveTypeImpl primitiveTypeImpl = (PrimitiveTypeImpl) p;
132         BaseTypeBinding baseTypeBinding = (BaseTypeBinding)primitiveTypeImpl._binding;
133         TypeBinding boxed = _env.getLookupEnvironment().computeBoxingType(baseTypeBinding);
134         return (TypeElement) _env.getFactory().newElement(boxed);
135     }
136
137     /* (non-Javadoc)
138      * @see javax.lang.model.util.Types#capture(javax.lang.model.type.TypeMirror)
139      */

140     @Override JavaDoc
141     public TypeMirror capture(TypeMirror t) {
142         // TODO Auto-generated method stub
143
throw new UnsupportedOperationException JavaDoc("NYI: TypesImpl.capture(...)"); //$NON-NLS-1$
144
}
145
146     /* (non-Javadoc)
147      * @see javax.lang.model.util.Types#contains(javax.lang.model.type.TypeMirror, javax.lang.model.type.TypeMirror)
148      */

149     @Override JavaDoc
150     public boolean contains(TypeMirror t1, TypeMirror t2) {
151         switch(t1.getKind()) {
152             case EXECUTABLE :
153             case PACKAGE :
154                 throw new IllegalArgumentException JavaDoc("Executable and package are illegal argument for Types.contains(..)"); //$NON-NLS-1$
155
}
156         switch(t2.getKind()) {
157             case EXECUTABLE :
158             case PACKAGE :
159                 throw new IllegalArgumentException JavaDoc("Executable and package are illegal argument for Types.contains(..)"); //$NON-NLS-1$
160
}
161         // TODO Auto-generated method stub
162
throw new UnsupportedOperationException JavaDoc("NYI: TypesImpl.contains(" + t1 + ", " + t2 + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
163
}
164
165     /* (non-Javadoc)
166      * @see javax.lang.model.util.Types#directSupertypes(javax.lang.model.type.TypeMirror)
167      */

168     @Override JavaDoc
169     public List JavaDoc<? extends TypeMirror> directSupertypes(TypeMirror t) {
170         switch(t.getKind()) {
171             case PACKAGE :
172             case EXECUTABLE :
173                 throw new IllegalArgumentException JavaDoc("Invalid type mirror for directSypertypes"); //$NON-NLS-1$
174
}
175         TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t;
176         Binding binding = typeMirrorImpl._binding;
177         if (binding instanceof ReferenceBinding) {
178             ReferenceBinding referenceBinding = (ReferenceBinding) binding;
179             ArrayList JavaDoc<TypeMirror> list = new ArrayList JavaDoc<TypeMirror>();
180             ReferenceBinding superclass = referenceBinding.superclass();
181             if (superclass != null) {
182                 list.add(this._env.getFactory().newTypeMirror(superclass));
183             }
184             for (ReferenceBinding interfaceBinding : referenceBinding.superInterfaces()) {
185                 list.add(this._env.getFactory().newTypeMirror(interfaceBinding));
186             }
187             return Collections.unmodifiableList(list);
188         }
189         return Collections.emptyList();
190     }
191
192     /* (non-Javadoc)
193      * @see javax.lang.model.util.Types#erasure(javax.lang.model.type.TypeMirror)
194      */

195     @Override JavaDoc
196     public TypeMirror erasure(TypeMirror t) {
197         TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) t;
198         Binding binding = typeMirrorImpl._binding;
199         if (binding instanceof ReferenceBinding) {
200             return _env.getFactory().newTypeMirror(((ReferenceBinding) binding).erasure());
201         }
202         // TODO should we return null or NoType ?
203
throw new UnsupportedOperationException JavaDoc("NYI: TypesImpl.erasure(...) when not a reference binding"); //$NON-NLS-1$
204
}
205
206     /* (non-Javadoc)
207      * @see javax.lang.model.util.Types#getArrayType(javax.lang.model.type.TypeMirror)
208      */

209     @Override JavaDoc
210     public ArrayType getArrayType(TypeMirror componentType) {
211         TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) componentType;
212         TypeBinding typeBinding = (TypeBinding) typeMirrorImpl._binding;
213         return new ArrayTypeImpl(_env, this._env.getLookupEnvironment().createArrayType(
214                 typeBinding.leafComponentType(),
215                 typeBinding.dimensions() + 1));
216     }
217
218     /* (non-Javadoc)
219      * @see javax.lang.model.util.Types#getDeclaredType(javax.lang.model.element.TypeElement, javax.lang.model.type.TypeMirror[])
220      */

221     @Override JavaDoc
222     public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) {
223         int typeArgsLength = typeArgs.length;
224         TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem;
225         ReferenceBinding referenceBinding = (ReferenceBinding) typeElementImpl._binding;
226         TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
227         int typeVariablesLength = typeVariables.length;
228         if (typeArgsLength == 0) {
229             if (referenceBinding.isGenericType()) {
230                 // must return a raw type
231
return _env.getFactory().newDeclaredType(this._env.getLookupEnvironment().createRawType(referenceBinding, null));
232             }
233             return (DeclaredType)typeElem.asType();
234         } else if (typeArgsLength != typeVariablesLength) {
235             throw new IllegalArgumentException JavaDoc("Number of typeArguments doesn't match the number of formal parameters of typeElem"); //$NON-NLS-1$
236
}
237         TypeBinding[] typeArguments = new TypeBinding[typeArgsLength];
238         for (int i = 0; i < typeArgsLength; i++) {
239             TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) typeArgs[i];
240             Binding binding = typeMirrorImpl._binding;
241             if (!(binding instanceof ReferenceBinding)) {
242                 throw new IllegalArgumentException JavaDoc("Invalid type for a type arguments : " + typeMirrorImpl); //$NON-NLS-1$
243
}
244             typeArguments[i] = (ReferenceBinding) binding;
245         }
246         return _env.getFactory().newDeclaredType(
247                 this._env.getLookupEnvironment().createParameterizedType(referenceBinding, typeArguments, null));
248     }
249
250     /* (non-Javadoc)
251      * @see javax.lang.model.util.Types#getDeclaredType(javax.lang.model.type.DeclaredType, javax.lang.model.element.TypeElement, javax.lang.model.type.TypeMirror[])
252      */

253     @Override JavaDoc
254     public DeclaredType getDeclaredType(DeclaredType containing, TypeElement typeElem,
255             TypeMirror... typeArgs) {
256         int typeArgsLength = typeArgs.length;
257         TypeElementImpl typeElementImpl = (TypeElementImpl) typeElem;
258         ReferenceBinding referenceBinding = (ReferenceBinding) typeElementImpl._binding;
259         TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
260         int typeVariablesLength = typeVariables.length;
261         DeclaredTypeImpl declaredTypeImpl = (DeclaredTypeImpl) containing;
262         ReferenceBinding enclosingType = (ReferenceBinding) declaredTypeImpl._binding;
263         if (typeArgsLength == 0) {
264             if (referenceBinding.isGenericType()) {
265                 // must return a raw type
266
return _env.getFactory().newDeclaredType(this._env.getLookupEnvironment().createRawType(referenceBinding, enclosingType));
267             }
268             // TODO (see how to create a member type binding
269
throw new UnsupportedOperationException JavaDoc("NYI: TypesImpl.getDeclaredType(...) for member types"); //$NON-NLS-1$
270
} else if (typeArgsLength != typeVariablesLength) {
271             throw new IllegalArgumentException JavaDoc("Number of typeArguments doesn't match the number of formal parameters of typeElem"); //$NON-NLS-1$
272
}
273         TypeBinding[] typeArguments = new TypeBinding[typeArgsLength];
274         for (int i = 0; i < typeArgsLength; i++) {
275             TypeMirrorImpl typeMirrorImpl = (TypeMirrorImpl) typeArgs[i];
276             Binding binding = typeMirrorImpl._binding;
277             if (!(binding instanceof ReferenceBinding)) {
278                 throw new IllegalArgumentException JavaDoc("Invalid type for a type arguments : " + typeMirrorImpl); //$NON-NLS-1$
279
}
280             typeArguments[i] = (ReferenceBinding) binding;
281         }
282         return _env.getFactory().newDeclaredType(
283                 this._env.getLookupEnvironment().createParameterizedType(referenceBinding, typeArguments, enclosingType));
284     }
285
286     @Override JavaDoc
287     public NoType getNoType(TypeKind kind) {
288         return _env.getFactory().getNoType(kind);
289     }
290
291     /* (non-Javadoc)
292      * @see javax.lang.model.util.Types#getNullType()
293      */

294     @Override JavaDoc
295     public NullType getNullType() {
296         return _env.getFactory().getNullType();
297     }
298
299     /* (non-Javadoc)
300      * @see javax.lang.model.util.Types#getPrimitiveType(javax.lang.model.type.TypeKind)
301      */

302     @Override JavaDoc
303     public PrimitiveType getPrimitiveType(TypeKind kind) {
304         return _env.getFactory().getPrimitiveType(kind);
305     }
306
307     /* (non-Javadoc)
308      * @see javax.lang.model.util.Types#getWildcardType(javax.lang.model.type.TypeMirror, javax.lang.model.type.TypeMirror)
309      */

310     @Override JavaDoc
311     public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) {
312         if (extendsBound != null && superBound != null) {
313             throw new IllegalArgumentException JavaDoc("Extends and super bounds cannot be set at the same time"); //$NON-NLS-1$
314
}
315         if (extendsBound != null) {
316             TypeMirrorImpl extendsBoundMirrorType = (TypeMirrorImpl) extendsBound;
317             TypeBinding typeBinding = (TypeBinding) extendsBoundMirrorType._binding;
318             return new WildcardTypeImpl(_env, this._env.getLookupEnvironment().createWildcard(
319                     null,
320                     0,
321                     typeBinding,
322                     null,
323                     Wildcard.EXTENDS));
324         }
325         if (superBound != null) {
326             TypeMirrorImpl superBoundMirrorType = (TypeMirrorImpl) superBound;
327             TypeBinding typeBinding = (TypeBinding) superBoundMirrorType._binding;
328             return new WildcardTypeImpl(_env, this._env.getLookupEnvironment().createWildcard(
329                     null,
330                     0,
331                     typeBinding,
332                     null,
333                     Wildcard.SUPER));
334         }
335         return new WildcardTypeImpl(_env, this._env.getLookupEnvironment().createWildcard(
336                 null,
337                 0,
338                 null,
339                 null,
340                 Wildcard.UNBOUND));
341     }
342
343     /**
344      * @return true if a value of type t1 can be assigned to a variable of type t2, i.e., t2 = t1.
345      */

346     @Override JavaDoc
347     public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
348         if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) {
349             return false;
350         }
351         Binding b1 = ((TypeMirrorImpl)t1).binding();
352         Binding b2 = ((TypeMirrorImpl)t2).binding();
353         if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) {
354             // package, method, import, etc.
355
throw new IllegalArgumentException JavaDoc();
356         }
357         if (((TypeBinding)b1).isCompatibleWith((TypeBinding)b2)) {
358             return true;
359         }
360
361         TypeBinding convertedType = _env.getLookupEnvironment().computeBoxingType((TypeBinding)b1);
362         return null != convertedType && convertedType.isCompatibleWith((TypeBinding)b2);
363     }
364
365     /* (non-Javadoc)
366      * @see javax.lang.model.util.Types#isSameType(javax.lang.model.type.TypeMirror, javax.lang.model.type.TypeMirror)
367      */

368     @Override JavaDoc
369     public boolean isSameType(TypeMirror t1, TypeMirror t2) {
370         if (t1.getKind() == TypeKind.WILDCARD || t2.getKind() == TypeKind.WILDCARD) {
371             return false;
372         }
373         if (t1 == t2) {
374             return true;
375         }
376         if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) {
377             return false;
378         }
379         Binding b1 = ((TypeMirrorImpl)t1).binding();
380         Binding b2 = ((TypeMirrorImpl)t2).binding();
381         // Wildcard types are never equal, according to the spec of this method
382
return (b1 == b2 && b1.kind() != Binding.WILDCARD_TYPE);
383     }
384
385     /* (non-Javadoc)
386      * @see javax.lang.model.util.Types#isSubsignature(javax.lang.model.type.ExecutableType, javax.lang.model.type.ExecutableType)
387      */

388     @Override JavaDoc
389     public boolean isSubsignature(ExecutableType m1, ExecutableType m2) {
390         MethodBinding methodBinding1 = (MethodBinding) ((ExecutableTypeImpl) m1)._binding;
391         MethodBinding methodBinding2 = (MethodBinding) ((ExecutableTypeImpl) m2)._binding;
392         if (!CharOperation.equals(methodBinding1.selector, methodBinding2.selector))
393             return false;
394         return methodBinding1.areParameterErasuresEqual(methodBinding2) && methodBinding1.areTypeVariableErasuresEqual(methodBinding2);
395     }
396
397     /**
398      * @return true if t1 is a subtype of t2, or if t1 == t2.
399      */

400     @Override JavaDoc
401     public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
402         if (t1 instanceof NoTypeImpl) {
403             if (t2 instanceof NoTypeImpl) {
404                 return ((NoTypeImpl) t1).getKind() == ((NoTypeImpl) t2).getKind();
405             }
406             return false;
407         } else if (t2 instanceof NoTypeImpl) {
408             return false;
409         }
410         if (!(t1 instanceof TypeMirrorImpl) || !(t2 instanceof TypeMirrorImpl)) {
411             return false;
412         }
413         if (t1 == t2) {
414             return true;
415         }
416         Binding b1 = ((TypeMirrorImpl)t1).binding();
417         Binding b2 = ((TypeMirrorImpl)t2).binding();
418         if (b1 == b2) {
419             return true;
420         }
421         if (!(b1 instanceof TypeBinding) || !(b2 instanceof TypeBinding)) {
422             // package, method, import, etc.
423
return false;
424         }
425         if (b1.kind() == Binding.BASE_TYPE || b2.kind() == Binding.BASE_TYPE) {
426             if (b1.kind() != b2.kind()) {
427                 return false;
428             }
429             else {
430                 // for primitives, compatibility implies subtype
431
return ((TypeBinding)b1).isCompatibleWith((TypeBinding)b2);
432             }
433         }
434         // TODO: array types and reference types
435
throw new UnsupportedOperationException JavaDoc("NYI: TypesImpl.isSubtype(TypeMirror, TypeMirror) for array and reference types"); //$NON-NLS-1$
436
}
437
438     @Override JavaDoc
439     public PrimitiveType unboxedType(TypeMirror t) {
440         if (!(((TypeMirrorImpl)t)._binding instanceof ReferenceBinding)) {
441             // Not an unboxable type - could be primitive, array, not a type at all, etc.
442
throw new IllegalArgumentException JavaDoc("Given type mirror cannot be unboxed"); //$NON-NLS-1$
443
}
444         ReferenceBinding boxed = (ReferenceBinding)((TypeMirrorImpl)t)._binding;
445         TypeBinding unboxed = _env.getLookupEnvironment().computeBoxingType(boxed);
446         if (unboxed.kind() != Binding.BASE_TYPE) {
447             // No boxing conversion was found
448
throw new IllegalArgumentException JavaDoc();
449         }
450         return _env.getFactory().getPrimitiveType((BaseTypeBinding)unboxed);
451     }
452
453 }
454
Popular Tags