| /* |
| * Copyright 2008 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.dev.javac.typemodel; |
| |
| import com.google.gwt.core.ext.typeinfo.JPrimitiveType; |
| import com.google.gwt.core.ext.typeinfo.JType; |
| import com.google.gwt.core.ext.typeinfo.NotFoundException; |
| import com.google.gwt.dev.util.collect.HashSet; |
| |
| import java.lang.annotation.Annotation; |
| import java.util.Collections; |
| import java.util.LinkedHashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * Type used to represent any non-primitive type. |
| */ |
| public abstract class JClassType implements |
| com.google.gwt.core.ext.typeinfo.JClassType { |
| |
| /** |
| * Returns all of the superclasses and superinterfaces for a given type |
| * including the type itself. The returned set maintains an internal |
| * breadth-first ordering of the type, followed by its interfaces (and their |
| * super-interfaces), then the supertype and its interfaces, and so on. |
| */ |
| protected static Set<JClassType> getFlattenedSuperTypeHierarchy( |
| JClassType type) { |
| Set<JClassType> flattened = type.flattenedSupertypes; |
| if (flattened == null) { |
| flattened = new LinkedHashSet<JClassType>(); |
| getFlattenedSuperTypeHierarchyRecursive(type, flattened); |
| // flattened.size() > 1 for all types other than Object |
| type.flattenedSupertypes = Collections.unmodifiableSet(flattened); |
| } |
| return flattened; |
| } |
| |
| /** |
| * Returns <code>true</code> if the rhs array type can be assigned to the lhs |
| * array type. |
| */ |
| private static boolean areArraysAssignable(JArrayType lhsType, |
| JArrayType rhsType) { |
| // areClassTypesAssignable should prevent us from getting here if the types |
| // are referentially equal. |
| assert (lhsType != rhsType); |
| |
| JType lhsComponentType = lhsType.getComponentType(); |
| JType rhsComponentType = rhsType.getComponentType(); |
| |
| if (lhsComponentType.isPrimitive() != null |
| || rhsComponentType.isPrimitive() != null) { |
| /* |
| * Arrays are referentially stable so there will only be one int[] no |
| * matter how many times it is referenced in the code. So, if either |
| * component type is a primitive then we know that we are not assignable. |
| */ |
| return false; |
| } |
| |
| assert (lhsComponentType instanceof JClassType); |
| assert (rhsComponentType instanceof JClassType); |
| |
| JClassType thisComponentClass = (JClassType) lhsComponentType; |
| JClassType subtypeComponentClass = (JClassType) rhsComponentType; |
| |
| return areClassTypesAssignable(thisComponentClass, subtypeComponentClass); |
| } |
| |
| /** |
| * Returns <code>true</code> if the rhsType can be assigned to the lhsType. |
| */ |
| private static boolean areClassTypesAssignable( |
| com.google.gwt.core.ext.typeinfo.JClassType lhsType, |
| com.google.gwt.core.ext.typeinfo.JClassType rhsType) { |
| // The supertypes of rhs will include rhs. |
| Set<JClassType> rhsSupertypes = getFlattenedSuperTypeHierarchy((JClassType) rhsType); |
| for (JClassType rhsSupertype : rhsSupertypes) { |
| if (areClassTypesAssignableNoSupers((JClassType) lhsType, rhsSupertype)) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Returns <code>true</code> if the lhs and rhs are assignable without |
| * consideration of the supertypes of the rhs. |
| * |
| * @param lhsType |
| * @param rhsType |
| * @return true if rhsType can be assigned to lhsType |
| */ |
| private static boolean areClassTypesAssignableNoSupers(JClassType lhsType, |
| JClassType rhsType) { |
| if (lhsType == rhsType) { |
| // Done, these are the same types. |
| return true; |
| } |
| |
| if (lhsType == lhsType.getOracle().getJavaLangObject()) { |
| // Done, any type can be assigned to object. |
| return true; |
| } |
| |
| /* |
| * Get the generic base type, if there is one, for the lhs type and convert |
| * it to a raw type if it is generic. |
| */ |
| if (lhsType.isGenericType() != null) { |
| lhsType = lhsType.isGenericType().getRawType(); |
| } |
| |
| if (rhsType.isGenericType() != null) { |
| // Treat the generic rhs type as a raw type. |
| rhsType = rhsType.isGenericType().getRawType(); |
| } |
| |
| // Check for JTypeParameters. |
| JTypeParameter lhsTypeParam = lhsType.isTypeParameter(); |
| JTypeParameter rhsTypeParam = rhsType.isTypeParameter(); |
| if (lhsTypeParam != null) { |
| JClassType[] lhsTypeBounds = lhsTypeParam.getBounds(); |
| for (JClassType lhsTypeBound : lhsTypeBounds) { |
| if (!areClassTypesAssignable(lhsTypeBound, rhsType)) { |
| // Done, the rhsType was not assignable to one of the bounds. |
| return false; |
| } |
| } |
| |
| // Done, the rhsType was assignable to all of the bounds. |
| return true; |
| } else if (rhsTypeParam != null) { |
| JClassType[] possibleSubtypeBounds = rhsTypeParam.getBounds(); |
| for (JClassType possibleSubtypeBound : possibleSubtypeBounds) { |
| if (areClassTypesAssignable(lhsType, possibleSubtypeBound)) { |
| // Done, at least one bound is assignable to this type. |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /* |
| * Check for JWildcards. We have not examined this part in great detail |
| * since there should not be top level wildcard types. |
| */ |
| JWildcardType lhsWildcard = lhsType.isWildcard(); |
| JWildcardType rhsWildcard = rhsType.isWildcard(); |
| if (lhsWildcard != null && rhsWildcard != null) { |
| // Both types are wildcards. |
| return areWildcardsAssignable(lhsWildcard, rhsWildcard); |
| } else if (lhsWildcard != null) { |
| // The lhs type is a wildcard but the rhs is not. |
| // ? extends T, U OR ? super T, U |
| JClassType[] lowerBounds = lhsWildcard.getLowerBounds(); |
| if (lowerBounds.length > 0) { |
| // ? super T will reach object no matter what the rhs type is |
| return true; |
| } else { |
| return areClassTypesAssignable(lhsWildcard.getFirstBound(), rhsType); |
| } |
| } |
| |
| // Check for JArrayTypes. |
| JArrayType lhsArray = lhsType.isArray(); |
| JArrayType rhsArray = rhsType.isArray(); |
| if (lhsArray != null) { |
| if (rhsArray == null) { |
| return false; |
| } else { |
| return areArraysAssignable(lhsArray, rhsArray); |
| } |
| } else if (rhsArray != null) { |
| // Safe although perhaps not necessary |
| return false; |
| } |
| |
| // Check for JParameterizedTypes and JRawTypes. |
| JMaybeParameterizedType lhsMaybeParameterized = lhsType.isMaybeParameterizedType(); |
| JMaybeParameterizedType rhsMaybeParameterized = rhsType.isMaybeParameterizedType(); |
| if (lhsMaybeParameterized != null && rhsMaybeParameterized != null) { |
| if (lhsMaybeParameterized.getBaseType() == rhsMaybeParameterized.getBaseType()) { |
| if (lhsMaybeParameterized.isRawType() != null |
| || rhsMaybeParameterized.isRawType() != null) { |
| /* |
| * Any raw type can be assigned to or from any parameterization of its |
| * generic type. |
| */ |
| return true; |
| } |
| |
| assert (lhsMaybeParameterized.isRawType() == null && rhsMaybeParameterized.isRawType() == null); |
| JParameterizedType lhsParameterized = lhsMaybeParameterized.isParameterized(); |
| JParameterizedType rhsParameterized = rhsMaybeParameterized.isParameterized(); |
| assert (lhsParameterized != null && rhsParameterized != null); |
| |
| return areTypeArgumentsAssignable(lhsParameterized, rhsParameterized); |
| } |
| } |
| |
| // Default to not being assignable. |
| return false; |
| } |
| |
| /** |
| * Returns <code>true</code> if the type arguments of the rhs parameterized |
| * type are assignable to the type arguments of the lhs parameterized type. |
| */ |
| private static boolean areTypeArgumentsAssignable(JParameterizedType lhsType, |
| JParameterizedType rhsType) { |
| // areClassTypesAssignable should prevent us from getting here if the types |
| // are referentially equal. |
| assert (lhsType != rhsType); |
| assert (lhsType.getBaseType() == rhsType.getBaseType()); |
| |
| JClassType[] lhsTypeArgs = lhsType.getTypeArgs(); |
| JClassType[] rhsTypeArgs = rhsType.getTypeArgs(); |
| JGenericType lhsBaseType = lhsType.getBaseType(); |
| |
| // Compare at least as many formal type parameters as are declared on the |
| // generic base type. gwt.typeArgs could cause more types to be included. |
| |
| JTypeParameter[] lhsTypeParams = lhsBaseType.getTypeParameters(); |
| for (int i = 0; i < lhsTypeParams.length; ++i) { |
| if (!doesTypeArgumentContain(lhsTypeArgs[i], rhsTypeArgs[i])) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Returns <code>true</code> if the rhsWildcard can be assigned to the |
| * lhsWildcard. This method does not consider supertypes of either lhs or rhs. |
| */ |
| private static boolean areWildcardsAssignable(JWildcardType lhsWildcard, |
| JWildcardType rhsWildcard) { |
| // areClassTypesAssignable should prevent us from getting here if the types |
| // are referentially equal. |
| assert (lhsWildcard != rhsWildcard); |
| assert (lhsWildcard != null && rhsWildcard != null); |
| |
| if (lhsWildcard.getLowerBounds().length > 0 |
| && rhsWildcard.getLowerBounds().length > 0) { |
| // lhsType: ? super T, rhsType ? super U |
| return areClassTypesAssignable(rhsWildcard.getFirstBound(), |
| lhsWildcard.getFirstBound()); |
| } else if (lhsWildcard.getUpperBounds().length > 0 |
| && lhsWildcard.getLowerBounds().length == 0 |
| && rhsWildcard.getUpperBounds().length > 0 |
| && rhsWildcard.getLowerBounds().length == 0) { |
| // lhsType: ? extends T, rhsType: ? extends U |
| return areClassTypesAssignable(lhsWildcard.getFirstBound(), |
| rhsWildcard.getFirstBound()); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * A restricted version of areClassTypesAssignable that is used for comparing |
| * the type arguments of parameterized types, where the lhsTypeArg is the |
| * container. |
| */ |
| private static boolean doesTypeArgumentContain(JClassType lhsTypeArg, |
| JClassType rhsTypeArg) { |
| if (lhsTypeArg == rhsTypeArg) { |
| return true; |
| } |
| |
| // Check for wildcard types |
| JWildcardType lhsWildcard = lhsTypeArg.isWildcard(); |
| JWildcardType rhsWildcard = rhsTypeArg.isWildcard(); |
| |
| if (lhsWildcard != null) { |
| if (rhsWildcard != null) { |
| return areWildcardsAssignable(lhsWildcard, rhsWildcard); |
| } else { |
| // LHS is a wildcard but the RHS is not. |
| if (lhsWildcard.getLowerBounds().length > 0) { |
| return areClassTypesAssignable(rhsTypeArg, |
| lhsWildcard.getFirstBound()); |
| } else { |
| return areClassTypesAssignable(lhsWildcard.getFirstBound(), |
| rhsTypeArg); |
| } |
| } |
| } |
| |
| /* |
| * At this point the arguments are not the same and they are not wildcards |
| * so, they cannot be assignable, Eh. |
| */ |
| return false; |
| } |
| |
| private static void getFlattenedSuperTypeHierarchyRecursive(JClassType type, |
| Set<JClassType> typesSeen) { |
| if (typesSeen.contains(type)) { |
| return; |
| } |
| typesSeen.add(type); |
| |
| // Check the interfaces |
| JClassType[] intfs = type.getImplementedInterfaces(); |
| for (JClassType intf : intfs) { |
| typesSeen.addAll(getFlattenedSuperTypeHierarchy(intf)); |
| } |
| |
| // Superclass |
| JClassType superclass = type.getSuperclass(); |
| if (superclass != null) { |
| typesSeen.addAll(getFlattenedSuperTypeHierarchy(superclass)); |
| } |
| } |
| |
| /** |
| * Cached set of supertypes for this type (including itself). If null, the set |
| * has not been calculated yet. |
| */ |
| private Set<JClassType> flattenedSupertypes; |
| |
| /** |
| * True if this type may be enhanced with server-only fields. This property is |
| * 'sticky' and may be set but not unset, since we need to generate the |
| * relevant RPC code for handling the server fields if there is any chance the |
| * class will be enhanced. |
| */ |
| private boolean isEnhanced = false; |
| |
| public JParameterizedType asParameterizationOf( |
| com.google.gwt.core.ext.typeinfo.JGenericType type) { |
| Set<JClassType> supertypes = getFlattenedSuperTypeHierarchy(this); |
| for (JClassType supertype : supertypes) { |
| JParameterizedType isParameterized = supertype.isParameterized(); |
| if (isParameterized != null && isParameterized.getBaseType() == type) { |
| return isParameterized; |
| } |
| |
| JRawType isRaw = supertype.isRawType(); |
| if (isRaw != null && isRaw.getBaseType() == type) { |
| return isRaw.asParameterizedByWildcards(); |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * All types use identity for comparison. |
| */ |
| @Override |
| public final boolean equals(Object obj) { |
| return super.equals(obj); |
| } |
| |
| /** |
| * Find an annotation on a type or on one of its superclasses or |
| * superinterfaces. |
| * <p> |
| * This provides semantics similar to that of |
| * {@link java.lang.annotation.Inherited} except that it checks all types to |
| * which this type is assignable. {@code @Inherited} only works on |
| * superclasses, not superinterfaces. |
| * <p> |
| * Annotations present on the superclass chain will be returned preferentially |
| * over those found in the superinterface hierarchy. Note that the annotation |
| * does not need to be tagged with {@code @Inherited} in order to be returned |
| * from the superclass chain. |
| * |
| * @param annotationType the type of the annotation to look for |
| * @return the desired annotation or <code>null</code> if the annotation is |
| * not present in the type's type hierarchy |
| */ |
| public <T extends Annotation> T findAnnotationInTypeHierarchy( |
| Class<T> annotationType) { |
| |
| // Remember what we've seen to avoid loops |
| Set<JClassType> seen = new HashSet<JClassType>(); |
| |
| // Work queue |
| List<JClassType> searchTypes = new LinkedList<JClassType>(); |
| searchTypes.add(this); |
| |
| T toReturn = null; |
| |
| while (!searchTypes.isEmpty()) { |
| JClassType current = searchTypes.remove(0); |
| |
| if (!seen.add(current)) { |
| continue; |
| } |
| |
| toReturn = current.getAnnotation(annotationType); |
| if (toReturn != null) { |
| /* |
| * First one wins. It might be desirable at some point to have a |
| * variation that can return more than one instance of the annotation if |
| * it is present on multiple supertypes. |
| */ |
| break; |
| } |
| |
| if (current.getSuperclass() != null) { |
| // Add the superclass at the front of the list |
| searchTypes.add(0, current.getSuperclass()); |
| } |
| |
| // Superinterfaces |
| Collections.addAll(searchTypes, current.getImplementedInterfaces()); |
| } |
| |
| return toReturn; |
| } |
| |
| public abstract JConstructor findConstructor(JType[] paramTypes); |
| |
| public abstract JField findField(String name); |
| |
| public abstract JMethod findMethod(String name, JType[] paramTypes); |
| |
| public abstract JClassType findNestedType(String typeName); |
| |
| public abstract <T extends Annotation> T getAnnotation( |
| Class<T> annotationClass); |
| |
| public abstract Annotation[] getAnnotations(); |
| |
| public abstract JConstructor getConstructor(JType[] paramTypes) |
| throws NotFoundException; |
| |
| public abstract JConstructor[] getConstructors(); |
| |
| public abstract Annotation[] getDeclaredAnnotations(); |
| |
| public abstract JClassType getEnclosingType(); |
| |
| public abstract JClassType getErasedType(); |
| |
| public abstract JField getField(String name); |
| |
| public abstract JField[] getFields(); |
| |
| /** |
| * Returns all of the superclasses and superinterfaces for a given type |
| * including the type itself. The returned set maintains an internal |
| * breadth-first ordering of the type, followed by its interfaces (and their |
| * super-interfaces), then the supertype and its interfaces, and so on. |
| */ |
| public Set<JClassType> getFlattenedSupertypeHierarchy() { |
| // Retuns an immutable set |
| return getFlattenedSuperTypeHierarchy(this); |
| } |
| |
| public abstract JClassType[] getImplementedInterfaces(); |
| |
| /** |
| * Iterates over the most-derived declaration of each unique inheritable |
| * method available in the type hierarchy of the specified type, including |
| * those found in superclasses and superinterfaces. A method is inheritable if |
| * its accessibility is <code>public</code>, <code>protected</code>, or |
| * package protected. |
| * |
| * This method offers a convenient way for Generators to find candidate |
| * methods to call from a subclass. |
| * |
| * @return an array of {@link JMethod} objects representing inheritable |
| * methods |
| */ |
| public abstract JMethod[] getInheritableMethods(); |
| |
| public abstract String getJNISignature(); |
| |
| public JType getLeafType() { |
| return this; |
| } |
| |
| @Deprecated |
| public final String[][] getMetaData(String tagName) { |
| return TypeOracle.NO_STRING_ARR_ARR; |
| } |
| |
| @Deprecated |
| public final String[] getMetaDataTags() { |
| return TypeOracle.NO_STRINGS; |
| } |
| |
| public abstract JMethod getMethod(String name, JType[] paramTypes) |
| throws NotFoundException; |
| |
| /* |
| * Returns the declared methods of this class (not any superclasses or |
| * superinterfaces). |
| */ |
| public abstract JMethod[] getMethods(); |
| |
| public abstract String getName(); |
| |
| public abstract JClassType getNestedType(String typeName) |
| throws NotFoundException; |
| |
| public abstract JClassType[] getNestedTypes(); |
| |
| public abstract TypeOracle getOracle(); |
| |
| public abstract JMethod[] getOverloads(String name); |
| |
| /** |
| * Iterates over the most-derived declaration of each unique overridable |
| * method available in the type hierarchy of the specified type, including |
| * those found in superclasses and superinterfaces. A method is overridable if |
| * it is not <code>final</code> and its accessibility is <code>public</code>, |
| * <code>protected</code>, or package protected. |
| * |
| * Deferred binding generators often need to generate method implementations; |
| * this method offers a convenient way to find candidate methods to implement. |
| * |
| * Note that the behavior does not match |
| * {@link Class#getMethod(String, Class[])}, which does not return the most |
| * derived method in some cases. |
| * |
| * @return an array of {@link JMethod} objects representing overridable |
| * methods |
| */ |
| public abstract JMethod[] getOverridableMethods(); |
| |
| public abstract JPackage getPackage(); |
| |
| public String getParameterizedQualifiedSourceName() { |
| return getQualifiedSourceName(); |
| } |
| |
| /** |
| * TODO(scottb): remove if we can resolve param names differently. |
| */ |
| public abstract String getQualifiedBinaryName(); |
| |
| public abstract String getQualifiedSourceName(); |
| |
| public abstract String getSimpleSourceName(); |
| |
| public abstract JClassType[] getSubtypes(); |
| |
| public abstract JClassType getSuperclass(); |
| |
| /** |
| * All types use identity for comparison. |
| */ |
| @Override |
| public final int hashCode() { |
| return super.hashCode(); |
| } |
| |
| public abstract boolean isAbstract(); |
| |
| /** |
| * Returns this instance if it is a annotation or <code>null</code> if it is |
| * not. |
| * |
| * @return this instance if it is a annotation or <code>null</code> if it is |
| * not |
| */ |
| public JAnnotationType isAnnotation() { |
| return null; |
| } |
| |
| public abstract boolean isAnnotationPresent( |
| Class<? extends Annotation> annotationClass); |
| |
| public abstract JArrayType isArray(); |
| |
| /** |
| * Returns <code>true</code> if this {@link JClassType} is assignable from the |
| * specified {@link JClassType} parameter. |
| * |
| * @param possibleSubtype possible subtype of this {@link JClassType} |
| * @return <code>true</code> if this {@link JClassType} is assignable from the |
| * specified {@link JClassType} parameter |
| * |
| * @throws NullPointerException if <code>possibleSubtype</code> is |
| * <code>null</code> |
| */ |
| public boolean isAssignableFrom( |
| com.google.gwt.core.ext.typeinfo.JClassType possibleSubtype) { |
| if (possibleSubtype == null) { |
| throw new NullPointerException("possibleSubtype"); |
| } |
| |
| return areClassTypesAssignable(this, possibleSubtype); |
| } |
| |
| /** |
| * Returns <code>true</code> if this {@link JClassType} is assignable to the |
| * specified {@link JClassType} parameter. |
| * |
| * @param possibleSupertype possible supertype of this {@link JClassType} |
| * @return <code>true</code> if this {@link JClassType} is assignable to the |
| * specified {@link JClassType} parameter |
| * |
| * @throws NullPointerException if <code>possibleSupertype</code> is |
| * <code>null</code> |
| */ |
| public boolean isAssignableTo( |
| com.google.gwt.core.ext.typeinfo.JClassType possibleSupertype) { |
| if (possibleSupertype == null) { |
| throw new NullPointerException("possibleSupertype"); |
| } |
| |
| return areClassTypesAssignable(possibleSupertype, this); |
| } |
| |
| public abstract JClassType isClass(); |
| |
| public JClassType isClassOrInterface() { |
| JClassType type = isClass(); |
| if (type != null) { |
| return type; |
| } |
| return isInterface(); |
| } |
| |
| /** |
| * Determines if the class can be constructed using a simple <code>new</code> |
| * operation. Specifically, the class must |
| * <ul> |
| * <li>be a class rather than an interface,</li> |
| * <li>have either no constructors or a parameterless constructor, and</li> |
| * <li>be a top-level class or a static nested class.</li> |
| * </ul> |
| * |
| * @return <code>true</code> if the type is default instantiable, or |
| * <code>false</code> otherwise |
| */ |
| public abstract boolean isDefaultInstantiable(); |
| |
| /** |
| * Returns true if the type may be enhanced on the server to contain extra |
| * fields that are unknown to client code. |
| * |
| * @return <code>true</code> if the type might be enhanced on the server |
| */ |
| public final boolean isEnhanced() { |
| return isEnhanced; |
| } |
| |
| /** |
| * Returns this instance if it is an enumeration or <code>null</code> if it is |
| * not. |
| * |
| * @return this instance if it is an enumeration or <code>null</code> if it is |
| * not |
| */ |
| public abstract JEnumType isEnum(); |
| |
| public abstract boolean isFinal(); |
| |
| public abstract JGenericType isGenericType(); |
| |
| public abstract JClassType isInterface(); |
| |
| /** |
| * @deprecated local types are not modeled |
| */ |
| @Deprecated |
| public final boolean isLocalType() { |
| return false; |
| } |
| |
| /** |
| * Tests if this type is contained within another type. |
| * |
| * @return true if this type has an enclosing type, false if this type is a |
| * top-level type |
| */ |
| public abstract boolean isMemberType(); |
| |
| public abstract JParameterizedType isParameterized(); |
| |
| public abstract JPrimitiveType isPrimitive(); |
| |
| public abstract boolean isPrivate(); |
| |
| public abstract boolean isProtected(); |
| |
| public abstract boolean isPublic(); |
| |
| // TODO: Rename this to isRaw |
| public abstract JRawType isRawType(); |
| |
| public abstract boolean isStatic(); |
| |
| public JTypeParameter isTypeParameter() { |
| return null; |
| } |
| |
| public abstract JWildcardType isWildcard(); |
| |
| /** |
| * Indicates that the type may be enhanced on the server to contain extra |
| * fields that are unknown to client code. |
| * |
| * TODO(rice): find a better way to do this. |
| */ |
| public void setEnhanced() { |
| this.isEnhanced = true; |
| } |
| |
| @Override |
| public String toString() { |
| return this.getQualifiedSourceName(); |
| } |
| |
| protected abstract void acceptSubtype(JClassType me); |
| |
| protected abstract void getInheritableMethodsOnSuperclassesAndThisClass( |
| Map<String, JMethod> methodsBySignature); |
| |
| /** |
| * Gets the methods declared in interfaces that this type extends. If this |
| * type is a class, its own methods are not added. If this type is an |
| * interface, its own methods are added. Used internally by |
| * {@link #getOverridableMethods()}. |
| * |
| * @param methodsBySignature |
| */ |
| protected abstract void getInheritableMethodsOnSuperinterfacesAndMaybeThisInterface( |
| Map<String, JMethod> methodsBySignature); |
| |
| protected abstract int getModifierBits(); |
| |
| protected JMaybeParameterizedType isMaybeParameterizedType() { |
| return null; |
| } |
| |
| /** |
| * Tells this type's superclasses and superinterfaces about it. |
| */ |
| protected abstract void notifySuperTypesOf(JClassType me); |
| |
| protected abstract void removeSubtype(JClassType me); |
| |
| abstract void addConstructor(JConstructor ctor); |
| |
| abstract void addField(JField field); |
| |
| abstract void addImplementedInterface(JClassType intf); |
| |
| abstract void addMethod(JMethod method); |
| |
| abstract void addModifierBits(int bits); |
| |
| abstract void addNestedType(JClassType type); |
| |
| abstract JClassType findNestedTypeImpl(String[] typeName, int index); |
| |
| /** |
| * Returns either the substitution of this type based on the parameterized |
| * type or this instance. |
| * |
| * @param parameterizedType |
| * @return either the substitution of this type based on the parameterized |
| * type or this instance |
| */ |
| abstract JClassType getSubstitutedType(JParameterizedType parameterizedType); |
| |
| abstract void notifySuperTypes(); |
| |
| /** |
| * Removes references to this instance from all of its super types. |
| */ |
| abstract void removeFromSupertypes(); |
| |
| abstract void setSuperclass(JClassType type); |
| } |