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 }