Home | History | Annotate | Download | only in sig
      1 /*
      2  * Copyright 2016 Google Inc. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.turbine.bytecode.sig;
     18 
     19 import com.google.common.collect.ImmutableList;
     20 import com.google.turbine.model.TurbineConstantTypeKind;
     21 import javax.annotation.Nullable;
     22 
     23 /** JVMS 4.7.9.1 signatures. */
     24 public class Sig {
     25 
     26   /** A JVMS 4.7.9.1 ClassSignature. */
     27   public static class ClassSig {
     28 
     29     private final ImmutableList<TyParamSig> tyParams;
     30     private final ClassTySig superClass;
     31     private final ImmutableList<ClassTySig> interfaces;
     32 
     33     public ClassSig(
     34         ImmutableList<TyParamSig> tyParams,
     35         ClassTySig superClass,
     36         ImmutableList<ClassTySig> interfaces) {
     37       this.tyParams = tyParams;
     38       this.superClass = superClass;
     39       this.interfaces = interfaces;
     40     }
     41 
     42     /** Formal type parameters. */
     43     public ImmutableList<TyParamSig> tyParams() {
     44       return tyParams;
     45     }
     46 
     47     /** The super class. */
     48     public ClassTySig superClass() {
     49       return superClass;
     50     }
     51 
     52     /** The interface list. */
     53     public ImmutableList<ClassTySig> interfaces() {
     54       return interfaces;
     55     }
     56   }
     57 
     58   /** A JVMS 4.7.9.1 FormalTypeParameter. */
     59   public static class TyParamSig {
     60 
     61     private final String name;
     62     @Nullable private final TySig classBound;
     63     private final ImmutableList<TySig> interfaceBounds;
     64 
     65     public TyParamSig(String name, TySig classBound, ImmutableList<TySig> interfaceBounds) {
     66       this.name = name;
     67       this.classBound = classBound;
     68       this.interfaceBounds = interfaceBounds;
     69     }
     70 
     71     /** A single class upper-bound, or {@code null}. */
     72     @Nullable
     73     public TySig classBound() {
     74       return classBound;
     75     }
     76 
     77     /** Interface upper-bounds. */
     78     public ImmutableList<TySig> interfaceBounds() {
     79       return interfaceBounds;
     80     }
     81 
     82     /** The name of the type parameter. */
     83     public String name() {
     84       return name;
     85     }
     86   }
     87 
     88   /** A JVMS 4.7.9.1 ClassTypeSignature. */
     89   public static class ClassTySig extends TySig {
     90 
     91     private final String pkg;
     92     private final ImmutableList<SimpleClassTySig> classes;
     93 
     94     public ClassTySig(String pkg, ImmutableList<SimpleClassTySig> classes) {
     95       this.pkg = pkg;
     96       this.classes = classes;
     97     }
     98 
     99     /** The package name of the class. */
    100     public String pkg() {
    101       return pkg;
    102     }
    103 
    104     /**
    105      * A list of a simple names, containing at least one top-level type and possible repeated member
    106      * class names. Each element may include type arguments.
    107      *
    108      * <p>It's possible for the top-level type to be a desugared nested class with no type
    109      * arguments, in this case the first element is the simple name of the lowered type, e.g. in
    110      * {@code Foo$Bar<X>.<Y>} the first element may be an nested class {@code Bar} with an enclosing
    111      * type {@code Foo}, but it may also be a top-level class that was named {@code Foo$Bar} in
    112      * source. The signature is the same either way.
    113      */
    114     public ImmutableList<SimpleClassTySig> classes() {
    115       return classes;
    116     }
    117 
    118     @Override
    119     public TySigKind kind() {
    120       return TySigKind.CLASS_TY_SIG;
    121     }
    122   }
    123 
    124   /** A JVMS 4.7.9.1 SimpleClassTypeSignature. */
    125   public static class SimpleClassTySig {
    126 
    127     private final String simpleName;
    128     private final ImmutableList<TySig> tyArgs;
    129 
    130     public SimpleClassTySig(String simpleName, ImmutableList<TySig> tyArgs) {
    131       this.tyArgs = tyArgs;
    132       this.simpleName = simpleName;
    133     }
    134 
    135     /** Type arguments. */
    136     public ImmutableList<TySig> tyArgs() {
    137       return tyArgs;
    138     }
    139 
    140     /** The simple name of the class. */
    141     public String simpleName() {
    142       return simpleName;
    143     }
    144   }
    145 
    146   /**
    147    * A wildcard type.
    148    *
    149    * <p>Wildcard are represented as first class types, instead only allowing them as top-level type
    150    * arguments. This diverges from the buggy grammar in JVMS 4.7.9.1, see:
    151    * http://mail.openjdk.java.net/pipermail/compiler-dev/2016-October/010450.html
    152    */
    153   public abstract static class WildTySig extends TySig {
    154     /** A wildcard bound kind. */
    155     public enum BoundKind {
    156       /** An unbounded wildcard. */
    157       NONE,
    158       /** A lower-bounded wildcard. */
    159       LOWER,
    160       /** An upper-bounded wildcard. */
    161       UPPER
    162     }
    163 
    164     /** Returns the wildcard bound kind. */
    165     public abstract BoundKind boundKind();
    166 
    167     @Override
    168     public TySigKind kind() {
    169       return TySigKind.WILD_TY_SIG;
    170     }
    171   }
    172 
    173   /** An upper-bounded wildcard. */
    174   public static class UpperBoundTySig extends WildTySig {
    175 
    176     private final TySig bound;
    177 
    178     public UpperBoundTySig(TySig bound) {
    179       this.bound = bound;
    180     }
    181 
    182     /** The upper bound. */
    183     public TySig bound() {
    184       return bound;
    185     }
    186 
    187     @Override
    188     public BoundKind boundKind() {
    189       return BoundKind.UPPER;
    190     }
    191   }
    192 
    193   /** An lower-bounded wildcard. */
    194   public static class LowerBoundTySig extends WildTySig {
    195 
    196     private final TySig bound;
    197 
    198     public LowerBoundTySig(TySig bound) {
    199       this.bound = bound;
    200     }
    201 
    202     /** The lower bound. */
    203     public TySig bound() {
    204       return bound;
    205     }
    206 
    207     @Override
    208     public BoundKind boundKind() {
    209       return BoundKind.LOWER;
    210     }
    211   }
    212 
    213   /** An unbounded wildcard. */
    214   public static class WildTyArgSig extends WildTySig {
    215     @Override
    216     public BoundKind boundKind() {
    217       return BoundKind.NONE;
    218     }
    219   }
    220 
    221   /** A JVMS 4.7.9.1 ArrayTypeSignature. */
    222   public static class ArrayTySig extends TySig {
    223 
    224     private final TySig elementType;
    225 
    226     public ArrayTySig(TySig elementType) {
    227       this.elementType = elementType;
    228     }
    229 
    230     /** The element type. */
    231     public TySig elementType() {
    232       return elementType;
    233     }
    234 
    235     @Override
    236     public TySigKind kind() {
    237       return TySigKind.ARRAY_TY_SIG;
    238     }
    239   }
    240 
    241   /** A JVMS 4.7.9.1 TypeVariableSignature. */
    242   public static class TyVarSig extends TySig {
    243 
    244     public final String name;
    245 
    246     public TyVarSig(String name) {
    247       this.name = name;
    248     }
    249 
    250     /** The name of the type variable. */
    251     public String name() {
    252       return name;
    253     }
    254 
    255     @Override
    256     public TySigKind kind() {
    257       return TySigKind.TY_VAR_SIG;
    258     }
    259   }
    260 
    261   /** An abstract class for all JVMS 4.7.9.1 JavaTypeSignatures. */
    262   public abstract static class TySig {
    263 
    264     /** The type kind. */
    265     public enum TySigKind {
    266       VOID_TY_SIG,
    267       BASE_TY_SIG,
    268       CLASS_TY_SIG,
    269       ARRAY_TY_SIG,
    270       TY_VAR_SIG,
    271       WILD_TY_SIG
    272     }
    273 
    274     /** The type kind. */
    275     public abstract TySigKind kind();
    276   }
    277 
    278   /** A JVMS 4.3.3 VoidDescriptor. */
    279   public static final TySig VOID =
    280       new TySig() {
    281         @Override
    282         public TySigKind kind() {
    283           return TySigKind.VOID_TY_SIG;
    284         }
    285       };
    286 
    287   /** A JVMS 4.3.2 BaseType. */
    288   public static class BaseTySig extends TySig {
    289 
    290     @Override
    291     public TySigKind kind() {
    292       return TySigKind.BASE_TY_SIG;
    293     }
    294 
    295     private final TurbineConstantTypeKind type;
    296 
    297     public BaseTySig(TurbineConstantTypeKind type) {
    298       this.type = type;
    299     }
    300 
    301     /** The base type kind. */
    302     public TurbineConstantTypeKind type() {
    303       return type;
    304     }
    305   }
    306 
    307   /** A JVMS 4.7.9.1 MethodTypeSignature. */
    308   public static class MethodSig {
    309 
    310     private final ImmutableList<TyParamSig> tyParams;
    311     private final ImmutableList<TySig> params;
    312     private final TySig returnType;
    313     private final ImmutableList<TySig> exceptions;
    314 
    315     public MethodSig(
    316         ImmutableList<TyParamSig> tyParams,
    317         ImmutableList<TySig> params,
    318         TySig returnType,
    319         ImmutableList<TySig> exceptions) {
    320       this.tyParams = tyParams;
    321       this.params = params;
    322       this.returnType = returnType;
    323       this.exceptions = exceptions;
    324     }
    325 
    326     /** The formal type parameters. */
    327     public ImmutableList<TyParamSig> tyParams() {
    328       return tyParams;
    329     }
    330 
    331     /** The return type. Non-null, possibly {@link #VOID}. */
    332     public TySig returnType() {
    333       return returnType;
    334     }
    335 
    336     /** The formal parameters. */
    337     public ImmutableList<TySig> params() {
    338       return params;
    339     }
    340 
    341     /** The thrown exceptions. */
    342     public ImmutableList<TySig> exceptions() {
    343       return exceptions;
    344     }
    345   }
    346 }
    347