diff --git a/src/org/openjdk/asmtools/jasm/ClassArrayAttr.java b/src/org/openjdk/asmtools/jasm/ClassArrayAttr.java
new file mode 100644
index 0000000..0aaf9e9
--- /dev/null
+++ b/src/org/openjdk/asmtools/jasm/ClassArrayAttr.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Base class of the "classes[]" data of attributes
+ *
+ * JEP 181 (Nest-based Access Control): class file 55.0
+ * NestMembers_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 number_of_classes;
+ * u2 classes[number_of_classes];
+ * }
+ *
+ * JEP 360 (Sealed types): class file 59.65535
+ * PermittedSubtypes_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 permitted_subtypes_count;
+ * u2 classes[permitted_subtypes_count];
+ * }
+ */
+public class ClassArrayAttr extends AttrData {
+
+ List classes;
+
+ public ClassArrayAttr(String attributeName, ClassData cdata, List classes) {
+ super(cdata, attributeName);
+ this.classes = classes;
+ }
+
+ @Override
+ public int attrLength() {
+ return 2 + classes.size() * 2;
+ }
+
+ @Override
+ public void write(CheckedDataOutputStream out) throws IOException {
+ super.write(out);
+ out.writeShort(classes.size());
+ for (ConstantPool.ConstCell c : classes) {
+ out.writeShort(c.arg);
+ }
+ }
+}
diff --git a/src/org/openjdk/asmtools/jasm/ClassData.java b/src/org/openjdk/asmtools/jasm/ClassData.java
index d11f70d..3712e09 100644
--- a/src/org/openjdk/asmtools/jasm/ClassData.java
+++ b/src/org/openjdk/asmtools/jasm/ClassData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,9 @@ class ClassData extends MemberData {
// JEP 359 - Record attribute since class file 58.65535
private RecordData recordData;
+ // JEP 360 - PermittedSubtypes attribute since class file 59.65535
+ private PermittedTypesAttr permittedTypesAttr;
+
ModuleAttr moduleAttribute = null;
Environment env;
protected ConstantPool pool;
@@ -296,11 +299,17 @@ class ClassData extends MemberData {
nestHostAttr = new CPXAttr(this, AttrTag.ATT_NestHost.parsekey(), hostClass);
}
- public void addNestMembers(List nestMemberClasses) {
+ public void addNestMembers(List classes) {
env.traceln("addNestMembers");
- nestMembersAttr = new NestMembersAttr(this, nestMemberClasses);
+ nestMembersAttr = new NestMembersAttr(this, classes);
}
+ public void addPermittedSubtypes(List classes) {
+ env.traceln("addPermittedSubtypes");
+ permittedTypesAttr = new PermittedTypesAttr(this, classes);
+ }
+
+
public void endClass() {
sourceFileNameAttr = new CPXAttr(this,
AttrTag.ATT_SourceFile.parsekey(),
@@ -442,6 +451,9 @@ class ClassData extends MemberData {
attrs.add(nestHostAttr);
if(nestMembersAttributesExist())
attrs.add(nestMembersAttr);
+ // since class version 59.65535 (JEP 360)
+ if ( permittedSubtypesAttributesExist() )
+ attrs.add(permittedTypesAttr);
}
return attrs;
}
@@ -496,6 +508,8 @@ class ClassData extends MemberData {
public boolean nestMembersAttributesExist() { return nestMembersAttr != null; }
+ public boolean permittedSubtypesAttributesExist() { return permittedTypesAttr != null; }
+
public boolean recordAttributeExists() { return recordData != null; }
/**
diff --git a/src/org/openjdk/asmtools/jasm/JasmTokens.java b/src/org/openjdk/asmtools/jasm/JasmTokens.java
index d53d49b..0612cc6 100644
--- a/src/org/openjdk/asmtools/jasm/JasmTokens.java
+++ b/src/org/openjdk/asmtools/jasm/JasmTokens.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -308,10 +308,12 @@ public class JasmTokens {
// Declaration keywords
BOOTSTRAPMETHOD (172, "BOOTSTRAPMETHOD", "BootstrapMethod", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
- NESTHOST (173, "NESTHOST", "NestHost", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
- NESTMEMBERS (174, "NESTMEMBERS", "NestMembers", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
+ NESTHOST (173, "NESTHOST", "NestHost", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
+ NESTMEMBERS (174, "NESTMEMBERS", "NestMembers", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
//
- RECORD (175, "RECORD", "Record", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
+ RECORD (175, "RECORD", "Record", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
+ //
+ PERMITTEDSUBTYPES (176, "PERMITTEDSUBTYPES", "PermittedSubtypes", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
//Module statements
REQUIRES (180, "REQUIRES", "requires", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
diff --git a/src/org/openjdk/asmtools/jasm/NestMembersAttr.java b/src/org/openjdk/asmtools/jasm/NestMembersAttr.java
index 362801d..143c743 100644
--- a/src/org/openjdk/asmtools/jasm/NestMembersAttr.java
+++ b/src/org/openjdk/asmtools/jasm/NestMembersAttr.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,33 +22,20 @@
*/
package org.openjdk.asmtools.jasm;
-import java.io.IOException;
import java.util.List;
/**
- * The NestMembers attribute data
- *
- * since class file 55.0 (JEP 181)
+ * The "classes[]" data of attributes
+ * JEP 181 (Nest-based Access Control): class file 55.0
+ * NestMembers_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 number_of_classes;
+ * u2 classes[number_of_classes];
+ * }
*/
-public class NestMembersAttr extends AttrData {
- List nestMembers;
-
- public NestMembersAttr(ClassData cdata, List nestMembers){
- super(cdata, Tables.AttrTag.ATT_NestMembers.parsekey());
- this.nestMembers = nestMembers;
- }
-
- @Override
- public int attrLength() {
- return 2 + nestMembers.size() * 2;
- }
-
- @Override
- public void write(CheckedDataOutputStream out) throws IOException {
- super.write(out);
- out.writeShort(nestMembers.size());
- for (ConstantPool.ConstCell c : nestMembers) {
- out.writeShort(c.arg);
- }
+public class NestMembersAttr extends ClassArrayAttr {
+ public NestMembersAttr(ClassData cdata, List classes) {
+ super(Tables.AttrTag.ATT_NestMembers.parsekey(), cdata, classes);
}
}
diff --git a/src/org/openjdk/asmtools/jasm/Parser.java b/src/org/openjdk/asmtools/jasm/Parser.java
index eb6a4a0..ea6d3a8 100644
--- a/src/org/openjdk/asmtools/jasm/Parser.java
+++ b/src/org/openjdk/asmtools/jasm/Parser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -369,7 +369,7 @@ class Parser extends ParseBase {
// either a CONSTANT_Methodref_info structure or a CONSTANT_InterfaceMethodref_info structure (ยง4.4.2)
// representing a class's or interface's method for which a method handle is to be created.
ConstType ctype = ConstType.CONSTANT_METHOD;
- if ( this.cd.cfv.major_version() >= 52 && Modifiers.isInterface(this.cd.access) ) {
+ if (this.cd.cfv.major_version() >= 52 && Modifiers.isInterface(this.cd.access)) {
ctype = ConstType.CONSTANT_INTERFACEMETHOD;
}
refCell = pool.FindCell(cpParser.parseConstValue(ctype));
@@ -561,28 +561,67 @@ class Parser extends ParseBase {
while (true) {
nextmod = 0;
switch (scanner.token) {
- case PUBLIC: nextmod = ACC_PUBLIC; break;
- case PRIVATE: nextmod = ACC_PRIVATE; break;
- case PROTECTED: nextmod = ACC_PROTECTED; break;
- case STATIC: nextmod = ACC_STATIC; break;
- case FINAL: nextmod = ACC_FINAL; break;
- case SYNCHRONIZED: nextmod = ACC_SYNCHRONIZED; break;
- case SUPER: nextmod = ACC_SUPER; break;
- case VOLATILE: nextmod = ACC_VOLATILE; break;
- case BRIDGE: nextmod = ACC_BRIDGE; break;
- case TRANSIENT: nextmod = ACC_TRANSIENT; break;
- case VARARGS: nextmod = ACC_VARARGS; break;
- case NATIVE: nextmod = ACC_NATIVE; break;
- case INTERFACE: nextmod = ACC_INTERFACE; break;
- case ABSTRACT: nextmod = ACC_ABSTRACT; break;
- case STRICT: nextmod = ACC_STRICT; break;
- case ENUM: nextmod = ACC_ENUM; break;
- case SYNTHETIC: nextmod = ACC_SYNTHETIC; break;
+ case PUBLIC:
+ nextmod = ACC_PUBLIC;
+ break;
+ case PRIVATE:
+ nextmod = ACC_PRIVATE;
+ break;
+ case PROTECTED:
+ nextmod = ACC_PROTECTED;
+ break;
+ case STATIC:
+ nextmod = ACC_STATIC;
+ break;
+ case FINAL:
+ nextmod = ACC_FINAL;
+ break;
+ case SYNCHRONIZED:
+ nextmod = ACC_SYNCHRONIZED;
+ break;
+ case SUPER:
+ nextmod = ACC_SUPER;
+ break;
+ case VOLATILE:
+ nextmod = ACC_VOLATILE;
+ break;
+ case BRIDGE:
+ nextmod = ACC_BRIDGE;
+ break;
+ case TRANSIENT:
+ nextmod = ACC_TRANSIENT;
+ break;
+ case VARARGS:
+ nextmod = ACC_VARARGS;
+ break;
+ case NATIVE:
+ nextmod = ACC_NATIVE;
+ break;
+ case INTERFACE:
+ nextmod = ACC_INTERFACE;
+ break;
+ case ABSTRACT:
+ nextmod = ACC_ABSTRACT;
+ break;
+ case STRICT:
+ nextmod = ACC_STRICT;
+ break;
+ case ENUM:
+ nextmod = ACC_ENUM;
+ break;
+ case SYNTHETIC:
+ nextmod = ACC_SYNTHETIC;
+ break;
case ANNOTATION_ACCESS:
- nextmod = ACC_ANNOTATION; break;
+ nextmod = ACC_ANNOTATION;
+ break;
- case DEPRECATED: nextmod = DEPRECATED_ATTRIBUTE; break;
- case MANDATED: nextmod = ACC_MANDATED; break;
+ case DEPRECATED:
+ nextmod = DEPRECATED_ATTRIBUTE;
+ break;
+ case MANDATED:
+ nextmod = ACC_MANDATED;
+ break;
default:
return nextmod;
}
@@ -865,20 +904,21 @@ class Parser extends ParseBase {
}
/**
- * Parse a NestMembers entry
+ * Parse a list of classes belonging to the [NestMembers | PermittedSubtypes] entry
*/
- private void parseNestMembers() throws Scanner.SyntaxError, IOException {
- ArrayList nestMembers = new ArrayList<>();
+ private void parseClasses(Consumer> classesConsumer)
+ throws Scanner.SyntaxError, IOException {
+ ArrayList classes = new ArrayList<>();
// Parses in the form:
- // NESTMEMBERS IDENT(, IDENT)*;
- debugStr(" [Parser.parseNestMembers]: <<>>");
+ // (NESTMEMBERS|PERMITTEDSUBTYPES)? IDENT(, IDENT)*;
+ debugStr(" [Parser.parseClasses]: <<>>");
while (true) {
String className = prependPackage(parseIdent(), true);
- nestMembers.add(pool.FindCellClassByName(className));
- debugScan(" [Parser.parseNestMembers]: NestMembers: class " + className);
+ classes.add(pool.FindCellClassByName(className));
+ debugScan(" [Parser.parseClasses]: class " + className);
if (scanner.token != Token.COMMA) {
scanner.expect(Token.SEMICOLON);
- cd.addNestMembers(nestMembers);
+ classesConsumer.accept(classes);
return;
}
scanner.scan();
@@ -886,7 +926,7 @@ class Parser extends ParseBase {
}
/**
- * Parse a Record entry
+ * Parse the Record entry
*/
private void parseRecord() throws Scanner.SyntaxError, IOException {
// Parses in the form:
@@ -898,7 +938,7 @@ class Parser extends ParseBase {
// SIGNATURE = (CPINDEX | STRING)
debugScan("[Parser.parseRecord]: Begin ");
RecordData rd = cd.setRecord(scanner.pos);
-Component:
+ Component:
while (true) {
ConstCell nameCell, descCell, signatureCell = null;
nameCell = parseName();
@@ -913,10 +953,10 @@ Component:
case SEMICOLON:
return; // EOR
case ANNOTATION:
- rd.setAnnotations( annotParser.scanAnnotations());
+ rd.setAnnotations(annotParser.scanAnnotations());
break;
default:
- if( signatureCell != null ) {
+ if (signatureCell != null) {
env.error(scanner.pos, "warn.signature.repeated");
}
signatureCell = parseName();
@@ -1627,10 +1667,18 @@ Component:
throw new Scanner.SyntaxError();
}
scanner.scan();
- parseNestMembers();
+ parseClasses(list -> cd.addNestMembers(list));
break;
- case RECORD:
- if( cd.recordAttributeExists() ) {
+ case PERMITTEDSUBTYPES: // JEP 360
+ if (cd.nestMembersAttributesExist()) {
+ env.error(scanner.pos, "extra.permittedsubtypes.attribute");
+ throw new Scanner.SyntaxError();
+ }
+ scanner.scan();
+ parseClasses(list -> cd.addPermittedSubtypes(list));
+ break;
+ case RECORD: // JEP 359
+ if (cd.recordAttributeExists()) {
env.error(scanner.pos, "extra.record.attribute");
throw new Scanner.SyntaxError();
}
diff --git a/src/org/openjdk/asmtools/jasm/PermittedTypesAttr.java b/src/org/openjdk/asmtools/jasm/PermittedTypesAttr.java
new file mode 100644
index 0000000..9517b51
--- /dev/null
+++ b/src/org/openjdk/asmtools/jasm/PermittedTypesAttr.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jasm;
+
+import java.util.List;
+
+/**
+ * The "classes[]" data of attributes
+ * JEP 360 (Sealed types): class file 59.65535
+ * PermittedSubtypes_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 permitted_subtypes_count;
+ * u2 classes[permitted_subtypes_count];
+ * }
+ */
+public class PermittedTypesAttr extends ClassArrayAttr {
+ public PermittedTypesAttr(ClassData cdata, List classes) {
+ super(Tables.AttrTag.ATT_PermittedSubtypes.parsekey(), cdata, classes);
+ }
+}
diff --git a/src/org/openjdk/asmtools/jasm/Tables.java b/src/org/openjdk/asmtools/jasm/Tables.java
index bf164d1..2c21a5f 100644
--- a/src/org/openjdk/asmtools/jasm/Tables.java
+++ b/src/org/openjdk/asmtools/jasm/Tables.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -227,7 +227,15 @@ public class Tables {
// u2 components_count;
// component_info components[components_count];
// }
- ATT_Record (34, "ATT_Record", "Record");
+ ATT_Record (34, "ATT_Record", "Record"),
+ // JEP 360 (Sealed types): class file 59.65535
+ // PermittedSubtypes_attribute {
+ // u2 attribute_name_index;
+ // u4 attribute_length;
+ // u2 permitted_subtypes_count;
+ // u2 classes[permitted_subtypes_count];
+ // }
+ ATT_PermittedSubtypes (35, "ATT_PermittedSubtypes", "PermittedSubtypes");
private final Integer value;
private final String printval;
diff --git a/src/org/openjdk/asmtools/jasm/i18n.properties b/src/org/openjdk/asmtools/jasm/i18n.properties
index b882d2a..0da7dc5 100644
--- a/src/org/openjdk/asmtools/jasm/i18n.properties
+++ b/src/org/openjdk/asmtools/jasm/i18n.properties
@@ -1,4 +1,4 @@
-# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -77,23 +77,20 @@ err.const.def.expected=Constant declaration expected.
err.const.undecl=Constant #{0} not declared.
err.const.redecl=Constant {0} redeclared.
warn.const0.redecl=Re-declaration of Constant #0 cannot be written to the class file.
-#err.const.bsmindex=Bad Bootstrap Methods index {0} specified.
-#warn.const.misused=Constant {0} was assumed to have another tag.
err.field.expected=Field, method, NestMembers, NestHost or Record declaration expected.
err.token.expected={0} expected.
err.identifier.expected=Identifier expected.
err.extra.nesthost.attribute=There may be at most one NestHost attribute.
err.extra.nestmembers.attribute=There may be at most one NestMembers attribute.
+err.extra.permittedsubtypes.attribute=There may be at most one PermittedSubtypes attribute.
err.extra.record.attribute=There may be at most one Record attribute.
err.both.nesthost.nestmembers.found=The attributes table of a ClassFile structure must not contain both a NestMembers attribute and a NestHost attribute.
err.name.expected=Name expected, got {0}.
err.module.name.expected=Module name expected, got {0}.
err.int.expected=Integer expected.
-err.neg.forbidden=Negative integer is not allowed here.
err.value.large=Value doesn't fit in {0}.
err.value.expected=Value expected.
err.wrong.mnemocode=Invalid mnemocode ({0}).
-#err.class.expected='class' or 'interface' keyword expected.
err.default.redecl=Default statement already declared in this table.
err.long.switchtable=Switchtable too long: > {0}.
err.io.exception=I/O error in {0}.
@@ -117,9 +114,7 @@ err.cannot.write=Cannot write to {0}.
err.msig.malformed=Malformed method signature at char {0}. [err={1}]
err.no.classname=Class name not defined.
warn.msig.more255=Number of parameters too large ({0}>255).
-#warn.msig.large=Number of parameters ({0}) exceeds max_locals value ({1}).
warn.illslot=Local variable at Illegal slot {0}.
-#warn.invalid.modifier=This modifier is not allowed here
warn.repeated.modifier=Repeated modifier.
warn.invalid.modifier.init=invalid modifier for method \"{0}\".
warn.invalid.modifier.fiva=at most one of final and volatile modifiers can be used for a field
@@ -155,10 +150,7 @@ err.stackmap.repeated=stack_map redeclared.
err.version.expected=class file version expected
err.invalid.innerclass=Invalid declaration of Inner Class
err.invalid.bootstrapmethod=Invalid declaration of BootstrapMethod Entry
-#err.table.expected=Table expected
-#err.package.module.expected=package or module expected
err.frametype.repeated=Frametype repeated
-#err.module.expected=module expected
err.invalid.paramnum=Invalid Parameter Number: {0}.
err.duplicate.paramnum=Duplicate Parameter Number: {0}.
err.paramname.constnum.invaltype=ParameterName CPX at {0} is not a ConstantString.
@@ -188,7 +180,6 @@ warn.dot.will.be.converted=Forward slash \"/\" expected instead of dot \".\". Th
#
# Compiler Errors
#
-# comperr.hashcode.err="CV hash:{0}"
comperr.constcell.nullvalset="Cell without value in setCell"
comperr.constcell.nullvalhash="Cell without value in cpoolHashByValue"
comperr.constcell.invarg="Cell[{0}] has #{1}"
diff --git a/src/org/openjdk/asmtools/jdec/ClassData.java b/src/org/openjdk/asmtools/jdec/ClassData.java
index bd6e5e7..2b603c6 100644
--- a/src/org/openjdk/asmtools/jdec/ClassData.java
+++ b/src/org/openjdk/asmtools/jdec/ClassData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -262,7 +262,7 @@ class ClassData {
}
}
- private void printCP(PrintWriter out) throws IOException {
+ private void printCP(PrintWriter out) {
int length = CPlen;
startArrayCmt(length, "Constant Pool");
out_println("; // first element is empty");
@@ -273,7 +273,7 @@ class ClassData {
byte btag = types[i];
ConstType tg = tag(btag);
int pos = cpe_pos[i];
- String tagstr = "";
+ String tagstr;
String valstr;
int v1;
long lv;
@@ -359,14 +359,6 @@ class ClassData {
return " at " + toHex(countedin.getPos());
}
- private String getStringPosCond() {
- if (printDetails) {
- return getStringPos();
- } else {
- return "";
- }
- }
-
private String getCommentPosCond() {
if (printDetails) {
return " // " + getStringPos();
@@ -384,16 +376,16 @@ class ClassData {
out_println("// invalid length of " + attrname + " attr: " + len + " (should be " + (expectedIndices * 2) + ") > ");
printBytes(out, in, len);
} else {
- String outputString = "";
+ StringBuilder outputString = new StringBuilder();
for (int k = 1; k <= expectedIndices; k++) {
- outputString += ("#" + in.readUnsignedShort() + "; ");
+ outputString.append("#").append(in.readUnsignedShort()).append("; ");
if (k % 16 == 0) {
- out_println(outputString.replaceAll("\\s+$",""));
- outputString = "";
+ out_println(outputString.toString().replaceAll("\\s+$",""));
+ outputString = new StringBuilder();
}
}
- if (!outputString.isEmpty()) {
- out_println(outputString.replaceAll("\\s+$",""));
+ if (outputString.length() > 0) {
+ out_println(outputString.toString().replaceAll("\\s+$",""));
}
}
}
@@ -740,11 +732,8 @@ class ClassData {
// Read the attributes
decodeAttrs(in, out);
break;
- case ATT_ConstantValue:
- decodeCPXAttr(in, len, AttrName, out);
- break;
+
case ATT_Exceptions:
- case ATT_NestMembers:
int count = in.readUnsignedShort();
startArrayCmt(count, AttrName);
try {
@@ -758,7 +747,7 @@ class ClassData {
break;
case ATT_LineNumberTable:
int ll_num = in.readUnsignedShort();
- startArrayCmt(ll_num, AttrName);
+ startArrayCmt(ll_num, "line_number_table");
try {
for (int i = 0; i < ll_num; i++) {
out_println(in.readUnsignedShort() + " " +
@@ -788,7 +777,7 @@ class ClassData {
break;
case ATT_InnerClasses:
int ic_num = in.readUnsignedShort();
- startArrayCmt(ic_num, AttrName);
+ startArrayCmt(ic_num, "classes");
try {
for (int i = 0; i < ic_num; i++) {
out_println("#" + in.readUnsignedShort() + " #" +
@@ -800,9 +789,6 @@ class ClassData {
out_end("}");
}
break;
- case ATT_Signature:
- decodeCPXAttr(in, len, AttrName, out);
- break;
case ATT_StackMap:
int e_num = in.readUnsignedShort();
startArrayCmt(e_num, "");
@@ -887,9 +873,6 @@ class ClassData {
case ATT_EnclosingMethod:
decodeCPXAttrM(in, len, AttrName, out, 2);
break;
- case ATT_SourceFile:
- decodeCPXAttr(in, len, AttrName, out);
- break;
case ATT_AnnotationDefault:
decodeElementValue(in, out);
break;
@@ -980,10 +963,6 @@ class ClassData {
out_end("}");
}
break;
- // JEP 181: class file 55.0
- case ATT_NestHost:
- decodeCPXAttr(in, len, AttrName, out);
- break;
// MethodParameters_attribute {
// u2 attribute_name_index;
// u4 attribute_length;
@@ -1026,13 +1005,48 @@ class ClassData {
out_end("}");
}
break;
+ case ATT_ConstantValue:
+ case ATT_Signature:
+ case ATT_SourceFile:
+ decodeCPXAttr(in, len, AttrName, out);
+ break;
+ // JEP 181 (Nest-based Access Control): class file 55.0
+ // NestHost_attribute {
+ // u2 attribute_name_index;
+ // u4 attribute_length;
+ // u2 host_class_index;
+ // }
+ case ATT_NestHost:
+ decodeTypes(in, out, 1);
+ break;
+ // JEP 181 (Nest-based Access Control): class file 55.0
+ // NestMembers_attribute {
+ // u2 attribute_name_index;
+ // u4 attribute_length;
+ // u2 number_of_classes;
+ // u2 classes[number_of_classes];
+ // }
+ case ATT_NestMembers:
+ // JEP 360 (Sealed types): class file 59.65535
+ // PermittedSubtypes_attribute {
+ // u2 attribute_name_index;
+ // u4 attribute_length;
+ // u2 permitted_subtypes_count;
+ // u2 classes[permitted_subtypes_count];
+ // }
+ case ATT_PermittedSubtypes:
+ int nsubtypes = in.readUnsignedShort();
+ startArrayCmt(nsubtypes, "classes");
+ try {
+ decodeTypes(in, out, nsubtypes);
+ } finally {
+ out_end("}");
+ }
+ break;
default:
+ printBytes(out, in, len);
if (AttrName == null) {
- printBytes(out, in, len);
endingComment = "Attr(#" + name_cpx + ")";
- } else {
- // some kind of error?
- printBytes(out, in, len);
}
}
@@ -1168,13 +1182,13 @@ class ClassData {
}
private void decodeMembers(DataInputStream in, PrintWriter out, String groupName, String elementName) throws IOException {
- int nfields = in.readUnsignedShort();
- traceln(groupName + "=" + nfields);
- startArrayCmt(nfields, groupName);
+ int count = in.readUnsignedShort();
+ traceln(groupName + "=" + count);
+ startArrayCmt(count, groupName);
try {
- for (int i = 0; i < nfields; i++) {
+ for (int i = 0; i < count; i++) {
decodeInfo(in,out,elementName,true);
- if (i + 1 < nfields) {
+ if (i + 1 < count) {
out_println(";");
}
}
@@ -1205,7 +1219,7 @@ class ClassData {
entityType = "class";
}
if (!entityName.isEmpty() && (JcodTokens.keyword_token_ident(entityName) != JcodTokens.Token.IDENT || JcodTokens.constValue(entityName) != -1)) {
- // Jcod can't parse a entityName matching a keyword or a constant value,
+ // JCod can't parse a entityName matching a keyword or a constant value,
// then use the filename instead:
out_begin(String.format("file \"%s.class\" {", entityName));
} else {
@@ -1235,16 +1249,12 @@ class ClassData {
traceln(i18n.getString("jdec.trace.access_thisCpx_superCpx", access, this_cpx, super_cpx));
out.println();
- // Read the interface names
+ // Read the interfaces
int numinterfaces = in.readUnsignedShort();
traceln(i18n.getString("jdec.trace.numinterfaces", numinterfaces));
startArrayCmt(numinterfaces, "Interfaces");
try {
- for (int i = 0; i < numinterfaces; i++) {
- int intrf_cpx = in.readUnsignedShort();
- traceln(i18n.getString("jdec.trace.intrf", i, intrf_cpx));
- out_println("#" + intrf_cpx + ";");
- }
+ decodeTypes(in, out, numinterfaces);
} finally {
out_end("} // Interfaces\n");
}
@@ -1267,6 +1277,20 @@ class ClassData {
}
} // end decodeClass()
+ private void decodeTypes(DataInputStream in, PrintWriter out, int count) throws IOException {
+ for (int i = 0; i < count; i++) {
+ int type_cpx = in.readUnsignedShort();
+ traceln(i18n.getString("jdec.trace.type", i, type_cpx));
+ out_print("#" + type_cpx + ";");
+ if (printDetails) {
+ String name = (String) cpool[(int)cpool[type_cpx]];
+ out.println(" // " + name + getStringPos());
+ } else {
+ out.println();
+ }
+ }
+ }
+
/* ====================================================== */
boolean DebugFlag = false;
diff --git a/src/org/openjdk/asmtools/jdec/i18n.properties b/src/org/openjdk/asmtools/jdec/i18n.properties
index b1c1abd..a27299c 100644
--- a/src/org/openjdk/asmtools/jdec/i18n.properties
+++ b/src/org/openjdk/asmtools/jdec/i18n.properties
@@ -1,4 +1,4 @@
-# Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -37,5 +37,5 @@ jdec.trace.CP_len=CP len= {0}
jdec.trace.CP_entry=CP entry # {0} tag= {1}
jdec.trace.access_thisCpx_superCpx=access={0} this_cpx={1} super_cpx={2}
jdec.trace.numinterfaces=numinterfaces={0}
-jdec.trace.intrf=\
-\ intrf_cpx[{0}]={1}
+jdec.trace.type=\
+\ type_cpx[{0}]={1}
diff --git a/src/org/openjdk/asmtools/jdis/ClassArrayData.java b/src/org/openjdk/asmtools/jdis/ClassArrayData.java
new file mode 100644
index 0000000..60e697c
--- /dev/null
+++ b/src/org/openjdk/asmtools/jdis/ClassArrayData.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jdis;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * Base class of the "classes[]" data of attributes
+ *
+ * JEP 181 (Nest-based Access Control): class file 55.0
+ * NestMembers_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 number_of_classes;
+ * u2 classes[number_of_classes];
+ * }
+ *
+ * JEP 360 (Sealed types): class file 59.65535
+ * PermittedSubtypes_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 permitted_subtypes_count;
+ * u2 classes[permitted_subtypes_count];
+ * }
+ *
+ */
+public class ClassArrayData {
+ String name;
+ ClassData cls;
+ int[] classes;
+ private Options options = Options.OptionObject();
+
+ protected ClassArrayData(ClassData cls, String attrName) {
+ this.cls = cls;
+ this.name = attrName;
+ }
+
+ public ClassArrayData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
+ int number_of_classes = in.readUnsignedShort();
+ if (attribute_length != 2 + number_of_classes * 2) {
+ throw new ClassFormatError(name + "_attribute: Invalid attribute length");
+ }
+ classes = new int[number_of_classes];
+ for (int i = 0; i < number_of_classes; i++) {
+ classes[i] = in.readUnsignedShort();
+ }
+ return this;
+ }
+
+ public void print() {
+ String indexes = "";
+ String names = "";
+ boolean pr_cpx = options.contains(Options.PR.CPX);
+ cls.out.print(name + " ");
+ for (int i = 0; i < classes.length; i++) {
+ if (pr_cpx) {
+ indexes += (indexes.isEmpty() ? "" : ", ") + "#" + classes[i];
+ }
+ names += (names.isEmpty() ? "" : ", ") + cls.pool.StringValue(classes[i]);
+ }
+ if (pr_cpx) {
+ cls.out.print(indexes + "; // ");
+ }
+ cls.out.print(names);
+ if (pr_cpx) {
+ cls.out.println();
+ } else {
+ cls.out.println(";");
+ }
+ }
+
+}
diff --git a/src/org/openjdk/asmtools/jdis/ClassData.java b/src/org/openjdk/asmtools/jdis/ClassData.java
index 3597937..2bc20cd 100644
--- a/src/org/openjdk/asmtools/jdis/ClassData.java
+++ b/src/org/openjdk/asmtools/jdis/ClassData.java
@@ -92,6 +92,9 @@ public class ClassData extends MemberData {
// The NestMembers of this class (since class file: 55.0)
protected NestMembersData nestMembers;
+ // The PermittedSubtypes of this class (JEP 360 (Sealed types): class file 59.65535)
+ protected PermittedSubtypesData permittedSubtypes;
+
// other parsing fields
protected PrintWriter out;
protected String pkgPrefix = "";
@@ -215,6 +218,10 @@ public class ClassData extends MemberData {
case ATT_Record:
record = new RecordData(this).read(in);
break;
+ case ATT_PermittedSubtypes:
+ // Read PermittedSubtypes Attribute (JEP 360 (Sealed types): class file 59.65535)
+ permittedSubtypes = new PermittedSubtypesData(this).read(in, attrlen);
+ break;
default:
handled = false;
break;
@@ -288,6 +295,7 @@ public class ClassData extends MemberData {
public void print() throws IOException {
int k, l;
String className = "";
+ String sourceName = "";
if( isModuleUnit() ) {
// Print the Annotations
printAnnotations(visibleAnnotations);
@@ -407,20 +415,16 @@ printSugar:
out.println("{");
if ((options.contains(Options.PR.SRC)) && (source_cpx != 0)) {
- String source_name = pool.getName(source_cpx);
- out.println("\t// Compiled from " + source_name);
+ sourceName = String.format(" compiled from %s" +
+ "" , pool.getName(source_cpx));
try {
- source = new TextLines(source_name);
+ source = new TextLines(sourceName);
} catch (IOException ignored) {}
}
- // keep this new line for classes to pass huge test suite.
- if(!isModuleUnit())
- out.println();
// Print the constant pool
if (options.contains(Options.PR.CP)) {
pool.print(out);
- out.println();
}
// Don't print fields, methods, inner classes and bootstrap methods if it is module-info entity
if ( !isModuleUnit() ) {
@@ -446,6 +450,10 @@ printSugar:
record.print();
}
+ // Print PermittedSubtypes Attribute (JEP 360 (Sealed types): class file 59.65535)
+ if( permittedSubtypes != null) {
+ permittedSubtypes.print();
+ }
// Print the NestHost (since class file: 55.0)
if(nestHost != null) {
nestHost.print();
@@ -470,7 +478,11 @@ printSugar:
}
out.println();
}
- out.println("} // end Class " + className);
+
+
+
+
+ out.println("} // end Class " + className + sourceName);
} else {
// Print module attributes
moduleData.print();
diff --git a/src/org/openjdk/asmtools/jdis/ConstantPool.java b/src/org/openjdk/asmtools/jdis/ConstantPool.java
index 01d3e07..99e6957 100644
--- a/src/org/openjdk/asmtools/jdis/ConstantPool.java
+++ b/src/org/openjdk/asmtools/jdis/ConstantPool.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1049,7 +1049,7 @@ public class ConstantPool {
continue;
}
- out.print("const #" + cpx + " = ");
+ out.print("\tconst #" + cpx + " = ");
if (cns == null) {
// do something
@@ -1060,7 +1060,6 @@ public class ConstantPool {
cpx += cns.size();
}
}
- out.println();
}
/**
diff --git a/src/org/openjdk/asmtools/jdis/InnerClassData.java b/src/org/openjdk/asmtools/jdis/InnerClassData.java
index 3917615..8c7f300 100644
--- a/src/org/openjdk/asmtools/jdis/InnerClassData.java
+++ b/src/org/openjdk/asmtools/jdis/InnerClassData.java
@@ -66,7 +66,7 @@ class InnerClassData {
if (outer_class_info_index != 0) {
cls.out.print(" of #" + outer_class_info_index);
}
- cls.out.print("; //");
+ cls.out.print("; // ");
}
if (inner_name_index != 0) {
cls.out.print(cls.pool.getName(inner_name_index) + "=");
diff --git a/src/org/openjdk/asmtools/jdis/MethodData.java b/src/org/openjdk/asmtools/jdis/MethodData.java
index d8110f9..15c4bd5 100644
--- a/src/org/openjdk/asmtools/jdis/MethodData.java
+++ b/src/org/openjdk/asmtools/jdis/MethodData.java
@@ -336,6 +336,8 @@ public class MethodData extends MemberData {
if (code != null) {
code.print();
+ } else {
+ out.println();
}
}
diff --git a/src/org/openjdk/asmtools/jdis/NestMembersData.java b/src/org/openjdk/asmtools/jdis/NestMembersData.java
index c6bfa84..b5eee6b 100644
--- a/src/org/openjdk/asmtools/jdis/NestMembersData.java
+++ b/src/org/openjdk/asmtools/jdis/NestMembersData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,49 +30,20 @@ import java.io.IOException;
/**
* The NestMembers attribute data
*
- * since class file 55.0 (JEP 181)
+ * JEP 181 (Nest-based Access Control): class file 55.0
+ * NestMembers_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 number_of_classes;
+ * u2 classes[number_of_classes];
+ * }
*/
-public class NestMembersData {
- ClassData cls;
- int[] classes;
- private Options options = Options.OptionObject();
-
+public class NestMembersData extends ClassArrayData {
public NestMembersData(ClassData cls) {
- this.cls = cls;
+ super(cls, JasmTokens.Token.NESTMEMBERS.parsekey());
}
public NestMembersData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
- int number_of_classes = in.readUnsignedShort();
- if (attribute_length != 2 + number_of_classes * 2 ) {
- throw new ClassFormatError("ATT_NestMembers: Invalid attribute length");
- }
- classes = new int[number_of_classes];
- for (int i = 0; i < number_of_classes; i++) {
- classes[i] = in.readUnsignedShort();
- }
- return this;
+ return (NestMembersData) super.read(in, attribute_length);
}
-
- public void print() {
- String indexes = "";
- String names = "";
- boolean pr_cpx = options.contains(Options.PR.CPX);
- cls.out.print(JasmTokens.Token.NESTMEMBERS.parsekey() + " ");
- for(int i = 0; i< classes.length; i++) {
- if (pr_cpx) {
- indexes += (indexes.isEmpty() ? "" : ", ") + "#" + classes[i];
- }
- names += (names.isEmpty() ? "" : ", ") + cls.pool.StringValue(classes[i]);
- }
- if (pr_cpx) {
- cls.out.print(indexes + "; //");
- }
- cls.out.print(names);
- if (pr_cpx) {
- cls.out.println();
- } else {
- cls.out.println(";");
- }
- }
-
}
diff --git a/src/org/openjdk/asmtools/jdis/PermittedSubtypesData.java b/src/org/openjdk/asmtools/jdis/PermittedSubtypesData.java
new file mode 100644
index 0000000..7b5901c
--- /dev/null
+++ b/src/org/openjdk/asmtools/jdis/PermittedSubtypesData.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.asmtools.jdis;
+
+import org.openjdk.asmtools.jasm.JasmTokens;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * The NestMembers attribute data
+ *
+ * JEP 360 (Sealed types): class file 59.65535
+ * PermittedSubtypes_attribute {
+ * u2 attribute_name_index;
+ * u4 attribute_length;
+ * u2 permitted_subtypes_count;
+ * u2 classes[permitted_subtypes_count];
+ * }
+ */
+public class PermittedSubtypesData extends ClassArrayData {
+ public PermittedSubtypesData(ClassData cls) {
+ super(cls, JasmTokens.Token.PERMITTEDSUBTYPES.parsekey());
+ }
+
+ public PermittedSubtypesData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
+ return (PermittedSubtypesData) super.read(in, attribute_length);
+ }
+}