1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * https://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.bcel.classfile;
20
21 import java.io.DataInput;
22 import java.io.DataOutputStream;
23 import java.io.IOException;
24
25 import org.apache.bcel.Const;
26
27 /**
28 * Record component info from a record. Instances from this class maps
29 * every component from a given record.
30 *
31 * @see <a href="https://docs.oracle.com/javase/specs/jvms/se14/preview/specs/records-jvms.html#jvms-4.7.30">
32 * The Java Virtual Machine Specification, Java SE 14 Edition, Records (preview)</a>
33 * @since 6.9.0
34 */
35 public class RecordComponentInfo implements Node {
36
37 private final int index;
38 private final int descriptorIndex;
39 private final Attribute[] attributes;
40 private final ConstantPool constantPool;
41
42 /**
43 * Constructs a new instance from an input stream.
44 *
45 * @param input Input stream
46 * @param constantPool Array of constants
47 * @throws IOException if an I/O error occurs.
48 */
49 public RecordComponentInfo(final DataInput input, final ConstantPool constantPool) throws IOException {
50 this.index = input.readUnsignedShort();
51 this.descriptorIndex = input.readUnsignedShort();
52 final int attributesCount = input.readUnsignedShort();
53 this.attributes = new Attribute[attributesCount];
54 for (int j = 0; j < attributesCount; j++) {
55 attributes[j] = Attribute.readAttribute(input, constantPool);
56 }
57 this.constantPool = constantPool;
58 }
59
60 @Override
61 public void accept(final Visitor v) {
62 v.visitRecordComponent(this);
63 }
64
65 /**
66 * Dumps contents into a file stream in binary format.
67 *
68 * @param file Output file stream
69 * @throws IOException if an I/O error occurs.
70 */
71 public void dump(final DataOutputStream file) throws IOException {
72 file.writeShort(index);
73 file.writeShort(descriptorIndex);
74 file.writeShort(attributes.length);
75 for (final Attribute attribute : attributes) {
76 attribute.dump(file);
77 }
78 }
79
80 /**
81 * Gets all attributes.
82 *
83 * @return all attributes.
84 */
85 public Attribute[] getAttributes() {
86 return attributes;
87 }
88
89 /**
90 * Gets the constant pool.
91 *
92 * @return Constant pool.
93 */
94 public ConstantPool getConstantPool() {
95 return constantPool;
96 }
97
98 /**
99 * Gets the description index.
100 *
101 * @return index in constant pool of this record component descriptor.
102 */
103 public int getDescriptorIndex() {
104 return descriptorIndex;
105 }
106
107 /**
108 * Gets the name index.
109 *
110 * @return index in constant pool of this record component name.
111 */
112 public int getIndex() {
113 return index;
114 }
115
116 /**
117 * Converts this instance to a String suitable for debugging.
118 *
119 * @return a String suitable for debugging.
120 */
121 @Override
122 public String toString() {
123 final StringBuilder buf = new StringBuilder();
124 buf.append("RecordComponentInfo(");
125 buf.append(constantPool.getConstantString(index, Const.CONSTANT_Utf8));
126 buf.append(",");
127 buf.append(constantPool.getConstantString(descriptorIndex, Const.CONSTANT_Utf8));
128 buf.append(",");
129 buf.append(attributes.length);
130 buf.append("):\n");
131 for (final Attribute attribute : attributes) {
132 buf.append(" ").append(attribute.toString()).append("\n");
133 }
134 return buf.substring(0, buf.length() - 1); // remove the last newline
135 }
136
137 }