1 /*
2 * Copyright (c) 2019, 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.jasm;
24
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
30
31 /**
32 * The record attribute (JEP 359 since class file 58.65535)
33 */
34 public class RecordData extends AttrData {
35 private List<ComponentData> components = new ArrayList<>();
36
37 public RecordData(ClassData cls) {
38 super(cls, Tables.AttrTag.ATT_Record.parsekey());
39 }
40
41 public void addComponent(ConstantPool.ConstCell nameCell,
42 ConstantPool.ConstCell descCell,
43 ConstantPool.ConstCell signature,
44 ArrayList<AnnotationData> annotations) {
45 // Define a field if absent
46 FieldData fd = getClassData().addFieldIfAbsent(ACC_MANDATED & ACC_PRIVATE & ACC_FINAL, nameCell, descCell);
47 ComponentData cd = new ComponentData(fd);
48 if( annotations != null ) {
49 cd.addAnnotations(annotations);
50 }
51 if( signature != null ) {
52 cd.setSignatureAttr(signature);
53 }
54 components.add(cd);
55 }
56
57 public boolean isEmpty() {
58 return components.isEmpty();
59 }
60
61 @Override
62 public void write(CheckedDataOutputStream out) throws IOException {
63 super.write(out);
64 out.writeShort(components.size());
65 for (ComponentData cd : components) {
66 cd.write(out);
67 }
68 }
69
70 @Override
71 public int attrLength() {
72 int compsLength = components.stream().mapToInt(c -> c.getLength()).sum();
73 return 2 + compsLength;
74 }
75
76 class ComponentData extends MemberData {
77 private FieldData field;
78
79 public ComponentData(FieldData field) {
80 super(getClassData());
81 this.field = field;
82 }
83
84 @Override
85 protected DataVector getAttrVector() {
86 return getDataVector(signatureAttr);
87 }
88
89 public void write(CheckedDataOutputStream out) throws IOException, Parser.CompilerError {
90 out.writeShort(field.getNameDesc().left.arg);
91 out.writeShort(field.getNameDesc().right.arg);
92 DataVector attrs = getAttrVector();
93 attrs.write(out);
94 }
95
96 public int getLength() {
97 return 4 + getAttrVector().getLength();
98 }
99 }
100 }