001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.core.ext.typeinfo;
017:
018: import com.google.gwt.core.ext.UnableToCompleteException;
019: import com.google.gwt.dev.util.Util;
020:
021: import java.io.UnsupportedEncodingException;
022: import java.lang.annotation.Annotation;
023: import java.util.ArrayList;
024: import java.util.HashSet;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Set;
028:
029: /**
030: * Type representing a Java class or interface type.
031: */
032: public class JRealClassType extends JClassType {
033:
034: private final Set<JClassType> allSubtypes = new HashSet<JClassType>();
035:
036: private final Annotations annotations = new Annotations();
037:
038: private final int bodyEnd;
039:
040: private final int bodyStart;
041:
042: private final CompilationUnitProvider cup;
043:
044: private final JPackage declaringPackage;
045:
046: private final int declEnd;
047:
048: private final int declStart;
049:
050: private final JClassType enclosingType;
051:
052: private final List<JClassType> interfaces = new ArrayList<JClassType>();
053:
054: private final boolean isInterface;
055:
056: private final boolean isLocalType;
057:
058: private String lazyHash;
059:
060: private String lazyQualifiedName;
061:
062: private final AbstractMembers members = new Members(this );
063:
064: private final HasMetaData metaData = new MetaData();
065:
066: private int modifierBits;
067:
068: private final String name;
069:
070: private final String nestedName;
071:
072: private final TypeOracle oracle;
073:
074: private JClassType super class;
075:
076: public JRealClassType(TypeOracle oracle,
077: CompilationUnitProvider cup, JPackage declaringPackage,
078: JClassType enclosingType, boolean isLocalType, String name,
079: int declStart, int declEnd, int bodyStart, int bodyEnd,
080: boolean isInterface) {
081: oracle.recordTypeInCompilationUnit(cup, this );
082: this .oracle = oracle;
083: this .cup = cup;
084: this .declaringPackage = declaringPackage;
085: this .enclosingType = enclosingType;
086: this .isLocalType = isLocalType;
087: this .name = name;
088: this .declStart = declStart;
089: this .declEnd = declEnd;
090: this .bodyStart = bodyStart;
091: this .bodyEnd = bodyEnd;
092: this .isInterface = isInterface;
093: if (enclosingType == null) {
094: // Add myself to my package.
095: //
096: declaringPackage.addType(this );
097: // The nested name of a top-level class is its simple name.
098: //
099: nestedName = name;
100: } else {
101: // Add myself to my enclosing type.
102: //
103: enclosingType.addNestedType(this );
104: // Compute my "nested name".
105: //
106: JClassType enclosing = enclosingType;
107: String nn = name;
108: do {
109: nn = enclosing.getSimpleSourceName() + "." + nn;
110: enclosing = enclosing.getEnclosingType();
111: } while (enclosing != null);
112: nestedName = nn;
113: }
114: }
115:
116: public void addAnnotations(
117: Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
118: annotations.addAnnotations(declaredAnnotations);
119: }
120:
121: public void addImplementedInterface(JClassType intf) {
122: assert (intf != null);
123: interfaces.add(intf);
124: }
125:
126: public void addMetaData(String tagName, String[] values) {
127: metaData.addMetaData(tagName, values);
128: }
129:
130: public void addModifierBits(int bits) {
131: modifierBits |= bits;
132: }
133:
134: @Override
135: public JConstructor findConstructor(JType[] paramTypes) {
136: return members.findConstructor(paramTypes);
137: }
138:
139: @Override
140: public JField findField(String name) {
141: return members.findField(name);
142: }
143:
144: @Override
145: public JMethod findMethod(String name, JType[] paramTypes) {
146: return members.findMethod(name, paramTypes);
147: }
148:
149: @Override
150: public JClassType findNestedType(String typeName) {
151: return members.findNestedType(typeName);
152: }
153:
154: public <T extends Annotation> T getAnnotation(
155: Class<T> annotationClass) {
156: return annotations.getAnnotation(annotationClass);
157: }
158:
159: public Annotation[] getAnnotations() {
160: return annotations.getAnnotations();
161: }
162:
163: public int getBodyEnd() {
164: return bodyEnd;
165: }
166:
167: public int getBodyStart() {
168: return bodyStart;
169: }
170:
171: public CompilationUnitProvider getCompilationUnit() {
172: return cup;
173: }
174:
175: @Override
176: public JConstructor getConstructor(JType[] paramTypes)
177: throws NotFoundException {
178: return members.getConstructor(paramTypes);
179: }
180:
181: @Override
182: public JConstructor[] getConstructors() {
183: return members.getConstructors();
184: }
185:
186: public Annotation[] getDeclaredAnnotations() {
187: return annotations.getDeclaredAnnotations();
188: }
189:
190: public JClassType getEnclosingType() {
191: return enclosingType;
192: }
193:
194: @Override
195: public JClassType getErasedType() {
196: return this ;
197: }
198:
199: @Override
200: public JField getField(String name) {
201: return members.getField(name);
202: }
203:
204: @Override
205: public JField[] getFields() {
206: return members.getFields();
207: }
208:
209: public JClassType[] getImplementedInterfaces() {
210: return interfaces.toArray(TypeOracle.NO_JCLASSES);
211: }
212:
213: @Override
214: public String getJNISignature() {
215: String typeName = nestedName.replace('.', '$');
216: String packageName = getPackage().getName().replace('.', '/');
217: if (packageName.length() > 0) {
218: packageName += "/";
219: }
220: return "L" + packageName + typeName + ";";
221: }
222:
223: public String[][] getMetaData(String tagName) {
224: return metaData.getMetaData(tagName);
225: }
226:
227: public String[] getMetaDataTags() {
228: return metaData.getMetaDataTags();
229: }
230:
231: @Override
232: public JMethod getMethod(String name, JType[] paramTypes)
233: throws NotFoundException {
234: return members.getMethod(name, paramTypes);
235: }
236:
237: @Override
238: public JMethod[] getMethods() {
239: return members.getMethods();
240: }
241:
242: public String getName() {
243: return nestedName;
244: }
245:
246: @Override
247: public JClassType getNestedType(String typeName)
248: throws NotFoundException {
249: return members.getNestedType(typeName);
250: }
251:
252: @Override
253: public JClassType[] getNestedTypes() {
254: return members.getNestedTypes();
255: }
256:
257: public TypeOracle getOracle() {
258: return oracle;
259: }
260:
261: @Override
262: public JMethod[] getOverloads(String name) {
263: return members.getOverloads(name);
264: }
265:
266: @Override
267: public JMethod[] getOverridableMethods() {
268: return members.getOverridableMethods();
269: }
270:
271: public JPackage getPackage() {
272: return declaringPackage;
273: }
274:
275: @Override
276: public String getQualifiedSourceName() {
277: if (lazyQualifiedName == null) {
278: JPackage pkg = getPackage();
279: if (!pkg.isDefault()) {
280: lazyQualifiedName = pkg.getName() + "."
281: + makeCompoundName(this );
282: } else {
283: lazyQualifiedName = makeCompoundName(this );
284: }
285: }
286: return lazyQualifiedName;
287: }
288:
289: @Override
290: public String getSimpleSourceName() {
291: return name;
292: }
293:
294: public JClassType[] getSubtypes() {
295: return allSubtypes.toArray(TypeOracle.NO_JCLASSES);
296: }
297:
298: public JClassType getSuperclass() {
299: return super class;
300: }
301:
302: public String getTypeHash() throws UnableToCompleteException {
303: if (lazyHash == null) {
304: char[] source = cup.getSource();
305: int length = declEnd - declStart + 1;
306: String s = new String(source, declStart, length);
307: try {
308: lazyHash = Util.computeStrongName(s
309: .getBytes(Util.DEFAULT_ENCODING));
310: } catch (UnsupportedEncodingException e) {
311: // Details, details...
312: throw new UnableToCompleteException();
313: }
314: }
315: return lazyHash;
316: }
317:
318: public boolean isAbstract() {
319: return 0 != (modifierBits & TypeOracle.MOD_ABSTRACT);
320: }
321:
322: public boolean isAnnotationPresent(
323: Class<? extends Annotation> annotationClass) {
324: return annotations.isAnnotationPresent(annotationClass);
325: }
326:
327: @Override
328: public JArrayType isArray() {
329: // intentional null
330: return null;
331: }
332:
333: @Override
334: public boolean isAssignableFrom(JClassType otherType) {
335: if (otherType == this ) {
336: return true;
337: }
338:
339: if (allSubtypes.contains(otherType)) {
340: // JGenericTypes should appear in the allSubtypes hierarchy - do nothing
341: return true;
342: } else if (this == getOracle().getJavaLangObject()) {
343: // This case handles the odd "every interface is an Object"
344: // but doesn't actually have Object as a superclass.
345: //
346: return true;
347: } else {
348: if (otherType.isTypeParameter() != null) {
349: return otherType.isAssignableTo(this );
350: }
351:
352: if (otherType.isWildcard() != null) {
353: return otherType.isAssignableTo(this );
354: }
355:
356: if (otherType.isGenericType() != null) {
357: return otherType.isAssignableTo(this );
358: }
359:
360: if (otherType.isRawType() != null) {
361: return otherType.isAssignableTo(this );
362: }
363:
364: if (otherType.isParameterized() != null) {
365: return otherType.isAssignableTo(this );
366: }
367:
368: // At this point we should only have JArrayTypes or JRealClassTypes from
369: // which we are not assignable.
370: return false;
371: }
372: }
373:
374: public boolean isAssignableTo(JClassType possibleSupertype) {
375: return possibleSupertype.isAssignableFrom(this );
376: }
377:
378: @Override
379: public JClassType isClass() {
380: return isInterface ? null : this ;
381: }
382:
383: /**
384: * Determines if the class can be constructed using a simple <code>new</code>
385: * operation. Specifically, the class must
386: * <ul>
387: * <li>be a class rather than an interface, </li>
388: * <li>have either no constructors or a parameterless constructor, and</li>
389: * <li>be a top-level class or a static nested class.</li>
390: * </ul>
391: *
392: * @return <code>true</code> if the type is default instantiable, or
393: * <code>false</code> otherwise
394: */
395: public boolean isDefaultInstantiable() {
396: if (isInterface() != null) {
397: return false;
398: }
399: if (getConstructors().length == 0) {
400: return true;
401: }
402: JConstructor ctor = findConstructor(TypeOracle.NO_JTYPES);
403: if (ctor != null) {
404: return true;
405: }
406: return false;
407: }
408:
409: @Override
410: public JEnumType isEnum() {
411: return null;
412: }
413:
414: @Override
415: public JGenericType isGenericType() {
416: return null;
417: }
418:
419: @Override
420: public JClassType isInterface() {
421: return isInterface ? this : null;
422: }
423:
424: /**
425: * Tests if this type is a local type (within a method).
426: *
427: * @return true if this type is a local type, whether it is named or
428: * anonymous.
429: */
430: public boolean isLocalType() {
431: return isLocalType;
432: }
433:
434: /**
435: * Tests if this type is contained within another type.
436: *
437: * @return true if this type has an enclosing type, false if this type is a
438: * top-level type
439: */
440: public boolean isMemberType() {
441: return enclosingType != null;
442: }
443:
444: @Override
445: public JParameterizedType isParameterized() {
446: // intentional null
447: return null;
448: }
449:
450: @Override
451: public JPrimitiveType isPrimitive() {
452: // intentional null
453: return null;
454: }
455:
456: public boolean isPrivate() {
457: return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
458: }
459:
460: public boolean isProtected() {
461: return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
462: }
463:
464: public boolean isPublic() {
465: return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
466: }
467:
468: @Override
469: public JRawType isRawType() {
470: // TODO Override in JGenericType?
471: return null;
472: }
473:
474: public boolean isStatic() {
475: return 0 != (modifierBits & TypeOracle.MOD_STATIC);
476: }
477:
478: @Override
479: public JWildcardType isWildcard() {
480: return null;
481: }
482:
483: @Override
484: public void setSuperclass(JClassType type) {
485: assert (type != null);
486: assert (isInterface() == null);
487: this .super class = type;
488: JRealClassType realSuperType;
489: if (type.isParameterized() != null) {
490: realSuperType = (JRealClassType) type.isParameterized()
491: .getBaseType();
492: } else if (type.isRawType() != null) {
493: realSuperType = type.isRawType().getGenericType();
494: } else {
495: realSuperType = (JRealClassType) type;
496: }
497: annotations.setParent(realSuperType.annotations);
498: }
499:
500: @Override
501: public String toString() {
502: if (isInterface) {
503: return "interface " + getQualifiedSourceName();
504: } else {
505: return "class " + getQualifiedSourceName();
506: }
507: }
508:
509: protected void acceptSubtype(JClassType me) {
510: // TODO(scottb): revisit
511: allSubtypes.add(me);
512: notifySuperTypesOf(me);
513: }
514:
515: @Override
516: protected void addConstructor(JConstructor ctor) {
517: members.addConstructor(ctor);
518: }
519:
520: @Override
521: protected void addField(JField field) {
522: members.addField(field);
523: }
524:
525: @Override
526: protected void addMethod(JMethod method) {
527: members.addMethod(method);
528: }
529:
530: @Override
531: protected void addNestedType(JClassType type) {
532: members.addNestedType(type);
533: }
534:
535: @Override
536: protected JClassType findNestedTypeImpl(String[] typeName, int index) {
537: return members.findNestedTypeImpl(typeName, index);
538: }
539:
540: protected int getModifierBits() {
541: return modifierBits;
542: }
543:
544: protected void getOverridableMethodsOnSuperclassesAndThisClass(
545: Map<String, JMethod> methodsBySignature) {
546: members
547: .getOverridableMethodsOnSuperclassesAndThisClass(methodsBySignature);
548: }
549:
550: /**
551: * Gets the methods declared in interfaces that this type extends. If this
552: * type is a class, its own methods are not added. If this type is an
553: * interface, its own methods are added. Used internally by
554: * {@link #getOverridableMethods()}.
555: *
556: * @param methodsBySignature
557: */
558: protected void getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(
559: Map<String, JMethod> methodsBySignature) {
560: members
561: .getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
562: }
563:
564: /**
565: * Tells this type's superclasses and superinterfaces about it.
566: */
567: protected void notifySuperTypesOf(JClassType me) {
568: // TODO(scottb): revisit
569: if (super class != null) {
570: super class.acceptSubtype(me);
571: }
572: for (int i = 0, n = interfaces.size(); i < n; ++i) {
573: JClassType intf = interfaces.get(i);
574: intf.acceptSubtype(me);
575: }
576: }
577:
578: protected void removeSubtype(JClassType me) {
579: // TODO(scottb): revisit
580: allSubtypes.remove(me);
581:
582: if (super class != null) {
583: super class.removeSubtype(me);
584: }
585:
586: for (int i = 0, n = interfaces.size(); i < n; ++i) {
587: JClassType intf = interfaces.get(i);
588:
589: intf.removeSubtype(me);
590: }
591: }
592:
593: @Override
594: JRealClassType getSubstitutedType(
595: JParameterizedType parameterizedType) {
596: return this ;
597: }
598:
599: void notifySuperTypes() {
600: notifySuperTypesOf(this );
601: }
602:
603: /**
604: * Removes references to this instance from all of its super types.
605: */
606: void removeFromSupertypes() {
607: removeSubtype(this);
608: }
609: }
|