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 ClassSig( ImmutableList<TyParamSig> tyParams, ClassTySig superClass, ImmutableList<ClassTySig> interfaces)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. */ tyParams()43 public ImmutableList<TyParamSig> tyParams() { 44 return tyParams; 45 } 46 47 /** The super class. */ superClass()48 public ClassTySig superClass() { 49 return superClass; 50 } 51 52 /** The interface list. */ interfaces()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 TyParamSig(String name, TySig classBound, ImmutableList<TySig> interfaceBounds)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 classBound()73 public TySig classBound() { 74 return classBound; 75 } 76 77 /** Interface upper-bounds. */ interfaceBounds()78 public ImmutableList<TySig> interfaceBounds() { 79 return interfaceBounds; 80 } 81 82 /** The name of the type parameter. */ name()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 ClassTySig(String pkg, ImmutableList<SimpleClassTySig> classes)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. */ pkg()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 */ classes()114 public ImmutableList<SimpleClassTySig> classes() { 115 return classes; 116 } 117 118 @Override kind()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 SimpleClassTySig(String simpleName, ImmutableList<TySig> tyArgs)130 public SimpleClassTySig(String simpleName, ImmutableList<TySig> tyArgs) { 131 this.tyArgs = tyArgs; 132 this.simpleName = simpleName; 133 } 134 135 /** Type arguments. */ tyArgs()136 public ImmutableList<TySig> tyArgs() { 137 return tyArgs; 138 } 139 140 /** The simple name of the class. */ simpleName()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. */ boundKind()165 public abstract BoundKind boundKind(); 166 167 @Override kind()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 UpperBoundTySig(TySig bound)178 public UpperBoundTySig(TySig bound) { 179 this.bound = bound; 180 } 181 182 /** The upper bound. */ bound()183 public TySig bound() { 184 return bound; 185 } 186 187 @Override boundKind()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 LowerBoundTySig(TySig bound)198 public LowerBoundTySig(TySig bound) { 199 this.bound = bound; 200 } 201 202 /** The lower bound. */ bound()203 public TySig bound() { 204 return bound; 205 } 206 207 @Override boundKind()208 public BoundKind boundKind() { 209 return BoundKind.LOWER; 210 } 211 } 212 213 /** An unbounded wildcard. */ 214 public static class WildTyArgSig extends WildTySig { 215 @Override boundKind()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 ArrayTySig(TySig elementType)226 public ArrayTySig(TySig elementType) { 227 this.elementType = elementType; 228 } 229 230 /** The element type. */ elementType()231 public TySig elementType() { 232 return elementType; 233 } 234 235 @Override kind()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 TyVarSig(String name)246 public TyVarSig(String name) { 247 this.name = name; 248 } 249 250 /** The name of the type variable. */ name()251 public String name() { 252 return name; 253 } 254 255 @Override kind()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. */ 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 kind()291 public TySigKind kind() { 292 return TySigKind.BASE_TY_SIG; 293 } 294 295 private final TurbineConstantTypeKind type; 296 BaseTySig(TurbineConstantTypeKind type)297 public BaseTySig(TurbineConstantTypeKind type) { 298 this.type = type; 299 } 300 301 /** The base type kind. */ type()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 MethodSig( ImmutableList<TyParamSig> tyParams, ImmutableList<TySig> params, TySig returnType, ImmutableList<TySig> exceptions)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. */ tyParams()327 public ImmutableList<TyParamSig> tyParams() { 328 return tyParams; 329 } 330 331 /** The return type. Non-null, possibly {@link #VOID}. */ returnType()332 public TySig returnType() { 333 return returnType; 334 } 335 336 /** The formal parameters. */ params()337 public ImmutableList<TySig> params() { 338 return params; 339 } 340 341 /** The thrown exceptions. */ exceptions()342 public ImmutableList<TySig> exceptions() { 343 return exceptions; 344 } 345 } 346 } 347