View Javadoc
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 }