CODETOOLS-7902525 Asmtools support: JEP 360 Sealed Types(Preview)
This commit is contained in:
parent
a136ef54ee
commit
79096622a1
69
src/org/openjdk/asmtools/jasm/ClassArrayAttr.java
Normal file
69
src/org/openjdk/asmtools/jasm/ClassArrayAttr.java
Normal file
@ -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
|
||||||
|
* <p>
|
||||||
|
* 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];
|
||||||
|
* }
|
||||||
|
* <p>
|
||||||
|
* 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<ConstantPool.ConstCell> classes;
|
||||||
|
|
||||||
|
public ClassArrayAttr(String attributeName, ClassData cdata, List<ConstantPool.ConstCell> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
// JEP 359 - Record attribute since class file 58.65535
|
||||||
private RecordData recordData;
|
private RecordData recordData;
|
||||||
|
|
||||||
|
// JEP 360 - PermittedSubtypes attribute since class file 59.65535
|
||||||
|
private PermittedTypesAttr permittedTypesAttr;
|
||||||
|
|
||||||
ModuleAttr moduleAttribute = null;
|
ModuleAttr moduleAttribute = null;
|
||||||
Environment env;
|
Environment env;
|
||||||
protected ConstantPool pool;
|
protected ConstantPool pool;
|
||||||
@ -296,11 +299,17 @@ class ClassData extends MemberData {
|
|||||||
nestHostAttr = new CPXAttr(this, AttrTag.ATT_NestHost.parsekey(), hostClass);
|
nestHostAttr = new CPXAttr(this, AttrTag.ATT_NestHost.parsekey(), hostClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNestMembers(List<ConstantPool.ConstCell> nestMemberClasses) {
|
public void addNestMembers(List<ConstantPool.ConstCell> classes) {
|
||||||
env.traceln("addNestMembers");
|
env.traceln("addNestMembers");
|
||||||
nestMembersAttr = new NestMembersAttr(this, nestMemberClasses);
|
nestMembersAttr = new NestMembersAttr(this, classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addPermittedSubtypes(List<ConstantPool.ConstCell> classes) {
|
||||||
|
env.traceln("addPermittedSubtypes");
|
||||||
|
permittedTypesAttr = new PermittedTypesAttr(this, classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void endClass() {
|
public void endClass() {
|
||||||
sourceFileNameAttr = new CPXAttr(this,
|
sourceFileNameAttr = new CPXAttr(this,
|
||||||
AttrTag.ATT_SourceFile.parsekey(),
|
AttrTag.ATT_SourceFile.parsekey(),
|
||||||
@ -442,6 +451,9 @@ class ClassData extends MemberData {
|
|||||||
attrs.add(nestHostAttr);
|
attrs.add(nestHostAttr);
|
||||||
if(nestMembersAttributesExist())
|
if(nestMembersAttributesExist())
|
||||||
attrs.add(nestMembersAttr);
|
attrs.add(nestMembersAttr);
|
||||||
|
// since class version 59.65535 (JEP 360)
|
||||||
|
if ( permittedSubtypesAttributesExist() )
|
||||||
|
attrs.add(permittedTypesAttr);
|
||||||
}
|
}
|
||||||
return attrs;
|
return attrs;
|
||||||
}
|
}
|
||||||
@ -496,6 +508,8 @@ class ClassData extends MemberData {
|
|||||||
|
|
||||||
public boolean nestMembersAttributesExist() { return nestMembersAttr != null; }
|
public boolean nestMembersAttributesExist() { return nestMembersAttr != null; }
|
||||||
|
|
||||||
|
public boolean permittedSubtypesAttributesExist() { return permittedTypesAttr != null; }
|
||||||
|
|
||||||
public boolean recordAttributeExists() { return recordData != null; }
|
public boolean recordAttributeExists() { return recordData != null; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -308,10 +308,12 @@ public class JasmTokens {
|
|||||||
|
|
||||||
// Declaration keywords
|
// Declaration keywords
|
||||||
BOOTSTRAPMETHOD (172, "BOOTSTRAPMETHOD", "BootstrapMethod", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
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),
|
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),
|
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
|
//Module statements
|
||||||
REQUIRES (180, "REQUIRES", "requires", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
REQUIRES (180, "REQUIRES", "requires", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,33 +22,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.openjdk.asmtools.jasm;
|
package org.openjdk.asmtools.jasm;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The NestMembers attribute data
|
* The "classes[]" data of attributes
|
||||||
* <p>
|
* JEP 181 (Nest-based Access Control): class file 55.0
|
||||||
* since class file 55.0 (JEP 181)
|
* NestMembers_attribute {
|
||||||
|
* u2 attribute_name_index;
|
||||||
|
* u4 attribute_length;
|
||||||
|
* u2 number_of_classes;
|
||||||
|
* u2 classes[number_of_classes];
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
public class NestMembersAttr extends AttrData {
|
public class NestMembersAttr extends ClassArrayAttr {
|
||||||
List<ConstantPool.ConstCell> nestMembers;
|
public NestMembersAttr(ClassData cdata, List<ConstantPool.ConstCell> classes) {
|
||||||
|
super(Tables.AttrTag.ATT_NestMembers.parsekey(), cdata, classes);
|
||||||
public NestMembersAttr(ClassData cdata, List<ConstantPool.ConstCell> 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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)
|
// 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.
|
// representing a class's or interface's method for which a method handle is to be created.
|
||||||
ConstType ctype = ConstType.CONSTANT_METHOD;
|
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;
|
ctype = ConstType.CONSTANT_INTERFACEMETHOD;
|
||||||
}
|
}
|
||||||
refCell = pool.FindCell(cpParser.parseConstValue(ctype));
|
refCell = pool.FindCell(cpParser.parseConstValue(ctype));
|
||||||
@ -561,28 +561,67 @@ class Parser extends ParseBase {
|
|||||||
while (true) {
|
while (true) {
|
||||||
nextmod = 0;
|
nextmod = 0;
|
||||||
switch (scanner.token) {
|
switch (scanner.token) {
|
||||||
case PUBLIC: nextmod = ACC_PUBLIC; break;
|
case PUBLIC:
|
||||||
case PRIVATE: nextmod = ACC_PRIVATE; break;
|
nextmod = ACC_PUBLIC;
|
||||||
case PROTECTED: nextmod = ACC_PROTECTED; break;
|
break;
|
||||||
case STATIC: nextmod = ACC_STATIC; break;
|
case PRIVATE:
|
||||||
case FINAL: nextmod = ACC_FINAL; break;
|
nextmod = ACC_PRIVATE;
|
||||||
case SYNCHRONIZED: nextmod = ACC_SYNCHRONIZED; break;
|
break;
|
||||||
case SUPER: nextmod = ACC_SUPER; break;
|
case PROTECTED:
|
||||||
case VOLATILE: nextmod = ACC_VOLATILE; break;
|
nextmod = ACC_PROTECTED;
|
||||||
case BRIDGE: nextmod = ACC_BRIDGE; break;
|
break;
|
||||||
case TRANSIENT: nextmod = ACC_TRANSIENT; break;
|
case STATIC:
|
||||||
case VARARGS: nextmod = ACC_VARARGS; break;
|
nextmod = ACC_STATIC;
|
||||||
case NATIVE: nextmod = ACC_NATIVE; break;
|
break;
|
||||||
case INTERFACE: nextmod = ACC_INTERFACE; break;
|
case FINAL:
|
||||||
case ABSTRACT: nextmod = ACC_ABSTRACT; break;
|
nextmod = ACC_FINAL;
|
||||||
case STRICT: nextmod = ACC_STRICT; break;
|
break;
|
||||||
case ENUM: nextmod = ACC_ENUM; break;
|
case SYNCHRONIZED:
|
||||||
case SYNTHETIC: nextmod = ACC_SYNTHETIC; break;
|
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:
|
case ANNOTATION_ACCESS:
|
||||||
nextmod = ACC_ANNOTATION; break;
|
nextmod = ACC_ANNOTATION;
|
||||||
|
break;
|
||||||
|
|
||||||
case DEPRECATED: nextmod = DEPRECATED_ATTRIBUTE; break;
|
case DEPRECATED:
|
||||||
case MANDATED: nextmod = ACC_MANDATED; break;
|
nextmod = DEPRECATED_ATTRIBUTE;
|
||||||
|
break;
|
||||||
|
case MANDATED:
|
||||||
|
nextmod = ACC_MANDATED;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return nextmod;
|
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 {
|
private void parseClasses(Consumer<ArrayList<ConstCell>> classesConsumer)
|
||||||
ArrayList<ConstCell> nestMembers = new ArrayList<>();
|
throws Scanner.SyntaxError, IOException {
|
||||||
|
ArrayList<ConstCell> classes = new ArrayList<>();
|
||||||
// Parses in the form:
|
// Parses in the form:
|
||||||
// NESTMEMBERS IDENT(, IDENT)*;
|
// (NESTMEMBERS|PERMITTEDSUBTYPES)? IDENT(, IDENT)*;
|
||||||
debugStr(" [Parser.parseNestMembers]: <<<Begin>>>");
|
debugStr(" [Parser.parseClasses]: <<<Begin>>>");
|
||||||
while (true) {
|
while (true) {
|
||||||
String className = prependPackage(parseIdent(), true);
|
String className = prependPackage(parseIdent(), true);
|
||||||
nestMembers.add(pool.FindCellClassByName(className));
|
classes.add(pool.FindCellClassByName(className));
|
||||||
debugScan(" [Parser.parseNestMembers]: NestMembers: class " + className);
|
debugScan(" [Parser.parseClasses]: class " + className);
|
||||||
if (scanner.token != Token.COMMA) {
|
if (scanner.token != Token.COMMA) {
|
||||||
scanner.expect(Token.SEMICOLON);
|
scanner.expect(Token.SEMICOLON);
|
||||||
cd.addNestMembers(nestMembers);
|
classesConsumer.accept(classes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scanner.scan();
|
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 {
|
private void parseRecord() throws Scanner.SyntaxError, IOException {
|
||||||
// Parses in the form:
|
// Parses in the form:
|
||||||
@ -898,7 +938,7 @@ class Parser extends ParseBase {
|
|||||||
// SIGNATURE = (CPINDEX | STRING)
|
// SIGNATURE = (CPINDEX | STRING)
|
||||||
debugScan("[Parser.parseRecord]: Begin ");
|
debugScan("[Parser.parseRecord]: Begin ");
|
||||||
RecordData rd = cd.setRecord(scanner.pos);
|
RecordData rd = cd.setRecord(scanner.pos);
|
||||||
Component:
|
Component:
|
||||||
while (true) {
|
while (true) {
|
||||||
ConstCell nameCell, descCell, signatureCell = null;
|
ConstCell nameCell, descCell, signatureCell = null;
|
||||||
nameCell = parseName();
|
nameCell = parseName();
|
||||||
@ -913,10 +953,10 @@ Component:
|
|||||||
case SEMICOLON:
|
case SEMICOLON:
|
||||||
return; // EOR
|
return; // EOR
|
||||||
case ANNOTATION:
|
case ANNOTATION:
|
||||||
rd.setAnnotations( annotParser.scanAnnotations());
|
rd.setAnnotations(annotParser.scanAnnotations());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if( signatureCell != null ) {
|
if (signatureCell != null) {
|
||||||
env.error(scanner.pos, "warn.signature.repeated");
|
env.error(scanner.pos, "warn.signature.repeated");
|
||||||
}
|
}
|
||||||
signatureCell = parseName();
|
signatureCell = parseName();
|
||||||
@ -1627,10 +1667,18 @@ Component:
|
|||||||
throw new Scanner.SyntaxError();
|
throw new Scanner.SyntaxError();
|
||||||
}
|
}
|
||||||
scanner.scan();
|
scanner.scan();
|
||||||
parseNestMembers();
|
parseClasses(list -> cd.addNestMembers(list));
|
||||||
break;
|
break;
|
||||||
case RECORD:
|
case PERMITTEDSUBTYPES: // JEP 360
|
||||||
if( cd.recordAttributeExists() ) {
|
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");
|
env.error(scanner.pos, "extra.record.attribute");
|
||||||
throw new Scanner.SyntaxError();
|
throw new Scanner.SyntaxError();
|
||||||
}
|
}
|
||||||
|
41
src/org/openjdk/asmtools/jasm/PermittedTypesAttr.java
Normal file
41
src/org/openjdk/asmtools/jasm/PermittedTypesAttr.java
Normal file
@ -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<ConstantPool.ConstCell> classes) {
|
||||||
|
super(Tables.AttrTag.ATT_PermittedSubtypes.parsekey(), cdata, classes);
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -227,7 +227,15 @@ public class Tables {
|
|||||||
// u2 components_count;
|
// u2 components_count;
|
||||||
// component_info components[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 Integer value;
|
||||||
private final String printval;
|
private final String printval;
|
||||||
|
@ -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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# 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.undecl=Constant #{0} not declared.
|
||||||
err.const.redecl=Constant {0} redeclared.
|
err.const.redecl=Constant {0} redeclared.
|
||||||
warn.const0.redecl=Re-declaration of Constant #0 cannot be written to the class file.
|
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.field.expected=Field, method, NestMembers, NestHost or Record declaration expected.
|
||||||
err.token.expected={0} expected.
|
err.token.expected={0} expected.
|
||||||
err.identifier.expected=Identifier expected.
|
err.identifier.expected=Identifier expected.
|
||||||
err.extra.nesthost.attribute=There may be at most one NestHost attribute.
|
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.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.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.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.name.expected=Name expected, got {0}.
|
||||||
err.module.name.expected=Module name expected, got {0}.
|
err.module.name.expected=Module name expected, got {0}.
|
||||||
err.int.expected=Integer expected.
|
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.large=Value doesn't fit in {0}.
|
||||||
err.value.expected=Value expected.
|
err.value.expected=Value expected.
|
||||||
err.wrong.mnemocode=Invalid mnemocode ({0}).
|
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.default.redecl=Default statement already declared in this table.
|
||||||
err.long.switchtable=Switchtable too long: > {0}.
|
err.long.switchtable=Switchtable too long: > {0}.
|
||||||
err.io.exception=I/O error in {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.msig.malformed=Malformed method signature at char {0}. [err={1}]
|
||||||
err.no.classname=Class name not defined.
|
err.no.classname=Class name not defined.
|
||||||
warn.msig.more255=Number of parameters too large ({0}>255).
|
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.illslot=Local variable at Illegal slot {0}.
|
||||||
#warn.invalid.modifier=This modifier is not allowed here
|
|
||||||
warn.repeated.modifier=Repeated modifier.
|
warn.repeated.modifier=Repeated modifier.
|
||||||
warn.invalid.modifier.init=invalid modifier for <init> method \"{0}\".
|
warn.invalid.modifier.init=invalid modifier for <init> method \"{0}\".
|
||||||
warn.invalid.modifier.fiva=at most one of final and volatile modifiers can be used for a field
|
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.version.expected=class file version expected
|
||||||
err.invalid.innerclass=Invalid declaration of Inner Class
|
err.invalid.innerclass=Invalid declaration of Inner Class
|
||||||
err.invalid.bootstrapmethod=Invalid declaration of BootstrapMethod Entry
|
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.frametype.repeated=Frametype repeated
|
||||||
#err.module.expected=module expected
|
|
||||||
err.invalid.paramnum=Invalid Parameter Number: {0}.
|
err.invalid.paramnum=Invalid Parameter Number: {0}.
|
||||||
err.duplicate.paramnum=Duplicate Parameter Number: {0}.
|
err.duplicate.paramnum=Duplicate Parameter Number: {0}.
|
||||||
err.paramname.constnum.invaltype=ParameterName CPX at {0} is not a ConstantString.
|
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
|
# Compiler Errors
|
||||||
#
|
#
|
||||||
# comperr.hashcode.err="CV hash:{0}"
|
|
||||||
comperr.constcell.nullvalset="Cell without value in setCell"
|
comperr.constcell.nullvalset="Cell without value in setCell"
|
||||||
comperr.constcell.nullvalhash="Cell without value in cpoolHashByValue"
|
comperr.constcell.nullvalhash="Cell without value in cpoolHashByValue"
|
||||||
comperr.constcell.invarg="Cell[{0}] has #{1}"
|
comperr.constcell.invarg="Cell[{0}] has #{1}"
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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;
|
int length = CPlen;
|
||||||
startArrayCmt(length, "Constant Pool");
|
startArrayCmt(length, "Constant Pool");
|
||||||
out_println("; // first element is empty");
|
out_println("; // first element is empty");
|
||||||
@ -273,7 +273,7 @@ class ClassData {
|
|||||||
byte btag = types[i];
|
byte btag = types[i];
|
||||||
ConstType tg = tag(btag);
|
ConstType tg = tag(btag);
|
||||||
int pos = cpe_pos[i];
|
int pos = cpe_pos[i];
|
||||||
String tagstr = "";
|
String tagstr;
|
||||||
String valstr;
|
String valstr;
|
||||||
int v1;
|
int v1;
|
||||||
long lv;
|
long lv;
|
||||||
@ -359,14 +359,6 @@ class ClassData {
|
|||||||
return " at " + toHex(countedin.getPos());
|
return " at " + toHex(countedin.getPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStringPosCond() {
|
|
||||||
if (printDetails) {
|
|
||||||
return getStringPos();
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getCommentPosCond() {
|
private String getCommentPosCond() {
|
||||||
if (printDetails) {
|
if (printDetails) {
|
||||||
return " // " + getStringPos();
|
return " // " + getStringPos();
|
||||||
@ -384,16 +376,16 @@ class ClassData {
|
|||||||
out_println("// invalid length of " + attrname + " attr: " + len + " (should be " + (expectedIndices * 2) + ") > ");
|
out_println("// invalid length of " + attrname + " attr: " + len + " (should be " + (expectedIndices * 2) + ") > ");
|
||||||
printBytes(out, in, len);
|
printBytes(out, in, len);
|
||||||
} else {
|
} else {
|
||||||
String outputString = "";
|
StringBuilder outputString = new StringBuilder();
|
||||||
for (int k = 1; k <= expectedIndices; k++) {
|
for (int k = 1; k <= expectedIndices; k++) {
|
||||||
outputString += ("#" + in.readUnsignedShort() + "; ");
|
outputString.append("#").append(in.readUnsignedShort()).append("; ");
|
||||||
if (k % 16 == 0) {
|
if (k % 16 == 0) {
|
||||||
out_println(outputString.replaceAll("\\s+$",""));
|
out_println(outputString.toString().replaceAll("\\s+$",""));
|
||||||
outputString = "";
|
outputString = new StringBuilder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!outputString.isEmpty()) {
|
if (outputString.length() > 0) {
|
||||||
out_println(outputString.replaceAll("\\s+$",""));
|
out_println(outputString.toString().replaceAll("\\s+$",""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -740,11 +732,8 @@ class ClassData {
|
|||||||
// Read the attributes
|
// Read the attributes
|
||||||
decodeAttrs(in, out);
|
decodeAttrs(in, out);
|
||||||
break;
|
break;
|
||||||
case ATT_ConstantValue:
|
|
||||||
decodeCPXAttr(in, len, AttrName, out);
|
|
||||||
break;
|
|
||||||
case ATT_Exceptions:
|
case ATT_Exceptions:
|
||||||
case ATT_NestMembers:
|
|
||||||
int count = in.readUnsignedShort();
|
int count = in.readUnsignedShort();
|
||||||
startArrayCmt(count, AttrName);
|
startArrayCmt(count, AttrName);
|
||||||
try {
|
try {
|
||||||
@ -758,7 +747,7 @@ class ClassData {
|
|||||||
break;
|
break;
|
||||||
case ATT_LineNumberTable:
|
case ATT_LineNumberTable:
|
||||||
int ll_num = in.readUnsignedShort();
|
int ll_num = in.readUnsignedShort();
|
||||||
startArrayCmt(ll_num, AttrName);
|
startArrayCmt(ll_num, "line_number_table");
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < ll_num; i++) {
|
for (int i = 0; i < ll_num; i++) {
|
||||||
out_println(in.readUnsignedShort() + " " +
|
out_println(in.readUnsignedShort() + " " +
|
||||||
@ -788,7 +777,7 @@ class ClassData {
|
|||||||
break;
|
break;
|
||||||
case ATT_InnerClasses:
|
case ATT_InnerClasses:
|
||||||
int ic_num = in.readUnsignedShort();
|
int ic_num = in.readUnsignedShort();
|
||||||
startArrayCmt(ic_num, AttrName);
|
startArrayCmt(ic_num, "classes");
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < ic_num; i++) {
|
for (int i = 0; i < ic_num; i++) {
|
||||||
out_println("#" + in.readUnsignedShort() + " #" +
|
out_println("#" + in.readUnsignedShort() + " #" +
|
||||||
@ -800,9 +789,6 @@ class ClassData {
|
|||||||
out_end("}");
|
out_end("}");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ATT_Signature:
|
|
||||||
decodeCPXAttr(in, len, AttrName, out);
|
|
||||||
break;
|
|
||||||
case ATT_StackMap:
|
case ATT_StackMap:
|
||||||
int e_num = in.readUnsignedShort();
|
int e_num = in.readUnsignedShort();
|
||||||
startArrayCmt(e_num, "");
|
startArrayCmt(e_num, "");
|
||||||
@ -887,9 +873,6 @@ class ClassData {
|
|||||||
case ATT_EnclosingMethod:
|
case ATT_EnclosingMethod:
|
||||||
decodeCPXAttrM(in, len, AttrName, out, 2);
|
decodeCPXAttrM(in, len, AttrName, out, 2);
|
||||||
break;
|
break;
|
||||||
case ATT_SourceFile:
|
|
||||||
decodeCPXAttr(in, len, AttrName, out);
|
|
||||||
break;
|
|
||||||
case ATT_AnnotationDefault:
|
case ATT_AnnotationDefault:
|
||||||
decodeElementValue(in, out);
|
decodeElementValue(in, out);
|
||||||
break;
|
break;
|
||||||
@ -980,10 +963,6 @@ class ClassData {
|
|||||||
out_end("}");
|
out_end("}");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// JEP 181: class file 55.0
|
|
||||||
case ATT_NestHost:
|
|
||||||
decodeCPXAttr(in, len, AttrName, out);
|
|
||||||
break;
|
|
||||||
// MethodParameters_attribute {
|
// MethodParameters_attribute {
|
||||||
// u2 attribute_name_index;
|
// u2 attribute_name_index;
|
||||||
// u4 attribute_length;
|
// u4 attribute_length;
|
||||||
@ -1026,13 +1005,48 @@ class ClassData {
|
|||||||
out_end("}");
|
out_end("}");
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
|
printBytes(out, in, len);
|
||||||
if (AttrName == null) {
|
if (AttrName == null) {
|
||||||
printBytes(out, in, len);
|
|
||||||
endingComment = "Attr(#" + name_cpx + ")";
|
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 {
|
private void decodeMembers(DataInputStream in, PrintWriter out, String groupName, String elementName) throws IOException {
|
||||||
int nfields = in.readUnsignedShort();
|
int count = in.readUnsignedShort();
|
||||||
traceln(groupName + "=" + nfields);
|
traceln(groupName + "=" + count);
|
||||||
startArrayCmt(nfields, groupName);
|
startArrayCmt(count, groupName);
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < nfields; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
decodeInfo(in,out,elementName,true);
|
decodeInfo(in,out,elementName,true);
|
||||||
if (i + 1 < nfields) {
|
if (i + 1 < count) {
|
||||||
out_println(";");
|
out_println(";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1205,7 +1219,7 @@ class ClassData {
|
|||||||
entityType = "class";
|
entityType = "class";
|
||||||
}
|
}
|
||||||
if (!entityName.isEmpty() && (JcodTokens.keyword_token_ident(entityName) != JcodTokens.Token.IDENT || JcodTokens.constValue(entityName) != -1)) {
|
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:
|
// then use the filename instead:
|
||||||
out_begin(String.format("file \"%s.class\" {", entityName));
|
out_begin(String.format("file \"%s.class\" {", entityName));
|
||||||
} else {
|
} else {
|
||||||
@ -1235,16 +1249,12 @@ class ClassData {
|
|||||||
traceln(i18n.getString("jdec.trace.access_thisCpx_superCpx", access, this_cpx, super_cpx));
|
traceln(i18n.getString("jdec.trace.access_thisCpx_superCpx", access, this_cpx, super_cpx));
|
||||||
out.println();
|
out.println();
|
||||||
|
|
||||||
// Read the interface names
|
// Read the interfaces
|
||||||
int numinterfaces = in.readUnsignedShort();
|
int numinterfaces = in.readUnsignedShort();
|
||||||
traceln(i18n.getString("jdec.trace.numinterfaces", numinterfaces));
|
traceln(i18n.getString("jdec.trace.numinterfaces", numinterfaces));
|
||||||
startArrayCmt(numinterfaces, "Interfaces");
|
startArrayCmt(numinterfaces, "Interfaces");
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < numinterfaces; i++) {
|
decodeTypes(in, out, numinterfaces);
|
||||||
int intrf_cpx = in.readUnsignedShort();
|
|
||||||
traceln(i18n.getString("jdec.trace.intrf", i, intrf_cpx));
|
|
||||||
out_println("#" + intrf_cpx + ";");
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
out_end("} // Interfaces\n");
|
out_end("} // Interfaces\n");
|
||||||
}
|
}
|
||||||
@ -1267,6 +1277,20 @@ class ClassData {
|
|||||||
}
|
}
|
||||||
} // end decodeClass()
|
} // 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;
|
boolean DebugFlag = false;
|
||||||
|
|
||||||
|
@ -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.
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
#
|
#
|
||||||
# This code is free software; you can redistribute it and/or modify it
|
# 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.CP_entry=CP entry # {0} tag= {1}
|
||||||
jdec.trace.access_thisCpx_superCpx=access={0} this_cpx={1} super_cpx={2}
|
jdec.trace.access_thisCpx_superCpx=access={0} this_cpx={1} super_cpx={2}
|
||||||
jdec.trace.numinterfaces=numinterfaces={0}
|
jdec.trace.numinterfaces=numinterfaces={0}
|
||||||
jdec.trace.intrf=\
|
jdec.trace.type=\
|
||||||
\ intrf_cpx[{0}]={1}
|
\ type_cpx[{0}]={1}
|
||||||
|
93
src/org/openjdk/asmtools/jdis/ClassArrayData.java
Normal file
93
src/org/openjdk/asmtools/jdis/ClassArrayData.java
Normal file
@ -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
|
||||||
|
* <p>
|
||||||
|
* 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];
|
||||||
|
* }
|
||||||
|
* <p>
|
||||||
|
* 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];
|
||||||
|
* }
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
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(";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -92,6 +92,9 @@ public class ClassData extends MemberData {
|
|||||||
// The NestMembers of this class (since class file: 55.0)
|
// The NestMembers of this class (since class file: 55.0)
|
||||||
protected NestMembersData nestMembers;
|
protected NestMembersData nestMembers;
|
||||||
|
|
||||||
|
// The PermittedSubtypes of this class (JEP 360 (Sealed types): class file 59.65535)
|
||||||
|
protected PermittedSubtypesData permittedSubtypes;
|
||||||
|
|
||||||
// other parsing fields
|
// other parsing fields
|
||||||
protected PrintWriter out;
|
protected PrintWriter out;
|
||||||
protected String pkgPrefix = "";
|
protected String pkgPrefix = "";
|
||||||
@ -215,6 +218,10 @@ public class ClassData extends MemberData {
|
|||||||
case ATT_Record:
|
case ATT_Record:
|
||||||
record = new RecordData(this).read(in);
|
record = new RecordData(this).read(in);
|
||||||
break;
|
break;
|
||||||
|
case ATT_PermittedSubtypes:
|
||||||
|
// Read PermittedSubtypes Attribute (JEP 360 (Sealed types): class file 59.65535)
|
||||||
|
permittedSubtypes = new PermittedSubtypesData(this).read(in, attrlen);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
handled = false;
|
handled = false;
|
||||||
break;
|
break;
|
||||||
@ -288,6 +295,7 @@ public class ClassData extends MemberData {
|
|||||||
public void print() throws IOException {
|
public void print() throws IOException {
|
||||||
int k, l;
|
int k, l;
|
||||||
String className = "";
|
String className = "";
|
||||||
|
String sourceName = "";
|
||||||
if( isModuleUnit() ) {
|
if( isModuleUnit() ) {
|
||||||
// Print the Annotations
|
// Print the Annotations
|
||||||
printAnnotations(visibleAnnotations);
|
printAnnotations(visibleAnnotations);
|
||||||
@ -407,20 +415,16 @@ printSugar:
|
|||||||
out.println("{");
|
out.println("{");
|
||||||
|
|
||||||
if ((options.contains(Options.PR.SRC)) && (source_cpx != 0)) {
|
if ((options.contains(Options.PR.SRC)) && (source_cpx != 0)) {
|
||||||
String source_name = pool.getName(source_cpx);
|
sourceName = String.format(" compiled from %s" +
|
||||||
out.println("\t// Compiled from " + source_name);
|
"" , pool.getName(source_cpx));
|
||||||
try {
|
try {
|
||||||
source = new TextLines(source_name);
|
source = new TextLines(sourceName);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
}
|
}
|
||||||
// keep this new line for classes to pass huge test suite.
|
|
||||||
if(!isModuleUnit())
|
|
||||||
out.println();
|
|
||||||
|
|
||||||
// Print the constant pool
|
// Print the constant pool
|
||||||
if (options.contains(Options.PR.CP)) {
|
if (options.contains(Options.PR.CP)) {
|
||||||
pool.print(out);
|
pool.print(out);
|
||||||
out.println();
|
|
||||||
}
|
}
|
||||||
// Don't print fields, methods, inner classes and bootstrap methods if it is module-info entity
|
// Don't print fields, methods, inner classes and bootstrap methods if it is module-info entity
|
||||||
if ( !isModuleUnit() ) {
|
if ( !isModuleUnit() ) {
|
||||||
@ -446,6 +450,10 @@ printSugar:
|
|||||||
record.print();
|
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)
|
// Print the NestHost (since class file: 55.0)
|
||||||
if(nestHost != null) {
|
if(nestHost != null) {
|
||||||
nestHost.print();
|
nestHost.print();
|
||||||
@ -470,7 +478,11 @@ printSugar:
|
|||||||
}
|
}
|
||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
out.println("} // end Class " + className);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
out.println("} // end Class " + className + sourceName);
|
||||||
} else {
|
} else {
|
||||||
// Print module attributes
|
// Print module attributes
|
||||||
moduleData.print();
|
moduleData.print();
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -1049,7 +1049,7 @@ public class ConstantPool {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.print("const #" + cpx + " = ");
|
out.print("\tconst #" + cpx + " = ");
|
||||||
|
|
||||||
if (cns == null) {
|
if (cns == null) {
|
||||||
// do something
|
// do something
|
||||||
@ -1060,7 +1060,6 @@ public class ConstantPool {
|
|||||||
cpx += cns.size();
|
cpx += cns.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.println();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,7 +66,7 @@ class InnerClassData {
|
|||||||
if (outer_class_info_index != 0) {
|
if (outer_class_info_index != 0) {
|
||||||
cls.out.print(" of #" + outer_class_info_index);
|
cls.out.print(" of #" + outer_class_info_index);
|
||||||
}
|
}
|
||||||
cls.out.print("; //");
|
cls.out.print("; // ");
|
||||||
}
|
}
|
||||||
if (inner_name_index != 0) {
|
if (inner_name_index != 0) {
|
||||||
cls.out.print(cls.pool.getName(inner_name_index) + "=");
|
cls.out.print(cls.pool.getName(inner_name_index) + "=");
|
||||||
|
@ -336,6 +336,8 @@ public class MethodData extends MemberData {
|
|||||||
|
|
||||||
if (code != null) {
|
if (code != null) {
|
||||||
code.print();
|
code.print();
|
||||||
|
} else {
|
||||||
|
out.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* The NestMembers attribute data
|
||||||
* <p>
|
* <p>
|
||||||
* 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 {
|
public class NestMembersData extends ClassArrayData {
|
||||||
ClassData cls;
|
|
||||||
int[] classes;
|
|
||||||
private Options options = Options.OptionObject();
|
|
||||||
|
|
||||||
public NestMembersData(ClassData cls) {
|
public NestMembersData(ClassData cls) {
|
||||||
this.cls = cls;
|
super(cls, JasmTokens.Token.NESTMEMBERS.parsekey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public NestMembersData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
|
public NestMembersData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
|
||||||
int number_of_classes = in.readUnsignedShort();
|
return (NestMembersData) super.read(in, attribute_length);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(";");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
49
src/org/openjdk/asmtools/jdis/PermittedSubtypesData.java
Normal file
49
src/org/openjdk/asmtools/jdis/PermittedSubtypesData.java
Normal file
@ -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
|
||||||
|
* <p>
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user