2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0.
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package gov.nasa.jpf.jvm;
20 import gov.nasa.jpf.JPFException;
21 import gov.nasa.jpf.vm.AnnotationInfo;
22 import gov.nasa.jpf.vm.AnnotationParser;
23 import gov.nasa.jpf.vm.ClassParseException;
24 import gov.nasa.jpf.vm.Types;
27 * parser that reads annotation classfiles and extracts default value entries
29 * Java annotations form a different type system. Java annotations are essentially
30 * restricted interfaces (no super-interface, no fields other than static finals
31 * that are inlined by the compiler)
33 * Since Java annotations use only a small subset of the Java classfile format
34 * we only have to parse methods and method attributes
36 * <2do> class and enum values are not yet supported
38 public class JVMAnnotationParser extends ClassFileReaderAdapter implements AnnotationParser {
47 String annotationName;
48 AnnotationInfo.Entry[] entries;
50 public JVMAnnotationParser (ClassFile cf) {
55 public void parse (AnnotationInfo ai) throws ClassParseException {
61 //--- the overridden ClassFileReader methods
64 public void setClass (ClassFile cf, String clsName, String superClsName, int flags, int cpCount) throws ClassParseException {
66 annotationName = Types.getClassNameFromTypeName(clsName);
68 ai.setName(annotationName);
72 public void setInterface (ClassFile cf, int ifcIndex, String ifcName) {
73 if (!"java/lang/annotation/Annotation".equals(ifcName)) {
74 throw new JPFException("illegal annotation interface of: " + annotationName + " is " + ifcName);
79 public void setMethodCount (ClassFile cf, int methodCount) {
80 entries = new AnnotationInfo.Entry[methodCount];
84 public void setMethod (ClassFile cf, int methodIndex, int accessFlags, String name, String descriptor) {
90 public void setMethodDone (ClassFile cf, int methodIndex){
91 entries[methodIndex] = new AnnotationInfo.Entry(key, value);
95 public void setMethodsDone (ClassFile cf){
96 ai.setEntries(entries);
100 public void setMethodAttribute (ClassFile cf, int methodIndex, int attrIndex, String name, int attrLength) {
101 if (name == ClassFile.ANNOTATIONDEFAULT_ATTR) {
102 cf.parseAnnotationDefaultAttr(this, key);
107 public void setClassAttribute (ClassFile cf, int attrIndex, String name, int attrLength) {
108 if (name == ClassFile.RUNTIME_VISIBLE_ANNOTATIONS_ATTR) {
110 cf.parseAnnotationsAttr(this, null);
115 public void setAnnotation (ClassFile cf, Object tag, int annotationIndex, String annotationType) {
116 if (annotationType.equals("Ljava/lang/annotation/Inherited;")) {
117 ai.setInherited( true);
122 public void setPrimitiveAnnotationValue (ClassFile cf, Object tag, int annotationIndex, int valueIndex,
123 String elementName, int arrayIndex, Object val) {
124 if (arrayIndex >= 0) {
125 valElements[arrayIndex] = val;
134 public void setStringAnnotationValue (ClassFile cf, Object tag, int annotationIndex, int valueIndex,
135 String elementName, int arrayIndex, String val) {
136 if (arrayIndex >= 0) {
137 valElements[arrayIndex] = val;
146 public void setClassAnnotationValue (ClassFile cf, Object tag, int annotationIndex, int valueIndex,
147 String elementName, int arrayIndex, String typeName) {
148 Object val = AnnotationInfo.getClassValue(typeName);
149 if (arrayIndex >= 0) {
150 valElements[arrayIndex] = val;
159 public void setEnumAnnotationValue (ClassFile cf, Object tag, int annotationIndex, int valueIndex,
160 String elementName, int arrayIndex, String enumType, String enumValue) {
161 Object val = AnnotationInfo.getEnumValue(enumType, enumValue);
162 if (arrayIndex >= 0) {
163 valElements[arrayIndex] = val;
172 public void setAnnotationValueElementCount (ClassFile cf, Object tag, int annotationIndex, int valueIndex,
173 String elementName, int elementCount) {
174 valElements = new Object[elementCount];
178 public void setAnnotationValueElementsDone (ClassFile cf, Object tag, int annotationIndex, int valueIndex,
179 String elementName) {