| /* |
| * 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(); |
| } |
| } |