The attached patch finishes up the Java 1.5 support in the TypeOracle. The patch makes the following changes:
* Implemented the functionality missing from the JDelegatingClassType subtypes.
* Enabled erasure and type parameter substitution for JRawType and JParameterizedType respectively. This means that List<Interger> is a full blown JClassType where every reference to its type parameter has been replaced with Integer.
* JParameterizedTypes and JWildcard types now have referential stability.
* Added test cases for the new functionality.
* Added support for enumerated types
* Implemented a wildcard capture type scheme that allows us to reasonably determine the set of subtypes of a parameterized type since this is technically an unbounded set. For example, the subtypes List<Integer> could actually be parameterized types like MyList<? extends Serializable, Integer> and so on.
* Fixes a bug in our Annotation proxy; we failed to implement the Annotation.annotationType() method.
* Fixed a problem with annotations. Specifically, JLS3 9.7, single element array values do not need curly braces
* Other minor issues with our JDT mapping
Issues outstanding:
* Subtype and assignability checks may still not deal with all of the corner cases.
* The TypeOracle's refresh logic needs to be update to properly flush generics and parameterized types are out of date.
Patch by: mmendez
Review by: scottb (TBR)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1523 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java
new file mode 100644
index 0000000..47fd220
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/AbstractMembers.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+abstract class AbstractMembers {
+
+ protected final JClassType classType;
+ private JMethod[] cachedOverridableMethods;
+ private final Map<String, JClassType> nestedTypes = new HashMap<String, JClassType>();
+
+ public AbstractMembers(JClassType classType) {
+ this.classType = classType;
+ }
+
+ public JConstructor findConstructor(JType[] paramTypes) {
+ JConstructor[] ctors = getConstructors();
+ for (int i = 0; i < ctors.length; i++) {
+ JConstructor candidate = ctors[i];
+ if (candidate.hasParamTypes(paramTypes)) {
+ return candidate;
+ }
+ }
+ return null;
+ }
+
+ public JField findField(String name) {
+ return doGetFields().get(name);
+ }
+
+ public JMethod findMethod(String name, JType[] paramTypes) {
+ JMethod[] overloads = getOverloads(name);
+ for (int i = 0; i < overloads.length; i++) {
+ JMethod candidate = overloads[i];
+ if (candidate.hasParamTypes(paramTypes)) {
+ return candidate;
+ }
+ }
+ return null;
+ }
+
+ public JClassType findNestedType(String typeName) {
+ String[] parts = typeName.split("\\.");
+ return findNestedTypeImpl(parts, 0);
+ }
+
+ public JConstructor getConstructor(JType[] paramTypes)
+ throws NotFoundException {
+ JConstructor result = findConstructor(paramTypes);
+ if (result == null) {
+ throw new NotFoundException();
+ }
+ return result;
+ }
+
+ public JConstructor[] getConstructors() {
+ return doGetConstructors().toArray(TypeOracle.NO_JCTORS);
+ }
+
+ public JField getField(String name) {
+ JField field = findField(name);
+ assert (field != null);
+ return field;
+ }
+
+ public JField[] getFields() {
+ return doGetFields().values().toArray(TypeOracle.NO_JFIELDS);
+ }
+
+ public JMethod getMethod(String name, JType[] paramTypes)
+ throws NotFoundException {
+ JMethod result = findMethod(name, paramTypes);
+ if (result == null) {
+ throw new NotFoundException();
+ }
+ return result;
+ }
+
+ public JMethod[] getMethods() {
+ List<JMethod> resultMethods = new ArrayList<JMethod>();
+ for (List<JMethod> overloads : doGetMethods().values()) {
+ resultMethods.addAll(overloads);
+ }
+ return resultMethods.toArray(TypeOracle.NO_JMETHODS);
+ }
+
+ public JClassType getNestedType(String typeName) throws NotFoundException {
+ JClassType result = findNestedType(typeName);
+ if (result == null) {
+ throw new NotFoundException();
+ }
+ return result;
+ }
+
+ public JClassType[] getNestedTypes() {
+ return nestedTypes.values().toArray(TypeOracle.NO_JCLASSES);
+ }
+
+ public JMethod[] getOverloads(String name) {
+ List<?> resultMethods = doGetMethods().get(name);
+ if (resultMethods != null) {
+ return resultMethods.toArray(TypeOracle.NO_JMETHODS);
+ } else {
+ return TypeOracle.NO_JMETHODS;
+ }
+ }
+
+ public JMethod[] getOverridableMethods() {
+ if (cachedOverridableMethods == null) {
+ Map<String, JMethod> methodsBySignature = new TreeMap<String, JMethod>();
+ getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
+ if (classType.isClass() != null) {
+ getOverridableMethodsOnSuperclassesAndThisClass(methodsBySignature);
+ }
+ int size = methodsBySignature.size();
+ Collection<JMethod> leafMethods = methodsBySignature.values();
+ cachedOverridableMethods = leafMethods.toArray(new JMethod[size]);
+ }
+ return cachedOverridableMethods;
+ }
+
+ protected void addConstructor(JConstructor ctor) {
+ assert (!doGetConstructors().contains(ctor));
+ doGetConstructors().add(ctor);
+ }
+
+ protected void addField(JField field) {
+ Object existing = doGetFields().put(field.getName(), field);
+ assert (existing == null);
+ }
+
+ protected void addMethod(JMethod method) {
+ String methodName = method.getName();
+ Map<String, List<JMethod>> methods = doGetMethods();
+ List<JMethod> overloads = methods.get(methodName);
+ if (overloads == null) {
+ overloads = new ArrayList<JMethod>();
+ methods.put(methodName, overloads);
+ }
+ overloads.add(method);
+ }
+
+ protected void addNestedType(JClassType type) {
+ nestedTypes.put(type.getSimpleSourceName(), type);
+ }
+
+ protected abstract List<JConstructor> doGetConstructors();
+
+ protected abstract Map<String, JField> doGetFields();
+
+ protected abstract Map<String, List<JMethod>> doGetMethods();
+
+ protected JClassType findNestedTypeImpl(String[] typeName, int index) {
+ JClassType found = nestedTypes.get(typeName[index]);
+ if (found == null) {
+ return null;
+ } else if (index < typeName.length - 1) {
+ return found.findNestedTypeImpl(typeName, index + 1);
+ } else {
+ return found;
+ }
+ }
+
+ protected void getOverridableMethodsOnSuperclassesAndThisClass(
+ Map<String, JMethod> methodsBySignature) {
+ assert (classType.isClass() != null);
+
+ // Recurse first so that more derived methods will clobber less derived
+ // methods.
+ JClassType superClass = classType.getSuperclass();
+ if (superClass != null) {
+ superClass.getOverridableMethodsOnSuperclassesAndThisClass(methodsBySignature);
+ }
+
+ JMethod[] declaredMethods = getMethods();
+ for (int i = 0; i < declaredMethods.length; i++) {
+ JMethod method = declaredMethods[i];
+
+ // Ensure that this method is overridable.
+ if (method.isFinal() || method.isPrivate() || method.isStatic()) {
+ // We cannot override this method, so skip it.
+ continue;
+ }
+
+ // We can override this method, so record it.
+ String sig = computeInternalSignature(method);
+ methodsBySignature.put(sig, method);
+ }
+ }
+
+ /**
+ * 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 void getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(
+ Map<String, JMethod> methodsBySignature) {
+ // Recurse first so that more derived methods will clobber less derived
+ // methods.
+ JClassType[] superIntfs = classType.getImplementedInterfaces();
+ for (int i = 0; i < superIntfs.length; i++) {
+ JClassType superIntf = superIntfs[i];
+ superIntf.getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
+ }
+
+ if (classType.isInterface() == null) {
+ // This is not an interface, so we're done after having visited its
+ // implemented interfaces.
+ return;
+ }
+
+ JMethod[] declaredMethods = getMethods();
+ for (int i = 0; i < declaredMethods.length; i++) {
+ JMethod method = declaredMethods[i];
+
+ String sig = computeInternalSignature(method);
+ JMethod existing = methodsBySignature.get(sig);
+ if (existing != null) {
+ JClassType existingType = existing.getEnclosingType();
+ JClassType thisType = method.getEnclosingType();
+ if (thisType.isAssignableFrom(existingType)) {
+ // The existing method is in a more-derived type, so don't replace it.
+ continue;
+ }
+ }
+ methodsBySignature.put(sig, method);
+ }
+ }
+
+ protected JClassType getParentType() {
+ return classType;
+ }
+
+ private String computeInternalSignature(JMethod method) {
+ StringBuffer sb = new StringBuffer();
+ sb.setLength(0);
+ sb.append(method.getName());
+ JParameter[] params = method.getParameters();
+ for (int j = 0; j < params.length; j++) {
+ JParameter param = params[j];
+ sb.append("/");
+ sb.append(param.getType().getErasedType().getQualifiedSourceName());
+ }
+ return sb.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/Annotations.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/Annotations.java
index 2d7631c..e90fa74 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/Annotations.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/Annotations.java
@@ -42,6 +42,23 @@
*/
private Annotations parent;
+ Annotations() {
+ }
+
+ Annotations(Annotations otherAnnotations) {
+ if (otherAnnotations != null) {
+ Annotation[] otherDeclaredAnnotations = otherAnnotations.getDeclaredAnnotations();
+ for (Annotation otherDeclaredAnnotation : otherDeclaredAnnotations) {
+ addAnnotation(otherDeclaredAnnotation.annotationType(),
+ otherDeclaredAnnotation);
+ }
+ }
+ }
+
+ Annotations(Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
+ this.declaredAnnotations.putAll(declaredAnnotations);
+ }
+
public void addAnnotations(
Map<Class<? extends Annotation>, Annotation> annotations) {
if (annotations != null) {
@@ -92,11 +109,12 @@
lazyAnnotations = new HashMap<Class<? extends Annotation>, Annotation>();
parent.initializeAnnotations();
for (Entry<Class<? extends Annotation>, Annotation> entry : parent.lazyAnnotations.entrySet()) {
- if (entry.getValue().annotationType().isAnnotationPresent(Inherited.class)) {
+ if (entry.getValue().annotationType().isAnnotationPresent(
+ Inherited.class)) {
lazyAnnotations.put(entry.getKey(), entry.getValue());
}
}
-
+
lazyAnnotations.putAll(declaredAnnotations);
} else {
lazyAnnotations = declaredAnnotations;
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/DelegateMembers.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/DelegateMembers.java
new file mode 100644
index 0000000..2502013
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/DelegateMembers.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class that initializes the different members of a
+ * {@link JDelegatingClassType} from its corresponding base type on demand.
+ */
+class DelegateMembers extends AbstractMembers {
+ private final JClassType baseType;
+ private List<JConstructor> lazyConstructors;
+ private Map<String, JField> lazyFields;
+ private Map<String, List<JMethod>> lazyMethods;
+ private final Substitution substitution;
+
+ /**
+ */
+ public DelegateMembers(JDelegatingClassType enclosingType,
+ JClassType baseType, Substitution substitution) {
+ super(enclosingType);
+ this.baseType = baseType;
+ this.substitution = substitution;
+ }
+
+ @Override
+ protected List<JConstructor> doGetConstructors() {
+ if (lazyConstructors != null) {
+ /*
+ * Return if the constructors are being initialized or have been
+ * initialized.
+ */
+ return lazyConstructors;
+ }
+ lazyConstructors = new ArrayList<JConstructor>();
+
+ JConstructor[] baseCtors = baseType.getConstructors();
+ for (JConstructor baseCtor : baseCtors) {
+ JConstructor newCtor = new JConstructor(getParentType(), baseCtor);
+ initializeParams(baseCtor, newCtor);
+ addConstructor(newCtor);
+ }
+
+ return lazyConstructors;
+ }
+
+ @Override
+ protected Map<String, JField> doGetFields() {
+ if (lazyFields != null) {
+ /*
+ * Return if the fields are being initialized or have been
+ * initialized.
+ */
+ return lazyFields;
+ }
+ lazyFields = new HashMap<String, JField>();
+
+ JField[] baseFields = baseType.getFields();
+ for (JField baseField : baseFields) {
+ JField newField = new JField(getParentType(), baseField);
+ newField.setType(substitution.getSubstitution(baseField.getType()));
+ addField(newField);
+ }
+
+ return lazyFields;
+ }
+
+ @Override
+ protected Map<String, List<JMethod>> doGetMethods() {
+ if (lazyMethods != null) {
+ /*
+ * Return if the methods are being initialized or have been
+ * initialized.
+ */
+ return lazyMethods;
+ }
+ lazyMethods = new HashMap<String, List<JMethod>>();
+
+ JMethod[] baseMethods = baseType.getMethods();
+ for (JMethod baseMethod : baseMethods) {
+ JMethod newMethod = new JMethod(getParentType(), baseMethod);
+ initializeParams(baseMethod, newMethod);
+ newMethod.setReturnType(substitution.getSubstitution(baseMethod.getReturnType()));
+ addMethod(newMethod);
+ }
+
+ return lazyMethods;
+ }
+
+ private void initializeParams(JAbstractMethod srcMethod,
+ JAbstractMethod newMethod) {
+ for (JParameter srcParam : srcMethod.getParameters()) {
+ JParameter newParam = new JParameter(newMethod, srcParam);
+ newParam.setType(substitution.getSubstitution(srcParam.getType()));
+ newMethod.addParameter(newParam);
+ }
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java
index be5ebca..e7f8b98 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JAbstractMethod.java
@@ -26,7 +26,7 @@
public abstract class JAbstractMethod implements HasAnnotations, HasMetaData,
HasTypeParameters {
- private final Annotations annotations = new Annotations();
+ private final Annotations annotations;
private int bodyEnd;
@@ -59,9 +59,26 @@
this.declEnd = declEnd;
this.bodyStart = bodyStart;
this.bodyEnd = bodyEnd;
+ annotations = new Annotations();
annotations.addAnnotations(declaredAnnotations);
}
+ /**
+ * @param enclosingType
+ * @param ctor
+ */
+ JAbstractMethod(JAbstractMethod srcMethod) {
+ this.annotations = new Annotations(srcMethod.annotations);
+ this.bodyEnd = srcMethod.bodyEnd;
+ this.bodyStart = srcMethod.bodyStart;
+ this.declEnd = srcMethod.declEnd;
+ this.declStart = srcMethod.declStart;
+ this.isVarArgs = srcMethod.isVarArgs;
+ MetaData.copy(this, srcMethod.metaData);
+ this.modifierBits = srcMethod.modifierBits;
+ this.name = srcMethod.name;
+ }
+
public void addMetaData(String tagName, String[] values) {
metaData.addMetaData(tagName, values);
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java
index a206c4b..d2f3ba7 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JArrayType.java
@@ -24,6 +24,7 @@
* Type representing a Java array.
*/
public class JArrayType extends JClassType {
+ private static final JArrayType[] NO_JARRAYS = new JArrayType[0];
private JType componentType;
@@ -63,14 +64,12 @@
@Override
public JField findField(String name) {
- // TODO length
return null;
}
@Override
public JMethod findMethod(String name, JType[] paramTypes) {
- // TODO Object
- return null;
+ return getOracle().getJavaLangObject().findMethod(name, paramTypes);
}
@Override
@@ -110,12 +109,12 @@
@Override
public JConstructor getConstructor(JType[] paramTypes)
throws NotFoundException {
- return null;
+ throw new NotFoundException();
}
@Override
public JConstructor[] getConstructors() {
- return null;
+ return TypeOracle.NO_JCTORS;
}
@Override
@@ -130,19 +129,16 @@
@Override
public JClassType getErasedType() {
- // TODO array of component type
- return this;
+ return getOracle().getArrayType(getComponentType().getErasedType());
}
@Override
public JField getField(String name) {
- // TODO length
return null;
}
@Override
public JField[] getFields() {
- // TODO length
return TypeOracle.NO_JFIELDS;
}
@@ -151,10 +147,12 @@
return TypeOracle.NO_JCLASSES;
}
+ @Override
public String getJNISignature() {
return "[" + componentType.getJNISignature();
}
+ @Override
public JType getLeafType() {
return componentType.getLeafType();
}
@@ -172,20 +170,17 @@
@Override
public JMethod getMethod(String name, JType[] paramTypes)
throws NotFoundException {
- // TODO Object
- return null;
+ return getOracle().getJavaLangObject().getMethod(name, paramTypes);
}
@Override
public JMethod[] getMethods() {
- // TODO Object
- return null;
+ return getOracle().getJavaLangObject().getMethods();
}
@Override
public String getName() {
- // TODO Auto-generated method stub
- return null;
+ return getSimpleSourceName();
}
@Override
@@ -205,26 +200,32 @@
@Override
public JMethod[] getOverloads(String name) {
- // TODO Object
- return null;
+ return getOracle().getJavaLangObject().getOverloads(name);
}
@Override
public JMethod[] getOverridableMethods() {
- // TODO Object
- return null;
+ return getOracle().getJavaLangObject().getOverridableMethods();
}
@Override
public JPackage getPackage() {
- // TODO
- return null;
+ JType leafType = getLeafType();
+ if (leafType.isPrimitive() != null) {
+ // TODO: is there a default package?
+ return null;
+ }
+
+ JClassType leafClass = (JClassType) leafType;
+ return leafClass.getPackage();
}
+ @Override
public String getParameterizedQualifiedSourceName() {
return getComponentType().getParameterizedQualifiedSourceName() + "[]";
}
+ @Override
public String getQualifiedSourceName() {
if (lazyQualifiedName == null) {
lazyQualifiedName = getComponentType().getQualifiedSourceName() + "[]";
@@ -241,6 +242,7 @@
return 1;
}
+ @Override
public String getSimpleSourceName() {
if (lazySimpleName == null) {
lazySimpleName = getComponentType().getSimpleSourceName() + "[]";
@@ -249,21 +251,64 @@
}
@Override
- public JClassType[] getSubtypes() {
- // TODO
- return TypeOracle.NO_JCLASSES;
+ public JArrayType[] getSubtypes() {
+ if (getComponentType().isPrimitive() != null) {
+ return NO_JARRAYS;
+ }
+
+ JClassType componentClass = (JClassType) getComponentType();
+ JClassType[] componentSubtypes = componentClass.getSubtypes();
+ JArrayType[] arraySubtypes = new JArrayType[componentSubtypes.length];
+ for (int i = 0; i < componentSubtypes.length; ++i) {
+ arraySubtypes[i] = getOracle().getArrayType(componentSubtypes[i]);
+ }
+
+ return arraySubtypes;
}
@Override
public JClassType getSuperclass() {
- // TODO Object?
- return null;
+ JType compType = getComponentType();
+ JClassType javaLangObject = getOracle().getJavaLangObject();
+ if (compType.isPrimitive() != null) {
+ // Super of primitive[] is object
+ return javaLangObject;
+ }
+
+ JArrayType arrayComponent = compType.isArray();
+ if (arrayComponent != null) {
+ // Superclass of multi-dimensional array is superclass of component
+ return getOracle().getArrayType(arrayComponent.getSuperclass());
+ }
+
+ JClassType type = compType.isClassOrInterface();
+ if (type == javaLangObject) {
+ // Superclass of Object[] is Object
+ return javaLangObject;
+ }
+
+ JClassType superType = type.getSuperclass();
+ if (superType == null) {
+ // Superclass of interface[] is Object[]
+ assert (type.isInterface() == null);
+ superType = javaLangObject;
+ }
+
+ return getOracle().getArrayType(superType);
}
@Override
public String getTypeHash() throws UnableToCompleteException {
- // TODO
- return null;
+ JType leafType = getLeafType();
+ JClassType leafClassType = leafType.isClassOrInterface();
+ if (leafClassType != null) {
+ return leafClassType.getTypeHash();
+ }
+
+ // Arrays of primitive types should have a stable hash
+ assert (leafType.isPrimitive() != null);
+
+ return leafType.getQualifiedSourceName();
}
@Override
@@ -276,22 +321,51 @@
return false;
}
+ @Override
public JArrayType isArray() {
return this;
}
@Override
public boolean isAssignableFrom(JClassType possibleSubtype) {
- // TODO
- return false;
+ if (this == possibleSubtype) {
+ // type is assignable to itself
+ return true;
+ }
+
+ JArrayType possibleSubtypeArray = possibleSubtype.isArray();
+ if (possibleSubtypeArray == null) {
+ // possible subtype must be an array to be assignable
+ return false;
+ }
+
+ JType thisComponentType = getComponentType();
+ JType otherComponentType = possibleSubtypeArray.getComponentType();
+
+ if (thisComponentType.isPrimitive() != null
+ || otherComponentType.isPrimitive() != null) {
+ /*
+ * Since this was not equal to the possible subtype, we know that either
+ * the dimensions are off or the component types are off
+ */
+ return false;
+ }
+
+ assert (thisComponentType instanceof JClassType);
+ assert (otherComponentType instanceof JClassType);
+
+ JClassType thisComponentClassType = (JClassType) thisComponentType;
+ JClassType otherComponentClassType = (JClassType) otherComponentType;
+
+ return thisComponentClassType.isAssignableFrom(otherComponentClassType);
}
@Override
public boolean isAssignableTo(JClassType possibleSupertype) {
- // TODO
- return false;
+ return possibleSupertype.isAssignableFrom(this);
}
+ @Override
public JClassType isClass() {
// intentional null
return null;
@@ -303,10 +377,16 @@
}
@Override
+ public JEnumType isEnum() {
+ return null;
+ }
+
+ @Override
public JGenericType isGenericType() {
return null;
}
+ @Override
public JClassType isInterface() {
// intentional null
return null;
@@ -322,11 +402,13 @@
return false;
}
+ @Override
public JParameterizedType isParameterized() {
// intentional null
return null;
}
+ @Override
public JPrimitiveType isPrimitive() {
// intentional null
return null;
@@ -357,6 +439,11 @@
return true;
}
+ @Override
+ public JWildcardType isWildcard() {
+ return null;
+ }
+
public void setLeafType(JType type) {
JArrayType componentTypeIsArray = componentType.isArray();
if (componentTypeIsArray != null) {
@@ -370,6 +457,7 @@
public void setSuperclass(JClassType type) {
}
+ @Override
public String toString() {
return getQualifiedSourceName();
}
@@ -388,13 +476,15 @@
@Override
protected void getOverridableMethodsOnSuperclassesAndThisClass(
Map<String, JMethod> methodsBySignature) {
- // TODO Object
+ getOracle().getJavaLangObject().getOverridableMethodsOnSuperclassesAndThisClass(
+ methodsBySignature);
}
@Override
protected void getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(
Map<String, JMethod> methodsBySignature) {
- // TODO Object
+ getOracle().getJavaLangObject().getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(
+ methodsBySignature);
}
@Override
@@ -435,6 +525,12 @@
}
@Override
+ JArrayType getSubstitutedType(JParameterizedType parameterizedType) {
+ return oracle.getArrayType(getComponentType().getSubstitutedType(
+ parameterizedType));
+ }
+
+ @Override
void notifySuperTypes() {
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JBound.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JBound.java
index a59fc01..b9f6141 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JBound.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JBound.java
@@ -16,36 +16,81 @@
package com.google.gwt.core.ext.typeinfo;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
- *
+ * Represents a bound for a {@link JTypeParameter} or a {@link JWildcardType}.
*/
-public class JBound {
+public abstract class JBound {
+ /**
+ * Types which make up this bound.
+ */
+ private final List<JClassType> bounds = new ArrayList<JClassType>();
- private final JClassType firstBound;
- private final List<JClassType> lowerBounds = new ArrayList<JClassType>();
- private final List<JClassType> upperBounds = new ArrayList<JClassType>();
-
- public JBound(JClassType firstBound) {
- this.firstBound = firstBound;
+ JBound(JClassType[] bounds) {
+ this.bounds.addAll(Arrays.asList(bounds));
}
- public void addLowerBound(JClassType bound) {
- lowerBounds.add(bound);
- }
-
- public void addUpperBound(JClassType bound) {
- upperBounds.add(bound);
+ public JClassType[] getBounds() {
+ return bounds.toArray(TypeOracle.NO_JCLASSES);
}
public JClassType getFirstBound() {
- return firstBound;
+ assert (!bounds.isEmpty());
+
+ return bounds.get(0);
}
+ public String getQualifiedSourceName() {
+ return toString(true);
+ }
+
+ public String getSimpleSourceName() {
+ return toString(false);
+ }
+
+ public abstract JLowerBound isLowerBound();
+
+ public abstract JUpperBound isUpperBound();
+
@Override
public String toString() {
- return " extends " + firstBound.getParameterizedQualifiedSourceName();
+ return getQualifiedSourceName();
}
-
+
+ abstract JClassType[] getSubtypes();
+
+ abstract boolean isAssignableFrom(JBound possibleSubWildcard);
+
+ private String toString(boolean useQualifiedNames) {
+ StringBuffer sb = new StringBuffer();
+
+ if (isUpperBound() != null) {
+ sb.append(" extends ");
+ } else {
+ sb.append(" super ");
+ }
+
+ boolean needsAmpersand = false;
+ for (JClassType bound : bounds) {
+
+ if (needsAmpersand) {
+ sb.append(" & ");
+ } else {
+ needsAmpersand = true;
+ }
+
+ String name;
+ if (useQualifiedNames) {
+ name = bound.getParameterizedQualifiedSourceName();
+ } else {
+ name = bound.getSimpleSourceName();
+ }
+
+ sb.append(name);
+ }
+
+ return sb.toString();
+ }
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
index 276a179..359bc04 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
@@ -222,11 +222,13 @@
abstract JClassType findNestedTypeImpl(String[] typeName, int index);
+ @Override
+ abstract JClassType getSubstitutedType(JParameterizedType parameterizedType);
+
abstract void notifySuperTypes();
/**
* Removes references to this instance from all of its super types.
*/
abstract void removeFromSupertypes();
-
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java
index feb2044..504eaa3 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JConstructor.java
@@ -37,10 +37,17 @@
enclosingType.addConstructor(this);
}
+ JConstructor(JClassType enclosingType, JConstructor ctor) {
+ super(ctor);
+ this.enclosingType = enclosingType;
+ }
+
+ @Override
public JClassType getEnclosingType() {
return enclosingType;
}
+ @Override
public String getReadableDeclaration() {
String[] names = TypeOracle.modifierBitsToNames(getModifierBits());
StringBuilder sb = new StringBuilder();
@@ -57,14 +64,17 @@
return sb.toString();
}
+ @Override
public JConstructor isConstructor() {
return this;
}
+ @Override
public JMethod isMethod() {
return null;
}
+ @Override
public String toString() {
return getReadableDeclaration();
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java
index 29df9df..e421658 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JDelegatingClassType.java
@@ -26,7 +26,7 @@
*/
abstract class JDelegatingClassType extends JClassType {
- protected JClassType baseType;
+ private JClassType baseType;
JDelegatingClassType() {
}
@@ -84,6 +84,10 @@
return baseType.getAnnotations();
}
+ public JClassType getBaseType() {
+ return baseType;
+ }
+
@Override
public int getBodyEnd() {
return baseType.getBodyEnd();
@@ -123,9 +127,12 @@
@Override
public JClassType getEnclosingType() {
+ // TODO this can be wrong if the enclosing type is a parameterized type. For
+ // example, if a generic class has a non-static generic inner class.
return baseType.getEnclosingType();
}
+ @Override
public JClassType getErasedType() {
return baseType.getErasedType();
}
@@ -220,9 +227,6 @@
return baseType.getSuperclass();
}
- /**
- * TODO: What is this???
- */
@Override
public String getTypeHash() throws UnableToCompleteException {
return baseType.getTypeHash();
@@ -282,6 +286,11 @@
}
@Override
+ public final JEnumType isEnum() {
+ return null;
+ }
+
+ @Override
public JClassType isInterface() {
if (baseType.isInterface() != null) {
return this;
@@ -410,5 +419,4 @@
final void setBaseType(JClassType baseType) {
this.baseType = baseType;
}
-
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumConstant.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumConstant.java
new file mode 100644
index 0000000..cf35f88
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumConstant.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+
+/**
+ * An enumeration constant declared in an enumerated type.
+ */
+public class JEnumConstant extends JField {
+ private final int ordinal;
+
+ public JEnumConstant(JClassType enclosingType, String name,
+ Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
+ int ordinal) {
+ super(enclosingType, name, declaredAnnotations);
+ this.ordinal = ordinal;
+ }
+
+ /**
+ * Returns the ordinal value for this enumeration constant.
+ *
+ * @return ordinal value for this enumeration constant
+ */
+ public int getOrdinal() {
+ return ordinal;
+ }
+
+ @Override
+ public JEnumConstant isEnumConstant() {
+ return this;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumType.java
new file mode 100644
index 0000000..c91f14b
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JEnumType.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Type representing a Java enumerated type.
+ */
+public class JEnumType extends JRealClassType {
+ private JEnumConstant[] lazyEnumConstants;
+
+ /**
+ * @param oracle
+ * @param cup
+ * @param declaringPackage
+ * @param enclosingType
+ * @param isLocalType
+ * @param name
+ * @param declStart
+ * @param declEnd
+ * @param bodyStart
+ * @param bodyEnd
+ * @param isInterface
+ */
+ public JEnumType(TypeOracle oracle, CompilationUnitProvider cup,
+ JPackage declaringPackage, JClassType enclosingType, boolean isLocalType,
+ String name, int declStart, int declEnd, int bodyStart, int bodyEnd,
+ boolean isInterface) {
+ super(oracle, cup, declaringPackage, enclosingType, isLocalType, name,
+ declStart, declEnd, bodyStart, bodyEnd, isInterface);
+ }
+
+ /**
+ * Returns the enumeration constants declared by this enumeration.
+ *
+ * @return enumeration constants declared by this enumeration
+ */
+ public JEnumConstant[] getEnumConstants() {
+ if (lazyEnumConstants == null) {
+ List<JEnumConstant> enumConstants = new ArrayList<JEnumConstant>();
+ for (JField field : getFields()) {
+ if (field.isEnumConstant() != null) {
+ enumConstants.add(field.isEnumConstant());
+ }
+ }
+
+ assert (!enumConstants.isEmpty());
+
+ lazyEnumConstants = enumConstants.toArray(new JEnumConstant[0]);
+ }
+
+ return lazyEnumConstants;
+ }
+
+ @Override
+ public JEnumType isEnum() {
+ return this;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java
index d8d920e..f7ce1d7 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JField.java
@@ -23,7 +23,7 @@
*/
public class JField implements HasAnnotations, HasMetaData {
- private final Annotations annotations = new Annotations();
+ private final Annotations annotations;
private final JClassType enclosingType;
@@ -41,14 +41,24 @@
public JField(JClassType enclosingType, String name,
Map<Class<? extends Annotation>, Annotation> declaredAnnotations) {
+ assert (enclosingType != null);
this.enclosingType = enclosingType;
this.name = name;
-
- assert (enclosingType != null);
- enclosingType.addField(this);
+ this.enclosingType.addField(this);
+ annotations = new Annotations();
annotations.addAnnotations(declaredAnnotations);
}
+ JField(JClassType enclosingType, JField srcField) {
+ this.annotations = new Annotations(srcField.annotations);
+ this.enclosingType = enclosingType;
+ this.modifierBits = srcField.modifierBits;
+ this.name = srcField.name;
+ this.type = srcField.type;
+
+ MetaData.copy(this, srcField);
+ }
+
public void addMetaData(String tagName, String[] values) {
metaData.addMetaData(tagName, values);
}
@@ -99,6 +109,10 @@
return 0 == (modifierBits & (TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED));
}
+ public JEnumConstant isEnumConstant() {
+ return null;
+ }
+
public boolean isFinal() {
return 0 != (modifierBits & TypeOracle.MOD_FINAL);
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java
index d5dda07..533f074 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JGenericType.java
@@ -41,7 +41,14 @@
@Override
public String getParameterizedQualifiedSourceName() {
StringBuffer sb = new StringBuffer();
- sb.append(getQualifiedSourceName());
+
+ if (getEnclosingType() != null) {
+ sb.append(getEnclosingType().getParameterizedQualifiedSourceName());
+ sb.append(".");
+ sb.append(getSimpleSourceName());
+ } else {
+ sb.append(getQualifiedSourceName());
+ }
sb.append('<');
boolean needComma = false;
@@ -59,8 +66,9 @@
public JRawType getRawType() {
if (lazyRawType == null) {
- lazyRawType = new JRawType(this);
+ lazyRawType = new JRawType(this, getEnclosingType());
}
+
return lazyRawType;
}
@@ -69,21 +77,17 @@
}
@Override
- public boolean isDefaultInstantiable() {
- /*
- * By definition, you cannot instantiate a generic type, only a
- * parameterized type or a raw type?
- */
- return false;
- }
-
- @Override
public JGenericType isGenericType() {
return this;
}
- protected boolean isDefaultInstantiableIfParameterized() {
- return super.isDefaultInstantiable();
+ @Override
+ public String toString() {
+ if (isInterface() != null) {
+ return "interface " + getParameterizedQualifiedSourceName();
+ }
+
+ return "class " + getParameterizedQualifiedSourceName();
}
void addTypeParameter(JTypeParameter typeParameter) {
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JLowerBound.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JLowerBound.java
new file mode 100644
index 0000000..111bfa9
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JLowerBound.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+/**
+ * Represents the super bound used in {@link JWildcardType}s.
+ */
+public class JLowerBound extends JBound {
+ /**
+ *
+ */
+ public JLowerBound(JClassType lowerBound) {
+ this(new JClassType[] {lowerBound});
+ }
+
+ /**
+ *
+ */
+ public JLowerBound(JClassType[] lowerBounds) {
+ super(lowerBounds);
+ }
+
+ @Override
+ public JLowerBound isLowerBound() {
+ return this;
+ }
+
+ @Override
+ public JUpperBound isUpperBound() {
+ return null;
+ }
+
+ @Override
+ JClassType[] getSubtypes() {
+ return TypeOracle.NO_JCLASSES;
+ }
+
+ @Override
+ boolean isAssignableFrom(JBound possibleSubWildcard) {
+ JLowerBound lowerBound = possibleSubWildcard.isLowerBound();
+ if (lowerBound != null) {
+ return lowerBound.getFirstBound().isAssignableFrom(getFirstBound());
+ }
+
+ return false;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java
index 6afd46f..bef2f11 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JMethod.java
@@ -40,6 +40,12 @@
enclosingType.addMethod(this);
}
+ JMethod(JClassType enclosingType, JMethod srcMethod) {
+ super(srcMethod);
+ this.enclosingType = enclosingType;
+ this.returnType = srcMethod.returnType;
+ }
+
@Override
public JClassType getEnclosingType() {
return enclosingType;
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java
index 07aaaf1..bf4b2b2 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameter.java
@@ -23,7 +23,7 @@
*/
public class JParameter implements HasAnnotations, HasMetaData {
- private final Annotations annotations = new Annotations();
+ private final Annotations annotations;
private final HasMetaData metaData = new MetaData();
@@ -45,9 +45,18 @@
enclosingMethod.addParameter(this);
+ annotations = new Annotations();
annotations.addAnnotations(declaredAnnotations);
}
+ JParameter(JAbstractMethod enclosingMethod, JParameter srcParam) {
+ this.enclosingMethod = enclosingMethod;
+ this.type = srcParam.type;
+ this.name = srcParam.name;
+ this.annotations = new Annotations(srcParam.annotations);
+ MetaData.copy(this, srcParam);
+ }
+
public void addMetaData(String tagName, String[] values) {
metaData.addMetaData(tagName, values);
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java
index 46f375a..ad0a18f 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JParameterizedType.java
@@ -16,21 +16,92 @@
package com.google.gwt.core.ext.typeinfo;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Represents a parameterized type in a declaration.
*/
public class JParameterizedType extends JDelegatingClassType {
+ /**
+ * Create a parameterized type along with any necessary enclosing
+ * parameterized types. Enclosing parameterized types are necessary when the
+ * base type is a non-static member and the enclosing type is also generic.
+ */
+ private static JParameterizedType createParameterizedTypeRecursive(
+ JGenericType baseType, Map<JClassType, JClassType> substitutionMap) {
+ JClassType enclosingType = null;
+ if (baseType.isMemberType() && !baseType.isStatic()) {
+ JGenericType isGenericEnclosingType = baseType.getEnclosingType().isGenericType();
+ if (isGenericEnclosingType != null) {
+ enclosingType = createParameterizedTypeRecursive(
+ isGenericEnclosingType, substitutionMap);
+ }
+ }
- private final Members members = new Members(this);
+ JTypeParameter[] typeParameters = baseType.getTypeParameters();
+ JClassType[] newTypeArgs = new JClassType[typeParameters.length];
+ TypeOracle oracle = baseType.getOracle();
+ for (int i = 0; i < newTypeArgs.length; ++i) {
+ JClassType newTypeArg = substitutionMap.get(typeParameters[i]);
+ if (newTypeArg == null) {
+ JBound typeParamBounds = typeParameters[i].getBounds();
+ JUpperBound newTypeArgBounds = new JUpperBound(
+ typeParamBounds.getFirstBound());
+ newTypeArg = oracle.getWildcardType(newTypeArgBounds);
+ }
+
+ newTypeArgs[i] = newTypeArg;
+ }
+
+ // TODO: this is wrong if the generic type is a non-static inner class.
+ JParameterizedType parameterizedType = oracle.getParameterizedType(
+ baseType, enclosingType, newTypeArgs);
+ return parameterizedType;
+ }
+
+ private final JClassType enclosingType;
+
+ private List<JClassType> interfaces;
+
+ private JClassType lazySuperclass;
+
+ private final AbstractMembers members;
private final List<JClassType> typeArgs = new ArrayList<JClassType>();
- JParameterizedType(JGenericType baseType) {
+ /**
+ * This map records the JClassType that should be used in place of a given
+ * {@link JTypeParameter}.
+ */
+ private final Map<JTypeParameter, JClassType> substitutionMap = new IdentityHashMap<JTypeParameter, JClassType>();
+
+ public JParameterizedType(JGenericType baseType, JClassType enclosingType,
+ JClassType[] typeArgs) {
super.setBaseType(baseType);
- // TODO: type substitutions setting up fields/methods!
+
+ this.enclosingType = enclosingType;
+
+ // NOTE: this instance is not considered a nested type of the enclosing type
+
+ final JParameterizedType parameterizedType = this;
+ members = new DelegateMembers(this, baseType, new Substitution() {
+ public JType getSubstitution(JType type) {
+ return type.getSubstitutedType(parameterizedType);
+ }
+ });
+
+ List<JClassType> typeArgsList = Arrays.asList(typeArgs);
+ this.typeArgs.addAll(typeArgsList);
+ assert (typeArgsList.indexOf(null) == -1);
+
+ initializeTypeParameterSubstitutionMap();
+
+ // NOTE: Can't perform substitutions until we are done building
}
@Override
@@ -53,8 +124,9 @@
return members.findNestedType(typeName);
}
+ @Override
public JGenericType getBaseType() {
- return (JGenericType) baseType;
+ return (JGenericType) super.getBaseType();
}
@Override
@@ -69,6 +141,11 @@
}
@Override
+ public JClassType getEnclosingType() {
+ return enclosingType;
+ }
+
+ @Override
public JField getField(String name) {
return members.getField(name);
}
@@ -79,6 +156,19 @@
}
@Override
+ public JClassType[] getImplementedInterfaces() {
+ if (interfaces == null) {
+ interfaces = new ArrayList<JClassType>();
+ JClassType[] intfs = getBaseType().getImplementedInterfaces();
+ for (JClassType intf : intfs) {
+ JClassType newIntf = intf.getSubstitutedType(this);
+ interfaces.add(newIntf);
+ }
+ }
+ return interfaces.toArray(TypeOracle.NO_JCLASSES);
+ }
+
+ @Override
public JMethod getMethod(String name, JType[] paramTypes)
throws NotFoundException {
return members.getMethod(name, paramTypes);
@@ -120,19 +210,35 @@
@Override
public String getParameterizedQualifiedSourceName() {
StringBuffer sb = new StringBuffer();
- sb.append(getQualifiedSourceName());
- sb.append('<');
- boolean needComma = false;
- for (JType typeArg : typeArgs) {
- if (needComma) {
- sb.append(", ");
- } else {
- needComma = true;
- }
- sb.append(typeArg.getParameterizedQualifiedSourceName());
+ if (getEnclosingType() != null) {
+ sb.append(getEnclosingType().getParameterizedQualifiedSourceName());
+ sb.append(".");
+ sb.append(getSimpleSourceName());
+ } else {
+ sb.append(getQualifiedSourceName());
}
- sb.append('>');
+
+ if (typeArgs.size() > 0) {
+ sb.append('<');
+ boolean needComma = false;
+ for (JType typeArg : typeArgs) {
+ if (needComma) {
+ sb.append(", ");
+ } else {
+ needComma = true;
+ }
+ sb.append(typeArg.getParameterizedQualifiedSourceName());
+ }
+ sb.append('>');
+ } else {
+ /*
+ * Non-static, inner classes of generic types are modeled as generic, even
+ * if they do not declare type parameters or reference the type parameters
+ * of their enclosing generic type.
+ */
+ }
+
return sb.toString();
}
@@ -140,6 +246,7 @@
* Everything is fully qualified and includes the < and > in the
* signature.
*/
+ @Override
public String getQualifiedSourceName() {
return getBaseType().getQualifiedSourceName();
}
@@ -151,8 +258,60 @@
/**
* In this case, the raw type name.
*/
+ @Override
public String getSimpleSourceName() {
- return getRawType().getSimpleSourceName();
+ return getBaseType().getSimpleSourceName();
+ }
+
+ /*
+ * Goal: Return a list of possible subtypes of this parameterized type. In the
+ * event that we have generic subtypes and we cannot resolve the all of the
+ * type arguments, we need to wildcard types in place of the arguments that we
+ * cannot resolve.
+ *
+ * Algorithm: - Ask generic type for its subtypes - Filter subtypes of the
+ * generic which cannot be our subtype.
+ */
+ @Override
+ public JClassType[] getSubtypes() {
+ List<JClassType> subtypeList = new ArrayList<JClassType>();
+
+ // Parameterized types are not tracked in the subtype hierarchy; ask base
+ // type
+ JClassType[] genericSubtypes = getBaseType().getSubtypes();
+ for (JClassType subtype : genericSubtypes) {
+ Set<JClassType> typeHierarchy = getFlattenedTypeHierarchy(subtype);
+
+ // Could be a subtype depending on how it is substituted
+ Map<JClassType, JClassType> substitutions = new IdentityHashMap<JClassType, JClassType>();
+ if (isSubtype(subtype, typeHierarchy, substitutions, true)) {
+ JGenericType genericType = subtype.isGenericType();
+ if (genericType != null) {
+ subtype = createParameterizedTypeRecursive(genericType, substitutions);
+ }
+
+ subtypeList.add(subtype);
+ }
+ }
+
+ return subtypeList.toArray(TypeOracle.NO_JCLASSES);
+ }
+
+ @Override
+ public JClassType getSuperclass() {
+ if (isInterface() != null) {
+ return null;
+ }
+
+ if (lazySuperclass == null) {
+ JGenericType baseType = getBaseType();
+ JClassType superclass = baseType.getSuperclass();
+ assert (superclass != null);
+
+ lazySuperclass = superclass.getSubstitutedType(this);
+ }
+
+ return lazySuperclass;
}
public JClassType[] getTypeArgs() {
@@ -160,8 +319,24 @@
}
@Override
- public boolean isDefaultInstantiable() {
- return getBaseType().isDefaultInstantiableIfParameterized();
+ public boolean isAssignableFrom(JClassType possibleSubtype) {
+ if (possibleSubtype == this) {
+ return true;
+ }
+
+ JRawType possibleRawSubtype = possibleSubtype.isRawType();
+ if (possibleRawSubtype != null) {
+ return getBaseType().isAssignableFrom(possibleRawSubtype.getBaseType());
+ }
+
+ Set<JClassType> typeHierarchy = getFlattenedTypeHierarchy(possibleSubtype);
+ return isSubtype(possibleSubtype, typeHierarchy,
+ new IdentityHashMap<JClassType, JClassType>(), false);
+ }
+
+ @Override
+ public boolean isAssignableTo(JClassType possibleSupertype) {
+ return possibleSupertype.isAssignableFrom(this);
}
@Override
@@ -180,10 +355,31 @@
}
@Override
+ public JWildcardType isWildcard() {
+ return null;
+ }
+
+ /**
+ */
+ public void setTypeArguments(JClassType[] typeArgs) {
+ this.typeArgs.addAll(Arrays.asList(typeArgs));
+ }
+
+ @Override
+ public String toString() {
+ if (isInterface() != null) {
+ return "interface " + getParameterizedQualifiedSourceName();
+ }
+
+ return "class " + getParameterizedQualifiedSourceName();
+ }
+
+ @Override
protected JClassType findNestedTypeImpl(String[] typeName, int index) {
return members.findNestedTypeImpl(typeName, index);
}
+ @Override
protected void getOverridableMethodsOnSuperclassesAndThisClass(
Map<String, JMethod> methodsBySignature) {
members.getOverridableMethodsOnSuperclassesAndThisClass(methodsBySignature);
@@ -197,14 +393,179 @@
*
* @param methodsBySignature
*/
+ @Override
protected void getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(
Map<String, JMethod> methodsBySignature) {
members.getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
}
- void addTypeArg(JClassType type) {
- assert (type.isPrimitive() == null);
- typeArgs.add(type);
+ @Override
+ JClassType getSubstitutedType(JParameterizedType parameterizedType) {
+ if (this == parameterizedType) {
+ return this;
+ }
+
+ JClassType[] newTypeArgs = new JClassType[typeArgs.size()];
+ for (int i = 0; i < newTypeArgs.length; ++i) {
+ newTypeArgs[i] = typeArgs.get(i).getSubstitutedType(parameterizedType);
+ }
+
+ return getOracle().getParameterizedType(getBaseType(), getEnclosingType(),
+ newTypeArgs);
}
-}
+ /**
+ * Returns the {@link JClassType} that is a substitute for the given
+ * {@link JTypeParameter}. If there is no substitution, the original
+ * {@link JTypeParameter} is returned.
+ */
+ JClassType getTypeParameterSubstitution(JTypeParameter typeParameter) {
+ JClassType substitute = substitutionMap.get(typeParameter);
+ if (substitute != null) {
+ return substitute;
+ }
+
+ return typeParameter;
+ }
+
+ boolean hasTypeArgs(JClassType[] otherArgTypes) {
+ if (otherArgTypes.length != typeArgs.size()) {
+ return false;
+ }
+
+ for (int i = 0; i < otherArgTypes.length; ++i) {
+ // Identity tests are ok since identity is durable within an oracle.
+ //
+ if (otherArgTypes[i] != typeArgs.get(i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Initialize a map of substitutions for {@link JTypeParameter}s to
+ * corresponding {@link JClassType}s.
+ */
+ void initializeTypeParameterSubstitutionMap() {
+ JParameterizedType currentParameterizedType = this;
+
+ while (currentParameterizedType != null) {
+ JGenericType genericType = currentParameterizedType.getBaseType();
+ JTypeParameter[] typeParameters = genericType.getTypeParameters();
+ JClassType[] typeArguments = currentParameterizedType.getTypeArgs();
+
+ for (JTypeParameter typeParameter : typeParameters) {
+ substitutionMap.put(typeParameter,
+ typeArguments[typeParameter.getOrdinal()]);
+ }
+
+ if (currentParameterizedType.isStatic()) {
+ break;
+ }
+
+ JClassType maybeParameterizedType = currentParameterizedType.getEnclosingType();
+ if (maybeParameterizedType == null
+ || maybeParameterizedType.isParameterized() == null) {
+ break;
+ }
+ currentParameterizedType = maybeParameterizedType.isParameterized();
+ }
+ }
+
+ /**
+ * Returns the flattened view of the type hierarchy.
+ */
+ private Set<JClassType> getFlattenedTypeHierarchy(JClassType type) {
+ Set<JClassType> typesSeen = new HashSet<JClassType>();
+ getFlattenedTypeHierarchyRecursive(type, typesSeen);
+ return typesSeen;
+ }
+
+ private void getFlattenedTypeHierarchyRecursive(JClassType type,
+ Set<JClassType> typesSeen) {
+ if (typesSeen.contains(type)) {
+ return;
+ }
+ typesSeen.add(type);
+
+ // Superclass
+ JClassType superclass = type.getSuperclass();
+ if (superclass != null) {
+ getFlattenedTypeHierarchyRecursive(superclass, typesSeen);
+ }
+
+ // Check the interfaces
+ JClassType[] intfs = type.getImplementedInterfaces();
+ for (JClassType intf : intfs) {
+ getFlattenedTypeHierarchyRecursive(intf, typesSeen);
+ }
+ }
+
+ /**
+ * Look at the type hierarchy and see if we can find a parameterized type that
+ * has the same base type as this instance. If we find one then we check to
+ * see if the type arguments are compatible. If they are, then we record what
+ * the typeArgument needs to be replaced with in order to make it a proper
+ * subtype of this parameterized type.
+ */
+ private boolean isSubtype(JClassType subtype, Set<JClassType> typeHierarchy,
+ Map<JClassType, JClassType> substitutions, boolean lookForSubstitutions) {
+ if (typeHierarchy.contains(this)) {
+ return true;
+ }
+
+ for (JClassType type : typeHierarchy) {
+ JParameterizedType parameterizedType = type.isParameterized();
+ if (parameterizedType == null) {
+ continue;
+ }
+
+ if (parameterizedType.getBaseType() != getBaseType()) {
+ continue;
+ }
+
+ // Check the type arguments to see if they are compatible.
+ JClassType[] otherTypeArgs = parameterizedType.getTypeArgs();
+ JClassType[] myTypeArgs = getTypeArgs();
+ boolean validSubstitution = true;
+ for (int i = 0; i < myTypeArgs.length; ++i) {
+ JClassType otherTypeArg = otherTypeArgs[i];
+ JClassType myTypeArg = myTypeArgs[i];
+
+ validSubstitution = myTypeArg == otherTypeArg;
+ if (!validSubstitution) {
+ if (lookForSubstitutions) {
+ // Make sure that the other type argument is assignable from mine
+ validSubstitution = otherTypeArg.isAssignableFrom(myTypeArg);
+ } else {
+ // Looking for strict subtypes; only wildcards allow a non-exact
+ // match
+ JWildcardType isWildcard = myTypeArg.isWildcard();
+ if (isWildcard != null) {
+ validSubstitution = myTypeArg.isAssignableFrom(otherTypeArg);
+ }
+ }
+ }
+
+ if (!validSubstitution) {
+ break;
+ }
+
+ substitutions.put(otherTypeArg, myTypeArg);
+ }
+
+ if (validSubstitution) {
+ /*
+ * At this point we know that the type can be a subtype and we know the
+ * substitution to apply.
+ */
+ return true;
+ }
+ }
+
+ // Can't be a subtype regardless of substitution.
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java
index fbbb82c..2d1e9ce 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JPrimitiveType.java
@@ -66,7 +66,7 @@
public JType getErasedType() {
return this;
}
-
+
@Override
public String getJNISignature() {
return jni;
@@ -95,6 +95,11 @@
}
@Override
+ public JEnumType isEnum() {
+ return null;
+ }
+
+ @Override
public JClassType isInterface() {
// intentional null
return null;
@@ -116,4 +121,14 @@
// intentional null
return null;
}
+
+ @Override
+ public JWildcardType isWildcard() {
+ return null;
+ }
+
+ @Override
+ JPrimitiveType getSubstitutedType(JParameterizedType parameterizedType) {
+ return this;
+ }
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java
index a4aceca..2d207e2 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRawType.java
@@ -15,18 +15,46 @@
*/
package com.google.gwt.core.ext.typeinfo;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
/**
* Represents a raw type; that is a generic type with no type arguments.
*/
public class JRawType extends JDelegatingClassType {
+ private static final Substitution ERASURE_SUBSTITUTION = new Substitution() {
+ public JType getSubstitution(JType type) {
+ return type.getErasedType();
+ }
+ };
- private final Members members = new Members(this);
+ private static JClassType normalizeType(JClassType type) {
+ JRawType isRawType = type.isRawType();
+ if (isRawType != null) {
+ return isRawType.getGenericType();
+ }
- public JRawType(JGenericType genericType) {
+ JParameterizedType isParameterized = type.isParameterized();
+ if (isParameterized != null) {
+ return isParameterized.getBaseType();
+ }
+
+ return type;
+ }
+
+ private final JClassType enclosingType;
+
+ private List<JClassType> interfaces;
+
+ private final AbstractMembers members;
+
+ public JRawType(JGenericType genericType, JClassType enclosingType) {
super.setBaseType(genericType);
- // TODO: type substitutions setting up fields/methods!
+ this.enclosingType = enclosingType;
+
+ // NOTE: this instance is not considered a nested type of the enclosing type
+
+ members = new DelegateMembers(this, getBaseType(), ERASURE_SUBSTITUTION);
}
@Override
@@ -49,8 +77,11 @@
return members.findNestedType(typeName);
}
+ @Override
public JGenericType getBaseType() {
- return (JGenericType) baseType;
+ JGenericType genericType = super.getBaseType().isGenericType();
+ assert (genericType != null);
+ return genericType;
}
@Override
@@ -79,6 +110,19 @@
}
@Override
+ public JClassType[] getImplementedInterfaces() {
+ if (interfaces == null) {
+ interfaces = new ArrayList<JClassType>();
+ JClassType[] intfs = getBaseType().getImplementedInterfaces();
+ for (JClassType intf : intfs) {
+ JClassType newIntf = intf.getErasedType();
+ interfaces.add(newIntf);
+ }
+ }
+ return interfaces.toArray(TypeOracle.NO_JCLASSES);
+ }
+
+ @Override
public JMethod getMethod(String name, JType[] paramTypes)
throws NotFoundException {
return members.getMethod(name, paramTypes);
@@ -116,12 +160,12 @@
@Override
public String getQualifiedSourceName() {
- return baseType.getQualifiedSourceName();
+ return getBaseType().getQualifiedSourceName();
}
@Override
public String getSimpleSourceName() {
- return baseType.getSimpleSourceName();
+ return getBaseType().getSimpleSourceName();
}
@Override
@@ -141,8 +185,25 @@
}
@Override
- public boolean isDefaultInstantiable() {
- return getBaseType().isDefaultInstantiableIfParameterized();
+ public JClassType getSuperclass() {
+ JClassType baseSuper = getBaseType().getSuperclass();
+ if (baseSuper == null) {
+ return null;
+ }
+
+ return baseSuper.getErasedType();
+ }
+
+ @Override
+ public boolean isAssignableFrom(JClassType possibleSubtype) {
+ JClassType type = normalizeType(possibleSubtype);
+ return getBaseType().isAssignableFrom(type);
+ }
+
+ @Override
+ public boolean isAssignableTo(JClassType possibleSupertype) {
+ JClassType type = normalizeType(possibleSupertype);
+ return getBaseType().isAssignableTo(type);
}
@Override
@@ -161,25 +222,15 @@
}
@Override
- protected JClassType findNestedTypeImpl(String[] typeName, int index) {
- return members.findNestedTypeImpl(typeName, index);
+ public JWildcardType isWildcard() {
+ return null;
}
- protected void getOverridableMethodsOnSuperclassesAndThisClass(
- Map<String, JMethod> methodsBySignature) {
- members.getOverridableMethodsOnSuperclassesAndThisClass(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 void getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(
- Map<String, JMethod> methodsBySignature) {
- members.getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
+ @Override
+ JRawType getSubstitutedType(JParameterizedType parameterizedType) {
+ /*
+ * Raw types do not participate in substitution.
+ */
+ return this;
}
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
index c0c84d3..74da5ea 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JRealClassType.java
@@ -59,7 +59,7 @@
private String lazyQualifiedName;
- private final Members members = new Members(this);
+ private final AbstractMembers members = new Members(this);
private final HasMetaData metaData = new MetaData();
@@ -376,6 +376,11 @@
}
@Override
+ public JEnumType isEnum() {
+ return null;
+ }
+
+ @Override
public JGenericType isGenericType() {
return null;
}
@@ -439,13 +444,19 @@
return 0 != (modifierBits & TypeOracle.MOD_STATIC);
}
+ @Override
+ public JWildcardType isWildcard() {
+ return null;
+ }
+
+ @Override
public void setSuperclass(JClassType type) {
assert (type != null);
assert (isInterface() == null);
this.superclass = type;
JRealClassType realSuperType;
if (type.isParameterized() != null) {
- realSuperType = type.isParameterized().getBaseType();
+ realSuperType = (JRealClassType) type.isParameterized().getBaseType();
} else if (type.isRawType() != null) {
realSuperType = type.isRawType().getGenericType();
} else {
@@ -545,6 +556,11 @@
}
}
+ @Override
+ JRealClassType getSubstitutedType(JParameterizedType parameterizedType) {
+ return this;
+ }
+
void notifySuperTypes() {
notifySuperTypesOf(this);
}
@@ -555,5 +571,4 @@
void removeFromSupertypes() {
removeSubtype(this);
}
-
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java
index 2ed4aad..c16d62c 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JType.java
@@ -59,6 +59,15 @@
return isInterface();
}
+ /**
+ * 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 JClassType isInterface();
public abstract JParameterizedType isParameterized();
@@ -67,4 +76,19 @@
public abstract JRawType isRawType();
+ public JTypeParameter isTypeParameter() {
+ return null;
+ }
+
+ public abstract JWildcardType isWildcard();
+
+ /**
+ * 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 JType getSubstitutedType(JParameterizedType parameterizedType);
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java
index cfea518..58cb21d 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JTypeParameter.java
@@ -15,6 +15,9 @@
*/
package com.google.gwt.core.ext.typeinfo;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Represents one of the type parameters in a generic type.
*/
@@ -22,30 +25,35 @@
private JBound bounds;
private final JGenericType declaringClass;
private final JAbstractMethod declaringMethod;
+ private final int ordinal;
private final String typeName;
- public JTypeParameter(String typeName, JAbstractMethod declaringMethod) {
+ public JTypeParameter(String typeName, JAbstractMethod declaringMethod,
+ int ordinal) {
this.typeName = typeName;
this.declaringMethod = declaringMethod;
this.declaringClass = null;
+ this.ordinal = ordinal;
declaringMethod.addTypeParameter(this);
}
- public JTypeParameter(String typeName, JGenericType declaringClass) {
+ public JTypeParameter(String typeName, JGenericType declaringClass,
+ int ordinal) {
this.typeName = typeName;
this.declaringClass = declaringClass;
this.declaringMethod = null;
+ this.ordinal = ordinal;
declaringClass.addTypeParameter(this);
}
@Override
public JField findField(String name) {
- return baseType.findField(name);
+ return getBaseType().findField(name);
}
@Override
public JMethod findMethod(String name, JType[] paramTypes) {
- return baseType.findMethod(name, paramTypes);
+ return getBaseType().findMethod(name, paramTypes);
}
public JBound getBounds() {
@@ -58,47 +66,71 @@
@Override
public JField getField(String name) {
- return baseType.getField(name);
+ return getBaseType().getField(name);
}
@Override
public JField[] getFields() {
- return baseType.getFields();
+ return getBaseType().getFields();
}
public JClassType getFirstBound() {
- return baseType;
+ return getBaseType();
}
@Override
public JMethod getMethod(String name, JType[] paramTypes)
throws NotFoundException {
- return baseType.getMethod(name, paramTypes);
+ return getBaseType().getMethod(name, paramTypes);
}
@Override
public JMethod[] getMethods() {
- return baseType.getMethods();
+ return getBaseType().getMethods();
}
@Override
public String getName() {
return typeName;
}
-
+
@Override
public String getParameterizedQualifiedSourceName() {
return typeName;
}
-
+
@Override
public String getQualifiedSourceName() {
- return typeName;
+ return typeName + bounds.getQualifiedSourceName();
}
@Override
public String getSimpleSourceName() {
- return typeName;
+ return typeName + bounds.getSimpleSourceName();
+ }
+
+ @Override
+ public JClassType[] getSubtypes() {
+ JClassType[] subtypes = super.getSubtypes();
+ List<JClassType> intersectionTypes = new ArrayList<JClassType>();
+ for (JClassType subtype : subtypes) {
+ if (isAssignableFrom(subtype)) {
+ intersectionTypes.add(subtype);
+ }
+ }
+ return intersectionTypes.toArray(TypeOracle.NO_JCLASSES);
+ }
+
+ @Override
+ public boolean isAssignableFrom(JClassType possibleSubtype) {
+ // TODO: Should this compute an intersection?
+ return getFirstBound().isAssignableFrom(possibleSubtype);
+ }
+
+ @Override
+ public boolean isAssignableTo(JClassType possibleSupertype) {
+ // TODO: Should this compute an intersection?
+ return getFirstBound().isAssignableTo(possibleSupertype);
}
@Override
@@ -116,6 +148,16 @@
return null;
}
+ @Override
+ public JTypeParameter isTypeParameter() {
+ return this;
+ }
+
+ @Override
+ public JWildcardType isWildcard() {
+ return null;
+ }
+
public void setBounds(JBound bounds) {
this.bounds = bounds;
super.setBaseType(bounds.getFirstBound());
@@ -123,10 +165,19 @@
@Override
public String toString() {
- if (baseType.isInterface() != null) {
+ if (getBaseType().isInterface() != null) {
return "interface " + getQualifiedSourceName();
} else {
return "class " + getQualifiedSourceName();
}
}
+
+ int getOrdinal() {
+ return ordinal;
+ }
+
+ @Override
+ JClassType getSubstitutedType(JParameterizedType parameterizedType) {
+ return parameterizedType.getTypeParameterSubstitution(this);
+ }
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JUpperBound.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JUpperBound.java
new file mode 100644
index 0000000..3762cd9
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JUpperBound.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+/**
+ * Represents the extends bound used in {@link JTypeParameter}s and
+ * {@link JWildcardType}s.
+ */
+public class JUpperBound extends JBound {
+ public JUpperBound(JClassType upperBound) {
+ this(new JClassType[] {upperBound});
+ }
+
+ /**
+ *
+ */
+ public JUpperBound(JClassType[] upperBounds) {
+ super(upperBounds);
+ }
+
+ @Override
+ public JLowerBound isLowerBound() {
+ return null;
+ }
+
+ @Override
+ public JUpperBound isUpperBound() {
+ return this;
+ }
+
+ @Override
+ JClassType[] getSubtypes() {
+ return getFirstBound().getSubtypes();
+ }
+
+ @Override
+ boolean isAssignableFrom(JBound possibleSubWildcard) {
+ JClassType firstBound = getFirstBound();
+
+ JUpperBound upperBound = possibleSubWildcard.isUpperBound();
+ if (upperBound != null) {
+ // Upper bound
+ return firstBound.isAssignableFrom(upperBound.getFirstBound());
+ }
+
+ // Lower bound
+ JClassType javaLangObject = firstBound.getOracle().getJavaLangObject();
+ return firstBound == javaLangObject
+ && possibleSubWildcard.getFirstBound() == javaLangObject;
+ }
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java
index 2cece8a..580e966 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JWildcardType.java
@@ -19,22 +19,21 @@
* Represents a wildcard type argument to a parameterized type.
*/
public class JWildcardType extends JDelegatingClassType implements HasBounds {
-
private final JBound bounds;
public JWildcardType(JBound bounds) {
- this.bounds = bounds;
super.setBaseType(bounds.getFirstBound());
+ this.bounds = bounds;
}
@Override
public JField findField(String name) {
- return baseType.findField(name);
+ return getBaseType().findField(name);
}
@Override
public JMethod findMethod(String name, JType[] paramTypes) {
- return baseType.findMethod(name, paramTypes);
+ return getBaseType().findMethod(name, paramTypes);
}
public JBound getBounds() {
@@ -43,37 +42,52 @@
@Override
public JField getField(String name) {
- return baseType.getField(name);
+ return getBaseType().getField(name);
}
@Override
public JField[] getFields() {
- return baseType.getFields();
+ return getBaseType().getFields();
}
public JClassType getFirstBound() {
- return baseType;
+ return getBounds().getFirstBound();
}
@Override
public JMethod getMethod(String name, JType[] paramTypes)
throws NotFoundException {
- return baseType.getMethod(name, paramTypes);
+ return getBaseType().getMethod(name, paramTypes);
}
@Override
public JMethod[] getMethods() {
- return baseType.getMethods();
+ return getBaseType().getMethods();
}
@Override
public String getQualifiedSourceName() {
- return "?";
+ return "?" + bounds.getQualifiedSourceName();
}
@Override
public String getSimpleSourceName() {
- return "?";
+ return "?" + bounds.getSimpleSourceName();
+ }
+
+ @Override
+ public JClassType[] getSubtypes() {
+ return bounds.getSubtypes();
+ }
+
+ @Override
+ public boolean isAssignableFrom(JClassType possibleSubtype) {
+ JWildcardType possibleSubWildcard = possibleSubtype.isWildcard();
+ if (possibleSubWildcard != null) {
+ return getBounds().isAssignableFrom(possibleSubWildcard.getBounds());
+ }
+
+ return getBaseType().isAssignableFrom(possibleSubtype);
}
@Override
@@ -90,4 +104,51 @@
public JRawType isRawType() {
return null;
}
+
+ @Override
+ public JWildcardType isWildcard() {
+ return this;
+ }
+
+ @Override
+ JClassType getSubstitutedType(JParameterizedType parameterizedType) {
+ JClassType[] currentBounds = bounds.getBounds();
+ JClassType[] newBounds = new JClassType[currentBounds.length];
+ for (int i = 0; i < currentBounds.length; ++i) {
+ newBounds[i] = currentBounds[i].getSubstitutedType(parameterizedType);
+ }
+
+ JBound newBound = bounds.isLowerBound() != null
+ ? new JLowerBound(newBounds) : new JUpperBound(newBounds);
+ return getOracle().getWildcardType(newBound);
+ }
+
+ /**
+ * Returns <code>true</code> if this instance has the same bounds that are
+ * requested.
+ *
+ * @param otherBounds
+ * @return <code>true</code> if this instance has the same bounds that are
+ * requested
+ */
+ boolean hasBounds(JBound otherBounds) {
+ if ((bounds.isUpperBound() != null && otherBounds.isLowerBound() != null)
+ || (bounds.isLowerBound() != null && otherBounds.isUpperBound() != null)) {
+ return false;
+ }
+
+ JClassType[] boundTypes = bounds.getBounds();
+ JClassType[] otherBoundTypes = otherBounds.getBounds();
+
+ if (boundTypes.length != otherBoundTypes.length) {
+ return false;
+ }
+
+ for (int i = 0; i < boundTypes.length; ++i) {
+ if (boundTypes[i] != otherBoundTypes[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/Members.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/Members.java
index f77b78e..7ff2d8b 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/Members.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/Members.java
@@ -16,249 +16,34 @@
package com.google.gwt.core.ext.typeinfo;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
/**
* A container for methods and fields.
*/
-class Members {
-
- protected final List<JConstructor> constructors = new ArrayList<JConstructor>();
- private JMethod[] cachedOverridableMethods;
- private final JClassType classType;
+class Members extends AbstractMembers {
+ private final List<JConstructor> constructors = new ArrayList<JConstructor>();
private final Map<String, JField> fields = new HashMap<String, JField>();
private final Map<String, List<JMethod>> methods = new HashMap<String, List<JMethod>>();
- private final Map<String, JClassType> nestedTypes = new HashMap<String, JClassType>();
public Members(JClassType classType) {
- this.classType = classType;
+ super(classType);
}
- public JConstructor findConstructor(JType[] paramTypes) {
- JConstructor[] ctors = getConstructors();
- for (int i = 0; i < ctors.length; i++) {
- JConstructor candidate = ctors[i];
- if (candidate.hasParamTypes(paramTypes)) {
- return candidate;
- }
- }
- return null;
+ @Override
+ protected List<JConstructor> doGetConstructors() {
+ return constructors;
}
- public JField findField(String name) {
- return fields.get(name);
+ @Override
+ protected Map<String, JField> doGetFields() {
+ return fields;
}
- public JMethod findMethod(String name, JType[] paramTypes) {
- JMethod[] overloads = getOverloads(name);
- for (int i = 0; i < overloads.length; i++) {
- JMethod candidate = overloads[i];
- if (candidate.hasParamTypes(paramTypes)) {
- return candidate;
- }
- }
- return null;
+ @Override
+ protected Map<String, List<JMethod>> doGetMethods() {
+ return methods;
}
-
- public JClassType findNestedType(String typeName) {
- String[] parts = typeName.split("\\.");
- return findNestedTypeImpl(parts, 0);
- }
-
- public JConstructor getConstructor(JType[] paramTypes)
- throws NotFoundException {
- JConstructor result = findConstructor(paramTypes);
- if (result == null) {
- throw new NotFoundException();
- }
- return result;
- }
-
- public JConstructor[] getConstructors() {
- return constructors.toArray(TypeOracle.NO_JCTORS);
- }
-
- public JField getField(String name) {
- JField field = findField(name);
- assert (field != null);
- return field;
- }
-
- public JField[] getFields() {
- return fields.values().toArray(TypeOracle.NO_JFIELDS);
- }
-
- public JMethod getMethod(String name, JType[] paramTypes)
- throws NotFoundException {
- JMethod result = findMethod(name, paramTypes);
- if (result == null) {
- throw new NotFoundException();
- }
- return result;
- }
-
- public JMethod[] getMethods() {
- List<JMethod> resultMethods = new ArrayList<JMethod>();
- for (List<JMethod> overloads : methods.values()) {
- resultMethods.addAll(overloads);
- }
- return resultMethods.toArray(TypeOracle.NO_JMETHODS);
- }
-
- public JClassType getNestedType(String typeName) throws NotFoundException {
- JClassType result = findNestedType(typeName);
- if (result == null) {
- throw new NotFoundException();
- }
- return result;
- }
-
- public JClassType[] getNestedTypes() {
- return nestedTypes.values().toArray(TypeOracle.NO_JCLASSES);
- }
-
- public JMethod[] getOverloads(String name) {
- List<?> resultMethods = methods.get(name);
- if (resultMethods != null) {
- return resultMethods.toArray(TypeOracle.NO_JMETHODS);
- } else {
- return TypeOracle.NO_JMETHODS;
- }
- }
-
- public JMethod[] getOverridableMethods() {
- if (cachedOverridableMethods == null) {
- Map<String, JMethod> methodsBySignature = new TreeMap<String, JMethod>();
- getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
- if (classType.isClass() != null) {
- getOverridableMethodsOnSuperclassesAndThisClass(methodsBySignature);
- }
- int size = methodsBySignature.size();
- Collection<JMethod> leafMethods = methodsBySignature.values();
- cachedOverridableMethods = leafMethods.toArray(new JMethod[size]);
- }
- return cachedOverridableMethods;
- }
-
- protected void addConstructor(JConstructor ctor) {
- assert (!constructors.contains(ctor));
- constructors.add(ctor);
- }
-
- protected void addField(JField field) {
- Object existing = fields.put(field.getName(), field);
- assert (existing == null);
- }
-
- protected void addMethod(JMethod method) {
- String methodName = method.getName();
- List<JMethod> overloads = methods.get(methodName);
- if (overloads == null) {
- overloads = new ArrayList<JMethod>();
- methods.put(methodName, overloads);
- }
- overloads.add(method);
- }
-
- protected void addNestedType(JClassType type) {
- nestedTypes.put(type.getSimpleSourceName(), type);
- }
-
- protected JClassType findNestedTypeImpl(String[] typeName, int index) {
- JClassType found = nestedTypes.get(typeName[index]);
- if (found == null) {
- return null;
- } else if (index < typeName.length - 1) {
- return found.findNestedTypeImpl(typeName, index + 1);
- } else {
- return found;
- }
- }
-
- protected void getOverridableMethodsOnSuperclassesAndThisClass(
- Map<String, JMethod> methodsBySignature) {
- assert (classType.isClass() != null);
-
- // Recurse first so that more derived methods will clobber less derived
- // methods.
- JClassType superClass = classType.getSuperclass();
- if (superClass != null) {
- superClass.getOverridableMethodsOnSuperclassesAndThisClass(methodsBySignature);
- }
-
- JMethod[] declaredMethods = getMethods();
- for (int i = 0; i < declaredMethods.length; i++) {
- JMethod method = declaredMethods[i];
-
- // Ensure that this method is overridable.
- if (method.isFinal() || method.isPrivate()) {
- // We cannot override this method, so skip it.
- continue;
- }
-
- // We can override this method, so record it.
- String sig = computeInternalSignature(method);
- methodsBySignature.put(sig, method);
- }
- }
-
- /**
- * 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 void getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(
- Map<String, JMethod> methodsBySignature) {
- // Recurse first so that more derived methods will clobber less derived
- // methods.
- JClassType[] superIntfs = classType.getImplementedInterfaces();
- for (int i = 0; i < superIntfs.length; i++) {
- JClassType superIntf = superIntfs[i];
- superIntf.getOverridableMethodsOnSuperinterfacesAndMaybeThisInterface(methodsBySignature);
- }
-
- if (classType.isInterface() == null) {
- // This is not an interface, so we're done after having visited its
- // implemented interfaces.
- return;
- }
-
- JMethod[] declaredMethods = getMethods();
- for (int i = 0; i < declaredMethods.length; i++) {
- JMethod method = declaredMethods[i];
-
- String sig = computeInternalSignature(method);
- JMethod existing = methodsBySignature.get(sig);
- if (existing != null) {
- JClassType existingType = existing.getEnclosingType();
- JClassType thisType = method.getEnclosingType();
- if (thisType.isAssignableFrom(existingType)) {
- // The existing method is in a more-derived type, so don't replace it.
- continue;
- }
- }
- methodsBySignature.put(sig, method);
- }
- }
-
- private String computeInternalSignature(JMethod method) {
- StringBuffer sb = new StringBuffer();
- sb.setLength(0);
- sb.append(method.getName());
- JParameter[] params = method.getParameters();
- for (int j = 0; j < params.length; j++) {
- JParameter param = params[j];
- sb.append("/");
- sb.append(param.getType().getQualifiedSourceName());
- }
- return sb.toString();
- }
-
}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/MetaData.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/MetaData.java
index 92fb5ba..dd4adaf 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/MetaData.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/MetaData.java
@@ -24,6 +24,23 @@
class MetaData implements HasMetaData {
+ /**
+ * Copy metadata from one metadata container to another. Perhaps overly
+ * paranoid but HasMetaData elements are mutable.
+ *
+ * @param dest
+ * @param src
+ */
+ static void copy(HasMetaData dest, HasMetaData src) {
+ String[] tagNames = src.getMetaDataTags();
+ for (String tagName : tagNames) {
+ String[][] tagValueSets = src.getMetaData(tagName);
+ for (String[] tagValues : tagValueSets) {
+ dest.addMetaData(tagName, tagValues);
+ }
+ }
+ }
+
private final Map<String, List<String[]>> tagNameToStringArrayList = new HashMap<String, List<String[]>>();
public void addMetaData(String tagName, String[] values) {
@@ -83,4 +100,5 @@
}
return sb.toString();
}
+
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/Substitution.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/Substitution.java
new file mode 100644
index 0000000..f9df504
--- /dev/null
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/Substitution.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+/**
+ * Interface used to perform type parameter substitutions or raw type
+ * substitutions.
+ */
+interface Substitution {
+ JType getSubstitution(JType type);
+}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
index d657e71..dab0a9e 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
@@ -53,14 +53,12 @@
* </p>
*/
public class TypeOracle {
-
/**
* A reserved metadata tag to indicates that a field type, method return type
* or method parameter type is intended to be parameterized. Note that
* constructor type parameters are not supported at present.
*/
public static final String TAG_TYPEARGS = "gwt.typeArgs";
-
static final int MOD_ABSTRACT = 0x00000001;
static final int MOD_FINAL = 0x00000002;
static final int MOD_NATIVE = 0x00000004;
@@ -69,8 +67,8 @@
static final int MOD_PUBLIC = 0x00000020;
static final int MOD_STATIC = 0x00000040;
static final int MOD_TRANSIENT = 0x00000080;
- static final int MOD_VOLATILE = 0x00000100;
+ static final int MOD_VOLATILE = 0x00000100;
static final Annotation[] NO_ANNOTATIONS = new Annotation[0];
static final JClassType[] NO_JCLASSES = new JClassType[0];
static final JConstructor[] NO_JCTORS = new JConstructor[0];
@@ -174,12 +172,14 @@
private final Map<String, JPackage> packages = new HashMap<String, JPackage>();
- private final Map<String, JParameterizedType> parameterizedTypes = new HashMap<String, JParameterizedType>();
+ private final Map<String, List<JParameterizedType>> parameterizedTypes = new HashMap<String, List<JParameterizedType>>();
private int reloadCount = 0;
private final Map<CompilationUnitProvider, JClassType[]> typesByCup = new IdentityHashMap<CompilationUnitProvider, JClassType[]>();
+ private final Map<String, List<JWildcardType>> wildcardTypes = new HashMap<String, List<JWildcardType>>();
+
public TypeOracle() {
// Always create the default package.
//
@@ -320,25 +320,65 @@
* the same arguments return the same object.
*
* @param genericType a generic base class
+ * @param enclosingType
+ * @param typeArgs the type arguments bound to the specified generic type
+ * @return a type object representing this particular binding of type
+ * arguments to the specified generic
+ */
+ public JParameterizedType getParameterizedType(JGenericType genericType,
+ JClassType enclosingType, JClassType[] typeArgs) {
+
+ if (genericType.isMemberType()) {
+ if (genericType.getEnclosingType().isGenericType() != null
+ && enclosingType.isParameterized() == null
+ && enclosingType.isRawType() == null) {
+ throw new IllegalArgumentException(
+ "enclosingType needs to be a parameterized type or a raw type");
+ }
+ }
+
+ // TODO: validate that the type arguments satisfy the generic type parameter
+ // bounds if any were specified
+
+ // Uses the generated string signature to intern parameterized types.
+ //
+ JParameterizedType parameterized = new JParameterizedType(genericType,
+ enclosingType, typeArgs);
+
+ // TODO: parameterized qualified source name does not account for the type
+ // args of the enclosing type
+ String sig = parameterized.getParameterizedQualifiedSourceName();
+ List<JParameterizedType> candidates = parameterizedTypes.get(sig);
+ if (candidates == null) {
+ candidates = new ArrayList<JParameterizedType>();
+ parameterizedTypes.put(sig, candidates);
+ } else {
+ for (JParameterizedType candidate : candidates) {
+ if (candidate.hasTypeArgs(typeArgs)) {
+ return candidate;
+ }
+ }
+ }
+
+ candidates.add(parameterized);
+
+ return parameterized;
+ }
+
+ /**
+ * Gets the parameterized type object that represents the combination of a
+ * specified raw type and a set of type arguments. The returned type always
+ * has a stable identity so as to guarantee that all calls to this method with
+ * the same arguments return the same object.
+ *
+ * @param genericType a generic base class
* @param typeArgs the type arguments bound to the specified generic type
* @return a type object representing this particular binding of type
* arguments to the specified generic
*/
public JParameterizedType getParameterizedType(JGenericType genericType,
JClassType[] typeArgs) {
- // Uses the generated string signature to intern parameterized types.
- //
- JParameterizedType parameterized = new JParameterizedType(genericType);
- for (int i = 0; i < typeArgs.length; i++) {
- parameterized.addTypeArg(typeArgs[i]);
- }
- String sig = parameterized.getParameterizedQualifiedSourceName();
- JParameterizedType existing = parameterizedTypes.get(sig);
- if (existing == null) {
- parameterizedTypes.put(sig, parameterized);
- existing = parameterized;
- }
- return existing;
+ return getParameterizedType(genericType, null, typeArgs);
}
public long getReloadCount() {
@@ -404,6 +444,26 @@
}
}
+ public JWildcardType getWildcardType(JBound bounds) {
+ JWildcardType wildcardType = new JWildcardType(bounds);
+ String sig = wildcardType.getQualifiedSourceName();
+ List<JWildcardType> candidates = wildcardTypes.get(sig);
+ if (candidates == null) {
+ candidates = new ArrayList<JWildcardType>();
+ wildcardTypes.put(sig, candidates);
+ } else {
+ for (JWildcardType candidate : candidates) {
+ if (candidate.hasBounds(bounds)) {
+ return candidate;
+ }
+ }
+ }
+
+ candidates.add(wildcardType);
+
+ return wildcardType;
+ }
+
/**
* Parses the string form of a type to produce the corresponding type object.
* The types that can be parsed include primitives, class and interface names,
@@ -500,7 +560,7 @@
/**
* Note, this method is called reflectively from the
- * {@link CacheManager#invalidateOnRefresh(TypeOracle)}
+ * {@link CacheManager#invalidateOnRefresh(TypeOracle)}.
*
* @param cup compilation unit whose types will be invalidated
*/
@@ -878,18 +938,21 @@
/**
* Remove any parameterized type that was invalidated because either its raw
- * type or any one of its type arguements was invalidated.
+ * type or any one of its type arguments was invalidated.
*
* @param invalidTypes set of types known to have been invalidated
*/
private void removeInvalidatedParameterizedTypes(Set<JClassType> invalidTypes) {
- Iterator<JParameterizedType> iter = parameterizedTypes.values().iterator();
+ Iterator<List<JParameterizedType>> listIterator = parameterizedTypes.values().iterator();
- while (iter.hasNext()) {
- JType type = iter.next();
-
- if (isInvalidatedTypeRecursive(type, invalidTypes)) {
- iter.remove();
+ while (listIterator.hasNext()) {
+ List<JParameterizedType> list = listIterator.next();
+ Iterator<JParameterizedType> typeIterator = list.iterator();
+ while (typeIterator.hasNext()) {
+ JType type = typeIterator.next();
+ if (isInvalidatedTypeRecursive(type, invalidTypes)) {
+ typeIterator.remove();
+ }
}
}
}
diff --git a/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java b/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java
index 79b2f4e..c93536a 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/AnnotationProxyFactory.java
@@ -186,6 +186,7 @@
// See if the value was explicitly declared
Object value = identifierToValue.get(name);
if (value != null) {
+ assert (method.getReturnType().isAssignableFrom(value.getClass()));
return value;
}
@@ -197,6 +198,11 @@
return annotationMethod.getDefaultValue();
}
+ if (method.getDeclaringClass() == Annotation.class
+ && "annotationType".equals(method.getName())) {
+ return annotationClass;
+ }
+
/*
* Maybe it's an Object method, just delegate to myself.
*/
diff --git a/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java b/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java
index 904f5d5..4e84999 100644
--- a/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jdt/TypeOracleBuilder.java
@@ -26,8 +26,11 @@
import com.google.gwt.core.ext.typeinfo.JBound;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JConstructor;
+import com.google.gwt.core.ext.typeinfo.JEnumConstant;
+import com.google.gwt.core.ext.typeinfo.JEnumType;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.core.ext.typeinfo.JGenericType;
+import com.google.gwt.core.ext.typeinfo.JLowerBound;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.core.ext.typeinfo.JParameter;
@@ -36,8 +39,9 @@
import com.google.gwt.core.ext.typeinfo.JRealClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.JTypeParameter;
-import com.google.gwt.core.ext.typeinfo.JWildcardType;
+import com.google.gwt.core.ext.typeinfo.JUpperBound;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
+import com.google.gwt.dev.jdt.CacheManager.Mapper;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.dev.util.Util;
@@ -46,6 +50,7 @@
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
@@ -68,9 +73,8 @@
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.NumberLiteral;
-import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
+import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -101,6 +105,7 @@
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -112,7 +117,7 @@
import java.util.regex.Pattern;
/**
- * Builds a {@link com.google.gwt.dev.typeinfo.TypeOracle} from a set of
+ * Builds a {@link com.google.gwt.core.ext.typeinfo.TypeOracle} from a set of
* compilation units.
* <p>
* For example,
@@ -128,7 +133,7 @@
* </pre>
*/
public class TypeOracleBuilder {
-
+ private static final JClassType[] NO_JCLASSES = new JClassType[0];
private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\s");
public static String computeBinaryClassName(JType type) {
@@ -283,6 +288,22 @@
return "package-info".equals(qname);
}
+ private static boolean maybeGeneric(TypeDeclaration typeDecl) {
+ if (typeDecl.typeParameters != null) {
+ // Definitely generic since it has type parameters
+ return true;
+ }
+
+ if (!typeDecl.binding.isStatic() && typeDecl.enclosingType != null) {
+ // Consider typeDecl to be generic if it is not static and its enclosing
+ // type is generic
+ return maybeGeneric(typeDecl.enclosingType);
+ }
+
+ return false;
+ }
+
+ // TODO: move into the Annotations class or create an AnnotationsUtil class?
private static HashMap<Class<? extends java.lang.annotation.Annotation>, java.lang.annotation.Annotation> newAnnotationMap() {
return new HashMap<Class<? extends java.lang.annotation.Annotation>, java.lang.annotation.Annotation>();
}
@@ -498,46 +519,6 @@
cud.traverse(new ASTVisitor() {
@Override
- public boolean visit(
- ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
- BlockScope scope) {
- ParameterizedTypeBinding jparameterizedType = (ParameterizedTypeBinding) parameterizedQualifiedTypeReference.resolvedType;
- processParameterizedType(jparameterizedType);
- return true; // do nothing by default, keep traversing
- }
-
- @Override
- public boolean visit(
- ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
- ClassScope scope) {
- ParameterizedTypeBinding jparameterizedType = (ParameterizedTypeBinding) parameterizedQualifiedTypeReference.resolvedType;
- processParameterizedType(jparameterizedType);
- return true; // do nothing by default, keep traversing
- }
-
- @Override
- public boolean visit(
- ParameterizedSingleTypeReference parameterizedSingleTypeReference,
- BlockScope scope) {
- if (parameterizedSingleTypeReference.resolvedType instanceof ParameterizedTypeBinding) {
- ParameterizedTypeBinding jparameterizedType = (ParameterizedTypeBinding) parameterizedSingleTypeReference.resolvedType;
- processParameterizedType(jparameterizedType);
- } else if (parameterizedSingleTypeReference.resolvedType instanceof SourceTypeBinding) {
- // nothing to do
- } else {
- assert false;
- }
- return true; // do nothing by default, keep traversing
- }
-
- @Override
- public boolean visit(
- ParameterizedSingleTypeReference parameterizedSingleTypeReference,
- ClassScope scope) {
- return true; // do nothing by default, keep traversing
- }
-
- @Override
public boolean visit(TypeDeclaration typeDecl, BlockScope scope) {
JClassType enclosingType = identityMapper.get(typeDecl.binding.enclosingType());
processType(typeDecl, enclosingType, true);
@@ -609,20 +590,37 @@
return oracle;
}
- private JBound createTypeVariableBounds(TreeLogger logger,
+ private JUpperBound createTypeVariableBounds(TreeLogger logger,
TypeVariableBinding tvBinding) {
- TypeBinding firstBound = tvBinding.firstBound;
- if (firstBound == null) {
- firstBound = tvBinding.superclass;
+ TypeBinding jfirstBound = tvBinding.firstBound;
+ if (jfirstBound == null) {
+ // No bounds were specified, so we default to Object
+ JClassType upperBound = (JClassType) resolveType(logger,
+ tvBinding.superclass);
+ /*
+ * Can't test for equality with TypeOracle.getJavaLangObject() since it
+ * may not be initialized at this point
+ */
+ assert (Object.class.getName().equals(upperBound.getQualifiedSourceName()));
+ return new JUpperBound(upperBound);
}
- JClassType firstBoundType = (JClassType) resolveType(logger, firstBound);
- JBound bounds = new JBound(firstBoundType);
- for (ReferenceBinding ref : tvBinding.superInterfaces()) {
- JClassType bound = (JClassType) resolveType(logger, ref);
- assert (bound.isInterface() != null);
- bounds.addUpperBound(bound);
+
+ List<JClassType> bounds = new ArrayList<JClassType>();
+ JClassType firstBound = (JClassType) resolveType(logger, jfirstBound);
+ if (firstBound.isClass() != null) {
+ bounds.add(firstBound);
}
- return bounds;
+
+ ReferenceBinding[] jsuperInterfaces = tvBinding.superInterfaces();
+ for (ReferenceBinding jsuperInterface : jsuperInterfaces) {
+ JClassType superInterface = (JClassType) resolveType(logger,
+ jsuperInterface);
+ assert (superInterface != null);
+ assert (superInterface.isInterface() != null);
+ bounds.add(superInterface);
+ }
+
+ return new JUpperBound(bounds.toArray(NO_JCLASSES));
}
private Object evaluateAnnotationExpression(TreeLogger logger,
@@ -650,6 +648,26 @@
return null;
}
+ try {
+ Method method = clazz.getMethod(identifier, new Class[0]);
+ Class<?> expectedClass = method.getReturnType();
+ Class<? extends Object> actualClass = value.getClass();
+ if (expectedClass.isArray() && !actualClass.isArray()) {
+ /*
+ * JSL3 Section 9.7 single element annotations can skip the curly
+ * braces; means we do not get an array
+ */
+ assert (expression instanceof SingleMemberAnnotation);
+ Object array = Array.newInstance(expectedClass.getComponentType(), 1);
+ Array.set(array, 0, value);
+ value = array;
+ }
+ } catch (SecurityException e) {
+ return null;
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+
identifierToValue.put(identifier, value);
}
@@ -796,6 +814,11 @@
}
private String getQualifiedName(ReferenceBinding binding) {
+ if (binding.isMemberType()) {
+ return String.valueOf(CharOperation.concat(
+ binding.enclosingType().readableName(), binding.sourceName, '.'));
+ }
+
return CharOperation.toString(binding.compoundName);
}
@@ -812,15 +835,6 @@
}
/**
- * Maps a ParameterizedTypeBinding into a JParameterizedType.
- */
- private void processParameterizedType(ParameterizedTypeBinding binding) {
- TypeOracle oracle = cacheManager.getTypeOracle();
- // TODO Get the JParameterized type for the current binding, fill it out
- // as you would a JClassType.
- }
-
- /**
* Maps a TypeDeclaration into a JClassType.
*/
private void processType(TypeDeclaration typeDecl, JClassType enclosingType,
@@ -838,7 +852,7 @@
*/
return;
}
-
+
String qname;
String jclassName;
if (binding instanceof LocalTypeBinding) {
@@ -854,10 +868,10 @@
qname = getQualifiedName(binding);
jclassName = getSimpleName(typeDecl);
}
+
if (oracle.findType(qname) != null) {
- // The oracle already knew about this type.
- // Don't re-add it.
- //
+ // TODO: gname of generic types includes the type arguments, I think that
+ // this would cause inner classes to not be found.
return;
}
@@ -876,22 +890,17 @@
if (jclassIsAnnonation) {
type = new JAnnotationType(oracle, cup, pkg, enclosingType, isLocalType,
jclassName, declStart, declEnd, bodyStart, bodyEnd, jclassIsIntf);
- } else if (typeDecl.typeParameters != null
- && typeDecl.typeParameters.length > 0) {
+ } else if (maybeGeneric(typeDecl)) {
type = new JGenericType(oracle, cup, pkg, enclosingType, isLocalType,
jclassName, declStart, declEnd, bodyStart, bodyEnd, jclassIsIntf);
- for (TypeParameter jtypeParameter : typeDecl.typeParameters) {
- JTypeParameter typeParameter = new JTypeParameter(
- String.valueOf(jtypeParameter.name), (JGenericType) type);
- cacheManager.setTypeForBinding(jtypeParameter.binding, typeParameter);
- }
+ } else if (binding.isEnum()) {
+ type = new JEnumType(oracle, cup, pkg, enclosingType, isLocalType,
+ jclassName, declStart, declEnd, bodyStart, bodyEnd, jclassIsIntf);
} else {
type = new JRealClassType(oracle, cup, pkg, enclosingType, isLocalType,
jclassName, declStart, declEnd, bodyStart, bodyEnd, jclassIsIntf);
}
- // TODO: enums?
-
cacheManager.setTypeForBinding(binding, type);
}
@@ -945,7 +954,14 @@
}
String name = String.valueOf(jfield.name);
- JField field = new JField(enclosingType, name, declaredAnnotations);
+ JField field;
+ if (jfield.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
+ assert (enclosingType.isEnum() != null);
+ field = new JEnumConstant(enclosingType, name, declaredAnnotations,
+ jfield.binding.original().id);
+ } else {
+ field = new JField(enclosingType, name, declaredAnnotations);
+ }
// Get modifiers.
//
@@ -1014,6 +1030,12 @@
if (jmethod.isConstructor()) {
method = new JConstructor(enclosingType, name, declStart, declEnd,
bodyStart, bodyEnd, declaredAnnotations);
+
+ // Resolve the type parameters, since they may be used as the return type,
+ // etc.
+ if (!resolveTypeParameters(logger, method, jmethod.typeParameters())) {
+ return false;
+ }
} else {
if (jmethod.isAnnotationMethod()) {
AnnotationMethodDeclaration annotationMethod = (AnnotationMethodDeclaration) jmethod;
@@ -1029,25 +1051,12 @@
bodyStart, bodyEnd, declaredAnnotations);
}
- // Add declared type parameters.
- if (jmethod.typeParameters() != null) {
- for (TypeParameter jtypeParameter : jmethod.typeParameters()) {
- JTypeParameter typeParameter = new JTypeParameter(
- String.valueOf(jtypeParameter.name), method);
- cacheManager.getIdentityMapper().put(jtypeParameter.binding,
- typeParameter);
- }
- JTypeParameter[] typeParameters = method.getTypeParameters();
- for (TypeParameter jtypeParameter : jmethod.typeParameters()) {
- JTypeParameter typeParameter = (JTypeParameter) cacheManager.getIdentityMapper().get(
- jtypeParameter.binding);
- JBound bounds = createTypeVariableBounds(logger,
- jtypeParameter.binding);
- typeParameter.setBounds(bounds);
- }
+ // Resolve the type parameters, since they may be used as the return type,
+ // etc.
+ if (!resolveTypeParameters(logger, method, jmethod.typeParameters())) {
+ return false;
}
- // Add the return type if necessary.
TypeBinding jreturnType = ((MethodDeclaration) jmethod).returnType.resolvedType;
JType returnType = resolveType(logger, jreturnType);
if (returnType == null) {
@@ -1241,12 +1250,13 @@
// First check the type oracle to prefer type identity with the type
// oracle we're assimilating into.
//
- String typeName = String.valueOf(referenceBinding.readableName());
+ String typeName = getQualifiedName(referenceBinding);
JType resolvedType = oracle.findType(typeName);
if (resolvedType == null) {
// Otherwise, it should be something we've mapped during this build.
resolvedType = cacheManager.getTypeForBinding(referenceBinding);
}
+
if (resolvedType != null) {
if (binding instanceof RawTypeBinding) {
// Use the raw type instead of the generic type.
@@ -1284,78 +1294,104 @@
// Check for parameterized.
if (binding instanceof ParameterizedTypeBinding) {
ParameterizedTypeBinding ptBinding = (ParameterizedTypeBinding) binding;
- JClassType[] typeArguments = new JClassType[ptBinding.arguments.length];
+
+ /*
+ * NOTE: it is possible for ParameterizedTypeBinding.arguments to be null.
+ * This can happen if a generic class has a non-static, non-generic, inner
+ * class that references a TypeParameter from its enclosing generic type.
+ * You would think that typeVariables() would do the right thing but it
+ * does not.
+ */
+ TypeBinding[] arguments = ptBinding.arguments;
+ int nArguments = arguments != null ? arguments.length : 0;
+ JClassType[] typeArguments = new JClassType[nArguments];
+ boolean failed = false;
for (int i = 0; i < typeArguments.length; ++i) {
- typeArguments[i] = (JClassType) resolveType(logger,
- ptBinding.arguments[i]);
+ typeArguments[i] = (JClassType) resolveType(logger, arguments[i]);
+ if (typeArguments[i] == null) {
+ failed = true;
+ }
}
- JGenericType baseType = (JGenericType) resolveType(logger, ptBinding.type);
- return oracle.getParameterizedType(baseType, typeArguments);
+ JClassType enclosingType = null;
+ if (ptBinding.enclosingType() != null) {
+ enclosingType = (JClassType) resolveType(logger,
+ ptBinding.enclosingType());
+ if (enclosingType == null) {
+ failed = true;
+ }
+ }
+
+ /*
+ * NOTE: In the case where a generic type has a nested, non-static,
+ * non-generic type. The type for the binding will not be a generic type.
+ */
+ JType resolveType = resolveType(logger, ptBinding.type);
+ if (resolveType == null) {
+ failed = true;
+ }
+
+ if (!failed) {
+ JEnumType enumType = resolveType.isEnum();
+ if (enumType != null) {
+ /*
+ * An enumerated type that is nested within a generic type is referenced
+ * via a parameterized type by JDT. In this case we just return the
+ * enumerated type and don't treat it as a parameterized type since
+ * enumerations cannot be parameterized and are implicitly static.
+ */
+ return enumType;
+ }
+
+ JGenericType genericType = (JGenericType) resolveType;
+ return oracle.getParameterizedType(genericType, enclosingType,
+ typeArguments);
+ } else {
+ // Fall-through to failure
+ }
}
if (binding instanceof TypeVariableBinding) {
TypeVariableBinding tvBinding = (TypeVariableBinding) binding;
JTypeParameter typeParameter = (JTypeParameter) cacheManager.getTypeForBinding(tvBinding);
assert (typeParameter != null);
-
- if (typeParameter.getBounds() == null) {
- // Setup a dummy bound to prevent recursion
- typeParameter.setBounds(new JBound(null));
- JBound bounds = createTypeVariableBounds(logger, tvBinding);
- typeParameter.setBounds(bounds);
- }
return typeParameter;
}
if (binding instanceof WildcardBinding) {
WildcardBinding wcBinding = (WildcardBinding) binding;
+
+ assert (wcBinding.otherBounds == null);
+
JBound bounds;
switch (wcBinding.boundKind) {
case Wildcard.EXTENDS: {
- JClassType firstBoundType = (JClassType) resolveType(logger,
+ assert (wcBinding.bound != null);
+ JClassType upperBound = (JClassType) resolveType(logger,
wcBinding.bound);
- bounds = new JBound(firstBoundType);
- if (wcBinding.otherBounds != null) {
- for (TypeBinding bound : wcBinding.otherBounds) {
- JClassType boundType = (JClassType) resolveType(logger, bound);
- bounds.addUpperBound(boundType);
- }
- }
+ bounds = new JUpperBound(new JClassType[] {upperBound});
}
break;
case Wildcard.SUPER: {
- // TODO: verify
- JClassType firstBoundType = (JClassType) resolveType(logger,
- wcBinding.erasure());
- assert (firstBoundType.getQualifiedSourceName().equals("java.lang.Object"));
- bounds = new JBound(firstBoundType);
-
assert (wcBinding.bound != null);
- JClassType boundType = (JClassType) resolveType(logger,
+ JClassType lowerBound = (JClassType) resolveType(logger,
wcBinding.bound);
- bounds.addLowerBound(boundType);
- if (wcBinding.otherBounds != null) {
- for (TypeBinding bound : wcBinding.otherBounds) {
- boundType = (JClassType) resolveType(logger, bound);
- bounds.addLowerBound(boundType);
- }
- }
+ bounds = new JLowerBound(new JClassType[] {lowerBound});
}
break;
case Wildcard.UNBOUND: {
- JClassType firstBoundType = (JClassType) resolveType(logger,
+ JClassType upperBound = (JClassType) resolveType(logger,
wcBinding.erasure());
- assert (firstBoundType.getQualifiedSourceName().equals("java.lang.Object"));
- bounds = new JBound(firstBoundType);
+ bounds = new JUpperBound(new JClassType[] {upperBound});
+ assert (bounds.getFirstBound().getQualifiedSourceName().equals("java.lang.Object"));
}
break;
default:
assert false : "WildcardBinding of unknown boundKind???";
return null;
}
- JWildcardType wcType = new JWildcardType(bounds);
- return wcType;
+
+ return oracle.getWildcardType(bounds);
}
// Log other cases we know about that don't make sense.
@@ -1411,9 +1447,11 @@
}
type.addAnnotations(declaredAnnotations);
- // Resolve type parameters
- List<JTypeParameter> typeParameters = new ArrayList<JTypeParameter>();
- if (!resolveTypeParameters(logger, jclass.typeParameters, typeParameters)) {
+ // Resolve type parameters for generic types
+ JGenericType genericType = type.isGenericType();
+ if (genericType != null
+ && !resolveTypeParameters(logger, type.isGenericType(),
+ jclass.typeParameters)) {
// Failed to resolve
return false;
}
@@ -1471,18 +1509,49 @@
}
private boolean resolveTypeParameter(TreeLogger logger,
- TypeParameter jtypeParameter, List<JTypeParameter> typeParameters) {
- JTypeParameter typeParameter = (JTypeParameter) cacheManager.getIdentityMapper().get(
- jtypeParameter.binding);
- typeParameters.add(typeParameter);
+ JAbstractMethod method, TypeParameter jtypeParameter, int ordinal) {
+ JTypeParameter typeParameter = new JTypeParameter(
+ String.valueOf(jtypeParameter.name), method, ordinal);
+ return resolveTypeParameter(logger, jtypeParameter.binding, typeParameter);
+ }
+
+ private boolean resolveTypeParameter(TreeLogger logger,
+ JGenericType genericType, TypeParameter jtypeParameter, int ordinal) {
+ JTypeParameter typeParameter = new JTypeParameter(
+ String.valueOf(jtypeParameter.name), genericType, ordinal);
+ return resolveTypeParameter(logger, jtypeParameter.binding, typeParameter);
+ }
+
+ private boolean resolveTypeParameter(TreeLogger logger,
+ TypeVariableBinding binding, JTypeParameter typeParameter) {
+ Mapper identityMapper = cacheManager.getIdentityMapper();
+ assert (identityMapper.get(binding) == null);
+
+ identityMapper.put(binding, typeParameter);
+
+ JBound bounds = createTypeVariableBounds(logger, binding);
+ typeParameter.setBounds(bounds);
+
return true;
}
private boolean resolveTypeParameters(TreeLogger logger,
- TypeParameter[] jtypeParameters, List<JTypeParameter> typeParameters) {
+ JAbstractMethod method, TypeParameter[] jtypeParameters) {
if (jtypeParameters != null) {
for (int i = 0; i < jtypeParameters.length; ++i) {
- if (!resolveTypeParameter(logger, jtypeParameters[i], typeParameters)) {
+ if (!resolveTypeParameter(logger, method, jtypeParameters[i], i)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean resolveTypeParameters(TreeLogger logger,
+ JGenericType genericType, TypeParameter[] jtypeParameters) {
+ if (jtypeParameters != null) {
+ for (int i = 0; i < jtypeParameters.length; ++i) {
+ if (!resolveTypeParameter(logger, genericType, jtypeParameters[i], i)) {
return false;
}
}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JArrayTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JArrayTypeTest.java
new file mode 100644
index 0000000..8f7c829
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JArrayTypeTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.test.CA;
+import com.google.gwt.core.ext.typeinfo.test.CB;
+import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
+import com.google.gwt.core.ext.typeinfo.test.MyList;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link JArrayType}.
+ */
+public class JArrayTypeTest extends TestCase {
+ /*
+ * Returns int[][]
+ */
+ private static JArrayType getIntArray(TypeOracle oracle) {
+ return oracle.getArrayType(getIntVector(oracle));
+ }
+ /*
+ * Returns int[].
+ */
+ private static JArrayType getIntVector(TypeOracle oracle) {
+ return oracle.getArrayType(JPrimitiveType.INT);
+ }
+
+ /*
+ * Returns Object[][]
+ */
+ private static JArrayType getObjectArray(TypeOracle oracle) {
+ return oracle.getArrayType(getObjectVector(oracle));
+ }
+
+ /*
+ * Returns Object[].
+ */
+ private static JArrayType getObjectVector(TypeOracle oracle) {
+ return oracle.getArrayType(oracle.getJavaLangObject());
+ }
+
+ private final boolean logToConsole = false;
+
+ private final ModuleContext moduleContext = new ModuleContext(logToConsole
+ ? new PrintWriterTreeLogger() : TreeLogger.NULL,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+
+ public JArrayTypeTest() throws UnableToCompleteException {
+ }
+
+ public void testGetSubtypes() throws NotFoundException {
+ JArrayType testArrayType = getTestArrayType();
+
+ JArrayType[] arraySubtypes = testArrayType.getSubtypes();
+ assertEquals(2, arraySubtypes.length);
+
+ for (int i = 0; i < arraySubtypes.length; ++i) {
+ assertTrue(testArrayType.isAssignableFrom(arraySubtypes[i]));
+ }
+ }
+
+ public void testGetSuperclass() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JArrayType intVector = getIntVector(oracle);
+ JArrayType intArray = getIntArray(oracle);
+ JArrayType objVector = getObjectVector(oracle);
+ JArrayType objArray = getObjectArray(oracle);
+
+ // Check that superclass of int[][] is Object[]
+ assertEquals(objVector, intArray.getSuperclass());
+
+ // Check that superclass of int[] is Object
+ assertEquals(oracle.getJavaLangObject(), intVector.getSuperclass());
+
+ // CA
+ JClassType caType = oracle.getType(CA.class.getCanonicalName());
+
+ // CA[]
+ JArrayType caVector = oracle.getArrayType(caType);
+
+ // CA[][]
+ JArrayType caArray = oracle.getArrayType(caVector);
+
+ // CB
+ JClassType cbType = oracle.getType(CB.class.getCanonicalName());
+
+ // CB[]
+ JArrayType cbVector = oracle.getArrayType(cbType);
+
+ // CB[][]
+ JArrayType cbArray = oracle.getArrayType(cbVector);
+
+ // Check that CB[][] has a supertype of CA[][]
+ JClassType cbArraySuper = cbArray.getSuperclass();
+ assertEquals(caArray, cbArraySuper);
+
+ // Check that CA[][] has a supertype of Object[][]
+ JClassType cbArraySuperSuper = cbArraySuper.getSuperclass();
+ assertEquals(objArray, cbArraySuperSuper);
+
+ // Check that Object[][] has supertype of Object[]
+ JClassType cbArraySuperSuperSuper = cbArraySuperSuper.getSuperclass();
+ assertEquals(objVector, cbArraySuperSuperSuper);
+
+ // Check that Object[] has supertype of Object
+ JClassType cbArraySuperSuperSuperSuper = cbArraySuperSuperSuper.getSuperclass();
+ assertEquals(oracle.getJavaLangObject(), cbArraySuperSuperSuperSuper);
+ }
+
+ public void testIsAssignableFrom() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+
+ JArrayType intVector = getIntVector(oracle);
+ JArrayType intArray = getIntArray(oracle);
+ JArrayType objVector = getObjectVector(oracle);
+ JArrayType objArray = getObjectArray(oracle);
+
+ // Object[] is not assignable from int[]
+ assertFalse(objVector.isAssignableFrom(intVector));
+ assertFalse(intVector.isAssignableFrom(objVector));
+
+ // Object[] is assignable from int[][]
+ assertTrue(objVector.isAssignableFrom(intArray));
+
+ // Object[] is assignable from Object[][]
+ assertTrue(objVector.isAssignableFrom(objArray));
+
+ // int[] is assignable from int[]
+ assertTrue(intVector.isAssignableFrom(intVector));
+
+ // int[] is assignable from int[][]
+ assertFalse(intArray.isAssignableFrom(intVector));
+
+ JClassType testSubtype = oracle.getType(MyCustomList.class.getName());
+
+ // MyCustomList[]
+ JArrayType testArraySubtype = oracle.getArrayType(testSubtype);
+
+ // MyList[] is assignable from MyCustomList[]
+ assertTrue(getTestArrayType().isAssignableFrom(testArraySubtype));
+
+ // MyCustomList[]
+ JArrayType testVectorSubtype = oracle.getArrayType(testArraySubtype);
+
+ // MyList[] is not assignable from MyCustomList[][]
+ assertFalse(getTestArrayType().isAssignableFrom(testVectorSubtype));
+
+ // MyCustomList[] is not assignable from MyList[]
+ assertFalse(testArraySubtype.isAssignableFrom(getTestArrayType()));
+ }
+
+ public void testIsAssignableTo() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType testSubtype = oracle.getType(MyCustomList.class.getName());
+ JArrayType testArraySubtype = oracle.getArrayType(testSubtype);
+
+ // MyCustomList[] is assignable to MyList[]
+ assertTrue(testArraySubtype.isAssignableTo(getTestArrayType()));
+
+ // MyCustomList[] is assignable to Object
+ assertTrue(testArraySubtype.isAssignableTo(oracle.getJavaLangObject()));
+
+ // MyList[] is not assignable to MyCustomList[]
+ assertFalse(getTestArrayType().isAssignableTo(testArraySubtype));
+
+ // MyList[] is assignable to MyCustomList[]
+ assertFalse(getTestArrayType().isAssignableTo(testArraySubtype));
+
+ }
+
+ private JArrayType getTestArrayType() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType genericComponentType = oracle.getType(MyList.class.getName()).isGenericType();
+
+ return oracle.getArrayType(genericComponentType);
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
index 26a3cf8..462da59 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JClassTypeTest.java
@@ -20,6 +20,7 @@
import com.google.gwt.dev.jdt.StaticCompilationUnitProvider;
import com.google.gwt.dev.jdt.TypeOracleBuilder;
import com.google.gwt.dev.jdt.URLCompilationUnitProvider;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import junit.framework.TestCase;
@@ -33,11 +34,18 @@
* Tests related to JClassType. See individual test methods to details.
*/
public class JClassTypeTest extends TestCase {
+ private final boolean logToConsole = false;
+ private final ModuleContext moduleContext = new ModuleContext(logToConsole
+ ? new PrintWriterTreeLogger() : TreeLogger.NULL,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
- public void testGetOverridableMethods() throws UnableToCompleteException,
- TypeOracleException {
+ public JClassTypeTest() throws UnableToCompleteException {
+ }
+
+ public void testGetOverridableMethods() throws TypeOracleException {
TreeLogger logger = TreeLogger.NULL;
- TypeOracle typeOracle = buildOracleFromTestPackage(logger);
+ TypeOracle typeOracle = moduleContext.getOracle();
+ // TypeOracle typeOracle = buildOracleFromTestPackage(logger);
String[] noParams = new String[0];
String[] intObjectParams = new String[] {"int", "java.lang.Object"};
@@ -224,7 +232,7 @@
// No files found.
return;
}
-
+
for (int i = 0; i < files.length; i++) {
File file = files[i];
if (file.isFile()) {
@@ -301,54 +309,4 @@
}
}
}
-
- /**
- * Looks in the package containing this class and uses it as an anchor for
- * including all the classes under the "test" subpackage.
- *
- * TODO: This is not generalized yet, but it could be made reusable and put
- * into TypeOracleBuilder.
- *
- * @return
- * @throws URISyntaxException
- * @throws UnableToCompleteException
- * @throws MalformedURLException
- */
- private TypeOracle buildOracleFromTestPackage(TreeLogger logger)
- throws UnableToCompleteException {
- Throwable caught;
- try {
- // Find the source path using this class as an anchor.
- String className = getClass().getName();
- String resName = className.replace('.', '/') + ".java";
- URL location = getClass().getClassLoader().getResource(resName);
- assertNotNull("Ensure that source is in classpath for: " + resName,
- location);
- String absPath = new File(new URI(location.toString())).getAbsolutePath();
- int sourcePathEntryLen = absPath.length() - resName.length();
- File sourcePathEntry = new File(absPath.substring(0, sourcePathEntryLen));
-
- // Determine the starting package name.
- int lastDot = className.lastIndexOf('.');
- String pkgName = (lastDot < 0 ? "test" : className.substring(0, lastDot)
- + ".test");
-
- // Create the builder to be filled in.
- TypeOracleBuilder builder = new TypeOracleBuilder();
-
- // Add java.lang.Object.
- builder.addCompilationUnit(new StaticCompilationUnitProvider("java.lang",
- "Object", "package java.lang; public class Object { }".toCharArray()));
-
- // Recursively walk the directories.
- addCompilationUnitsInPath(builder, sourcePathEntry, pkgName);
- return builder.build(logger);
- } catch (URISyntaxException e) {
- caught = e;
- } catch (MalformedURLException e) {
- caught = e;
- }
- logger.log(TreeLogger.ERROR, "Failed to build type oracle", caught);
- throw new UnableToCompleteException();
- }
}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JDelegatingClassTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JDelegatingClassTypeTest.java
new file mode 100644
index 0000000..f36935d
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JDelegatingClassTypeTest.java
@@ -0,0 +1,814 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import junit.framework.TestCase;
+
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+
+/**
+ * Base test cases for all {@link JDelegatingClassType}s.
+ */
+public abstract class JDelegatingClassTypeTest extends TestCase {
+
+ protected static void assertArraysEqual(Object[] expected, Object[] actual) {
+ assertTrue("Expected: \n" + Arrays.toString(expected) + ",\n Actual: \n"
+ + Arrays.toString(actual), Arrays.equals(expected, actual));
+ }
+
+ protected static void validateAbstractMethodSubstitution(
+ JAbstractMethod preSubMethod, JAbstractMethod postSubMethod,
+ Substitution substitution) {
+
+ assertEquals(preSubMethod.getName(), postSubMethod.getName());
+
+ assertEquals(preSubMethod.getModifierBits(),
+ postSubMethod.getModifierBits());
+
+ validateAnnotations(preSubMethod, postSubMethod);
+
+ validateMetaData(preSubMethod, postSubMethod);
+
+ JParameter[] preSubParams = preSubMethod.getParameters();
+ JParameter[] postSubParams = postSubMethod.getParameters();
+
+ assertEquals(preSubParams.length, postSubParams.length);
+
+ for (int j = 0; j < preSubParams.length; ++j) {
+ JParameter preSubParam = preSubParams[j];
+ JParameter postSubParam = postSubParams[j];
+
+ validateAnnotations(preSubParam, postSubParam);
+ validateMetaData(preSubParam, postSubParam);
+
+ assertEquals(substitution.getSubstitution(preSubParam.getType()),
+ postSubParam.getType());
+ }
+ }
+
+ protected static void validateAnnotations(HasAnnotations ha1,
+ HasAnnotations ha2) {
+ assertArraysEqual(ha1.getAnnotations(), ha2.getAnnotations());
+ }
+
+ protected static void validateConstructorSubstitutions(
+ JClassType preSubstitution, JClassType postSubstituion,
+ Substitution substitution) {
+ // Check the constructors
+ JConstructor[] preSubCtors = preSubstitution.getConstructors();
+ JConstructor[] postSubCtors = postSubstituion.getConstructors();
+ assertEquals(preSubCtors.length, postSubCtors.length);
+ for (int i = 0; i < preSubCtors.length; ++i) {
+ validateAbstractMethodSubstitution(preSubCtors[i], postSubCtors[i],
+ substitution);
+ }
+ }
+
+ protected static void validateDeclaredAnnotations(HasAnnotations ha1,
+ HasAnnotations ha2) {
+ assertArraysEqual(ha1.getDeclaredAnnotations(),
+ ha2.getDeclaredAnnotations());
+ }
+
+ protected static void validateEquals(TypeOracle oracle,
+ JClassType[] expectedTypes, JClassType actualTypes[]) {
+ oracle.sort(expectedTypes);
+ oracle.sort(actualTypes);
+
+ assertArraysEqual(expectedTypes, actualTypes);
+ }
+
+ protected static void validateFieldSubstitutions(JClassType preSubstitution,
+ JClassType postSubstituion, Substitution substitution) {
+ // Check the fields
+ JField[] preSubfields = preSubstitution.getFields();
+ JField[] postSubFields = postSubstituion.getFields();
+ assertEquals(preSubfields.length, postSubFields.length);
+ for (int i = 0; i < preSubfields.length; ++i) {
+ JField postSubField = postSubstituion.getField(preSubfields[i].getName());
+ assertNotNull(postSubField);
+ assertEquals(substitution.getSubstitution(preSubfields[i].getType()),
+ postSubField.getType());
+ }
+ }
+
+ protected static void validateFindConstructor(JClassType preSubstitution,
+ JClassType postSubstitution, Substitution substitution) {
+
+ JConstructor[] constructors = preSubstitution.getConstructors();
+ for (JConstructor constructor : constructors) {
+ JParameter[] params = constructor.getParameters();
+ JType[] paramTypes = new JType[params.length];
+
+ for (int i = 0; i < params.length; ++i) {
+ paramTypes[i] = substitution.getSubstitution(params[i].getType());
+ }
+
+ assertNotNull(postSubstitution.findConstructor(paramTypes));
+ }
+ }
+
+ /**
+ *
+ */
+ protected static void validateFindField(JClassType preSubstitution,
+ JClassType postSubstitution) {
+ JField[] fields = preSubstitution.getFields();
+ for (JField field : fields) {
+ assertNotNull(postSubstitution.findField(field.getName()));
+ }
+ }
+
+ protected static void validateFindMethod(JClassType preSubstitution,
+ JClassType postSubstitution, Substitution substitution) {
+
+ JMethod[] methods = preSubstitution.getMethods();
+ for (JMethod method : methods) {
+ JParameter[] params = method.getParameters();
+ JType[] paramTypes = new JType[params.length];
+
+ for (int i = 0; i < params.length; ++i) {
+ paramTypes[i] = substitution.getSubstitution(params[i].getType());
+ }
+
+ assertNotNull(postSubstitution.findMethod(method.getName(), paramTypes));
+ }
+ }
+
+ protected static void validateGetConstructor(JClassType preSubstitution,
+ JClassType postSubstitution, Substitution substitution)
+ throws NotFoundException {
+
+ JConstructor[] constructors = preSubstitution.getConstructors();
+ for (JConstructor constructor : constructors) {
+ JParameter[] params = constructor.getParameters();
+ JType[] paramTypes = new JType[params.length];
+
+ for (int i = 0; i < params.length; ++i) {
+ paramTypes[i] = substitution.getSubstitution(params[i].getType());
+ }
+
+ assertNotNull(postSubstitution.getConstructor(paramTypes));
+ }
+ }
+
+ /**
+ *
+ */
+ protected static void validateGetField(JClassType preSubstitution,
+ JClassType postSubstitution) {
+ JField[] fields = preSubstitution.getFields();
+ for (JField field : fields) {
+ assertNotNull(postSubstitution.getField(field.getName()));
+ }
+ }
+
+ protected static void validateGetMethod(JClassType preSubstitution,
+ JClassType postSubstitution, Substitution substitution)
+ throws NotFoundException {
+
+ JMethod[] methods = preSubstitution.getMethods();
+ for (JMethod method : methods) {
+ JParameter[] params = method.getParameters();
+ JType[] paramTypes = new JType[params.length];
+
+ for (int i = 0; i < params.length; ++i) {
+ paramTypes[i] = substitution.getSubstitution(params[i].getType());
+ }
+
+ assertNotNull(postSubstitution.getMethod(method.getName(), paramTypes));
+ }
+ }
+
+ protected static void validateGetOverloads(JClassType preSubstitution,
+ JClassType postSubstitution) {
+ JMethod[] methods = preSubstitution.getMethods();
+ for (JMethod method : methods) {
+ assertEquals(preSubstitution.getOverloads(method.getName()).length,
+ postSubstitution.getOverloads(method.getName()).length);
+ }
+ }
+
+ protected static void validateImplementedInterfaceSubstitution(
+ JClassType preSubstitution, JClassType postSubstituion,
+ Substitution substitution) {
+ JClassType[] preSubIntfs = preSubstitution.getImplementedInterfaces();
+ JClassType[] postSubIntfs = postSubstituion.getImplementedInterfaces();
+
+ assertEquals(preSubIntfs.length, postSubIntfs.length);
+
+ for (int i = 0; i < preSubIntfs.length; ++i) {
+ assertEquals(postSubIntfs[i],
+ substitution.getSubstitution(postSubIntfs[i]));
+ }
+ }
+
+ protected static void validateMetaData(HasMetaData md1, HasMetaData md2) {
+ validateMetaDataTags(md1, md2);
+
+ String[] md1TagNames = md1.getMetaDataTags();
+ String[] md2TagNames = md2.getMetaDataTags();
+
+ for (int i = 0; i < md1TagNames.length; ++i) {
+ assertEquals(md1TagNames[i], md2TagNames[i]);
+
+ String[][] md1TagValues = md1.getMetaData(md1TagNames[i]);
+ String[][] md2TagValues = md2.getMetaData(md2TagNames[i]);
+
+ assertTrue(Arrays.deepEquals(md1TagValues, md2TagValues));
+ }
+ }
+
+ protected static void validateMetaDataTags(HasMetaData md1, HasMetaData md2) {
+ assertEquals(md1.getMetaDataTags().length, md2.getMetaDataTags().length);
+ }
+
+ protected static void validateMethodSubstitution(JMethod preSubMethod,
+ JMethod postSubMethod, Substitution substitution) {
+
+ assertEquals(substitution.getSubstitution(preSubMethod.getReturnType()),
+ postSubMethod.getReturnType());
+
+ validateAbstractMethodSubstitution(preSubMethod, postSubMethod,
+ substitution);
+ }
+
+ protected static void validateMethodSubstitutions(JClassType preSubstitution,
+ JClassType postSubstituion, Substitution substitution)
+ throws NotFoundException {
+ // Check the methods
+ JMethod[] preSubMethods = preSubstitution.getMethods();
+ JMethod[] postSubMethods = postSubstituion.getMethods();
+ assertEquals(preSubMethods.length, postSubMethods.length);
+
+ for (int i = 0; i < preSubMethods.length; ++i) {
+ JMethod preSubMethod = preSubMethods[i];
+
+ JParameter[] preSubParams = preSubMethod.getParameters();
+ JType[] postSubParamTypes = new JType[preSubParams.length];
+ for (int j = 0; j < preSubParams.length; ++j) {
+ postSubParamTypes[j] = substitution.getSubstitution(preSubParams[j].getType());
+ }
+ JMethod postSubMethod = postSubstituion.getMethod(preSubMethod.getName(),
+ postSubParamTypes);
+
+ validateMethodSubstitution(preSubMethod, postSubMethod, substitution);
+ }
+ }
+
+ protected static void validateTypeSubstitution(JClassType preSubstitution,
+ JClassType postSubstituion, Substitution substitution)
+ throws NotFoundException {
+ if (preSubstitution.isGenericType() == null) {
+ return;
+ }
+
+ assertEquals(preSubstitution.getModifierBits(),
+ postSubstituion.getModifierBits());
+
+ validateAnnotations(preSubstitution, postSubstituion);
+
+ validateMetaData(preSubstitution, postSubstituion);
+
+ assertEquals(preSubstitution.getName(), postSubstituion.getName());
+ // assertEquals(preSubstitution.getSubstitution(substitution),
+ // postSubstituion);
+
+ // Check superclass
+ JClassType superClass = preSubstitution.getSuperclass();
+ if (superClass != null) {
+ validateTypeSubstitution(superClass, postSubstituion.getSuperclass(),
+ substitution);
+ }
+
+ // Check interfaces
+ validateImplementedInterfaceSubstitution(preSubstitution, postSubstituion,
+ substitution);
+
+ validateFieldSubstitutions(preSubstitution, postSubstituion, substitution);
+
+ validateConstructorSubstitutions(preSubstitution, postSubstituion,
+ substitution);
+
+ validateMethodSubstitutions(preSubstitution, postSubstituion, substitution);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findConstructor(com.google.gwt.core.ext.typeinfo.JType[])}.
+ */
+ public void testFindConstructor() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateFindConstructor(baseType, testType, getSubstitution());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findField(java.lang.String)}.
+ */
+ public void testFindField() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateFindField(baseType, testType);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findMethod(java.lang.String, com.google.gwt.core.ext.typeinfo.JType[])}.
+ */
+ public void testFindMethod() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateFindMethod(baseType, testType, getSubstitution());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#findNestedType(java.lang.String)}.
+ */
+ public abstract void testFindNestedType() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getAnnotation(java.lang.Class)}.
+ */
+ public void testGetAnnotation() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ Annotation[] annotations = baseType.getAnnotations();
+ for (Annotation annotation : annotations) {
+ assertNotNull(testType.getAnnotation(annotation.annotationType()));
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getAnnotations()}.
+ */
+ public void testGetAnnotations() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateAnnotations(baseType, testType);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getBaseType()}.
+ */
+ public void testGetBaseType() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ assertNotNull(testType.getBaseType());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getCompilationUnit()}.
+ */
+ public void testGetCompilationUnit() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(testType.getCompilationUnit(), baseType.getCompilationUnit());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getConstructor(com.google.gwt.core.ext.typeinfo.JType[])}.
+ */
+ public void testGetConstructor() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+ JConstructor[] constructors = baseType.getConstructors();
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getConstructors()}.
+ */
+ public void testGetConstructors() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateConstructorSubstitutions(baseType, testType, getSubstitution());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getDeclaredAnnotations()}.
+ */
+ public void testGetDeclaredAnnotations() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateDeclaredAnnotations(baseType, testType);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getEnclosingType()}.
+ */
+ public abstract void testGetEnclosingType() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getErasedType()}.
+ */
+ public void testGetErasedType() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.getErasedType(), testType.getErasedType());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getField(java.lang.String)}.
+ */
+ public void testGetField() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateGetField(baseType, testType);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getFields()}.
+ */
+ public void testGetFields() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateFieldSubstitutions(baseType, testType, getSubstitution());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getImplementedInterfaces()}.
+ */
+ public void testGetImplementedInterfaces() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateImplementedInterfaceSubstitution(baseType, testType,
+ getSubstitution());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getJNISignature()}.
+ */
+ public void testGetJNISignature() {
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getMetaData(java.lang.String)}.
+ */
+ public void testGetMetaData() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateMetaData(baseType, testType);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getMetaDataTags()}.
+ */
+ public void testGetMetaDataTags() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateMetaDataTags(baseType, testType);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getMethod(java.lang.String, com.google.gwt.core.ext.typeinfo.JType[])}.
+ */
+ public void testGetMethod() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateGetMethod(baseType, testType, getSubstitution());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getMethods()}.
+ */
+ public void testGetMethods() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateMethodSubstitutions(baseType, testType, getSubstitution());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getModifierBits()}.
+ */
+ public void testGetModifierBits() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.getModifierBits(), testType.getModifierBits());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getName()}.
+ */
+ public void testGetName() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.getName(), testType.getName());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getNestedType(java.lang.String)}.
+ */
+ public abstract void testGetNestedType() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getNestedTypes()}.
+ */
+ public abstract void testGetNestedTypes() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getOracle()}.
+ */
+ public void testGetOracle() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.getOracle(), testType.getOracle());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getOverloads(java.lang.String)}.
+ */
+ public void testGetOverloads() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ validateGetOverloads(baseType, testType);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getOverridableMethods()}.
+ */
+ public abstract void testGetOverridableMethods() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getPackage()}.
+ */
+ public void testGetPackage() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.getPackage(), testType.getPackage());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getSubtypes()}.
+ */
+ public abstract void testGetSubtypes() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#getSuperclass()}.
+ */
+ public void testGetSuperclass() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.getSuperclass() != null,
+ testType.getSuperclass() != null);
+
+ /*
+ * TODO: need to check that the super classes are consistent, if base super
+ * is generic then test type super should be parameterized with same super,
+ * etc.
+ */
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isAbstract()}.
+ */
+ public void testIsAbstract() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isAbstract(), testType.isAbstract());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isAnnotationPresent(java.lang.Class)}.
+ */
+ public void testIsAnnotationPresent() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ Annotation[] annotations = baseType.getAnnotations();
+ for (Annotation annotation : annotations) {
+ assertTrue(testType.isAnnotationPresent(annotation.annotationType()));
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isArray()}.
+ */
+ public void testIsArray() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isArray(), testType.isArray());
+
+ // TODO: check parameterized arrays
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isAssignableFrom(com.google.gwt.core.ext.typeinfo.JClassType)}.
+ */
+ public abstract void testIsAssignableFrom() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isAssignableTo(com.google.gwt.core.ext.typeinfo.JClassType)}.
+ */
+ public abstract void testIsAssignableTo() throws NotFoundException;
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isClass()}.
+ */
+ public void testIsClass() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isClass() != null, testType.isClass() != null);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isClassOrInterface()}.
+ */
+ public void testIsClassOrInterface() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isClassOrInterface() != null,
+ testType.isClassOrInterface() != null);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isDefaultInstantiable()}.
+ */
+ public void testIsDefaultInstantiable() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isDefaultInstantiable(),
+ testType.isDefaultInstantiable());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isEnum()}.
+ */
+ public void testIsEnum() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isEnum() != null, testType.isEnum() != null);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isInterface()}.
+ */
+ public void testIsInterface() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isInterface() != null, testType.isInterface() != null);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isLocalType()}.
+ */
+ public void testIsLocalType() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isLocalType(), testType.isLocalType());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isMemberType()}.
+ */
+ public void testIsMemberType() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isMemberType(), testType.isMemberType());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isPrimitive()}.
+ */
+ public void testIsPrimitive() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertNull(testType.isPrimitive());
+ assertNull(baseType.isPrimitive());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isPrivate()}.
+ */
+ public void testIsPrivate() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isPrivate(), testType.isPrivate());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isProtected()}.
+ */
+ public void testIsProtected() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isProtected(), testType.isProtected());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isPublic()}.
+ */
+ public void testIsPublic() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isPublic(), testType.isPublic());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JDelegatingClassType#isStatic()}.
+ */
+ public void testIsStatic() throws NotFoundException {
+ JDelegatingClassType testType = getTestType();
+ JClassType baseType = testType.getBaseType();
+
+ assertEquals(baseType.isStatic(), testType.isStatic());
+ }
+
+ protected abstract Substitution getSubstitution() throws NotFoundException;
+
+ protected abstract JDelegatingClassType getTestType()
+ throws NotFoundException;
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java
new file mode 100644
index 0000000..fdc1b38
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JEnumTypeTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.test.MyEnum;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.cfg.ModuleDefLoader;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link JEnumType}.
+ */
+public class JEnumTypeTest extends TestCase {
+ private final TreeLogger logger = TreeLogger.NULL;
+
+ private ModuleDef moduleDef;
+
+ private final TypeOracle typeOracle;
+
+ public JEnumTypeTest() throws UnableToCompleteException, NotFoundException {
+ moduleDef = ModuleDefLoader.loadFromClassPath(logger,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+ typeOracle = moduleDef.getTypeOracle(logger);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JEnumType#getEnumConstants()}.
+ *
+ * @throws NotFoundException
+ */
+ public void testGetEnumConstants() throws NotFoundException {
+ JClassType type = typeOracle.getType(MyEnum.class.getName());
+ JEnumType enumType = type.isEnum();
+ assertNotNull(enumType);
+
+ JEnumConstant[] enumConstants = enumType.getEnumConstants();
+ assertEquals(3, enumConstants.length);
+
+ for (JEnumConstant enumConstant : enumConstants) {
+ assertEquals(
+ Integer.parseInt(enumConstant.getName().substring(3)),
+ enumConstant.getOrdinal());
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JClassType#getFields()}.
+ *
+ * @throws NotFoundException
+ */
+ public void testGetFields() throws NotFoundException {
+ JClassType type = typeOracle.getType(MyEnum.class.getName());
+ JEnumType enumType = validateTypeIsEnum(type);
+
+ assertEquals(5, enumType.getFields().length);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JClassType#getField(String)}.
+ *
+ * @throws NotFoundException
+ */
+ public void testGetFieldString() throws NotFoundException {
+ JClassType type = typeOracle.getType(MyEnum.class.getName());
+
+ validateTypeIsEnum(type);
+
+ type.getField("VAL0");
+ type.getField("VAL1");
+ type.getField("VAL2");
+ type.getField("instanceField");
+ type.getField("e");
+ }
+
+ /**
+ * Test method for {@link JEnumType#getConstructors()}
+ *
+ * @throws NotFoundException
+ * @throws NotFoundException
+ */
+ public void testGetConstructors() throws NotFoundException {
+ JClassType type = typeOracle.getType(MyEnum.class.getName());
+ JEnumType enumType = validateTypeIsEnum(type);
+
+ assertEquals(1, enumType.getConstructors().length);
+ }
+
+ /**
+ * Test method for {@link JEnumType#getMethods()}
+ *
+ * @throws NotFoundException
+ */
+ public void testGetMethods() throws NotFoundException {
+ JClassType type = typeOracle.getType(MyEnum.class.getName());
+ JEnumType enumType = validateTypeIsEnum(type);
+
+ assertEquals(1, enumType.getMethods().length);
+ }
+
+ /**
+ * Test method for {@link com.google.gwt.core.ext.typeinfo.JEnumType#isEnum()}.
+ *
+ * @throws NotFoundException
+ */
+ public void testIsEnum() throws NotFoundException {
+ JClassType type = typeOracle.getType(MyEnum.class.getName());
+ validateTypeIsEnum(type);
+ }
+
+ private static JEnumType validateTypeIsEnum(JClassType type)
+ throws NotFoundException {
+ JEnumType maybeEnum = type.isEnum();
+ assertNotNull(maybeEnum);
+
+ JClassType enumType = type.getOracle().getType(Enum.class.getName());
+
+ assertTrue(enumType.isAssignableFrom(maybeEnum));
+
+ return maybeEnum;
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java
new file mode 100644
index 0000000..c054387
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JGenericTypeTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.test.GenericClass;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link JGenericType}.
+ */
+public class JGenericTypeTest extends TestCase {
+ private final boolean logToConsole = false;
+ private final ModuleContext moduleContext = new ModuleContext(logToConsole
+ ? new PrintWriterTreeLogger() : TreeLogger.NULL,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+
+ public JGenericTypeTest() throws UnableToCompleteException {
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JGenericType#getErasedType()}.
+ *
+ * @throws NotFoundException
+ */
+ public void testGetErasedType() throws NotFoundException {
+ JGenericType genericClass = getTestType();
+
+ assertEquals(genericClass.getRawType(), genericClass.getErasedType());
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JGenericType#getRawType()}.
+ *
+ * @throws NotFoundException
+ */
+ public void testGetRawType() throws NotFoundException {
+ JGenericType genericClass = getTestType();
+
+ JDelegatingClassTypeTest.validateTypeSubstitution(genericClass,
+ genericClass.getRawType(), new Substitution() {
+ public JType getSubstitution(JType type) {
+ return type.getErasedType();
+ }
+ });
+ }
+
+ /**
+ * Test method for {@link
+ * com.google.gwt.core.ext.typeinfo.JGenericType#getTypeParameters()}.
+ *
+ * @throws NotFoundException
+ */
+ public void testGetTypeParameters() throws NotFoundException {
+ JGenericType genericType = getTestType();
+ JTypeParameter[] typeParameters = genericType.getTypeParameters();
+
+ assertEquals(1, typeParameters.length);
+
+ JTypeParameter typeParameter = typeParameters[0];
+ assertEquals("T", typeParameter.getName());
+
+ JBound bound = typeParameter.getBounds();
+ assertNotNull(bound.isUpperBound());
+
+ JClassType[] bounds = bound.getBounds();
+ assertEquals(1, bounds.length);
+ assertEquals(moduleContext.getOracle().getJavaLangObject(), bounds[0]);
+ }
+
+ /**
+ * Returns the generic version of {@link GenericClass}.
+ */
+ protected JGenericType getTestType() throws NotFoundException {
+ JClassType type = moduleContext.getOracle().getType(
+ GenericClass.class.getName());
+ JGenericType genericType = type.isGenericType();
+ assertNotNull(genericType);
+ return genericType;
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java
new file mode 100644
index 0000000..50a06c4
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JParameterizedTypeTest.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.test.Base;
+import com.google.gwt.core.ext.typeinfo.test.Derived;
+import com.google.gwt.core.ext.typeinfo.test.GenericClass;
+import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
+import com.google.gwt.core.ext.typeinfo.test.MyIntegerList;
+import com.google.gwt.core.ext.typeinfo.test.MyList;
+import com.google.gwt.core.ext.typeinfo.test.GenericClass.GenericInnerClass;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Test for {@link JParameterizedType}.
+ */
+public class JParameterizedTypeTest extends JDelegatingClassTypeTest {
+ /**
+ * Helper for verifying parameterized substitutions.
+ */
+ static class ParameterizedSubstitution implements Substitution {
+ private final JParameterizedType parameterizedType;
+
+ public ParameterizedSubstitution(JParameterizedType parameterizedType) {
+ this.parameterizedType = parameterizedType;
+ }
+
+ public JType getSubstitution(JType type) {
+ return type.getSubstitutedType(parameterizedType);
+ }
+ }
+
+ private final JClassType integerType;
+ private final boolean logToConsole = false;
+ private final ModuleContext moduleContext = new ModuleContext(logToConsole
+ ? new PrintWriterTreeLogger() : TreeLogger.NULL,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+
+ public JParameterizedTypeTest() throws UnableToCompleteException,
+ NotFoundException {
+ integerType = moduleContext.getOracle().getType(Integer.class.getName());
+ }
+
+ @Override
+ public void testFindNestedType() {
+ // TODO: complete this test method
+ }
+
+ /**
+ * Checks that GenericClass<Integer> ends up with the correct substitutions.
+ *
+ * @throws NotFoundException
+ */
+ public void testGenericClass_Integer() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType genericType = getGenericTestType();
+ JClassType type = oracle.getParameterizedType(genericType,
+ new JClassType[] {integerType});
+ JParameterizedType parameterizedType = type.isParameterized();
+
+ validateTypeSubstitution(genericType, parameterizedType,
+ new ParameterizedSubstitution(parameterizedType));
+ }
+
+ public void testGenericClass_LowerBoundWildcard() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType genericType = getGenericTestType();
+ JWildcardType lowerBoundWildcard = oracle.getWildcardType(new JLowerBound(
+ new JClassType[] {integerType}));
+
+ JClassType type = oracle.getParameterizedType(genericType,
+ new JClassType[] {lowerBoundWildcard});
+ JParameterizedType parameterizedType = type.isParameterized();
+
+ validateTypeSubstitution(genericType, parameterizedType,
+ new ParameterizedSubstitution(parameterizedType));
+ }
+
+ public void testGenericClass_UnboundWildcard() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType genericType = getGenericTestType();
+ JWildcardType upperBoundWildcard = oracle.getWildcardType(new JUpperBound(
+ new JClassType[] {oracle.getJavaLangObject()}));
+
+ JClassType type = oracle.getParameterizedType(genericType,
+ new JClassType[] {upperBoundWildcard});
+ JParameterizedType parameterizedType = type.isParameterized();
+
+ validateTypeSubstitution(genericType, parameterizedType,
+ new ParameterizedSubstitution(parameterizedType));
+ }
+
+ public void testGenericClass_UpperBoundWildcard() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType genericType = getGenericTestType();
+ JWildcardType upperBoundWildcard = oracle.getWildcardType(new JUpperBound(
+ new JClassType[] {integerType}));
+
+ JClassType type = oracle.getParameterizedType(genericType,
+ new JClassType[] {upperBoundWildcard});
+ JParameterizedType parameterizedType = type.isParameterized();
+
+ validateTypeSubstitution(genericType, parameterizedType,
+ new ParameterizedSubstitution(parameterizedType));
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JParameterizedType#getEnclosingType()}.
+ *
+ * @throws NotFoundException
+ */
+ @Override
+ public void testGetEnclosingType() throws NotFoundException {
+ JParameterizedType testType = getTestType();
+
+ // Check that GenericClass<Integer> is not nested
+ assertNull(testType.getEnclosingType());
+
+ /*
+ * Check that GenericClass<Integer>.GenericInnerClass<Boolean> has //
+ * GenericClass<Integer> as its // enclosing type
+ */
+ JParameterizedType parameterizedInnerClass = getInnerParameterizedType();
+
+ assertEquals(testType, parameterizedInnerClass.getEnclosingType());
+ }
+
+ @Override
+ public void testGetNestedType() {
+ // TODO: complete this test method
+ }
+
+ /**
+ * Test method for {@link
+ * com.google.gwt.core.ext.typeinfo.JParameterizedType#getNestedTypes()}.
+ *
+ * @throws NotFoundException
+ */
+ @Override
+ public void testGetNestedTypes() throws NotFoundException {
+ JParameterizedType cut = getTestType();
+ JParameterizedType innerCut = getInnerParameterizedType();
+
+ // Check that inner parameterized types don't appear in the parent's nested
+ // type set
+ assertEquals(0, cut.getNestedTypes().length);
+
+ try {
+ cut.getNestedType(innerCut.getSimpleSourceName());
+ fail("Type " + cut.getQualifiedSourceName()
+ + " should report that it has no nested types");
+ } catch (NotFoundException ex) {
+ // Expected to get here
+ }
+ }
+
+ @Override
+ public void testGetOverridableMethods() throws NotFoundException {
+ // Tested via testOverridableMethods_Base, testOverridableMethods_Derived,
+ // testOverridableMethods_Derived_Integer
+ }
+
+ /**
+ * Tests the subtypes of MyList<Integer>. These should be:
+ * <ul>
+ * <li><code>MyIntegerList</code></li>
+ * <li><code>MyCustomList<? extends Serializable, Integer></code></li>
+ * </ul>
+ *
+ * @throws NotFoundException
+ */
+ @Override
+ public void testGetSubtypes() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType genericType = oracle.getType(MyList.class.getName()).isGenericType();
+
+ JParameterizedType parameterizedType = oracle.getParameterizedType(
+ genericType, new JClassType[] {integerType});
+ JClassType[] actualSubtypes = parameterizedType.getSubtypes();
+
+ JGenericType myCustomListType = oracle.getType(MyCustomList.class.getName()).isGenericType();
+ JParameterizedType parameterizedMyCustomList = oracle.getParameterizedType(
+ myCustomListType, new JClassType[] {
+ oracle.getWildcardType(new JUpperBound(
+ oracle.getType(Serializable.class.getName()))), integerType});
+ JClassType[] expected = {
+ oracle.getType(MyIntegerList.class.getName()),
+ parameterizedMyCustomList
+ };
+
+ validateEquals(oracle, expected, actualSubtypes);
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JParameterizedType#isAssignableFrom(JClassType)}.
+ */
+ @Override
+ public void testIsAssignableFrom() throws NotFoundException {
+ // Check that raw types can be assigned to a parameterized type
+ JParameterizedType testType = getTestType();
+ JClassType rawType = testType.getRawType();
+
+ assertTrue(testType.isAssignableFrom(rawType));
+
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType genericList = (JGenericType) oracle.getType(List.class.getName());
+
+ JWildcardType unboundWildcard = oracle.getWildcardType(new JUpperBound(
+ oracle.getJavaLangObject()));
+ JWildcardType numUpperBoundWildcard = oracle.getWildcardType(new JUpperBound(
+ oracle.getType(Number.class.getName())));
+
+ // List<?> should be assignable from List<? extends Number>
+ JParameterizedType unboundList = oracle.getParameterizedType(genericList,
+ new JClassType[] {unboundWildcard});
+ JParameterizedType numUpperBoundList = oracle.getParameterizedType(
+ genericList, new JClassType[] {numUpperBoundWildcard});
+ assertTrue(unboundList.isAssignableFrom(numUpperBoundList));
+ assertFalse(numUpperBoundList.isAssignableFrom(unboundList));
+
+ // List<? extends Number> should be assignable from List<? extends Integer>
+ JWildcardType intUpperBoundWildcard = oracle.getWildcardType(new JUpperBound(
+ integerType));
+
+ JParameterizedType intUpperBoundList = oracle.getParameterizedType(
+ genericList, new JClassType[] {intUpperBoundWildcard});
+ assertTrue(numUpperBoundList.isAssignableFrom(intUpperBoundList));
+ assertFalse(intUpperBoundList.isAssignableFrom(numUpperBoundList));
+
+ // List<? super Integer> should be assignable from List<? super Number>
+ JWildcardType numLowerBoundWildcard = oracle.getWildcardType(new JLowerBound(
+ oracle.getType(Number.class.getName())));
+ JWildcardType intLowerBoundWildcard = oracle.getWildcardType(new JLowerBound(
+ integerType));
+
+ JParameterizedType numLowerBoundList = oracle.getParameterizedType(
+ genericList, new JClassType[] {numLowerBoundWildcard});
+ JParameterizedType intLowerBoundList = oracle.getParameterizedType(
+ genericList, new JClassType[] {intLowerBoundWildcard});
+
+ assertTrue(intLowerBoundList.isAssignableFrom(numLowerBoundList));
+ assertFalse(numLowerBoundList.isAssignableFrom(intLowerBoundList));
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.core.ext.typeinfo.JParameterizedType#isAssignableTo(JClassType)}.
+ */
+ @Override
+ public void testIsAssignableTo() {
+ // TODO:
+ }
+
+ public void testOverridableMethods_Base() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType type = oracle.getType(Base.class.getName());
+ JGenericType genericType = type.isGenericType();
+ assertNotNull(genericType);
+
+ List<JMethod> expected = new ArrayList<JMethod>(
+ Arrays.asList(type.getOverloads("m")));
+ List<JMethod> actual = new ArrayList<JMethod>(
+ Arrays.asList(type.getOverridableMethods()));
+
+ validateOverridableMethods(expected, actual, true);
+ }
+
+ public void testOverridableMethods_Derived() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType type = oracle.getType(Derived.class.getName());
+ JGenericType genericType = type.isGenericType();
+ assertNotNull(genericType);
+
+ JClassType supertype = type.getSuperclass();
+ JParameterizedType paramType = supertype.isParameterized();
+ // JGenericType genericSuperType = paramType.getBaseType().isGenericType();
+ assertNotNull(paramType);
+
+ List<JMethod> expected = new ArrayList<JMethod>();
+ expected.addAll(Arrays.asList(genericType.getOverloads("m")));
+ expected.add(paramType.getMethod("m",
+ new JType[] {paramType.getTypeArgs()[0]}));
+
+ List<JMethod> actual = new ArrayList<JMethod>(
+ Arrays.asList(type.getOverridableMethods()));
+
+ validateOverridableMethods(expected, actual, true);
+ }
+
+ public void testOverridableMethods_Derived_Integer() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType type = oracle.getType(Derived.class.getName());
+ JGenericType genericType = type.isGenericType();
+ assertNotNull(genericType);
+
+ JParameterizedType paramType = oracle.getParameterizedType(genericType,
+ new JClassType[] {integerType});
+
+ List<JMethod> expected = new ArrayList<JMethod>();
+ expected.addAll(Arrays.asList(paramType.getOverloads("m")));
+
+ List<JMethod> actual = new ArrayList<JMethod>(
+ Arrays.asList(paramType.getOverridableMethods()));
+
+ validateOverridableMethods(expected, actual, true);
+ }
+
+ /**
+ * Returns the <code>TypeOracle</code> type for {@link GenericClass}.
+ *
+ * @return <code>TypeOracle</code> type for {@link GenericClass}
+ * @throws NotFoundException
+ */
+ protected JGenericType getGenericTestType() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType type = oracle.getType(GenericClass.class.getName());
+ assertNotNull(type.isGenericType());
+ return type.isGenericType();
+ }
+
+ @Override
+ protected Substitution getSubstitution() throws NotFoundException {
+ return new ParameterizedSubstitution(getTestType());
+ }
+
+ @Override
+ protected JParameterizedType getTestType() throws NotFoundException {
+ JGenericType type = getGenericTestType();
+
+ return moduleContext.getOracle().getParameterizedType(type, null,
+ new JClassType[] {integerType});
+ }
+
+ /**
+ * Returns the type for GenericClass<Integer>.GenericInnerClass<Boolean>.
+ *
+ * @throws NotFoundException
+ * @return type for GenericClass<Integer>.GenericInnerClass<Boolean>
+ */
+ private JParameterizedType getInnerParameterizedType()
+ throws NotFoundException {
+ JParameterizedType cut = getTestType();
+ TypeOracle oracle = moduleContext.getOracle();
+ JGenericType innerGenericClass = cut.getBaseType().getNestedType(
+ GenericInnerClass.class.getSimpleName()).isGenericType();
+
+ JClassType booleanType = oracle.getType(Boolean.class.getName());
+
+ /*
+ * Check that GenericClass<Integer>.GenericInnerClass<Boolean> has
+ * GenericClass<Integer> as its enclosing type
+ */
+ //
+ JParameterizedType parameterizedInnerClass = oracle.getParameterizedType(
+ innerGenericClass, cut, new JClassType[] {booleanType});
+
+ return parameterizedInnerClass;
+ }
+
+ private void validateOverridableMethods(List<JMethod> expected,
+ List<JMethod> actual, boolean addObjectMethods) {
+ Set<JMethod> expectedMethods = new HashSet<JMethod>();
+ expectedMethods.addAll(expected);
+ if (addObjectMethods) {
+ TypeOracle oracle = moduleContext.getOracle();
+ expectedMethods.addAll(Arrays.asList(oracle.getJavaLangObject().getMethods()));
+ }
+
+ for (JMethod method : actual) {
+ assertEquals("Method " + method.getReadableDeclaration() + " from type "
+ + method.getEnclosingType().getQualifiedSourceName()
+ + " was not expected", true, expectedMethods.remove(method));
+ }
+
+ assertTrue(expectedMethods.isEmpty());
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JRawTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JRawTypeTest.java
new file mode 100644
index 0000000..b1f4425
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JRawTypeTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
+import com.google.gwt.core.ext.typeinfo.test.MyIntegerList;
+import com.google.gwt.core.ext.typeinfo.test.MyList;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import java.util.ArrayList;
+
+/**
+ * Test for {@link JRawType}.
+ */
+public class JRawTypeTest extends JDelegatingClassTypeTest {
+ private final boolean logToConsole = false;
+
+ private final ModuleContext moduleContext = new ModuleContext(logToConsole
+ ? new PrintWriterTreeLogger() : TreeLogger.NULL,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+
+ public JRawTypeTest() throws UnableToCompleteException {
+ }
+
+ @Override
+ public void testFindNestedType() {
+ // TODO Auto-generated method stub
+ }
+ @Override
+ public void testGetEnclosingType() {
+ // TODO Auto-generated method stub
+ }
+ @Override
+ public void testGetNestedType() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void testGetNestedTypes() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void testGetOverridableMethods() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void testGetSubtypes() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType testType = oracle.getType(MyList.class.getName());
+ JGenericType genericTestType = testType.isGenericType();
+ assertNotNull(genericTestType);
+
+ JRawType rawTestType = genericTestType.getRawType();
+ JClassType[] expectedTypes = new JClassType[] {
+ oracle.getType(MyCustomList.class.getName()).isGenericType().getRawType(),
+ oracle.getType(MyIntegerList.class.getName())
+ };
+ JClassType[] actualSubtypes = rawTestType.getSubtypes();
+
+ validateEquals(oracle, expectedTypes, actualSubtypes);
+ }
+
+ @Override
+ public void testIsAssignableFrom() throws NotFoundException {
+ JRawType rawType = getTestType();
+ assertTrue(rawType.isAssignableFrom(rawType.getBaseType()));
+ }
+
+ @Override
+ public void testIsAssignableTo() throws NotFoundException {
+ JRawType rawType = getTestType();
+ assertTrue(rawType.getBaseType().isAssignableTo(rawType));
+ }
+
+ @Override
+ protected Substitution getSubstitution() throws NotFoundException {
+ return new Substitution() {
+ public JType getSubstitution(JType type) {
+ return type.getErasedType();
+ }
+ };
+ }
+
+ /**
+ * Returns the RawType for {@link ArrayList}.
+ */
+ @Override
+ protected JRawType getTestType() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType testType = oracle.getType(ArrayList.class.getName());
+ return testType.isGenericType().getRawType();
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java
new file mode 100644
index 0000000..0fb9438
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JTypeParameterTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.test.GenericClass;
+import com.google.gwt.core.ext.typeinfo.test.GenericSubclass;
+import com.google.gwt.core.ext.typeinfo.test.MyCustomList;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import java.util.Arrays;
+
+/**
+ * Tests for {@link JTypeParameter}.
+ */
+public class JTypeParameterTest extends JDelegatingClassTypeTest {
+ private final boolean logToConsole = false;
+ private final ModuleContext moduleContext = new ModuleContext(logToConsole
+ ? new PrintWriterTreeLogger() : TreeLogger.NULL,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+
+ public JTypeParameterTest() throws UnableToCompleteException {
+ }
+
+ @Override
+ public void testFindConstructor() {
+ }
+
+ @Override
+ public void testFindNestedType() {
+ }
+
+ @Override
+ public void testGetConstructors() {
+ }
+
+ @Override
+ public void testGetEnclosingType() throws NotFoundException {
+ JTypeParameter testType = getTestType();
+ assertEquals(
+ moduleContext.getOracle().getType(GenericClass.class.getName()),
+ testType.getDeclaringClass());
+ }
+
+ @Override
+ public void testGetName() throws NotFoundException {
+ assertEquals("T", getTestType().getName());
+ }
+
+ @Override
+ public void testGetNestedType() {
+ }
+
+ @Override
+ public void testGetNestedTypes() throws NotFoundException {
+ JTypeParameter testType = getTestType();
+
+ assertTrue(Arrays.deepEquals(testType.getNestedTypes(),
+ testType.getFirstBound().getNestedTypes()));
+ }
+
+ @Override
+ public void testGetOverridableMethods() throws NotFoundException {
+ JTypeParameter testType = getTestType();
+
+ assertTrue(Arrays.deepEquals(testType.getOverridableMethods(),
+ testType.getFirstBound().getOverridableMethods()));
+ }
+
+ @Override
+ public void testGetSubtypes() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType testType = oracle.getType(MyCustomList.class.getName());
+ JGenericType genericType = testType.isGenericType();
+ JTypeParameter[] typeParameters = genericType.getTypeParameters();
+ JTypeParameter typeParameter = typeParameters[0];
+
+ JClassType[] expected = new JClassType[] {
+ /*
+ * TODO: Re-eneable this once java.io.Serializable is added to the JRE
+ *
+ * emulation classes oracle.getType(Integer.class.getName()),
+ * oracle.getType(Float.class.getName()),
+ * oracle.getType(Short.class.getName()),
+ * oracle.getType(Double.class.getName()),
+ * oracle.getType(Number.class.getName()),
+ * oracle.getType(Long.class.getName()),
+ * oracle.getType(Byte.class.getName()),
+ */
+ };
+ validateEquals(oracle, expected, typeParameter.getSubtypes());
+ }
+
+ @Override
+ public void testIsAssignableFrom() throws NotFoundException {
+ JTypeParameter testType = getTestType();
+ assertTrue(testType.isAssignableFrom(moduleContext.getOracle().getJavaLangObject()));
+ }
+
+ @Override
+ public void testIsAssignableTo() throws NotFoundException {
+ JTypeParameter testType = getTestType();
+ assertTrue(testType.isAssignableTo(moduleContext.getOracle().getJavaLangObject()));
+ }
+
+ @Override
+ protected Substitution getSubstitution() {
+ return new Substitution() {
+ public JType getSubstitution(JType type) {
+ return type;
+ }
+ };
+ }
+
+ /*
+ * NOTE: This method returns the type parameter T from the GenericClass<T>
+ * type.
+ */
+ @Override
+ protected JTypeParameter getTestType() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType testType = oracle.getType(GenericClass.class.getName());
+ JGenericType genericTestType = testType.isGenericType();
+ assertNotNull(genericTestType);
+ JTypeParameter[] typeParameters = genericTestType.getTypeParameters();
+ assertTrue(typeParameters.length > 0);
+ return typeParameters[0];
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java
new file mode 100644
index 0000000..becea26
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/JWildcardTypeTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.typeinfo.test.CA;
+import com.google.gwt.core.ext.typeinfo.test.CB;
+import com.google.gwt.core.ext.typeinfo.test.CC;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Test for {@link JWildcardType}.
+ */
+public class JWildcardTypeTest extends JDelegatingClassTypeTest {
+ private final boolean logToConsole = false;
+ private final ModuleContext moduleContext = new ModuleContext(logToConsole
+ ? new PrintWriterTreeLogger() : TreeLogger.NULL,
+ "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
+
+ public JWildcardTypeTest() throws UnableToCompleteException {
+ }
+
+ @Override
+ public void testFindConstructor() {
+ // Wildcard types do not have constructors
+ }
+
+ @Override
+ public void testFindNestedType() {
+ // Wildcard do not have nested types...
+ }
+
+ @Override
+ public void testGetConstructors() {
+ }
+
+ @Override
+ public void testGetEnclosingType() {
+ // Wildcard do not have nested types...
+ }
+
+ @Override
+ public void testGetNestedType() {
+ // No nested types
+ }
+
+ @Override
+ public void testGetNestedTypes() {
+ // No nested types
+ }
+
+ @Override
+ public void testGetOverridableMethods() {
+ // No overridable methods
+ }
+
+ @Override
+ public void testGetSubtypes() {
+ // Tested by testGetSubtypes_LowerBound() and testGetSubtypes_UpperBound()
+ }
+
+ public void testGetSubtypes_LowerBound() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ // <? super Number>
+ JWildcardType lowerBoundWildcard = oracle.getWildcardType(new JLowerBound(
+ oracle.getType(Number.class.getName())));
+ JClassType[] subtypes = lowerBoundWildcard.getSubtypes();
+ assertEquals(0, subtypes.length);
+// assertEquals(oracle.getJavaLangObject(), subtypes[0]);
+ }
+
+ public void testGetSubtypes_UpperBound() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ // <? extends CA>
+ JWildcardType upperBoundWildcard = oracle.getWildcardType(new JUpperBound(
+ oracle.getType(CA.class.getName())));
+
+ JClassType[] expected = new JClassType[] {
+ oracle.getType(CB.class.getName()), oracle.getType(CC.class.getName())};
+ Set<JClassType> expectedSet = new HashSet<JClassType>();
+ expectedSet.addAll(Arrays.asList(expected));
+
+ JClassType[] actual = upperBoundWildcard.getSubtypes();
+ assertEquals(expectedSet.size(), actual.length);
+
+ for (int i = 0; i < actual.length; ++i) {
+ expectedSet.remove(actual[i]);
+ }
+ assertTrue(expectedSet.isEmpty());
+ }
+
+ @Override
+ public void testIsAssignableFrom() {
+ // Covered by the different testIsAssignableFrom*() variants below.
+ }
+
+ /**
+ * Tests that <? extends Number> is assignable from <? extends Integer> and
+ * that the reverse is not <code>true</code>.
+ */
+ public void testIsAssignableFrom_Extends_Number_To_Extends_Integer()
+ throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType numberType = oracle.getType(Number.class.getName());
+ JClassType integerType = oracle.getType(Integer.class.getName());
+
+ JUpperBound numberBound = new JUpperBound(numberType);
+ JUpperBound integerBound = new JUpperBound(integerType);
+
+ JWildcardType numberWildcard = oracle.getWildcardType(numberBound);
+ JWildcardType integerWildcard = oracle.getWildcardType(integerBound);
+
+ assertTrue(numberWildcard.isAssignableFrom(integerWildcard));
+ assertFalse(integerWildcard.isAssignableFrom(numberWildcard));
+ }
+
+ /**
+ * Tests that <? extends Number> is assignable from <? extends Integer> and
+ * that the reverse is not <code>true</code>.
+ */
+ public void testIsAssignableFrom_Extends_Object_From_Super_Object()
+ throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+
+ JClassType javaLangObject = oracle.getJavaLangObject();
+ JLowerBound lowerBound = new JLowerBound(javaLangObject);
+ JUpperBound upperBound = new JUpperBound(javaLangObject);
+
+ JWildcardType lowerWildcard = oracle.getWildcardType(lowerBound);
+ JWildcardType upperWildcard = oracle.getWildcardType(upperBound);
+
+ assertTrue(upperWildcard.isAssignableFrom(lowerWildcard));
+ assertFalse(lowerWildcard.isAssignableFrom(upperWildcard));
+ }
+
+ /**
+ * Tests that <? super Integer> is assignable from <? super Number> and that
+ * the reverse is not <code>true</code>.
+ */
+ public void testIsAssignableFrom_Super_Integer_From_Super_Number()
+ throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType numberType = oracle.getType(Number.class.getName());
+ JClassType integerType = oracle.getType(Integer.class.getName());
+
+ JLowerBound numberBound = new JLowerBound(numberType);
+ JLowerBound integerBound = new JLowerBound(integerType);
+
+ JWildcardType numberWildcard = oracle.getWildcardType(numberBound);
+ JWildcardType integerWildcard = oracle.getWildcardType(integerBound);
+
+ assertFalse(numberWildcard.isAssignableFrom(integerWildcard));
+ assertTrue(integerWildcard.isAssignableFrom(numberWildcard));
+ }
+
+ /**
+ * Tests that <? super Number> is assignable to <? super Integer> and that the
+ * reverse is not <code>true</code>.
+ */
+ public void testIsAssignableFrom_Super_Number_To_Super_Integer()
+ throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType numberType = oracle.getType(Number.class.getName());
+ JClassType integerType = oracle.getType(Integer.class.getName());
+
+ JLowerBound numberBound = new JLowerBound(numberType);
+ JLowerBound integerBound = new JLowerBound(integerType);
+
+ JWildcardType numberWildcard = oracle.getWildcardType(numberBound);
+ JWildcardType integerWildcard = oracle.getWildcardType(integerBound);
+
+ assertFalse(numberWildcard.isAssignableTo(integerWildcard));
+ assertTrue(integerWildcard.isAssignableTo(numberWildcard));
+ }
+
+ @Override
+ public void testIsAssignableTo() {
+ }
+
+ /**
+ * Tests that <? extends Integer> is assignable to <? extends Number> and that
+ * the reverse is not <code>true</code>.
+ */
+ public void testIsAssignableTo_Extends_Integer_To_Extends_Number()
+ throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ JClassType numberType = oracle.getType(Number.class.getName());
+ JClassType integerType = oracle.getType(Integer.class.getName());
+
+ JUpperBound numberBound = new JUpperBound(numberType);
+ JUpperBound integerBound = new JUpperBound(integerType);
+
+ JWildcardType numberWildcard = oracle.getWildcardType(numberBound);
+ JWildcardType integerWildcard = oracle.getWildcardType(integerBound);
+
+ assertTrue(integerWildcard.isAssignableTo(numberWildcard));
+ assertFalse(numberWildcard.isAssignableTo(integerWildcard));
+ }
+
+ @Override
+ protected Substitution getSubstitution() {
+ return new Substitution() {
+ public JType getSubstitution(JType type) {
+ return type;
+ }
+ };
+ }
+
+ public void testGetMethods() throws NotFoundException {
+ super.testGetMethods();
+ }
+
+
+ @Override
+ protected JWildcardType getTestType() throws NotFoundException {
+ TypeOracle oracle = moduleContext.getOracle();
+ return oracle.getWildcardType(new JUpperBound(
+ oracle.getType(Number.class.getName())));
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/ModuleContext.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/ModuleContext.java
new file mode 100644
index 0000000..acb8b2f
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/ModuleContext.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.cfg.ModuleDef;
+import com.google.gwt.dev.cfg.ModuleDefLoader;
+
+/**
+ * Helper for loading modules from the classpath.
+ */
+class ModuleContext {
+ private final TypeOracle oracle;
+ private final ModuleDef moduleDef;
+
+ ModuleContext(TreeLogger logger, String moduleName)
+ throws UnableToCompleteException {
+ moduleDef = ModuleDefLoader.loadFromClassPath(logger, moduleName);
+ oracle = moduleDef.getTypeOracle(logger);
+ }
+
+ public TypeOracle getOracle() {
+ return oracle;
+ }
+
+ public ModuleDef getModule() {
+ return moduleDef;
+ }
+}
\ No newline at end of file
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleGenericsSupportTest.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleGenericsSupportTest.java
index d1b4f93..e69de29 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleGenericsSupportTest.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleGenericsSupportTest.java
@@ -1,49 +0,0 @@
-/*
- * Copyright 2007 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.core.ext.typeinfo;
-
-import com.google.gwt.core.ext.TreeLogger;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.core.ext.typeinfo.test.GenericSubclass;
-import com.google.gwt.dev.cfg.ModuleDef;
-import com.google.gwt.dev.cfg.ModuleDefLoader;
-
-import junit.framework.TestCase;
-
-/**
- * Test cases for the {@link TypeOracle}'s and TypeOracleBuilder support for
- * generics.
- */
-public class TypeOracleGenericsSupportTest extends TestCase {
- static {
- ModuleDefLoader.setEnableCachingModules(true);
- }
-
- private final TreeLogger logger = TreeLogger.NULL;
- private ModuleDef moduleDef;
-
- private final TypeOracle typeOracle;
-
- public TypeOracleGenericsSupportTest() throws UnableToCompleteException {
- moduleDef = ModuleDefLoader.loadFromClassPath(logger,
- "com.google.gwt.core.ext.typeinfo.TypeOracleTest");
- typeOracle = moduleDef.getTypeOracle(logger);
- }
-
- public void test() throws NotFoundException {
- JClassType type = typeOracle.getType(GenericSubclass.class.getName());
- }
-}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleSuite.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleSuite.java
new file mode 100644
index 0000000..307e7da
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/TypeOracleSuite.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TypeOracleSuite extends TestSuite {
+ public static Test suite() {
+ TestSuite suite = new TestSuite("Test suite for TypeOracle");
+ suite.addTestSuite(AnnotationsTest.class);
+ suite.addTestSuite(JArrayTypeTest.class);
+ suite.addTestSuite(JClassTypeTest.class);
+ suite.addTestSuite(JEnumTypeTest.class);
+ suite.addTestSuite(JGenericTypeTest.class);
+ suite.addTestSuite(JParameterizedTypeTest.class);
+ suite.addTestSuite(JRawTypeTest.class);
+ suite.addTestSuite(JTypeParameterTest.class);
+ suite.addTestSuite(JWildcardTypeTest.class);
+ return suite;
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Base.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Base.java
new file mode 100644
index 0000000..8300078
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Base.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo.test;
+
+import java.io.Serializable;
+
+/**
+ * Class used to test
+ * {@link com.google.gwt.core.ext.typeinfo.JClassType#getOverridableMethods()}.
+ */
+public class Base<T> {
+ void m(T t) {
+ System.out.println("Base<T>.m(T)");
+ }
+
+ <N extends Number> void m(N n) {
+ System.out.println("Base<T>.m(N)");
+ }
+
+ static <N extends Serializable> void serialize(N n) {
+ System.out.println("Base<T>.<N extends Serializable>.serialize(N)");
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Derived.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Derived.java
new file mode 100644
index 0000000..1cf20c7
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/Derived.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo.test;
+
+import java.io.Serializable;
+
+/**
+ * Class used to test
+ * {@link com.google.gwt.core.ext.typeinfo.JClassType#getOverridableMethods()}.
+ *
+ * Derived<T> Overridable Methods (methods from java.lang.Object not shown):
+ * Derived<T>.m(Integer)
+ * Derived<T>.m(Number)
+ * Derived<T>.m(Integer)
+ * Derived<T>.<T extends Serializable> void m(T t)
+ */
+public class Derived<T> extends Base<T> {
+ public void m(Integer i) {
+ System.out.println("Derived<T>.m(Integer)");
+ } // new Overload
+
+ /**
+ * Overrides Base<T>.m(T)
+ *
+ * NOTE: this is commented out because JDT 3.1 will report it as an error,
+ * even though javac 1.5 allows this.
+ */
+// @Override
+// public void m(Object t) {
+// System.out.println("Derived<T>.m(Object)");
+// } //
+
+ /**
+ * Overrides Base<T>.<N extends Number>.m(N)
+ */
+ @Override
+ public void m(Number n) {
+ System.out.println("Derived<T>.m(Number)");
+ } // overrides m(N)
+
+ /**
+ * Overloads m
+ * @param <T>
+ * @param t
+ */
+ public <T extends Serializable> void m(T t) {
+ System.out.println("Derived<T>.<T extends Serializable>.m(T)");
+ }
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java
index 085a567..047b3af 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericClass.java
@@ -15,21 +15,106 @@
*/
package com.google.gwt.core.ext.typeinfo.test;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
/**
- *
+ * Generic class.
+ *
+ * @param <T>
+ *
+ * NOTE: It seems that the JDT 3.1 will not allow: GenericClass<Integer> if the
+ * definition of GenericClass is as follows: class GenericClass<T extends
+ * Serializable & Comparable<T>> implements Comparable<T> { ... }
*/
-public class GenericClass<T> {
- T t;
-
+public class GenericClass<T> implements Comparable<T> {
+ /**
+ * Non-static, generic inner class.
+ *
+ * @param <U>
+ */
+ public class GenericInnerClass<U> {
+ T t2;
+ U u2;
+ }
+
+ /**
+ * This class is not technically a generic class although it has a member that
+ * references a type parameter from its enclosing type.
+ */
+ public class NonGenericInnerClass {
+ T t3;
+ }
+
+ public class Foo {
+ public class Bar {
+ T t4;
+ }
+ }
+
+ /**
+ * Field of an inner class that is enclosed in a parameterized type.
+ */
+ GenericClass<Integer>.NonGenericInnerClass nonGenericInnerClassField;
+
+ /**
+ * NOTE: The following is disabled because it violates an assumption in TOB
+ * line 1228.
+ */
+// GenericClass.NonGenericInnerClass rawNonGenericInnerClassField;
+
+ GenericClass<Integer>.Foo.Bar wtf;
+
+ Class rawClazzField;
+
+ /**
+ * Field of a raw type.
+ */
+ ArrayList rawFieldType;
+
+ /**
+ * Field of a type parameter type.
+ */
+ T typeParameterField;
+
+ /**
+ * Parameterized with a array type argument.
+ */
+ List<T[]> parameterizedListField;
+
+ public GenericClass() {
+ }
+
public GenericClass(T t) {
- this.t = t;
+ this.typeParameterField = t;
}
-
+
+ public int compareTo(T o) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
public T getT() {
- return t;
+ return typeParameterField;
}
-
+
+ /*
+ * Generic method
+ */
+ public <U> U max(Collection<U> collection) {
+ return collection.iterator().next();
+ }
+
+ /*
+ * Generic method
+ */
+ public <U> U min(Collection<U> collection) {
+ return collection.iterator().next();
+ }
+
public void setT(T t) {
- this.t = t;
+ this.typeParameterField = t;
}
-}
+}
\ No newline at end of file
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java
index 056313a..23187a6 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/GenericSubclass.java
@@ -16,13 +16,18 @@
package com.google.gwt.core.ext.typeinfo.test;
/**
- *
+ * Test a generic class that extends a generic class.
*/
public class GenericSubclass<U> extends GenericClass<U> {
- // Explore what JDT does when there is a parameterized type
GenericClass<Integer> child;
-
+
public GenericSubclass(U t) {
super(t);
}
+
+ // TODO: This triggers a name clash problem with JDT 3.1 but not with JDT
+ // 3.3.0 or with javac 1.5.06.
+ // public void setT(Object t) {
+ // // this should override GenericClass<U>.setT(T t);
+ // }
}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyCustomList.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyCustomList.java
new file mode 100644
index 0000000..53ce7ed
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyCustomList.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo.test;
+
+import java.io.Serializable;
+
+/**
+ * Used to test wildcard card expansion when looking for List<Integer>
+ * subtypes.
+ */
+public class MyCustomList<T extends Serializable & Comparable<T>, U> extends
+ MyList<U> {
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyEnum.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyEnum.java
new file mode 100644
index 0000000..d703461
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyEnum.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo.test;
+
+/**
+ * Enumerated type used in the
+ * {@link com.google.gwt.core.ext.typeinfo.JEnumTypeTest}.
+ *
+ * NOTE: do not reorder the enumerated values
+ */
+public enum MyEnum {
+ @Deprecated
+ VAL0(-1) {
+ @Override
+ public int getId() {
+ return instanceField;
+ }
+ },
+
+ VAL1(-2) {
+ @Override
+ public int getId() {
+ return instanceField;
+ }
+ },
+
+ VAL2(-3) {
+ @Override
+ public int getId() {
+ return instanceField;
+ }
+ };
+
+ MyEnum(int instanceField) {
+ this.instanceField = instanceField;
+ }
+
+ public final int instanceField;
+
+ public static final MyEnum e = VAL2;
+
+ public abstract int getId();
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyIntegerList.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyIntegerList.java
new file mode 100644
index 0000000..0d1e559
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyIntegerList.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo.test;
+
+/**
+ * Used to test that this type gets picked up as a subtype of List<Integer>.
+ */
+public class MyIntegerList extends MyList<Integer> {
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyList.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyList.java
new file mode 100644
index 0000000..94fa2f1
--- /dev/null
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/MyList.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 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.core.ext.typeinfo.test;
+
+/**
+ * Used for testing parameterized subtypes.
+ */
+public class MyList<T> {
+}
diff --git a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NonGenericSubclass.java b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NonGenericSubclass.java
index 44413a4..03f98fb 100644
--- a/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NonGenericSubclass.java
+++ b/dev/core/test/com/google/gwt/core/ext/typeinfo/test/NonGenericSubclass.java
@@ -16,7 +16,7 @@
package com.google.gwt.core.ext.typeinfo.test;
/**
- *
+ * Test a non-generic class that extends a parameterized type.
*/
public class NonGenericSubclass extends GenericClass<Integer> {
/**
@@ -24,6 +24,12 @@
*/
public NonGenericSubclass(Integer t) {
super(t);
- // TODO Auto-generated constructor stub
+ }
+
+
+ /**
+ * Tests overloading of generic methods.
+ */
+ public void setT(Integer t) {
}
}