blob: 41e908a02f33d7862947e515a2ed4c67643b72c4 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.dev.javac.typemodel;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.dev.util.StringInterner;
import java.util.ArrayList;
import java.util.List;
/**
* Represents one of the type parameters in a generic type.
*/
public class JTypeParameter extends JDelegatingClassType implements
com.google.gwt.core.ext.typeinfo.JTypeParameter {
private JClassType[] bounds;
private JGenericType declaringClass;
private final int ordinal;
private final String typeName;
public JTypeParameter(String typeName, int ordinal) {
this.typeName = StringInterner.get().intern(typeName);
this.ordinal = ordinal;
}
@Override
public JField findField(String name) {
return getBaseType().findField(name);
}
@Override
public JMethod findMethod(String name, JType[] paramTypes) {
return getBaseType().findMethod(name, paramTypes);
}
public JClassType[] getBounds() {
return bounds;
}
public JGenericType getDeclaringClass() {
return declaringClass;
}
@Override
public JClassType getEnclosingType() {
// Type parameters do not have an enclosing type.
return null;
}
@Override
public JField getField(String name) {
return getBaseType().getField(name);
}
@Override
public JField[] getFields() {
return getBaseType().getFields();
}
public JClassType getFirstBound() {
return getBaseType();
}
@Override
public JMethod getMethod(String name, JType[] paramTypes)
throws NotFoundException {
return getBaseType().getMethod(name, paramTypes);
}
@Override
public JMethod[] getMethods() {
return getBaseType().getMethods();
}
@Override
public String getName() {
return typeName;
}
public int getOrdinal() {
return ordinal;
}
@Override
public String getParameterizedQualifiedSourceName() {
return typeName;
}
@Override
public String getQualifiedBinaryName() {
// TODO(jat): !! does a binary name have meaning for a type parameter?
return toString(true);
}
@Override
public String getQualifiedSourceName() {
return toString(false);
}
@Override
public String getSimpleSourceName() {
return toString(true);
}
@Override
public JClassType[] getSubtypes() {
JClassType[] subtypes = super.getSubtypes();
List<JClassType> intersectionTypes = new ArrayList<JClassType>();
if (getFirstBound().isInterface() == null
&& isAssignableFrom(getFirstBound())) {
// Include the first bound as a subtype if it is not an interface and it
// is assignable to all of our bounds.
intersectionTypes.add(getFirstBound());
}
for (JClassType subtype : subtypes) {
if (isAssignableFrom(subtype)) {
intersectionTypes.add(subtype);
}
}
// Only types that intersect with all our bounds make it here.
return intersectionTypes.toArray(TypeOracle.NO_JCLASSES);
}
@Override
public JGenericType isGenericType() {
return null;
}
@Override
public JParameterizedType isParameterized() {
return null;
}
@Override
public JRawType isRawType() {
return null;
}
@Override
public JTypeParameter isTypeParameter() {
return this;
}
@Override
public JWildcardType isWildcard() {
return null;
}
public void setBounds(JClassType[] bounds) {
this.bounds = bounds;
super.setBaseType(bounds[0]);
}
@Override
public String toString() {
if (getBaseType().isInterface() != null) {
return "interface " + getQualifiedSourceName();
} else {
return "class " + getQualifiedSourceName();
}
}
@Override
JClassType getSubstitutedType(JParameterizedType parameterizedType) {
return parameterizedType.getTypeParameterSubstitution(this);
}
void setDeclaringClass(JGenericType declaringClass) {
this.declaringClass = declaringClass;
}
private String toString(boolean simpleName) {
StringBuffer sb = new StringBuffer();
sb.append(typeName);
sb.append(" extends ");
for (int i = 0; i < bounds.length; ++i) {
if (i != 0) {
sb.append(" & ");
}
String boundName;
if (simpleName) {
boundName = bounds[i].getSimpleSourceName();
} else {
boundName = bounds[i].getParameterizedQualifiedSourceName();
}
sb.append(boundName);
}
return sb.toString();
}
}