1 /*
2 * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.openjdk.asmtools.jdis;
24
25 import org.openjdk.asmtools.jasm.Tables;
26 import java.io.DataInputStream;
27 import java.io.IOException;
28 import java.io.PrintWriter;
29 import java.util.ArrayList;
30
31 import static java.lang.String.format;
32
33 /**
34 * Base class for ClassData, MethodData, FieldData and RecordData(JEP 360)
35 */
36 public abstract class MemberData extends Indenter {
37
38 // access flags (modifiers)
39 protected int access;
40
41 // flags
42 protected boolean isSynthetic = false;
43 protected boolean isDeprecated = false;
44
45 // Signature can be located in ClassFile, field_info, method_info, and component_info
46 protected SignatureData signature;
47
48 /**
49 * The visible annotations for this class, member( field or method) or record component
50 */
51 protected ArrayList<AnnotationData> visibleAnnotations;
52
53 /**
54 * The invisible annotations for this class, member( field or method) or record component
55 */
56 protected ArrayList<AnnotationData> invisibleAnnotations;
57
58 /**
59 * The visible annotations for this class, member( field or method) or record component
60 */
61 protected ArrayList<TypeAnnotationData> visibleTypeAnnotations;
62
63 /**
64 * The invisible annotations for this class, member( field or method) or record component
65 */
66 protected ArrayList<TypeAnnotationData> invisibleTypeAnnotations;
67
68 /**
69 * The remaining attributes of this class, member( field or method) or record component
70 */
71 protected ArrayList<AttrData> attrs;
72
73 // internal references
74 protected final Options options = Options.OptionObject();
75 protected final boolean pr_cpx = options.contains(Options.PR.CPX);;
76 protected ClassData cls;
77 protected PrintWriter out;
78 protected String memberType = "";
79
80 public MemberData(ClassData cls) {
81 this();
82 init(cls);
83 }
84
85 public MemberData() {
86 }
87
88 public void init(ClassData cls) {
89 this.out = cls.out;
90 this.cls = cls;
91 }
92
93 protected boolean handleAttributes(DataInputStream in, Tables.AttrTag attrtag, int attrlen) throws IOException {
94 // sub-classes override
95 return false;
96 }
97
98 protected abstract void print() throws IOException;
99
100 final protected int getAnnotationsCount() {
101 return ((visibleAnnotations == null) ? 0 : visibleAnnotations.size()) +
102 ((invisibleAnnotations == null) ? 0 : invisibleAnnotations.size()) +
103 ((visibleTypeAnnotations == null) ? 0 : visibleTypeAnnotations.size()) +
104 ((invisibleTypeAnnotations == null) ? 0 : invisibleTypeAnnotations.size());
105
106 }
107
108 final protected void printAnnotations(String initialTab) {
109 if( getAnnotationsCount() > 0 ) {
110 if (visibleAnnotations != null) {
111 for (AnnotationData visad : visibleAnnotations) {
112 // out.print(initialTab);
113 visad.print(out, initialTab);
114 out.println();
115 }
116 }
117 if (invisibleAnnotations != null) {
118 for (AnnotationData invisad : invisibleAnnotations) {
119 invisad.print(out, initialTab);
120 out.println();
121 }
122 }
123
124 if (visibleTypeAnnotations != null) {
125 for (TypeAnnotationData visad : visibleTypeAnnotations) {
126 visad.print(out, initialTab);
127 out.println();
128 }
129 }
130 if (invisibleTypeAnnotations != null) {
131 for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
132 invisad.print(out, initialTab);
133 out.println();
134 }
135 }
136 }
137 }
138
139 protected void printVar(StringBuilder bodyPrefix, StringBuilder tailPrefix, int name_cpx, int type_cpx) {
140 if( pr_cpx ) {
141 bodyPrefix.append('#').append(name_cpx).append(":#").append(type_cpx);
142 tailPrefix.append(";\t // ").append(cls.pool.getName(name_cpx)).append(':').append(cls.pool.getName(type_cpx));
143
144 } else {
145 bodyPrefix.append(cls.pool.getName(name_cpx)).append(':').append(cls.pool.getName(type_cpx));
146 tailPrefix.append(';');
147 }
148
149 if (signature != null) {
150 signature.print(bodyPrefix.append(':').toString(), tailPrefix.append( pr_cpx ? ":" : "" ).toString());
151 } else {
152 out.print(bodyPrefix);
153 out.print(tailPrefix);
154 }
155 out.println();
156 }
157
158 protected void readAttributes(DataInputStream in) throws IOException {
159 // Read the Attributes
160 int natt = in.readUnsignedShort();
161 attrs = new ArrayList<>(natt);
162 TraceUtils.traceln(format("%s - Attributes[%d]", memberType , natt));
163 AttrData attr;
164 for (int k = 0; k < natt; k++) {
165 int name_cpx = in.readUnsignedShort();
166 attr = new AttrData(cls);
167 attrs.add(attr);
168 String attr_name = cls.pool.getString(name_cpx);
169 TraceUtils.traceln(format(" #%d name[%d]=\"%s\"", k, name_cpx, attr_name));
170 Tables.AttrTag tag = Tables.attrtag(attr_name);
171 int attrlen = in.readInt();
172 switch (tag) {
173 case ATT_Synthetic:
174 // Read Synthetic Attr
175 if (attrlen != 0) {
176 throw new ClassFormatError("invalid Synthetic attr length");
177 }
178 isSynthetic = true;
179 break;
180 case ATT_Deprecated:
181 // Read Deprecated Attr
182 if (attrlen != 0) {
183 throw new ClassFormatError("invalid Deprecated attr length");
184 }
185 isDeprecated = true;
186 break;
187 case ATT_RuntimeVisibleAnnotations:
188 case ATT_RuntimeInvisibleAnnotations:
189 // Read Annotations Attr
190 int cnt = in.readShort();
191 ArrayList<AnnotationData> annots = new ArrayList<>(cnt);
192 boolean invisible = (tag == Tables.AttrTag.ATT_RuntimeInvisibleAnnotations);
193 for (int i = 0; i < cnt; i++) {
194 TraceUtils.traceln(" AnnotationData: #" + i);
195 AnnotationData annot = new AnnotationData(invisible, cls);
196 annot.read(in);
197 annots.add(annot);
198 }
199
200 if (invisible) {
201 invisibleAnnotations = annots;
202 } else {
203 visibleAnnotations = annots;
204 }
205 break;
206 case ATT_RuntimeVisibleTypeAnnotations:
207 case ATT_RuntimeInvisibleTypeAnnotations:
208 // Read Type Annotations Attr
209 int tcnt = in.readShort();
210 ArrayList<TypeAnnotationData> tannots = new ArrayList<>(tcnt);
211 boolean tinvisible = (tag == Tables.AttrTag.ATT_RuntimeInvisibleTypeAnnotations);
212 for (int tindex = 0; tindex < tcnt; tindex++) {
213 TraceUtils.traceln(" TypeAnnotationData: #" + tindex);
214 TypeAnnotationData tannot = new TypeAnnotationData(tinvisible, cls);
215 tannot.read(in);
216 tannots.add(tannot);
217 }
218
219 if (tinvisible) {
220 invisibleTypeAnnotations = tannots;
221 } else {
222 visibleTypeAnnotations = tannots;
223 }
224 break;
225 default:
226 boolean handled = handleAttributes(in, tag, attrlen);
227 if (!handled) {
228 attr.read(name_cpx, attrlen, in);
229 }
230 break;
231
232 }
233 }
234 }
235 }