CODETOOLS-7902618 CODETOOLS-7902643 CODETOOLS-7902644 CODETOOLS-7902648
This commit is contained in:
parent
79096622a1
commit
61d329f0fb
19
.hgignore
19
.hgignore
|
@ -1,9 +1,10 @@
|
|||
re:data
|
||||
re:data/.*
|
||||
re:asmtools-6.0-build/.*
|
||||
re:.*~$
|
||||
re:.*\.log$
|
||||
re:.*\.pyc$
|
||||
re:.*\.swp$
|
||||
re:.*\.DS_Store$
|
||||
re:.*\iml$
|
||||
syntax: regexp
|
||||
data
|
||||
data/.*
|
||||
asmtools-7.0-build/.*
|
||||
.*~$
|
||||
.*\.log$
|
||||
.*\.pyc$
|
||||
.*\.swp$
|
||||
.*\.DS_Store$
|
||||
.*\.iml$
|
||||
|
|
72
README.html
72
README.html
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<!--
|
||||
|
||||
Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2008, 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
|
||||
|
@ -31,7 +31,7 @@
|
|||
<head>
|
||||
<meta http-equiv="content-type"
|
||||
content="text/html; charset=ISO-8859-1">
|
||||
<title>README - AsmTools - Version 6.0</title>
|
||||
<title>README - AsmTools - Version 7.0</title>
|
||||
<style>
|
||||
body, tr {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
|
@ -106,7 +106,7 @@ table.Screen { margin-top: 0.5em; margin-bottom: 0.5em;
|
|||
<h1>Release Notes</h1>
|
||||
<h2>AsmTools</h2>
|
||||
</h2>
|
||||
<h2>October 2017</h2>
|
||||
<h2>April 2020</h2>
|
||||
</center>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -143,7 +143,7 @@ development process to test the compliance of a Virtual Machine (VM) to
|
|||
its specification.</p>
|
||||
<p>
|
||||
These
|
||||
release notes contain information about the ASM Tools version 6.0.
|
||||
release notes contain information about the ASM Tools version 7.0.
|
||||
See the (
|
||||
<a href="https://wiki.openjdk.java.net/display/CodeTools/Main">CodeTools</a> project)
|
||||
<a href="https://wiki.openjdk.java.net/display/CodeTools/AsmTools">AsmTools</a> OpenJDK project page for more information about AsmTools.
|
||||
|
@ -163,8 +163,22 @@ See the (
|
|||
<th class="sun-darkblue" scope="col"><b>Bug ID </b></th>
|
||||
<th class="sun-darkblue" scope="col"><b>Description</b></th>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902525">CODETOOLS-7902525</a>
|
||||
</td>
|
||||
<td>
|
||||
Asmtools support: JEP 360 Sealed Types(Preview)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902524">CODETOOLS-7902524</a>
|
||||
</td>
|
||||
<td>
|
||||
Asmtools support: JEP 359 Records(Preview)
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
|
@ -180,9 +194,39 @@ See the (
|
|||
<th class="sun-darkblue" scope="col"><b>Bug ID </b></th>
|
||||
<th class="sun-darkblue" scope="col"><b>Description</b></th>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902618">CODETOOLS-7902618</a>
|
||||
</td>
|
||||
<td>
|
||||
Asmtools does not support jasm output/input for TypeAnnotations.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902643">CODETOOLS-7902643</a>
|
||||
</td>
|
||||
<td>
|
||||
Asmtools(jasm) does not support signature attributes in field_info, component_info
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902644">CODETOOLS-7902644</a>
|
||||
</td>
|
||||
<td>
|
||||
Asmtools (jcoder) fails if an jcod file contains CONSTANT_Utf8_info with non-normative char sequences
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://bugs.openjdk.java.net/browse/CODETOOLS-7902648">CODETOOLS-7902648</a>
|
||||
</td>
|
||||
<td>
|
||||
jasm has no clues about how to interpret CONSTANT_MethodHandle_info:reference_kind in an invokedynamic instruction
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="nav-link">[<a href="#_top">Top</a>]</p>
|
||||
<p><a name="system_requirements"></a></p>
|
||||
|
@ -195,7 +239,7 @@ version 1.8 or later, or a Java SE platform 8.0 runtime environment.
|
|||
<p class="nav-link">[<a href="#_top">Top</a>]</p>
|
||||
<a name="installation"></a>
|
||||
<h2>Installation</h2>
|
||||
To install the AsmTools, simply unzip the asmtools-6.0.zip
|
||||
To install the AsmTools, simply unzip the asmtools-7.0.zip
|
||||
distribution file in the directory of your choice. Optionally, you may
|
||||
wish to define an environment variable (ASMTOOLSHOME) to point to this
|
||||
location for your convenience.
|
||||
|
@ -204,7 +248,7 @@ location for your convenience.
|
|||
<h2>Release Contents</h2>
|
||||
<p>
|
||||
This section lists the components under the base subdirectory structure
|
||||
(<code>asmtools-6.0/</code>)
|
||||
(<code>asmtools-7.0/</code>)
|
||||
that is created when you unzip the AsmTools distribution archive during
|
||||
installation.
|
||||
</p>
|
||||
|
@ -285,7 +329,7 @@ The AsmTools open source project was created in order to develop a community tha
|
|||
<p><a name="source" id="source"></a></p>
|
||||
<h2>Obtaining the Sources</h2>
|
||||
<p>
|
||||
The sources for <a href="">ASM Tools</a> 6.0 and later is available via the community
|
||||
The sources for <a href="">ASM Tools</a> 7.0 and later is available via the community
|
||||
<a href="http://www.openjdk.org/">OpenJDK</a> project. The sources are stored
|
||||
and accessed through a Mercurial repository, which the public may access in a
|
||||
read-only fashion. Committing to changes to the sources is accomplished by
|
||||
|
@ -340,7 +384,7 @@ The general steps to do a build from source from the command line:
|
|||
<li>Make your current directory <code><topdir>/build/</code>
|
||||
<li>Invoke ant:<br><code>% ant</code>
|
||||
<li>Output appears in a directory above (one above <topdir>),
|
||||
such as: <code>../../asmtools-6.0-build/</code>
|
||||
such as: <code>../../asmtools-7.0-build/</code>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
|
@ -368,7 +412,7 @@ specify in your IDE for building.
|
|||
<hr>
|
||||
|
||||
<hr noshade="noshade">
|
||||
<p><a href="legal/copyright.txt">Copyright</a> © 2008, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
<p><a href="legal/copyright.txt">Copyright</a> © 2008, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
Use is subject to license terms.The majority of the Assember Tools project is released under the <A
|
||||
HREF="http://openjdk.java.net/legal/gplv2+ce.html">GNU
|
||||
General Public License Version 2 (GPLv2)</A></p>
|
||||
|
|
|
@ -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.asmutils;
|
||||
|
||||
/**
|
||||
* Utility class to share common tools/methods.
|
||||
*/
|
||||
public class StringUtils {
|
||||
/**
|
||||
* Converts CONSTANT_Utf8_info string to a printable string for jdis/jdes.
|
||||
* @param utf8 UTF8 string taken from within ConstantPool of a class file
|
||||
* @return output string for jcod/jasm
|
||||
*/
|
||||
public static String Utf8ToString(String utf8) {
|
||||
StringBuilder sb = new StringBuilder("\"");
|
||||
for (int k = 0; k < utf8.length(); k++) {
|
||||
char c = utf8.charAt(k);
|
||||
switch (c) {
|
||||
case '\t':
|
||||
sb.append('\\').append('t');
|
||||
break;
|
||||
case '\n':
|
||||
sb.append('\\').append('n');
|
||||
break;
|
||||
case '\r':
|
||||
sb.append('\\').append('r');
|
||||
break;
|
||||
case '\b':
|
||||
sb.append('\\').append('b');
|
||||
break;
|
||||
case '\f':
|
||||
sb.append('\\').append('f');
|
||||
break;
|
||||
case '\"':
|
||||
sb.append('\\').append('\"');
|
||||
break;
|
||||
case '\'':
|
||||
sb.append('\\').append('\'');
|
||||
break;
|
||||
case '\\':
|
||||
sb.append('\\').append('\\');
|
||||
break;
|
||||
default:
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.append('\"').toString();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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,6 +22,8 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.common;
|
||||
|
||||
import org.openjdk.asmtools.jdis.Indenter;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -30,7 +32,7 @@ import static java.lang.String.format;
|
|||
/**
|
||||
* Internal presentation of a module
|
||||
*/
|
||||
public final class Module {
|
||||
public final class Module extends Indenter {
|
||||
|
||||
//* A module name and module_flags
|
||||
public final Header header;
|
||||
|
@ -66,7 +68,7 @@ public final class Module {
|
|||
int l = 0;
|
||||
requires.stream()
|
||||
.sorted()
|
||||
.forEach(d -> sb.append(format(" requires %s;%s%n",
|
||||
.forEach(d -> sb.append(getIndentString()).append(format("requires %s;%s%n",
|
||||
d.toString(),
|
||||
d.getModuleVersion() == null ? "" : " // @" + d.getModuleVersion())));
|
||||
//
|
||||
|
@ -74,14 +76,14 @@ public final class Module {
|
|||
exports.entrySet().stream()
|
||||
.filter(e -> e.getValue().isEmpty())
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.map(e -> format(" exports %s;%n", e.getKey().toString()))
|
||||
.map(e -> format("%sexports %s;%n", getIndentString(), e.getKey().toString()))
|
||||
.forEach(sb::append);
|
||||
exports.entrySet().stream()
|
||||
.filter(e -> !e.getValue().isEmpty())
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.map(e -> format(" exports %s to%n%s;%n", e.getKey().toString(),
|
||||
.map(e -> format("%sexports %s to%n%s;%n", getIndentString(), e.getKey().toString(),
|
||||
e.getValue().stream().sorted()
|
||||
.map(mn -> format(" %s", mn))
|
||||
.map(mn -> format("%s %s", getIndentString(), mn))
|
||||
.collect(Collectors.joining(",\n"))))
|
||||
.forEach(sb::append);
|
||||
//
|
||||
|
@ -89,29 +91,29 @@ public final class Module {
|
|||
opens.entrySet().stream()
|
||||
.filter(e -> e.getValue().isEmpty())
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.map(e -> format(" opens %s;%n", e.getKey().toString()))
|
||||
.map(e -> format("%sopens %s;%n", getIndentString(), e.getKey().toString()))
|
||||
.forEach(sb::append);
|
||||
opens.entrySet().stream()
|
||||
.filter(e -> !e.getValue().isEmpty())
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.map(e -> format(" opens %s to%n%s;%n", e.getKey().toString(),
|
||||
.map(e -> format("%sopens %s to%n%s;%n", getIndentString(), e.getKey().toString(),
|
||||
e.getValue().stream().sorted()
|
||||
.map(mn -> format(" %s", mn))
|
||||
.map(mn -> format("%s %s", getIndentString(), mn))
|
||||
.collect(Collectors.joining(",\n"))))
|
||||
.forEach(sb::append);
|
||||
//
|
||||
l = newLine(sb,l);
|
||||
uses.stream().sorted()
|
||||
.map(s -> format(" uses %s;%n", s))
|
||||
.map(s -> format("%suses %s;%n", getIndentString(), s))
|
||||
.forEach(sb::append);
|
||||
//
|
||||
l = newLine(sb,l);
|
||||
provides.entrySet().stream()
|
||||
.filter(e -> !e.getValue().isEmpty())
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.map(e -> format(" provides %s with%n%s;%n", e.getKey().toString(),
|
||||
.map(e -> format("%sprovides %s with%n%s;%n", getIndentString(), e.getKey().toString(),
|
||||
e.getValue().stream().sorted()
|
||||
.map(mn -> format(" %s", mn))
|
||||
.map(mn -> format("%s %s", getIndentString(), mn))
|
||||
.collect(Collectors.joining(",\n"))))
|
||||
.forEach(sb::append);
|
||||
//
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -26,7 +26,15 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* See JVMS3, section 4.8.16.
|
||||
* JVMS 4.7.16.
|
||||
*
|
||||
* annotation {
|
||||
* u2 type_index;
|
||||
* u2 num_element_value_pairs;
|
||||
* { u2 element_name_index;
|
||||
* element_value value;
|
||||
* } element_value_pairs[num_element_value_pairs];
|
||||
* }
|
||||
*/
|
||||
class AnnotationData implements Data {
|
||||
|
||||
|
|
|
@ -193,6 +193,13 @@ class ClassData extends MemberData {
|
|||
return this.recordData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rejects a record: removes the record attribute if there are no components
|
||||
*/
|
||||
public void rejectRecord() {
|
||||
this.recordData = null;
|
||||
}
|
||||
|
||||
// Field
|
||||
public ConstantPool.ConstValue_Pair mkNape(ConstantPool.ConstCell name, ConstantPool.ConstCell sig) {
|
||||
return new ConstantPool.ConstValue_Pair(ConstType.CONSTANT_NAMEANDTYPE, name, sig);
|
||||
|
@ -325,14 +332,14 @@ class ClassData extends MemberData {
|
|||
env.traceln("ascicell=" + ascicell);
|
||||
ConstantPool.ConstValue_String me_str = (ConstantPool.ConstValue_String) ascicell.ref;
|
||||
myClassName = me_str.value;
|
||||
env.traceln("--------------------------------------------");
|
||||
env.traceln("-------------------");
|
||||
env.traceln("-- Constant Pool --");
|
||||
env.traceln("-------------------");
|
||||
pool.printPool();
|
||||
env.traceln("--------------------------------------------");
|
||||
env.traceln("-------------------");
|
||||
env.traceln(" ");
|
||||
env.traceln(" ");
|
||||
env.traceln("--------------------------------------------");
|
||||
env.traceln("-------------------");
|
||||
env.traceln("-- Inner Classes --");
|
||||
env.traceln("-------------------");
|
||||
printInnerClasses();
|
||||
|
|
|
@ -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
|
||||
|
@ -23,161 +23,37 @@
|
|||
package org.openjdk.asmtools.jasm;
|
||||
|
||||
import org.openjdk.asmtools.jasm.OpcodeTables.Opcode;
|
||||
import static org.openjdk.asmtools.jasm.RuntimeConstants.SPLIT_VERIFIER_CFV;
|
||||
import org.openjdk.asmtools.jasm.Tables.AttrTag;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.RuntimeConstants.SPLIT_VERIFIER_CFV;
|
||||
|
||||
class CodeAttr extends AttrData {
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* CodeAttr inner classes */
|
||||
static public class Local extends Argument {
|
||||
|
||||
String name;
|
||||
boolean defd = false, refd = false;
|
||||
|
||||
public Local(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static public class Label extends Local {
|
||||
|
||||
public Label(String name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class LocVarData extends Local implements Data {
|
||||
|
||||
// arg means slot
|
||||
|
||||
short start_pc, length;
|
||||
ConstantPool.ConstCell name_cpx, sig_cpx;
|
||||
|
||||
public LocVarData(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(start_pc);
|
||||
out.writeShort(length);
|
||||
out.writeShort(name_cpx.arg);
|
||||
out.writeShort(sig_cpx.arg);
|
||||
out.writeShort(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class LineNumData implements Data {
|
||||
|
||||
int start_pc, line_number;
|
||||
|
||||
public LineNumData(int start_pc, int line_number) {
|
||||
this.start_pc = start_pc;
|
||||
this.line_number = line_number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(start_pc);
|
||||
out.writeShort(line_number);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Trap extends Local {
|
||||
|
||||
int start_pc = Argument.NotSet, end_pc = Argument.NotSet;
|
||||
int pos;
|
||||
|
||||
Trap(int pos, String name) {
|
||||
super(name);
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class TrapData implements Data {
|
||||
|
||||
int pos;
|
||||
Trap trap;
|
||||
int handler_pc;
|
||||
Argument catchType;
|
||||
|
||||
public TrapData(int pos, Trap trap, int handler_pc, Argument catchType) {
|
||||
this.pos = pos;
|
||||
this.trap = trap;
|
||||
this.handler_pc = handler_pc;
|
||||
this.catchType = catchType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 8; // add the length of number of elements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(trap.start_pc);
|
||||
out.writeShort(trap.end_pc);
|
||||
out.writeShort(handler_pc);
|
||||
if (catchType.isSet()) {
|
||||
out.writeShort(catchType.arg);
|
||||
} else {
|
||||
out.writeShort(0);
|
||||
}
|
||||
}
|
||||
} // end TrapData
|
||||
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* CodeAttr Fields */
|
||||
protected MethodData mtd;
|
||||
protected ClassData cls;
|
||||
|
||||
protected MethodData mtd;
|
||||
protected Environment env;
|
||||
protected Argument max_stack, max_locals;
|
||||
protected Instr zeroInstr, lastInstr;
|
||||
protected int cur_pc = 0;
|
||||
protected DataVector<TrapData> trap_table
|
||||
= new DataVector<>(0); // TrapData
|
||||
protected DataVector<TrapData> trap_table; // TrapData
|
||||
protected DataVectorAttr<LineNumData> lin_num_tb; // LineNumData
|
||||
protected int lastln = 0;
|
||||
protected DataVectorAttr<LocVarData> loc_var_tb; // LocVarData
|
||||
protected DataVector<DataVectorAttr<? extends Data>> attrs;
|
||||
// protected iVector slots;
|
||||
protected ArrayList<Integer> slots;
|
||||
protected HashMap<String, LocVarData> locvarsHash;
|
||||
protected HashMap<String, Label> labelsHash;
|
||||
protected HashMap<String, Trap> trapsHash;
|
||||
protected StackMapData curMapEntry = null;
|
||||
protected DataVectorAttr<StackMapData> stackMap;
|
||||
/*-------------------------------------------------------- */
|
||||
// type annotations
|
||||
protected DataVectorAttr<TypeAnnotationData> type_annotAttrVis = null;
|
||||
protected DataVectorAttr<TypeAnnotationData> type_annotAttrInv = null;
|
||||
|
||||
public CodeAttr(MethodData mtd, int pos, int paramcnt, Argument max_stack, Argument max_locals) {
|
||||
super(mtd.cls, AttrTag.ATT_Code.parsekey());
|
||||
|
@ -193,10 +69,8 @@ class CodeAttr extends AttrData {
|
|||
lin_num_tb = new DataVectorAttr<>(cls, AttrTag.ATT_LineNumberTable.parsekey());
|
||||
attrs.add(lin_num_tb);
|
||||
}
|
||||
// slots = new iVector(paramcnt);
|
||||
slots = new ArrayList<>(paramcnt);
|
||||
for (int k = 0; k < paramcnt; k++) {
|
||||
// slots.setElement(1, k);
|
||||
slots.add(k, 1);
|
||||
}
|
||||
}
|
||||
|
@ -205,6 +79,36 @@ class CodeAttr extends AttrData {
|
|||
checkTraps();
|
||||
checkLocVars();
|
||||
checkLabels();
|
||||
//
|
||||
if (type_annotAttrVis != null) {
|
||||
attrs.add(type_annotAttrVis);
|
||||
}
|
||||
if (type_annotAttrInv != null) {
|
||||
attrs.add(type_annotAttrInv);
|
||||
}
|
||||
}
|
||||
|
||||
public void addAnnotations(ArrayList<AnnotationData> list) {
|
||||
for (AnnotationData item : list) {
|
||||
boolean invisible = item.invisible;
|
||||
if (item instanceof TypeAnnotationData) {
|
||||
// Type Annotations
|
||||
TypeAnnotationData ta = (TypeAnnotationData) item;
|
||||
if (invisible) {
|
||||
if (type_annotAttrInv == null) {
|
||||
type_annotAttrInv = new DataVectorAttr(cls,
|
||||
AttrTag.ATT_RuntimeInvisibleTypeAnnotations.parsekey());
|
||||
}
|
||||
type_annotAttrInv.add(ta);
|
||||
} else {
|
||||
if (type_annotAttrVis == null) {
|
||||
type_annotAttrVis = new DataVectorAttr(cls,
|
||||
AttrTag.ATT_RuntimeVisibleTypeAnnotations.parsekey());
|
||||
}
|
||||
type_annotAttrVis.add(ta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------- Traps */
|
||||
|
@ -332,11 +236,8 @@ class CodeAttr extends AttrData {
|
|||
}
|
||||
|
||||
public void LocVarDataDef(int slot) {
|
||||
// slots.setElement(1, slot);
|
||||
slots.set(slot, 1);
|
||||
if ((max_locals != null) && (max_locals.arg < slots.size())) {
|
||||
|
||||
// if ((max_locals != null) && (max_locals.arg < slots.length)) {
|
||||
env.error("warn.illslot", Integer.toString(slot));
|
||||
}
|
||||
}
|
||||
|
@ -354,16 +255,6 @@ class CodeAttr extends AttrData {
|
|||
int k;
|
||||
findSlot:
|
||||
{
|
||||
/*
|
||||
for (k = 0; k < slots.length; k++) {
|
||||
if (slots.data[k] == 0) {
|
||||
break findSlot;
|
||||
}
|
||||
}
|
||||
k = slots.length;
|
||||
*
|
||||
*/
|
||||
|
||||
for (k = 0; k < slots.size(); k++) {
|
||||
if (slots.get(k) == 0) {
|
||||
break findSlot;
|
||||
|
@ -391,7 +282,6 @@ class CodeAttr extends AttrData {
|
|||
}
|
||||
|
||||
public void LocVarDataEnd(int slot) {
|
||||
// slots.data[slot] = 0;
|
||||
slots.set(slot, 0);
|
||||
}
|
||||
|
||||
|
@ -405,10 +295,8 @@ class CodeAttr extends AttrData {
|
|||
return;
|
||||
}
|
||||
locvar.length = (short) (cur_pc - locvar.start_pc);
|
||||
// slots.data[locvar.arg] = 0;
|
||||
|
||||
slots.set(locvar.arg, 0);
|
||||
// locvarsHash.put(name, null); unfortunately, prohibited
|
||||
locvarsHash.put(name, new LocVarData(name));
|
||||
}
|
||||
|
||||
|
@ -422,9 +310,7 @@ class CodeAttr extends AttrData {
|
|||
} // this is false locvar
|
||||
// set end of scope, if not set
|
||||
if (slots.get(locvar.arg) == 1) {
|
||||
// if (slots.data[locvar.arg] == 1) {
|
||||
locvar.length = (short) (cur_pc - locvar.start_pc);
|
||||
// slots.data[locvar.arg] = 0;
|
||||
slots.set(locvar.arg, 0);
|
||||
}
|
||||
}
|
||||
|
@ -497,14 +383,12 @@ class CodeAttr extends AttrData {
|
|||
return 2 + 2 + 4 // for max_stack, max_locals, and cur_pc
|
||||
+ cur_pc // + 2+trap_table.size()*8
|
||||
+ trap_table.getLength() + attrs.getLength();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out)
|
||||
throws IOException, Parser.CompilerError {
|
||||
int mxstck = (max_stack != null) ? max_stack.arg : 0;
|
||||
// int mxloc = (max_locals != null) ? max_locals.arg : slots.length;
|
||||
int mxloc = (max_locals != null) ? max_locals.arg : slots.size();
|
||||
super.write(out); // attr name, attr len
|
||||
out.writeShort(mxstck);
|
||||
|
@ -518,5 +402,128 @@ class CodeAttr extends AttrData {
|
|||
|
||||
attrs.write(out);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* CodeAttr inner classes */
|
||||
static public class Local extends Argument {
|
||||
|
||||
String name;
|
||||
boolean defd = false, refd = false;
|
||||
|
||||
public Local(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static public class Label extends Local {
|
||||
|
||||
public Label(String name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class LocVarData extends Local implements Data {
|
||||
|
||||
// arg means slot
|
||||
short start_pc, length;
|
||||
ConstantPool.ConstCell name_cpx, sig_cpx;
|
||||
|
||||
public LocVarData(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(start_pc);
|
||||
out.writeShort(length);
|
||||
out.writeShort(name_cpx.arg);
|
||||
out.writeShort(sig_cpx.arg);
|
||||
out.writeShort(arg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class LineNumData implements Data {
|
||||
|
||||
int start_pc, line_number;
|
||||
|
||||
public LineNumData(int start_pc, int line_number) {
|
||||
this.start_pc = start_pc;
|
||||
this.line_number = line_number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(start_pc);
|
||||
out.writeShort(line_number);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Trap extends Local {
|
||||
|
||||
int start_pc = Argument.NotSet, end_pc = Argument.NotSet;
|
||||
int pos;
|
||||
|
||||
Trap(int pos, String name) {
|
||||
super(name);
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class TrapData implements Data {
|
||||
|
||||
int pos;
|
||||
Trap trap;
|
||||
int handler_pc;
|
||||
Argument catchType;
|
||||
|
||||
public TrapData(int pos, Trap trap, int handler_pc, Argument catchType) {
|
||||
this.pos = pos;
|
||||
this.trap = trap;
|
||||
this.handler_pc = handler_pc;
|
||||
this.catchType = catchType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 8; // add the length of number of elements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(trap.start_pc);
|
||||
out.writeShort(trap.end_pc);
|
||||
out.writeShort(handler_pc);
|
||||
if (catchType.isSet()) {
|
||||
out.writeShort(catchType.arg);
|
||||
} else {
|
||||
out.writeShort(0);
|
||||
}
|
||||
}
|
||||
} // end TrapData
|
||||
} // end CodeAttr
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -25,11 +25,19 @@ package org.openjdk.asmtools.jasm;
|
|||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
* Base contract for writeable structures
|
||||
*/
|
||||
interface Data {
|
||||
|
||||
public void write(CheckedDataOutputStream out) throws IOException;
|
||||
void write(CheckedDataOutputStream out) throws IOException;
|
||||
|
||||
public int getLength();
|
||||
int getLength();
|
||||
|
||||
default String tabString(int tabLevel) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < tabLevel; i++) {
|
||||
sb.append('\t');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -320,15 +320,13 @@ public class Environment {
|
|||
|
||||
// Report the errors
|
||||
for (ErrorMessage msg = errors; msg != null; msg = msg.next) {
|
||||
int ln = lineNumber(msg.where);
|
||||
int off = lineOffset(msg.where);
|
||||
|
||||
int i, j;
|
||||
for (i = off; (i > 0) && (data[i - 1] != '\n') && (data[i - 1] != '\r'); i--);
|
||||
for (j = off; (j < data.length) && (data[j] != '\n') && (data[j] != '\r'); j++);
|
||||
|
||||
String prefix = simpleInputFileName + ":" + ln + ":";
|
||||
outputln(prefix + " " + msg.message);
|
||||
outputln( String.format( "%s (%d:%d) %s", getSimpleInputFileName(), lineNumber(msg.where), off - i, msg.message));
|
||||
outputln(new String(data, i, j - i));
|
||||
|
||||
char strdata[] = new char[(off - i) + 1];
|
||||
|
@ -385,7 +383,7 @@ public class Environment {
|
|||
msg = "Error: ";
|
||||
}
|
||||
msg = msg + errorString(err, arg1, arg2, arg3);
|
||||
traceln("error(" + lineNumber(where) + ":" + lineOffset(where) + "):" + msg);
|
||||
traceln(msg);
|
||||
insertError(where, msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -24,11 +24,9 @@ package org.openjdk.asmtools.jasm;
|
|||
|
||||
import org.openjdk.asmtools.jasm.Tables.AttrTag;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* field_info
|
||||
*/
|
||||
class FieldData extends MemberData {
|
||||
|
||||
|
@ -55,7 +53,7 @@ class FieldData extends MemberData {
|
|||
|
||||
@Override
|
||||
protected DataVector getAttrVector() {
|
||||
return getDataVector(initValue, syntheticAttr, deprecatedAttr);
|
||||
return getDataVector(initValue, syntheticAttr, deprecatedAttr, signatureAttr);
|
||||
}
|
||||
|
||||
public void write(CheckedDataOutputStream out) throws IOException, Parser.CompilerError {
|
||||
|
|
|
@ -23,11 +23,8 @@
|
|||
package org.openjdk.asmtools.jasm;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.Token.ALL_TOKENS;
|
||||
|
||||
/**
|
||||
*
|
||||
* JasmTokens
|
||||
|
@ -81,7 +78,9 @@ public class JasmTokens {
|
|||
JASM (10, "Jasm"),
|
||||
MISC (11, "Misc"),
|
||||
JASM_IDENT (12, "Jasm identifier"),
|
||||
MODULE_NAME (13, "Module Name");
|
||||
MODULE_NAME (13, "Module Name"),
|
||||
TYPE_PATH_KIND (14, "Type path kind") // Table 4.7.20.2-A Interpretation of type_path_kind values
|
||||
;
|
||||
|
||||
private final Integer value;
|
||||
private final String printval;
|
||||
|
@ -95,11 +94,76 @@ public class JasmTokens {
|
|||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
public enum AnnotationType {
|
||||
Visible("@+"),
|
||||
Invisible("@-"),
|
||||
VisibleType("@T+"),
|
||||
InvisibleType("@T-");
|
||||
|
||||
private final String jasmPrefix;
|
||||
|
||||
AnnotationType(String jasmPrefix) {
|
||||
this.jasmPrefix = jasmPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* isAnnotationToken
|
||||
*
|
||||
* examines the beginning of a string to see if it starts with an annotation
|
||||
* characters ('@+' = visible annotation, '@-' = invisible).
|
||||
*
|
||||
* @param str String to be analyzed
|
||||
* @return True if the string starts with an annotation char.
|
||||
*/
|
||||
static public boolean isAnnotationToken(String str) {
|
||||
return (str.startsWith(AnnotationType.Invisible.jasmPrefix) ||
|
||||
str.startsWith(AnnotationType.Visible.jasmPrefix));
|
||||
}
|
||||
|
||||
/**
|
||||
* isTypeAnnotationToken
|
||||
*
|
||||
* examines the beginning of a string to see if it starts with type annotation
|
||||
* characters ('@T+' = visible type annotation, '@T-' = invisible).
|
||||
*
|
||||
* @param str String to be analyzed
|
||||
* @return True if the string starts with an annotation char.
|
||||
*/
|
||||
static public boolean isTypeAnnotationToken(String str) {
|
||||
return (str.startsWith(AnnotationType.InvisibleType.jasmPrefix) ||
|
||||
str.startsWith(AnnotationType.VisibleType.jasmPrefix));
|
||||
}
|
||||
|
||||
/**
|
||||
* isAnnotation
|
||||
*
|
||||
* examines the beginning of a string to see if it starts with an annotation character
|
||||
*
|
||||
* @param str String to be analyzed
|
||||
* @return True if the string starts with an annotation char.
|
||||
*/
|
||||
static public boolean isAnnotation(String str) {
|
||||
return (str.startsWith("@"));
|
||||
}
|
||||
|
||||
/**
|
||||
* isInvisibleAnnotationToken
|
||||
*
|
||||
* examines the end of an annotation token to determine visibility ('+' = visible
|
||||
* annotation, '-' = invisible).
|
||||
*
|
||||
* @param str String to be analyzed
|
||||
* @return True if the token implies invisible annotation.
|
||||
*/
|
||||
static public boolean isInvisibleAnnotationToken(String str) {
|
||||
return (str.endsWith("-"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scanner Tokens (Definitive List)
|
||||
*/
|
||||
static public enum Token {
|
||||
public enum Token {
|
||||
EOF (-1, "EOF", "EOF", EnumSet.of(TokenType.MISC)),
|
||||
COMMA (0, "COMMA", ",", EnumSet.of(TokenType.OPERATOR)),
|
||||
ASSIGN (1, "ASSIGN", "=", EnumSet.of(TokenType.OPERATOR)),
|
||||
|
@ -290,9 +354,11 @@ public class JasmTokens {
|
|||
CPINDEX (156, "CPINDEX", "CPINDEX", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
|
||||
CPNAME (157, "CPNAME", "CPName", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
|
||||
SIGN (158, "SIGN", "SIGN", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME )),
|
||||
BITS (159, "BITS", "bits", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
BITS (159, "BITS", "bits", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
|
||||
INF (160, "INF", "Inf", "Infinity", EnumSet.of(TokenType.MISC, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
NAN (161, "NAN", "NaN", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
NAN (161, "NAN", "NaN", EnumSet.of(TokenType.MISC, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
|
||||
INNERCLASS (162, "INNERCLASS", "InnerClass", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
OF (163, "OF", "of", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
SYNTHETIC (164, "SYNTHETIC", "synthetic", EnumSet.of(TokenType.MODIFIER, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
|
@ -311,9 +377,10 @@ public class JasmTokens {
|
|||
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),
|
||||
COMPONENT (176, "COMPONENT", "Component", 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),
|
||||
PERMITTEDSUBTYPES (177, "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),
|
||||
|
@ -322,7 +389,17 @@ public class JasmTokens {
|
|||
USES (184, "USES", "uses", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
PROVIDES (185, "PROVIDES", "provides", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
WITH (186, "WITH", "with", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
OPENS (187, "OPENS", "opens", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD);
|
||||
OPENS (187, "OPENS", "opens", EnumSet.of(TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
|
||||
// Table 4.7.20.2-1 type_path_kind
|
||||
ARRAY_TYPEPATH (188, TypeAnnotationTypes.EPathKind.ARRAY.parseKey(), TypeAnnotationTypes.EPathKind.ARRAY.parseKey(),
|
||||
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
INNER_TYPE_TYPEPATH (189, TypeAnnotationTypes.EPathKind.INNER_TYPE.parseKey(), TypeAnnotationTypes.EPathKind.INNER_TYPE.parseKey(),
|
||||
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
WILDCARD_TYPEPATH (190, TypeAnnotationTypes.EPathKind.WILDCARD.parseKey(), TypeAnnotationTypes.EPathKind.WILDCARD.parseKey(),
|
||||
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD),
|
||||
TYPE_ARGUMENT_TYPEPATH (191, TypeAnnotationTypes.EPathKind.TYPE_ARGUMENT.parseKey(), TypeAnnotationTypes.EPathKind.TYPE_ARGUMENT.parseKey(),
|
||||
EnumSet.of(TokenType.TYPE_PATH_KIND, TokenType.DECLARATION, TokenType.JASM_IDENT, TokenType.MODULE_NAME ), KeywordType.KEYWORD);
|
||||
|
||||
final static EnumSet<Token> ALL_TOKENS = EnumSet.allOf(Token.class);
|
||||
// Misc Keywords
|
||||
|
@ -334,36 +411,39 @@ public class JasmTokens {
|
|||
final private KeywordType key_type; // KeywordType.KEYWORD
|
||||
|
||||
public static Optional<Token> get(String parsekey, KeywordType ktype) {
|
||||
return ALL_TOKENS.stream().filter(t->t.key_type == ktype).filter(t->t.parsekey.equals(parsekey)).findFirst();
|
||||
return ALL_TOKENS.stream().
|
||||
filter(t->t.key_type == ktype).
|
||||
filter(t->t.parsekey.equals(parsekey) || ( t.alias != null && t.alias.equals(parsekey))).
|
||||
findFirst();
|
||||
}
|
||||
|
||||
// By default, if a KeywordType is not specified, it has the value 'TOKEN'
|
||||
Token(Integer val, String print, String op, EnumSet<TokenType> ttype) {
|
||||
this(val, print, op, null, ttype, KeywordType.TOKEN);
|
||||
Token(Integer val, String print, String parsekey, EnumSet<TokenType> ttype) {
|
||||
this(val, print, parsekey, null, ttype, KeywordType.TOKEN);
|
||||
}
|
||||
|
||||
Token(Integer val, String print, String op, String als, EnumSet<TokenType> ttype) {
|
||||
this(val, print, op, als, ttype, KeywordType.TOKEN);
|
||||
Token(Integer val, String print, String parsekey, String als, EnumSet<TokenType> ttype) {
|
||||
this(val, print, parsekey, als, ttype, KeywordType.TOKEN);
|
||||
}
|
||||
|
||||
Token(Integer val, String print, String op, EnumSet<TokenType> ttype, KeywordType ktype) {
|
||||
this(val, print, op, null, ttype, ktype);
|
||||
Token(Integer val, String print, String parsekey, EnumSet<TokenType> ttype, KeywordType ktype) {
|
||||
this(val, print, parsekey, null, ttype, ktype);
|
||||
}
|
||||
|
||||
Token(Integer val, String print, String op, String als, EnumSet<TokenType> ttype, KeywordType ktype) {
|
||||
Token(Integer val, String print, String parsekey, String als, EnumSet<TokenType> ttype, KeywordType ktype) {
|
||||
this.value = val;
|
||||
this.printval = print;
|
||||
this.parsekey = op;
|
||||
this.parsekey = parsekey;
|
||||
this.tokenType = ttype;
|
||||
this.key_type = ktype;
|
||||
this.alias = als;
|
||||
}
|
||||
|
||||
public String printval() {
|
||||
public String printValue() {
|
||||
return printval;
|
||||
}
|
||||
|
||||
public String parsekey() {
|
||||
public String parseKey() {
|
||||
return parsekey;
|
||||
}
|
||||
|
||||
|
@ -377,6 +457,13 @@ public class JasmTokens {
|
|||
|
||||
public boolean possibleModuleName() { return tokenType.contains(TokenType.MODULE_NAME) && !tokenType.contains(TokenType.PUNCTUATION); }
|
||||
|
||||
/**
|
||||
* Checks a token belonging to the table: Table 4.7.20.2-A. Interpretation of type_path_kind values
|
||||
*
|
||||
* @return true if token is ARRAY, INNER_TYPE, WILDCARD or TYPE_ARGUMENT
|
||||
*/
|
||||
public boolean possibleTypePathKind() { return tokenType.contains(TokenType.TYPE_PATH_KIND); }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<" + printval + "> [" + value + "]";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -26,11 +26,9 @@ import static org.openjdk.asmtools.jasm.RuntimeConstants.DEPRECATED_ATTRIBUTE;
|
|||
import static org.openjdk.asmtools.jasm.RuntimeConstants.SYNTHETIC_ATTRIBUTE;
|
||||
import org.openjdk.asmtools.jasm.Tables.AttrTag;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* The common base structure for field_info, method_info, and component_info
|
||||
*/
|
||||
abstract public class MemberData {
|
||||
|
||||
|
@ -41,6 +39,7 @@ abstract public class MemberData {
|
|||
protected DataVectorAttr<TypeAnnotationData> type_annotAttrVis = null;
|
||||
protected DataVectorAttr<TypeAnnotationData> type_annotAttrInv = null;
|
||||
protected ClassData cls;
|
||||
protected AttrData signatureAttr;
|
||||
|
||||
public MemberData(ClassData cls, int access) {
|
||||
this.cls = cls;
|
||||
|
@ -61,18 +60,19 @@ abstract public class MemberData {
|
|||
// create the appropriate marker attributes,
|
||||
// and clear the PseudoModifiers from the access flags.
|
||||
if (Modifiers.isSyntheticPseudoMod(access)) {
|
||||
syntheticAttr = new AttrData(cls,
|
||||
AttrTag.ATT_Synthetic.parsekey());
|
||||
|
||||
syntheticAttr = new AttrData(cls, AttrTag.ATT_Synthetic.parsekey());
|
||||
access &= ~SYNTHETIC_ATTRIBUTE;
|
||||
}
|
||||
if (Modifiers.isDeprecatedPseudoMod(access)) {
|
||||
deprecatedAttr = new AttrData(cls,
|
||||
AttrTag.ATT_Deprecated.parsekey());
|
||||
deprecatedAttr = new AttrData(cls, AttrTag.ATT_Deprecated.parsekey());
|
||||
access &= ~DEPRECATED_ATTRIBUTE;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSignatureAttr(ConstantPool.ConstCell value_cpx) {
|
||||
signatureAttr = new CPXAttr(cls, Tables.AttrTag.ATT_Signature.parsekey(), value_cpx);
|
||||
}
|
||||
|
||||
protected abstract DataVector getAttrVector();
|
||||
|
||||
protected final DataVector getDataVector(Data... extraAttrs) {
|
||||
|
@ -98,25 +98,24 @@ abstract public class MemberData {
|
|||
return attrs;
|
||||
}
|
||||
|
||||
public void addAnnotations(ArrayList<AnnotationData> annttns) {
|
||||
for (AnnotationData annot : annttns) {
|
||||
boolean invisible = annot.invisible;
|
||||
if (annot instanceof TypeAnnotationData) {
|
||||
public void addAnnotations(ArrayList<AnnotationData> list) {
|
||||
for (AnnotationData item : list) {
|
||||
boolean invisible = item.invisible;
|
||||
if (item instanceof TypeAnnotationData) {
|
||||
// Type Annotations
|
||||
TypeAnnotationData tannot = (TypeAnnotationData) annot;
|
||||
TypeAnnotationData ta = (TypeAnnotationData) item;
|
||||
if (invisible) {
|
||||
if (type_annotAttrInv == null) {
|
||||
type_annotAttrInv = new DataVectorAttr(cls,
|
||||
AttrTag.ATT_RuntimeInvisibleTypeAnnotations.parsekey());
|
||||
|
||||
}
|
||||
type_annotAttrInv.add(tannot);
|
||||
type_annotAttrInv.add(ta);
|
||||
} else {
|
||||
if (type_annotAttrVis == null) {
|
||||
type_annotAttrVis = new DataVectorAttr(cls,
|
||||
AttrTag.ATT_RuntimeVisibleTypeAnnotations.parsekey());
|
||||
}
|
||||
type_annotAttrVis.add(tannot);
|
||||
type_annotAttrVis.add(ta);
|
||||
}
|
||||
} else {
|
||||
// Regular Annotations
|
||||
|
@ -124,16 +123,14 @@ abstract public class MemberData {
|
|||
if (annotAttrInv == null) {
|
||||
annotAttrInv = new DataVectorAttr(cls,
|
||||
AttrTag.ATT_RuntimeInvisibleAnnotations.parsekey());
|
||||
|
||||
}
|
||||
annotAttrInv.add(annot);
|
||||
annotAttrInv.add(item);
|
||||
} else {
|
||||
if (annotAttrVis == null) {
|
||||
annotAttrVis = new DataVectorAttr(cls,
|
||||
AttrTag.ATT_RuntimeVisibleAnnotations.parsekey());
|
||||
|
||||
}
|
||||
annotAttrVis.add(annot);
|
||||
annotAttrVis.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -22,12 +22,6 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jasm;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.Token;
|
||||
import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
|
||||
import static org.openjdk.asmtools.jasm.Tables.CF_Context;
|
||||
|
@ -38,8 +32,6 @@ import static org.openjdk.asmtools.jasm.Tables.CF_Context;
|
|||
*/
|
||||
public class Modifiers {
|
||||
|
||||
private static Modifiers ref;
|
||||
|
||||
/*
|
||||
* Modifier masks
|
||||
*/
|
||||
|
@ -377,71 +369,71 @@ public class Modifiers {
|
|||
private static StringBuffer _accessString(int mod, CF_Context context) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (context == CF_Context.CTX_CLASS && isModule(mod)) {
|
||||
sb.append(Token.MODULE.parsekey() + " ");
|
||||
sb.append(Token.MODULE.parseKey() + " ");
|
||||
}
|
||||
if (isPublic(mod)) {
|
||||
sb.append(Token.PUBLIC.parsekey() + " ");
|
||||
sb.append(Token.PUBLIC.parseKey() + " ");
|
||||
}
|
||||
if (isPrivate(mod)) {
|
||||
sb.append(Token.PRIVATE.parsekey() + " ");
|
||||
sb.append(Token.PRIVATE.parseKey() + " ");
|
||||
}
|
||||
if (isProtected(mod)) {
|
||||
sb.append(Token.PROTECTED.parsekey() + " ");
|
||||
sb.append(Token.PROTECTED.parseKey() + " ");
|
||||
}
|
||||
if (isStatic(mod)) {
|
||||
sb.append(Token.STATIC.parsekey() + " ");
|
||||
sb.append(Token.STATIC.parseKey() + " ");
|
||||
}
|
||||
if (context == CF_Context.CTX_METHOD && isFinal(mod)) {
|
||||
sb.append(Token.FINAL.parsekey() + " ");
|
||||
sb.append(Token.FINAL.parseKey() + " ");
|
||||
}
|
||||
if (context == CF_Context.CTX_FIELD && isTransient(mod)) {
|
||||
sb.append(Token.TRANSIENT.parsekey() + " ");
|
||||
sb.append(Token.TRANSIENT.parseKey() + " ");
|
||||
}
|
||||
if (context == CF_Context.CTX_CLASS && isSuper(mod)) {
|
||||
sb.append(Token.SUPER.parsekey() + " ");
|
||||
sb.append(Token.SUPER.parseKey() + " ");
|
||||
}
|
||||
if (context == CF_Context.CTX_METHOD && isSynchronized(mod)) {
|
||||
sb.append(Token.SYNCHRONIZED.parsekey() + " ");
|
||||
sb.append(Token.SYNCHRONIZED.parseKey() + " ");
|
||||
}
|
||||
if (context == CF_Context.CTX_METHOD) {
|
||||
if (isBridge(mod)) {
|
||||
sb.append(Token.BRIDGE.parsekey() + " ");
|
||||
sb.append(Token.BRIDGE.parseKey() + " ");
|
||||
}
|
||||
if (isVarArgs(mod)) {
|
||||
sb.append(Token.VARARGS.parsekey() + " ");
|
||||
sb.append(Token.VARARGS.parseKey() + " ");
|
||||
}
|
||||
if (isNative(mod)) {
|
||||
sb.append(Token.NATIVE.parsekey() + " ");
|
||||
sb.append(Token.NATIVE.parseKey() + " ");
|
||||
}
|
||||
}
|
||||
if (isAbstract(mod)) {
|
||||
if ((context != CF_Context.CTX_CLASS) || !isInterface(mod)) {
|
||||
sb.append(Token.ABSTRACT.parsekey() + " ");
|
||||
sb.append(Token.ABSTRACT.parseKey() + " ");
|
||||
}
|
||||
}
|
||||
if ( context.isOneOf(CF_Context.CTX_CLASS, CF_Context.CTX_INNERCLASS, CF_Context.CTX_FIELD) && isFinal(mod)) {
|
||||
sb.append(Token.FINAL.parsekey() + " ");
|
||||
sb.append(Token.FINAL.parseKey() + " ");
|
||||
}
|
||||
if (context.isOneOf(CF_Context.CTX_CLASS, CF_Context.CTX_INNERCLASS) && isInterface(mod)) {
|
||||
if (isAnnotation(mod)) {
|
||||
sb.append(Token.ANNOTATION_ACCESS.parsekey() + " ");
|
||||
sb.append(Token.ANNOTATION_ACCESS.parseKey() + " ");
|
||||
}
|
||||
sb.append(Token.INTERFACE.parsekey() + " ");
|
||||
sb.append(Token.INTERFACE.parseKey() + " ");
|
||||
}
|
||||
if (isStrict(mod)) {
|
||||
sb.append(Token.STRICT.parsekey() + " ");
|
||||
sb.append(Token.STRICT.parseKey() + " ");
|
||||
}
|
||||
if (isSynthetic(mod)) {
|
||||
sb.append(Token.SYNTHETIC.parsekey() + " ");
|
||||
sb.append(Token.SYNTHETIC.parseKey() + " ");
|
||||
}
|
||||
if (context == CF_Context.CTX_FIELD && isVolatile(mod)) {
|
||||
sb.append(Token.VOLATILE.parsekey() + " ");
|
||||
sb.append(Token.VOLATILE.parseKey() + " ");
|
||||
}
|
||||
if (isEnum(mod)) {
|
||||
sb.append(Token.ENUM.parsekey() + " ");
|
||||
sb.append(Token.ENUM.parseKey() + " ");
|
||||
}
|
||||
if (context.isOneOf(CF_Context.CTX_METHOD, CF_Context.CTX_FIELD) && isMandated(mod)) {
|
||||
sb.append(Token.MANDATED.parsekey() + " ");
|
||||
sb.append(Token.MANDATED.parseKey() + " ");
|
||||
}
|
||||
|
||||
return sb;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package org.openjdk.asmtools.jasm;
|
||||
|
||||
import org.openjdk.asmtools.common.Module;
|
||||
|
@ -34,6 +33,8 @@ import java.util.function.Consumer;
|
|||
|
||||
import static org.openjdk.asmtools.jasm.ConstantPool.*;
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.Token;
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.Token.COMMA;
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.Token.SEMICOLON;
|
||||
import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
|
||||
|
@ -73,7 +74,7 @@ class Parser extends ParseBase {
|
|||
|
||||
CodeAttr curCode;
|
||||
|
||||
private ArrayList clsDataList = new ArrayList<>();
|
||||
private ArrayList<ClassData> clsDataList = new ArrayList<>();
|
||||
private String pkg = null;
|
||||
private String pkgPrefix = "";
|
||||
private ArrayList<AnnotationData> pkgAnnttns = null;
|
||||
|
@ -123,7 +124,7 @@ class Parser extends ParseBase {
|
|||
*/
|
||||
|
||||
private void parseVersionPkg() throws IOException {
|
||||
if (scanner.token == Token.SEMICOLON) {
|
||||
if (scanner.token == SEMICOLON) {
|
||||
return;
|
||||
}
|
||||
parse_ver:
|
||||
|
@ -267,8 +268,8 @@ class Parser extends ParseBase {
|
|||
tag = Tables.tag(sValue);
|
||||
if (itemType != null) { // itemType OK
|
||||
if ((tag != null) // ambiguity: "int," or "int 77,"?
|
||||
&& (scanner.token != Token.SEMICOLON)
|
||||
&& (scanner.token != Token.COMMA)) {
|
||||
&& (scanner.token != SEMICOLON)
|
||||
&& (scanner.token != COMMA)) {
|
||||
itemType = StackMapType.ITEM_Object;
|
||||
}
|
||||
break resolve;
|
||||
|
@ -279,7 +280,7 @@ class Parser extends ParseBase {
|
|||
}
|
||||
// resolution failed:
|
||||
itemType = StackMapType.ITEM_Bogus;
|
||||
env.error("itemtype.expected", "<" + ptoken.printval() + ">");
|
||||
env.error("itemtype.expected", "<" + ptoken.printValue() + ">");
|
||||
}
|
||||
switch (itemType) {
|
||||
case ITEM_Object: // followed by CP index
|
||||
|
@ -316,6 +317,26 @@ class Parser extends ParseBase {
|
|||
|
||||
// In many cases, Identifiers can correctly have the same
|
||||
// names as keywords. We need to allow these.
|
||||
case OPEN:
|
||||
case MODULE:
|
||||
case VARARGS:
|
||||
case REQUIRES:
|
||||
case EXPORTS:
|
||||
case TO:
|
||||
case USES:
|
||||
case PROVIDES:
|
||||
case WITH:
|
||||
case OPENS:
|
||||
|
||||
case ARRAY_TYPEPATH:
|
||||
case INNER_TYPE_TYPEPATH:
|
||||
case WILDCARD_TYPEPATH:
|
||||
case TYPE_ARGUMENT_TYPEPATH:
|
||||
case PERMITTEDSUBTYPES:
|
||||
case INF:
|
||||
case NAN:
|
||||
case COMPONENT:
|
||||
|
||||
case SYNTHETIC:
|
||||
case DEPRECATED:
|
||||
case VERSION:
|
||||
|
@ -323,7 +344,6 @@ class Parser extends ParseBase {
|
|||
case STACK:
|
||||
case LOCAL:
|
||||
case OF:
|
||||
case NAN:
|
||||
case INNERCLASS:
|
||||
case STRICT:
|
||||
case FIELDREF:
|
||||
|
@ -345,12 +365,21 @@ class Parser extends ParseBase {
|
|||
ConstCell parseMethodHandle(SubTag subtag) throws Scanner.SyntaxError, IOException {
|
||||
ConstCell refCell;
|
||||
switch (subtag) {
|
||||
// If the value of the reference_kind item is
|
||||
// 1 (REF_getField), 2 (REF_getStatic), 3 (REF_putField) or 4 (REF_putStatic),
|
||||
// then the constant_pool entry at that index must be a CONSTANT_Fieldref_info structure (§4.4.2)
|
||||
// representing a field for which a method handle is to be created. jvms-4.4.8-200-C-A
|
||||
case REF_GETFIELD:
|
||||
case REF_GETSTATIC:
|
||||
case REF_PUTFIELD:
|
||||
case REF_PUTSTATIC:
|
||||
refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_FIELD));
|
||||
break;
|
||||
// If the value of the reference_kind item is
|
||||
// 5 (REF_invokeVirtual) or 8 (REF_newInvokeSpecial),
|
||||
// then the constant_pool entry at that index must be a CONSTANT_Methodref_info structure (§4.4.2)
|
||||
// representing a class's method or constructor (§2.9.1) for which a method handle is to be created.
|
||||
// jvms-4.4.8-200-C-B
|
||||
case REF_INVOKEVIRTUAL:
|
||||
case REF_NEWINVOKESPECIAL:
|
||||
refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_METHOD));
|
||||
|
@ -368,11 +397,13 @@ class Parser extends ParseBase {
|
|||
// if the class file version number is 52.0 or above, the constant_pool entry at that index must be
|
||||
// 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;
|
||||
ConstType ctype01 = ConstType.CONSTANT_METHOD;
|
||||
ConstType ctype02 = ConstType.CONSTANT_INTERFACEMETHOD;
|
||||
if (this.cd.cfv.major_version() >= 52 && Modifiers.isInterface(this.cd.access)) {
|
||||
ctype = ConstType.CONSTANT_INTERFACEMETHOD;
|
||||
ctype01 = ConstType.CONSTANT_INTERFACEMETHOD;
|
||||
ctype02 = ConstType.CONSTANT_METHOD;
|
||||
}
|
||||
refCell = pool.FindCell(cpParser.parseConstValue(ctype));
|
||||
refCell = cpParser.parseConstRef(ctype01, ctype02);
|
||||
break;
|
||||
case REF_INVOKEINTERFACE:
|
||||
refCell = pool.FindCell(cpParser.parseConstValue(ConstType.CONSTANT_INTERFACEMETHOD));
|
||||
|
@ -420,6 +451,26 @@ class Parser extends ParseBase {
|
|||
return pool.FindCellAsciz(v);
|
||||
// Some identifiers might coincide with token names.
|
||||
// these should be OK to use as identifier names.
|
||||
case OPEN:
|
||||
case MODULE:
|
||||
case VARARGS:
|
||||
case REQUIRES:
|
||||
case EXPORTS:
|
||||
case TO:
|
||||
case USES:
|
||||
case PROVIDES:
|
||||
case WITH:
|
||||
case OPENS:
|
||||
|
||||
case ARRAY_TYPEPATH:
|
||||
case INNER_TYPE_TYPEPATH:
|
||||
case WILDCARD_TYPEPATH:
|
||||
case TYPE_ARGUMENT_TYPEPATH:
|
||||
case PERMITTEDSUBTYPES:
|
||||
case INF:
|
||||
case NAN:
|
||||
case COMPONENT:
|
||||
|
||||
case SYNTHETIC:
|
||||
case DEPRECATED:
|
||||
case VERSION:
|
||||
|
@ -427,7 +478,6 @@ class Parser extends ParseBase {
|
|||
case STACK:
|
||||
case LOCAL:
|
||||
case OF:
|
||||
case NAN:
|
||||
case INNERCLASS:
|
||||
case STRICT:
|
||||
case FIELDREF:
|
||||
|
@ -441,7 +491,7 @@ class Parser extends ParseBase {
|
|||
default:
|
||||
ConstType key = Tables.tag(scanner.token.value());
|
||||
env.traceln("%%%%% Unrecognized token [" + scanner.token + "]: '" + (key == null ? "null" : key.parseKey()) + "'.");
|
||||
env.error(scanner.prevPos, "name.expected", "\"" + scanner.token.parsekey() + "\"");
|
||||
env.error(scanner.prevPos, "name.expected", "\"" + scanner.token.parseKey() + "\"");
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
}
|
||||
|
@ -544,8 +594,8 @@ class Parser extends ParseBase {
|
|||
env.error("const.def.expected");
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
if (scanner.token != Token.COMMA) {
|
||||
scanner.expect(Token.SEMICOLON);
|
||||
if (scanner.token != COMMA) {
|
||||
scanner.expect(SEMICOLON);
|
||||
return;
|
||||
}
|
||||
scanner.scan(); // COMMA
|
||||
|
@ -666,6 +716,13 @@ class Parser extends ParseBase {
|
|||
fld.addAnnotations(memberAnnttns);
|
||||
}
|
||||
|
||||
// Parse the optional attribute: signature
|
||||
if (scanner.token == Token.COLON) {
|
||||
scanner.scan();
|
||||
ConstCell signatureCell = parseName();
|
||||
fld.setSignatureAttr(signatureCell);
|
||||
}
|
||||
|
||||
// Parse the optional initializer
|
||||
if (scanner.token == Token.ASSIGN) {
|
||||
scanner.scan();
|
||||
|
@ -675,8 +732,8 @@ class Parser extends ParseBase {
|
|||
// If the next scanner.token is a comma, then there is more
|
||||
debugScan(" [Parser.parseField]: Field: " + fld + " ");
|
||||
|
||||
if (scanner.token != Token.COMMA) {
|
||||
scanner.expect(Token.SEMICOLON);
|
||||
if (scanner.token != COMMA) {
|
||||
scanner.expect(SEMICOLON);
|
||||
return;
|
||||
}
|
||||
scanner.scan();
|
||||
|
@ -799,7 +856,7 @@ class Parser extends ParseBase {
|
|||
exc_table.add(exc);
|
||||
env.traceln("THROWS:" + exc.arg);
|
||||
}
|
||||
if (scanner.token != Token.COMMA) {
|
||||
if (scanner.token != COMMA) {
|
||||
break;
|
||||
}
|
||||
scanner.scan();
|
||||
|
@ -825,7 +882,7 @@ class Parser extends ParseBase {
|
|||
annotParser.parseParamAnnots(paramcnt, curMethod);
|
||||
}
|
||||
|
||||
if (scanner.token == Token.SEMICOLON) {
|
||||
if (scanner.token == SEMICOLON) {
|
||||
if ((max_stack != null) || (max_locals != null)) {
|
||||
env.error("token.expected", "{");
|
||||
}
|
||||
|
@ -838,9 +895,13 @@ class Parser extends ParseBase {
|
|||
if (scanner.token == Token.RBRACE) {
|
||||
break;
|
||||
}
|
||||
scanner.expect(Token.SEMICOLON);
|
||||
// code's type annotation(s)
|
||||
if (scanner.token == Token.ANNOTATION) {
|
||||
curCode.addAnnotations(annotParser.scanAnnotations());
|
||||
break;
|
||||
}
|
||||
scanner.expect(SEMICOLON);
|
||||
}
|
||||
|
||||
curCode.endCode();
|
||||
scanner.expect(Token.RBRACE);
|
||||
}
|
||||
|
@ -869,7 +930,7 @@ class Parser extends ParseBase {
|
|||
scanner.scan();
|
||||
ArrayList<ConstCell> bsm_args = new ArrayList<>(256);
|
||||
|
||||
while (scanner.token != Token.SEMICOLON) {
|
||||
while (scanner.token != SEMICOLON) {
|
||||
if (scanner.token == Token.CPINDEX) {
|
||||
bsm_args.add(pool.getCell(scanner.intValue));
|
||||
|
||||
|
@ -899,7 +960,7 @@ class Parser extends ParseBase {
|
|||
String className = prependPackage(parseIdent(), true);
|
||||
ConstCell hostClass = pool.FindCellClassByName(className);
|
||||
debugScan(" [Parser.parseNestHost]: NestHost: class " + className);
|
||||
scanner.expect(Token.SEMICOLON);
|
||||
scanner.expect(SEMICOLON);
|
||||
cd.addNestHost(hostClass);
|
||||
}
|
||||
|
||||
|
@ -916,8 +977,8 @@ class Parser extends ParseBase {
|
|||
String className = prependPackage(parseIdent(), true);
|
||||
classes.add(pool.FindCellClassByName(className));
|
||||
debugScan(" [Parser.parseClasses]: class " + className);
|
||||
if (scanner.token != Token.COMMA) {
|
||||
scanner.expect(Token.SEMICOLON);
|
||||
if (scanner.token != COMMA) {
|
||||
scanner.expect(SEMICOLON);
|
||||
classesConsumer.accept(classes);
|
||||
return;
|
||||
}
|
||||
|
@ -930,40 +991,67 @@ class Parser extends ParseBase {
|
|||
*/
|
||||
private void parseRecord() throws Scanner.SyntaxError, IOException {
|
||||
// Parses in the form:
|
||||
// RECORD COMPONENT (, COMPONENT)*;
|
||||
// RECORD { (COMPONENT)+ }
|
||||
// where
|
||||
// COMPONENT NAME:DESCRIPTOR SIGNATURE? (ANNOTATION)*
|
||||
// COMPONENT Component (ANNOTATION)* NAME:DESCRIPTOR(:SIGNATURE)? (,|;)
|
||||
// NAME = (CPINDEX | IDENT)
|
||||
// DESCRIPTOR = (CPINDEX | STRING)
|
||||
// SIGNATURE = (CPINDEX | STRING)
|
||||
debugScan("[Parser.parseRecord]: Begin ");
|
||||
debugScan("[Parser.parseRecord]: Begin");
|
||||
scanner.expect(Token.LBRACE);
|
||||
|
||||
ArrayList<AnnotationData> componentAnntts = null;
|
||||
boolean grouped = false;
|
||||
RecordData rd = cd.setRecord(scanner.pos);
|
||||
Component:
|
||||
|
||||
while (true) {
|
||||
if (scanner.token == Token.RBRACE) {
|
||||
if (rd.isEmpty()) {
|
||||
env.error(scanner.pos, "warn.no.components.in.record.attribute");
|
||||
cd.rejectRecord();
|
||||
} else if (grouped) {
|
||||
env.error(scanner.pos, "grouped.component.expected");
|
||||
}
|
||||
scanner.scan();
|
||||
break;
|
||||
}
|
||||
|
||||
ConstCell nameCell, descCell, signatureCell = null;
|
||||
if (scanner.token == Token.ANNOTATION) {
|
||||
componentAnntts = annotParser.scanAnnotations();
|
||||
}
|
||||
|
||||
scanner.expect(Token.COMPONENT);
|
||||
|
||||
nameCell = parseName();
|
||||
scanner.expect(Token.COLON);
|
||||
descCell = parseName();
|
||||
rd.addComponent(nameCell, descCell);
|
||||
while (true) {
|
||||
switch (scanner.token) {
|
||||
case COMMA:
|
||||
scanner.scan();
|
||||
continue Component; // next component
|
||||
case SEMICOLON:
|
||||
return; // EOR
|
||||
case ANNOTATION:
|
||||
rd.setAnnotations(annotParser.scanAnnotations());
|
||||
break;
|
||||
default:
|
||||
if (signatureCell != null) {
|
||||
env.error(scanner.pos, "warn.signature.repeated");
|
||||
}
|
||||
signatureCell = parseName();
|
||||
rd.setComponentSignature(signatureCell);
|
||||
}
|
||||
// Parse the optional attribute: signature
|
||||
if (scanner.token == Token.COLON) {
|
||||
scanner.scan();
|
||||
signatureCell = parseName();
|
||||
}
|
||||
|
||||
rd.addComponent(nameCell, descCell, signatureCell, componentAnntts);
|
||||
|
||||
switch (scanner.token) {
|
||||
case COMMA:
|
||||
grouped = true;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
grouped = false;
|
||||
componentAnntts = null;
|
||||
break;
|
||||
default:
|
||||
env.error(scanner.pos, "one.of.two.token.expected",
|
||||
"<" + SEMICOLON.printValue() + ">",
|
||||
"<" + COMMA.printValue() + ">");
|
||||
break;
|
||||
}
|
||||
// next component
|
||||
scanner.scan();
|
||||
} // end while
|
||||
debugScan("[Parser.parseRecord]: End");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1046,7 +1134,7 @@ class Parser extends ParseBase {
|
|||
}
|
||||
|
||||
// See if declaration is terminated
|
||||
if (scanner.token == Token.SEMICOLON) {
|
||||
if (scanner.token == SEMICOLON) {
|
||||
// InnerClass is complete, no OUTERINFO;
|
||||
outerClass = pool.getCell(0);
|
||||
pic_tracecreate(mod, nameCell, innerClass, outerClass);
|
||||
|
@ -1076,7 +1164,7 @@ class Parser extends ParseBase {
|
|||
outerClass = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
|
||||
}
|
||||
|
||||
if (scanner.token == Token.SEMICOLON) {
|
||||
if (scanner.token == SEMICOLON) {
|
||||
pic_tracecreate(mod, nameCell, innerClass, outerClass);
|
||||
cd.addInnerClass(mod, nameCell, innerClass, outerClass);
|
||||
} else {
|
||||
|
@ -1250,7 +1338,7 @@ class Parser extends ParseBase {
|
|||
mod |= ACC_ANNOTATION | ACC_INTERFACE;
|
||||
scanner.scan();
|
||||
} else {
|
||||
env.error(scanner.prevPos, "token.expected", Token.ANNOTATION.parsekey() + Token.INTERFACE.parsekey());
|
||||
env.error(scanner.prevPos, "token.expected", Token.ANNOTATION.parseKey() + Token.INTERFACE.parseKey());
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
}
|
||||
|
@ -1275,9 +1363,9 @@ class Parser extends ParseBase {
|
|||
scanner.scan();
|
||||
cd.fileExtension = "." + fileExtension;
|
||||
} else if (scanner.token == Token.MODULE) {
|
||||
env.error(scanner.prevPos, "token.expected", Token.OPEN.parsekey());
|
||||
env.error(scanner.prevPos, "token.expected", Token.OPEN.parseKey());
|
||||
throw new Scanner.SyntaxError();
|
||||
} else if (scanner.token == Token.SEMICOLON) {
|
||||
} else if (scanner.token == SEMICOLON) {
|
||||
// drop the semi-colon following a name
|
||||
scanner.scan();
|
||||
}
|
||||
|
@ -1287,7 +1375,7 @@ class Parser extends ParseBase {
|
|||
if (scanner.token == Token.EXTENDS) {
|
||||
scanner.scan();
|
||||
sup = cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
|
||||
while (scanner.token == Token.COMMA) {
|
||||
while (scanner.token == COMMA) {
|
||||
scanner.scan();
|
||||
env.error(posa, "multiple.inherit");
|
||||
cpParser.parseConstRef(ConstType.CONSTANT_CLASS);
|
||||
|
@ -1305,7 +1393,7 @@ class Parser extends ParseBase {
|
|||
} else {
|
||||
impl.add(intf);
|
||||
}
|
||||
} while (scanner.token == Token.COMMA);
|
||||
} while (scanner.token == COMMA);
|
||||
}
|
||||
parseVersion();
|
||||
scanner.expect(Token.LBRACE);
|
||||
|
@ -1346,7 +1434,7 @@ class Parser extends ParseBase {
|
|||
name = name + field + scanner.idValue;
|
||||
scanner.scan();
|
||||
} else {
|
||||
env.error(scanner.pos, "name.expected", "\"" + scanner.token.parsekey() + "\"");
|
||||
env.error(scanner.pos, "name.expected", "\"" + scanner.token.parseKey() + "\"");
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
if (scanner.token == Token.FIELD) {
|
||||
|
@ -1370,7 +1458,7 @@ class Parser extends ParseBase {
|
|||
name = name + field + scanner.idValue;
|
||||
scanner.scanModuleStatement();
|
||||
} else {
|
||||
env.error(scanner.pos, "module.name.expected", "\"" + scanner.token.parsekey() + "\"");
|
||||
env.error(scanner.pos, "module.name.expected", "\"" + scanner.token.parseKey() + "\"");
|
||||
throw new Scanner.SyntaxError().Fatal();
|
||||
}
|
||||
if (scanner.token == Token.FIELD) {
|
||||
|
@ -1407,7 +1495,7 @@ class Parser extends ParseBase {
|
|||
scanner.scanModuleStatement();
|
||||
// scanner.scan();
|
||||
} else {
|
||||
env.error(scanner.pos, "token.expected", Token.MODULE.parsekey());
|
||||
env.error(scanner.pos, "token.expected", Token.MODULE.parseKey());
|
||||
throw new Scanner.SyntaxError().Fatal();
|
||||
}
|
||||
// Parse the module name
|
||||
|
@ -1476,7 +1564,7 @@ class Parser extends ParseBase {
|
|||
int flags = 0;
|
||||
String mn = "";
|
||||
scanner.scanModuleStatement();
|
||||
while (scanner.token != Token.SEMICOLON) {
|
||||
while (scanner.token != SEMICOLON) {
|
||||
switch (scanner.token) {
|
||||
case STATIC:
|
||||
if (((flags & (1 << Module.Modifier.ACC_STATIC_PHASE.asInt())) != 0) || !mn.isEmpty()) {
|
||||
|
@ -1548,7 +1636,7 @@ class Parser extends ParseBase {
|
|||
String typeName = "";
|
||||
HashSet<String> names = new HashSet<>();
|
||||
scanner.scan();
|
||||
while (scanner.token != Token.SEMICOLON) {
|
||||
while (scanner.token != SEMICOLON) {
|
||||
if (scanner.token == Token.IDENT) {
|
||||
if (typeName.isEmpty()) {
|
||||
typeName = source.get();
|
||||
|
@ -1589,7 +1677,7 @@ class Parser extends ParseBase {
|
|||
HashSet<String> names = new HashSet<>();
|
||||
boolean comma = false, first = true;
|
||||
scanMethod.call();
|
||||
while (scanner.token != Token.SEMICOLON) {
|
||||
while (scanner.token != SEMICOLON) {
|
||||
switch (scanner.token) {
|
||||
case COMMA:
|
||||
if (comma || first || onlyOneElement) {
|
||||
|
@ -1788,7 +1876,7 @@ class Parser extends ParseBase {
|
|||
int where = scanner.pos;
|
||||
String id = parseIdent();
|
||||
parseVersionPkg();
|
||||
scanner.expect(Token.SEMICOLON);
|
||||
scanner.expect(SEMICOLON);
|
||||
|
||||
if (pkg == null) {
|
||||
pkg = id;
|
||||
|
@ -1802,7 +1890,7 @@ class Parser extends ParseBase {
|
|||
recoverFile();
|
||||
}
|
||||
// skip bogus semi colons
|
||||
while (scanner.token == Token.SEMICOLON) {
|
||||
while (scanner.token == SEMICOLON) {
|
||||
scanner.scan();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -22,7 +22,10 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jasm;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
|
||||
import org.openjdk.asmtools.jasm.TypeAnnotationTargetInfoData.*;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.AnnotationType.isInvisibleAnnotationToken;
|
||||
import static org.openjdk.asmtools.jasm.TypeAnnotationTypes.*;
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.*;
|
||||
import static org.openjdk.asmtools.jasm.ConstantPool.*;
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
|
@ -50,7 +53,7 @@ public class ParserAnnotation extends ParseBase {
|
|||
*
|
||||
* Used to store Annotation values
|
||||
*/
|
||||
class AnnotationElemValue implements Data {
|
||||
static class AnnotationElemValue implements Data {
|
||||
|
||||
AnnotationData annotation;
|
||||
|
||||
|
@ -185,21 +188,11 @@ public class ParserAnnotation extends ParseBase {
|
|||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* Annotation Parser Fields */
|
||||
/**
|
||||
* local handles on the scanner, main parser, and the error reporting env
|
||||
*/
|
||||
private static TTVis ttVisitor;
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* main constructor
|
||||
*
|
||||
* @param scanner
|
||||
* @param parser
|
||||
* @param env
|
||||
*/
|
||||
protected ParserAnnotation(Scanner scanner, Parser parser, Environment env) {
|
||||
super.init(scanner, parser, env);
|
||||
ttVisitor = new TTVis();
|
||||
|
@ -249,76 +242,23 @@ public class ParserAnnotation extends ParseBase {
|
|||
* @throws IOException
|
||||
*/
|
||||
ArrayList<AnnotationData> scanAnnotations() throws IOException {
|
||||
ArrayList<AnnotationData> annttns = new ArrayList<>();
|
||||
|
||||
ArrayList<AnnotationData> list = new ArrayList<>();
|
||||
while (scanner.token == Token.ANNOTATION) {
|
||||
if (isAnnotationToken(scanner.stringValue)) {
|
||||
annttns.add(parseAnnotation());
|
||||
} else if (isTypeAnnotationToken(scanner.stringValue)) {
|
||||
annttns.add(parseTypeAnnotation());
|
||||
if ( JasmTokens.AnnotationType.isAnnotationToken(scanner.stringValue)) {
|
||||
list.add(parseAnnotation());
|
||||
} else if (JasmTokens.AnnotationType.isTypeAnnotationToken(scanner.stringValue)) {
|
||||
list.add(parseTypeAnnotation());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (annttns.size() > 0) {
|
||||
return annttns;
|
||||
if (list.size() > 0) {
|
||||
return list;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* isAnnotation
|
||||
*
|
||||
* examines the beginning of a string to see if it starts with an annotation character
|
||||
*
|
||||
* @param str
|
||||
* @return True if the string starts with an annotation char.
|
||||
*/
|
||||
protected boolean isAnnotation(String str) {
|
||||
return (str.startsWith("@"));
|
||||
}
|
||||
|
||||
/**
|
||||
* isAnnotationToken
|
||||
*
|
||||
* examines the beginning of a string to see if it starts with an annotation
|
||||
* characters ('@+' = visible annotation, '@-' = invisible).
|
||||
*
|
||||
* @param str
|
||||
* @return True if the string starts with an annotation char.
|
||||
*/
|
||||
protected boolean isAnnotationToken(String str) {
|
||||
return (str.startsWith("@+") || str.startsWith("@-"));
|
||||
}
|
||||
|
||||
/**
|
||||
* isTypeAnnotationToken
|
||||
*
|
||||
* examines the beginning of a string to see if it starts with type annotation
|
||||
* characters ('@T+' = visible type annotation, '@T-' = invisible).
|
||||
*
|
||||
* @param str
|
||||
* @return True if the string starts with an annotation char.
|
||||
*/
|
||||
protected boolean isTypeAnnotationToken(String str) {
|
||||
return (str.startsWith("@T+") || str.startsWith("@T-"));
|
||||
}
|
||||
|
||||
/**
|
||||
* isInvisibleAnnotToken
|
||||
*
|
||||
* examines the end of an annotation token to determine visibility ('+' = visible
|
||||
* annotation, '-' = invisible).
|
||||
*
|
||||
* @param str
|
||||
* @return True if the token implies invisible annotation.
|
||||
*/
|
||||
protected boolean isInvisibleAnnotToken(String str) {
|
||||
return (str.endsWith("-"));
|
||||
}
|
||||
|
||||
/**
|
||||
* parseDefaultAnnotation
|
||||
*
|
||||
|
@ -412,7 +352,7 @@ public class ParserAnnotation extends ParseBase {
|
|||
* @throws IOException
|
||||
*/
|
||||
private AnnotationData parseTypeAnnotation() throws Scanner.SyntaxError, IOException {
|
||||
boolean invisible = isInvisibleAnnotToken(scanner.stringValue);
|
||||
boolean invisible = isInvisibleAnnotationToken(scanner.stringValue);
|
||||
scanner.scan();
|
||||
debugScan(" [ParserAnnotation.parseTypeAnnotation]: id = " + scanner.stringValue + " ");
|
||||
String annoName = "L" + scanner.stringValue + ";";
|
||||
|
@ -425,11 +365,13 @@ public class ParserAnnotation extends ParseBase {
|
|||
// Scan the usual annotation data
|
||||
_scanAnnotation(anno);
|
||||
|
||||
// scan the Target
|
||||
// scan the Target (u1: target_type, union{...}: target_info)
|
||||
_scanTypeTarget(anno);
|
||||
|
||||
// scan the Location
|
||||
_scanTargetPath(anno);
|
||||
if( scanner.token != Token.RBRACE ) {
|
||||
// scan the Location (type_path: target_path)
|
||||
_scanTargetPath(anno);
|
||||
}
|
||||
|
||||
scanner.expect(Token.RBRACE);
|
||||
return anno;
|
||||
|
@ -445,7 +387,7 @@ public class ParserAnnotation extends ParseBase {
|
|||
*/
|
||||
private AnnotationData parseAnnotation() throws Scanner.SyntaxError, IOException {
|
||||
debugScan(" - - - > [ParserAnnotation.parseAnnotation]: Begin ");
|
||||
boolean invisible = isInvisibleAnnotToken(scanner.stringValue);
|
||||
boolean invisible = isInvisibleAnnotationToken(scanner.stringValue);
|
||||
scanner.scan();
|
||||
String annoName = "L" + scanner.stringValue + ";";
|
||||
|
||||
|
@ -478,7 +420,7 @@ public class ParserAnnotation extends ParseBase {
|
|||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
String name = ((ConstValue_String) cellref)._toString();
|
||||
debugScan(" - - - > [ParserAnnotation._scanAnnotation]: Annot - Field Name: " + name);
|
||||
debugScan(" [ParserAnnotation._scanAnnotation]: Annot - Field Name: " + name);
|
||||
Data data = scanAnnotationData(name);
|
||||
annotData.add(new AnnotationData.ElemValuePair(nameCell, data));
|
||||
|
||||
|
@ -505,21 +447,21 @@ public class ParserAnnotation extends ParseBase {
|
|||
//Scan the target_type and the target_info
|
||||
scanner.expect(Token.IDENT);
|
||||
debugScan(" [ParserAnnotation._scanTypeTarget]: TargetType: " + scanner.idValue);
|
||||
TypeAnnotationUtils.TargetType tt = TypeAnnotationUtils.getTargetType(scanner.idValue);
|
||||
if (tt == null) {
|
||||
ETargetType targetType = ETargetType.getTargetType(scanner.idValue);
|
||||
if (targetType == null) {
|
||||
env.error(scanner.pos, "incorrect.typeannot.target", scanner.idValue);
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
|
||||
debugScan(" [ParserAnnotation._scanTypeTarget]: Got TargetType: " + tt);
|
||||
debugScan(" [ParserAnnotation._scanTypeTarget]: Got TargetType: " + targetType);
|
||||
|
||||
if (ttVisitor.scanner == null) {
|
||||
ttVisitor.scanner = scanner;
|
||||
}
|
||||
ttVisitor.visitExcept(tt);
|
||||
ttVisitor.visitExcept(targetType);
|
||||
|
||||
annotData.targetInfo = ttVisitor.getTargetInfo();
|
||||
annotData.targetType = tt;
|
||||
annotData.targetType = targetType;
|
||||
debugScan(" [ParserAnnotation._scanTypeTarget]: Got TargetInfo: " + annotData.targetInfo);
|
||||
|
||||
scanner.expect(Token.RBRACE);
|
||||
|
@ -531,9 +473,9 @@ public class ParserAnnotation extends ParseBase {
|
|||
* Target Type visitor, used for constructing the target-info within a type
|
||||
* annotation. visitExcept() is the entry point. ti is the constructed target info.
|
||||
*/
|
||||
private static class TTVis extends TypeAnnotationUtils.TypeAnnotationTargetVisitor {
|
||||
private static class TTVis extends TypeAnnotationTypes.TypeAnnotationTargetVisitor {
|
||||
|
||||
private TypeAnnotationUtils.TargetInfo ti;
|
||||
private TypeAnnotationTargetInfoData ti;
|
||||
private IOException IOProb;
|
||||
private Scanner.SyntaxError SyProb;
|
||||
private Scanner scanner;
|
||||
|
@ -560,7 +502,7 @@ public class ParserAnnotation extends ParseBase {
|
|||
}
|
||||
|
||||
//This is the entry point for a visitor that tunnels exceptions
|
||||
public void visitExcept(TypeAnnotationUtils.TargetType tt) throws IOException, Scanner.SyntaxError {
|
||||
public void visitExcept(ETargetType tt) throws IOException, Scanner.SyntaxError {
|
||||
IOProb = null;
|
||||
SyProb = null;
|
||||
ti = null;
|
||||
|
@ -576,13 +518,13 @@ public class ParserAnnotation extends ParseBase {
|
|||
}
|
||||
}
|
||||
|
||||
public TypeAnnotationUtils.TargetInfo getTargetInfo() {
|
||||
public TypeAnnotationTargetInfoData getTargetInfo() {
|
||||
return ti;
|
||||
}
|
||||
|
||||
// this fn gathers intvals, and tunnels any exceptions thrown by
|
||||
// the scanner
|
||||
private int scanIntVal(TypeAnnotationUtils.TargetType tt) {
|
||||
private int scanIntVal(ETargetType tt) {
|
||||
int ret = -1;
|
||||
if (scanner.token == Token.INTVAL) {
|
||||
ret = scanner.intValue;
|
||||
|
@ -602,7 +544,7 @@ public class ParserAnnotation extends ParseBase {
|
|||
|
||||
// this fn gathers intvals, and tunnels any exceptions thrown by
|
||||
// the scanner
|
||||
private String scanStringVal(TypeAnnotationUtils.TargetType tt) {
|
||||
private String scanStringVal(ETargetType tt) {
|
||||
String ret = "";
|
||||
if (scanner.token == Token.STRINGVAL) {
|
||||
ret = scanner.stringValue;
|
||||
|
@ -637,25 +579,25 @@ public class ParserAnnotation extends ParseBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void visit_type_param_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_type_param_target(ETargetType tt) {
|
||||
env.traceln("Type Param Target: ");
|
||||
int byteval = scanIntVal(tt); // param index
|
||||
if (!error()) {
|
||||
ti = new TypeAnnotationUtils.typeparam_target(tt, byteval);
|
||||
ti = new TypeAnnotationTargetInfoData.type_parameter_target(tt, byteval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_supertype_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_supertype_target(ETargetType tt) {
|
||||
env.traceln("SuperType Target: ");
|
||||
int shortval = scanIntVal(tt); // type index
|
||||
if (!error()) {
|
||||
ti = new TypeAnnotationUtils.supertype_target(tt, shortval);
|
||||
ti = new TypeAnnotationTargetInfoData.supertype_target(tt, shortval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_typeparam_bound_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_typeparam_bound_target(ETargetType tt) {
|
||||
env.traceln("TypeParam Bound Target: ");
|
||||
int byteval1 = scanIntVal(tt); // param index
|
||||
if (error()) {
|
||||
|
@ -665,39 +607,39 @@ public class ParserAnnotation extends ParseBase {
|
|||
if (error()) {
|
||||
return;
|
||||
}
|
||||
ti = new TypeAnnotationUtils.typeparam_bound_target(tt, byteval1, byteval2);
|
||||
ti = new TypeAnnotationTargetInfoData.type_parameter_bound_target(tt, byteval1, byteval2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_empty_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_empty_target(ETargetType tt) {
|
||||
env.traceln("Empty Target: ");
|
||||
if (!error()) {
|
||||
ti = new TypeAnnotationUtils.empty_target(tt);
|
||||
ti = new TypeAnnotationTargetInfoData.empty_target(tt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_methodformalparam_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_methodformalparam_target(ETargetType tt) {
|
||||
env.traceln("MethodParam Target: ");
|
||||
int byteval = scanIntVal(tt); // param index
|
||||
if (!error()) {
|
||||
ti = new TypeAnnotationUtils.methodformalparam_target(tt, byteval);
|
||||
ti = new formal_parameter_target(tt, byteval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_throws_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_throws_target(ETargetType tt) {
|
||||
env.traceln("Throws Target: ");
|
||||
int shortval = scanIntVal(tt); // exception index
|
||||
if (!error()) {
|
||||
ti = new TypeAnnotationUtils.throws_target(tt, shortval);
|
||||
ti = new throws_target(tt, shortval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_localvar_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_localvar_target(ETargetType tt) {
|
||||
env.traceln("LocalVar Target: ");
|
||||
TypeAnnotationUtils.localvar_target locvartab = new TypeAnnotationUtils.localvar_target(tt, 0);
|
||||
localvar_target locvartab = new localvar_target(tt, 0);
|
||||
ti = locvartab;
|
||||
|
||||
while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
|
||||
|
@ -725,24 +667,24 @@ public class ParserAnnotation extends ParseBase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void visit_catch_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_catch_target(ETargetType tt) {
|
||||
env.traceln("Catch Target: ");
|
||||
int shortval = scanIntVal(tt); // catch index
|
||||
|
||||
ti = new TypeAnnotationUtils.catch_target(tt, shortval);
|
||||
ti = new catch_target(tt, shortval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_offset_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_offset_target(ETargetType tt) {
|
||||
env.traceln("Offset Target: ");
|
||||
int shortval = scanIntVal(tt); // offset index
|
||||
if (!error()) {
|
||||
ti = new TypeAnnotationUtils.offset_target(tt, shortval);
|
||||
ti = new offset_target(tt, shortval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_typearg_target(TypeAnnotationUtils.TargetType tt) {
|
||||
public void visit_typearg_target(ETargetType tt) {
|
||||
env.traceln("TypeArg Target: ");
|
||||
int shortval = scanIntVal(tt); // offset
|
||||
if (error()) {
|
||||
|
@ -752,75 +694,77 @@ public class ParserAnnotation extends ParseBase {
|
|||
if (error()) {
|
||||
return;
|
||||
}
|
||||
ti = new TypeAnnotationUtils.typearg_target(tt, shortval, byteval);
|
||||
ti = new type_argument_target(tt, shortval, byteval);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* _scanTypeLocation
|
||||
* _scanTargetPath
|
||||
*
|
||||
* parses an individual annotation-data.
|
||||
* parses and fills the type_path structure (4.7.20.2)
|
||||
*
|
||||
* @return a parsed annotation.
|
||||
* @throws IOException
|
||||
* type_path {
|
||||
* u1 path_length;
|
||||
* { u1 type_path_kind;
|
||||
* u1 type_argument_index;
|
||||
* } path[path_length];
|
||||
* }
|
||||
*
|
||||
* @throws Scanner.SyntaxError, IOException
|
||||
*/
|
||||
private void _scanTargetPath(TypeAnnotationData annotData) throws Scanner.SyntaxError, IOException {
|
||||
|
||||
ArrayList<TypePathEntry> targPath = new ArrayList<>();
|
||||
// parse the location info
|
||||
scanner.expect(Token.LBRACE);
|
||||
|
||||
while ((scanner.token != Token.EOF) && (scanner.token != Token.RBRACE)) {
|
||||
TypePathEntry tpe = _scanTypePathEntry();
|
||||
|
||||
scanner.scan();
|
||||
annotData.addTypePathEntry(tpe);
|
||||
// throw away comma
|
||||
if (scanner.token == Token.COMMA) {
|
||||
scanner.scan();
|
||||
}
|
||||
}
|
||||
|
||||
scanner.expect(Token.RBRACE);
|
||||
annotData.targetPath = targPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* _scanTypeLocation
|
||||
*
|
||||
* parses an individual annotation-data.
|
||||
* parses a path entry of the type_path.
|
||||
*
|
||||
* @return a parsed annotation.
|
||||
* @throws IOException
|
||||
* { u1 type_path_kind;
|
||||
* u1 type_argument_index;
|
||||
* }
|
||||
*
|
||||
* @return a parsed type path.
|
||||
* @throws Scanner.SyntaxError, IOException
|
||||
*/
|
||||
private TypePathEntry _scanTypePathEntry() throws Scanner.SyntaxError, IOException {
|
||||
TypePathEntry tpe;
|
||||
|
||||
if ((scanner.token != Token.EOF) && (scanner.token == Token.STRINGVAL)) {
|
||||
String pathEntryKey = scanner.stringValue;
|
||||
PathKind pk = pathKind(pathEntryKey);
|
||||
if (pk == null) {
|
||||
// unexpected Type Path
|
||||
env.error(scanner.pos, "incorrect.typeannot.pathentry", scanner.stringValue);
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
if (pk == PathKind.ITHARG_PARAMETERTYPE) {
|
||||
//
|
||||
if ( (scanner.token != Token.EOF) && scanner.token.possibleTypePathKind() ) {
|
||||
EPathKind pathKind = EPathKind.getPathKind(scanner.stringValue);
|
||||
if (pathKind == EPathKind.TYPE_ARGUMENT) {
|
||||
scanner.scan();
|
||||
// need to scan the index
|
||||
// Take the form: INNER_TYPE(#)
|
||||
scanner.expect(Token.LPAREN);
|
||||
// Take the form: TYPE_ARGUMENT{#}
|
||||
scanner.expect(Token.LBRACE);
|
||||
int index = 0;
|
||||
if ((scanner.token != Token.EOF) && (scanner.token == Token.INTVAL)) {
|
||||
index = scanner.intValue;
|
||||
scanner.scan();
|
||||
} else {
|
||||
// incorrect Arg index
|
||||
env.error(scanner.pos, "incorrect.typeannot.pathentry.argindex", scanner.token);
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
|
||||
scanner.expect(Token.RPAREN);
|
||||
tpe = new TypePathEntry(pk.key(), (char) index);
|
||||
tpe = new TypePathEntry(pathKind, index);
|
||||
scanner.expect(Token.RBRACE);
|
||||
} else {
|
||||
tpe = new TypePathEntry(pk.key(), (char) 0);
|
||||
tpe = new TypePathEntry(pathKind, 0);
|
||||
scanner.scan();
|
||||
}
|
||||
} else {
|
||||
// unexpected Type Path
|
||||
|
@ -1136,7 +1080,6 @@ public class ParserAnnotation extends ParseBase {
|
|||
env.error(scanner.pos, "incorrect.annot.keyword", ident);
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -565,7 +565,7 @@ d2l: {
|
|||
break;
|
||||
default:
|
||||
// problem - no constant value
|
||||
System.err.println("NEAR: " + scanner.token.printval());
|
||||
System.err.println("NEAR: " + scanner.token.printValue());
|
||||
env.error(scanner.pos, "value.expected");
|
||||
throw new Scanner.SyntaxError();
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import static org.openjdk.asmtools.jasm.JasmTokens.*;
|
|||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
import static org.openjdk.asmtools.jasm.OpcodeTables.*;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* ParserInstr
|
||||
|
@ -88,7 +89,7 @@ public class ParserInstr extends ParseBase {
|
|||
|
||||
Opcode opcode = OpcodeTables.opcode(mnemocode);
|
||||
if (opcode == null) {
|
||||
debugScan(" %%error%%error%%% $$$$$$$$$$$$$$$ mnemocode = '" + mnemocode + "'. ");
|
||||
debugScan(" Error: mnemocode = '" + mnemocode + "'. ");
|
||||
}
|
||||
OpcodeType optype = opcode.type();
|
||||
|
||||
|
@ -267,7 +268,13 @@ public class ParserInstr extends ParseBase {
|
|||
break;
|
||||
case opc_invokestatic:
|
||||
case opc_invokespecial:
|
||||
arg = cpParser.parseConstRef(ConstType.CONSTANT_METHOD, ConstType.CONSTANT_INTERFACEMETHOD);
|
||||
ConstType ctype01 = ConstType.CONSTANT_METHOD;
|
||||
ConstType ctype02 = ConstType.CONSTANT_INTERFACEMETHOD;
|
||||
if(Modifier.isInterface(this.parser.cd.access)) {
|
||||
ctype01 = ConstType.CONSTANT_INTERFACEMETHOD;
|
||||
ctype02 = ConstType.CONSTANT_METHOD;
|
||||
}
|
||||
arg = cpParser.parseConstRef(ctype01, ctype02);
|
||||
break;
|
||||
case opc_jsr:
|
||||
case opc_goto:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 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
|
||||
|
@ -33,26 +33,29 @@ import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
|
|||
*/
|
||||
public class RecordData extends AttrData {
|
||||
private List<ComponentData> components = new ArrayList<>();
|
||||
private ComponentData currentComp = null;
|
||||
|
||||
/* Record Data Fields */
|
||||
public RecordData(ClassData cls) {
|
||||
super(cls, Tables.AttrTag.ATT_Record.parsekey());
|
||||
}
|
||||
|
||||
public void addComponent(ConstantPool.ConstCell nameCell, ConstantPool.ConstCell descCell) {
|
||||
public void addComponent(ConstantPool.ConstCell nameCell,
|
||||
ConstantPool.ConstCell descCell,
|
||||
ConstantPool.ConstCell signature,
|
||||
ArrayList<AnnotationData> annotations) {
|
||||
// Define a field if absent
|
||||
FieldData fd = getClassData().addFieldIfAbsent(ACC_MANDATED & ACC_PRIVATE & ACC_FINAL, nameCell, descCell);
|
||||
currentComp = new ComponentData(fd);
|
||||
components.add(currentComp);
|
||||
ComponentData cd = new ComponentData(fd);
|
||||
if( annotations != null ) {
|
||||
cd.addAnnotations(annotations);
|
||||
}
|
||||
if( signature != null ) {
|
||||
cd.setSignatureAttr(signature);
|
||||
}
|
||||
components.add(cd);
|
||||
}
|
||||
|
||||
public void setComponentSignature(ConstantPool.ConstCell signature) {
|
||||
currentComp.setSignature(signature);
|
||||
}
|
||||
|
||||
public void setAnnotations(ArrayList<AnnotationData> annotations) {
|
||||
currentComp.addAnnotations(annotations);
|
||||
public boolean isEmpty() {
|
||||
return components.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -72,20 +75,15 @@ public class RecordData extends AttrData {
|
|||
|
||||
class ComponentData extends MemberData {
|
||||
private FieldData field;
|
||||
private AttrData signature;
|
||||
|
||||
public ComponentData(FieldData field) {
|
||||
super(getClassData());
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public void setSignature(ConstantPool.ConstCell value_cpx) {
|
||||
signature = new CPXAttr(cls, Tables.AttrTag.ATT_Signature.parsekey(), value_cpx);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataVector getAttrVector() {
|
||||
return getDataVector(signature);
|
||||
return getDataVector(signatureAttr);
|
||||
}
|
||||
|
||||
public void write(CheckedDataOutputStream out) throws IOException, Parser.CompilerError {
|
||||
|
|
|
@ -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
|
||||
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jasm;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.*;
|
||||
import static org.openjdk.asmtools.jasm.Constants.EOF;
|
||||
import static org.openjdk.asmtools.jasm.Constants.OFFSETBITS;
|
||||
|
@ -188,7 +189,7 @@ prefix:
|
|||
env.error(pos, "identifier.expected");
|
||||
break;
|
||||
default:
|
||||
env.error(pos, "token.expected", "<" + t.printval() + ">");
|
||||
env.error(pos, "token.expected", "<" + t.printValue() + ">");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -948,7 +949,7 @@ scanloop:
|
|||
idValue = bufferString();
|
||||
stringValue = idValue;
|
||||
token = keyword_token_ident(idValue);
|
||||
debugStr("##### SCANNER (scanIdent) ######## token = " + token + " ##### ");
|
||||
debugStr(format("##### SCANNER (scanIdent) ######## token = %s value = \"%s\"\n", token, idValue));
|
||||
} // end scanIdentifier
|
||||
|
||||
//==============================
|
||||
|
@ -1127,7 +1128,6 @@ loop:
|
|||
// Our one concession to DOS.
|
||||
if ((ch = in.read()) == EOF) {
|
||||
token = Token.EOF;
|
||||
// t0ken = Token.EOF;
|
||||
break loop;
|
||||
}
|
||||
env.error(pos, "funny.char");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -22,40 +22,64 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jasm;
|
||||
|
||||
import org.openjdk.asmtools.jasm.TypeAnnotationTypes.ETargetType;
|
||||
import org.openjdk.asmtools.jasm.TypeAnnotationTypes.TypePathEntry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* JVMS 4.7.20.
|
||||
* type_annotation {
|
||||
* u1 target_type;
|
||||
* union {
|
||||
* type_parameter_target;
|
||||
* supertype_target;
|
||||
* type_parameter_bound_target;
|
||||
* empty_target;
|
||||
* formal_parameter_target;
|
||||
* throws_target;
|
||||
* localvar_target;
|
||||
* catch_target;
|
||||
* offset_target;
|
||||
* type_argument_target;
|
||||
* } target_info;
|
||||
* type_path target_path;
|
||||
* u2 type_index;
|
||||
* //
|
||||
* //
|
||||
* u2 num_element_value_pairs;
|
||||
* { u2 element_name_index;
|
||||
* element_value value;
|
||||
* } element_value_pairs[num_element_value_pairs];
|
||||
* }
|
||||
*/
|
||||
public class TypeAnnotationData extends AnnotationData {
|
||||
|
||||
protected TargetType targetType;
|
||||
protected TargetInfo targetInfo;
|
||||
protected ArrayList<TypePathEntry> targetPath;
|
||||
protected ETargetType targetType;
|
||||
protected TypeAnnotationTargetInfoData targetInfo;
|
||||
protected TypeAnnotationTypePathData typePath;
|
||||
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* TypeAnnotationData Methods */
|
||||
public TypeAnnotationData(Argument typeCPX, boolean invisible) {
|
||||
super(typeCPX, invisible);
|
||||
typePath = new TypeAnnotationTypePathData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return super.getLength() + 2 + targetInfo.getLength();
|
||||
// lengthOf(annotations[]) + lengthOf(targetType) + lengthOf(targetInfo) + lengthOf(targetInfo)
|
||||
return super.getLength() + 1 + targetInfo.getLength() + typePath.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
super.write(out);
|
||||
// KTL: (1/10/13) Spec changed: char -> byte
|
||||
// out.writeShort(targetType.value);
|
||||
out.writeByte(targetType.value);
|
||||
targetInfo.write(out);
|
||||
typePath.write(out);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
public void addTypePathEntry(TypePathEntry path) {
|
||||
typePath.addTypePathEntry(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,40 +88,11 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
}
|
||||
|
||||
public String toString(int tabLevel) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String tabStr = tabString(tabLevel);
|
||||
|
||||
sb.append(tabStr + "Target Type: ");
|
||||
sb.append(targetType.toString());
|
||||
sb.append('\n');
|
||||
|
||||
sb.append(tabStr + "Target Info: ");
|
||||
sb.append(targetInfo.toString(tabLevel));
|
||||
sb.append('\n');
|
||||
|
||||
sb.append(tabStr + "Target Path: [");
|
||||
boolean first = true;
|
||||
for (TypePathEntry tpe : targetPath) {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
}
|
||||
first = false;
|
||||
sb.append(tpe);
|
||||
|
||||
}
|
||||
sb.append("]");
|
||||
sb.append('\n');
|
||||
|
||||
StringBuilder sb = new StringBuilder(tabString(tabLevel));
|
||||
sb.append(targetType.toString()).
|
||||
append(' ').
|
||||
append(targetInfo.toString(tabLevel)).
|
||||
append(typePath.toString(tabLevel));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected static String tabString(int tabLevel) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < tabLevel; i++) {
|
||||
sb.append('\t');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
* 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.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* TargetInfo (4.7.20.1. The target_info union)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info.
|
||||
*/
|
||||
public abstract class TypeAnnotationTargetInfoData implements Data {
|
||||
|
||||
protected TypeAnnotationTypes.ETargetType targettype = null;
|
||||
|
||||
public TypeAnnotationTargetInfoData(TypeAnnotationTypes.ETargetType tt) {
|
||||
targettype = tt;
|
||||
}
|
||||
|
||||
public TypeAnnotationTypes.ETargetType getTargetType() {
|
||||
return targettype;
|
||||
}
|
||||
|
||||
public void print(PrintWriter out, String tab) {
|
||||
// print the TargetType and TargetInfo
|
||||
out.print(tab + " {");
|
||||
targettype.print(out);
|
||||
_print(out, tab);
|
||||
out.print(tab + "} ");
|
||||
}
|
||||
|
||||
public abstract void _print(PrintWriter out, String tab);
|
||||
|
||||
public abstract void write(CheckedDataOutputStream out) throws IOException;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(0);
|
||||
}
|
||||
|
||||
protected abstract void _toString(StringBuilder sb, int tabLevel);
|
||||
|
||||
public String toString(int tabLevel) {
|
||||
StringBuilder sb = new StringBuilder(tabString(tabLevel));
|
||||
// first print the target info name (
|
||||
sb.append(targettype.targetInfo().printValue()).append("_target ");
|
||||
// get the sub-classes parts
|
||||
_toString(sb, tabLevel);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* type_parameter_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The type_parameter_target item indicates that an annotation appears on the declaration of the i'th type parameter
|
||||
* of a generic class, generic interface, generic method, or generic constructor.
|
||||
*
|
||||
* type_parameter_target {
|
||||
* u1 type_parameter_index;
|
||||
* }
|
||||
*/
|
||||
public static class type_parameter_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int typeParamIndex;
|
||||
|
||||
public type_parameter_target(TypeAnnotationTypes.ETargetType tt, int index) {
|
||||
super(tt);
|
||||
typeParamIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeByte(typeParamIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(typeParamIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ type_parameter_index: %d; }",typeParamIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* supertype_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The supertype_target item indicates that an annotation appears on a type in the extends or implements clause of
|
||||
* a class or interface declaration.
|
||||
*
|
||||
* supertype_target {
|
||||
* u2 supertype_index;
|
||||
* }
|
||||
*/
|
||||
public static class supertype_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int superTypeIndex;
|
||||
|
||||
public supertype_target(TypeAnnotationTypes.ETargetType tt, int index) {
|
||||
super(tt);
|
||||
superTypeIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(superTypeIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(superTypeIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ supertype_index: %d; }",superTypeIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* type_parameter_bound_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The type_parameter_bound_target item indicates that an annotation appears on the i'th bound of the j'th type parameter
|
||||
* declaration of a generic class, interface, method, or constructor.
|
||||
*
|
||||
* type_parameter_bound_target {
|
||||
* u1 type_parameter_index;
|
||||
* u1 bound_index;
|
||||
* }
|
||||
*/
|
||||
public static class type_parameter_bound_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int typeParamIndex;
|
||||
int boundIndex;
|
||||
|
||||
public type_parameter_bound_target(TypeAnnotationTypes.ETargetType tt, int pindx, int bindx) {
|
||||
super(tt);
|
||||
typeParamIndex = pindx;
|
||||
boundIndex = bindx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeByte(typeParamIndex);
|
||||
out.writeByte(boundIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(typeParamIndex);
|
||||
out.print(" ");
|
||||
out.print(boundIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ type_parameter_index: %d; bound_index: %d; }",
|
||||
typeParamIndex, boundIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* empty_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The empty_target item indicates that an annotation appears on either the type in a field declaration,
|
||||
* the return type of a method, the type of a newly constructed object, or the receiver type of a method or constructor.
|
||||
*
|
||||
* empty_target {
|
||||
* }
|
||||
*/
|
||||
public static class empty_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
public empty_target(TypeAnnotationTypes.ETargetType tt) {
|
||||
super(tt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() { return 0; }
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append("{ }");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* formal_parameter_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The formal_parameter_target item indicates that an annotation appears on the type in a formal parameter
|
||||
* declaration of a method, constructor, or lambda expression.
|
||||
*
|
||||
* formal_parameter_target {
|
||||
* u1 formal_parameter_index;
|
||||
* }
|
||||
*/
|
||||
public static class formal_parameter_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int formalParamIndex;
|
||||
|
||||
public formal_parameter_target(TypeAnnotationTypes.ETargetType tt, int index) {
|
||||
super(tt);
|
||||
formalParamIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeByte(formalParamIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(formalParamIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ formal_parameter_index: %d; }",formalParamIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* throws_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The throws_target item indicates that an annotation appears on the i'th type in the throws clause of a method or
|
||||
* constructor declaration.
|
||||
*
|
||||
* throws_target {
|
||||
* u2 throws_type_index;
|
||||
* }
|
||||
*/
|
||||
public static class throws_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int throwsTypeIndex;
|
||||
|
||||
public throws_target(TypeAnnotationTypes.ETargetType tt, int index) {
|
||||
super(tt);
|
||||
throwsTypeIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(throwsTypeIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(throwsTypeIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ throws_type_index: %d; }",throwsTypeIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* localvar_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The localvar_target item indicates that an annotation appears on the type in a local variable declaration,
|
||||
* including a variable declared as a resource in a try-with-resources statement.
|
||||
*
|
||||
* localvar_target {
|
||||
* u2 table_length;
|
||||
* { u2 start_pc;
|
||||
* u2 length;
|
||||
* u2 index;
|
||||
* } table[table_length];
|
||||
* }
|
||||
*/
|
||||
public static class localvar_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
public class LocalVar_Entry {
|
||||
|
||||
public int startPC;
|
||||
public int length;
|
||||
public int cpx;
|
||||
|
||||
public LocalVar_Entry(int st, int len, int index) {
|
||||
startPC = st;
|
||||
length = len;
|
||||
cpx = index;
|
||||
}
|
||||
|
||||
void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(startPC);
|
||||
out.writeShort(length);
|
||||
out.writeShort(cpx);
|
||||
}
|
||||
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(tab + "{");
|
||||
out.print(startPC);
|
||||
out.print(" ");
|
||||
out.print(length);
|
||||
out.print(" ");
|
||||
out.print(cpx);
|
||||
out.print("}");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("start_pc: %d, length: %d, index: %d", startPC, length, cpx);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<LocalVar_Entry> table = null;
|
||||
|
||||
public localvar_target(TypeAnnotationTypes.ETargetType tt, int size) {
|
||||
super(tt);
|
||||
table = new ArrayList<>(size);
|
||||
}
|
||||
|
||||
public void addEntry(int startPC, int length, int cpx) {
|
||||
LocalVar_Entry entry = new LocalVar_Entry(startPC, length, cpx);
|
||||
table.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(table.size());
|
||||
for (LocalVar_Entry entry : table) {
|
||||
entry.write(out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
String innerTab = tab + " ";
|
||||
for (LocalVar_Entry entry : table) {
|
||||
entry._print(out, innerTab);
|
||||
}
|
||||
out.print(tab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2 + // U2 for table size
|
||||
(6 * table.size()); // (3 * U2) for each table entry
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
int i = 0;
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ %d {", table.size()));
|
||||
for (LocalVar_Entry entry : table) {
|
||||
sb.append(String.format(" [%d]: %s;", i++, entry.toString()));
|
||||
}
|
||||
sb.append(" } }");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* catch_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The catch_target item indicates that an annotation appears on the i'th type in an exception parameter declaration.
|
||||
*
|
||||
* catch_target {
|
||||
* u2 exception_table_index;
|
||||
* }
|
||||
*/
|
||||
public static class catch_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int exceptionTableIndex;
|
||||
|
||||
public catch_target(TypeAnnotationTypes.ETargetType tt, int index) {
|
||||
super(tt);
|
||||
exceptionTableIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(exceptionTableIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(exceptionTableIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ exception_table_index: %d; }",exceptionTableIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* offset_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The offset_target item indicates that an annotation appears on either the type in an instanceof expression or
|
||||
* a new expression, or the type before the :: in a method reference expression.
|
||||
*
|
||||
* offset_target {
|
||||
* u2 offset;
|
||||
* }
|
||||
*/
|
||||
public static class offset_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int offset;
|
||||
|
||||
public offset_target(TypeAnnotationTypes.ETargetType tt, int offset) {
|
||||
super(tt);
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ offset: %d; }", offset));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* type_argument_target (4.7.20.1. The target_info union)
|
||||
*
|
||||
* The type_argument_target item indicates that an annotation appears either on the i'th type in a cast expression,
|
||||
* or on the i'th type argument in the explicit type argument list for any of the following: a new expression,
|
||||
* an explicit constructor invocation statement, a method invocation expression, or a method reference expression
|
||||
*
|
||||
* type_argument_target {
|
||||
* u2 offset;
|
||||
* u1 type_argument_index;
|
||||
* }
|
||||
*/
|
||||
public static class type_argument_target extends TypeAnnotationTargetInfoData {
|
||||
|
||||
int offset;
|
||||
int typeArgumentIndex;
|
||||
|
||||
public type_argument_target(TypeAnnotationTypes.ETargetType tt, int offset, int index) {
|
||||
super(tt);
|
||||
this.offset = offset;
|
||||
typeArgumentIndex = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(offset);
|
||||
out.writeByte(typeArgumentIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(offset);
|
||||
out.print(" ");
|
||||
out.print(typeArgumentIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
sb.append(tabString(tabLevel)).append(String.format("{ offset: %d; type_argument_index: %d; }",
|
||||
offset, typeArgumentIndex));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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 org.openjdk.asmtools.jasm.TypeAnnotationTypes.TypePathEntry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* JVMS 4.7.20.2. The type_path structure
|
||||
*
|
||||
* type_path {
|
||||
* u1 path_length;
|
||||
* { u1 type_path_kind;
|
||||
* u1 type_argument_index;
|
||||
* } path[path_length];
|
||||
* }
|
||||
*/
|
||||
public class TypeAnnotationTypePathData implements Data {
|
||||
|
||||
private ArrayList<TypePathEntry> typePathEntries = new ArrayList<>();
|
||||
|
||||
public void addTypePathEntry( TypePathEntry entry) {
|
||||
typePathEntries.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeByte(typePathEntries.size());
|
||||
for (TypePathEntry entry : typePathEntries) {
|
||||
out.writeByte(entry.getTypePathKind());
|
||||
out.writeByte(entry.getTypeArgumentIndex());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 1 + typePathEntries.size() * 2;
|
||||
}
|
||||
|
||||
public String toString(int tabLevel) {
|
||||
String buffer = "";
|
||||
if( typePathEntries.size() > 0 ) {
|
||||
StringBuilder sb = new StringBuilder(tabString(tabLevel));
|
||||
sb.append(" [ ");
|
||||
boolean first = true;
|
||||
for (TypePathEntry entry : typePathEntries) {
|
||||
if (!first)
|
||||
sb.append(", ");
|
||||
first = false;
|
||||
sb.append(entry.toString());
|
||||
}
|
||||
sb.append("]");
|
||||
buffer = sb.toString();
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* jdis: print the type_path structure
|
||||
*/
|
||||
public void print(PrintWriter out, String tab) {
|
||||
if( typePathEntries.size() > 0 ) {
|
||||
out.print(tab + " {");
|
||||
boolean first = true;
|
||||
for (TypePathEntry entry : typePathEntries) {
|
||||
if (!first) {
|
||||
out.print(", ");
|
||||
}
|
||||
first = false;
|
||||
out.print(entry.toString());
|
||||
}
|
||||
out.print(tab + "} ");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* 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
|
||||
* 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.PrintWriter;
|
||||
|
||||
/**
|
||||
* Type annotation types: target_type, target_info && target_path
|
||||
*/
|
||||
public class TypeAnnotationTypes {
|
||||
|
||||
/**
|
||||
* Interpretation of type_path_kind values (Table 4.7.20.2-A)
|
||||
*/
|
||||
public enum EPathKind {
|
||||
ARRAY(0),
|
||||
INNER_TYPE(1),
|
||||
WILDCARD(2),
|
||||
TYPE_ARGUMENT(3);
|
||||
|
||||
private final int tag;
|
||||
public static final int maxLen = 3;
|
||||
|
||||
EPathKind(int tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public int tag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public String parseKey() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
static EPathKind getPathKind(String token) {
|
||||
for (EPathKind pk : values()) {
|
||||
if( pk.parseKey().equals(token)) {
|
||||
return pk;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// will throw ArrayIndexOutOfBounds if i < 0 or i > 3
|
||||
static public EPathKind getPathKind(int i) {
|
||||
return EPathKind.values()[i];
|
||||
}
|
||||
|
||||
static public class TypePathEntry {
|
||||
|
||||
private final EPathKind kind;
|
||||
private final int typeArgumentIndex;
|
||||
|
||||
public TypePathEntry(int kind, int typeArgumentIndex) {
|
||||
this.kind = getPathKind(kind);
|
||||
this.typeArgumentIndex = typeArgumentIndex;
|
||||
}
|
||||
|
||||
public TypePathEntry(EPathKind kind, int typeArgumentIndex) {
|
||||
this.kind = kind;
|
||||
this.typeArgumentIndex = typeArgumentIndex;
|
||||
}
|
||||
|
||||
public int getTypePathKind() {
|
||||
return kind.tag();
|
||||
}
|
||||
|
||||
public int getTypeArgumentIndex() {
|
||||
return typeArgumentIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// Chapter 4.7.20.2 The type_path structure
|
||||
// if the value of the type_path_kind is 0,1, or 2, thebn the value of the
|
||||
// type_argument_index item is 0.
|
||||
return kind.parseKey() + ( kind.tag == 3 ?
|
||||
JasmTokens.Token.LBRACE.parseKey() + typeArgumentIndex + JasmTokens.Token.RBRACE.parseKey() :
|
||||
"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* union {
|
||||
* type_parameter_target;
|
||||
* supertype_target;
|
||||
* type_parameter_bound_target;
|
||||
* empty_target;
|
||||
* method_formal_parameter_target;
|
||||
* throws_target;
|
||||
* localvar_target;
|
||||
* catch_target;
|
||||
* offset_target;
|
||||
* type_argument_target;
|
||||
* } target_info;
|
||||
*/
|
||||
public enum ETargetInfo {
|
||||
TYPEPARAM ("TYPEPARAM", "type_parameter"),
|
||||
SUPERTYPE ("SUPERTYPE", "supertype"),
|
||||
TYPEPARAM_BOUND ("TYPEPARAM_BOUND", "type_parameter_bound"),
|
||||
EMPTY ("EMPTY", "empty"),
|
||||
METHODPARAM ("METHODPARAM", "formal_parameter"),
|
||||
EXCEPTION ("EXCEPTION", "throws"),
|
||||
LOCALVAR ("LOCALVAR", "localvar"),
|
||||
CATCH ("CATCH", "catch"),
|
||||
OFFSET ("OFFSET", "offset"),
|
||||
TYPEARG ("TYPEARG", "type_argument");
|
||||
|
||||
private final String parseKey;
|
||||
private final String printValue;
|
||||
|
||||
ETargetInfo(String parse, String printValue) {
|
||||
parseKey = parse;
|
||||
this.printValue = printValue;
|
||||
}
|
||||
public String parseKey() {
|
||||
return this.parseKey;
|
||||
}
|
||||
|
||||
public String printValue() {
|
||||
return this.printValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpretation of target_type values (Table 4.7.20-A./B.)
|
||||
*/
|
||||
static public enum ETargetType {
|
||||
class_type_param (0x00, "CLASS_TYPE_PARAMETER", ETargetInfo.TYPEPARAM, "class/interface type parameter"),
|
||||
meth_type_param (0x01, "METHOD_TYPE_PARAMETER", ETargetInfo.TYPEPARAM, "method/constructor type parameter"),
|
||||
class_exts_impls (0x10, "CLASS_EXTENDS", ETargetInfo.SUPERTYPE, "class extends/implements"),
|
||||
class_type_param_bnds (0x11, "CLASS_TYPE_PARAMETER_BOUND", ETargetInfo.TYPEPARAM_BOUND, "class/interface type parameter bounds"),
|
||||
meth_type_param_bnds (0x12, "METHOD_TYPE_PARAMETER_BOUND", ETargetInfo.TYPEPARAM_BOUND, "method/constructor type parameter bounds"),
|
||||
field (0x13, "FIELD", ETargetInfo.EMPTY, "field"),
|
||||
meth_ret_type (0x14, "METHOD_RETURN", ETargetInfo.EMPTY, "method return type"),
|
||||
meth_receiver (0x15, "METHOD_RECEIVER", ETargetInfo.EMPTY, "method receiver"),
|
||||
meth_formal_param (0x16, "METHOD_FORMAL_PARAMETER", ETargetInfo.METHODPARAM, "method formal parameter type"),
|
||||
throws_type (0x17, "THROWS", ETargetInfo.EXCEPTION, "exception type in throws"),
|
||||
|
||||
local_var (0x40, "LOCAL_VARIABLE", ETargetInfo.LOCALVAR, "local variable"),
|
||||
resource_var (0x41, "RESOURCE_VARIABLE", ETargetInfo.LOCALVAR, "resource variable"),
|
||||
exception_param (0x42, "EXCEPTION_PARAM", ETargetInfo.CATCH, "exception parameter"),
|
||||
type_test (0x43, "INSTANCEOF", ETargetInfo.OFFSET, "type test (instanceof)"),
|
||||
obj_creat (0x44, "NEW", ETargetInfo.OFFSET, "object creation (new)"),
|
||||
constr_ref_receiver (0x45, "CONSTRUCTOR_REFERENCE_RECEIVER", ETargetInfo.OFFSET, "constructor reference receiver"),
|
||||
meth_ref_receiver (0x46, "METHOD_REFERENCE_RECEIVER", ETargetInfo.OFFSET, "method reference receiver"),
|
||||
cast (0x47, "CAST", ETargetInfo.TYPEARG, "cast"),
|
||||
constr_invoc_typearg (0x48, "CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in constructor call"),
|
||||
meth_invoc_typearg (0x49, "METHOD_INVOCATION_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in method call"),
|
||||
constr_ref_typearg (0x4A, "CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in constructor reference"),
|
||||
meth_ref_typearg (0x4B, "METHOD_REFERENCE_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in method reference");
|
||||
|
||||
public static final int maxTag = 0x9A;
|
||||
public static final int maxLen = 36;
|
||||
|
||||
public final int value;
|
||||
private final String parseKey;
|
||||
private final ETargetInfo targetInfo;
|
||||
private final String printVal;
|
||||
|
||||
ETargetType(int val, String parse, ETargetInfo targetInfo, String printVal) {
|
||||
value = val;
|
||||
parseKey = parse;
|
||||
this.targetInfo = targetInfo;
|
||||
this.printVal = printVal;
|
||||
}
|
||||
|
||||
public String parseKey() {
|
||||
return parseKey;
|
||||
}
|
||||
|
||||
public String infoKey() {
|
||||
return targetInfo.parseKey();
|
||||
}
|
||||
|
||||
public ETargetInfo targetInfo() {
|
||||
return targetInfo;
|
||||
}
|
||||
|
||||
public void print(PrintWriter out) {
|
||||
out.print(parseKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s[%#x]", parseKey, value);
|
||||
}
|
||||
|
||||
public static ETargetType getTargetType(int typeCode) {
|
||||
for( ETargetType type: ETargetType.values() ) {
|
||||
if (type.value == typeCode) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static public ETargetType getTargetType(String typeName) {
|
||||
for( ETargetType type: ETargetType.values() ) {
|
||||
if (type.parseKey.equals(typeName)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/* TypeAnnotationVisitor Methods */
|
||||
public static class TypeAnnotationTargetVisitor {
|
||||
|
||||
public final void visit(ETargetType tt) {
|
||||
switch (tt) {
|
||||
case class_type_param:
|
||||
case meth_type_param:
|
||||
visit_type_param_target(tt);
|
||||
break;
|
||||
case class_exts_impls:
|
||||
visit_supertype_target(tt);
|
||||
break;
|
||||
case class_type_param_bnds:
|
||||
case meth_type_param_bnds:
|
||||
visit_typeparam_bound_target(tt);
|
||||
break;
|
||||
case field:
|
||||
case meth_ret_type:
|
||||
case meth_receiver:
|
||||
visit_empty_target(tt);
|
||||
break;
|
||||
case meth_formal_param:
|
||||
visit_methodformalparam_target(tt);
|
||||
break;
|
||||
case throws_type:
|
||||
visit_throws_target(tt);
|
||||
break;
|
||||
case local_var:
|
||||
case resource_var:
|
||||
visit_localvar_target(tt);
|
||||
break;
|
||||
case exception_param:
|
||||
visit_catch_target(tt);
|
||||
break;
|
||||
case type_test:
|
||||
case obj_creat:
|
||||
case constr_ref_receiver:
|
||||
case meth_ref_receiver:
|
||||
visit_offset_target(tt);
|
||||
break;
|
||||
|
||||
case cast:
|
||||
case constr_invoc_typearg:
|
||||
case meth_invoc_typearg:
|
||||
case constr_ref_typearg:
|
||||
case meth_ref_typearg:
|
||||
|
||||
visit_typearg_target(tt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit_type_param_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_supertype_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_typeparam_bound_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_empty_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_methodformalparam_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_throws_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_localvar_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_catch_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_offset_target(ETargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_typearg_target(ETargetType tt) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,891 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class TypeAnnotationUtils {
|
||||
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* TypeAnnotationData Inner Classes */
|
||||
static public enum PathKind {
|
||||
DEEPER_ARRAY (0, "DEEPER_ARRAY", "ARRAY"),
|
||||
DEEPER_NESTEDTYPE (1, "DEEPER_NESTEDTYPE", "INNER_TYPE"),
|
||||
BOUND_WILDCARDTYPE (2, "BOUND_WILDCARDTYPE", "WILDCARD"),
|
||||
ITHARG_PARAMETERTYPE (3, "ITHARG_PARAMETERTYPE", "TYPE_ARGUMENT");
|
||||
|
||||
private final int key;
|
||||
private final String type;
|
||||
private final String parseKey;
|
||||
public static final int maxLen = 3;
|
||||
|
||||
PathKind(int key, String type, String parseval) {
|
||||
this.key = key;
|
||||
this.type = type;
|
||||
this.parseKey = parseval;
|
||||
}
|
||||
|
||||
public int key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public String parsekey() {
|
||||
return parseKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static private HashMap<String, PathKind> PathTypeHash = new HashMap<>(PathKind.maxLen);
|
||||
|
||||
private static void initPathTypes(PathKind pk) {
|
||||
PathTypeHash.put(pk.parseKey, pk);
|
||||
}
|
||||
|
||||
static {
|
||||
for (PathKind pk : PathKind.values()) {
|
||||
initPathTypes(pk);
|
||||
}
|
||||
}
|
||||
|
||||
public static PathKind pathKind(String parseKey) {
|
||||
return PathTypeHash.get(parseKey);
|
||||
}
|
||||
|
||||
// will throw ArrayIndexOutOfBounds if i < 0 or i > 3
|
||||
static public PathKind getPathKind(int i) {
|
||||
return PathKind.values()[i];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* TypeAnnotationData Inner Classes */
|
||||
static public class TypePathEntry {
|
||||
|
||||
private final PathKind kind;
|
||||
private final char index;
|
||||
|
||||
public TypePathEntry(int kind, char index) {
|
||||
this.kind = getPathKind(kind);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public PathKind kind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public char index() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return kind.parsekey() + "(" + index + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* TypeAnnotationData Inner Classes */
|
||||
static public enum InfoType {
|
||||
TYPEPARAM ("TYPEPARAM", "TYPEPARAM"),
|
||||
SUPERTYPE ("SUPERTYPE", "SUPERTYPE"),
|
||||
TYPEPARAM_BOUND ("TYPEPARAM_BOUND", "TYPEPARAM_BOUND"),
|
||||
EMPTY ("EMPTY", "EMPTY"),
|
||||
METHODPARAM ("METHODPARAM", "METHODPARAM"),
|
||||
EXCEPTION ("EXCEPTION", "EXCEPTION"),
|
||||
LOCALVAR ("LOCALVAR", "LOCALVAR"),
|
||||
CATCH ("CATCH", "CATCH"),
|
||||
OFFSET ("OFFSET", "OFFSET"),
|
||||
TYPEARG ("TYPEARG", "TYPEARG");
|
||||
|
||||
private final String parseKey;
|
||||
private final String printval;
|
||||
|
||||
InfoType(String parse, String print) {
|
||||
parseKey = parse;
|
||||
printval = print;
|
||||
}
|
||||
|
||||
public String parseKey() {
|
||||
return parseKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TargetType
|
||||
*
|
||||
* A (typed) tag (constant) representing the type of Annotation Target.
|
||||
*/
|
||||
static public enum TargetType {
|
||||
class_type_param (0x00, "CLASS_TYPE_PARAMETER", InfoType.TYPEPARAM, "class type parameter"),
|
||||
meth_type_param (0x01, "METHOD_TYPE_PARAMETER", InfoType.TYPEPARAM, "method type parameter"),
|
||||
class_exts_impls (0x10, "CLASS_EXTENDS", InfoType.SUPERTYPE, "class extends/implements"),
|
||||
class_type_param_bnds (0x11, "CLASS_TYPE_PARAMETER_BOUND", InfoType.TYPEPARAM_BOUND, "class type parameter bounds"),
|
||||
meth_type_param_bnds (0x12, "METHOD_TYPE_PARAMETER_BOUND", InfoType.TYPEPARAM_BOUND, "method type parameter bounds"),
|
||||
field (0x13, "FIELD", InfoType.EMPTY, "field"),
|
||||
meth_ret_type (0x14, "METHOD_RETURN", InfoType.EMPTY, "method return type"),
|
||||
meth_receiver (0x15, "METHOD_RECEIVER", InfoType.EMPTY, "method receiver"),
|
||||
meth_formal_param (0x16, "METHOD_FORMAL_PARAMETER", InfoType.METHODPARAM, "method formal parameter type"),
|
||||
throws_type (0x17, "THROWS", InfoType.EXCEPTION, "exception type in throws"),
|
||||
local_var (0x40, "LOCAL_VARIABLE", InfoType.LOCALVAR, "local variable"),
|
||||
resource_var (0x41, "RESOURCE_VARIABLE", InfoType.LOCALVAR, "resource variable"), // TODO
|
||||
exception_param (0x42, "EXCEPTION_PARAM", InfoType.CATCH, "exception parameter"), // TODO
|
||||
type_test (0x43, "INSTANCEOF", InfoType.OFFSET, "type test (instanceof)"),
|
||||
obj_creat (0x44, "NEW", InfoType.OFFSET, "object creation (new)"),
|
||||
constr_ref_receiver (0x45, "CONSTRUCTOR_REFERENCE_RECEIVER", InfoType.OFFSET, "constructor reference receiver"),
|
||||
meth_ref_receiver (0x46, "METHOD_REFERENCE_RECEIVER", InfoType.OFFSET, "method reference receiver"),
|
||||
cast (0x47, "CAST", InfoType.TYPEARG, "cast"),
|
||||
constr_invoc_typearg (0x48, "CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in constructor call"),
|
||||
meth_invoc_typearg (0x49, "METHOD_INVOCATION_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in method call"),
|
||||
constr_ref_typearg (0x4A, "CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in constructor reference"),
|
||||
meth_ref_typearg (0x4B, "METHOD_REFERENCE_TYPE_ARGUMENT", InfoType.TYPEARG, "type argument in method reference");
|
||||
|
||||
public static final int maxTag = 0x9A;
|
||||
public static final int maxLen = 36;
|
||||
|
||||
public final int value;
|
||||
private final String parseKey;
|
||||
private final InfoType infoKey;
|
||||
private final String printval;
|
||||
|
||||
TargetType(int val, String parse, InfoType info, String print) {
|
||||
value = val;
|
||||
parseKey = parse;
|
||||
infoKey = info;
|
||||
printval = print;
|
||||
}
|
||||
|
||||
public String parseKey() {
|
||||
return parseKey;
|
||||
}
|
||||
|
||||
public String infoKey() {
|
||||
return infoKey.parseKey();
|
||||
}
|
||||
|
||||
public InfoType infoType() {
|
||||
return infoKey;
|
||||
}
|
||||
|
||||
public void print(PrintWriter out) {
|
||||
out.print(parseKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return parseKey + " (" + infoKey() + ") <" + printval + "> [" + Integer.toHexString(value) + "]";
|
||||
}
|
||||
};
|
||||
|
||||
static private HashMap<String, TargetType> TargetTypeHash = new HashMap<>(TargetType.maxLen);
|
||||
static private HashMap<Integer, TargetType> TargetTypeList = new HashMap<>(TargetType.maxLen);
|
||||
|
||||
private static void initTargetTypes(TypeAnnotationUtils.TargetType tt) {
|
||||
TargetTypeList.put(tt.value, tt);
|
||||
TargetTypeHash.put(tt.parseKey, tt);
|
||||
}
|
||||
|
||||
static {
|
||||
for (TargetType type : TargetType.values()) {
|
||||
initTargetTypes(type);
|
||||
}
|
||||
}
|
||||
|
||||
public static TargetType targetType(String parseKey) {
|
||||
return TargetTypeHash.get(parseKey);
|
||||
}
|
||||
|
||||
public static TargetType targetTypeEnum(Integer typeCode) {
|
||||
return TargetTypeList.get(typeCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* TargetInfo
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info.
|
||||
*/
|
||||
public static class TargetInfo {
|
||||
|
||||
protected TargetType targettype = null;
|
||||
|
||||
public TargetInfo(TargetType tt) {
|
||||
targettype = tt;
|
||||
}
|
||||
|
||||
public TargetType getTargetType() {
|
||||
return targettype;
|
||||
}
|
||||
|
||||
public void print(PrintWriter out, String tab) {
|
||||
// print the TargetType and TargetInfo
|
||||
out.print(tab + " {");
|
||||
targettype.print(out);
|
||||
_print(out, tab);
|
||||
out.print(tab + "}");
|
||||
}
|
||||
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
// sub-classes override
|
||||
}
|
||||
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
// placeholder
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(0);
|
||||
}
|
||||
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
// sub-classes override
|
||||
}
|
||||
|
||||
public String toString(int tabLevel) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String tabStr = tabString(tabLevel);
|
||||
|
||||
// first print the name/target-type
|
||||
sb.append(tabStr);
|
||||
sb.append(targettype.infoKey() + " \n");
|
||||
sb.append(tabStr);
|
||||
sb.append(targettype + " \n");
|
||||
|
||||
// get the sub-classes parts
|
||||
_toString(sb, tabLevel);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected static String tabString(int tabLevel) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < tabLevel; i++) {
|
||||
sb.append('\t');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TypeParams_Target (3.3.1 Type parameters)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class typeparam_target extends TargetInfo {
|
||||
|
||||
int pindex;
|
||||
|
||||
public typeparam_target(TargetType tt, int indx) {
|
||||
super(tt);
|
||||
pindex = indx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeByte(pindex);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(pindex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 1 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("param_index: ");
|
||||
sb.append(pindex);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* supertype_target (3.3.2 Class extends and implements)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class supertype_target extends TargetInfo {
|
||||
|
||||
int type_index;
|
||||
|
||||
public supertype_target(TargetType tt, int tindex) {
|
||||
super(tt);
|
||||
type_index = tindex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(type_index);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(type_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("type_index: ");
|
||||
sb.append(type_index);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* typeparam_bound_target (3.3.3 Type parameter bounds)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class typeparam_bound_target extends TargetInfo {
|
||||
|
||||
int pindex;
|
||||
int bindex;
|
||||
|
||||
public typeparam_bound_target(TargetType tt, int pindx, int bindx) {
|
||||
super(tt);
|
||||
pindex = pindx;
|
||||
bindex = bindx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeByte(pindex);
|
||||
out.writeByte(bindex);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(pindex);
|
||||
out.print(" ");
|
||||
out.print(bindex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("param_index: ");
|
||||
sb.append(pindex);
|
||||
sb.append('\n');
|
||||
|
||||
sb.append(tabStr);
|
||||
sb.append("bound_index: ");
|
||||
sb.append(bindex);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* empty_target (3.3.4 )
|
||||
*
|
||||
* Types without arguments.
|
||||
*
|
||||
* Basic types without arguments, like field, method return, or method receiver.
|
||||
*/
|
||||
public static class empty_target extends TargetInfo {
|
||||
|
||||
public empty_target(TargetType tt) {
|
||||
super(tt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* methodformalparam_target (3.3.5 Method parameters)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class methodformalparam_target extends TargetInfo {
|
||||
|
||||
int index;
|
||||
|
||||
public methodformalparam_target(TargetType tt, int indx) {
|
||||
super(tt);
|
||||
index = indx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeByte(index);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 1 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("index: ");
|
||||
sb.append(index);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* throws_target (3.3.6 throws clauses)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class throws_target extends TargetInfo {
|
||||
|
||||
int type_index;
|
||||
|
||||
public throws_target(TargetType tt, int tindex) {
|
||||
super(tt);
|
||||
type_index = tindex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(type_index);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(type_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("type_index: ");
|
||||
sb.append(type_index);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* localvar_target (3.3.7 Local variables)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class localvar_target extends TargetInfo {
|
||||
|
||||
public static class LocalVar_Entry {
|
||||
|
||||
public int startPC;
|
||||
public int length;
|
||||
public int cpx;
|
||||
|
||||
public LocalVar_Entry(int st, int len, int index) {
|
||||
startPC = st;
|
||||
length = len;
|
||||
cpx = index;
|
||||
}
|
||||
|
||||
void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(startPC);
|
||||
out.writeShort(length);
|
||||
out.writeShort(cpx);
|
||||
}
|
||||
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(tab + "{");
|
||||
out.print(startPC);
|
||||
out.print(" ");
|
||||
out.print(length);
|
||||
out.print(" ");
|
||||
out.print(cpx);
|
||||
out.println("}");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new String("startPC: " + startPC
|
||||
+ " length: " + length
|
||||
+ " cpx: " + cpx);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<LocalVar_Entry> table = null;
|
||||
|
||||
public localvar_target(TargetType tt, int size) {
|
||||
super(tt);
|
||||
table = new ArrayList<>(size);
|
||||
}
|
||||
|
||||
public void addEntry(int startPC, int length, int cpx) {
|
||||
LocalVar_Entry entry = new LocalVar_Entry(startPC, length, cpx);
|
||||
table.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(table.size());
|
||||
for (LocalVar_Entry entry : table) {
|
||||
entry.write(out);
|
||||
}
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
String innerTab = tab + " ";
|
||||
out.println();
|
||||
for (LocalVar_Entry entry : table) {
|
||||
entry._print(out, innerTab);
|
||||
}
|
||||
out.print(innerTab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2 + // U2 for table size
|
||||
(6 * table.size()) + // (3 * U2) for each table entry
|
||||
super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr1 = tabString(tabLevel + 1);
|
||||
int i = 1;
|
||||
for (LocalVar_Entry entry : table) {
|
||||
sb.append(tabStr1);
|
||||
sb.append("[" + i + "]: ");
|
||||
sb.append(entry.toString());
|
||||
sb.append('\n');
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* catch_target (3.3.8 Exception parameters (catch clauses))
|
||||
*
|
||||
* Index to the exception type (the type that shows up in a catch clause).
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class catch_target extends TargetInfo {
|
||||
|
||||
int exception_table_index;
|
||||
|
||||
public catch_target(TargetType tt, int indx) {
|
||||
super(tt);
|
||||
exception_table_index = indx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(exception_table_index);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(exception_table_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("exception_table_index: ");
|
||||
sb.append(exception_table_index);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* offset_target (3.3.9 Typecasts, type tests, and object creation)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class offset_target extends TargetInfo {
|
||||
|
||||
int offset;
|
||||
|
||||
public offset_target(TargetType tt, int ofst) {
|
||||
super(tt);
|
||||
offset = ofst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(offset);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 2 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("offset: ");
|
||||
sb.append(offset);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* typearg_target (3.3.10 Constructor and method call type arguments)
|
||||
*
|
||||
* BaseClass for any Type Annotation Target-Info that is in a parameterized type,
|
||||
* array, or nested type.
|
||||
*
|
||||
* These need location information to identify the annotated element.
|
||||
*/
|
||||
public static class typearg_target extends TargetInfo {
|
||||
|
||||
int offset;
|
||||
int typeIndex;
|
||||
|
||||
public typearg_target(TargetType tt, int ofst, int tindx) {
|
||||
super(tt);
|
||||
offset = ofst;
|
||||
typeIndex = tindx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CheckedDataOutputStream out) throws IOException {
|
||||
out.writeShort(offset);
|
||||
out.writeByte(typeIndex);
|
||||
super.write(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void _print(PrintWriter out, String tab) {
|
||||
out.print(" ");
|
||||
out.print(offset);
|
||||
out.print(" ");
|
||||
out.print(typeIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return 3 + super.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb, int tabLevel) {
|
||||
String tabStr = tabString(tabLevel);
|
||||
sb.append(tabStr);
|
||||
sb.append("offset: ");
|
||||
sb.append(offset);
|
||||
sb.append('\n');
|
||||
|
||||
sb.append(tabStr);
|
||||
sb.append("type_index: ");
|
||||
sb.append(typeIndex);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* TypeAnnotationVisitor Methods */
|
||||
public static class TypeAnnotationTargetVisitor {
|
||||
|
||||
public final void visit(TargetType tt) {
|
||||
switch (tt) {
|
||||
case class_type_param:
|
||||
case meth_type_param:
|
||||
visit_type_param_target(tt);
|
||||
break;
|
||||
case class_exts_impls:
|
||||
visit_supertype_target(tt);
|
||||
break;
|
||||
case class_type_param_bnds:
|
||||
case meth_type_param_bnds:
|
||||
visit_typeparam_bound_target(tt);
|
||||
break;
|
||||
case field:
|
||||
case meth_ret_type:
|
||||
case meth_receiver:
|
||||
visit_empty_target(tt);
|
||||
break;
|
||||
case meth_formal_param:
|
||||
visit_methodformalparam_target(tt);
|
||||
break;
|
||||
case throws_type:
|
||||
visit_throws_target(tt);
|
||||
break;
|
||||
case local_var:
|
||||
case resource_var:
|
||||
visit_localvar_target(tt);
|
||||
break;
|
||||
case exception_param:
|
||||
visit_catch_target(tt);
|
||||
break;
|
||||
case type_test:
|
||||
case obj_creat:
|
||||
case constr_ref_receiver:
|
||||
case meth_ref_receiver:
|
||||
visit_offset_target(tt);
|
||||
break;
|
||||
|
||||
case cast:
|
||||
case constr_invoc_typearg:
|
||||
case meth_invoc_typearg:
|
||||
case constr_ref_typearg:
|
||||
case meth_ref_typearg:
|
||||
|
||||
visit_typearg_target(tt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void visit_type_param_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_supertype_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_typeparam_bound_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_empty_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_methodformalparam_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_throws_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_localvar_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_catch_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_offset_target(TargetType tt) {
|
||||
}
|
||||
|
||||
public void visit_typearg_target(TargetType tt) {
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* TypeAnnotationData Methods */
|
||||
public TypeAnnotationUtils() {
|
||||
}
|
||||
|
||||
public static TargetType getTargetType(int tt_index) {
|
||||
if (tt_index < 0 || tt_index > TargetType.maxTag) {
|
||||
return null;
|
||||
}
|
||||
return TargetTypeList.get(tt_index);
|
||||
}
|
||||
|
||||
static public TargetType getTargetType(String tt) {
|
||||
TargetType retval = TargetTypeHash.get(tt);
|
||||
|
||||
if (retval.name().equals("UNUSED")) {
|
||||
retval = null;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
}
|
|
@ -52,7 +52,6 @@ jasm.error.fatal_error=fatal error
|
|||
jasm.error.fatal_exception=fatal exception
|
||||
|
||||
|
||||
#err.not.implemented=Sorry, {0} not implemented.
|
||||
# Scanner:
|
||||
err.invalid.escape.char=Invalid escape character.
|
||||
err.eof.in.comment=Comment not terminated at end of input.
|
||||
|
@ -62,14 +61,12 @@ err.overflow=Numeric overflow.
|
|||
err.float.format=Invalid floating point format.
|
||||
err.eof.in.string=String not terminated at end of input.
|
||||
err.newline.in.string=String not terminated at end of line.
|
||||
#err.invalid.char.constant=Invalid character constant.
|
||||
err.funny.char=Invalid character in input.
|
||||
err.unbalanced.paren=Unbalanced parentheses.
|
||||
# Parser:
|
||||
err.package.repeated=Package statement repeated.
|
||||
warn.intf.repeated=Interface {0} repeated.
|
||||
warn.exc.repeated=Exception repeated in throws clause.
|
||||
warn.signature.repeated=Signature attribute repeated in the record's component.
|
||||
warn.record.repeated=Record attribute repeated.
|
||||
err.multiple.inherit=Multiple inheritance is not supported.
|
||||
err.toplevel.expected=Class, module or interface declaration expected.
|
||||
|
@ -77,17 +74,22 @@ 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.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.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.grouped.component.expected=Either an annotation or a record component expected.
|
||||
warn.no.components.in.record.attribute=Record should have at least one component.
|
||||
err.one.of.two.token.expected=Either #{0} or #{1} token expected.
|
||||
|
||||
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}).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009, 2017, 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
|
||||
|
@ -662,7 +662,7 @@ class Jcoder {
|
|||
/**
|
||||
* Parse an Jcoder file.
|
||||
*/
|
||||
ArrayList<ByteBuffer> parseFile() {
|
||||
void parseFile() {
|
||||
env.traceln("PARSER");
|
||||
context.init();
|
||||
try {
|
||||
|
@ -690,7 +690,7 @@ class Jcoder {
|
|||
|
||||
case EOF:
|
||||
// The end
|
||||
return Classes;
|
||||
return;
|
||||
|
||||
default:
|
||||
env.traceln("unexpected token=" + scanner.token.toString());
|
||||
|
@ -708,9 +708,7 @@ class Jcoder {
|
|||
}
|
||||
} catch (IOException e) {
|
||||
env.error(scanner.pos, "io.exception", env.getInputFileName());
|
||||
return Classes;
|
||||
}
|
||||
return Classes;
|
||||
} //end parseFile
|
||||
|
||||
/*---------------------------------------------*/
|
||||
|
|
|
@ -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
|
||||
|
@ -41,9 +41,7 @@ public class Main extends Tool {
|
|||
|
||||
public Main(PrintWriter out, String programName) {
|
||||
super(out, programName);
|
||||
printCannotReadMsg = (fname) -> {
|
||||
error(i18n.getString("jcoder.error.cannot_read", fname));
|
||||
};
|
||||
printCannotReadMsg = (fname) -> error(i18n.getString("jcoder.error.cannot_read", fname));
|
||||
}
|
||||
|
||||
public Main(PrintStream out, String program) {
|
||||
|
@ -192,7 +190,7 @@ public class Main extends Tool {
|
|||
/**
|
||||
* main program
|
||||
*/
|
||||
public static void main(String argv[]) {
|
||||
public static void main(String[] argv) {
|
||||
Main compiler = new Main(new PrintWriter(System.out), "jcoder");
|
||||
System.exit(compiler.compile(argv) ? 0 : 1);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -100,7 +100,7 @@ public class Scanner {
|
|||
* A growable character buffer.
|
||||
*/
|
||||
private int count;
|
||||
private char buffer[] = new char[32];
|
||||
private char[] buffer = new char[32];
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/**
|
||||
|
@ -170,7 +170,7 @@ public class Scanner {
|
|||
|
||||
private void putc(int ch) {
|
||||
if (count == buffer.length) {
|
||||
char newBuffer[] = new char[buffer.length * 2];
|
||||
char[] newBuffer = new char[buffer.length * 2];
|
||||
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
|
||||
buffer = newBuffer;
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ public class Scanner {
|
|||
}
|
||||
|
||||
private String bufferString() {
|
||||
char buf[] = new char[count];
|
||||
char[] buf = new char[count];
|
||||
System.arraycopy(buffer, 0, buf, 0, count);
|
||||
return new String(buf);
|
||||
}
|
||||
|
@ -472,16 +472,6 @@ numberLoop:
|
|||
}
|
||||
return n;
|
||||
}
|
||||
// Utf8 "\%pattern\%NonNegativePoint\%(II)";
|
||||
case '%':
|
||||
readCh();
|
||||
return '%';
|
||||
case '@':
|
||||
readCh();
|
||||
return '@';
|
||||
case ':':
|
||||
readCh();
|
||||
return ':';
|
||||
case 'r':
|
||||
readCh();
|
||||
return '\r';
|
||||
|
@ -540,11 +530,7 @@ loop:
|
|||
case '\\': {
|
||||
int c = scanEscapeChar();
|
||||
if (c >= 0) {
|
||||
char ch = (char)c;
|
||||
if ( ch == '@' || ch == ':' || ch == '\\') {
|
||||
putc('\\');
|
||||
}
|
||||
putc(ch);
|
||||
putc((char)c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -618,16 +604,12 @@ loop:
|
|||
for (;;) {
|
||||
putc(ch);
|
||||
readCh();
|
||||
//env.traceln(" read:"+(char)ch);
|
||||
if ((ch == '/') || (ch == '.') || (ch == '-')) {
|
||||
//env.traceln(" =>compound");
|
||||
compound = true;
|
||||
continue;
|
||||
} else if (!Character.isJavaIdentifierPart((char) ch)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
//env.traceln(" end:"+(char)ch);
|
||||
stringValue = bufferString();
|
||||
if (compound) {
|
||||
token = Token.IDENT;
|
||||
|
@ -646,8 +628,6 @@ loop:
|
|||
token = Token.INTVAL;
|
||||
intSize = 1;
|
||||
longValue = intValue;
|
||||
} else {
|
||||
//env.traceln(" ^^^^^^^^ Massive Weirdness here: Can't locate IDENT '" + stringValue + "'. ^^^^^^^^^^");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
package org.openjdk.asmtools.jdec;
|
||||
|
||||
import org.openjdk.asmtools.common.Module;
|
||||
import org.openjdk.asmtools.asmutils.StringUtils;
|
||||
import org.openjdk.asmtools.jasm.Modifiers;
|
||||
import org.openjdk.asmtools.jcoder.JcodTokens;
|
||||
import org.openjdk.asmtools.util.I18NResourceBundle;
|
||||
|
@ -36,7 +37,7 @@ import java.io.PrintWriter;
|
|||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
import static org.openjdk.asmtools.jasm.Tables.AnnotElemType.AE_UNKNOWN;
|
||||
import static org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
|
||||
import static org.openjdk.asmtools.jasm.TypeAnnotationTypes.*;
|
||||
|
||||
/**
|
||||
* Class data of the Java Decoder
|
||||
|
@ -285,30 +286,7 @@ class ClassData {
|
|||
switch (tg) {
|
||||
case CONSTANT_UTF8: {
|
||||
tagstr = "Utf8";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s = (String) cpool[i];
|
||||
sb.append('\"');
|
||||
for (int k = 0; k < s.length(); k++) {
|
||||
char c = s.charAt(k);
|
||||
switch (c) {
|
||||
case '\t':
|
||||
sb.append('\\').append('t');
|
||||
break;
|
||||
case '\n':
|
||||
sb.append('\\').append('n');
|
||||
break;
|
||||
case '\r':
|
||||
sb.append('\\').append('r');
|
||||
break;
|
||||
case '\"':
|
||||
sb.append('\\').append('\"');
|
||||
break;
|
||||
default:
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
valstr = sb.append('\"').toString();
|
||||
valstr = StringUtils.Utf8ToString((String) cpool[i]);
|
||||
}
|
||||
break;
|
||||
case CONSTANT_FLOAT:
|
||||
|
@ -438,11 +416,13 @@ class ClassData {
|
|||
*/
|
||||
private void decodeTargetTypeAndRefInfo(DataInputStream in) throws IOException {
|
||||
int tt = in.readUnsignedByte(); // [4.7.20] annotations[], type_annotation { u1 target_type; ...}
|
||||
TargetType target_type = targetTypeEnum(tt);
|
||||
InfoType info_type = target_type.infoType();
|
||||
out_println(toHex(tt, 1) + "; // target_type: " + target_type.parseKey());
|
||||
|
||||
switch (info_type) {
|
||||
ETargetType targetType = ETargetType.getTargetType(tt);
|
||||
if( targetType == null ) {
|
||||
throw new Error("Type annotation: invalid target_type(u1) " + tt);
|
||||
}
|
||||
ETargetInfo targetInfo = targetType.targetInfo();
|
||||
out_println(toHex(tt, 1) + "; // target_type: " + targetType.parseKey());
|
||||
switch (targetInfo) {
|
||||
case TYPEPARAM: //[3.3.1] meth_type_param, class_type_param:
|
||||
out_println(toHex(in.readUnsignedByte(), 1) + "; // param_index");
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -27,21 +27,22 @@ import java.io.IOException;
|
|||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class AnnotationData {
|
||||
public class AnnotationData {
|
||||
/*-------------------------------------------------------- */
|
||||
/* AnnotData Fields */
|
||||
|
||||
private boolean invisible = false;
|
||||
private int type_cpx = 0; //an index into the constant pool indicating the annotation type for this annotation.
|
||||
private ArrayList<AnnotElem> array = new ArrayList<>();
|
||||
|
||||
private ClassData cls;
|
||||
protected String visAnnotToken = "@+";
|
||||
protected String invAnnotToken = "@-";
|
||||
protected String dataName = "AnnotationData";
|
||||
private boolean invisible = false;
|
||||
private int type_cpx = 0; //an index into the constant pool indicating the annotation type for this annotation.
|
||||
private ArrayList<AnnotationElement> array = new ArrayList<>();
|
||||
private ClassData cls;
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
public AnnotationData(boolean invisible, ClassData cls) {
|
||||
|
@ -51,12 +52,12 @@ public class AnnotationData {
|
|||
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
type_cpx = in.readShort();
|
||||
TraceUtils.traceln(" " + dataName + ": name[" + type_cpx + "]=" + cls.pool.getString(type_cpx));
|
||||
int elemValueLength = in.readShort();
|
||||
TraceUtils.traceln(" " + dataName + ": " + cls.pool.getString(type_cpx) + "num_elems: " + elemValueLength);
|
||||
TraceUtils.traceln(3, format(" %s: name[%d]=%s", dataName, type_cpx, cls.pool.getString(type_cpx)),
|
||||
format(" %s: %s num_elems: %d", dataName, cls.pool.getString(type_cpx), elemValueLength));
|
||||
for (int evc = 0; evc < elemValueLength; evc++) {
|
||||
AnnotElem elem = new AnnotElem(cls);
|
||||
TraceUtils.traceln(" " + dataName + ": " + cls.pool.getString(type_cpx) + " reading [" + evc + "]");
|
||||
AnnotationElement elem = new AnnotationElement(cls);
|
||||
TraceUtils.traceln(3, format(" %s: %s reading [%d]", dataName, cls.pool.getString(type_cpx), evc));
|
||||
elem.read(in, invisible);
|
||||
array.add(elem);
|
||||
}
|
||||
|
@ -64,7 +65,7 @@ public class AnnotationData {
|
|||
|
||||
public void print(PrintWriter out, String tab) {
|
||||
printHeader(out, tab);
|
||||
printBody(out, tab);
|
||||
printBody(out, "");
|
||||
}
|
||||
|
||||
protected void printHeader(PrintWriter out, String tab) {
|
||||
|
@ -92,16 +93,14 @@ public class AnnotationData {
|
|||
// For a standard annotation, print out brackets,
|
||||
// and list the name/value pairs.
|
||||
out.print(" { ");
|
||||
|
||||
int i = 0;
|
||||
for (AnnotElem elem : array) {
|
||||
for (AnnotationElement elem : array) {
|
||||
elem.print(out, tab);
|
||||
|
||||
if (i++ < array.size() - 1) {
|
||||
out.print(", ");
|
||||
}
|
||||
}
|
||||
out.print(tab + "}");
|
||||
out.print(" }");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -126,7 +125,7 @@ public class AnnotationData {
|
|||
sb.append(" { ");
|
||||
|
||||
int i = 0;
|
||||
for (AnnotElem elem : array) {
|
||||
for (AnnotationElement elem : array) {
|
||||
sb.append(elem.toString());
|
||||
|
||||
if (i++ < array.size() - 1) {
|
||||
|
@ -143,5 +142,5 @@ public class AnnotationData {
|
|||
protected void _toString(StringBuilder sb) {
|
||||
// sub-classes override this
|
||||
}
|
||||
} // end AnnotData
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -22,6 +22,7 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -29,13 +30,9 @@ import java.io.PrintWriter;
|
|||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
*
|
||||
* AnnotElem
|
||||
*
|
||||
* Base class of all AnnotationElement entries
|
||||
*
|
||||
*/
|
||||
public class AnnotElem {
|
||||
public class AnnotationElement {
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -46,8 +43,6 @@ public class AnnotElem {
|
|||
*/
|
||||
public static class AnnotValue {
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* AnnotElem Fields */
|
||||
/**
|
||||
* tag the descriptor for the constant
|
||||
*/
|
||||
|
@ -55,7 +50,6 @@ public class AnnotElem {
|
|||
|
||||
// internal references
|
||||
protected ClassData cls;
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
public AnnotValue(AnnotElemType tagval, ClassData cls) {
|
||||
tag = tagval;
|
||||
|
@ -67,7 +61,7 @@ public class AnnotElem {
|
|||
}
|
||||
|
||||
public void print(PrintWriter out, String tab) {
|
||||
out.print(tag.val() + "\t");
|
||||
out.print(tag.val() + " ");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -362,7 +356,7 @@ public class AnnotElem {
|
|||
protected ClassData cls;
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
public AnnotElem(ClassData cls) {
|
||||
public AnnotationElement(ClassData cls) {
|
||||
this.cls = cls;
|
||||
}
|
||||
|
||||
|
@ -376,9 +370,8 @@ public class AnnotElem {
|
|||
*/
|
||||
public void read(DataInputStream in, boolean invisible) throws IOException {
|
||||
name_cpx = in.readShort();
|
||||
TraceUtils.traceln(" AnnotElem: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx));
|
||||
value = readValue(in, cls, invisible);
|
||||
TraceUtils.traceln(" " + value.toString());
|
||||
TraceUtils.traceln(format(" AnnotElem: name[%d]=%s value=%s", name_cpx, cls.pool.getString(name_cpx), value.toString()));
|
||||
}
|
||||
|
||||
public String stringVal() {
|
||||
|
@ -387,7 +380,7 @@ public class AnnotElem {
|
|||
|
||||
public void print(PrintWriter out, String tab) {
|
||||
out.print(stringVal() + " = ");
|
||||
value.print(out, tab);
|
||||
value.print(out, "");
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -23,20 +23,28 @@
|
|||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import org.openjdk.asmtools.jasm.Tables;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class AttrData {
|
||||
|
||||
int name_cpx;
|
||||
byte data[];
|
||||
ClassData cls;
|
||||
public AttrData(ClassData cls) {
|
||||
this.cls = cls;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* attributeTag
|
||||
*
|
||||
* returns either -1 (not found), or the hashed integer tag key.
|
||||
*
|
||||
* <p>
|
||||
* returns either -1 (not found), or the hashed integer tag tag.
|
||||
*/
|
||||
public static int attributeTag(String tagname) {
|
||||
int intgr = Tables.attrtagValue(tagname);
|
||||
|
@ -48,22 +56,10 @@ public class AttrData {
|
|||
return intgr;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* AttrData Fields */
|
||||
int name_cpx;
|
||||
byte data[];
|
||||
ClassData cls;
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
public AttrData(ClassData cls) {
|
||||
this.cls = cls;
|
||||
}
|
||||
|
||||
public void read(int name_cpx, int attrlen, DataInputStream in) throws IOException {
|
||||
this.name_cpx = name_cpx;
|
||||
data = new byte[attrlen];
|
||||
TraceUtils.traceln(" AttrData:#" + name_cpx + " len=" + attrlen);
|
||||
TraceUtils.traceln(format("AttrData:#%d len=%d", name_cpx, attrlen));
|
||||
in.readFully(data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -32,9 +32,7 @@ import java.util.ArrayList;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public class BootstrapMethodData {
|
||||
/*-------------------------------------------------------- */
|
||||
/* BootstrapMethodData Fields */
|
||||
public class BootstrapMethodData extends Indenter {
|
||||
|
||||
int bsm_index;
|
||||
ArrayList<Integer> bsm_args_indexes;
|
||||
|
@ -43,7 +41,6 @@ public class BootstrapMethodData {
|
|||
private Options options = Options.OptionObject();
|
||||
private ClassData cls;
|
||||
private PrintWriter out;
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
public BootstrapMethodData(ClassData cls) {
|
||||
this.cls = cls;
|
||||
|
@ -53,6 +50,7 @@ public class BootstrapMethodData {
|
|||
|
||||
/*========================================================*/
|
||||
/* Read Methods */
|
||||
|
||||
/**
|
||||
*
|
||||
* read
|
||||
|
@ -75,7 +73,7 @@ public class BootstrapMethodData {
|
|||
/*========================================================*/
|
||||
/* Print Methods */
|
||||
public void print() throws IOException {
|
||||
out.print(JasmTokens.Token.BOOTSTRAPMETHOD.parsekey() + " #" + bsm_index);
|
||||
out.print(getIndentString() + JasmTokens.Token.BOOTSTRAPMETHOD.parseKey() + " #" + bsm_index);
|
||||
for (int i = 0; i < bsm_args_indexes.size(); i++) {
|
||||
out.print(" #" + bsm_args_indexes.get(i));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -27,10 +27,14 @@ import org.openjdk.asmtools.common.Tool;
|
|||
import org.openjdk.asmtools.jasm.Modifiers;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jasm.RuntimeConstants.*;
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
|
||||
|
@ -98,9 +102,9 @@ public class ClassData extends MemberData {
|
|||
// other parsing fields
|
||||
protected PrintWriter out;
|
||||
protected String pkgPrefix = "";
|
||||
private int pkgPrefixLen = 0;
|
||||
private TextLines source = null;
|
||||
private static final String initialTab = ""; //The number of elements in the buffer
|
||||
// source file data
|
||||
private TextLines sourceLines = null;
|
||||
private Path classFile = null;
|
||||
|
||||
public ClassData(PrintWriter out, Tool tool) {
|
||||
this.out = out;
|
||||
|
@ -112,11 +116,17 @@ public class ClassData extends MemberData {
|
|||
}
|
||||
|
||||
public void read(File in) throws IOException {
|
||||
read(new DataInputStream(new FileInputStream(in)));
|
||||
try ( DataInputStream dis = new DataInputStream(new FileInputStream(in))){
|
||||
read(dis);
|
||||
}
|
||||
classFile = in.toPath();
|
||||
}
|
||||
|
||||
public void read(String in) throws IOException {
|
||||
read(new DataInputStream(new FileInputStream(in)));
|
||||
try ( DataInputStream dis = new DataInputStream(new FileInputStream(in))){
|
||||
read(dis);
|
||||
}
|
||||
classFile = Paths.get(in);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +242,7 @@ public class ClassData extends MemberData {
|
|||
/**
|
||||
* Read and resolve the class data
|
||||
*/
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
private void read(DataInputStream in) throws IOException {
|
||||
// Read the header
|
||||
int magic = in.readInt();
|
||||
if (magic != JAVA_MAGIC) {
|
||||
|
@ -261,22 +271,20 @@ public class ClassData extends MemberData {
|
|||
|
||||
// Read the attributes
|
||||
readAttributes(in);
|
||||
|
||||
TraceUtils.traceln("");
|
||||
TraceUtils.traceln("Reading is done-----------------------------------------------------");
|
||||
TraceUtils.traceln("");
|
||||
//
|
||||
TraceUtils.traceln("", "<< Reading is done >>", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and resolve the attribute data
|
||||
*/
|
||||
public String getSrcLine(int lnum) {
|
||||
if (source == null) {
|
||||
if (sourceLines == null) {
|
||||
return null; // impossible call
|
||||
}
|
||||
String line;
|
||||
try {
|
||||
line = source.getLine(lnum);
|
||||
line = sourceLines.getLine(lnum);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
line = "Line number " + lnum + " is out of bounds";
|
||||
}
|
||||
|
@ -286,23 +294,24 @@ public class ClassData extends MemberData {
|
|||
private <T extends AnnotationData> void printAnnotations(List<T> annotations) {
|
||||
if (annotations != null) {
|
||||
for (T ad : annotations) {
|
||||
ad.print(out, initialTab);
|
||||
ad.print(out, "");
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print() throws IOException {
|
||||
int k, l;
|
||||
String className = "";
|
||||
String sourceName = "";
|
||||
String sourceName = null;
|
||||
if( isModuleUnit() ) {
|
||||
// Print the Annotations
|
||||
printAnnotations(visibleAnnotations);
|
||||
printAnnotations(invisibleAnnotations);
|
||||
} else {
|
||||
className = pool.getClassName(this_cpx);
|
||||
pkgPrefixLen = className.lastIndexOf("/") + 1;
|
||||
int pkgPrefixLen = className.lastIndexOf("/") + 1;
|
||||
// Write the header
|
||||
// package-info compilation unit
|
||||
if (className.endsWith("package-info")) {
|
||||
|
@ -415,11 +424,10 @@ printSugar:
|
|||
out.println("{");
|
||||
|
||||
if ((options.contains(Options.PR.SRC)) && (source_cpx != 0)) {
|
||||
sourceName = String.format(" compiled from %s" +
|
||||
"" , pool.getName(source_cpx));
|
||||
try {
|
||||
source = new TextLines(sourceName);
|
||||
} catch (IOException ignored) {}
|
||||
sourceName = pool.getString(source_cpx);
|
||||
if (sourceName != null) {
|
||||
sourceLines = new TextLines(classFile.getParent(), sourceName);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the constant pool
|
||||
|
@ -430,23 +438,13 @@ printSugar:
|
|||
if ( !isModuleUnit() ) {
|
||||
|
||||
// Print the fields
|
||||
if (fields != null && !fields.isEmpty()) {
|
||||
for (FieldData curf : fields) {
|
||||
curf.print();
|
||||
}
|
||||
}
|
||||
printMemberDataList(fields);
|
||||
|
||||
// Print the methods
|
||||
if (methods != null && !methods.isEmpty()) {
|
||||
for (MethodData curm : methods) {
|
||||
boolean skipBlankLine = false;
|
||||
curm.print(skipBlankLine);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
printMemberDataList(methods);
|
||||
|
||||
// Print the Record (since class file 58.65535 JEP 359)
|
||||
if( record != null && !record.isEmpty()) {
|
||||
if( record != null ) {
|
||||
record.print();
|
||||
}
|
||||
|
||||
|
@ -478,11 +476,9 @@ printSugar:
|
|||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
out.println("} // end Class " + className + sourceName);
|
||||
out.println(format("} // end Class %s%s",
|
||||
className,
|
||||
sourceName != null ? " compiled from \"" + sourceName +"\"" : ""));
|
||||
} else {
|
||||
// Print module attributes
|
||||
moduleData.print();
|
||||
|
@ -505,11 +501,27 @@ printSugar:
|
|||
return moduleData != null;
|
||||
}
|
||||
|
||||
private void printMemberDataList( List<? extends MemberData> list) throws IOException {
|
||||
if( list != null ) {
|
||||
int count = list.size();
|
||||
if( count > 0 ) {
|
||||
for( int i=0; i < count; i++ ) {
|
||||
MemberData md = list.get(i);
|
||||
md.setIndent(Options.BODY_INDENT);
|
||||
if( i !=0 && md.getAnnotationsCount() > 0 )
|
||||
out.println();
|
||||
md.print();
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<IOException> getIssues() {
|
||||
return this.pool.pool.stream().
|
||||
filter(c->c!=null).
|
||||
filter(Objects::nonNull).
|
||||
filter(c->c.getIssue() != null).
|
||||
map(c->c.getIssue()).
|
||||
map(ConstantPool.Constant::getIssue).
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2018, 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
|
||||
|
@ -22,9 +22,7 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
import static org.openjdk.asmtools.jasm.OpcodeTables.*;
|
||||
import static org.openjdk.asmtools.jdis.Utils.commentString;
|
||||
import org.openjdk.asmtools.jasm.Tables;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -32,90 +30,32 @@ import java.io.PrintWriter;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.OpcodeTables.Opcode;
|
||||
import static org.openjdk.asmtools.jasm.OpcodeTables.opcode;
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
import static org.openjdk.asmtools.jasm.Tables.AttrTag.ATT_RuntimeInvisibleTypeAnnotations;
|
||||
import static org.openjdk.asmtools.jasm.Tables.AttrTag.ATT_RuntimeVisibleTypeAnnotations;
|
||||
import static org.openjdk.asmtools.jdis.Utils.commentString;
|
||||
|
||||
/**
|
||||
*
|
||||
* Code data for a code attribute in method members in a class of the Java Disassembler
|
||||
*/
|
||||
public class CodeData {
|
||||
public class CodeData extends Indenter {
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* Code Data inner classes */
|
||||
class LineNumData {
|
||||
|
||||
short start_pc, line_number;
|
||||
|
||||
public LineNumData() {
|
||||
}
|
||||
|
||||
public LineNumData(DataInputStream in) throws IOException {
|
||||
start_pc = in.readShort();
|
||||
line_number = in.readShort();
|
||||
//traceln(" line:"+start_pc+":="+line_number);
|
||||
}
|
||||
}
|
||||
|
||||
public static class LocVarData {
|
||||
|
||||
short start_pc, length, name_cpx, sig_cpx, slot;
|
||||
|
||||
public LocVarData() {
|
||||
}
|
||||
|
||||
public LocVarData(DataInputStream in) throws IOException {
|
||||
start_pc = in.readShort();
|
||||
length = in.readShort();
|
||||
name_cpx = in.readShort();
|
||||
sig_cpx = in.readShort();
|
||||
slot = in.readShort();
|
||||
// cls.traceln(" var #"+name_cpx+" start:"+start_pc
|
||||
// +" length:"+length+"sig_cpx:"+sig_cpx+" sig_cpx:"+sig_cpx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* CodeData Fields */
|
||||
/**
|
||||
* Raw byte array for the byte codes
|
||||
*/
|
||||
protected byte[] code;
|
||||
|
||||
/**
|
||||
* Limit for the stack size
|
||||
*/
|
||||
protected int max_stack;
|
||||
|
||||
/* CodeData Fields */
|
||||
/**
|
||||
* Limit for the number of local vars
|
||||
*/
|
||||
protected int max_locals;
|
||||
|
||||
/**
|
||||
* (parsed) Trap table, describes exceptions caught
|
||||
*/
|
||||
private ArrayList<TrapData> trap_table = new ArrayList<>(0); // TrapData
|
||||
|
||||
/**
|
||||
* (parsed) Line Number table, describes source lines associated with ByteCode indexes
|
||||
*/
|
||||
private ArrayList<LineNumData> lin_num_tb = new ArrayList<>(0); // LineNumData
|
||||
|
||||
/**
|
||||
* (parsed) Local Variable table, describes variable scopes associated with ByteCode
|
||||
* indexes
|
||||
*/
|
||||
private ArrayList<LocVarData> loc_var_tb = new ArrayList<>(0); // LocVarData
|
||||
|
||||
/**
|
||||
* (parsed) stack map table, describes compiler hints for stack rep, associated with
|
||||
* ByteCode indexes
|
||||
*/
|
||||
private ArrayList<StackMapData> stack_map = null;
|
||||
|
||||
/**
|
||||
* (parsed) reversed bytecode index hash, associates labels with ByteCode indexes
|
||||
*/
|
||||
private HashMap<Integer, iAtt> iattrs = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The remaining attributes of this class
|
||||
*/
|
||||
|
@ -124,15 +64,49 @@ public class CodeData {
|
|||
// internal references
|
||||
protected ClassData cls;
|
||||
protected MethodData meth;
|
||||
private PrintWriter out;
|
||||
/*-------------------------------------------------------- */
|
||||
/**
|
||||
* (parsed) Trap table, describes exceptions caught
|
||||
*/
|
||||
private ArrayList<TrapData> trap_table = new ArrayList<>(0); // TrapData
|
||||
/**
|
||||
* (parsed) Line Number table, describes source lines associated with ByteCode indexes
|
||||
*/
|
||||
private ArrayList<LineNumData> lin_num_tb = new ArrayList<>(0); // LineNumData
|
||||
/**
|
||||
* (parsed) Local Variable table, describes variable scopes associated with ByteCode
|
||||
* indexes
|
||||
*/
|
||||
private ArrayList<LocVarData> loc_var_tb = new ArrayList<>(0); // LocVarData
|
||||
/**
|
||||
* (parsed) stack map table, describes compiler hints for stack rep, associated with
|
||||
* ByteCode indexes
|
||||
*/
|
||||
private ArrayList<StackMapData> stack_map = null;
|
||||
/**
|
||||
* The visible type annotations for this method
|
||||
*/
|
||||
private ArrayList<TypeAnnotationData> visibleTypeAnnotations;
|
||||
/**
|
||||
* The invisible type annotations for this method
|
||||
*/
|
||||
private ArrayList<TypeAnnotationData> invisibleTypeAnnotations;
|
||||
|
||||
/**
|
||||
* (parsed) reversed bytecode index hash, associates labels with ByteCode indexes
|
||||
*/
|
||||
private HashMap<Integer, iAtt> iattrs = new HashMap<>();
|
||||
private PrintWriter out;
|
||||
public CodeData(MethodData meth) {
|
||||
this.meth = meth;
|
||||
this.cls = meth.cls;
|
||||
this.out = cls.out;
|
||||
}
|
||||
|
||||
private static int align(int n) {
|
||||
return (n + 3) & ~3;
|
||||
}
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
private int getbyte(int pc) {
|
||||
return code[pc];
|
||||
}
|
||||
|
@ -153,10 +127,6 @@ public class CodeData {
|
|||
return (getShort(pc) << 16) | (getShort(pc + 2) & 0xFFFF);
|
||||
}
|
||||
|
||||
private static int align(int n) {
|
||||
return (n + 3) & ~3;
|
||||
}
|
||||
|
||||
protected iAtt get_iAtt(int pc) {
|
||||
Integer PC = pc;
|
||||
iAtt res = iattrs.get(PC);
|
||||
|
@ -167,14 +137,13 @@ public class CodeData {
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*========================================================*/
|
||||
/* Read Methods */
|
||||
private void readLineNumTable(DataInputStream in) throws IOException {
|
||||
int len = in.readInt(); // attr_length
|
||||
int numlines = in.readUnsignedShort();
|
||||
lin_num_tb = new ArrayList<>(numlines);
|
||||
TraceUtils.traceln(" CodeAttr: LineNumTable[" + numlines + "] len=" + len);
|
||||
TraceUtils.traceln(3, "CodeAttr: LineNumTable[" + numlines + "] len=" + len);
|
||||
for (int l = 0; l < numlines; l++) {
|
||||
lin_num_tb.add(new LineNumData(in));
|
||||
}
|
||||
|
@ -184,7 +153,7 @@ public class CodeData {
|
|||
int len = in.readInt(); // attr_length
|
||||
int numlines = in.readUnsignedShort();
|
||||
loc_var_tb = new ArrayList<>(numlines);
|
||||
TraceUtils.traceln(" CodeAttr: LocalVariableTable[" + numlines + "] len=" + len);
|
||||
TraceUtils.traceln(3, "CodeAttr: LocalVariableTable[" + numlines + "] len=" + len);
|
||||
for (int l = 0; l < numlines; l++) {
|
||||
loc_var_tb.add(new LocVarData(in));
|
||||
}
|
||||
|
@ -192,7 +161,7 @@ public class CodeData {
|
|||
|
||||
private void readTrapTable(DataInputStream in) throws IOException {
|
||||
int trap_table_len = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" CodeAttr: TrapTable[" + trap_table_len + "]");
|
||||
TraceUtils.traceln(3, "CodeAttr: TrapTable[" + trap_table_len + "]");
|
||||
trap_table = new ArrayList<>(trap_table_len);
|
||||
for (int l = 0; l < trap_table_len; l++) {
|
||||
trap_table.add(new TrapData(in, l));
|
||||
|
@ -202,7 +171,7 @@ public class CodeData {
|
|||
private void readStackMap(DataInputStream in) throws IOException {
|
||||
int len = in.readInt(); // attr_length
|
||||
int stack_map_len = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" CodeAttr: Stack_Map: attrlen=" + len + " num=" + stack_map_len);
|
||||
TraceUtils.traceln(3, "CodeAttr: Stack_Map: attrlen=" + len + " num=" + stack_map_len);
|
||||
stack_map = new ArrayList<>(stack_map_len);
|
||||
StackMapData.prevFramePC = 0;
|
||||
for (int k = 0; k < stack_map_len; k++) {
|
||||
|
@ -213,7 +182,7 @@ public class CodeData {
|
|||
private void readStackMapTable(DataInputStream in) throws IOException {
|
||||
int len = in.readInt(); // attr_length
|
||||
int stack_map_len = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" CodeAttr: Stack_Map_Table: attrlen=" + len + " num=" + stack_map_len);
|
||||
TraceUtils.traceln(3, "CodeAttr: Stack_Map_Table: attrlen=" + len + " num=" + stack_map_len);
|
||||
stack_map = new ArrayList<>(stack_map_len);
|
||||
StackMapData.prevFramePC = 0;
|
||||
for (int k = 0; k < stack_map_len; k++) {
|
||||
|
@ -221,13 +190,33 @@ public class CodeData {
|
|||
}
|
||||
}
|
||||
|
||||
private void readTypeAnnotations(DataInputStream in, boolean isInvisible) throws IOException {
|
||||
int attrLength = in.readInt();
|
||||
// Read Type Annotations Attr
|
||||
int count = in.readShort();
|
||||
ArrayList<TypeAnnotationData> tannots = new ArrayList<>(count);
|
||||
TraceUtils.traceln(3, "CodeAttr: Runtime" +
|
||||
(isInvisible ? "Inv" : "V") +
|
||||
"isibleTypeAnnotation: attrlen=" +
|
||||
attrLength + " num=" + count);
|
||||
for (int index = 0; index < count; index++) {
|
||||
TraceUtils.traceln("\t\t\t[" + index +"]:");
|
||||
TypeAnnotationData tannot = new TypeAnnotationData(isInvisible, cls);
|
||||
tannot.read(in);
|
||||
tannots.add(tannot);
|
||||
}
|
||||
if (isInvisible) {
|
||||
invisibleTypeAnnotations = tannots;
|
||||
} else {
|
||||
visibleTypeAnnotations = tannots;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* read
|
||||
*
|
||||
* <p>
|
||||
* read and resolve the code attribute data called from MethodData. precondition:
|
||||
* NumFields has already been read from the stream.
|
||||
*
|
||||
*/
|
||||
public void read(DataInputStream in, int codeattrlen) throws IOException {
|
||||
|
||||
|
@ -235,7 +224,10 @@ public class CodeData {
|
|||
max_stack = in.readUnsignedShort();
|
||||
max_locals = in.readUnsignedShort();
|
||||
int codelen = in.readInt();
|
||||
TraceUtils.traceln(" CodeAttr: Codelen=" + codelen + " fulllen=" + codeattrlen + " max_stack=" + max_stack + " max_locals=" + max_locals);
|
||||
TraceUtils.traceln(3, "CodeAttr: Codelen=" + codelen +
|
||||
" fulllen=" + codeattrlen +
|
||||
" max_stack=" + max_stack +
|
||||
" max_locals=" + max_locals);
|
||||
|
||||
// read the raw code bytes
|
||||
code = new byte[codelen];
|
||||
|
@ -246,14 +238,14 @@ public class CodeData {
|
|||
|
||||
// Read any attributes of the Code Attribute
|
||||
int nattr = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" CodeAttr: add.attr:" + nattr);
|
||||
TraceUtils.traceln(3, "CodeAttr: add.attr:" + nattr);
|
||||
for (int k = 0; k < nattr; k++) {
|
||||
int name_cpx = in.readUnsignedShort();
|
||||
// verify the Attrs name
|
||||
ConstantPool.Constant name_const = cls.pool.getConst(name_cpx);
|
||||
if (name_const != null && name_const.tag == ConstantPool.TAG.CONSTANT_UTF8) {
|
||||
String attrname = cls.pool.getString(name_cpx);
|
||||
TraceUtils.traceln(" CodeAttr: attr: " + attrname);
|
||||
TraceUtils.traceln(3, "CodeAttr: attr: " + attrname);
|
||||
// process the attr
|
||||
AttrTag attrtag = attrtag(attrname);
|
||||
switch (attrtag) {
|
||||
|
@ -269,6 +261,10 @@ public class CodeData {
|
|||
case ATT_StackMapTable:
|
||||
readStackMapTable(in);
|
||||
break;
|
||||
case ATT_RuntimeVisibleTypeAnnotations:
|
||||
case ATT_RuntimeInvisibleTypeAnnotations:
|
||||
readTypeAnnotations(in, attrtag == ATT_RuntimeInvisibleTypeAnnotations);
|
||||
break;
|
||||
default:
|
||||
AttrData attr = new AttrData(cls);
|
||||
int attrlen = in.readInt(); // attr_length
|
||||
|
@ -350,7 +346,7 @@ public class CodeData {
|
|||
} // end checkForLabelRef
|
||||
|
||||
private void loadLabelTable() {
|
||||
for (int pc = 0; pc < code.length;) {
|
||||
for (int pc = 0; pc < code.length; ) {
|
||||
pc = pc + checkForLabelRef(pc);
|
||||
}
|
||||
}
|
||||
|
@ -382,7 +378,6 @@ public class CodeData {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*========================================================*/
|
||||
/* Print Methods */
|
||||
private void PrintConstant(int cpx) {
|
||||
|
@ -447,7 +442,7 @@ public class CodeData {
|
|||
return 1;
|
||||
}
|
||||
out.print(opcode.parsekey());
|
||||
// TraceUtils.traceln("****** [CodeData.printInstr]: got an '" + opcode.parsekey() + "' [" + opc + "] instruction ****** ");
|
||||
// TraceUtils.traceln("****** [CodeData.printInstr]: got an '" + opcode.parseKey() + "' [" + opc + "] instruction ****** ");
|
||||
switch (opcode) {
|
||||
case opc_aload:
|
||||
case opc_astore:
|
||||
|
@ -525,7 +520,19 @@ public class CodeData {
|
|||
out.print(" BOGUS TYPE:" + type);
|
||||
}
|
||||
return 2;
|
||||
case opc_anewarray: {
|
||||
case opc_anewarray:
|
||||
case opc_ldc_w:
|
||||
case opc_ldc2_w:
|
||||
case opc_instanceof:
|
||||
case opc_checkcast:
|
||||
case opc_new:
|
||||
case opc_putstatic:
|
||||
case opc_getstatic:
|
||||
case opc_putfield:
|
||||
case opc_getfield:
|
||||
case opc_invokevirtual:
|
||||
case opc_invokespecial:
|
||||
case opc_invokestatic: {
|
||||
int index = getUShort(pc + 1);
|
||||
if (pr_cpx) {
|
||||
out.print("\t#" + index + "; //");
|
||||
|
@ -547,28 +554,8 @@ public class CodeData {
|
|||
PrintConstant(index);
|
||||
return 2;
|
||||
}
|
||||
case opc_ldc_w:
|
||||
case opc_ldc2_w:
|
||||
case opc_instanceof:
|
||||
case opc_checkcast:
|
||||
case opc_new:
|
||||
case opc_putstatic:
|
||||
case opc_getstatic:
|
||||
case opc_putfield:
|
||||
case opc_getfield:
|
||||
case opc_invokevirtual:
|
||||
case opc_invokespecial:
|
||||
case opc_invokestatic: {
|
||||
int index = getUShort(pc + 1);
|
||||
if (pr_cpx) {
|
||||
out.print("\t#" + index + "; //");
|
||||
}
|
||||
PrintConstant(index);
|
||||
return 3;
|
||||
}
|
||||
case opc_invokeinterface: {
|
||||
int index = getUShort(pc + 1), nargs = getUbyte(pc + 3);
|
||||
// getUbyte(pc + 4); // reserved byte
|
||||
if (pr_cpx) {
|
||||
out.print("\t#" + index + ", " + nargs + "; //");
|
||||
PrintConstant(index);
|
||||
|
@ -579,6 +566,7 @@ public class CodeData {
|
|||
return 5;
|
||||
}
|
||||
case opc_invokedynamic: { // JSR-292
|
||||
cls.pool.setPrintTAG(true);
|
||||
int index = getUShort(pc + 1);
|
||||
// getUbyte(pc + 3); // reserved byte
|
||||
// getUbyte(pc + 4); // reserved byte
|
||||
|
@ -588,6 +576,7 @@ public class CodeData {
|
|||
} else {
|
||||
PrintConstant(index);
|
||||
}
|
||||
cls.pool.setPrintTAG(false);
|
||||
return 5;
|
||||
}
|
||||
case opc_multianewarray: {
|
||||
|
@ -631,11 +620,9 @@ public class CodeData {
|
|||
} // end printInstr
|
||||
|
||||
/**
|
||||
*
|
||||
* print
|
||||
*
|
||||
* <p>
|
||||
* prints the code data to the current output stream. called from MethodData.
|
||||
*
|
||||
*/
|
||||
public void print() throws IOException {
|
||||
if (!lin_num_tb.isEmpty()) {
|
||||
|
@ -658,10 +645,10 @@ public class CodeData {
|
|||
// Need to print ParamAnnotations here.
|
||||
meth.printPAnnotations();
|
||||
|
||||
out.println("{");
|
||||
out.println(getIndentString() + "{");
|
||||
|
||||
iAtt iatt = iattrs.get(0);
|
||||
for (int pc = 0; pc < code.length;) {
|
||||
for (int pc = 0; pc < code.length; ) {
|
||||
if (iatt != null) {
|
||||
iatt.printBegins(); // equ. print("\t");
|
||||
} else {
|
||||
|
@ -693,7 +680,47 @@ public class CodeData {
|
|||
iatt.printStackMap();
|
||||
out.println();
|
||||
}
|
||||
out.println("}");
|
||||
// print TypeAnnotations
|
||||
if (visibleTypeAnnotations != null) {
|
||||
out.println();
|
||||
for (TypeAnnotationData visad : visibleTypeAnnotations) {
|
||||
visad.print(out, getIndentString());
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
if (invisibleTypeAnnotations != null) {
|
||||
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
|
||||
invisad.print(out, getIndentString());
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
// end of code
|
||||
out.println(getIndentString() + "}");
|
||||
}
|
||||
|
||||
|
||||
public static class LocVarData {
|
||||
|
||||
short start_pc, length, name_cpx, sig_cpx, slot;
|
||||
|
||||
public LocVarData(DataInputStream in) throws IOException {
|
||||
start_pc = in.readShort();
|
||||
length = in.readShort();
|
||||
name_cpx = in.readShort();
|
||||
sig_cpx = in.readShort();
|
||||
slot = in.readShort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Code Data inner classes */
|
||||
class LineNumData {
|
||||
|
||||
short start_pc, line_number;
|
||||
|
||||
public LineNumData(DataInputStream in) throws IOException {
|
||||
start_pc = in.readShort();
|
||||
line_number = in.readShort();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import org.openjdk.asmtools.asmutils.HexUtils;
|
||||
import org.openjdk.asmtools.asmutils.StringUtils;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -31,8 +32,8 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.Hashtable;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jdis.Utils.commentString;
|
||||
|
||||
/**
|
||||
|
@ -46,6 +47,16 @@ public class ConstantPool {
|
|||
private static final Hashtable<Byte, TAG> taghash = new Hashtable<>();
|
||||
private static final Hashtable<Byte, SUBTAG> subtaghash = new Hashtable<>();
|
||||
|
||||
private boolean printTAG = false;
|
||||
|
||||
public void setPrintTAG(boolean value) {
|
||||
this.printTAG = value;
|
||||
}
|
||||
|
||||
public String getPrintedTAG(TAG tag) {
|
||||
return (this.printTAG) ? tag.tagname + " " : "" ;
|
||||
}
|
||||
|
||||
class Indent {
|
||||
private int length, offset, step;
|
||||
|
||||
|
@ -77,7 +88,7 @@ public class ConstantPool {
|
|||
* A Tag descriptor of constants in the constant pool
|
||||
*
|
||||
*/
|
||||
static public enum TAG {
|
||||
public enum TAG {
|
||||
CONSTANT_UTF8 ((byte) 1, "Asciz", "CONSTANT_UTF8"),
|
||||
CONSTANT_UNICODE ((byte) 2, "unicorn", "CONSTANT_UNICODE"),
|
||||
CONSTANT_INTEGER ((byte) 3, "int", "CONSTANT_INTEGER"),
|
||||
|
@ -105,7 +116,6 @@ public class ConstantPool {
|
|||
value = val;
|
||||
tagname = tgname;
|
||||
printval = print;
|
||||
// taghash.put(new Byte(val), this);
|
||||
}
|
||||
|
||||
public byte value() {
|
||||
|
@ -124,6 +134,7 @@ public class ConstantPool {
|
|||
public String toString() {
|
||||
return "<" + tagname + "> ";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -276,41 +287,7 @@ public class ConstantPool {
|
|||
|
||||
@Override
|
||||
public String stringVal() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s = value;
|
||||
sb.append('\"');
|
||||
for (int k = 0; k < s.length(); k++) {
|
||||
char c = s.charAt(k);
|
||||
switch (c) {
|
||||
case '\t':
|
||||
sb.append('\\').append('t');
|
||||
break;
|
||||
case '\n':
|
||||
sb.append('\\').append('n');
|
||||
break;
|
||||
case '\r':
|
||||
sb.append('\\').append('r');
|
||||
break;
|
||||
case '\b':
|
||||
sb.append('\\').append('b');
|
||||
break;
|
||||
case '\f':
|
||||
sb.append('\\').append('f');
|
||||
break;
|
||||
case '\"':
|
||||
sb.append('\\').append('\"');
|
||||
break;
|
||||
case '\'':
|
||||
sb.append('\\').append('\'');
|
||||
break;
|
||||
case '\\':
|
||||
sb.append('\\').append('\\');
|
||||
break;
|
||||
default:
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.append('\"').toString();
|
||||
return StringUtils.Utf8ToString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -532,6 +509,7 @@ public class ConstantPool {
|
|||
class CPX2 extends Constant {
|
||||
|
||||
int value1, value2;
|
||||
|
||||
CPX2(TAG tagval, int cpx1, int cpx2) {
|
||||
super(tagval);
|
||||
this.value1 = cpx1;
|
||||
|
@ -546,7 +524,7 @@ public class ConstantPool {
|
|||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
str = getShortClassName(getClassName(value1), cd.pkgPrefix) + "." + StringValue(value2);
|
||||
str = getPrintedTAG(tag) + getShortClassName(getClassName(value1), cd.pkgPrefix) + "." + StringValue(value2);
|
||||
break;
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
str = getName(value1) + ":" + StringValue(value2);
|
||||
|
@ -946,7 +924,7 @@ public class ConstantPool {
|
|||
* getShortClassName
|
||||
*
|
||||
* shortens a class name (if the class is in the given package). works with a CP index
|
||||
* to a ConstantClasss.
|
||||
* to a ConstantClass.
|
||||
*
|
||||
*/
|
||||
public String getShortClassName(int cpx, String pkgPrefix) {
|
||||
|
@ -1018,7 +996,7 @@ public class ConstantPool {
|
|||
* a tag descriptor in the beginning.
|
||||
*
|
||||
*/
|
||||
String ConstantStrValue(int cpx) {
|
||||
public String ConstantStrValue(int cpx) {
|
||||
if (cpx == 0) {
|
||||
return "#0";
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -22,13 +22,16 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import org.openjdk.asmtools.jasm.JasmTokens;
|
||||
import org.openjdk.asmtools.jasm.Modifiers;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jasm.Tables.AttrTag;
|
||||
import static org.openjdk.asmtools.jasm.Tables.CF_Context;
|
||||
import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
|
||||
|
||||
/**
|
||||
* Field data for field members in a class of the Java Disassembler
|
||||
|
@ -37,15 +40,11 @@ public class FieldData extends MemberData {
|
|||
|
||||
// CP index to the field name
|
||||
protected int name_cpx;
|
||||
|
||||
// CP index to the field type
|
||||
protected int sig_cpx;
|
||||
|
||||
// CP index to the field value
|
||||
protected int type_cpx;
|
||||
// CP index to the field value
|
||||
protected int value_cpx = 0;
|
||||
|
||||
public static final String initialTab = "";
|
||||
|
||||
public FieldData(ClassData cls) {
|
||||
super(cls);
|
||||
memberType = "FieldData";
|
||||
|
@ -56,9 +55,16 @@ public class FieldData extends MemberData {
|
|||
// Read the Attributes
|
||||
boolean handled = true;
|
||||
switch (attrtag) {
|
||||
case ATT_Signature:
|
||||
if( signature != null ) {
|
||||
traceln("Record attribute: more than one attribute Signature are in component.attribute_info_attributes[attribute_count]");
|
||||
traceln("Last one will be used.");
|
||||
}
|
||||
signature = new SignatureData(cls).read(in, attrlen);
|
||||
break;
|
||||
case ATT_ConstantValue:
|
||||
if (attrlen != 2) {
|
||||
throw new ClassFormatError("invalid ConstantValue attr length");
|
||||
throw new ClassFormatError(format("%s: Invalid attribute length #%d", AttrTag.ATT_ConstantValue.printval(), attrlen));
|
||||
}
|
||||
value_cpx = in.readUnsignedShort();
|
||||
break;
|
||||
|
@ -77,71 +83,44 @@ public class FieldData extends MemberData {
|
|||
// read the Fields CP indexes
|
||||
access = in.readUnsignedShort();
|
||||
name_cpx = in.readUnsignedShort();
|
||||
sig_cpx = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" FieldData: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
|
||||
+ " sig[" + sig_cpx + "]=" + cls.pool.getString(sig_cpx));
|
||||
|
||||
type_cpx = in.readUnsignedShort();
|
||||
// Read the attributes
|
||||
readAttributes(in);
|
||||
//
|
||||
TraceUtils.traceln(2,
|
||||
format("FieldData: name[%d]=%s type[%d]=%s%s",
|
||||
name_cpx, cls.pool.getString(name_cpx),
|
||||
type_cpx, cls.pool.getString(type_cpx),
|
||||
signature != null ? signature : ""));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prints the field data to the current output stream. called from ClassData.
|
||||
*/
|
||||
@Override
|
||||
public void print() throws IOException {
|
||||
// Print annotations first
|
||||
// Print the Annotations
|
||||
if (visibleAnnotations != null) {
|
||||
out.println();
|
||||
for (AnnotationData visad : visibleAnnotations) {
|
||||
visad.print(out, initialTab);
|
||||
}
|
||||
}
|
||||
if (invisibleAnnotations != null) {
|
||||
out.println();
|
||||
for (AnnotationData invisad : invisibleAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
}
|
||||
}
|
||||
super.printAnnotations(getIndentString());
|
||||
|
||||
if (visibleTypeAnnotations != null) {
|
||||
out.println();
|
||||
for (TypeAnnotationData visad : visibleTypeAnnotations) {
|
||||
visad.print(out, initialTab);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
if (invisibleTypeAnnotations != null) {
|
||||
out.println();
|
||||
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
StringBuilder bodyPrefix = new StringBuilder(getIndentString()).append(Modifiers.accessString(access, CF_Context.CTX_FIELD));
|
||||
StringBuilder tailPrefix = new StringBuilder();
|
||||
|
||||
boolean pr_cpx = options.contains(Options.PR.CPX);
|
||||
out.print(Modifiers.accessString(access, CF_Context.CTX_FIELD));
|
||||
if (isSynthetic) {
|
||||
out.print("synthetic ");
|
||||
bodyPrefix.append(JasmTokens.Token.SYNTHETIC.parseKey()).append(' ');
|
||||
}
|
||||
if (isDeprecated) {
|
||||
out.print("deprecated ");
|
||||
}
|
||||
out.print("Field ");
|
||||
if (pr_cpx) {
|
||||
out.print("#" + name_cpx + ":#" + sig_cpx);
|
||||
} else {
|
||||
out.print(cls.pool.getName(name_cpx) + ":" + cls.pool.getName(sig_cpx));
|
||||
bodyPrefix.append(JasmTokens.Token.DEPRECATED.parseKey()).append(' ');
|
||||
}
|
||||
|
||||
// field
|
||||
bodyPrefix.append(JasmTokens.Token.FIELDREF.parseKey()).append(' ');
|
||||
|
||||
if (value_cpx != 0) {
|
||||
out.print("\t= ");
|
||||
cls.pool.PrintConstant(cls.out, value_cpx);
|
||||
}
|
||||
if (pr_cpx) {
|
||||
out.println(";\t // " + cls.pool.getName(name_cpx) + ":" + cls.pool.getName(sig_cpx));
|
||||
} else {
|
||||
out.println(";");
|
||||
tailPrefix.append("\t= ").append(cls.pool.ConstantStrValue(value_cpx));
|
||||
}
|
||||
|
||||
printVar(bodyPrefix, tailPrefix,name_cpx, type_cpx);
|
||||
}
|
||||
} // end FieldData
|
||||
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public class Indenter {
|
||||
|
||||
private int indentLength;
|
||||
|
||||
public Indenter(int indentLength) {
|
||||
this.indentLength = indentLength;
|
||||
}
|
||||
|
||||
public Indenter() {
|
||||
this.indentLength = Options.BODY_INDENT;
|
||||
}
|
||||
/**
|
||||
* Returns current indentation length.
|
||||
*
|
||||
* @return current indentation length.
|
||||
*/
|
||||
public int indent() {
|
||||
return indentLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases indentation length.
|
||||
*
|
||||
* @param indentLength new indent length
|
||||
*
|
||||
* @throws IllegalArgumentException if indentLength is negative.
|
||||
*/
|
||||
public Indenter setIndent(int indentLength) {
|
||||
if (indentLength < 0) {
|
||||
throw new IllegalArgumentException("indent length can't be negative");
|
||||
}
|
||||
this.indentLength = indentLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases indentation length.
|
||||
*
|
||||
* @param increase length to increase by.
|
||||
*
|
||||
* @throws IllegalArgumentException if increase is negative.
|
||||
*/
|
||||
public Indenter increaseIndent(int increase) {
|
||||
if (increase < 0) {
|
||||
throw new IllegalArgumentException("indent length can't be negative");
|
||||
}
|
||||
setIndent(indent() + increase);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decreases indentation length.
|
||||
*
|
||||
* @param decrease length to decrease by
|
||||
*
|
||||
* @throws IllegalArgumentException if decrease is negative, or if decrease is greater than
|
||||
* {@link #indent() current indentation length}.
|
||||
*/
|
||||
public Indenter decreaseIndent(int decrease) {
|
||||
if (decrease < 0) {
|
||||
throw new IllegalArgumentException("decrease can't be negative");
|
||||
}
|
||||
setIndent(indent() - decrease);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates indent string based on current indent size.
|
||||
*/
|
||||
public String getIndentString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < indent(); i++) {
|
||||
sb.append(' ');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -30,11 +30,7 @@ import java.io.IOException;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
class InnerClassData {
|
||||
/*-------------------------------------------------------- */
|
||||
/* InnerClassData Fields */
|
||||
|
||||
private Options options = Options.OptionObject();
|
||||
class InnerClassData extends Indenter {
|
||||
|
||||
ClassData cls;
|
||||
int inner_class_info_index;
|
||||
|
@ -55,8 +51,8 @@ class InnerClassData {
|
|||
} // end read
|
||||
|
||||
public void print() throws IOException {
|
||||
boolean pr_cpx = options.contains(Options.PR.CPX);
|
||||
cls.out.print(Modifiers.accessString(access, CF_Context.CTX_INNERCLASS));
|
||||
boolean pr_cpx = Options.OptionObject().contains(Options.PR.CPX);
|
||||
cls.out.print(getIndentString() + Modifiers.accessString(access, CF_Context.CTX_INNERCLASS));
|
||||
cls.out.print("InnerClass ");
|
||||
if (pr_cpx) {
|
||||
if (inner_name_index != 0) {
|
||||
|
|
|
@ -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
|
||||
|
@ -41,7 +41,7 @@ public class Main extends Tool {
|
|||
public static final I18NResourceBundle i18n
|
||||
= I18NResourceBundle.getBundleForClass(Main.class);
|
||||
|
||||
public Main(PrintWriter out, PrintWriter err, String programName) {
|
||||
public Main(PrintWriter out, PrintWriter err, String programName) {
|
||||
super(out, err, programName);
|
||||
// tool specific initialization
|
||||
options = Options.OptionObject();
|
||||
|
@ -66,7 +66,7 @@ public class Main extends Tool {
|
|||
/**
|
||||
* Run the disassembler
|
||||
*/
|
||||
public synchronized boolean disasm(String argv[]) {
|
||||
public synchronized boolean disasm(String argv[]) {
|
||||
ArrayList<String> files = new ArrayList<>();
|
||||
|
||||
// Parse arguments
|
||||
|
@ -105,27 +105,23 @@ public class Main extends Tool {
|
|||
return false;
|
||||
}
|
||||
|
||||
for (String inpname : files) {
|
||||
if (inpname == null) {
|
||||
for (String fname : files) {
|
||||
if (fname == null) {
|
||||
continue;
|
||||
} // cross out by CompilerChoice.compile
|
||||
try {
|
||||
DataInputStream dataInputStream = getDataInputStream(inpname);
|
||||
if( dataInputStream == null )
|
||||
return false;
|
||||
ClassData cc = new ClassData(out, this);
|
||||
cc.read(dataInputStream);
|
||||
cc.read(fname);
|
||||
cc.print();
|
||||
dataInputStream.close();
|
||||
continue;
|
||||
} catch (Error ee) {
|
||||
if (DebugFlag.getAsBoolean())
|
||||
ee.printStackTrace();
|
||||
error(i18n.getString("jdis.error.fatal_error", inpname));
|
||||
error(i18n.getString("jdis.error.fatal_error", fname));
|
||||
} catch (Exception ee) {
|
||||
if (DebugFlag.getAsBoolean())
|
||||
ee.printStackTrace();
|
||||
error(i18n.getString("jdis.error.fatal_exception", inpname));
|
||||
error(i18n.getString("jdis.error.fatal_exception", fname));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -28,20 +28,23 @@ import java.io.IOException;
|
|||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Base class for ClassData, MethodData, FieldData and RecordData(JEP 360)
|
||||
*/
|
||||
public class MemberData {
|
||||
public abstract class MemberData extends Indenter {
|
||||
|
||||
/**
|
||||
* access flags (modifiers)
|
||||
*/
|
||||
// access flags (modifiers)
|
||||
protected int access;
|
||||
|
||||
// flags
|
||||
protected boolean isSynthetic = false;
|
||||
protected boolean isDeprecated = false;
|
||||
|
||||
// Signature can be located in ClassFile, field_info, method_info, and component_info
|
||||
protected SignatureData signature;
|
||||
|
||||
/**
|
||||
* The visible annotations for this class, member( field or method) or record component
|
||||
*/
|
||||
|
@ -68,12 +71,14 @@ public class MemberData {
|
|||
protected ArrayList<AttrData> attrs;
|
||||
|
||||
// internal references
|
||||
protected Options options = Options.OptionObject();
|
||||
protected final Options options = Options.OptionObject();
|
||||
protected final boolean pr_cpx = options.contains(Options.PR.CPX);;
|
||||
protected ClassData cls;
|
||||
protected PrintWriter out;
|
||||
protected String memberType = "";
|
||||
|
||||
public MemberData(ClassData cls) {
|
||||
this();
|
||||
init(cls);
|
||||
}
|
||||
|
||||
|
@ -83,26 +88,85 @@ public class MemberData {
|
|||
public void init(ClassData cls) {
|
||||
this.out = cls.out;
|
||||
this.cls = cls;
|
||||
this.options = cls.options;
|
||||
}
|
||||
|
||||
protected boolean handleAttributes(DataInputStream in, Tables.AttrTag attrtag, int attrlen) throws IOException {
|
||||
// sub-classes override
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract void print() throws IOException;
|
||||
|
||||
final protected int getAnnotationsCount() {
|
||||
return ((visibleAnnotations == null) ? 0 : visibleAnnotations.size()) +
|
||||
((invisibleAnnotations == null) ? 0 : invisibleAnnotations.size()) +
|
||||
((visibleTypeAnnotations == null) ? 0 : visibleTypeAnnotations.size()) +
|
||||
((invisibleTypeAnnotations == null) ? 0 : invisibleTypeAnnotations.size());
|
||||
|
||||
}
|
||||
|
||||
final protected void printAnnotations(String initialTab) {
|
||||
if( getAnnotationsCount() > 0 ) {
|
||||
if (visibleAnnotations != null) {
|
||||
for (AnnotationData visad : visibleAnnotations) {
|
||||
// out.print(initialTab);
|
||||
visad.print(out, initialTab);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
if (invisibleAnnotations != null) {
|
||||
for (AnnotationData invisad : invisibleAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleTypeAnnotations != null) {
|
||||
for (TypeAnnotationData visad : visibleTypeAnnotations) {
|
||||
visad.print(out, initialTab);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
if (invisibleTypeAnnotations != null) {
|
||||
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void printVar(StringBuilder bodyPrefix, StringBuilder tailPrefix, int name_cpx, int type_cpx) {
|
||||
if( pr_cpx ) {
|
||||
bodyPrefix.append('#').append(name_cpx).append(":#").append(type_cpx);
|
||||
tailPrefix.append(";\t // ").append(cls.pool.getName(name_cpx)).append(':').append(cls.pool.getName(type_cpx));
|
||||
|
||||
} else {
|
||||
bodyPrefix.append(cls.pool.getName(name_cpx)).append(':').append(cls.pool.getName(type_cpx));
|
||||
tailPrefix.append(';');
|
||||
}
|
||||
|
||||
if (signature != null) {
|
||||
signature.print(bodyPrefix.append(':').toString(), tailPrefix.append( pr_cpx ? ":" : "" ).toString());
|
||||
} else {
|
||||
out.print(bodyPrefix);
|
||||
out.print(tailPrefix);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
protected void readAttributes(DataInputStream in) throws IOException {
|
||||
// Read the Attributes
|
||||
int natt = in.readUnsignedShort();
|
||||
TraceUtils.traceln("natt=" + natt);
|
||||
attrs = new ArrayList<>(natt);
|
||||
TraceUtils.traceln(memberType + " - Attributes: " + natt);
|
||||
TraceUtils.traceln(format("%s - Attributes[%d]", memberType , natt));
|
||||
AttrData attr;
|
||||
for (int k = 0; k < natt; k++) {
|
||||
int name_cpx = in.readUnsignedShort();
|
||||
attr = new AttrData(cls);
|
||||
attrs.add(attr);
|
||||
String attr_name = cls.pool.getString(name_cpx);
|
||||
TraceUtils.traceln(" " + memberType + ": #" + k + " name[" + name_cpx + "]=" + attr_name);
|
||||
TraceUtils.traceln(format(" #%d name[%d]=\"%s\"", k, name_cpx, attr_name));
|
||||
Tables.AttrTag tag = Tables.attrtag(attr_name);
|
||||
int attrlen = in.readInt();
|
||||
switch (tag) {
|
||||
|
@ -168,5 +232,4 @@ public class MemberData {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -37,11 +37,6 @@ import static org.openjdk.asmtools.jasm.Tables.CF_Context;
|
|||
*/
|
||||
public class MethodData extends MemberData {
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
/* MethodData Fields */
|
||||
|
||||
public static final String initialTab = "";
|
||||
/*-------------------------------------------------------- */
|
||||
/**
|
||||
* CP index to the method name
|
||||
*/
|
||||
|
@ -67,7 +62,7 @@ public class MethodData extends MemberData {
|
|||
/**
|
||||
* The invisible parameter annotations for this method
|
||||
*/
|
||||
protected AnnotElem.AnnotValue defaultAnnotation;
|
||||
protected AnnotationElement.AnnotValue defaultAnnotation;
|
||||
/**
|
||||
* The code data for this method. May be null
|
||||
*/
|
||||
|
@ -103,17 +98,17 @@ public class MethodData extends MemberData {
|
|||
break;
|
||||
case ATT_RuntimeVisibleParameterAnnotations:
|
||||
case ATT_RuntimeInvisibleParameterAnnotations:
|
||||
boolean invisible1 = (attrtag == AttrTag.ATT_RuntimeInvisibleParameterAnnotations);
|
||||
ParameterAnnotationData pannots = new ParameterAnnotationData(cls, invisible1);
|
||||
boolean invisible = (attrtag == AttrTag.ATT_RuntimeInvisibleParameterAnnotations);
|
||||
ParameterAnnotationData pannots = new ParameterAnnotationData(cls, invisible);
|
||||
pannots.read(in);
|
||||
if (invisible1) {
|
||||
if (invisible) {
|
||||
invisibleParameterAnnotations = pannots;
|
||||
} else {
|
||||
visibleParameterAnnotations = pannots;
|
||||
}
|
||||
break;
|
||||
case ATT_AnnotationDefault:
|
||||
defaultAnnotation = AnnotElem.readValue(in, cls, false);
|
||||
defaultAnnotation = AnnotationElement.readValue(in, cls, false);
|
||||
break;
|
||||
default:
|
||||
handled = false;
|
||||
|
@ -132,9 +127,8 @@ public class MethodData extends MemberData {
|
|||
access = in.readUnsignedShort(); // & MM_METHOD; // Q
|
||||
name_cpx = in.readUnsignedShort();
|
||||
sig_cpx = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" MethodData: {modifiers}: " + Modifiers.toString(access, CF_Context.CTX_METHOD));
|
||||
TraceUtils.traceln(" MethodData: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
|
||||
+ " sig[" + sig_cpx + "]=" + cls.pool.getString(sig_cpx));
|
||||
TraceUtils.traceln(2,"MethodData: {modifiers}: " + Modifiers.toString(access, CF_Context.CTX_METHOD),
|
||||
" MethodData: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx) + " sig[" + sig_cpx + "]=" + cls.pool.getString(sig_cpx));
|
||||
// Read the attributes
|
||||
readAttributes(in);
|
||||
}
|
||||
|
@ -142,11 +136,11 @@ public class MethodData extends MemberData {
|
|||
private void readExceptions(DataInputStream in) throws IOException {
|
||||
// this is not really a CodeAttr attribute, it's part of the CodeAttr
|
||||
int exc_table_len = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" ExceptionsAttr[" + exc_table_len + "]");
|
||||
TraceUtils.traceln(3,"ExceptionsAttr[" + exc_table_len + "]");
|
||||
exc_table = new int[exc_table_len];
|
||||
for (int l = 0; l < exc_table_len; l++) {
|
||||
int exc = in.readShort();
|
||||
TraceUtils.traceln(" throws:#" + exc);
|
||||
TraceUtils.traceln(4,"throws:#" + exc);
|
||||
exc_table[l] = exc;
|
||||
}
|
||||
}
|
||||
|
@ -154,12 +148,12 @@ public class MethodData extends MemberData {
|
|||
private void readMethodParameters(DataInputStream in) throws IOException {
|
||||
// this is not really a CodeAttr attribute, it's part of the CodeAttr
|
||||
int num_params = in.readUnsignedByte();
|
||||
TraceUtils.traceln(" MethodParametersAttr[" + num_params + "]");
|
||||
TraceUtils.traceln(3,"MethodParametersAttr[" + num_params + "]");
|
||||
paramNames = new ArrayList<>(num_params);
|
||||
for (int l = 0; l < num_params; l++) {
|
||||
short pname_cpx = (short) in.readUnsignedShort();
|
||||
int paccess = in.readUnsignedShort();
|
||||
TraceUtils.traceln(" P[" + l + "] ={ name[" + pname_cpx + "]: " + cls.pool.getString(pname_cpx)
|
||||
TraceUtils.traceln(4,"P[" + l + "] ={ name[" + pname_cpx + "]: " + cls.pool.getString(pname_cpx)
|
||||
+ " modifiers [" + paccess + "]: " + Modifiers.toString(paccess, CF_Context.CTX_METHOD) + "}");
|
||||
paramNames.add(l, new ParamNameData(pname_cpx, paccess));
|
||||
}
|
||||
|
@ -218,12 +212,12 @@ public class MethodData extends MemberData {
|
|||
|
||||
// Print the Parameter name
|
||||
if (pname != null) {
|
||||
out.print(Token.PARAM_NAME.parsekey());
|
||||
out.print(Token.LBRACE.parsekey());
|
||||
out.print(Token.PARAM_NAME.parseKey());
|
||||
out.print(Token.LBRACE.parseKey());
|
||||
out.print(cls.pool.getString(pname.name_cpx));
|
||||
out.print(" ");
|
||||
out.print(Modifiers.toString(pname.access, CF_Context.CTX_METHOD));
|
||||
out.print(Token.RBRACE.parsekey());
|
||||
out.print(Token.RBRACE.parseKey());
|
||||
out.print(" ");
|
||||
}
|
||||
|
||||
|
@ -233,7 +227,7 @@ public class MethodData extends MemberData {
|
|||
if (!firstTime) {
|
||||
out.print("\t ");
|
||||
}
|
||||
annot.print(out, initialTab);
|
||||
annot.print(out, getIndentString());
|
||||
// out.println();
|
||||
firstTime = false;
|
||||
}
|
||||
|
@ -245,7 +239,7 @@ public class MethodData extends MemberData {
|
|||
if (!firstTime) {
|
||||
out.print("\t ");
|
||||
}
|
||||
annot.print(out, initialTab);
|
||||
annot.print(out, getIndentString());
|
||||
// out.println();
|
||||
firstTime = false;
|
||||
}
|
||||
|
@ -253,68 +247,30 @@ public class MethodData extends MemberData {
|
|||
|
||||
// Reset the line, if there were parameters
|
||||
if ((pname != null) || !nullAnnots) {
|
||||
out.println("");
|
||||
out.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*========================================================*/
|
||||
/* Print Methods */
|
||||
|
||||
/**
|
||||
* Prints the method data to the current output stream. called from ClassData.
|
||||
*/
|
||||
public void print(boolean skipBlankLine) throws IOException {
|
||||
// Print the Annotations
|
||||
if (visibleAnnotations != null) {
|
||||
out.println();
|
||||
for (AnnotationData visad : visibleAnnotations) {
|
||||
visad.print(out, initialTab);
|
||||
out.println();
|
||||
skipBlankLine = true;
|
||||
}
|
||||
}
|
||||
if (invisibleAnnotations != null) {
|
||||
out.println();
|
||||
for (AnnotationData invisad : invisibleAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
out.println();
|
||||
skipBlankLine = true;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void print() throws IOException {
|
||||
|
||||
if (visibleTypeAnnotations != null) {
|
||||
out.println();
|
||||
for (TypeAnnotationData visad : visibleTypeAnnotations) {
|
||||
visad.print(out, initialTab);
|
||||
out.println();
|
||||
skipBlankLine = true;
|
||||
}
|
||||
}
|
||||
if (invisibleTypeAnnotations != null) {
|
||||
out.println();
|
||||
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
out.println();
|
||||
skipBlankLine = true;
|
||||
}
|
||||
}
|
||||
printAnnotations(getIndentString());
|
||||
|
||||
boolean pr_cpx = options.contains(Options.PR.CPX);
|
||||
out.print(getIndentString() + Modifiers.accessString(access, CF_Context.CTX_METHOD));
|
||||
|
||||
if (!skipBlankLine) {
|
||||
out.println();
|
||||
}
|
||||
out.print(Modifiers.accessString(access, CF_Context.CTX_METHOD));
|
||||
if (isSynthetic) {
|
||||
out.print(Token.SYNTHETIC.parsekey() + " ");
|
||||
out.print(Token.SYNTHETIC.parseKey() + " ");
|
||||
}
|
||||
if (isDeprecated) {
|
||||
out.print(Token.DEPRECATED.parsekey() + " ");
|
||||
out.print(Token.DEPRECATED.parseKey() + " ");
|
||||
}
|
||||
out.print(Token.METHODREF.parsekey() + " ");
|
||||
out.print(Token.METHODREF.parseKey() + " ");
|
||||
|
||||
if (pr_cpx) {
|
||||
// print the CPX method descriptor
|
||||
|
@ -328,7 +284,7 @@ public class MethodData extends MemberData {
|
|||
// followed by default annotation
|
||||
if (defaultAnnotation != null) {
|
||||
out.print(" default { ");
|
||||
defaultAnnotation.print(out, initialTab);
|
||||
defaultAnnotation.print(out, getIndentString());
|
||||
out.print(" }" + ((code == null && exc_table == null) ? ";" : " "));
|
||||
}
|
||||
// followed by exception table
|
||||
|
@ -337,6 +293,9 @@ public class MethodData extends MemberData {
|
|||
if (code != null) {
|
||||
code.print();
|
||||
} else {
|
||||
if( exc_table != null ) {
|
||||
out.print(';');
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
@ -366,6 +325,5 @@ public class MethodData extends MemberData {
|
|||
this.access = access;
|
||||
this.name_cpx = name;
|
||||
}
|
||||
|
||||
}
|
||||
} // end MethodData
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
|
@ -62,7 +62,7 @@ public class ModuleData {
|
|||
return "N/A";
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder(module.getModuleFlags());
|
||||
sb.append(JasmTokens.Token.MODULE.parsekey()).append(" ");
|
||||
sb.append(JasmTokens.Token.MODULE.parseKey()).append(" ");
|
||||
sb.append(module.getModuleName());
|
||||
if (module.getModuleVersion() != null)
|
||||
sb.append("// @").append(module.getModuleVersion());
|
||||
|
@ -195,7 +195,7 @@ public class ModuleData {
|
|||
}
|
||||
|
||||
/* Print Methods */
|
||||
public void print() throws IOException {
|
||||
public void print() {
|
||||
if (module != null)
|
||||
out.println(module.toString());
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -33,7 +33,7 @@ import java.io.IOException;
|
|||
* <p>
|
||||
* since class file 55.0 (JEP 181)
|
||||
*/
|
||||
public class NestHostData {
|
||||
public class NestHostData extends Indenter{
|
||||
ClassData cls;
|
||||
int host_class_index;
|
||||
private Options options = Options.OptionObject();
|
||||
|
@ -52,7 +52,7 @@ public class NestHostData {
|
|||
|
||||
public void print() {
|
||||
boolean pr_cpx = options.contains(Options.PR.CPX);
|
||||
cls.out.print(JasmTokens.Token.NESTHOST.parsekey() + " ");
|
||||
cls.out.print(getIndentString() + JasmTokens.Token.NESTHOST.parseKey() + " ");
|
||||
if (pr_cpx) {
|
||||
cls.out.print("#" + host_class_index + "; //");
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ import java.io.IOException;
|
|||
*/
|
||||
public class NestMembersData extends ClassArrayData {
|
||||
public NestMembersData(ClassData cls) {
|
||||
super(cls, JasmTokens.Token.NESTMEMBERS.parsekey());
|
||||
super(cls, JasmTokens.Token.NESTMEMBERS.parseKey());
|
||||
}
|
||||
|
||||
public NestMembersData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
|
||||
|
|
|
@ -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
|
||||
|
@ -29,11 +29,12 @@ import java.util.EnumSet;
|
|||
*/
|
||||
public class Options {
|
||||
|
||||
/*-------------------------------------------------------- */
|
||||
public static final int BODY_INDENT = 2;
|
||||
|
||||
/* Options Fields */
|
||||
private static Options ref;
|
||||
|
||||
static public enum PR {
|
||||
public enum PR {
|
||||
|
||||
CP, // print Constant Pool
|
||||
LNT, // print Line Number table
|
||||
|
|
|
@ -40,7 +40,7 @@ import java.io.IOException;
|
|||
*/
|
||||
public class PermittedSubtypesData extends ClassArrayData {
|
||||
public PermittedSubtypesData(ClassData cls) {
|
||||
super(cls, JasmTokens.Token.PERMITTEDSUBTYPES.parsekey());
|
||||
super(cls, JasmTokens.Token.PERMITTEDSUBTYPES.parseKey());
|
||||
}
|
||||
|
||||
public PermittedSubtypesData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 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,6 +30,8 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jasm.JasmTokens.Token.*;
|
||||
import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
|
||||
|
||||
/**
|
||||
|
@ -37,11 +39,10 @@ import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
|
|||
* <p>
|
||||
* since class file 58.65535 (JEP 359)
|
||||
*/
|
||||
public class RecordData {
|
||||
public class RecordData extends Indenter {
|
||||
|
||||
|
||||
private final ClassData cls;
|
||||
private final boolean pr_cpx = Options.OptionObject().contains(Options.PR.CPX);
|
||||
private String initialTab = " ";
|
||||
private List<Component> components;
|
||||
|
||||
public RecordData(ClassData cls) {
|
||||
|
@ -62,28 +63,26 @@ public class RecordData {
|
|||
* Prints the record data to the current output stream. called from ClassData.
|
||||
*/
|
||||
public void print() throws IOException {
|
||||
int bound = components.size()-1;
|
||||
cls.out.println(JasmTokens.Token.RECORD.parsekey());
|
||||
for(int cn = 0; cn <= bound; cn++) {
|
||||
components.get(cn).print( cn == bound ? ";" : ",");
|
||||
int count = components.size();
|
||||
if (count > 0) {
|
||||
cls.out.println(getIndentString() + RECORD.parseKey() + getIndentString() + LBRACE.parseKey());
|
||||
for (int i = 0; i < count; i++) {
|
||||
Component cn = components.get(i);
|
||||
cn.setIndent(indent() * 2);
|
||||
if (i != 0 && cn.getAnnotationsCount() > 0)
|
||||
cn.out.println();
|
||||
cn.print();
|
||||
}
|
||||
cls.out.println(getIndentString() + RBRACE.parseKey());
|
||||
cls.out.println();
|
||||
}
|
||||
cls.out.println();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return components.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
private class Component extends MemberData {
|
||||
// CP index to the name
|
||||
private int name_cpx;
|
||||
// CP index to the descriptor
|
||||
private int desc_cpx;
|
||||
// Signature can be located in component_info
|
||||
private SignatureData signature;
|
||||
//
|
||||
private int countAttr = 0;
|
||||
// CP index to the type descriptor
|
||||
private int type_cpx;
|
||||
|
||||
public Component(ClassData cls) {
|
||||
super(cls);
|
||||
|
@ -115,92 +114,33 @@ public class RecordData {
|
|||
public Component read(DataInputStream in) throws IOException {
|
||||
// read the Component CP indexes
|
||||
name_cpx = in.readUnsignedShort();
|
||||
desc_cpx = in.readUnsignedShort();
|
||||
traceln(" RecordComponent: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
|
||||
+ " descriptor[" + desc_cpx + "]=" + cls.pool.getString(desc_cpx));
|
||||
type_cpx = in.readUnsignedShort();
|
||||
traceln(2, "RecordComponent: name[" + name_cpx + "]=" + cls.pool.getString(name_cpx)
|
||||
+ " descriptor[" + type_cpx + "]=" + cls.pool.getString(type_cpx));
|
||||
// Read the attributes
|
||||
readAttributes(in);
|
||||
// Calculate amount of attributes
|
||||
countAttr = (visibleAnnotations == null ? 0 : visibleAnnotations.size()) +
|
||||
(invisibleAnnotations == null ? 0 : invisibleAnnotations.size()) +
|
||||
(visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size()) +
|
||||
(invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations.size()) +
|
||||
(signature != null ? 1 : 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return countAttr == 0;
|
||||
}
|
||||
|
||||
private void printAnnotations(String endOfComponent) {
|
||||
if( signature != null ) {
|
||||
signature.print(initialTab);
|
||||
countAttr--;
|
||||
if(countAttr != 0)
|
||||
out.println();
|
||||
}
|
||||
if (visibleAnnotations != null) {
|
||||
for (AnnotationData visad : visibleAnnotations) {
|
||||
// out.print(initialTab);
|
||||
visad.print(out, initialTab);
|
||||
countAttr--;
|
||||
if(countAttr != 0)
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
if (invisibleAnnotations != null) {
|
||||
for (AnnotationData invisad : invisibleAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
countAttr--;
|
||||
if(countAttr != 0)
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
if (visibleTypeAnnotations != null) {
|
||||
for (TypeAnnotationData visad : visibleTypeAnnotations) {
|
||||
visad.print(out, initialTab);
|
||||
countAttr--;
|
||||
if(countAttr != 0)
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
if (invisibleTypeAnnotations != null) {
|
||||
for (TypeAnnotationData invisad : invisibleTypeAnnotations) {
|
||||
invisad.print(out, initialTab);
|
||||
countAttr--;
|
||||
if(countAttr != 0)
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
out.println(endOfComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the component data to the current output stream. called from RecordData.
|
||||
*/
|
||||
public void print(String endOfComponent) throws IOException {
|
||||
|
||||
out.print(initialTab);
|
||||
public void print() throws IOException {
|
||||
// print component's attributes
|
||||
super.printAnnotations(getIndentString());
|
||||
// print component
|
||||
StringBuilder bodyPrefix = new StringBuilder(getIndentString());
|
||||
StringBuilder tailPrefix = new StringBuilder();
|
||||
if (isSynthetic) {
|
||||
out.print("synthetic ");
|
||||
bodyPrefix.append(JasmTokens.Token.SYNTHETIC.parseKey()).append(' ');
|
||||
}
|
||||
if (isDeprecated) {
|
||||
out.print("deprecated ");
|
||||
bodyPrefix.append(JasmTokens.Token.DEPRECATED.parseKey()).append(' ');
|
||||
}
|
||||
// component
|
||||
bodyPrefix.append(JasmTokens.Token.COMPONENT.parseKey()).append(' ');
|
||||
|
||||
if (pr_cpx) {
|
||||
out.print("#" + name_cpx + ":#" + desc_cpx + (isEmpty() ? endOfComponent : ""));
|
||||
out.println("\t // " + cls.pool.getName(name_cpx) + ":" + cls.pool.getName(desc_cpx));
|
||||
|
||||
} else {
|
||||
out.println(cls.pool.getName(name_cpx) + ":" + cls.pool.getName(desc_cpx) + (isEmpty() ? endOfComponent : ""));
|
||||
}
|
||||
// print component's attributes
|
||||
if (!isEmpty()) {
|
||||
printAnnotations(endOfComponent);
|
||||
}
|
||||
printVar(bodyPrefix, tailPrefix,name_cpx, type_cpx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -23,9 +23,13 @@
|
|||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
|
||||
import org.openjdk.asmtools.jasm.Tables;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* The Signature attribute data
|
||||
* <p>
|
||||
|
@ -42,18 +46,23 @@ public class SignatureData {
|
|||
|
||||
public SignatureData read(DataInputStream in, int attribute_length) throws IOException, ClassFormatError {
|
||||
if (attribute_length != 2) {
|
||||
throw new ClassFormatError("ATT_Signature: Invalid attribute length");
|
||||
throw new ClassFormatError(format("%s: Invalid attribute length #%d", Tables.AttrTag.ATT_Signature.printval(), attribute_length));
|
||||
}
|
||||
signature_index = in.readUnsignedShort();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void print(String initialTab) {
|
||||
public void print(String bodyPrefix, String commentPrefix) {
|
||||
boolean pr_cpx = options.contains(Options.PR.CPX);
|
||||
if (pr_cpx) {
|
||||
cls.out.print(initialTab + "#" + signature_index + "\t\t // Signature: " + cls.pool.StringValue(signature_index));
|
||||
cls.out.print(format("%s#%d%s%s", bodyPrefix, signature_index, commentPrefix, cls.pool.StringValue(signature_index)));
|
||||
} else {
|
||||
cls.out.print(initialTab + cls.pool.StringValue(signature_index));
|
||||
cls.out.print(format("%s%s%s", bodyPrefix, cls.pool.getName(signature_index), commentPrefix));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return format("signature[%d]=%s", signature_index, cls.pool.StringValue(signature_index));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2017, 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
|
||||
|
@ -22,8 +22,11 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import org.openjdk.asmtools.asmutils.HexUtils;
|
||||
import static java.lang.String.format;
|
||||
import static org.openjdk.asmtools.jasm.Tables.*;
|
||||
import static org.openjdk.asmtools.jdis.TraceUtils.mapToHexString;
|
||||
import static org.openjdk.asmtools.jdis.TraceUtils.traceln;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
@ -32,28 +35,19 @@ import java.io.IOException;
|
|||
* represents one entry of StackMap attribute
|
||||
*/
|
||||
class StackMapData {
|
||||
/*-------------------------------------------------------- */
|
||||
/* StackMapData Fields */
|
||||
|
||||
static int prevFramePC = 0;
|
||||
boolean isStackMapTable = false;
|
||||
StackMapFrameType stackFrameType = null;
|
||||
int start_pc;
|
||||
int[] lockMap;
|
||||
int[] stackMap;
|
||||
/*-------------------------------------------------------- */
|
||||
|
||||
public StackMapData() {
|
||||
}
|
||||
|
||||
public StackMapData(CodeData code, DataInputStream in) throws IOException {
|
||||
start_pc = in.readUnsignedShort();
|
||||
TraceUtils.trace(" stack_map_entry:pc=" + start_pc);
|
||||
TraceUtils.trace(" numloc=");
|
||||
lockMap = readMap(code, in);
|
||||
TraceUtils.trace(" numstack=");
|
||||
stackMap = readMap(code, in);
|
||||
TraceUtils.traceln("");
|
||||
traceln(2, format("stack_map_entry:pc=%d numloc=%s numstack=%s",
|
||||
start_pc, mapToHexString(lockMap), mapToHexString(stackMap)));
|
||||
}
|
||||
|
||||
public StackMapData(CodeData code, DataInputStream in,
|
||||
|
@ -65,69 +59,52 @@ class StackMapData {
|
|||
switch (frame_type) {
|
||||
case SAME_FRAME:
|
||||
// type is same_frame;
|
||||
TraceUtils.trace(" same_frame=" + ft_val);
|
||||
TraceUtils.traceln("");
|
||||
offset = ft_val;
|
||||
traceln(2, format("same_frame=%d", ft_val));
|
||||
break;
|
||||
case SAME_FRAME_EX:
|
||||
// type is same_frame_extended;
|
||||
TraceUtils.trace(" same_frame_extended=" + ft_val);
|
||||
TraceUtils.traceln("");
|
||||
offset = in.readUnsignedShort();
|
||||
TraceUtils.trace(" offset=" + offset);
|
||||
traceln(2, format("same_frame_extended=%d, offset=%d", ft_val, offset));
|
||||
break;
|
||||
case SAME_LOCALS_1_STACK_ITEM_FRAME:
|
||||
// type is same_locals_1_stack_item_frame
|
||||
TraceUtils.trace(" same_locals_1_stack_item_frame=" + ft_val);
|
||||
offset = ft_val - 64;
|
||||
TraceUtils.trace(" offset=" + offset);
|
||||
// read additional single stack element
|
||||
TraceUtils.trace(" numstack=");
|
||||
stackMap = readMapElements(code, in, 1);
|
||||
TraceUtils.traceln("");
|
||||
traceln(2, format("same_locals_1_stack_item_frame=%d, offset=%d, numstack=%s",
|
||||
ft_val, offset, mapToHexString(stackMap)));
|
||||
break;
|
||||
case SAME_LOCALS_1_STACK_ITEM_EXTENDED_FRAME:
|
||||
// type is same_locals_1_stack_item_frame_extended
|
||||
TraceUtils.trace(" same_locals_1_stack_item_frame_extended=" + ft_val);
|
||||
offset = in.readUnsignedShort();
|
||||
TraceUtils.trace(" offset=" + offset);
|
||||
// read additional single stack element
|
||||
TraceUtils.trace(" numstack=");
|
||||
stackMap = readMapElements(code, in, 1);
|
||||
TraceUtils.traceln("");
|
||||
traceln(2, format("same_locals_1_stack_item_frame_extended=%d, offset=%d, numstack=%s",
|
||||
ft_val, offset, mapToHexString(stackMap)));
|
||||
break;
|
||||
case CHOP_1_FRAME:
|
||||
case CHOP_2_FRAME:
|
||||
case CHOP_3_FRAME:
|
||||
// type is chop_frame
|
||||
TraceUtils.trace(" chop_frame=" + ft_val);
|
||||
TraceUtils.traceln("");
|
||||
offset = in.readUnsignedShort();
|
||||
TraceUtils.trace(" offset=" + offset);
|
||||
traceln(2, format("chop_frame=%d offset=%d", ft_val, offset));
|
||||
break;
|
||||
case APPEND_FRAME:
|
||||
// type is append_frame
|
||||
TraceUtils.trace(" append_frame=" + ft_val);
|
||||
offset = in.readUnsignedShort();
|
||||
TraceUtils.trace(" offset=" + offset);
|
||||
// read additional locals
|
||||
TraceUtils.trace(" numloc=");
|
||||
lockMap = readMapElements(code, in, ft_val - 251);
|
||||
TraceUtils.traceln("");
|
||||
traceln(2, format("append_frame=%d offset=%d numlock=%s",
|
||||
ft_val, offset, mapToHexString(lockMap)));
|
||||
break;
|
||||
case FULL_FRAME:
|
||||
// type is full_frame
|
||||
TraceUtils.trace(" full_frame=" + ft_val);
|
||||
offset = in.readUnsignedShort();
|
||||
TraceUtils.trace(" offset=" + offset);
|
||||
TraceUtils.trace(" numloc=");
|
||||
lockMap = readMap(code, in);
|
||||
TraceUtils.trace(" numstack=");
|
||||
stackMap = readMap(code, in);
|
||||
TraceUtils.traceln("");
|
||||
traceln(2, format("full_frame=%d offset=%d numloc=%s numstack=%s",
|
||||
ft_val, offset, mapToHexString(lockMap), mapToHexString(stackMap)));
|
||||
break;
|
||||
default:
|
||||
TraceUtils.trace("incorrect frame_type argument");
|
||||
TraceUtils.traceln("incorrect frame_type argument");
|
||||
|
||||
}
|
||||
stackFrameType = frame_type;
|
||||
|
@ -137,7 +114,6 @@ class StackMapData {
|
|||
|
||||
private int[] readMap(CodeData code, DataInputStream in) throws IOException {
|
||||
int num = in.readUnsignedShort();
|
||||
TraceUtils.trace("" + num);
|
||||
return readMapElements(code, in, num);
|
||||
}
|
||||
|
||||
|
@ -148,7 +124,6 @@ class StackMapData {
|
|||
try {
|
||||
mt_val = in.readUnsignedByte();
|
||||
} catch (EOFException eofe) {
|
||||
TraceUtils.traceln("");
|
||||
throw eofe;
|
||||
}
|
||||
StackMapType maptype = stackMapType(mt_val, null);
|
||||
|
@ -164,7 +139,6 @@ class StackMapData {
|
|||
}
|
||||
}
|
||||
map[k] = mt_val;
|
||||
TraceUtils.trace(" " + HexUtils.toHex(mt_val));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2014, 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
|
||||
|
@ -22,59 +22,35 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* A container for the java sources tied to an jasm output when -sl in on
|
||||
*/
|
||||
public class TextLines {
|
||||
/*-------------------------------------------------------- */
|
||||
/* TextLines Fields */
|
||||
|
||||
byte data[];
|
||||
// ends[k] points to the end of k-th line
|
||||
ArrayList<Integer> ends = new ArrayList<>(60);
|
||||
public int length;
|
||||
/*-------------------------------------------------------- */
|
||||
final Path file;
|
||||
List<String> lines;
|
||||
|
||||
public TextLines() {
|
||||
public TextLines(Path directory, String sourceFileName) {
|
||||
file = directory == null ? Paths.get(sourceFileName) : directory.resolve(sourceFileName);
|
||||
try {
|
||||
lines = Files.readAllLines(file, StandardCharsets.UTF_8);
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
|
||||
public TextLines(String textfilename) throws IOException {
|
||||
read(textfilename);
|
||||
}
|
||||
|
||||
private void read(String textfilename) throws IOException {
|
||||
FileInputStream in = new FileInputStream(textfilename);
|
||||
data = new byte[in.available()];
|
||||
in.read(data);
|
||||
in.close();
|
||||
ends.add(-1);
|
||||
for (int k = 0; k < data.length; k++) {
|
||||
if (data[k] == '\n') {
|
||||
ends.add(k);
|
||||
public String getLine(int index) {
|
||||
if( lines != null ) {
|
||||
if (index < 1 || index >= lines.size()) {
|
||||
return String.format("Line number %d is out of range in \"%s\"", index, file);
|
||||
}
|
||||
return lines.get(index - 1);
|
||||
}
|
||||
length = ends.size(); // but if text is empty??
|
||||
}
|
||||
|
||||
public String getLine(int linenumber) {
|
||||
int entry = linenumber - 1;
|
||||
int start;
|
||||
int end;
|
||||
ends.add(entry);
|
||||
start = ends.size() + 1;
|
||||
searchEnd:
|
||||
for (end = start; end < data.length; end++) {
|
||||
switch (data[end]) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
break searchEnd;
|
||||
}
|
||||
}
|
||||
//System.out.println("start="+start+" end="+end);
|
||||
return new String(data, start, end - start);
|
||||
return String.format("\"%s\" not found", file);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -22,8 +22,17 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import org.openjdk.asmtools.asmutils.HexUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
public class TraceUtils {
|
||||
/* ====================================================== */
|
||||
|
||||
public static String prefixString = "\t";
|
||||
|
||||
public static void trace(String s) {
|
||||
if (!(Options.OptionObject()).debug()) {
|
||||
return;
|
||||
|
@ -31,10 +40,60 @@ public class TraceUtils {
|
|||
System.out.print(s);
|
||||
}
|
||||
|
||||
public static void trace(int prefixLength, String s) {
|
||||
if (!(Options.OptionObject()).debug()) {
|
||||
return;
|
||||
}
|
||||
System.out.print((prefixLength > 0) ? new String(new char[prefixLength]).replace("\0", prefixString) + s : s);
|
||||
}
|
||||
|
||||
public static void traceln(String s) {
|
||||
if (!(Options.OptionObject()).debug()) {
|
||||
return;
|
||||
}
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
public static void traceln(String... lines) {
|
||||
if (!(Options.OptionObject()).debug()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lines.length == 0) {
|
||||
System.out.println();
|
||||
} else {
|
||||
for (String s : lines) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void traceln(int prefixLength, String s) {
|
||||
if (!(Options.OptionObject()).debug()) {
|
||||
return;
|
||||
}
|
||||
System.out.println((prefixLength > 0) ? new String(new char[prefixLength]).replace("\0", prefixString) + s : s);
|
||||
}
|
||||
|
||||
public static void traceln(int prefixLength, String... lines) {
|
||||
if (!(Options.OptionObject()).debug()) {
|
||||
return;
|
||||
}
|
||||
if (lines.length == 0) {
|
||||
System.out.println();
|
||||
} else {
|
||||
String prefix = (prefixLength > 0) ? new String(new char[prefixLength]).replace("\0", prefixString) : "";
|
||||
for (String s : lines) {
|
||||
System.out.println(prefix + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String mapToHexString(int[] array) {
|
||||
return format("%d %s",
|
||||
array.length,
|
||||
Arrays.stream(array).
|
||||
mapToObj(val -> HexUtils.toHex(val)).
|
||||
collect(Collectors.joining(" ")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -22,30 +22,35 @@
|
|||
*/
|
||||
package org.openjdk.asmtools.jdis;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.TypeAnnotationUtils.*;
|
||||
import org.openjdk.asmtools.jasm.TypeAnnotationTargetInfoData;
|
||||
import org.openjdk.asmtools.jasm.TypeAnnotationTypePathData;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.openjdk.asmtools.jasm.TypeAnnotationTargetInfoData.*;
|
||||
import static org.openjdk.asmtools.jasm.TypeAnnotationTypes.*;
|
||||
|
||||
/**
|
||||
* Type Annotation data is a specific kind of AnnotationData. As well as the normal data
|
||||
* items needed to present an annotation, Type annotations require a TargetInfo
|
||||
* descriptor. This descriptor is based on a TargetType, and it optionally may contain a
|
||||
* location descriptor (when the Type is embedded in a collection).
|
||||
*
|
||||
* <p>
|
||||
* The TypeAnnotationData class is based on JDis's AnnotationData class, and contains the
|
||||
* (jasm) class for representing TargetInfo.
|
||||
*/
|
||||
public class TypeAnnotationData extends AnnotationData {
|
||||
|
||||
private TargetInfo target_info;
|
||||
private ArrayList<TypePathEntry> target_path;
|
||||
private static TTVis TT_Visitor = new TTVis();
|
||||
private TypeAnnotationTargetInfoData targetInfo;
|
||||
private TypeAnnotationTypePathData typePath;
|
||||
|
||||
public TypeAnnotationData(boolean invisible, ClassData cls) {
|
||||
super(invisible, cls);
|
||||
target_info = null;
|
||||
targetInfo = null;
|
||||
typePath = new TypeAnnotationTypePathData();
|
||||
visAnnotToken = "@T+";
|
||||
invAnnotToken = "@T-";
|
||||
dataName = "TypeAnnotationData";
|
||||
|
@ -53,42 +58,33 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
|
||||
@Override
|
||||
public void read(DataInputStream in) throws IOException {
|
||||
super.read(in);
|
||||
|
||||
// read everything related to the Type Annotation
|
||||
// target type tag
|
||||
// KTL 1/10/13 (changed short-> byte for latest spec rev)
|
||||
// int tt = (char) in.readUnsignedShort(); // cast to introduce signedness
|
||||
int tt = (byte) in.readUnsignedByte(); // cast to introduce signedness
|
||||
Integer ttInt = tt;
|
||||
TargetType ttype;
|
||||
ttype = targetTypeEnum(ttInt);
|
||||
int ttype = in.readUnsignedByte();
|
||||
ETargetType targetType = ETargetType.getTargetType(ttype);
|
||||
|
||||
if (ttype == null) {
|
||||
if (targetType == null) {
|
||||
// Throw some kind of error for bad target type index
|
||||
throw new IOException("Bad target type: " + tt + " in TypeAnnotationData");
|
||||
throw new IOException("Bad target type: " + ttype + " in TypeAnnotationData");
|
||||
}
|
||||
|
||||
// read the target info
|
||||
TT_Visitor.init(in);
|
||||
TT_Visitor.visitExcept(ttype);
|
||||
target_info = TT_Visitor.getTargetInfo();
|
||||
TT_Visitor.visitExcept(targetType);
|
||||
targetInfo = TT_Visitor.getTargetInfo();
|
||||
|
||||
// read the target path info
|
||||
int len = in.readUnsignedShort();
|
||||
target_path = new ArrayList<>(len);
|
||||
TraceUtils.traceln(" --------- [TypeAnnotationData.read]: Reading Location (length = " + len + ").");
|
||||
TraceUtils.trace(" --------- [TypeAnnotationData.read]: [ ");
|
||||
int len = in.readUnsignedByte();
|
||||
TraceUtils.traceln(4,"[TypeAnnotationData.read]: Reading Location (length = " + len + ").");
|
||||
TraceUtils.trace(4,"[TypeAnnotationData.read]: [ ");
|
||||
for (int i = 0; i < len; i++) {
|
||||
int pathType = in.readUnsignedByte();
|
||||
String pk = (getPathKind(pathType)).parsekey();
|
||||
String pk = (getPathKind(pathType)).parseKey();
|
||||
char pathArgIndex = (char) in.readUnsignedByte();
|
||||
target_path.add(new TypePathEntry(pathType, pathArgIndex));
|
||||
typePath.addTypePathEntry(new TypePathEntry(pathType, pathArgIndex));
|
||||
TraceUtils.trace(" " + pk + "(" + pathType + "," + pathArgIndex + "), ");
|
||||
}
|
||||
TraceUtils.traceln("] ");
|
||||
|
||||
// target_info.setLocation(location);
|
||||
super.read(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -97,51 +93,24 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
// print out the (regular) annotation name/value pairs,
|
||||
// then print out the target types.
|
||||
out.print(" {");
|
||||
super.printBody(out, tab);
|
||||
target_info.print(out, tab);
|
||||
printPath(out, tab);
|
||||
out.print("}");
|
||||
}
|
||||
|
||||
protected void printPath(PrintWriter out, String tab) {
|
||||
// For a type annotation, print out brackets,
|
||||
// print out the (regular) annotation name/value pairs,
|
||||
// then print out the target types.
|
||||
out.print(" {");
|
||||
boolean first = true;
|
||||
for (TypePathEntry tpe : target_path) {
|
||||
if (!first) {
|
||||
out.print(", ");
|
||||
}
|
||||
first = false;
|
||||
out.print(tpe.toString());
|
||||
}
|
||||
target_info.print(out, tab);
|
||||
printPath(out, tab);
|
||||
out.print("}");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void _toString(StringBuilder sb) {
|
||||
// sub-classes override this
|
||||
sb.append(target_info.toString());
|
||||
super.printBody(out, "");
|
||||
targetInfo.print(out, tab);
|
||||
typePath.print(out, tab);
|
||||
out.print(tab + "}");
|
||||
}
|
||||
|
||||
/**
|
||||
* TTVis
|
||||
*
|
||||
* <p>
|
||||
* Target Type visitor, used for constructing the target-info within a type
|
||||
* annotation. visitExcept() is the entry point. ti is the constructed target info.
|
||||
*/
|
||||
private static class TTVis extends TypeAnnotationTargetVisitor {
|
||||
|
||||
private TargetInfo ti = null;
|
||||
private TypeAnnotationTargetInfoData targetInfo = null;
|
||||
private IOException IOProb = null;
|
||||
private DataInputStream in;
|
||||
|
||||
public TTVis() {
|
||||
}
|
||||
|
||||
public void init(DataInputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
@ -166,22 +135,12 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
return val;
|
||||
}
|
||||
|
||||
public int scanIntVal() {
|
||||
int val = 0;
|
||||
try {
|
||||
val = in.readInt();
|
||||
} catch (IOException e) {
|
||||
IOProb = e;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
//This is the entry point for a visitor that tunnels exceptions
|
||||
public void visitExcept(TargetType tt) throws IOException {
|
||||
public void visitExcept(ETargetType tt) throws IOException {
|
||||
IOProb = null;
|
||||
ti = null;
|
||||
targetInfo = null;
|
||||
|
||||
TraceUtils.traceln(" Target Type: " + tt.parseKey());
|
||||
TraceUtils.traceln(4,"Target Type: " + tt.parseKey());
|
||||
visit(tt);
|
||||
|
||||
if (IOProb != null) {
|
||||
|
@ -189,8 +148,8 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
}
|
||||
}
|
||||
|
||||
public TargetInfo getTargetInfo() {
|
||||
return ti;
|
||||
public TypeAnnotationTargetInfoData getTargetInfo() {
|
||||
return targetInfo;
|
||||
}
|
||||
|
||||
private boolean error() {
|
||||
|
@ -198,28 +157,28 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void visit_type_param_target(TargetType tt) {
|
||||
TraceUtils.trace(" Type Param Target: ");
|
||||
public void visit_type_param_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"Type Param Target: ");
|
||||
int byteval = scanByteVal(); // param index
|
||||
TraceUtils.traceln("{ param_index: " + byteval + "}");
|
||||
if (!error()) {
|
||||
ti = new typeparam_target(tt, byteval);
|
||||
targetInfo = new type_parameter_target(tt, byteval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_supertype_target(TargetType tt) {
|
||||
TraceUtils.trace(" SuperType Target: ");
|
||||
public void visit_supertype_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"SuperType Target: ");
|
||||
int shortval = scanShortVal(); // type index
|
||||
TraceUtils.traceln("{ type_index: " + shortval + "}");
|
||||
if (!error()) {
|
||||
ti = new supertype_target(tt, shortval);
|
||||
targetInfo = new supertype_target(tt, shortval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_typeparam_bound_target(TargetType tt) {
|
||||
TraceUtils.trace(" TypeParam Bound Target: ");
|
||||
public void visit_typeparam_bound_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"TypeParam Bound Target: ");
|
||||
int byteval1 = scanByteVal(); // param index
|
||||
if (error()) {
|
||||
return;
|
||||
|
@ -229,46 +188,46 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
return;
|
||||
}
|
||||
TraceUtils.traceln("{ param_index: " + byteval1 + " bound_index: " + byteval2 + "}");
|
||||
ti = new typeparam_bound_target(tt, byteval1, byteval2);
|
||||
targetInfo = new type_parameter_bound_target(tt, byteval1, byteval2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_empty_target(TargetType tt) {
|
||||
TraceUtils.traceln(" Empty Target: ");
|
||||
public void visit_empty_target(ETargetType tt) {
|
||||
TraceUtils.traceln(4,"Empty Target: ");
|
||||
if (!error()) {
|
||||
ti = new empty_target(tt);
|
||||
targetInfo = new empty_target(tt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_methodformalparam_target(TargetType tt) {
|
||||
TraceUtils.trace(" MethodFormalParam Target: ");
|
||||
public void visit_methodformalparam_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"MethodFormalParam Target: ");
|
||||
int byteval = scanByteVal(); // param index
|
||||
TraceUtils.traceln("{ param_index: " + byteval + "}");
|
||||
if (!error()) {
|
||||
ti = new methodformalparam_target(tt, byteval);
|
||||
targetInfo = new formal_parameter_target(tt, byteval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_throws_target(TargetType tt) {
|
||||
TraceUtils.trace(" Throws Target: ");
|
||||
public void visit_throws_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"Throws Target: ");
|
||||
int shortval = scanShortVal(); // exception index
|
||||
TraceUtils.traceln("{ exception_index: " + shortval + "}");
|
||||
if (!error()) {
|
||||
ti = new throws_target(tt, shortval);
|
||||
targetInfo = new throws_target(tt, shortval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_localvar_target(TargetType tt) {
|
||||
TraceUtils.traceln(" LocalVar Target: ");
|
||||
public void visit_localvar_target(ETargetType tt) {
|
||||
TraceUtils.traceln(4,"LocalVar Target: ");
|
||||
int tblsize = scanShortVal(); // table length (short)
|
||||
if (error()) {
|
||||
return;
|
||||
}
|
||||
localvar_target locvartab = new localvar_target(tt, tblsize);
|
||||
ti = locvartab;
|
||||
targetInfo = locvartab;
|
||||
|
||||
for (int i = 0; i < tblsize; i++) {
|
||||
int shortval1 = scanShortVal(); // startPC
|
||||
|
@ -280,35 +239,35 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
return;
|
||||
}
|
||||
int shortval3 = scanShortVal(); // CPX
|
||||
TraceUtils.trace(" LocalVar[" + i + "]: ");
|
||||
TraceUtils.trace(4,"LocalVar[" + i + "]: ");
|
||||
TraceUtils.traceln("{ startPC: " + shortval1 + ", length: " + shortval2 + ", CPX: " + shortval3 + "}");
|
||||
locvartab.addEntry(shortval1, shortval2, shortval3);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_catch_target(TargetType tt) {
|
||||
TraceUtils.trace(" Catch Target: ");
|
||||
public void visit_catch_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"Catch Target: ");
|
||||
int shortval = scanShortVal(); // catch index
|
||||
TraceUtils.traceln("{ catch_index: " + shortval + "}");
|
||||
if (!error()) {
|
||||
ti = new catch_target(tt, shortval);
|
||||
targetInfo = new catch_target(tt, shortval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_offset_target(TargetType tt) {
|
||||
TraceUtils.trace(" Offset Target: ");
|
||||
public void visit_offset_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"Offset Target: ");
|
||||
int shortval = scanShortVal(); // offset index
|
||||
TraceUtils.traceln("{ offset_index: " + shortval + "}");
|
||||
if (!error()) {
|
||||
ti = new offset_target(tt, shortval);
|
||||
targetInfo = new offset_target(tt, shortval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit_typearg_target(TargetType tt) {
|
||||
TraceUtils.trace(" TypeArg Target: ");
|
||||
public void visit_typearg_target(ETargetType tt) {
|
||||
TraceUtils.trace(4,"TypeArg Target: ");
|
||||
int shortval = scanShortVal(); // offset
|
||||
if (error()) {
|
||||
return;
|
||||
|
@ -318,9 +277,7 @@ public class TypeAnnotationData extends AnnotationData {
|
|||
return;
|
||||
}
|
||||
TraceUtils.traceln("{ offset: " + shortval + " type_index: " + byteval + "}");
|
||||
ti = new typearg_target(tt, shortval, byteval);
|
||||
targetInfo = new type_argument_target(tt, shortval, byteval);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ public class I18NResourceBundle extends ResourceBundle {
|
|||
* A required internal method for ResourceBundle. Load the actual resource bundle, if
|
||||
* it has not yet been loaded, then hand the request off to that bundle. If the
|
||||
* resource cannot be found, a message is printed to the console and the result will
|
||||
* be the original key.
|
||||
* be the original tag.
|
||||
*/
|
||||
protected Object handleGetObject(String key) throws MissingResourceException {
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue