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