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