001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.bcel.classfile; 020 021import java.io.DataInput; 022import java.io.DataOutputStream; 023import java.io.IOException; 024 025import org.apache.bcel.Const; 026 027/** 028 * Record component info from a record. Instances from this class maps 029 * every component from a given record. 030 * 031 * @see <a href="https://docs.oracle.com/javase/specs/jvms/se14/preview/specs/records-jvms.html#jvms-4.7.30"> 032 * The Java Virtual Machine Specification, Java SE 14 Edition, Records (preview)</a> 033 * @since 6.9.0 034 */ 035public class RecordComponentInfo implements Node { 036 037 private final int index; 038 private final int descriptorIndex; 039 private final Attribute[] attributes; 040 private final ConstantPool constantPool; 041 042 /** 043 * Constructs a new instance from an input stream. 044 * 045 * @param input Input stream 046 * @param constantPool Array of constants 047 * @throws IOException if an I/O error occurs. 048 */ 049 public RecordComponentInfo(final DataInput input, final ConstantPool constantPool) throws IOException { 050 this.index = input.readUnsignedShort(); 051 this.descriptorIndex = input.readUnsignedShort(); 052 final int attributesCount = input.readUnsignedShort(); 053 this.attributes = new Attribute[attributesCount]; 054 for (int j = 0; j < attributesCount; j++) { 055 attributes[j] = Attribute.readAttribute(input, constantPool); 056 } 057 this.constantPool = constantPool; 058 } 059 060 @Override 061 public void accept(final Visitor v) { 062 v.visitRecordComponent(this); 063 } 064 065 /** 066 * Dumps contents into a file stream in binary format. 067 * 068 * @param file Output file stream 069 * @throws IOException if an I/O error occurs. 070 */ 071 public void dump(final DataOutputStream file) throws IOException { 072 file.writeShort(index); 073 file.writeShort(descriptorIndex); 074 file.writeShort(attributes.length); 075 for (final Attribute attribute : attributes) { 076 attribute.dump(file); 077 } 078 } 079 080 /** 081 * Gets all attributes. 082 * 083 * @return all attributes. 084 */ 085 public Attribute[] getAttributes() { 086 return attributes; 087 } 088 089 /** 090 * Gets the constant pool. 091 * 092 * @return Constant pool. 093 */ 094 public ConstantPool getConstantPool() { 095 return constantPool; 096 } 097 098 /** 099 * 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}