1 /* 2 * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.apt.mirror.util; 27 28 29 import java.util.Collection; 30 31 import com.sun.mirror.declaration.*; 32 import com.sun.mirror.type.*; 33 import com.sun.mirror.util.Types; 34 import com.sun.tools.apt.mirror.AptEnv; 35 import com.sun.tools.apt.mirror.declaration.*; 36 import com.sun.tools.apt.mirror.type.TypeMirrorImpl; 37 import com.sun.tools.javac.code.BoundKind; 38 import com.sun.tools.javac.code.Type; 39 import com.sun.tools.javac.code.Symbol.ClassSymbol; 40 import com.sun.tools.javac.util.Context; 41 import com.sun.tools.javac.util.ListBuffer; 42 43 44 /** 45 * Implementation of Types utility methods for annotation processors 46 */ 47 @SuppressWarnings("deprecation") 48 public class TypesImpl implements Types { 49 50 private final AptEnv env; 51 52 53 private static final Context.Key<Types> typesKey = 54 new Context.Key<Types>(); 55 56 public static Types instance(Context context) { 57 Types instance = context.get(typesKey); 58 if (instance == null) { 59 instance = new TypesImpl(context); 60 } 61 return instance; 62 } 63 64 private TypesImpl(Context context) { 65 context.put(typesKey, this); 66 env = AptEnv.instance(context); 67 } 68 69 70 /** 71 * {@inheritDoc} 72 */ 73 public boolean isSubtype(TypeMirror t1, TypeMirror t2) { 74 return env.jctypes.isSubtype(((TypeMirrorImpl) t1).type, 75 ((TypeMirrorImpl) t2).type); 76 } 77 78 /** 79 * {@inheritDoc} 80 */ 81 public boolean isAssignable(TypeMirror t1, TypeMirror t2) { 82 return env.jctypes.isAssignable(((TypeMirrorImpl) t1).type, 83 ((TypeMirrorImpl) t2).type); 84 } 85 86 /** 87 * {@inheritDoc} 88 */ 89 public TypeMirror getErasure(TypeMirror t) { 90 return env.typeMaker.getType( 91 env.jctypes.erasure(((TypeMirrorImpl) t).type)); 92 } 93 94 /** 95 * {@inheritDoc} 96 */ 97 public PrimitiveType getPrimitiveType(PrimitiveType.Kind kind) { 98 Type prim = null; 99 switch (kind) { 100 case BOOLEAN: prim = env.symtab.booleanType; break; 101 case BYTE: prim = env.symtab.byteType; break; 102 case SHORT: prim = env.symtab.shortType; break; 103 case INT: prim = env.symtab.intType; break; 104 case LONG: prim = env.symtab.longType; break; 105 case CHAR: prim = env.symtab.charType; break; 106 case FLOAT: prim = env.symtab.floatType; break; 107 case DOUBLE: prim = env.symtab.doubleType; break; 108 default: assert false; 109 } 110 return (PrimitiveType) env.typeMaker.getType(prim); 111 } 112 113 /** 114 * {@inheritDoc} 115 */ 116 public VoidType getVoidType() { 117 return (VoidType) env.typeMaker.getType(env.symtab.voidType); 118 } 119 120 /** 121 * {@inheritDoc} 122 */ 123 public ArrayType getArrayType(TypeMirror componentType) { 124 if (componentType instanceof VoidType) { 125 throw new IllegalArgumentException("void"); 126 } 127 return (ArrayType) env.typeMaker.getType( 128 new Type.ArrayType(((TypeMirrorImpl) componentType).type, 129 env.symtab.arrayClass)); 130 } 131 132 /** 133 * {@inheritDoc} 134 */ 135 public TypeVariable getTypeVariable(TypeParameterDeclaration tparam) { 136 return (TypeVariable) env.typeMaker.getType( 137 ((DeclarationImpl) tparam).sym.type); 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 public WildcardType getWildcardType(Collection<ReferenceType> upperBounds, 144 Collection<ReferenceType> lowerBounds) { 145 BoundKind kind; 146 Type bound; 147 int uppers = upperBounds.size(); 148 int downers = lowerBounds.size(); 149 150 if (uppers + downers > 1) { 151 throw new IllegalArgumentException("Multiple bounds not allowed"); 152 153 } else if (uppers + downers == 0) { 154 kind = BoundKind.UNBOUND; 155 bound = env.symtab.objectType; 156 157 } else if (uppers == 1) { 158 assert downers == 0; 159 kind = BoundKind.EXTENDS; 160 bound = ((TypeMirrorImpl) upperBounds.iterator().next()).type; 161 162 } else { 163 assert uppers == 0 && downers == 1; 164 kind = BoundKind.SUPER; 165 bound = ((TypeMirrorImpl) lowerBounds.iterator().next()).type; 166 } 167 168 if (bound instanceof Type.WildcardType) 169 throw new IllegalArgumentException(bound.toString()); 170 171 return (WildcardType) env.typeMaker.getType( 172 new Type.WildcardType(bound, kind, env.symtab.boundClass)); 173 } 174 175 /** 176 * {@inheritDoc} 177 */ 178 public DeclaredType getDeclaredType(TypeDeclaration decl, 179 TypeMirror... typeArgs) { 180 ClassSymbol sym = ((TypeDeclarationImpl) decl).sym; 181 182 if (typeArgs.length == 0) 183 return (DeclaredType) env.typeMaker.getType( 184 env.jctypes.erasure(sym.type)); 185 if (sym.type.getEnclosingType().isParameterized()) 186 throw new IllegalArgumentException(decl.toString()); 187 188 return getDeclaredType(sym.type.getEnclosingType(), sym, typeArgs); 189 } 190 191 /** 192 * {@inheritDoc} 193 */ 194 public DeclaredType getDeclaredType(DeclaredType containing, 195 TypeDeclaration decl, 196 TypeMirror... typeArgs) { 197 if (containing == null) 198 return getDeclaredType(decl, typeArgs); 199 200 ClassSymbol sym = ((TypeDeclarationImpl) decl).sym; 201 Type outer = ((TypeMirrorImpl) containing).type; 202 203 if (outer.tsym != sym.owner.enclClass()) 204 throw new IllegalArgumentException(containing.toString()); 205 if (!outer.isParameterized()) 206 return getDeclaredType(decl, typeArgs); 207 208 return getDeclaredType(outer, sym, typeArgs); 209 } 210 211 private DeclaredType getDeclaredType(Type outer, 212 ClassSymbol sym, 213 TypeMirror... typeArgs) { 214 if (typeArgs.length != sym.type.getTypeArguments().length()) 215 throw new IllegalArgumentException( 216 "Incorrect number of type arguments"); 217 218 ListBuffer<Type> targs = new ListBuffer<Type>(); 219 for (TypeMirror t : typeArgs) { 220 if (!(t instanceof ReferenceType || t instanceof WildcardType)) 221 throw new IllegalArgumentException(t.toString()); 222 targs.append(((TypeMirrorImpl) t).type); 223 } 224 //### Need a way to check that type args match formals. 225 226 return (DeclaredType) env.typeMaker.getType( 227 new Type.ClassType(outer, targs.toList(), sym)); 228 } 229 }