ClassFile.java revision 3088f83b806b82d866d119e344da274105f42821
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 17package com.google.turbine.bytecode; 18 19import com.google.common.collect.ImmutableList; 20import com.google.turbine.model.Const; 21import java.util.List; 22import java.util.Map; 23import javax.annotation.Nullable; 24 25/** A JVMS §4.1 ClassFile. */ 26public class ClassFile { 27 28 private final int access; 29 private final String name; 30 private final String signature; 31 private final String superClass; 32 private final List<String> interfaces; 33 private final List<MethodInfo> methods; 34 private final List<FieldInfo> fields; 35 private final List<AnnotationInfo> annotations; 36 private final List<InnerClass> innerClasses; 37 38 public ClassFile( 39 int access, 40 String name, 41 String signature, 42 String superClass, 43 List<String> interfaces, 44 List<MethodInfo> methods, 45 List<FieldInfo> fields, 46 List<AnnotationInfo> annotations, 47 List<InnerClass> innerClasses) { 48 this.access = access; 49 this.name = name; 50 this.signature = signature; 51 this.superClass = superClass; 52 this.interfaces = interfaces; 53 this.methods = methods; 54 this.fields = fields; 55 this.annotations = annotations; 56 this.innerClasses = innerClasses; 57 } 58 59 /** Class access and property flags. */ 60 public int access() { 61 return access; 62 } 63 64 /** The name of the class or interface. */ 65 public String name() { 66 return name; 67 } 68 69 /** The value of the Signature attribute. */ 70 public String signature() { 71 return signature; 72 } 73 74 /** The super class. */ 75 public String superName() { 76 return superClass; 77 } 78 79 /** The direct superinterfaces. */ 80 public List<String> interfaces() { 81 return interfaces; 82 } 83 84 /** Methods declared by this class or interfaces type. */ 85 public List<MethodInfo> methods() { 86 return methods; 87 } 88 89 /** Fields declared by this class or interfaces type. */ 90 public List<FieldInfo> fields() { 91 return fields; 92 } 93 94 /** Declaration annotations of the class. */ 95 public List<AnnotationInfo> annotations() { 96 return annotations; 97 } 98 99 /** Inner class information. */ 100 public List<InnerClass> innerClasses() { 101 return innerClasses; 102 } 103 104 /** The contents of a JVMS §4.5 field_info structure. */ 105 public static class FieldInfo { 106 107 private final int access; 108 private final String name; 109 private final String descriptor; 110 @Nullable private final String signature; 111 @Nullable private final Const.Value value; 112 private final List<AnnotationInfo> annotations; 113 114 public FieldInfo( 115 int access, 116 String name, 117 String descriptor, 118 @Nullable String signature, 119 Const.Value value, 120 List<AnnotationInfo> annotations) { 121 this.access = access; 122 this.name = name; 123 this.descriptor = descriptor; 124 this.signature = signature; 125 this.value = value; 126 this.annotations = annotations; 127 } 128 129 /** Field access and property flags. */ 130 public int access() { 131 return access; 132 } 133 134 /** The name of the field. */ 135 public String name() { 136 return name; 137 } 138 139 /** The descriptor. */ 140 public String descriptor() { 141 return descriptor; 142 } 143 144 /** The value of Signature attribute. */ 145 @Nullable 146 public String signature() { 147 return signature; 148 } 149 150 /** The compile-time constant value. */ 151 @Nullable 152 public Const.Value value() { 153 return value; 154 } 155 156 /** Declaration annotations of the field. */ 157 public List<AnnotationInfo> annotations() { 158 return annotations; 159 } 160 } 161 162 /** A JVMS §4.7.6 InnerClasses attribute. */ 163 public static class InnerClass { 164 165 private final String innerClass; 166 private final String outerClass; 167 private final String innerName; 168 private final int access; 169 170 public InnerClass(String innerClass, String outerClass, String innerName, int access) { 171 this.innerClass = innerClass; 172 this.outerClass = outerClass; 173 this.innerName = innerName; 174 this.access = access; 175 } 176 177 /** The binary name of the inner class. */ 178 public String innerClass() { 179 return innerClass; 180 } 181 182 /** The binary name of the enclosing class. */ 183 public String outerClass() { 184 return outerClass; 185 } 186 187 /** The simple name of the inner class. */ 188 public String innerName() { 189 return innerName; 190 } 191 192 /** Access and property flags of the inner class; see JVMS table 4.8. */ 193 public int access() { 194 return access; 195 } 196 } 197 198 /** The contents of a JVMS §4.6 method_info structure. */ 199 public static class MethodInfo { 200 201 private final int access; 202 private final String name; 203 private final String descriptor; 204 @Nullable private final String signature; 205 private final List<String> exceptions; 206 @Nullable private final AnnotationInfo.ElementValue defaultValue; 207 private final List<AnnotationInfo> annotations; 208 private final ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations; 209 210 public MethodInfo( 211 int access, 212 String name, 213 String descriptor, 214 @Nullable String signature, 215 List<String> exceptions, 216 @Nullable AnnotationInfo.ElementValue defaultValue, 217 List<AnnotationInfo> annotations, 218 ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations) { 219 this.access = access; 220 this.name = name; 221 this.descriptor = descriptor; 222 this.signature = signature; 223 this.exceptions = exceptions; 224 this.defaultValue = defaultValue; 225 this.annotations = annotations; 226 this.parameterAnnotations = parameterAnnotations; 227 } 228 229 /** Method access and property flags. */ 230 public int access() { 231 return access; 232 } 233 234 /** The name of the method. */ 235 public String name() { 236 return name; 237 } 238 239 /** The descriptor. */ 240 public String descriptor() { 241 return descriptor; 242 } 243 244 /** The value of Signature attribute. */ 245 @Nullable 246 public String signature() { 247 return signature; 248 } 249 250 /** The value of Exceptions attribute. */ 251 public List<String> exceptions() { 252 return exceptions; 253 } 254 255 /** The value of the AnnotationDefault attribute. */ 256 @Nullable 257 public AnnotationInfo.ElementValue defaultValue() { 258 return defaultValue; 259 } 260 261 /** Declaration annotations of the method. */ 262 public List<AnnotationInfo> annotations() { 263 return annotations; 264 } 265 266 /** Declaration annotations of the formal parameters. */ 267 public ImmutableList<ImmutableList<AnnotationInfo>> parameterAnnotations() { 268 return parameterAnnotations; 269 } 270 } 271 272 /** The contents of a JVMS §4.7.16 annotation structure. */ 273 // TODO(cushon): RuntimeVisibleTypeAnnotations (JVMS 4.7.20) will need to be modelled separately 274 public static class AnnotationInfo { 275 276 private final String typeName; 277 private final boolean runtimeVisible; 278 private final Map<String, ElementValue> elementValuePairs; 279 280 public AnnotationInfo( 281 String typeName, boolean runtimeVisible, Map<String, ElementValue> elementValuePairs) { 282 this.typeName = typeName; 283 this.runtimeVisible = runtimeVisible; 284 this.elementValuePairs = elementValuePairs; 285 } 286 287 /** The JVMS §4.3.2 field descriptor for the type of the annotation. */ 288 public String typeName() { 289 return typeName; 290 } 291 292 /** Returns true if the annotation is visible at runtime. */ 293 public boolean isRuntimeVisible() { 294 return runtimeVisible; 295 } 296 297 /** The element-value pairs of the annotation. */ 298 public Map<String, ElementValue> elementValuePairs() { 299 return elementValuePairs; 300 } 301 302 /** A value of a JVMS §4.7.16.1 element-value pair. */ 303 public interface ElementValue { 304 305 /** The value kind. */ 306 Kind kind(); 307 308 /** Element value kinds. */ 309 enum Kind { 310 ENUM, 311 CONST, 312 ARRAY, 313 CLASS, 314 ANNOTATION 315 } 316 317 /** An enum constant value. */ 318 class EnumConstValue implements ElementValue { 319 320 private final String typeName; 321 private final String constName; 322 323 public EnumConstValue(String typeName, String constName) { 324 this.typeName = typeName; 325 this.constName = constName; 326 } 327 328 @Override 329 public Kind kind() { 330 return Kind.ENUM; 331 } 332 333 /** The type of the enum. */ 334 public String typeName() { 335 return typeName; 336 } 337 338 /** The name of the enum constant. */ 339 public String constName() { 340 return constName; 341 } 342 } 343 344 /** A primitive or string constant value. */ 345 class ConstValue implements ElementValue { 346 347 private final Const.Value value; 348 349 public ConstValue(Const.Value value) { 350 351 this.value = value; 352 } 353 354 @Override 355 public Kind kind() { 356 return Kind.CONST; 357 } 358 359 /** The constant value. */ 360 public Const.Value value() { 361 return value; 362 } 363 } 364 365 /** A constant array value. */ 366 class ArrayValue implements ElementValue { 367 368 private final List<ElementValue> elements; 369 370 public ArrayValue(List<ElementValue> elements) { 371 this.elements = elements; 372 } 373 374 @Override 375 public Kind kind() { 376 return Kind.ARRAY; 377 } 378 379 /** The elements of the array. */ 380 public List<ElementValue> elements() { 381 return elements; 382 } 383 } 384 385 /** A constant class literal value. */ 386 class ConstClassValue implements ElementValue { 387 388 private final String className; 389 390 public ConstClassValue(String className) { 391 this.className = className; 392 } 393 394 @Override 395 public Kind kind() { 396 return Kind.CLASS; 397 } 398 399 /** The class name. */ 400 public String className() { 401 return className; 402 } 403 } 404 405 /** A nested annotation value. */ 406 class AnnotationValue implements ElementValue { 407 408 private final AnnotationInfo annotation; 409 410 public AnnotationValue(AnnotationInfo annotation) { 411 this.annotation = annotation; 412 } 413 414 @Override 415 public Kind kind() { 416 return Kind.ANNOTATION; 417 } 418 419 /** The annotation. */ 420 public AnnotationInfo annotation() { 421 return annotation; 422 } 423 } 424 } 425 } 426} 427