Home » openjdk-7 » com.sun.tools » javac » model » [javadoc | source]

    1   /*
    2    * Copyright (c) 2005, 2011, 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.javac.model;
   27   
   28   import java.util.List;
   29   import java.util.Set;
   30   import java.util.EnumSet;
   31   import javax.lang.model.element;
   32   import javax.lang.model.type;
   33   import com.sun.tools.javac.code;
   34   import com.sun.tools.javac.code.Symbol;
   35   import com.sun.tools.javac.util;
   36   
   37   /**
   38    * Utility methods for operating on types.
   39    *
   40    * <p><b>This is NOT part of any supported API.
   41    * If you write code that depends on this, you do so at your own
   42    * risk.  This code and its internal interfaces are subject to change
   43    * or deletion without notice.</b></p>
   44    */
   45   public class JavacTypes implements javax.lang.model.util.Types {
   46   
   47       private Symtab syms;
   48       private Types types;
   49   
   50       public static JavacTypes instance(Context context) {
   51           JavacTypes instance = context.get(JavacTypes.class);
   52           if (instance == null)
   53               instance = new JavacTypes(context);
   54           return instance;
   55       }
   56   
   57       /**
   58        * Public for use only by JavacProcessingEnvironment
   59        */
   60       protected JavacTypes(Context context) {
   61           setContext(context);
   62       }
   63   
   64       /**
   65        * Use a new context.  May be called from outside to update
   66        * internal state for a new annotation-processing round.
   67        */
   68       public void setContext(Context context) {
   69           context.put(JavacTypes.class, this);
   70           syms = Symtab.instance(context);
   71           types = Types.instance(context);
   72       }
   73   
   74       public Element asElement(TypeMirror t) {
   75           switch (t.getKind()) {
   76               case DECLARED:
   77               case ERROR:
   78               case TYPEVAR:
   79                   Type type = cast(Type.class, t);
   80                   return type.asElement();
   81               default:
   82                   return null;
   83           }
   84       }
   85   
   86       public boolean isSameType(TypeMirror t1, TypeMirror t2) {
   87           return types.isSameType((Type) t1, (Type) t2);
   88       }
   89   
   90       public boolean isSubtype(TypeMirror t1, TypeMirror t2) {
   91           validateTypeNotIn(t1, EXEC_OR_PKG);
   92           validateTypeNotIn(t2, EXEC_OR_PKG);
   93           return types.isSubtype((Type) t1, (Type) t2);
   94       }
   95   
   96       public boolean isAssignable(TypeMirror t1, TypeMirror t2) {
   97           validateTypeNotIn(t1, EXEC_OR_PKG);
   98           validateTypeNotIn(t2, EXEC_OR_PKG);
   99           return types.isAssignable((Type) t1, (Type) t2);
  100       }
  101   
  102       public boolean contains(TypeMirror t1, TypeMirror t2) {
  103           validateTypeNotIn(t1, EXEC_OR_PKG);
  104           validateTypeNotIn(t2, EXEC_OR_PKG);
  105           return types.containsType((Type) t1, (Type) t2);
  106       }
  107   
  108       public boolean isSubsignature(ExecutableType m1, ExecutableType m2) {
  109           return types.isSubSignature((Type) m1, (Type) m2);
  110       }
  111   
  112       public List<Type> directSupertypes(TypeMirror t) {
  113           validateTypeNotIn(t, EXEC_OR_PKG);
  114           Type type = (Type) t;
  115           Type sup = types.supertype(type);
  116           return (sup == Type.noType || sup == type || sup == null)
  117                 ? types.interfaces(type)
  118                 : types.interfaces(type).prepend(sup);
  119       }
  120   
  121       public TypeMirror erasure(TypeMirror t) {
  122           if (t.getKind() == TypeKind.PACKAGE)
  123               throw new IllegalArgumentException(t.toString());
  124           return types.erasure((Type) t);
  125       }
  126   
  127       public TypeElement boxedClass(PrimitiveType p) {
  128           return types.boxedClass((Type) p);
  129       }
  130   
  131       public PrimitiveType unboxedType(TypeMirror t) {
  132           if (t.getKind() != TypeKind.DECLARED)
  133               throw new IllegalArgumentException(t.toString());
  134           Type unboxed = types.unboxedType((Type) t);
  135           if (! unboxed.isPrimitive())    // only true primitives, not void
  136               throw new IllegalArgumentException(t.toString());
  137           return unboxed;
  138       }
  139   
  140       public TypeMirror capture(TypeMirror t) {
  141           validateTypeNotIn(t, EXEC_OR_PKG);
  142           return types.capture((Type) t);
  143       }
  144   
  145       public PrimitiveType getPrimitiveType(TypeKind kind) {
  146           switch (kind) {
  147           case BOOLEAN:   return syms.booleanType;
  148           case BYTE:      return syms.byteType;
  149           case SHORT:     return syms.shortType;
  150           case INT:       return syms.intType;
  151           case LONG:      return syms.longType;
  152           case CHAR:      return syms.charType;
  153           case FLOAT:     return syms.floatType;
  154           case DOUBLE:    return syms.doubleType;
  155           default:
  156               throw new IllegalArgumentException("Not a primitive type: " + kind);
  157           }
  158       }
  159   
  160       public NullType getNullType() {
  161           return (NullType) syms.botType;
  162       }
  163   
  164       public NoType getNoType(TypeKind kind) {
  165           switch (kind) {
  166           case VOID:      return syms.voidType;
  167           case NONE:      return Type.noType;
  168           default:
  169               throw new IllegalArgumentException(kind.toString());
  170           }
  171       }
  172   
  173       public ArrayType getArrayType(TypeMirror componentType) {
  174           switch (componentType.getKind()) {
  175           case VOID:
  176           case EXECUTABLE:
  177           case WILDCARD:  // heh!
  178           case PACKAGE:
  179               throw new IllegalArgumentException(componentType.toString());
  180           }
  181           return new Type.ArrayType((Type) componentType, syms.arrayClass);
  182       }
  183   
  184       public WildcardType getWildcardType(TypeMirror extendsBound,
  185                                           TypeMirror superBound) {
  186           BoundKind bkind;
  187           Type bound;
  188           if (extendsBound == null && superBound == null) {
  189               bkind = BoundKind.UNBOUND;
  190               bound = syms.objectType;
  191           } else if (superBound == null) {
  192               bkind = BoundKind.EXTENDS;
  193               bound = (Type) extendsBound;
  194           } else if (extendsBound == null) {
  195               bkind = BoundKind.SUPER;
  196               bound = (Type) superBound;
  197           } else {
  198               throw new IllegalArgumentException(
  199                       "Extends and super bounds cannot both be provided");
  200           }
  201           switch (bound.getKind()) {
  202           case ARRAY:
  203           case DECLARED:
  204           case ERROR:
  205           case TYPEVAR:
  206               return new Type.WildcardType(bound, bkind, syms.boundClass);
  207           default:
  208               throw new IllegalArgumentException(bound.toString());
  209           }
  210       }
  211   
  212       public DeclaredType getDeclaredType(TypeElement typeElem,
  213                                           TypeMirror... typeArgs) {
  214           ClassSymbol sym = (ClassSymbol) typeElem;
  215   
  216           if (typeArgs.length == 0)
  217               return (DeclaredType) sym.erasure(types);
  218           if (sym.type.getEnclosingType().isParameterized())
  219               throw new IllegalArgumentException(sym.toString());
  220   
  221           return getDeclaredType0(sym.type.getEnclosingType(), sym, typeArgs);
  222       }
  223   
  224       public DeclaredType getDeclaredType(DeclaredType enclosing,
  225                                           TypeElement typeElem,
  226                                           TypeMirror... typeArgs) {
  227           if (enclosing == null)
  228               return getDeclaredType(typeElem, typeArgs);
  229   
  230           ClassSymbol sym = (ClassSymbol) typeElem;
  231           Type outer = (Type) enclosing;
  232   
  233           if (outer.tsym != sym.owner.enclClass())
  234               throw new IllegalArgumentException(enclosing.toString());
  235           if (!outer.isParameterized())
  236               return getDeclaredType(typeElem, typeArgs);
  237   
  238           return getDeclaredType0(outer, sym, typeArgs);
  239       }
  240       // where
  241           private DeclaredType getDeclaredType0(Type outer,
  242                                                 ClassSymbol sym,
  243                                                 TypeMirror... typeArgs) {
  244               if (typeArgs.length != sym.type.getTypeArguments().length())
  245                   throw new IllegalArgumentException(
  246                   "Incorrect number of type arguments");
  247   
  248               ListBuffer<Type> targs = new ListBuffer<Type>();
  249               for (TypeMirror t : typeArgs) {
  250                   if (!(t instanceof ReferenceType || t instanceof WildcardType))
  251                       throw new IllegalArgumentException(t.toString());
  252                   targs.append((Type) t);
  253               }
  254               // TODO: Would like a way to check that type args match formals.
  255   
  256               return (DeclaredType) new Type.ClassType(outer, targs.toList(), sym);
  257           }
  258   
  259       /**
  260        * Returns the type of an element when that element is viewed as
  261        * a member of, or otherwise directly contained by, a given type.
  262        * For example,
  263        * when viewed as a member of the parameterized type {@code Set<String>},
  264        * the {@code Set.add} method is an {@code ExecutableType}
  265        * whose parameter is of type {@code String}.
  266        *
  267        * @param containing  the containing type
  268        * @param element     the element
  269        * @return the type of the element as viewed from the containing type
  270        * @throws IllegalArgumentException if the element is not a valid one
  271        *          for the given type
  272        */
  273       public TypeMirror asMemberOf(DeclaredType containing, Element element) {
  274           Type site = (Type)containing;
  275           Symbol sym = (Symbol)element;
  276           if (types.asSuper(site, sym.getEnclosingElement()) == null)
  277               throw new IllegalArgumentException(sym + "@" + site);
  278           return types.memberType(site, sym);
  279       }
  280   
  281   
  282       private static final Set<TypeKind> EXEC_OR_PKG =
  283               EnumSet.of(TypeKind.EXECUTABLE, TypeKind.PACKAGE);
  284   
  285       /**
  286        * Throws an IllegalArgumentException if a type's kind is one of a set.
  287        */
  288       private void validateTypeNotIn(TypeMirror t, Set<TypeKind> invalidKinds) {
  289           if (invalidKinds.contains(t.getKind()))
  290               throw new IllegalArgumentException(t.toString());
  291       }
  292   
  293       /**
  294        * Returns an object cast to the specified type.
  295        * @throws NullPointerException if the object is {@code null}
  296        * @throws IllegalArgumentException if the object is of the wrong type
  297        */
  298       private static <T> T cast(Class<T> clazz, Object o) {
  299           if (! clazz.isInstance(o))
  300               throw new IllegalArgumentException(o.toString());
  301           return clazz.cast(o);
  302       }
  303   }

Home » openjdk-7 » com.sun.tools » javac » model » [javadoc | source]