feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
44
jdkSrc/jdk8/sun/tools/asm/ArrayData.java
Normal file
44
jdkSrc/jdk8/sun/tools/asm/ArrayData.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class ArrayData {
|
||||
Type type;
|
||||
int nargs;
|
||||
|
||||
public ArrayData(Type type, int nargs) {
|
||||
this.type = type;
|
||||
this.nargs = nargs;
|
||||
}
|
||||
}
|
||||
963
jdkSrc/jdk8/sun/tools/asm/Assembler.java
Normal file
963
jdkSrc/jdk8/sun/tools/asm/Assembler.java
Normal file
@@ -0,0 +1,963 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Vector;
|
||||
// JCOV
|
||||
import sun.tools.javac.*;
|
||||
import java.io.File;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.String;
|
||||
// end JCOV
|
||||
|
||||
/**
|
||||
* This class is used to assemble the bytecode instructions for a method.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public final
|
||||
class Assembler implements Constants {
|
||||
static final int NOTREACHED = 0;
|
||||
static final int REACHED = 1;
|
||||
static final int NEEDED = 2;
|
||||
|
||||
Label first = new Label();
|
||||
Instruction last = first;
|
||||
int maxdepth;
|
||||
int maxvar;
|
||||
int maxpc;
|
||||
|
||||
/**
|
||||
* Add an instruction
|
||||
*/
|
||||
public void add(Instruction inst) {
|
||||
if (inst != null) {
|
||||
last.next = inst;
|
||||
last = inst;
|
||||
}
|
||||
}
|
||||
public void add(long where, int opc) {
|
||||
add(new Instruction(where, opc, null));
|
||||
}
|
||||
public void add(long where, int opc, Object obj) {
|
||||
add(new Instruction(where, opc, obj));
|
||||
}
|
||||
// JCOV
|
||||
public void add(long where, int opc, Object obj, boolean flagCondInverted) {
|
||||
add(new Instruction(where, opc, obj, flagCondInverted));
|
||||
}
|
||||
|
||||
public void add(boolean flagNoCovered, long where, int opc, Object obj) {
|
||||
add(new Instruction(flagNoCovered, where, opc, obj));
|
||||
}
|
||||
|
||||
public void add(long where, int opc, boolean flagNoCovered) {
|
||||
add(new Instruction(where, opc, flagNoCovered));
|
||||
}
|
||||
|
||||
static Vector<String> SourceClassList = new Vector<>();
|
||||
|
||||
static Vector<String> TmpCovTable = new Vector<>();
|
||||
|
||||
static int[] JcovClassCountArray = new int[CT_LAST_KIND + 1];
|
||||
|
||||
static String JcovMagicLine = "JCOV-DATA-FILE-VERSION: 2.0";
|
||||
static String JcovClassLine = "CLASS: ";
|
||||
static String JcovSrcfileLine = "SRCFILE: ";
|
||||
static String JcovTimestampLine = "TIMESTAMP: ";
|
||||
static String JcovDataLine = "DATA: ";
|
||||
static String JcovHeadingLine = "#kind\tcount";
|
||||
|
||||
static int[] arrayModifiers =
|
||||
{M_PUBLIC, M_PRIVATE, M_PROTECTED, M_ABSTRACT, M_FINAL, M_INTERFACE};
|
||||
static int[] arrayModifiersOpc =
|
||||
{PUBLIC, PRIVATE, PROTECTED, ABSTRACT, FINAL, INTERFACE};
|
||||
//end JCOV
|
||||
|
||||
/**
|
||||
* Optimize instructions and mark those that can be reached
|
||||
*/
|
||||
void optimize(Environment env, Label lbl) {
|
||||
lbl.pc = REACHED;
|
||||
|
||||
for (Instruction inst = lbl.next ; inst != null ; inst = inst.next) {
|
||||
switch (inst.pc) {
|
||||
case NOTREACHED:
|
||||
inst.optimize(env);
|
||||
inst.pc = REACHED;
|
||||
break;
|
||||
case REACHED:
|
||||
return;
|
||||
case NEEDED:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (inst.opc) {
|
||||
case opc_label:
|
||||
case opc_dead:
|
||||
if (inst.pc == REACHED) {
|
||||
inst.pc = NOTREACHED;
|
||||
}
|
||||
break;
|
||||
|
||||
case opc_ifeq:
|
||||
case opc_ifne:
|
||||
case opc_ifgt:
|
||||
case opc_ifge:
|
||||
case opc_iflt:
|
||||
case opc_ifle:
|
||||
case opc_if_icmpeq:
|
||||
case opc_if_icmpne:
|
||||
case opc_if_icmpgt:
|
||||
case opc_if_icmpge:
|
||||
case opc_if_icmplt:
|
||||
case opc_if_icmple:
|
||||
case opc_if_acmpeq:
|
||||
case opc_if_acmpne:
|
||||
case opc_ifnull:
|
||||
case opc_ifnonnull:
|
||||
optimize(env, (Label)inst.value);
|
||||
break;
|
||||
|
||||
case opc_goto:
|
||||
optimize(env, (Label)inst.value);
|
||||
return;
|
||||
|
||||
case opc_jsr:
|
||||
optimize(env, (Label)inst.value);
|
||||
break;
|
||||
|
||||
case opc_ret:
|
||||
case opc_return:
|
||||
case opc_ireturn:
|
||||
case opc_lreturn:
|
||||
case opc_freturn:
|
||||
case opc_dreturn:
|
||||
case opc_areturn:
|
||||
case opc_athrow:
|
||||
return;
|
||||
|
||||
case opc_tableswitch:
|
||||
case opc_lookupswitch: {
|
||||
SwitchData sw = (SwitchData)inst.value;
|
||||
optimize(env, sw.defaultLabel);
|
||||
for (Enumeration<Label> e = sw.tab.elements() ; e.hasMoreElements();) {
|
||||
optimize(env, e.nextElement());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case opc_try: {
|
||||
TryData td = (TryData)inst.value;
|
||||
td.getEndLabel().pc = NEEDED;
|
||||
for (Enumeration<CatchData> e = td.catches.elements() ; e.hasMoreElements();) {
|
||||
CatchData cd = e.nextElement();
|
||||
optimize(env, cd.getLabel());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eliminate instructions that are not reached
|
||||
*/
|
||||
boolean eliminate() {
|
||||
boolean change = false;
|
||||
Instruction prev = first;
|
||||
|
||||
for (Instruction inst = first.next ; inst != null ; inst = inst.next) {
|
||||
if (inst.pc != NOTREACHED) {
|
||||
prev.next = inst;
|
||||
prev = inst;
|
||||
inst.pc = NOTREACHED;
|
||||
} else {
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
first.pc = NOTREACHED;
|
||||
prev.next = null;
|
||||
return change;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize the byte codes
|
||||
*/
|
||||
public void optimize(Environment env) {
|
||||
//listing(System.out);
|
||||
do {
|
||||
// Figure out which instructions are reached
|
||||
optimize(env, first);
|
||||
|
||||
// Eliminate instructions that are not reached
|
||||
} while (eliminate() && env.opt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all constants into the constant table
|
||||
*/
|
||||
public void collect(Environment env, MemberDefinition field, ConstantPool tab) {
|
||||
// Collect constants for arguments only
|
||||
// if a local variable table is generated
|
||||
if ((field != null) && env.debug_vars()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments();
|
||||
if (v != null) {
|
||||
for (Enumeration<MemberDefinition> e = v.elements() ; e.hasMoreElements() ;) {
|
||||
MemberDefinition f = e.nextElement();
|
||||
tab.put(f.getName().toString());
|
||||
tab.put(f.getType().getTypeSignature());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect constants from the instructions
|
||||
for (Instruction inst = first ; inst != null ; inst = inst.next) {
|
||||
inst.collect(tab);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine stack size, count local variables
|
||||
*/
|
||||
void balance(Label lbl, int depth) {
|
||||
for (Instruction inst = lbl ; inst != null ; inst = inst.next) {
|
||||
//Environment.debugOutput(inst.toString() + ": " + depth + " => " +
|
||||
// (depth + inst.balance()));
|
||||
depth += inst.balance();
|
||||
if (depth < 0) {
|
||||
throw new CompilerError("stack under flow: " + inst.toString() + " = " + depth);
|
||||
}
|
||||
if (depth > maxdepth) {
|
||||
maxdepth = depth;
|
||||
}
|
||||
switch (inst.opc) {
|
||||
case opc_label:
|
||||
lbl = (Label)inst;
|
||||
if (inst.pc == REACHED) {
|
||||
if (lbl.depth != depth) {
|
||||
throw new CompilerError("stack depth error " +
|
||||
depth + "/" + lbl.depth +
|
||||
": " + inst.toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
lbl.pc = REACHED;
|
||||
lbl.depth = depth;
|
||||
break;
|
||||
|
||||
case opc_ifeq:
|
||||
case opc_ifne:
|
||||
case opc_ifgt:
|
||||
case opc_ifge:
|
||||
case opc_iflt:
|
||||
case opc_ifle:
|
||||
case opc_if_icmpeq:
|
||||
case opc_if_icmpne:
|
||||
case opc_if_icmpgt:
|
||||
case opc_if_icmpge:
|
||||
case opc_if_icmplt:
|
||||
case opc_if_icmple:
|
||||
case opc_if_acmpeq:
|
||||
case opc_if_acmpne:
|
||||
case opc_ifnull:
|
||||
case opc_ifnonnull:
|
||||
balance((Label)inst.value, depth);
|
||||
break;
|
||||
|
||||
case opc_goto:
|
||||
balance((Label)inst.value, depth);
|
||||
return;
|
||||
|
||||
case opc_jsr:
|
||||
balance((Label)inst.value, depth + 1);
|
||||
break;
|
||||
|
||||
case opc_ret:
|
||||
case opc_return:
|
||||
case opc_ireturn:
|
||||
case opc_lreturn:
|
||||
case opc_freturn:
|
||||
case opc_dreturn:
|
||||
case opc_areturn:
|
||||
case opc_athrow:
|
||||
return;
|
||||
|
||||
case opc_iload:
|
||||
case opc_fload:
|
||||
case opc_aload:
|
||||
case opc_istore:
|
||||
case opc_fstore:
|
||||
case opc_astore: {
|
||||
int v = ((inst.value instanceof Number)
|
||||
? ((Number)inst.value).intValue()
|
||||
: ((LocalVariable)inst.value).slot) + 1;
|
||||
if (v > maxvar)
|
||||
maxvar = v;
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_lload:
|
||||
case opc_dload:
|
||||
case opc_lstore:
|
||||
case opc_dstore: {
|
||||
int v = ((inst.value instanceof Number)
|
||||
? ((Number)inst.value).intValue()
|
||||
: ((LocalVariable)inst.value).slot) + 2;
|
||||
if (v > maxvar)
|
||||
maxvar = v;
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_iinc: {
|
||||
int v = ((int[])inst.value)[0] + 1;
|
||||
if (v > maxvar)
|
||||
maxvar = v + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_tableswitch:
|
||||
case opc_lookupswitch: {
|
||||
SwitchData sw = (SwitchData)inst.value;
|
||||
balance(sw.defaultLabel, depth);
|
||||
for (Enumeration<Label> e = sw.tab.elements() ; e.hasMoreElements();) {
|
||||
balance(e.nextElement(), depth);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case opc_try: {
|
||||
TryData td = (TryData)inst.value;
|
||||
for (Enumeration<CatchData> e = td.catches.elements() ; e.hasMoreElements();) {
|
||||
CatchData cd = e.nextElement();
|
||||
balance(cd.getLabel(), depth + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate code
|
||||
*/
|
||||
public void write(Environment env, DataOutputStream out,
|
||||
MemberDefinition field, ConstantPool tab)
|
||||
throws IOException {
|
||||
//listing(System.out);
|
||||
|
||||
if ((field != null) && field.getArguments() != null) {
|
||||
int sum = 0;
|
||||
@SuppressWarnings("unchecked")
|
||||
Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments();
|
||||
for (Enumeration<MemberDefinition> e = v.elements(); e.hasMoreElements(); ) {
|
||||
MemberDefinition f = e.nextElement();
|
||||
sum += f.getType().stackSize();
|
||||
}
|
||||
maxvar = sum;
|
||||
}
|
||||
|
||||
// Make sure the stack balances. Also calculate maxvar and maxstack
|
||||
try {
|
||||
balance(first, 0);
|
||||
} catch (CompilerError e) {
|
||||
System.out.println("ERROR: " + e);
|
||||
listing(System.out);
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Assign PCs
|
||||
int pc = 0, nexceptions = 0;
|
||||
for (Instruction inst = first ; inst != null ; inst = inst.next) {
|
||||
inst.pc = pc;
|
||||
int sz = inst.size(tab);
|
||||
if (pc<65536 && (pc+sz)>=65536) {
|
||||
env.error(inst.where, "warn.method.too.long");
|
||||
}
|
||||
pc += sz;
|
||||
|
||||
if (inst.opc == opc_try) {
|
||||
nexceptions += ((TryData)inst.value).catches.size();
|
||||
}
|
||||
}
|
||||
|
||||
// Write header
|
||||
out.writeShort(maxdepth);
|
||||
out.writeShort(maxvar);
|
||||
out.writeInt(maxpc = pc);
|
||||
|
||||
// Generate code
|
||||
for (Instruction inst = first.next ; inst != null ; inst = inst.next) {
|
||||
inst.write(out, tab);
|
||||
}
|
||||
|
||||
// write exceptions
|
||||
out.writeShort(nexceptions);
|
||||
if (nexceptions > 0) {
|
||||
//listing(System.out);
|
||||
writeExceptions(env, out, tab, first, last);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the exceptions table
|
||||
*/
|
||||
void writeExceptions(Environment env, DataOutputStream out, ConstantPool tab, Instruction first, Instruction last) throws IOException {
|
||||
for (Instruction inst = first ; inst != last.next ; inst = inst.next) {
|
||||
if (inst.opc == opc_try) {
|
||||
TryData td = (TryData)inst.value;
|
||||
writeExceptions(env, out, tab, inst.next, td.getEndLabel());
|
||||
for (Enumeration<CatchData> e = td.catches.elements() ; e.hasMoreElements();) {
|
||||
CatchData cd = e.nextElement();
|
||||
//System.out.println("EXCEPTION: " + env.getSource() + ", pc=" + inst.pc + ", end=" + td.getEndLabel().pc + ", hdl=" + cd.getLabel().pc + ", tp=" + cd.getType());
|
||||
out.writeShort(inst.pc);
|
||||
out.writeShort(td.getEndLabel().pc);
|
||||
out.writeShort(cd.getLabel().pc);
|
||||
if (cd.getType() != null) {
|
||||
out.writeShort(tab.index(cd.getType()));
|
||||
} else {
|
||||
out.writeShort(0);
|
||||
}
|
||||
}
|
||||
inst = td.getEndLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//JCOV
|
||||
/**
|
||||
* Write the coverage table
|
||||
*/
|
||||
public void writeCoverageTable(Environment env, ClassDefinition c, DataOutputStream out, ConstantPool tab, long whereField) throws IOException {
|
||||
Vector<Cover> TableLot = new Vector<>(); /* Coverage table */
|
||||
boolean begseg = false;
|
||||
boolean begmeth = false;
|
||||
@SuppressWarnings("deprecation")
|
||||
long whereClass = ((SourceClass)c).getWhere();
|
||||
Vector<Long> whereTry = new Vector<>();
|
||||
int numberTry = 0;
|
||||
int count = 0;
|
||||
|
||||
for (Instruction inst = first ; inst != null ; inst = inst.next) {
|
||||
long n = (inst.where >> WHEREOFFSETBITS);
|
||||
if (n > 0 && inst.opc != opc_label) {
|
||||
if (!begmeth) {
|
||||
if ( whereClass == inst.where)
|
||||
TableLot.addElement(new Cover(CT_FIKT_METHOD, whereField, inst.pc));
|
||||
else
|
||||
TableLot.addElement(new Cover(CT_METHOD, whereField, inst.pc));
|
||||
count++;
|
||||
begmeth = true;
|
||||
}
|
||||
if (!begseg && !inst.flagNoCovered ) {
|
||||
boolean findTry = false;
|
||||
for (Enumeration<Long> e = whereTry.elements(); e.hasMoreElements();) {
|
||||
if (e.nextElement().longValue() == inst.where) {
|
||||
findTry = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!findTry) {
|
||||
TableLot.addElement(new Cover(CT_BLOCK, inst.where, inst.pc));
|
||||
count++;
|
||||
begseg = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (inst.opc) {
|
||||
case opc_label:
|
||||
begseg = false;
|
||||
break;
|
||||
case opc_ifeq:
|
||||
case opc_ifne:
|
||||
case opc_ifnull:
|
||||
case opc_ifnonnull:
|
||||
case opc_ifgt:
|
||||
case opc_ifge:
|
||||
case opc_iflt:
|
||||
case opc_ifle:
|
||||
case opc_if_icmpeq:
|
||||
case opc_if_icmpne:
|
||||
case opc_if_icmpgt:
|
||||
case opc_if_icmpge:
|
||||
case opc_if_icmplt:
|
||||
case opc_if_icmple:
|
||||
case opc_if_acmpeq:
|
||||
case opc_if_acmpne: {
|
||||
if ( inst.flagCondInverted ) {
|
||||
TableLot.addElement(new Cover(CT_BRANCH_TRUE, inst.where, inst.pc));
|
||||
TableLot.addElement(new Cover(CT_BRANCH_FALSE, inst.where, inst.pc));
|
||||
} else {
|
||||
TableLot.addElement(new Cover(CT_BRANCH_FALSE, inst.where, inst.pc));
|
||||
TableLot.addElement(new Cover(CT_BRANCH_TRUE, inst.where, inst.pc));
|
||||
}
|
||||
count += 2;
|
||||
begseg = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_goto: {
|
||||
begseg = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_ret:
|
||||
case opc_return:
|
||||
case opc_ireturn:
|
||||
case opc_lreturn:
|
||||
case opc_freturn:
|
||||
case opc_dreturn:
|
||||
case opc_areturn:
|
||||
case opc_athrow: {
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_try: {
|
||||
whereTry.addElement(Long.valueOf(inst.where));
|
||||
begseg = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_tableswitch: {
|
||||
SwitchData sw = (SwitchData)inst.value;
|
||||
for (int i = sw.minValue; i <= sw.maxValue; i++) {
|
||||
TableLot.addElement(new Cover(CT_CASE, sw.whereCase(new Integer(i)), inst.pc));
|
||||
count++;
|
||||
}
|
||||
if (!sw.getDefault()) {
|
||||
TableLot.addElement(new Cover(CT_SWITH_WO_DEF, inst.where, inst.pc));
|
||||
count++;
|
||||
} else {
|
||||
TableLot.addElement(new Cover(CT_CASE, sw.whereCase("default"), inst.pc));
|
||||
count++;
|
||||
}
|
||||
begseg = false;
|
||||
break;
|
||||
}
|
||||
case opc_lookupswitch: {
|
||||
SwitchData sw = (SwitchData)inst.value;
|
||||
for (Enumeration<Integer> e = sw.sortedKeys(); e.hasMoreElements() ; ) {
|
||||
Integer v = e.nextElement();
|
||||
TableLot.addElement(new Cover(CT_CASE, sw.whereCase(v), inst.pc));
|
||||
count++;
|
||||
}
|
||||
if (!sw.getDefault()) {
|
||||
TableLot.addElement(new Cover(CT_SWITH_WO_DEF, inst.where, inst.pc));
|
||||
count++;
|
||||
} else {
|
||||
TableLot.addElement(new Cover(CT_CASE, sw.whereCase("default"), inst.pc));
|
||||
count++;
|
||||
}
|
||||
begseg = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Cover Lot;
|
||||
long ln, pos;
|
||||
|
||||
out.writeShort(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Lot = TableLot.elementAt(i);
|
||||
ln = (Lot.Addr >> WHEREOFFSETBITS);
|
||||
pos = (Lot.Addr << (64 - WHEREOFFSETBITS)) >> (64 - WHEREOFFSETBITS);
|
||||
out.writeShort(Lot.NumCommand);
|
||||
out.writeShort(Lot.Type);
|
||||
out.writeInt((int)ln);
|
||||
out.writeInt((int)pos);
|
||||
|
||||
if ( !(Lot.Type == CT_CASE && Lot.Addr == 0) ) {
|
||||
JcovClassCountArray[Lot.Type]++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase count of methods for native methods
|
||||
*/
|
||||
|
||||
public void addNativeToJcovTab(Environment env, ClassDefinition c) {
|
||||
JcovClassCountArray[CT_METHOD]++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create class jcov element
|
||||
*/
|
||||
|
||||
private String createClassJcovElement(Environment env, ClassDefinition c) {
|
||||
String SourceClass = (Type.mangleInnerType((c.getClassDeclaration()).getName())).toString();
|
||||
String ConvSourceClass;
|
||||
String classJcovLine;
|
||||
|
||||
SourceClassList.addElement(SourceClass);
|
||||
ConvSourceClass = SourceClass.replace('.', '/');
|
||||
classJcovLine = JcovClassLine + ConvSourceClass;
|
||||
|
||||
classJcovLine = classJcovLine + " [";
|
||||
String blank = "";
|
||||
|
||||
for (int i = 0; i < arrayModifiers.length; i++ ) {
|
||||
if ((c.getModifiers() & arrayModifiers[i]) != 0) {
|
||||
classJcovLine = classJcovLine + blank + opNames[arrayModifiersOpc[i]];
|
||||
blank = " ";
|
||||
}
|
||||
}
|
||||
classJcovLine = classJcovLine + "]";
|
||||
|
||||
return classJcovLine;
|
||||
}
|
||||
|
||||
/*
|
||||
* generate coverage data
|
||||
*/
|
||||
|
||||
public void GenVecJCov(Environment env, ClassDefinition c, long Time) {
|
||||
@SuppressWarnings("deprecation")
|
||||
String SourceFile = ((SourceClass)c).getAbsoluteName();
|
||||
|
||||
TmpCovTable.addElement(createClassJcovElement(env, c));
|
||||
TmpCovTable.addElement(JcovSrcfileLine + SourceFile);
|
||||
TmpCovTable.addElement(JcovTimestampLine + Time);
|
||||
TmpCovTable.addElement(JcovDataLine + "A"); // data format
|
||||
TmpCovTable.addElement(JcovHeadingLine);
|
||||
|
||||
for (int i = CT_FIRST_KIND; i <= CT_LAST_KIND; i++) {
|
||||
if (JcovClassCountArray[i] != 0) {
|
||||
TmpCovTable.addElement(new String(i + "\t" + JcovClassCountArray[i]));
|
||||
JcovClassCountArray[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* generate file of coverage data
|
||||
*/
|
||||
|
||||
@SuppressWarnings("deprecation") // for JCovd.readLine() calls
|
||||
public void GenJCov(Environment env) {
|
||||
|
||||
try {
|
||||
File outFile = env.getcovFile();
|
||||
if( outFile.exists()) {
|
||||
DataInputStream JCovd = new DataInputStream(
|
||||
new BufferedInputStream(
|
||||
new FileInputStream(outFile)));
|
||||
String CurrLine = null;
|
||||
boolean first = true;
|
||||
String Class;
|
||||
|
||||
CurrLine = JCovd.readLine();
|
||||
if ((CurrLine != null) && CurrLine.startsWith(JcovMagicLine)) {
|
||||
// this is a good Jcov file
|
||||
|
||||
while((CurrLine = JCovd.readLine()) != null ) {
|
||||
if ( CurrLine.startsWith(JcovClassLine) ) {
|
||||
first = true;
|
||||
for(Enumeration<String> e = SourceClassList.elements(); e.hasMoreElements();) {
|
||||
String clsName = CurrLine.substring(JcovClassLine.length());
|
||||
int idx = clsName.indexOf(' ');
|
||||
|
||||
if (idx != -1) {
|
||||
clsName = clsName.substring(0, idx);
|
||||
}
|
||||
Class = e.nextElement();
|
||||
if ( Class.compareTo(clsName) == 0) {
|
||||
first = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (first) // re-write old class
|
||||
TmpCovTable.addElement(CurrLine);
|
||||
}
|
||||
}
|
||||
JCovd.close();
|
||||
}
|
||||
PrintStream CovFile = new PrintStream(new DataOutputStream(new FileOutputStream(outFile)));
|
||||
CovFile.println(JcovMagicLine);
|
||||
for(Enumeration<String> e = TmpCovTable.elements(); e.hasMoreElements();) {
|
||||
CovFile.println(e.nextElement());
|
||||
}
|
||||
CovFile.close();
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
System.out.println("ERROR: " + e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.out.println("ERROR: " + e);
|
||||
}
|
||||
}
|
||||
// end JCOV
|
||||
|
||||
|
||||
/**
|
||||
* Write the linenumber table
|
||||
*/
|
||||
public void writeLineNumberTable(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
long ln = -1;
|
||||
int count = 0;
|
||||
|
||||
for (Instruction inst = first ; inst != null ; inst = inst.next) {
|
||||
long n = (inst.where >> WHEREOFFSETBITS);
|
||||
if ((n > 0) && (ln != n)) {
|
||||
ln = n;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
ln = -1;
|
||||
out.writeShort(count);
|
||||
for (Instruction inst = first ; inst != null ; inst = inst.next) {
|
||||
long n = (inst.where >> WHEREOFFSETBITS);
|
||||
if ((n > 0) && (ln != n)) {
|
||||
ln = n;
|
||||
out.writeShort(inst.pc);
|
||||
out.writeShort((int)ln);
|
||||
//System.out.println("pc = " + inst.pc + ", ln = " + ln);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Figure out when registers contain a legal value. This is done
|
||||
* using a simple data flow algorithm. This information is later used
|
||||
* to generate the local variable table.
|
||||
*/
|
||||
void flowFields(Environment env, Label lbl, MemberDefinition locals[]) {
|
||||
if (lbl.locals != null) {
|
||||
// Been here before. Erase any conflicts.
|
||||
MemberDefinition f[] = lbl.locals;
|
||||
for (int i = 0 ; i < maxvar ; i++) {
|
||||
if (f[i] != locals[i]) {
|
||||
f[i] = null;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Remember the set of active registers at this point
|
||||
lbl.locals = new MemberDefinition[maxvar];
|
||||
System.arraycopy(locals, 0, lbl.locals, 0, maxvar);
|
||||
|
||||
MemberDefinition newlocals[] = new MemberDefinition[maxvar];
|
||||
System.arraycopy(locals, 0, newlocals, 0, maxvar);
|
||||
locals = newlocals;
|
||||
|
||||
for (Instruction inst = lbl.next ; inst != null ; inst = inst.next) {
|
||||
switch (inst.opc) {
|
||||
case opc_istore: case opc_istore_0: case opc_istore_1:
|
||||
case opc_istore_2: case opc_istore_3:
|
||||
case opc_fstore: case opc_fstore_0: case opc_fstore_1:
|
||||
case opc_fstore_2: case opc_fstore_3:
|
||||
case opc_astore: case opc_astore_0: case opc_astore_1:
|
||||
case opc_astore_2: case opc_astore_3:
|
||||
case opc_lstore: case opc_lstore_0: case opc_lstore_1:
|
||||
case opc_lstore_2: case opc_lstore_3:
|
||||
case opc_dstore: case opc_dstore_0: case opc_dstore_1:
|
||||
case opc_dstore_2: case opc_dstore_3:
|
||||
if (inst.value instanceof LocalVariable) {
|
||||
LocalVariable v = (LocalVariable)inst.value;
|
||||
locals[v.slot] = v.field;
|
||||
}
|
||||
break;
|
||||
|
||||
case opc_label:
|
||||
flowFields(env, (Label)inst, locals);
|
||||
return;
|
||||
|
||||
case opc_ifeq: case opc_ifne: case opc_ifgt:
|
||||
case opc_ifge: case opc_iflt: case opc_ifle:
|
||||
case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpgt:
|
||||
case opc_if_icmpge: case opc_if_icmplt: case opc_if_icmple:
|
||||
case opc_if_acmpeq: case opc_if_acmpne:
|
||||
case opc_ifnull: case opc_ifnonnull:
|
||||
case opc_jsr:
|
||||
flowFields(env, (Label)inst.value, locals);
|
||||
break;
|
||||
|
||||
case opc_goto:
|
||||
flowFields(env, (Label)inst.value, locals);
|
||||
return;
|
||||
|
||||
case opc_return: case opc_ireturn: case opc_lreturn:
|
||||
case opc_freturn: case opc_dreturn: case opc_areturn:
|
||||
case opc_athrow: case opc_ret:
|
||||
return;
|
||||
|
||||
case opc_tableswitch:
|
||||
case opc_lookupswitch: {
|
||||
SwitchData sw = (SwitchData)inst.value;
|
||||
flowFields(env, sw.defaultLabel, locals);
|
||||
for (Enumeration<Label> e = sw.tab.elements() ; e.hasMoreElements();) {
|
||||
flowFields(env, e.nextElement(), locals);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case opc_try: {
|
||||
Vector<CatchData> catches = ((TryData)inst.value).catches;
|
||||
for (Enumeration<CatchData> e = catches.elements(); e.hasMoreElements();) {
|
||||
CatchData cd = e.nextElement();
|
||||
flowFields(env, cd.getLabel(), locals);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the local variable table. The necessary constants have already been
|
||||
* added to the constant table by the collect() method. The flowFields method
|
||||
* is used to determine which variables are alive at each pc.
|
||||
*/
|
||||
public void writeLocalVariableTable(Environment env, MemberDefinition field, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
MemberDefinition locals[] = new MemberDefinition[maxvar];
|
||||
int i = 0;
|
||||
|
||||
// Initialize arguments
|
||||
if ((field != null) && (field.getArguments() != null)) {
|
||||
int reg = 0;
|
||||
@SuppressWarnings("unchecked")
|
||||
Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments();
|
||||
for (Enumeration<MemberDefinition> e = v.elements(); e.hasMoreElements(); ) {
|
||||
MemberDefinition f = e.nextElement();
|
||||
locals[reg] = f;
|
||||
reg += f.getType().stackSize();
|
||||
}
|
||||
}
|
||||
|
||||
flowFields(env, first, locals);
|
||||
LocalVariableTable lvtab = new LocalVariableTable();
|
||||
|
||||
// Initialize arguments again
|
||||
for (i = 0; i < maxvar; i++)
|
||||
locals[i] = null;
|
||||
if ((field != null) && (field.getArguments() != null)) {
|
||||
int reg = 0;
|
||||
@SuppressWarnings("unchecked")
|
||||
Vector<MemberDefinition> v = (Vector<MemberDefinition>)field.getArguments();
|
||||
for (Enumeration<MemberDefinition> e = v.elements(); e.hasMoreElements(); ) {
|
||||
MemberDefinition f = e.nextElement();
|
||||
locals[reg] = f;
|
||||
lvtab.define(f, reg, 0, maxpc);
|
||||
reg += f.getType().stackSize();
|
||||
}
|
||||
}
|
||||
|
||||
int pcs[] = new int[maxvar];
|
||||
|
||||
for (Instruction inst = first ; inst != null ; inst = inst.next) {
|
||||
switch (inst.opc) {
|
||||
case opc_istore: case opc_istore_0: case opc_istore_1:
|
||||
case opc_istore_2: case opc_istore_3: case opc_fstore:
|
||||
case opc_fstore_0: case opc_fstore_1: case opc_fstore_2:
|
||||
case opc_fstore_3:
|
||||
case opc_astore: case opc_astore_0: case opc_astore_1:
|
||||
case opc_astore_2: case opc_astore_3:
|
||||
case opc_lstore: case opc_lstore_0: case opc_lstore_1:
|
||||
case opc_lstore_2: case opc_lstore_3:
|
||||
case opc_dstore: case opc_dstore_0: case opc_dstore_1:
|
||||
case opc_dstore_2: case opc_dstore_3:
|
||||
if (inst.value instanceof LocalVariable) {
|
||||
LocalVariable v = (LocalVariable)inst.value;
|
||||
int pc = (inst.next != null) ? inst.next.pc : inst.pc;
|
||||
if (locals[v.slot] != null) {
|
||||
lvtab.define(locals[v.slot], v.slot, pcs[v.slot], pc);
|
||||
}
|
||||
pcs[v.slot] = pc;
|
||||
locals[v.slot] = v.field;
|
||||
}
|
||||
break;
|
||||
|
||||
case opc_label: {
|
||||
// flush previous labels
|
||||
for (i = 0 ; i < maxvar ; i++) {
|
||||
if (locals[i] != null) {
|
||||
lvtab.define(locals[i], i, pcs[i], inst.pc);
|
||||
}
|
||||
}
|
||||
// init new labels
|
||||
int pc = inst.pc;
|
||||
MemberDefinition[] labelLocals = ((Label)inst).locals;
|
||||
if (labelLocals == null) { // unreachable code??
|
||||
for (i = 0; i < maxvar; i++)
|
||||
locals[i] = null;
|
||||
} else {
|
||||
System.arraycopy(labelLocals, 0, locals, 0, maxvar);
|
||||
}
|
||||
for (i = 0 ; i < maxvar ; i++) {
|
||||
pcs[i] = pc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flush remaining labels
|
||||
for (i = 0 ; i < maxvar ; i++) {
|
||||
if (locals[i] != null) {
|
||||
lvtab.define(locals[i], i, pcs[i], maxpc);
|
||||
}
|
||||
}
|
||||
|
||||
// write the local variable table
|
||||
lvtab.write(env, out, tab);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if empty
|
||||
*/
|
||||
public boolean empty() {
|
||||
return first == last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the byte codes
|
||||
*/
|
||||
public void listing(PrintStream out) {
|
||||
out.println("-- listing --");
|
||||
for (Instruction inst = first ; inst != null ; inst = inst.next) {
|
||||
out.println(inst.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/sun/tools/asm/CatchData.java
Normal file
62
jdkSrc/jdk8/sun/tools/asm/CatchData.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class CatchData {
|
||||
Object type;
|
||||
Label label;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
CatchData(Object type) {
|
||||
this.type = type;
|
||||
this.label = new Label();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the label
|
||||
*/
|
||||
public Label getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clazz
|
||||
*/
|
||||
public Object getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
79
jdkSrc/jdk8/sun/tools/asm/ClassConstantData.java
Normal file
79
jdkSrc/jdk8/sun/tools/asm/ClassConstantData.java
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* This is a class constant pool item.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
final
|
||||
class ClassConstantData extends ConstantPoolData {
|
||||
String name;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
||||
ClassConstantData(ConstantPool tab, ClassDeclaration clazz) {
|
||||
String sig = clazz.getType().getTypeSignature();
|
||||
// sig is like "Lfoo/bar;", name is like "foo/bar".
|
||||
// We assume SIG_CLASS and SIG_ENDCLASS are 1 char each.
|
||||
name = sig.substring(1, sig.length()-1);
|
||||
tab.put(name);
|
||||
}
|
||||
|
||||
// REMIND: this case should eventually go away.
|
||||
ClassConstantData(ConstantPool tab, Type t) {
|
||||
name = t.getTypeSignature();
|
||||
tab.put(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the constant to the output stream
|
||||
*/
|
||||
void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
out.writeByte(CONSTANT_CLASS);
|
||||
out.writeShort(tab.index(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order of the constant
|
||||
*/
|
||||
int order() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "ClassConstantData[" + name + "]";
|
||||
}
|
||||
}
|
||||
176
jdkSrc/jdk8/sun/tools/asm/ConstantPool.java
Normal file
176
jdkSrc/jdk8/sun/tools/asm/ConstantPool.java
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import sun.tools.tree.StringExpression;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* A table of constants
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class ConstantPool implements RuntimeConstants {
|
||||
Hashtable<Object,ConstantPoolData> hash = new Hashtable<>(101);
|
||||
|
||||
/**
|
||||
* Find an entry, may return 0
|
||||
*/
|
||||
public int index(Object obj) {
|
||||
return hash.get(obj).index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an entry
|
||||
*/
|
||||
public void put(Object obj) {
|
||||
ConstantPoolData data = hash.get(obj);
|
||||
if (data == null) {
|
||||
if (obj instanceof String) {
|
||||
data = new StringConstantData(this, (String)obj);
|
||||
} else if (obj instanceof StringExpression) {
|
||||
data = new StringExpressionConstantData(this, (StringExpression)obj);
|
||||
} else if (obj instanceof ClassDeclaration) {
|
||||
data = new ClassConstantData(this, (ClassDeclaration)obj);
|
||||
} else if (obj instanceof Type) {
|
||||
data = new ClassConstantData(this, (Type)obj);
|
||||
} else if (obj instanceof MemberDefinition) {
|
||||
data = new FieldConstantData(this, (MemberDefinition)obj);
|
||||
} else if (obj instanceof NameAndTypeData) {
|
||||
data = new NameAndTypeConstantData(this, (NameAndTypeData)obj);
|
||||
} else if (obj instanceof Number) {
|
||||
data = new NumberConstantData(this, (Number)obj);
|
||||
}
|
||||
hash.put(obj, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to output
|
||||
*/
|
||||
public void write(Environment env, DataOutputStream out) throws IOException {
|
||||
ConstantPoolData list[] = new ConstantPoolData[hash.size()];
|
||||
String keys[] = new String[list.length];
|
||||
int index = 1, count = 0;
|
||||
|
||||
// Make a list of all the constant pool items
|
||||
for (int n = 0 ; n < 5 ; n++) {
|
||||
int first = count;
|
||||
for (Enumeration<ConstantPoolData> e = hash.elements() ; e.hasMoreElements() ;) {
|
||||
ConstantPoolData data = e.nextElement();
|
||||
if (data.order() == n) {
|
||||
keys[count] = sortKey(data);
|
||||
list[count++] = data;
|
||||
}
|
||||
}
|
||||
xsort(list, keys, first, count-1);
|
||||
}
|
||||
|
||||
// Assign an index to each constant pool item
|
||||
for (int n = 0 ; n < list.length ; n++) {
|
||||
ConstantPoolData data = list[n];
|
||||
data.index = index;
|
||||
index += data.width();
|
||||
}
|
||||
|
||||
// Write length
|
||||
out.writeShort(index);
|
||||
|
||||
// Write each constant pool item
|
||||
for (int n = 0 ; n < count ; n++) {
|
||||
list[n].write(env, out, this);
|
||||
}
|
||||
}
|
||||
|
||||
private
|
||||
static String sortKey(ConstantPoolData f) {
|
||||
if (f instanceof NumberConstantData) {
|
||||
Number num = ((NumberConstantData)f).num;
|
||||
String str = num.toString();
|
||||
int key = 3;
|
||||
if (num instanceof Integer) key = 0;
|
||||
else if (num instanceof Float) key = 1;
|
||||
else if (num instanceof Long) key = 2;
|
||||
return "\0" + (char)(str.length() + key<<8) + str;
|
||||
}
|
||||
if (f instanceof StringExpressionConstantData)
|
||||
return (String)((StringExpressionConstantData)f).str.getValue();
|
||||
if (f instanceof FieldConstantData) {
|
||||
MemberDefinition fd = ((FieldConstantData)f).field;
|
||||
return fd.getName()+" "+fd.getType().getTypeSignature()
|
||||
+" "+fd.getClassDeclaration().getName();
|
||||
}
|
||||
if (f instanceof NameAndTypeConstantData)
|
||||
return ((NameAndTypeConstantData)f).name+
|
||||
" "+((NameAndTypeConstantData)f).type;
|
||||
if (f instanceof ClassConstantData)
|
||||
return ((ClassConstantData)f).name;
|
||||
return ((StringConstantData)f).str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick sort an array of pool entries and a corresponding array of Strings
|
||||
* that are the sort keys for the field.
|
||||
*/
|
||||
private
|
||||
static void xsort(ConstantPoolData ff[], String ss[], int left, int right) {
|
||||
if (left >= right)
|
||||
return;
|
||||
String pivot = ss[left];
|
||||
int l = left;
|
||||
int r = right;
|
||||
while (l < r) {
|
||||
while (l <= right && ss[l].compareTo(pivot) <= 0)
|
||||
l++;
|
||||
while (r >= left && ss[r].compareTo(pivot) > 0)
|
||||
r--;
|
||||
if (l < r) {
|
||||
// swap items at l and at r
|
||||
ConstantPoolData def = ff[l];
|
||||
String name = ss[l];
|
||||
ff[l] = ff[r]; ff[r] = def;
|
||||
ss[l] = ss[r]; ss[r] = name;
|
||||
}
|
||||
}
|
||||
int middle = r;
|
||||
// swap left and middle
|
||||
ConstantPoolData def = ff[left];
|
||||
String name = ss[left];
|
||||
ff[left] = ff[middle]; ff[middle] = def;
|
||||
ss[left] = ss[middle]; ss[middle] = name;
|
||||
xsort(ff, ss, left, middle-1);
|
||||
xsort(ff, ss, middle + 1, right);
|
||||
}
|
||||
|
||||
}
|
||||
62
jdkSrc/jdk8/sun/tools/asm/ConstantPoolData.java
Normal file
62
jdkSrc/jdk8/sun/tools/asm/ConstantPoolData.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* Base constant data class. Every constant pool data item
|
||||
* is derived from this class.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
abstract class ConstantPoolData implements RuntimeConstants {
|
||||
int index;
|
||||
|
||||
/**
|
||||
* Write the constant to the output stream
|
||||
*/
|
||||
abstract void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException;
|
||||
|
||||
/**
|
||||
* Return the order of the constant
|
||||
*/
|
||||
int order() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of entries that it takes up in the constant pool
|
||||
*/
|
||||
int width() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
46
jdkSrc/jdk8/sun/tools/asm/Cover.java
Normal file
46
jdkSrc/jdk8/sun/tools/asm/Cover.java
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public class Cover {
|
||||
public int Type;
|
||||
public long Addr;
|
||||
public int NumCommand;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Cover(int type, long addr, int command) {
|
||||
Type=type;
|
||||
Addr=addr;
|
||||
NumCommand=command;
|
||||
}
|
||||
}
|
||||
77
jdkSrc/jdk8/sun/tools/asm/FieldConstantData.java
Normal file
77
jdkSrc/jdk8/sun/tools/asm/FieldConstantData.java
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* This is a field constant pool data item
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
final
|
||||
class FieldConstantData extends ConstantPoolData {
|
||||
MemberDefinition field;
|
||||
NameAndTypeData nt;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
FieldConstantData(ConstantPool tab, MemberDefinition field) {
|
||||
this.field = field;
|
||||
nt = new NameAndTypeData(field);
|
||||
tab.put(field.getClassDeclaration());
|
||||
tab.put(nt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the constant to the output stream
|
||||
*/
|
||||
void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
if (field.isMethod()) {
|
||||
if (field.getClassDefinition().isInterface()) {
|
||||
out.writeByte(CONSTANT_INTERFACEMETHOD);
|
||||
} else {
|
||||
out.writeByte(CONSTANT_METHOD);
|
||||
}
|
||||
} else {
|
||||
out.writeByte(CONSTANT_FIELD);
|
||||
}
|
||||
out.writeShort(tab.index(field.getClassDeclaration()));
|
||||
out.writeShort(tab.index(nt));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order of the constant
|
||||
*/
|
||||
int order() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
832
jdkSrc/jdk8/sun/tools/asm/Instruction.java
Normal file
832
jdkSrc/jdk8/sun/tools/asm/Instruction.java
Normal file
@@ -0,0 +1,832 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* An Java instruction
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public
|
||||
class Instruction implements Constants {
|
||||
long where;
|
||||
int pc;
|
||||
int opc;
|
||||
Object value;
|
||||
Instruction next;
|
||||
//JCOV
|
||||
boolean flagCondInverted; /* if true, the condition is reversed
|
||||
relatively of source code */
|
||||
boolean flagNoCovered = false; /* if true, the command will
|
||||
ignored for coverage */
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Instruction(long where, int opc, Object value, boolean flagCondInverted) {
|
||||
this.where = where;
|
||||
this.opc = opc;
|
||||
this.value = value;
|
||||
this.flagCondInverted = flagCondInverted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Instruction(boolean flagNoCovered, long where, int opc, Object value) {
|
||||
this.where = where;
|
||||
this.opc = opc;
|
||||
this.value = value;
|
||||
this.flagNoCovered = flagNoCovered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Instruction(long where, int opc, boolean flagNoCovered) {
|
||||
this.where = where;
|
||||
this.opc = opc;
|
||||
this.flagNoCovered = flagNoCovered;
|
||||
}
|
||||
//end JCOV
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Instruction(long where, int opc, Object value) {
|
||||
this.where = where;
|
||||
this.opc = opc;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* When deciding between a lookupswitch and a tableswitch, this
|
||||
* value is used in determining how much size increase is
|
||||
* acceptable.
|
||||
*/
|
||||
public static final double SWITCHRATIO;
|
||||
|
||||
static {
|
||||
// Set SWITCHRATIO from the property javac.switchratio
|
||||
// if it exists and is reasonable. Otherwise, set
|
||||
// SWITCHRATIO to 1.5, meaning that we will accept a 1.5x
|
||||
// blowup (for the instruction) to use a tableswitch instead
|
||||
// of a lookupswitch.
|
||||
double ratio = 1.5;
|
||||
String valStr = System.getProperty("javac.switchratio");
|
||||
if (valStr != null) {
|
||||
try {
|
||||
double temp = Double.valueOf(valStr).doubleValue();
|
||||
if (!(Double.isNaN(temp) || temp < 0.0)) {
|
||||
ratio = temp;
|
||||
}
|
||||
} catch (NumberFormatException ee) {}
|
||||
}
|
||||
SWITCHRATIO = ratio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor
|
||||
*/
|
||||
public int getOpcode() {
|
||||
return pc;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Optimize
|
||||
*/
|
||||
void optimize(Environment env) {
|
||||
switch (opc) {
|
||||
case opc_istore: case opc_lstore: case opc_fstore:
|
||||
case opc_dstore: case opc_astore:
|
||||
// Don't keep the LocalVariable info around, unless we
|
||||
// are actually going to generate a local variable table.
|
||||
if ((value instanceof LocalVariable) && !env.debug_vars()) {
|
||||
value = new Integer(((LocalVariable)value).slot);
|
||||
}
|
||||
break;
|
||||
|
||||
case opc_goto: {
|
||||
Label lbl = (Label)value;
|
||||
value = lbl = lbl.getDestination();
|
||||
if (lbl == next) {
|
||||
// goto to the next instruction, obsolete
|
||||
opc = opc_dead;
|
||||
break;
|
||||
}
|
||||
|
||||
// We optimize
|
||||
//
|
||||
// goto Tag
|
||||
// ...
|
||||
// Tag:
|
||||
// return
|
||||
//
|
||||
// except when we're generating debuggable code. When
|
||||
// we're generating debuggable code, we leave it alone,
|
||||
// in order to provide better stepping behavior. Consider
|
||||
// a method the end of which looks like this:
|
||||
//
|
||||
// ...
|
||||
// break;
|
||||
// } // end of loop
|
||||
// } // end of method
|
||||
//
|
||||
// If we optimize the goto away, we'll be left with a
|
||||
// single instruction (return) and the need to ascribe that
|
||||
// instruction to two source lines (the break statement and
|
||||
// the method's right curly). Can't get there from here.
|
||||
// Depending on which line-number ascription we choose, the
|
||||
// stepping user will step directly from the break statement
|
||||
// back into the caller of the method (case 1) or from the
|
||||
// statement that precedes the break statement to the method's
|
||||
// right curly (case 2). Similarly, he'll be able to set a
|
||||
// breakpoint on the break statement (case 1) or the method's
|
||||
// right curly (case 2), but not on both. Neither case 1 nor
|
||||
// case 2 is desirable. .We want him to see both the break
|
||||
// statement and the method's right curly when stepping,
|
||||
// and we want him to be able to set a breakpoint on either or
|
||||
// both. So we suppress the optimization when generating
|
||||
// debuggable code.
|
||||
// (Above notes from brucek@eng in JDK1.0.2, copied here
|
||||
// by kelly.ohair@eng for JDK1.1)
|
||||
//
|
||||
// With the changes to allow -O and -g at the same time,
|
||||
// I've changed the condition to be whether optimization is
|
||||
// on instead of the debugging flag being off.
|
||||
// - david.stoutamire@eng for 1.2
|
||||
|
||||
if (lbl.next != null && env.opt()) {
|
||||
switch (lbl.next.opc) {
|
||||
case opc_return: case opc_ireturn: case opc_lreturn:
|
||||
case opc_freturn: case opc_dreturn: case opc_areturn:
|
||||
// goto to return
|
||||
opc = lbl.next.opc;
|
||||
value = lbl.next.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_ifeq: case opc_ifne: case opc_ifgt:
|
||||
case opc_ifge: case opc_iflt: case opc_ifle:
|
||||
case opc_ifnull: case opc_ifnonnull:
|
||||
value = ((Label)value).getDestination();
|
||||
if (value == next) {
|
||||
// branch to next instruction, obsolete
|
||||
opc = opc_pop;
|
||||
break;
|
||||
}
|
||||
if ((next.opc == opc_goto) && (value == next.next)) {
|
||||
// Conditional branch over goto, invert
|
||||
// Note that you can't invert all conditions, condition
|
||||
// results for float/double compares are not invertable.
|
||||
switch (opc) {
|
||||
case opc_ifeq: opc = opc_ifne; break;
|
||||
case opc_ifne: opc = opc_ifeq; break;
|
||||
case opc_iflt: opc = opc_ifge; break;
|
||||
case opc_ifle: opc = opc_ifgt; break;
|
||||
case opc_ifgt: opc = opc_ifle; break;
|
||||
case opc_ifge: opc = opc_iflt; break;
|
||||
case opc_ifnull: opc = opc_ifnonnull; break;
|
||||
case opc_ifnonnull: opc = opc_ifnull; break;
|
||||
}
|
||||
//JCOV
|
||||
flagCondInverted = !flagCondInverted;
|
||||
//end JCOV
|
||||
value = next.value;
|
||||
next.opc = opc_dead;
|
||||
}
|
||||
break;
|
||||
|
||||
case opc_if_acmpeq: case opc_if_acmpne:
|
||||
case opc_if_icmpeq: case opc_if_icmpne:
|
||||
case opc_if_icmpgt: case opc_if_icmpge:
|
||||
case opc_if_icmplt: case opc_if_icmple:
|
||||
value = ((Label)value).getDestination();
|
||||
if (value == next) {
|
||||
// branch to next instruction, obsolete
|
||||
opc = opc_pop2;
|
||||
break;
|
||||
}
|
||||
if ((next.opc == opc_goto) && (value == next.next)) {
|
||||
// Conditional branch over goto, invert
|
||||
switch (opc) {
|
||||
case opc_if_acmpeq: opc = opc_if_acmpne; break;
|
||||
case opc_if_acmpne: opc = opc_if_acmpeq; break;
|
||||
case opc_if_icmpeq: opc = opc_if_icmpne; break;
|
||||
case opc_if_icmpne: opc = opc_if_icmpeq; break;
|
||||
case opc_if_icmpgt: opc = opc_if_icmple; break;
|
||||
case opc_if_icmpge: opc = opc_if_icmplt; break;
|
||||
case opc_if_icmplt: opc = opc_if_icmpge; break;
|
||||
case opc_if_icmple: opc = opc_if_icmpgt; break;
|
||||
}
|
||||
//JCOV
|
||||
flagCondInverted = !flagCondInverted;
|
||||
//end JCOV
|
||||
value = next.value;
|
||||
next.opc = opc_dead;
|
||||
}
|
||||
break;
|
||||
|
||||
case opc_tableswitch:
|
||||
case opc_lookupswitch: {
|
||||
SwitchData sw = (SwitchData)value;
|
||||
sw.defaultLabel = sw.defaultLabel.getDestination();
|
||||
for (Enumeration<Integer> e = sw.tab.keys() ; e.hasMoreElements() ; ) {
|
||||
Integer k = e.nextElement();
|
||||
Label lbl = sw.tab.get(k);
|
||||
sw.tab.put(k, lbl.getDestination());
|
||||
}
|
||||
|
||||
// Compute the approximate sizes of a tableswitch and a
|
||||
// lookupswitch. Decide which one we want to generate.
|
||||
|
||||
long range = (long)sw.maxValue - (long)sw.minValue + 1;
|
||||
long entries = sw.tab.size();
|
||||
|
||||
long tableSize = 4 + range;
|
||||
long lookupSize = 3 + 2 * entries;
|
||||
|
||||
if (tableSize <= lookupSize * SWITCHRATIO) {
|
||||
opc = opc_tableswitch;
|
||||
} else {
|
||||
opc = opc_lookupswitch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect constants into the constant table
|
||||
*/
|
||||
void collect(ConstantPool tab) {
|
||||
switch (opc) {
|
||||
case opc_istore: case opc_lstore: case opc_fstore:
|
||||
case opc_dstore: case opc_astore:
|
||||
if (value instanceof LocalVariable) {
|
||||
MemberDefinition field = ((LocalVariable)value).field;
|
||||
tab.put(field.getName().toString());
|
||||
tab.put(field.getType().getTypeSignature());
|
||||
}
|
||||
return;
|
||||
|
||||
case opc_new: case opc_putfield:
|
||||
case opc_putstatic: case opc_getfield:
|
||||
case opc_getstatic: case opc_invokevirtual:
|
||||
case opc_invokespecial: case opc_invokestatic:
|
||||
case opc_invokeinterface: case opc_instanceof:
|
||||
case opc_checkcast:
|
||||
tab.put(value);
|
||||
return;
|
||||
|
||||
case opc_anewarray:
|
||||
tab.put(value);
|
||||
return;
|
||||
|
||||
case opc_multianewarray:
|
||||
tab.put(((ArrayData)value).type);
|
||||
return;
|
||||
|
||||
case opc_ldc:
|
||||
case opc_ldc_w:
|
||||
if (value instanceof Integer) {
|
||||
int v = ((Integer)value).intValue();
|
||||
if ((v >= -1) && (v <= 5)) {
|
||||
opc = opc_iconst_0 + v;
|
||||
return;
|
||||
} else if ((v >= -(1 << 7)) && (v < (1 << 7))) {
|
||||
opc = opc_bipush;
|
||||
return;
|
||||
} else if ((v >= -(1 << 15)) && (v < (1 << 15))) {
|
||||
opc = opc_sipush;
|
||||
return;
|
||||
}
|
||||
} else if (value instanceof Float) {
|
||||
float v = ((Float)value).floatValue();
|
||||
if (v == 0) {
|
||||
if (Float.floatToIntBits(v) == 0) {
|
||||
opc = opc_fconst_0;
|
||||
return;
|
||||
}
|
||||
} else if (v == 1) {
|
||||
opc = opc_fconst_1;
|
||||
return;
|
||||
} else if (v == 2) {
|
||||
opc = opc_fconst_2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
tab.put(value);
|
||||
return;
|
||||
|
||||
case opc_ldc2_w:
|
||||
if (value instanceof Long) {
|
||||
long v = ((Long)value).longValue();
|
||||
if (v == 0) {
|
||||
opc = opc_lconst_0;
|
||||
return;
|
||||
} else if (v == 1) {
|
||||
opc = opc_lconst_1;
|
||||
return;
|
||||
}
|
||||
} else if (value instanceof Double) {
|
||||
double v = ((Double)value).doubleValue();
|
||||
if (v == 0) {
|
||||
if (Double.doubleToLongBits(v) == 0) {
|
||||
opc = opc_dconst_0;
|
||||
return;
|
||||
}
|
||||
} else if (v == 1) {
|
||||
opc = opc_dconst_1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
tab.put(value);
|
||||
return;
|
||||
|
||||
case opc_try:
|
||||
for (Enumeration<CatchData> e = ((TryData)value).catches.elements() ; e.hasMoreElements() ;) {
|
||||
CatchData cd = e.nextElement();
|
||||
if (cd.getType() != null) {
|
||||
tab.put(cd.getType());
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case opc_nop:
|
||||
if ((value != null) && (value instanceof ClassDeclaration))
|
||||
tab.put(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Balance the stack
|
||||
*/
|
||||
int balance() {
|
||||
switch (opc) {
|
||||
case opc_dead: case opc_label: case opc_iinc:
|
||||
case opc_arraylength: case opc_laload: case opc_daload:
|
||||
case opc_nop: case opc_ineg: case opc_fneg:
|
||||
case opc_lneg: case opc_dneg: case opc_i2f:
|
||||
case opc_f2i: case opc_l2d: case opc_d2l:
|
||||
case opc_i2b: case opc_i2c: case opc_i2s:
|
||||
case opc_jsr: case opc_goto: case opc_jsr_w:
|
||||
case opc_goto_w: case opc_return: case opc_ret:
|
||||
case opc_instanceof: case opc_checkcast: case opc_newarray:
|
||||
case opc_anewarray: case opc_try: case opc_swap:
|
||||
return 0;
|
||||
|
||||
case opc_ldc: case opc_ldc_w: case opc_bipush:
|
||||
case opc_sipush: case opc_aconst_null: case opc_iconst_m1:
|
||||
case opc_iconst_0: case opc_iconst_1: case opc_iconst_2:
|
||||
case opc_iconst_3: case opc_iconst_4: case opc_iconst_5:
|
||||
case opc_fconst_0: case opc_fconst_1: case opc_fconst_2:
|
||||
case opc_iload: case opc_fload: case opc_aload:
|
||||
case opc_dup: case opc_dup_x1: case opc_dup_x2:
|
||||
case opc_i2l: case opc_i2d: case opc_f2l:
|
||||
case opc_f2d: case opc_new:
|
||||
return 1;
|
||||
|
||||
case opc_lload: case opc_dload: case opc_dup2:
|
||||
case opc_dup2_x1: case opc_dup2_x2: case opc_ldc2_w:
|
||||
case opc_lconst_0: case opc_lconst_1: case opc_dconst_0:
|
||||
case opc_dconst_1:
|
||||
return 2;
|
||||
|
||||
case opc_istore: case opc_fstore: case opc_astore:
|
||||
case opc_iaload: case opc_faload: case opc_aaload:
|
||||
case opc_baload: case opc_caload: case opc_saload:
|
||||
case opc_pop: case opc_iadd: case opc_fadd:
|
||||
case opc_isub: case opc_fsub: case opc_imul:
|
||||
case opc_fmul: case opc_idiv: case opc_fdiv:
|
||||
case opc_irem: case opc_frem: case opc_ishl:
|
||||
case opc_ishr: case opc_iushr: case opc_lshl:
|
||||
case opc_lshr: case opc_lushr: case opc_iand:
|
||||
case opc_ior: case opc_ixor: case opc_l2i:
|
||||
case opc_l2f: case opc_d2i: case opc_d2f:
|
||||
case opc_ifeq: case opc_ifne: case opc_iflt:
|
||||
case opc_ifle: case opc_ifgt: case opc_ifge:
|
||||
case opc_ifnull: case opc_ifnonnull: case opc_fcmpl:
|
||||
case opc_fcmpg: case opc_ireturn: case opc_freturn:
|
||||
case opc_areturn: case opc_tableswitch: case opc_lookupswitch:
|
||||
case opc_athrow: case opc_monitorenter: case opc_monitorexit:
|
||||
return -1;
|
||||
|
||||
case opc_lstore: case opc_dstore: case opc_pop2:
|
||||
case opc_ladd: case opc_dadd: case opc_lsub:
|
||||
case opc_dsub: case opc_lmul: case opc_dmul:
|
||||
case opc_ldiv: case opc_ddiv: case opc_lrem:
|
||||
case opc_drem: case opc_land: case opc_lor:
|
||||
case opc_lxor: case opc_if_acmpeq: case opc_if_acmpne:
|
||||
case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt:
|
||||
case opc_if_icmple: case opc_if_icmpgt: case opc_if_icmpge:
|
||||
case opc_lreturn: case opc_dreturn:
|
||||
return -2;
|
||||
|
||||
case opc_iastore: case opc_fastore: case opc_aastore:
|
||||
case opc_bastore: case opc_castore: case opc_sastore:
|
||||
case opc_lcmp: case opc_dcmpl: case opc_dcmpg:
|
||||
return -3;
|
||||
|
||||
case opc_lastore: case opc_dastore:
|
||||
return -4;
|
||||
|
||||
case opc_multianewarray:
|
||||
return 1 - ((ArrayData)value).nargs;
|
||||
|
||||
case opc_getfield:
|
||||
return ((MemberDefinition)value).getType().stackSize() - 1;
|
||||
|
||||
case opc_putfield:
|
||||
return -1 - ((MemberDefinition)value).getType().stackSize();
|
||||
|
||||
case opc_getstatic:
|
||||
return ((MemberDefinition)value).getType().stackSize();
|
||||
|
||||
case opc_putstatic:
|
||||
return -((MemberDefinition)value).getType().stackSize();
|
||||
|
||||
case opc_invokevirtual:
|
||||
case opc_invokespecial:
|
||||
case opc_invokeinterface:
|
||||
return ((MemberDefinition)value).getType().getReturnType().stackSize() -
|
||||
(((MemberDefinition)value).getType().stackSize() + 1);
|
||||
|
||||
case opc_invokestatic:
|
||||
return ((MemberDefinition)value).getType().getReturnType().stackSize() -
|
||||
(((MemberDefinition)value).getType().stackSize());
|
||||
}
|
||||
throw new CompilerError("invalid opcode: " + toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the instruction
|
||||
*/
|
||||
int size(ConstantPool tab) {
|
||||
switch (opc) {
|
||||
case opc_try: case opc_label: case opc_dead:
|
||||
return 0;
|
||||
|
||||
case opc_bipush: case opc_newarray:
|
||||
return 2;
|
||||
|
||||
case opc_sipush: case opc_goto: case opc_jsr:
|
||||
case opc_ifeq: case opc_ifne: case opc_ifgt:
|
||||
case opc_ifge: case opc_iflt: case opc_ifle:
|
||||
case opc_ifnull: case opc_ifnonnull: case opc_if_acmpeq:
|
||||
case opc_if_acmpne: case opc_if_icmpeq: case opc_if_icmpne:
|
||||
case opc_if_icmpgt: case opc_if_icmpge: case opc_if_icmplt:
|
||||
case opc_if_icmple:
|
||||
return 3;
|
||||
|
||||
case opc_ldc:
|
||||
case opc_ldc_w:
|
||||
if (tab.index(value) < 256) {
|
||||
opc = opc_ldc;
|
||||
return 2;
|
||||
} else {
|
||||
opc = opc_ldc_w;
|
||||
return 3;
|
||||
}
|
||||
|
||||
case opc_iload: case opc_lload: case opc_fload:
|
||||
case opc_dload: case opc_aload: {
|
||||
int v = ((Number)value).intValue();
|
||||
if (v < 4) {
|
||||
if (v < 0) {
|
||||
throw new CompilerError("invalid slot: " + toString()
|
||||
+ "\nThis error possibly resulted from poorly constructed class paths.");
|
||||
}
|
||||
opc = opc_iload_0 + (opc - opc_iload) * 4 + v;
|
||||
return 1;
|
||||
} else if (v <= 255) {
|
||||
return 2;
|
||||
} else {
|
||||
opc += 256; // indicate wide variant
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
case opc_iinc: {
|
||||
int register = ((int[])value)[0];
|
||||
int increment = ((int[])value)[1];
|
||||
if (register < 0) {
|
||||
throw new CompilerError("invalid slot: " + toString());
|
||||
}
|
||||
if (register <= 255 && (((byte)increment) == increment)) {
|
||||
return 3;
|
||||
} else {
|
||||
opc += 256; // indicate wide variant
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
case opc_istore: case opc_lstore: case opc_fstore:
|
||||
case opc_dstore: case opc_astore: {
|
||||
int v = (value instanceof Number) ?
|
||||
((Number)value).intValue() : ((LocalVariable)value).slot;
|
||||
if (v < 4) {
|
||||
if (v < 0) {
|
||||
throw new CompilerError("invalid slot: " + toString());
|
||||
}
|
||||
opc = opc_istore_0 + (opc - opc_istore) * 4 + v;
|
||||
return 1;
|
||||
} else if (v <= 255) {
|
||||
return 2;
|
||||
} else {
|
||||
opc += 256; // indicate wide variant
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
case opc_ret: {
|
||||
int v = ((Number)value).intValue();
|
||||
if (v <= 255) {
|
||||
if (v < 0) {
|
||||
throw new CompilerError("invalid slot: " + toString());
|
||||
}
|
||||
return 2;
|
||||
} else {
|
||||
opc += 256; // indicate wide variant
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
case opc_ldc2_w: case opc_new:
|
||||
case opc_putstatic: case opc_getstatic:
|
||||
case opc_putfield: case opc_getfield:
|
||||
case opc_invokevirtual: case opc_invokespecial:
|
||||
case opc_invokestatic: case opc_instanceof:
|
||||
case opc_checkcast: case opc_anewarray:
|
||||
return 3;
|
||||
|
||||
case opc_multianewarray:
|
||||
return 4;
|
||||
|
||||
case opc_invokeinterface:
|
||||
case opc_goto_w:
|
||||
case opc_jsr_w:
|
||||
return 5;
|
||||
|
||||
case opc_tableswitch: {
|
||||
SwitchData sw = (SwitchData)value;
|
||||
int n = 1;
|
||||
for(; ((pc + n) % 4) != 0 ; n++);
|
||||
return n + 16 + (sw.maxValue - sw.minValue) * 4;
|
||||
}
|
||||
|
||||
case opc_lookupswitch: {
|
||||
SwitchData sw = (SwitchData)value;
|
||||
int n = 1;
|
||||
for(; ((pc + n) % 4) != 0 ; n++);
|
||||
return n + 8 + sw.tab.size() * 8;
|
||||
}
|
||||
|
||||
case opc_nop:
|
||||
if ((value != null) && !(value instanceof Integer))
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
// most opcodes are only 1 byte long
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate code
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
void write(DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
switch (opc) {
|
||||
case opc_try: case opc_label: case opc_dead:
|
||||
break;
|
||||
|
||||
case opc_bipush: case opc_newarray:
|
||||
case opc_iload: case opc_lload: case opc_fload:
|
||||
case opc_dload: case opc_aload: case opc_ret:
|
||||
out.writeByte(opc);
|
||||
out.writeByte(((Number)value).intValue());
|
||||
break;
|
||||
|
||||
case opc_iload + 256: case opc_lload + 256:
|
||||
case opc_fload + 256: case opc_dload + 256:
|
||||
case opc_aload + 256: case opc_ret + 256:
|
||||
out.writeByte(opc_wide);
|
||||
out.writeByte(opc - 256);
|
||||
out.writeShort(((Number)value).intValue());
|
||||
break;
|
||||
|
||||
case opc_istore: case opc_lstore: case opc_fstore:
|
||||
case opc_dstore: case opc_astore:
|
||||
out.writeByte(opc);
|
||||
out.writeByte((value instanceof Number) ?
|
||||
((Number)value).intValue() : ((LocalVariable)value).slot);
|
||||
break;
|
||||
|
||||
case opc_istore + 256: case opc_lstore + 256:
|
||||
case opc_fstore + 256: case opc_dstore + 256:
|
||||
case opc_astore + 256:
|
||||
out.writeByte(opc_wide);
|
||||
out.writeByte(opc - 256);
|
||||
out.writeShort((value instanceof Number) ?
|
||||
((Number)value).intValue() : ((LocalVariable)value).slot);
|
||||
break;
|
||||
|
||||
case opc_sipush:
|
||||
out.writeByte(opc);
|
||||
out.writeShort(((Number)value).intValue());
|
||||
break;
|
||||
|
||||
case opc_ldc:
|
||||
out.writeByte(opc);
|
||||
out.writeByte(tab.index(value));
|
||||
break;
|
||||
|
||||
case opc_ldc_w: case opc_ldc2_w:
|
||||
case opc_new: case opc_putstatic:
|
||||
case opc_getstatic: case opc_putfield:
|
||||
case opc_getfield: case opc_invokevirtual:
|
||||
case opc_invokespecial: case opc_invokestatic:
|
||||
case opc_instanceof: case opc_checkcast:
|
||||
out.writeByte(opc);
|
||||
out.writeShort(tab.index(value));
|
||||
break;
|
||||
|
||||
case opc_iinc:
|
||||
out.writeByte(opc);
|
||||
out.writeByte(((int[])value)[0]); // register
|
||||
out.writeByte(((int[])value)[1]); // increment
|
||||
break;
|
||||
|
||||
case opc_iinc + 256:
|
||||
out.writeByte(opc_wide);
|
||||
out.writeByte(opc - 256);
|
||||
out.writeShort(((int[])value)[0]); // register
|
||||
out.writeShort(((int[])value)[1]); // increment
|
||||
break;
|
||||
|
||||
case opc_anewarray:
|
||||
out.writeByte(opc);
|
||||
out.writeShort(tab.index(value));
|
||||
break;
|
||||
|
||||
case opc_multianewarray:
|
||||
out.writeByte(opc);
|
||||
out.writeShort(tab.index(((ArrayData)value).type));
|
||||
out.writeByte(((ArrayData)value).nargs);
|
||||
break;
|
||||
|
||||
case opc_invokeinterface:
|
||||
out.writeByte(opc);
|
||||
out.writeShort(tab.index(value));
|
||||
out.writeByte(((MemberDefinition)value).getType().stackSize() + 1);
|
||||
out.writeByte(0);
|
||||
break;
|
||||
|
||||
case opc_goto: case opc_jsr: case opc_ifeq:
|
||||
case opc_ifne: case opc_ifgt: case opc_ifge:
|
||||
case opc_iflt: case opc_ifle: case opc_ifnull:
|
||||
case opc_ifnonnull: case opc_if_acmpeq: case opc_if_acmpne:
|
||||
case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpgt:
|
||||
case opc_if_icmpge: case opc_if_icmplt: case opc_if_icmple:
|
||||
out.writeByte(opc);
|
||||
out.writeShort(((Instruction)value).pc - pc);
|
||||
break;
|
||||
|
||||
case opc_goto_w:
|
||||
case opc_jsr_w:
|
||||
out.writeByte(opc);
|
||||
out.writeLong(((Instruction)value).pc - pc);
|
||||
break;
|
||||
|
||||
case opc_tableswitch: {
|
||||
SwitchData sw = (SwitchData)value;
|
||||
out.writeByte(opc);
|
||||
for(int n = 1 ; ((pc + n) % 4) != 0 ; n++) {
|
||||
out.writeByte(0);
|
||||
}
|
||||
out.writeInt(sw.defaultLabel.pc - pc);
|
||||
out.writeInt(sw.minValue);
|
||||
out.writeInt(sw.maxValue);
|
||||
for (int n = sw.minValue ; n <= sw.maxValue ; n++) {
|
||||
Label lbl = sw.get(n);
|
||||
int target_pc = (lbl != null) ? lbl.pc : sw.defaultLabel.pc;
|
||||
out.writeInt(target_pc - pc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_lookupswitch: {
|
||||
SwitchData sw = (SwitchData)value;
|
||||
out.writeByte(opc);
|
||||
int n = pc + 1;
|
||||
for(; (n % 4) != 0 ; n++) {
|
||||
out.writeByte(0);
|
||||
}
|
||||
out.writeInt(sw.defaultLabel.pc - pc);
|
||||
out.writeInt(sw.tab.size());
|
||||
for (Enumeration<Integer> e = sw.sortedKeys(); e.hasMoreElements() ; ) {
|
||||
Integer v = e.nextElement();
|
||||
out.writeInt(v.intValue());
|
||||
out.writeInt(sw.get(v).pc - pc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case opc_nop:
|
||||
if (value != null) {
|
||||
if (value instanceof Integer)
|
||||
out.writeByte(((Integer)value).intValue());
|
||||
else
|
||||
out.writeShort(tab.index(value));
|
||||
return;
|
||||
}
|
||||
// fall through
|
||||
|
||||
default:
|
||||
out.writeByte(opc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* toString
|
||||
*/
|
||||
public String toString() {
|
||||
String prefix = (where >> WHEREOFFSETBITS) + ":\t";
|
||||
switch (opc) {
|
||||
case opc_try:
|
||||
return prefix + "try " + ((TryData)value).getEndLabel().hashCode();
|
||||
|
||||
case opc_dead:
|
||||
return prefix + "dead";
|
||||
|
||||
case opc_iinc: {
|
||||
int register = ((int[])value)[0];
|
||||
int increment = ((int[])value)[1];
|
||||
return prefix + opcNames[opc] + " " + register + ", " + increment;
|
||||
}
|
||||
|
||||
default:
|
||||
if (value != null) {
|
||||
if (value instanceof Label) {
|
||||
return prefix + opcNames[opc] + " " + value.toString();
|
||||
} else if (value instanceof Instruction) {
|
||||
return prefix + opcNames[opc] + " " + value.hashCode();
|
||||
} else if (value instanceof String) {
|
||||
return prefix + opcNames[opc] + " \"" + value + "\"";
|
||||
} else {
|
||||
return prefix + opcNames[opc] + " " + value;
|
||||
}
|
||||
} else {
|
||||
return prefix + opcNames[opc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
jdkSrc/jdk8/sun/tools/asm/Label.java
Normal file
117
jdkSrc/jdk8/sun/tools/asm/Label.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.MemberDefinition;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* A label instruction. This is a 0 size instruction.
|
||||
* It is the only valid target of a branch instruction.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class Label extends Instruction {
|
||||
static int labelCount = 0;
|
||||
int ID;
|
||||
int depth;
|
||||
MemberDefinition locals[];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Label() {
|
||||
super(0, opc_label, null);
|
||||
this.ID = ++labelCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the final destination, eliminate jumps gotos, and jumps to
|
||||
* labels that are immediately folowed by another label. The depth
|
||||
* field is used to leave bread crumbs to avoid infinite loops.
|
||||
*/
|
||||
Label getDestination() {
|
||||
Label lbl = this;
|
||||
if ((next != null) && (next != this) && (depth == 0)) {
|
||||
depth = 1;
|
||||
|
||||
switch (next.opc) {
|
||||
case opc_label:
|
||||
lbl = ((Label)next).getDestination();
|
||||
break;
|
||||
|
||||
case opc_goto:
|
||||
lbl = ((Label)next.value).getDestination();
|
||||
break;
|
||||
|
||||
case opc_ldc:
|
||||
case opc_ldc_w:
|
||||
if (next.value instanceof Integer) {
|
||||
Instruction inst = next.next;
|
||||
if (inst.opc == opc_label) {
|
||||
inst = ((Label)inst).getDestination().next;
|
||||
}
|
||||
|
||||
if (inst.opc == opc_ifeq) {
|
||||
if (((Integer)next.value).intValue() == 0) {
|
||||
lbl = (Label)inst.value;
|
||||
} else {
|
||||
lbl = new Label();
|
||||
lbl.next = inst.next;
|
||||
inst.next = lbl;
|
||||
}
|
||||
lbl = lbl.getDestination();
|
||||
break;
|
||||
}
|
||||
if (inst.opc == opc_ifne) {
|
||||
if (((Integer)next.value).intValue() == 0) {
|
||||
lbl = new Label();
|
||||
lbl.next = inst.next;
|
||||
inst.next = lbl;
|
||||
} else {
|
||||
lbl = (Label)inst.value;
|
||||
}
|
||||
lbl = lbl.getDestination();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
depth = 0;
|
||||
}
|
||||
return lbl;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String s = "$" + ID + ":";
|
||||
if (value != null)
|
||||
s = s + " stack=" + value;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
66
jdkSrc/jdk8/sun/tools/asm/LocalVariable.java
Normal file
66
jdkSrc/jdk8/sun/tools/asm/LocalVariable.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
|
||||
/**
|
||||
* This class is used to assemble the local variables in the local
|
||||
* variable table.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public final
|
||||
class LocalVariable {
|
||||
MemberDefinition field;
|
||||
int slot;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
public LocalVariable(MemberDefinition field, int slot) {
|
||||
if (field == null) {
|
||||
new Exception().printStackTrace();
|
||||
}
|
||||
this.field = field;
|
||||
this.slot = slot;
|
||||
to = -1;
|
||||
}
|
||||
|
||||
LocalVariable(MemberDefinition field, int slot, int from, int to) {
|
||||
this.field = field;
|
||||
this.slot = slot;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return field + "/" + slot;
|
||||
}
|
||||
}
|
||||
132
jdkSrc/jdk8/sun/tools/asm/LocalVariableTable.java
Normal file
132
jdkSrc/jdk8/sun/tools/asm/LocalVariableTable.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* This class is used to assemble the local variable table.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
final
|
||||
class LocalVariableTable {
|
||||
LocalVariable locals[] = new LocalVariable[8];
|
||||
int len;
|
||||
|
||||
/**
|
||||
* Define a new local variable. Merge entries where possible.
|
||||
*/
|
||||
void define(MemberDefinition field, int slot, int from, int to) {
|
||||
if (from >= to) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0 ; i < len ; i++) {
|
||||
if ((locals[i].field == field) && (locals[i].slot == slot) &&
|
||||
(from <= locals[i].to) && (to >= locals[i].from)) {
|
||||
locals[i].from = Math.min(locals[i].from, from);
|
||||
locals[i].to = Math.max(locals[i].to, to);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (len == locals.length) {
|
||||
LocalVariable newlocals[] = new LocalVariable[len * 2];
|
||||
System.arraycopy(locals, 0, newlocals, 0, len);
|
||||
locals = newlocals;
|
||||
}
|
||||
locals[len++] = new LocalVariable(field, slot, from, to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim overlapping local ranges. Java forbids shadowing of
|
||||
* locals in nested scopes, but non-nested scopes may still declare
|
||||
* locals with the same name. Because local variable ranges are
|
||||
* computed using flow analysis as part of assembly, it isn't
|
||||
* possible to simply make sure variable ranges end where the
|
||||
* enclosing lexical scope ends. This method makes sure that
|
||||
* variables with the same name don't overlap, giving priority to
|
||||
* fields with higher slot numbers that should have appeared later
|
||||
* in the source.
|
||||
*/
|
||||
private void trim_ranges() {
|
||||
for (int i=0; i<len; i++) {
|
||||
for (int j=i+1; j<len; j++) {
|
||||
if ((locals[i].field.getName()==locals[j].field.getName())
|
||||
&& (locals[i].from <= locals[j].to)
|
||||
&& (locals[i].to >= locals[j].from)) {
|
||||
// At this point we know that both ranges are
|
||||
// the same name and there is also overlap or they abut
|
||||
if (locals[i].slot < locals[j].slot) {
|
||||
if (locals[i].from < locals[j].from) {
|
||||
locals[i].to = Math.min(locals[i].to, locals[j].from);
|
||||
} else {
|
||||
// We've detected two local variables with the
|
||||
// same name, and the one with the greater slot
|
||||
// number starts before the other. This order
|
||||
// reversal may happen with locals with the same
|
||||
// name declared in both a try body and an
|
||||
// associated catch clause. This is rare, and
|
||||
// we give up.
|
||||
}
|
||||
} else if (locals[i].slot > locals[j].slot) {
|
||||
if (locals[i].from > locals[j].from) {
|
||||
locals[j].to = Math.min(locals[j].to, locals[i].from);
|
||||
} else {
|
||||
// Same situation as above; just give up.
|
||||
}
|
||||
} else {
|
||||
// This case can happen if there are two variables
|
||||
// with the same name and slot numbers, and ranges
|
||||
// that abut. AFAIK the only way this can occur
|
||||
// is with multiple static initializers. Punt.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write out the data.
|
||||
*/
|
||||
void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
trim_ranges();
|
||||
out.writeShort(len);
|
||||
for (int i = 0 ; i < len ; i++) {
|
||||
//System.out.println("pc=" + locals[i].from + ", len=" + (locals[i].to - locals[i].from) + ", nm=" + locals[i].field.getName() + ", slot=" + locals[i].slot);
|
||||
out.writeShort(locals[i].from);
|
||||
out.writeShort(locals[i].to - locals[i].from);
|
||||
out.writeShort(tab.index(locals[i].field.getName().toString()));
|
||||
out.writeShort(tab.index(locals[i].field.getType().getTypeSignature()));
|
||||
out.writeShort(locals[i].slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
69
jdkSrc/jdk8/sun/tools/asm/NameAndTypeConstantData.java
Normal file
69
jdkSrc/jdk8/sun/tools/asm/NameAndTypeConstantData.java
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* This is a name and type constant pool data item
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
final
|
||||
class NameAndTypeConstantData extends ConstantPoolData {
|
||||
String name;
|
||||
String type;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
NameAndTypeConstantData(ConstantPool tab, NameAndTypeData nt) {
|
||||
name = nt.field.getName().toString();
|
||||
type = nt.field.getType().getTypeSignature();
|
||||
tab.put(name);
|
||||
tab.put(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the constant to the output stream
|
||||
*/
|
||||
void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
out.writeByte(CONSTANT_NAMEANDTYPE);
|
||||
out.writeShort(tab.index(name));
|
||||
out.writeShort(tab.index(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order of the constant
|
||||
*/
|
||||
int order() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
73
jdkSrc/jdk8/sun/tools/asm/NameAndTypeData.java
Normal file
73
jdkSrc/jdk8/sun/tools/asm/NameAndTypeData.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
|
||||
/**
|
||||
* An object to represent a name and type constant pool data item.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
final
|
||||
class NameAndTypeData {
|
||||
MemberDefinition field;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
NameAndTypeData(MemberDefinition field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashcode
|
||||
*/
|
||||
public int hashCode() {
|
||||
return field.getName().hashCode() * field.getType().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Equality
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof NameAndTypeData)) {
|
||||
NameAndTypeData nt = (NameAndTypeData)obj;
|
||||
return field.getName().equals(nt.field.getName()) &&
|
||||
field.getType().equals(nt.field.getType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to string
|
||||
*/
|
||||
public String toString() {
|
||||
return "%%" + field.toString() + "%%";
|
||||
}
|
||||
}
|
||||
81
jdkSrc/jdk8/sun/tools/asm/NumberConstantData.java
Normal file
81
jdkSrc/jdk8/sun/tools/asm/NumberConstantData.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* A numeric constant pool item. Can either be integer, float, long or double.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
final
|
||||
class NumberConstantData extends ConstantPoolData {
|
||||
Number num;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
NumberConstantData(ConstantPool tab, Number num) {
|
||||
this.num = num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the constant to the output stream
|
||||
*/
|
||||
void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
if (num instanceof Integer) {
|
||||
out.writeByte(CONSTANT_INTEGER);
|
||||
out.writeInt(num.intValue());
|
||||
} else if (num instanceof Long) {
|
||||
out.writeByte(CONSTANT_LONG);
|
||||
out.writeLong(num.longValue());
|
||||
} else if (num instanceof Float) {
|
||||
out.writeByte(CONSTANT_FLOAT);
|
||||
out.writeFloat(num.floatValue());
|
||||
} else if (num instanceof Double) {
|
||||
out.writeByte(CONSTANT_DOUBLE);
|
||||
out.writeDouble(num.doubleValue());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return the order of the constant
|
||||
*/
|
||||
int order() {
|
||||
return (width() == 1) ? 0 : 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of entries that it takes up in the constant pool
|
||||
*/
|
||||
int width() {
|
||||
return ((num instanceof Double) || (num instanceof Long)) ? 2 : 1;
|
||||
}
|
||||
}
|
||||
71
jdkSrc/jdk8/sun/tools/asm/StringConstantData.java
Normal file
71
jdkSrc/jdk8/sun/tools/asm/StringConstantData.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* This is a string constant pool data item.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
final
|
||||
class StringConstantData extends ConstantPoolData {
|
||||
String str;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
StringConstantData(ConstantPool tab, String str) {
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the constant to the output stream
|
||||
*/
|
||||
void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
out.writeByte(CONSTANT_UTF8);
|
||||
out.writeUTF(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order of the constant
|
||||
*/
|
||||
int order() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString
|
||||
*/
|
||||
public String toString() {
|
||||
return "StringConstantData[" + str + "]=" + str.hashCode();
|
||||
}
|
||||
}
|
||||
74
jdkSrc/jdk8/sun/tools/asm/StringExpressionConstantData.java
Normal file
74
jdkSrc/jdk8/sun/tools/asm/StringExpressionConstantData.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import sun.tools.tree.StringExpression;
|
||||
import java.io.IOException;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* This is a string expression constant. This constant
|
||||
* represents an Java string constant.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
final
|
||||
class StringExpressionConstantData extends ConstantPoolData {
|
||||
StringExpression str;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
StringExpressionConstantData(ConstantPool tab, StringExpression str) {
|
||||
this.str = str;
|
||||
tab.put(str.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the constant to the output stream
|
||||
*/
|
||||
void write(Environment env, DataOutputStream out, ConstantPool tab) throws IOException {
|
||||
out.writeByte(CONSTANT_STRING);
|
||||
out.writeShort(tab.index(str.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the order of the constant
|
||||
*/
|
||||
int order() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString
|
||||
*/
|
||||
public String toString() {
|
||||
return "StringExpressionConstantData[" + str.getValue() + "]=" + str.getValue().hashCode();
|
||||
}
|
||||
}
|
||||
149
jdkSrc/jdk8/sun/tools/asm/SwitchData.java
Normal file
149
jdkSrc/jdk8/sun/tools/asm/SwitchData.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class SwitchData {
|
||||
int minValue, maxValue;
|
||||
Label defaultLabel = new Label();
|
||||
Hashtable<Integer,Label> tab = new Hashtable<>();
|
||||
// JCOV
|
||||
Hashtable<Integer,Long> whereCaseTab = null;
|
||||
// end JCOV
|
||||
|
||||
/**
|
||||
* Get a label
|
||||
*/
|
||||
public Label get(int n) {
|
||||
return tab.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a label
|
||||
*/
|
||||
public Label get(Integer n) {
|
||||
return tab.get(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a label
|
||||
*/
|
||||
public void add(int n, Label lbl) {
|
||||
if (tab.size() == 0) {
|
||||
minValue = n;
|
||||
maxValue = n;
|
||||
} else {
|
||||
if (n < minValue) {
|
||||
minValue = n;
|
||||
}
|
||||
if (n > maxValue) {
|
||||
maxValue = n;
|
||||
}
|
||||
}
|
||||
tab.put(Integer.valueOf(n), lbl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default label
|
||||
*/
|
||||
public Label getDefaultLabel() {
|
||||
return defaultLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the keys of this enumaration sorted in ascending order
|
||||
*/
|
||||
public synchronized Enumeration<Integer> sortedKeys() {
|
||||
return new SwitchDataEnumeration(tab);
|
||||
}
|
||||
|
||||
// JCOV
|
||||
public void initTableCase() {
|
||||
whereCaseTab = new Hashtable<Integer,Long>();
|
||||
}
|
||||
public void addTableCase(int index, long where) {
|
||||
if (whereCaseTab != null)
|
||||
whereCaseTab.put(Integer.valueOf(index), Long.valueOf(where));
|
||||
}
|
||||
// this puts String key into Hashtable<Integer,Long>
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addTableDefault(long where) {
|
||||
if (whereCaseTab != null)
|
||||
((Hashtable)whereCaseTab).put("default", Long.valueOf(where));
|
||||
}
|
||||
public long whereCase(Object key) {
|
||||
Long i = whereCaseTab.get(key);
|
||||
return (i == null) ? 0L : i.longValue();
|
||||
}
|
||||
public boolean getDefault() {
|
||||
return (whereCase("default") != 0L);
|
||||
}
|
||||
// end JCOV
|
||||
}
|
||||
|
||||
class SwitchDataEnumeration implements Enumeration<Integer> {
|
||||
private Integer table[];
|
||||
private int current_index = 0;
|
||||
|
||||
/**
|
||||
* Create a new enumeration from the hashtable. Each key in the
|
||||
* hash table will be an Integer, with the value being a label. The
|
||||
* enumeration returns the keys in sorted order.
|
||||
*/
|
||||
SwitchDataEnumeration(Hashtable<Integer,Label> tab) {
|
||||
table = new Integer[tab.size()];
|
||||
int i = 0;
|
||||
for (Enumeration<Integer> e = tab.keys() ; e.hasMoreElements() ; ) {
|
||||
table[i++] = e.nextElement();
|
||||
}
|
||||
Arrays.sort(table);
|
||||
current_index = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are there more keys to return?
|
||||
*/
|
||||
public boolean hasMoreElements() {
|
||||
return current_index < table.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next key.
|
||||
*/
|
||||
public Integer nextElement() {
|
||||
return table[current_index++];
|
||||
}
|
||||
}
|
||||
63
jdkSrc/jdk8/sun/tools/asm/TryData.java
Normal file
63
jdkSrc/jdk8/sun/tools/asm/TryData.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.asm;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class TryData {
|
||||
Vector<CatchData> catches = new Vector<>();
|
||||
Label endLabel = new Label();
|
||||
|
||||
/**
|
||||
* Add a label
|
||||
*/
|
||||
public CatchData add(Object type) {
|
||||
CatchData cd = new CatchData(type);
|
||||
catches.addElement(cd);
|
||||
return cd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a label
|
||||
*/
|
||||
public CatchData getCatch(int n) {
|
||||
return catches.elementAt(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default label
|
||||
*/
|
||||
public Label getEndLabel() {
|
||||
return endLabel;
|
||||
}
|
||||
}
|
||||
181
jdkSrc/jdk8/sun/tools/attach/HotSpotAttachProvider.java
Normal file
181
jdkSrc/jdk8/sun/tools/attach/HotSpotAttachProvider.java
Normal file
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.AttachPermission;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import sun.jvmstat.monitor.HostIdentifier;
|
||||
import sun.jvmstat.monitor.Monitor;
|
||||
import sun.jvmstat.monitor.MonitoredHost;
|
||||
import sun.jvmstat.monitor.MonitoredVm;
|
||||
import sun.jvmstat.monitor.MonitoredVmUtil;
|
||||
import sun.jvmstat.monitor.VmIdentifier;
|
||||
import sun.jvmstat.monitor.MonitorException;
|
||||
|
||||
/*
|
||||
* Platform specific provider implementations extend this
|
||||
*/
|
||||
public abstract class HotSpotAttachProvider extends AttachProvider {
|
||||
|
||||
// perf count name for the JVM version
|
||||
private static final String JVM_VERSION = "java.property.java.vm.version";
|
||||
|
||||
public HotSpotAttachProvider() {
|
||||
}
|
||||
|
||||
public void checkAttachPermission() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(
|
||||
new AttachPermission("attachVirtualMachine")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This listVirtualMachines implementation is based on jvmstat. Can override
|
||||
* this in platform implementations when there is a more efficient mechanism
|
||||
* available.
|
||||
*/
|
||||
public List<VirtualMachineDescriptor> listVirtualMachines() {
|
||||
ArrayList<VirtualMachineDescriptor> result =
|
||||
new ArrayList<VirtualMachineDescriptor>();
|
||||
|
||||
MonitoredHost host;
|
||||
Set<Integer> vms;
|
||||
try {
|
||||
host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
|
||||
vms = host.activeVms();
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof ExceptionInInitializerError) {
|
||||
t = t.getCause();
|
||||
}
|
||||
if (t instanceof ThreadDeath) {
|
||||
throw (ThreadDeath)t;
|
||||
}
|
||||
if (t instanceof SecurityException) {
|
||||
return result;
|
||||
}
|
||||
throw new InternalError(t); // shouldn't happen
|
||||
}
|
||||
|
||||
for (Integer vmid: vms) {
|
||||
String pid = vmid.toString();
|
||||
String name = pid; // default to pid if name not available
|
||||
boolean isAttachable = false;
|
||||
MonitoredVm mvm = null;
|
||||
try {
|
||||
mvm = host.getMonitoredVm(new VmIdentifier(pid));
|
||||
try {
|
||||
isAttachable = MonitoredVmUtil.isAttachable(mvm);
|
||||
// use the command line as the display name
|
||||
name = MonitoredVmUtil.commandLine(mvm);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (isAttachable) {
|
||||
result.add(new HotSpotVirtualMachineDescriptor(this, pid, name));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof ThreadDeath) {
|
||||
throw (ThreadDeath)t;
|
||||
}
|
||||
} finally {
|
||||
if (mvm != null) {
|
||||
mvm.detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a VM is attachable. If it's not attachable,
|
||||
* an AttachNotSupportedException will be thrown. For example,
|
||||
* 1.4.2 or 5.0 VM are not attachable. There are cases that
|
||||
* we can't determine if a VM is attachable or not and this method
|
||||
* will just return.
|
||||
*
|
||||
* This method uses the jvmstat counter to determine if a VM
|
||||
* is attachable. If the target VM does not have a jvmstat
|
||||
* share memory buffer, this method returns.
|
||||
*
|
||||
* @exception AttachNotSupportedException if it's not attachable
|
||||
*/
|
||||
void testAttachable(String id) throws AttachNotSupportedException {
|
||||
MonitoredVm mvm = null;
|
||||
try {
|
||||
VmIdentifier vmid = new VmIdentifier(id);
|
||||
MonitoredHost host = MonitoredHost.getMonitoredHost(vmid);
|
||||
mvm = host.getMonitoredVm(vmid);
|
||||
|
||||
if (MonitoredVmUtil.isAttachable(mvm)) {
|
||||
// it's attachable; so return false
|
||||
return;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
if (t instanceof ThreadDeath) {
|
||||
ThreadDeath td = (ThreadDeath)t;
|
||||
throw td;
|
||||
}
|
||||
// we do not know what this id is
|
||||
return;
|
||||
} finally {
|
||||
if (mvm != null) {
|
||||
mvm.detach();
|
||||
}
|
||||
}
|
||||
|
||||
// we're sure it's not attachable; throw exception
|
||||
throw new AttachNotSupportedException(
|
||||
"The VM does not support the attach mechanism");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A virtual machine descriptor to describe a HotSpot virtual machine.
|
||||
*/
|
||||
static class HotSpotVirtualMachineDescriptor extends VirtualMachineDescriptor {
|
||||
HotSpotVirtualMachineDescriptor(AttachProvider provider,
|
||||
String id,
|
||||
String displayName) {
|
||||
super(provider, id, displayName);
|
||||
}
|
||||
|
||||
public boolean isAttachable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
358
jdkSrc/jdk8/sun/tools/attach/HotSpotVirtualMachine.java
Normal file
358
jdkSrc/jdk8/sun/tools/attach/HotSpotVirtualMachine.java
Normal file
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2023, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AgentInitializationException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/*
|
||||
* The HotSpot implementation of com.sun.tools.attach.VirtualMachine.
|
||||
*/
|
||||
|
||||
public abstract class HotSpotVirtualMachine extends VirtualMachine {
|
||||
|
||||
HotSpotVirtualMachine(AttachProvider provider, String id) {
|
||||
super(provider, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load agent library
|
||||
* If isAbsolute is true then the agent library is the absolute path
|
||||
* to the library and thus will not be expanded in the target VM.
|
||||
* if isAbsolute is false then the agent library is just a library
|
||||
* name and it will be expended in the target VM.
|
||||
*/
|
||||
private void loadAgentLibrary(String agentLibrary, boolean isAbsolute, String options)
|
||||
throws AgentLoadException, AgentInitializationException, IOException
|
||||
{
|
||||
InputStream in = execute("load",
|
||||
agentLibrary,
|
||||
isAbsolute ? "true" : "false",
|
||||
options);
|
||||
try {
|
||||
int result = readInt(in);
|
||||
if (result != 0) {
|
||||
throw new AgentInitializationException("Agent_OnAttach failed", result);
|
||||
}
|
||||
} finally {
|
||||
in.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Load agent library - library name will be expanded in target VM
|
||||
*/
|
||||
public void loadAgentLibrary(String agentLibrary, String options)
|
||||
throws AgentLoadException, AgentInitializationException, IOException
|
||||
{
|
||||
loadAgentLibrary(agentLibrary, false, options);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load agent - absolute path of library provided to target VM
|
||||
*/
|
||||
public void loadAgentPath(String agentLibrary, String options)
|
||||
throws AgentLoadException, AgentInitializationException, IOException
|
||||
{
|
||||
loadAgentLibrary(agentLibrary, true, options);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load JPLIS agent which will load the agent JAR file and invoke
|
||||
* the agentmain method.
|
||||
*/
|
||||
public void loadAgent(String agent, String options)
|
||||
throws AgentLoadException, AgentInitializationException, IOException
|
||||
{
|
||||
String args = agent;
|
||||
if (options != null) {
|
||||
args = args + "=" + options;
|
||||
}
|
||||
try {
|
||||
loadAgentLibrary("instrument", args);
|
||||
} catch (AgentLoadException x) {
|
||||
throw new InternalError("instrument library is missing in target VM", x);
|
||||
} catch (AgentInitializationException x) {
|
||||
/*
|
||||
* Translate interesting errors into the right exception and
|
||||
* message (FIXME: create a better interface to the instrument
|
||||
* implementation so this isn't necessary)
|
||||
*/
|
||||
int rc = x.returnValue();
|
||||
switch (rc) {
|
||||
case JNI_ENOMEM:
|
||||
throw new AgentLoadException("Insuffient memory");
|
||||
case ATTACH_ERROR_BADJAR:
|
||||
throw new AgentLoadException("Agent JAR not found or no Agent-Class attribute");
|
||||
case ATTACH_ERROR_NOTONCP:
|
||||
throw new AgentLoadException("Unable to add JAR file to system class path");
|
||||
case ATTACH_ERROR_STARTFAIL:
|
||||
throw new AgentInitializationException("Agent JAR loaded but agent failed to initialize");
|
||||
default :
|
||||
throw new AgentLoadException("Failed to load agent - unknown reason: " + rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The possible errors returned by JPLIS's agentmain
|
||||
*/
|
||||
private static final int JNI_ENOMEM = -4;
|
||||
private static final int ATTACH_ERROR_BADJAR = 100;
|
||||
private static final int ATTACH_ERROR_NOTONCP = 101;
|
||||
private static final int ATTACH_ERROR_STARTFAIL = 102;
|
||||
|
||||
|
||||
/*
|
||||
* Send "properties" command to target VM
|
||||
*/
|
||||
public Properties getSystemProperties() throws IOException {
|
||||
InputStream in = null;
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
in = executeCommand("properties");
|
||||
props.load(in);
|
||||
} finally {
|
||||
if (in != null) in.close();
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
public Properties getAgentProperties() throws IOException {
|
||||
InputStream in = null;
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
in = executeCommand("agentProperties");
|
||||
props.load(in);
|
||||
} finally {
|
||||
if (in != null) in.close();
|
||||
}
|
||||
return props;
|
||||
}
|
||||
|
||||
private static final String MANAGMENT_PREFIX = "com.sun.management.";
|
||||
|
||||
private static boolean checkedKeyName(Object key) {
|
||||
if (!(key instanceof String)) {
|
||||
throw new IllegalArgumentException("Invalid option (not a String): "+key);
|
||||
}
|
||||
if (!((String)key).startsWith(MANAGMENT_PREFIX)) {
|
||||
throw new IllegalArgumentException("Invalid option: "+key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String stripKeyName(Object key) {
|
||||
return ((String)key).substring(MANAGMENT_PREFIX.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startManagementAgent(Properties agentProperties) throws IOException {
|
||||
if (agentProperties == null) {
|
||||
throw new NullPointerException("agentProperties cannot be null");
|
||||
}
|
||||
// Convert the arguments into arguments suitable for the Diagnostic Command:
|
||||
// "ManagementAgent.start jmxremote.port=5555 jmxremote.authenticate=false"
|
||||
String args = agentProperties.entrySet().stream()
|
||||
.filter(entry -> checkedKeyName(entry.getKey()))
|
||||
.map(entry -> stripKeyName(entry.getKey()) + "=" + escape(entry.getValue()))
|
||||
.collect(Collectors.joining(" "));
|
||||
executeJCmd("ManagementAgent.start " + args);
|
||||
}
|
||||
|
||||
private String escape(Object arg) {
|
||||
String value = arg.toString();
|
||||
if (value.contains(" ")) {
|
||||
return "'" + value + "'";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String startLocalManagementAgent() throws IOException {
|
||||
executeJCmd("ManagementAgent.start_local");
|
||||
return getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
|
||||
}
|
||||
|
||||
// --- HotSpot specific methods ---
|
||||
|
||||
// same as SIGQUIT
|
||||
public void localDataDump() throws IOException {
|
||||
executeCommand("datadump").close();
|
||||
}
|
||||
|
||||
// Remote ctrl-break. The output of the ctrl-break actions can
|
||||
// be read from the input stream.
|
||||
public InputStream remoteDataDump(Object ... args) throws IOException {
|
||||
return executeCommand("threaddump", args);
|
||||
}
|
||||
|
||||
// Remote heap dump. The output (error message) can be read from the
|
||||
// returned input stream.
|
||||
public InputStream dumpHeap(Object ... args) throws IOException {
|
||||
return executeCommand("dumpheap", args);
|
||||
}
|
||||
|
||||
// Heap histogram (heap inspection in HotSpot)
|
||||
public InputStream heapHisto(Object ... args) throws IOException {
|
||||
return executeCommand("inspectheap", args);
|
||||
}
|
||||
|
||||
// set JVM command line flag
|
||||
public InputStream setFlag(String name, String value) throws IOException {
|
||||
return executeCommand("setflag", name, value);
|
||||
}
|
||||
|
||||
// print command line flag
|
||||
public InputStream printFlag(String name) throws IOException {
|
||||
return executeCommand("printflag", name);
|
||||
}
|
||||
|
||||
public InputStream executeJCmd(String command) throws IOException {
|
||||
return executeCommand("jcmd", command);
|
||||
}
|
||||
|
||||
// -- Supporting methods
|
||||
|
||||
|
||||
/*
|
||||
* Execute the given command in the target VM - specific platform
|
||||
* implementation must implement this.
|
||||
*/
|
||||
abstract InputStream execute(String cmd, Object ... args)
|
||||
throws AgentLoadException, IOException;
|
||||
|
||||
/*
|
||||
* Convenience method for simple commands
|
||||
*/
|
||||
private InputStream executeCommand(String cmd, Object ... args) throws IOException {
|
||||
try {
|
||||
return execute(cmd, args);
|
||||
} catch (AgentLoadException x) {
|
||||
throw new InternalError("Should not get here", x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Utility method to read an 'int' from the input stream. Ideally
|
||||
* we should be using java.util.Scanner here but this implementation
|
||||
* guarantees not to read ahead.
|
||||
*/
|
||||
int readInt(InputStream in) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// read to \n or EOF
|
||||
int n;
|
||||
byte buf[] = new byte[1];
|
||||
do {
|
||||
n = in.read(buf, 0, 1);
|
||||
if (n > 0) {
|
||||
char c = (char)buf[0];
|
||||
if (c == '\n') {
|
||||
break; // EOL found
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
} while (n > 0);
|
||||
|
||||
if (sb.length() == 0) {
|
||||
throw new IOException("Premature EOF");
|
||||
}
|
||||
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt(sb.toString());
|
||||
} catch (NumberFormatException x) {
|
||||
throw new IOException("Non-numeric value found - int expected");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility method to read data into a String.
|
||||
*/
|
||||
String readErrorMessage(InputStream sis) throws IOException {
|
||||
byte b[] = new byte[1024];
|
||||
int n;
|
||||
StringBuffer message = new StringBuffer();
|
||||
while ((n = sis.read(b)) != -1) {
|
||||
message.append(new String(b, 0, n, "UTF-8"));
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
|
||||
// -- attach timeout support
|
||||
|
||||
private static long defaultAttachTimeout = 5000;
|
||||
private volatile long attachTimeout;
|
||||
|
||||
/*
|
||||
* Return attach timeout based on the value of the sun.tools.attach.attachTimeout
|
||||
* property, or the default timeout if the property is not set to a positive
|
||||
* value.
|
||||
*/
|
||||
long attachTimeout() {
|
||||
if (attachTimeout == 0) {
|
||||
synchronized(this) {
|
||||
if (attachTimeout == 0) {
|
||||
try {
|
||||
String s =
|
||||
System.getProperty("sun.tools.attach.attachTimeout");
|
||||
attachTimeout = Long.parseLong(s);
|
||||
} catch (SecurityException se) {
|
||||
} catch (NumberFormatException ne) {
|
||||
}
|
||||
if (attachTimeout <= 0) {
|
||||
attachTimeout = defaultAttachTimeout;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return attachTimeout;
|
||||
}
|
||||
|
||||
protected static void checkNulls(Object... args) {
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof String) {
|
||||
String s = (String)arg;
|
||||
if (s.indexOf(0) >= 0) {
|
||||
throw new IllegalArgumentException("illegal null character in command");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
178
jdkSrc/jdk8/sun/tools/attach/WindowsAttachProvider.java
Normal file
178
jdkSrc/jdk8/sun/tools/attach/WindowsAttachProvider.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public class WindowsAttachProvider extends HotSpotAttachProvider {
|
||||
|
||||
public WindowsAttachProvider() {
|
||||
String os = System.getProperty("os.name");
|
||||
if (os.startsWith("Windows 9") || os.equals("Windows Me")) {
|
||||
throw new RuntimeException(
|
||||
"This provider is not supported on this version of Windows");
|
||||
}
|
||||
String arch = System.getProperty("os.arch");
|
||||
if (!arch.equals("x86") && !arch.equals("amd64")) {
|
||||
throw new RuntimeException(
|
||||
"This provider is not supported on this processor architecture");
|
||||
}
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "sun";
|
||||
}
|
||||
|
||||
public String type() {
|
||||
return "windows";
|
||||
}
|
||||
|
||||
public VirtualMachine attachVirtualMachine(String vmid)
|
||||
throws AttachNotSupportedException, IOException
|
||||
{
|
||||
checkAttachPermission();
|
||||
|
||||
// AttachNotSupportedException will be thrown if the target VM can be determined
|
||||
// to be not attachable.
|
||||
testAttachable(vmid);
|
||||
|
||||
return new WindowsVirtualMachine(this, vmid);
|
||||
}
|
||||
|
||||
public List<VirtualMachineDescriptor> listVirtualMachines() {
|
||||
// If the temporary file system is secure then we use the default
|
||||
// implementation, otherwise we create a list of Windows processes.
|
||||
if (isTempPathSecure()) {
|
||||
return super.listVirtualMachines();
|
||||
} else {
|
||||
return listJavaProcesses();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the temporary file system supports security
|
||||
*/
|
||||
private static boolean isTempPathSecure() {
|
||||
if (!wasTempPathChecked) {
|
||||
synchronized (WindowsAttachProvider.class) {
|
||||
if (!wasTempPathChecked) {
|
||||
// get the value of TMP/TEMP, ignoring UNC, and paths that
|
||||
// aren't absolute
|
||||
String temp = tempPath();
|
||||
if ((temp != null) && (temp.length() >= 3) &&
|
||||
(temp.charAt(1) == ':') && (temp.charAt(2) == '\\'))
|
||||
{
|
||||
// check if the volume supports security
|
||||
long flags = volumeFlags(temp.substring(0, 3));
|
||||
isTempPathSecure = ((flags & FS_PERSISTENT_ACLS) != 0);
|
||||
}
|
||||
wasTempPathChecked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isTempPathSecure;
|
||||
}
|
||||
|
||||
// flag to indicate persistent ACLs are supported
|
||||
private static final long FS_PERSISTENT_ACLS = 0x8L;
|
||||
|
||||
// indicates if we've checked the temporary file system
|
||||
private static volatile boolean wasTempPathChecked;
|
||||
|
||||
// indicates if the temporary file system is secure (only valid when
|
||||
// wasTempPathChecked is true)
|
||||
private static boolean isTempPathSecure;
|
||||
|
||||
// returns the value of TMP/TEMP
|
||||
private static native String tempPath();
|
||||
|
||||
// returns the flags for the given volume
|
||||
private static native long volumeFlags(String volume);
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of virtual machine descriptors derived from an enumeration
|
||||
* of the process list.
|
||||
*/
|
||||
private List<VirtualMachineDescriptor> listJavaProcesses() {
|
||||
ArrayList<VirtualMachineDescriptor> list =
|
||||
new ArrayList<VirtualMachineDescriptor>();
|
||||
|
||||
// Use localhost in the display name
|
||||
String host = "localhost";
|
||||
try {
|
||||
host = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException uhe) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// Enumerate all processes.
|
||||
// For those processes that have loaded a library named "jvm.dll"
|
||||
// then we attempt to attach. If we succeed then we have a 6.0+ VM.
|
||||
int processes[] = new int[1024];
|
||||
int count = enumProcesses(processes, processes.length);
|
||||
for (int i=0; i<count; i++) {
|
||||
if (isLibraryLoadedByProcess("jvm.dll", processes[i])) {
|
||||
String pid = Integer.toString(processes[i]);
|
||||
try {
|
||||
new WindowsVirtualMachine(this, pid).detach();
|
||||
|
||||
// FIXME - for now we don't have an appropriate display
|
||||
// name so we use pid@hostname
|
||||
String name = pid + "@" + host;
|
||||
|
||||
list.add(new HotSpotVirtualMachineDescriptor(this, pid, name));
|
||||
} catch (AttachNotSupportedException x) {
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
// enumerates processes using psapi's EnumProcesses
|
||||
private static native int enumProcesses(int[] processes, int max);
|
||||
|
||||
// indicates if a library of a given name has been loaded by a process
|
||||
private static native boolean isLibraryLoadedByProcess(String library,
|
||||
int processId);
|
||||
|
||||
|
||||
// native functions in this library
|
||||
static {
|
||||
System.loadLibrary("attach");
|
||||
}
|
||||
|
||||
}
|
||||
196
jdkSrc/jdk8/sun/tools/attach/WindowsVirtualMachine.java
Normal file
196
jdkSrc/jdk8/sun/tools/attach/WindowsVirtualMachine.java
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2023, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.attach;
|
||||
|
||||
import com.sun.tools.attach.AttachOperationFailedException;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
import com.sun.tools.attach.spi.AttachProvider;
|
||||
|
||||
import sun.tools.attach.HotSpotVirtualMachine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Random;
|
||||
|
||||
public class WindowsVirtualMachine extends HotSpotVirtualMachine {
|
||||
|
||||
// the enqueue code stub (copied into each target VM)
|
||||
private static byte[] stub;
|
||||
|
||||
private volatile long hProcess; // handle to the process
|
||||
|
||||
WindowsVirtualMachine(AttachProvider provider, String id)
|
||||
throws AttachNotSupportedException, IOException
|
||||
{
|
||||
super(provider, id);
|
||||
|
||||
int pid;
|
||||
try {
|
||||
pid = Integer.parseInt(id);
|
||||
} catch (NumberFormatException x) {
|
||||
throw new AttachNotSupportedException("Invalid process identifier");
|
||||
}
|
||||
hProcess = openProcess(pid);
|
||||
|
||||
// The target VM might be a pre-6.0 VM so we enqueue a "null" command
|
||||
// which minimally tests that the enqueue function exists in the target
|
||||
// VM.
|
||||
try {
|
||||
enqueue(hProcess, stub, null, null);
|
||||
} catch (IOException x) {
|
||||
throw new AttachNotSupportedException(x.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void detach() throws IOException {
|
||||
synchronized (this) {
|
||||
if (hProcess != -1) {
|
||||
closeProcess(hProcess);
|
||||
hProcess = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputStream execute(String cmd, Object ... args)
|
||||
throws AgentLoadException, IOException
|
||||
{
|
||||
assert args.length <= 3; // includes null
|
||||
checkNulls(args);
|
||||
|
||||
// create a pipe using a random name
|
||||
int r = (new Random()).nextInt();
|
||||
String pipename = "\\\\.\\pipe\\javatool" + r;
|
||||
long hPipe = createPipe(pipename);
|
||||
|
||||
// check if we are detached - in theory it's possible that detach is invoked
|
||||
// after this check but before we enqueue the command.
|
||||
if (hProcess == -1) {
|
||||
closePipe(hPipe);
|
||||
throw new IOException("Detached from target VM");
|
||||
}
|
||||
|
||||
try {
|
||||
// enqueue the command to the process
|
||||
enqueue(hProcess, stub, cmd, pipename, args);
|
||||
|
||||
// wait for command to complete - process will connect with the
|
||||
// completion status
|
||||
connectPipe(hPipe);
|
||||
|
||||
// create an input stream for the pipe
|
||||
PipedInputStream is = new PipedInputStream(hPipe);
|
||||
|
||||
// read completion status
|
||||
int status = readInt(is);
|
||||
if (status != 0) {
|
||||
// read from the stream and use that as the error message
|
||||
String message = readErrorMessage(is);
|
||||
// special case the load command so that the right exception is thrown
|
||||
if (cmd.equals("load")) {
|
||||
throw new AgentLoadException("Failed to load agent library");
|
||||
} else {
|
||||
if (message == null) {
|
||||
throw new AttachOperationFailedException("Command failed in target VM");
|
||||
} else {
|
||||
throw new AttachOperationFailedException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the input stream
|
||||
return is;
|
||||
|
||||
} catch (IOException ioe) {
|
||||
closePipe(hPipe);
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
// An InputStream based on a pipe to the target VM
|
||||
private class PipedInputStream extends InputStream {
|
||||
|
||||
private long hPipe;
|
||||
|
||||
public PipedInputStream(long hPipe) {
|
||||
this.hPipe = hPipe;
|
||||
}
|
||||
|
||||
public synchronized int read() throws IOException {
|
||||
byte b[] = new byte[1];
|
||||
int n = this.read(b, 0, 1);
|
||||
if (n == 1) {
|
||||
return b[0] & 0xff;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized int read(byte[] bs, int off, int len) throws IOException {
|
||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0)
|
||||
return 0;
|
||||
|
||||
return WindowsVirtualMachine.readPipe(hPipe, bs, off, len);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (hPipe != -1) {
|
||||
WindowsVirtualMachine.closePipe(hPipe);
|
||||
hPipe = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-- native methods
|
||||
|
||||
static native void init();
|
||||
|
||||
static native byte[] generateStub();
|
||||
|
||||
static native long openProcess(int pid) throws IOException;
|
||||
|
||||
static native void closeProcess(long hProcess) throws IOException;
|
||||
|
||||
static native long createPipe(String name) throws IOException;
|
||||
|
||||
static native void closePipe(long hPipe) throws IOException;
|
||||
|
||||
static native void connectPipe(long hPipe) throws IOException;
|
||||
|
||||
static native int readPipe(long hPipe, byte buf[], int off, int buflen) throws IOException;
|
||||
|
||||
static native void enqueue(long hProcess, byte[] stub,
|
||||
String cmd, String pipename, Object ... args) throws IOException;
|
||||
|
||||
static {
|
||||
System.loadLibrary("attach");
|
||||
init(); // native initialization
|
||||
stub = generateStub(); // generate stub to copy into target process
|
||||
}
|
||||
}
|
||||
91
jdkSrc/jdk8/sun/tools/jar/CommandLine.java
Normal file
91
jdkSrc/jdk8/sun/tools/jar/CommandLine.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jar;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.FileReader;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StreamTokenizer;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Various utility methods for processing Java tool command line arguments.
|
||||
*
|
||||
* <p><b>This is NOT part of any API supported by Oracle. If
|
||||
* you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class CommandLine {
|
||||
/**
|
||||
* Process Win32-style command files for the specified command line
|
||||
* arguments and return the resulting arguments. A command file argument
|
||||
* is of the form '@file' where 'file' is the name of the file whose
|
||||
* contents are to be parsed for additional arguments. The contents of
|
||||
* the command file are parsed using StreamTokenizer and the original
|
||||
* '@file' argument replaced with the resulting tokens. Recursive command
|
||||
* files are not supported. The '@' character itself can be quoted with
|
||||
* the sequence '@@'.
|
||||
*/
|
||||
public static String[] parse(String[] args)
|
||||
throws IOException
|
||||
{
|
||||
List<String> newArgs = new ArrayList<>(args.length);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String arg = args[i];
|
||||
if (arg.length() > 1 && arg.charAt(0) == '@') {
|
||||
arg = arg.substring(1);
|
||||
if (arg.charAt(0) == '@') {
|
||||
newArgs.add(arg);
|
||||
} else {
|
||||
loadCmdFile(arg, newArgs);
|
||||
}
|
||||
} else {
|
||||
newArgs.add(arg);
|
||||
}
|
||||
}
|
||||
return newArgs.toArray(new String[newArgs.size()]);
|
||||
}
|
||||
|
||||
private static void loadCmdFile(String name, List<String> args)
|
||||
throws IOException
|
||||
{
|
||||
Reader r = new BufferedReader(new FileReader(name));
|
||||
StreamTokenizer st = new StreamTokenizer(r);
|
||||
st.resetSyntax();
|
||||
st.wordChars(' ', 255);
|
||||
st.whitespaceChars(0, ' ');
|
||||
st.commentChar('#');
|
||||
st.quoteChar('"');
|
||||
st.quoteChar('\'');
|
||||
while (st.nextToken() != StreamTokenizer.TT_EOF) {
|
||||
args.add(st.sval);
|
||||
}
|
||||
r.close();
|
||||
}
|
||||
}
|
||||
42
jdkSrc/jdk8/sun/tools/jar/JarException.java
Normal file
42
jdkSrc/jdk8/sun/tools/jar/JarException.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jar;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public
|
||||
class JarException extends IOException {
|
||||
|
||||
static final long serialVersionUID = -4351820108009811497L;
|
||||
|
||||
public JarException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public JarException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
1361
jdkSrc/jdk8/sun/tools/jar/Main.java
Normal file
1361
jdkSrc/jdk8/sun/tools/jar/Main.java
Normal file
File diff suppressed because it is too large
Load Diff
258
jdkSrc/jdk8/sun/tools/jar/Manifest.java
Normal file
258
jdkSrc/jdk8/sun/tools/jar/Manifest.java
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jar;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
|
||||
import sun.net.www.MessageHeader;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* This is OBSOLETE. DO NOT USE THIS. Use java.util.jar.Manifest
|
||||
* instead. It has to stay here because some apps (namely HJ and HJV)
|
||||
* call directly into it.
|
||||
*
|
||||
* @author David Brown
|
||||
* @author Benjamin Renaud
|
||||
*/
|
||||
|
||||
public class Manifest {
|
||||
|
||||
/* list of headers that all pertain to a particular
|
||||
* file in the archive
|
||||
*/
|
||||
private Vector<MessageHeader> entries = new Vector<>();
|
||||
private byte[] tmpbuf = new byte[512];
|
||||
/* a hashtable of entries, for fast lookup */
|
||||
private Hashtable<String, MessageHeader> tableEntries = new Hashtable<>();
|
||||
|
||||
static final String[] hashes = {"SHA"};
|
||||
static final byte[] EOL = {(byte)'\r', (byte)'\n'};
|
||||
|
||||
static final boolean debug = false;
|
||||
static final String VERSION = "1.0";
|
||||
static final void debug(String s) {
|
||||
if (debug)
|
||||
System.out.println("man> " + s);
|
||||
}
|
||||
|
||||
public Manifest() {}
|
||||
|
||||
public Manifest(byte[] bytes) throws IOException {
|
||||
this(new ByteArrayInputStream(bytes), false);
|
||||
}
|
||||
|
||||
public Manifest(InputStream is) throws IOException {
|
||||
this(is, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a manifest from a stream, optionally computing hashes
|
||||
* for the files.
|
||||
*/
|
||||
public Manifest(InputStream is, boolean compute) throws IOException {
|
||||
if (!is.markSupported()) {
|
||||
is = new BufferedInputStream(is);
|
||||
}
|
||||
/* do not rely on available() here! */
|
||||
while (true) {
|
||||
is.mark(1);
|
||||
if (is.read() == -1) { // EOF
|
||||
break;
|
||||
}
|
||||
is.reset();
|
||||
MessageHeader m = new MessageHeader(is);
|
||||
if (compute) {
|
||||
doHashes(m);
|
||||
}
|
||||
addEntry(m);
|
||||
}
|
||||
}
|
||||
|
||||
/* recursively generate manifests from directory tree */
|
||||
public Manifest(String[] files) throws IOException {
|
||||
MessageHeader globals = new MessageHeader();
|
||||
globals.add("Manifest-Version", VERSION);
|
||||
String jdkVersion = System.getProperty("java.version");
|
||||
globals.add("Created-By", "Manifest JDK "+jdkVersion);
|
||||
addEntry(globals);
|
||||
addFiles(null, files);
|
||||
}
|
||||
|
||||
public void addEntry(MessageHeader entry) {
|
||||
entries.addElement(entry);
|
||||
String name = entry.findValue("Name");
|
||||
debug("addEntry for name: "+name);
|
||||
if (name != null) {
|
||||
tableEntries.put(name, entry);
|
||||
}
|
||||
}
|
||||
|
||||
public MessageHeader getEntry(String name) {
|
||||
return tableEntries.get(name);
|
||||
}
|
||||
|
||||
public MessageHeader entryAt(int i) {
|
||||
return entries.elementAt(i);
|
||||
}
|
||||
|
||||
public Enumeration<MessageHeader> entries() {
|
||||
return entries.elements();
|
||||
}
|
||||
|
||||
public void addFiles(File dir, String[] files) throws IOException {
|
||||
if (files == null)
|
||||
return;
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File file;
|
||||
if (dir == null) {
|
||||
file = new File(files[i]);
|
||||
} else {
|
||||
file = new File(dir, files[i]);
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
addFiles(file, file.list());
|
||||
} else {
|
||||
addFile(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* File names are represented internally using "/";
|
||||
* they are converted to the local format for anything else
|
||||
*/
|
||||
|
||||
private final String stdToLocal(String name) {
|
||||
return name.replace('/', java.io.File.separatorChar);
|
||||
}
|
||||
|
||||
private final String localToStd(String name) {
|
||||
name = name.replace(java.io.File.separatorChar, '/');
|
||||
if (name.startsWith("./"))
|
||||
name = name.substring(2);
|
||||
else if (name.startsWith("/"))
|
||||
name = name.substring(1);
|
||||
return name;
|
||||
}
|
||||
|
||||
public void addFile(File f) throws IOException {
|
||||
String stdName = localToStd(f.getPath());
|
||||
if (tableEntries.get(stdName) == null) {
|
||||
MessageHeader mh = new MessageHeader();
|
||||
mh.add("Name", stdName);
|
||||
addEntry(mh);
|
||||
}
|
||||
}
|
||||
|
||||
public void doHashes(MessageHeader mh) throws IOException {
|
||||
// If unnamed or is a directory return immediately
|
||||
String name = mh.findValue("Name");
|
||||
if (name == null || name.endsWith("/")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* compute hashes, write over any other "Hash-Algorithms" (?) */
|
||||
for (int j = 0; j < hashes.length; ++j) {
|
||||
InputStream is = new FileInputStream(stdToLocal(name));
|
||||
try {
|
||||
MessageDigest dig = MessageDigest.getInstance(hashes[j]);
|
||||
|
||||
int len;
|
||||
while ((len = is.read(tmpbuf, 0, tmpbuf.length)) != -1) {
|
||||
dig.update(tmpbuf, 0, len);
|
||||
}
|
||||
mh.set(hashes[j] + "-Digest", Base64.getMimeEncoder().encodeToString(dig.digest()));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new JarException("Digest algorithm " + hashes[j] +
|
||||
" not available.");
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a manifest file at current position in a stream
|
||||
*/
|
||||
public void stream(OutputStream os) throws IOException {
|
||||
|
||||
PrintStream ps;
|
||||
if (os instanceof PrintStream) {
|
||||
ps = (PrintStream) os;
|
||||
} else {
|
||||
ps = new PrintStream(os);
|
||||
}
|
||||
|
||||
/* the first header in the file should be the global one.
|
||||
* It should say "Manifest-Version: x.x"; if not add it
|
||||
*/
|
||||
MessageHeader globals = entries.elementAt(0);
|
||||
|
||||
if (globals.findValue("Manifest-Version") == null) {
|
||||
/* Assume this is a user-defined manifest. If it has a Name: <..>
|
||||
* field, then it is not global, in which case we just add our own
|
||||
* global Manifest-version: <version>
|
||||
* If the first MessageHeader has no Name: <..>, we assume it
|
||||
* is a global header and so prepend Manifest to it.
|
||||
*/
|
||||
String jdkVersion = System.getProperty("java.version");
|
||||
|
||||
if (globals.findValue("Name") == null) {
|
||||
globals.prepend("Manifest-Version", VERSION);
|
||||
globals.add("Created-By", "Manifest JDK "+jdkVersion);
|
||||
} else {
|
||||
ps.print("Manifest-Version: "+VERSION+"\r\n"+
|
||||
"Created-By: "+jdkVersion+"\r\n\r\n");
|
||||
}
|
||||
ps.flush();
|
||||
}
|
||||
|
||||
globals.print(ps);
|
||||
|
||||
for (int i = 1; i < entries.size(); ++i) {
|
||||
MessageHeader mh = entries.elementAt(i);
|
||||
mh.print(ps);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isManifestName(String name) {
|
||||
|
||||
// remove leading /
|
||||
if (name.charAt(0) == '/') {
|
||||
name = name.substring(1, name.length());
|
||||
}
|
||||
// case insensitive
|
||||
name = name.toUpperCase();
|
||||
|
||||
if (name.equals("META-INF/MANIFEST.MF")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
360
jdkSrc/jdk8/sun/tools/jar/SignatureFile.java
Normal file
360
jdkSrc/jdk8/sun/tools/jar/SignatureFile.java
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jar;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
|
||||
import sun.net.www.MessageHeader;
|
||||
import java.util.Base64;
|
||||
|
||||
|
||||
import sun.security.pkcs.*;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
|
||||
/**
|
||||
* <p>A signature file as defined in the <a
|
||||
* href="manifest.html">Manifest and Signature Format</a>. It has
|
||||
* essentially the same structure as a Manifest file in that it is a
|
||||
* set of RFC 822 headers (sections). The first section contains meta
|
||||
* data relevant to the entire file (i.e "Signature-Version:1.0") and
|
||||
* each subsequent section contains data relevant to specific entries:
|
||||
* entry sections.
|
||||
*
|
||||
* <p>Each entry section contains the name of an entry (which must
|
||||
* have a counterpart in the manifest). Like the manifest it contains
|
||||
* a hash, the hash of the manifest section corresponding to the
|
||||
* name. Since the manifest entry contains the hash of the data, this
|
||||
* is equivalent to a signature of the data, plus the attributes of
|
||||
* the manifest entry.
|
||||
*
|
||||
* <p>This signature file format deal with PKCS7 encoded DSA signature
|
||||
* block. It should be straightforward to extent to support other
|
||||
* algorithms.
|
||||
*
|
||||
* @author David Brown
|
||||
* @author Benjamin Renaud */
|
||||
|
||||
public class SignatureFile {
|
||||
|
||||
/* Are we debugging? */
|
||||
static final boolean debug = false;
|
||||
|
||||
/* list of headers that all pertain to a particular file in the
|
||||
* archive */
|
||||
private Vector<MessageHeader> entries = new Vector<>();
|
||||
|
||||
/* Right now we only support SHA hashes */
|
||||
static final String[] hashes = {"SHA"};
|
||||
|
||||
static final void debug(String s) {
|
||||
if (debug)
|
||||
System.out.println("sig> " + s);
|
||||
}
|
||||
|
||||
/*
|
||||
* The manifest we're working with. */
|
||||
private Manifest manifest;
|
||||
|
||||
/*
|
||||
* The file name for the file. This is the raw name, i.e. the
|
||||
* extention-less 8 character name (such as MYSIGN) which wil be
|
||||
* used to build the signature filename (MYSIGN.SF) and the block
|
||||
* filename (MYSIGN.DSA) */
|
||||
private String rawName;
|
||||
|
||||
/* The digital signature block corresponding to this signature
|
||||
* file. */
|
||||
private PKCS7 signatureBlock;
|
||||
|
||||
|
||||
/**
|
||||
* Private constructor which takes a name a given signature
|
||||
* file. The name must be extension-less and less or equal to 8
|
||||
* character in length. */
|
||||
private SignatureFile(String name) throws JarException {
|
||||
|
||||
entries = new Vector<>();
|
||||
|
||||
if (name != null) {
|
||||
if (name.length() > 8 || name.indexOf('.') != -1) {
|
||||
throw new JarException("invalid file name");
|
||||
}
|
||||
rawName = name.toUpperCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private constructor which takes a name a given signature file
|
||||
* and a new file predicate. If it is a new file, a main header
|
||||
* will be added. */
|
||||
private SignatureFile(String name, boolean newFile)
|
||||
throws JarException {
|
||||
|
||||
this(name);
|
||||
|
||||
if (newFile) {
|
||||
MessageHeader globals = new MessageHeader();
|
||||
globals.set("Signature-Version", "1.0");
|
||||
entries.addElement(globals);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Signature file corresponding to a given
|
||||
* Manifest. All entries in the manifest are signed.
|
||||
*
|
||||
* @param manifest the manifest to use.
|
||||
*
|
||||
* @param name for this signature file. This should
|
||||
* be less than 8 characters, and without a suffix (i.e.
|
||||
* without a period in it.
|
||||
*
|
||||
* @exception JarException if an invalid name is passed in.
|
||||
*/
|
||||
public SignatureFile(Manifest manifest, String name)
|
||||
throws JarException {
|
||||
|
||||
this(name, true);
|
||||
|
||||
this.manifest = manifest;
|
||||
Enumeration<MessageHeader> enum_ = manifest.entries();
|
||||
while (enum_.hasMoreElements()) {
|
||||
MessageHeader mh = enum_.nextElement();
|
||||
String entryName = mh.findValue("Name");
|
||||
if (entryName != null) {
|
||||
add(entryName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new Signature file corresponding to a given
|
||||
* Manifest. Specific entries in the manifest are signed.
|
||||
*
|
||||
* @param manifest the manifest to use.
|
||||
*
|
||||
* @param entries the entries to sign.
|
||||
*
|
||||
* @param filename for this signature file. This should
|
||||
* be less than 8 characters, and without a suffix (i.e.
|
||||
* without a period in it.
|
||||
*
|
||||
* @exception JarException if an invalid name is passed in.
|
||||
*/
|
||||
public SignatureFile(Manifest manifest, String[] entries,
|
||||
String filename)
|
||||
throws JarException {
|
||||
this(filename, true);
|
||||
this.manifest = manifest;
|
||||
add(entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Signature file from an input stream.
|
||||
*
|
||||
* @exception IOException if an invalid name is passed in or if a
|
||||
* stream exception occurs.
|
||||
*/
|
||||
public SignatureFile(InputStream is, String filename)
|
||||
throws IOException {
|
||||
this(filename);
|
||||
while (is.available() > 0) {
|
||||
MessageHeader m = new MessageHeader(is);
|
||||
entries.addElement(m);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Signature file from an input stream.
|
||||
*
|
||||
* @exception IOException if an invalid name is passed in or if a
|
||||
* stream exception occurs.
|
||||
*/
|
||||
public SignatureFile(InputStream is) throws IOException {
|
||||
this(is, null);
|
||||
}
|
||||
|
||||
public SignatureFile(byte[] bytes) throws IOException {
|
||||
this(new ByteArrayInputStream(bytes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the signature file, ending with a ".SF"
|
||||
* suffix */
|
||||
public String getName() {
|
||||
return "META-INF/" + rawName + ".SF";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the block file, ending with a block suffix
|
||||
* such as ".DSA". */
|
||||
public String getBlockName() {
|
||||
String suffix = "DSA";
|
||||
if (signatureBlock != null) {
|
||||
SignerInfo info = signatureBlock.getSignerInfos()[0];
|
||||
suffix = info.getDigestEncryptionAlgorithmId().getName();
|
||||
String temp = AlgorithmId.getEncAlgFromSigAlg(suffix);
|
||||
if (temp != null) suffix = temp;
|
||||
}
|
||||
return "META-INF/" + rawName + "." + suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature block associated with this file.
|
||||
*/
|
||||
public PKCS7 getBlock() {
|
||||
return signatureBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the signature block associated with this file.
|
||||
*/
|
||||
public void setBlock(PKCS7 block) {
|
||||
this.signatureBlock = block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a set of entries from the current manifest.
|
||||
*/
|
||||
public void add(String[] entries) throws JarException {
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
add (entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a specific entry from the current manifest.
|
||||
*/
|
||||
public void add(String entry) throws JarException {
|
||||
MessageHeader mh = manifest.getEntry(entry);
|
||||
if (mh == null) {
|
||||
throw new JarException("entry " + entry + " not in manifest");
|
||||
}
|
||||
MessageHeader smh;
|
||||
try {
|
||||
smh = computeEntry(mh);
|
||||
} catch (IOException e) {
|
||||
throw new JarException(e.getMessage());
|
||||
}
|
||||
entries.addElement(smh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entry corresponding to a given name. Returns null if
|
||||
*the entry does not exist.
|
||||
*/
|
||||
public MessageHeader getEntry(String name) {
|
||||
Enumeration<MessageHeader> enum_ = entries();
|
||||
while(enum_.hasMoreElements()) {
|
||||
MessageHeader mh = enum_.nextElement();
|
||||
if (name.equals(mh.findValue("Name"))) {
|
||||
return mh;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the n-th entry. The global header is a entry 0. */
|
||||
public MessageHeader entryAt(int n) {
|
||||
return entries.elementAt(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an enumeration of the entries.
|
||||
*/
|
||||
public Enumeration<MessageHeader> entries() {
|
||||
return entries.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a manifest entry, computes the signature entry for this
|
||||
* manifest entry.
|
||||
*/
|
||||
private MessageHeader computeEntry(MessageHeader mh) throws IOException {
|
||||
MessageHeader smh = new MessageHeader();
|
||||
|
||||
String name = mh.findValue("Name");
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
smh.set("Name", name);
|
||||
|
||||
try {
|
||||
for (int i = 0; i < hashes.length; ++i) {
|
||||
MessageDigest dig = getDigest(hashes[i]);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(baos);
|
||||
mh.print(ps);
|
||||
byte[] headerBytes = baos.toByteArray();
|
||||
byte[] digest = dig.digest(headerBytes);
|
||||
smh.set(hashes[i] + "-Digest", Base64.getMimeEncoder().encodeToString(digest));
|
||||
}
|
||||
return smh;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new JarException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Hashtable<String, MessageDigest> digests = new Hashtable<>();
|
||||
|
||||
private MessageDigest getDigest(String algorithm)
|
||||
throws NoSuchAlgorithmException {
|
||||
MessageDigest dig = digests.get(algorithm);
|
||||
if (dig == null) {
|
||||
dig = MessageDigest.getInstance(algorithm);
|
||||
digests.put(algorithm, dig);
|
||||
}
|
||||
dig.reset();
|
||||
return dig;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a signature file at current position in a stream
|
||||
*/
|
||||
public void stream(OutputStream os) throws IOException {
|
||||
|
||||
/* the first header in the file should be the global one.
|
||||
* It should say "SignatureFile-Version: x.x"; barf if not
|
||||
*/
|
||||
MessageHeader globals = entries.elementAt(0);
|
||||
if (globals.findValue("Signature-Version") == null) {
|
||||
throw new JarException("Signature file requires " +
|
||||
"Signature-Version: 1.0 in 1st header");
|
||||
}
|
||||
|
||||
PrintStream ps = new PrintStream(os);
|
||||
globals.print(ps);
|
||||
|
||||
for (int i = 1; i < entries.size(); ++i) {
|
||||
MessageHeader mh = entries.elementAt(i);
|
||||
mh.print(ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
34
jdkSrc/jdk8/sun/tools/jar/resources/jar.java
Normal file
34
jdkSrc/jdk8/sun/tools/jar/resources/jar.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "'c' flag requires manifest or input files to be specified!" },
|
||||
{ "error.bad.eflag", "'e' flag and manifest with the 'Main-Class' attribute cannot be specified \ntogether!" },
|
||||
{ "error.bad.option", "One of options -{ctxu} must be specified." },
|
||||
{ "error.bad.uflag", "'u' flag requires manifest, 'e' flag or input files to be specified!" },
|
||||
{ "error.cant.open", "can''t open: {0} " },
|
||||
{ "error.create.dir", "{0} : could not create directory" },
|
||||
{ "error.create.tempfile", "Could not create a temporary file" },
|
||||
{ "error.illegal.option", "Illegal option: {0}" },
|
||||
{ "error.incorrect.length", "incorrect length while processing: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0} : no such file or directory" },
|
||||
{ "error.write.file", "Error in writing existing jar file" },
|
||||
{ "out.added.manifest", "added manifest" },
|
||||
{ "out.adding", "adding: {0}" },
|
||||
{ "out.create", " created: {0}" },
|
||||
{ "out.deflated", "(deflated {0}%)" },
|
||||
{ "out.extracted", "extracted: {0}" },
|
||||
{ "out.ignore.entry", "ignoring entry {0}" },
|
||||
{ "out.inflated", " inflated: {0}" },
|
||||
{ "out.kept", " skipped: {0} exists" },
|
||||
{ "out.size", "(in = {0}) (out= {1})" },
|
||||
{ "out.stored", "(stored 0%)" },
|
||||
{ "out.update.manifest", "updated manifest" },
|
||||
{ "usage", "Usage: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOptions:\n -c create new archive\n -t list table of contents for archive\n -x, Extract named (or all) files from the archive.\n If a file with the same name appears more than once in\n the archive, each copy will be extracted, with later copies\n overwriting (replacing) earlier copies unless 'k' is specified.\n -u update existing archive\n -v generate verbose output on standard output\n -f specify archive file name\n -m include manifest information from specified manifest file\n -n perform Pack200 normalization after creating a new archive\n -e specify application entry point for stand-alone application \n bundled into an executable jar file\n -0 store only; use no ZIP compression\n -P preserve leading '/' (absolute path) and \"..\" (parent directory) components from file names\n -M do not create a manifest file for the entries\n -i generate index information for the specified jar files\n -C change to the specified directory and include the following file\nOperation modifiers valid only in extract mode:\n -k Do not overwrite existing files.\n If a Jar file entry with the same name exists in the target\n directory, the existing file will not be overwritten.\n As a result, if a file appears more than once in an\n archive, later copies will not overwrite earlier copies.\n Also note that some file system can be case insensitive.\nIf any file is a directory then it is processed recursively.\nThe manifest file name, the archive file name and the entry point name are\nspecified in the same order as the 'm', 'f' and 'e' flags.\n\nExample 1: to archive two class files into an archive called classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExample 2: use an existing manifest file 'mymanifest' and archive all the\n files in the foo/ directory into 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
{ "warn.option.is.ignored", "Warning: The {0} option is not valid with current usage, will be ignored." },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_de.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_de.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_de extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "Kennzeichen \"c\" erfordert Angabe von Manifest oder Eingabedateien." },
|
||||
{ "error.bad.eflag", "Kennzeichen \"e\" und Manifest mit dem Attribut \"Main-Class\" k\u00F6nnen nicht zusammen angegeben\nwerden." },
|
||||
{ "error.bad.option", "Eine der Optionen -{ctxu} muss angegeben werden." },
|
||||
{ "error.bad.uflag", "Kennzeichen \"u\" erfordert Angabe von Manifest, Kennzeichen \"e\" oder Eingabedateien." },
|
||||
{ "error.cant.open", "\u00D6ffnen nicht m\u00F6glich: {0} " },
|
||||
{ "error.create.dir", "{0}: Verzeichnis konnte nicht erstellt werden" },
|
||||
{ "error.create.tempfile", "Es konnte keine tempor\u00E4re Datei erstellt werden" },
|
||||
{ "error.illegal.option", "Unzul\u00E4ssige Option: {0}" },
|
||||
{ "error.incorrect.length", "Falsche L\u00E4nge bei der Verarbeitung: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0}: Datei oder Verzeichnis nicht vorhanden" },
|
||||
{ "error.write.file", "Fehler beim Schreiben in vorhandener JAR-Datei" },
|
||||
{ "out.added.manifest", "Manifest wurde hinzugef\u00FCgt" },
|
||||
{ "out.adding", "{0} wird hinzugef\u00FCgt" },
|
||||
{ "out.create", " erstellt: {0}" },
|
||||
{ "out.deflated", "({0} % verkleinert)" },
|
||||
{ "out.extracted", "extrahiert: {0}" },
|
||||
{ "out.ignore.entry", "Eintrag {0} wird ignoriert" },
|
||||
{ "out.inflated", " vergr\u00F6\u00DFert: {0}" },
|
||||
{ "out.size", "(ein = {0}) (aus = {1})" },
|
||||
{ "out.stored", "(0 % gespeichert)" },
|
||||
{ "out.update.manifest", "Manifest wurde aktualisiert" },
|
||||
{ "usage", "Verwendung: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] Dateien...\nOptionen:\n -c Neues Archiv erstellen\n -t Inhaltsverzeichnis f\u00FCr Archiv anzeigen\n -x Benannte (oder alle) Dateien aus dem Archiv extrahieren\n -u Vorhandenes Archiv aktualisieren\n -v Ausgabe im Verbose-Modus aus Standard-Ausgabe generieren\n -f Dateinamen f\u00FCr Archiv angeben\n -m Manifestinformationen aus angegebener Manifestdatei einschlie\u00DFen\n -n Pack200-Normalisierung nach Erstellung eines neuen Archivs ausf\u00FChren\n -e Anwendungseinstiegspunkt f\u00FCr Standalone-Anwendung angeben \n in einer ausf\u00FChrbaren JAR-Datei geb\u00FCndelt\n -0 Nur speichern; keine ZIP-Komprimierung verwenden\n -P Komponenten mit vorangestelltem \"/\" (absoluter Pfad) und \"..\" (\u00FCbergeordnetes Verzeichnis) aus Dateinamen beibehalten\n -M Keine Manifest-Datei f\u00FCr die Eintr\u00E4ge erstellen\n -i Indexinformationen f\u00FCr die angegebenen JAR-Dateien erstellen\n -C Zum angegebenen Verzeichnis wechseln und folgende Datei einschlie\u00DFen\nFalls eine Datei ein Verzeichnis ist, wird dieses rekursiv verarbeitet.\nDer Name der Manifestdatei, der Name der Archivdatei und der Name des Einstiegspunkts werden\nin derselben Reihenfolge wie die Kennzeichen \"m\", \"f\" und \"e\" angegeben.\n\nBeispiel 1: Archivieren Sie zwei Klassendateien in ein Archiv mit Namen \"classes.jar\": \n jar cvf classes.jar Foo.class Bar.class \nBeispiel 2: Verwenden Sie die vorhandenen Manifestdatei \"mymanifest\", und archivieren Sie alle\n Dateien im Verzeichnis foo/ directory in \"classes.jar\": \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_es.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_es.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_es extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "El indicador 'c' necesita la especificaci\u00F3n de archivos de manifiesto o de entrada." },
|
||||
{ "error.bad.eflag", "El indicador 'e' y el manifiesto con el atributo 'Main-Class' no pueden especificarse \na la vez." },
|
||||
{ "error.bad.option", "Se debe especificar una de las opciones -{ctxu}." },
|
||||
{ "error.bad.uflag", "El indicador 'u' necesita la especificaci\u00F3n de archivos de manifiesto, de entrada o indicador 'e'." },
|
||||
{ "error.cant.open", "no se puede abrir: {0} " },
|
||||
{ "error.create.dir", "{0} : no se ha podido crear el directorio" },
|
||||
{ "error.create.tempfile", "No se ha podido crear el archivo temporal" },
|
||||
{ "error.illegal.option", "Opci\u00F3n no permitida: {0}" },
|
||||
{ "error.incorrect.length", "longitud incorrecta al procesar: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0} : no existe tal archivo o directorio" },
|
||||
{ "error.write.file", "Error al escribir un archivo jar existente" },
|
||||
{ "out.added.manifest", "manifiesto agregado" },
|
||||
{ "out.adding", "agregando: {0}" },
|
||||
{ "out.create", " creado: {0}" },
|
||||
{ "out.deflated", "(desinflado {0}%)" },
|
||||
{ "out.extracted", "extra\u00EDdo: {0}" },
|
||||
{ "out.ignore.entry", "ignorando entrada {0}" },
|
||||
{ "out.inflated", " inflado: {0}" },
|
||||
{ "out.size", "(entrada = {0}) (salida = {1})" },
|
||||
{ "out.stored", "(almacenado 0%)" },
|
||||
{ "out.update.manifest", "manifiesto actualizado" },
|
||||
{ "usage", "Sintaxis: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOpciones:\n -c crear nuevo archivo\n -t crear la tabla de contenido del archivo\n -x extraer el archivo mencionado (o todos) del archivo\n -u actualizar archivo existente\n -v generar salida detallada de los datos de salida est\u00E1ndar\n -f especificar nombre de archivo de almacenamiento\n -m incluir informaci\u00F3n de manifiesto del archivo de manifiesto especificado\n -e especificar punto de entrada de la aplicaci\u00F3n para la aplicaci\u00F3n aut\u00F3noma \n que se incluye dentro de un archivo jar ejecutable\n -0 s\u00F3lo almacenar; no utilizar compresi\u00F3n ZIP\n -P conservar componentes iniciales '/' (ruta absoluta) y \"..\" (directorio principal) en los nombres de archivo\n -M no crear un archivo de manifiesto para las entradas\n -i generar informaci\u00F3n de \u00EDndice para los archivos jar especificados\n -C cambiar al directorio especificado e incluir el archivo siguiente\nSi alg\u00FAn archivo es un directorio, se procesar\u00E1 de forma recurrente.\nEl nombre del archivo de manifiesto, el nombre del archivo de almacenamiento y el nombre del punto de entrada se\nespecifican en el mismo orden que los indicadores 'm', 'f' y 'e'.\n\nEjemplo 1: para archivar archivos de dos clases en un archivo llamado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEjemplo 2: utilice un archivo de manifiesto existente 'mymanifest' y archive todos los\n archivos del directorio foo/ en 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_fr.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_fr.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_fr extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "L'indicateur c requiert la sp\u00E9cification d'un fichier manifeste ou d'un fichier d'entr\u00E9e." },
|
||||
{ "error.bad.eflag", "L'indicateur e et le fichier manifeste portant l'attribut Main-Class ne peuvent pas \u00EAtre sp\u00E9cifi\u00E9s \nensemble." },
|
||||
{ "error.bad.option", "Une des options -{ctxu} doit \u00EAtre sp\u00E9cifi\u00E9e." },
|
||||
{ "error.bad.uflag", "L'indicateur u requiert la sp\u00E9cification d'un fichier manifeste, d'un fichier d'entr\u00E9e ou d'un indicateur e." },
|
||||
{ "error.cant.open", "impossible d''ouvrir : {0} " },
|
||||
{ "error.create.dir", "{0} : impossible de cr\u00E9er le r\u00E9pertoire" },
|
||||
{ "error.create.tempfile", "Impossible de cr\u00E9er un fichier temporaire" },
|
||||
{ "error.illegal.option", "Option non admise : {0}" },
|
||||
{ "error.incorrect.length", "longueur incorrecte lors du traitement de : {0}" },
|
||||
{ "error.nosuch.fileordir", "{0} : fichier ou r\u00E9pertoire introuvable" },
|
||||
{ "error.write.file", "Erreur lors de l'\u00E9criture d'un fichier JAR existant" },
|
||||
{ "out.added.manifest", "manifeste ajout\u00E9" },
|
||||
{ "out.adding", "ajout : {0}" },
|
||||
{ "out.create", " cr\u00E9\u00E9 : {0}" },
|
||||
{ "out.deflated", "(compression : {0} %)" },
|
||||
{ "out.extracted", "extrait : {0}" },
|
||||
{ "out.ignore.entry", "entr\u00E9e {0} ignor\u00E9e" },
|
||||
{ "out.inflated", " d\u00E9compress\u00E9 : {0}" },
|
||||
{ "out.size", "(entr\u00E9e = {0}) (sortie = {1})" },
|
||||
{ "out.stored", "(stockage : 0 %)" },
|
||||
{ "out.update.manifest", "manifeste mis \u00E0 jour" },
|
||||
{ "usage", "Syntaxe : jar {ctxui}[vfmn0PMek] [fichier-jar] [fichier-manifeste] [point-entr\u00E9e] [-C r\u00E9p] fichiers...\nOptions :\n -c cr\u00E9e une archive\n -t affiche la table des mati\u00E8res de l'archive\n -x extrait les fichiers nomm\u00E9s (ou tous les fichiers) de l'archive\n -u met \u00E0 jour l'archive existante\n -v g\u00E9n\u00E8re une version d\u00E9taill\u00E9e d'une sortie standard\n -f sp\u00E9cifie le nom du fichier archive\n -m inclut les informations de manifeste \u00E0 partir du fichier manifeste sp\u00E9cifi\u00E9\n -n effectue une normalisation Pack200 apr\u00E8s la cr\u00E9ation d'une archive\n -e sp\u00E9cifie le point d'entr\u00E9e d'une application en mode autonome \n int\u00E9gr\u00E9e \u00E0 un fichier JAR ex\u00E9cutable\n -0 stockage uniquement, pas de compression ZIP\n -P pr\u00E9serve les signes de d\u00E9but '/' (chemin absolu) et \"..\" (r\u00E9pertoire parent) dans les noms de fichier\n -M ne cr\u00E9e pas de fichier manifeste pour les entr\u00E9es\n -i g\u00E9n\u00E8re les informations d'index des fichiers JAR sp\u00E9cifi\u00E9s\n -C passe au r\u00E9pertoire sp\u00E9cifi\u00E9 et inclut le fichier suivant\nSi l'un des fichiers est un r\u00E9pertoire, celui-ci est trait\u00E9 r\u00E9cursivement.\nLes noms du fichier manifeste, du fichier archive et du point d'entr\u00E9e sont\nsp\u00E9cifi\u00E9s dans le m\u00EAme ordre que celui des indicateurs m, f et e.\n\nExemple 1 : pour archiver deux fichiers de classe dans une archive intitul\u00E9e classes.jar : \n jar cvf classes.jar Foo.class Bar.class \nExemple 2 : pour utiliser un fichier manifeste existant 'monmanifeste', puis archiver tous les\n fichiers du r\u00E9pertoire foo/ dans 'classes.jar' : \n jar cvfm classes.jar monmanifeste -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_it.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_it.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_it extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "Per il flag 'c' \u00E8 necessario specificare file manifest o di input." },
|
||||
{ "error.bad.eflag", "Il flag 'e' e il manifest con l'attributo 'Main-Class' non possono essere specificati\ninsieme." },
|
||||
{ "error.bad.option", "\u00C8 necessario specificare una delle opzioni -{ctxu}." },
|
||||
{ "error.bad.uflag", "Per il flag 'u' \u00E8 necessario specificare il flag 'e' oppure file manifest o di input." },
|
||||
{ "error.cant.open", "impossibile aprire: {0} " },
|
||||
{ "error.create.dir", "{0} : impossibile creare la directory" },
|
||||
{ "error.create.tempfile", "Impossibile creare il file temporaneo." },
|
||||
{ "error.illegal.option", "Opzione non valida: {0}" },
|
||||
{ "error.incorrect.length", "lunghezza non valida durante l''elaborazione: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0} : file o directory inesistente" },
|
||||
{ "error.write.file", "Errore durante la scrittura del file jar esistente" },
|
||||
{ "out.added.manifest", "aggiunto manifest" },
|
||||
{ "out.adding", "aggiunta in corso di: {0}" },
|
||||
{ "out.create", " creato: {0}" },
|
||||
{ "out.deflated", "(compresso {0}%)" },
|
||||
{ "out.extracted", "estratto: {0}" },
|
||||
{ "out.ignore.entry", "la voce {0} sar\u00E0 ignorata" },
|
||||
{ "out.inflated", " decompresso: {0}" },
|
||||
{ "out.size", "(in = {0}) (out = {1})" },
|
||||
{ "out.stored", "(memorizzato 0%)" },
|
||||
{ "out.update.manifest", "aggiornato manifest" },
|
||||
{ "usage", "Uso: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nOpzioni:\n -c crea un nuovo archivio\n -t visualizza l'indice dell'archivio\n -x estrae i file con nome (o tutti i file) dall'archivio\n -u aggiorna l'archivio esistente\n -v genera output commentato dall'output standard\n -f specifica il nome file dell'archivio\n -m include informazioni manifest dal file manifest specificato\n -n esegue normalizzazione Pack200 dopo la creazione di un nuovo archivio\n -e specifica il punto di ingresso per l'applicazione stand-alone \n inclusa nel file jar eseguibile\n -0 solo memorizzazione; senza compressione ZIP\n -P conserva i componenti iniziali '/' (percorso assoluto) e \\\"..\\\" (directory padre) dai nomi file\n -M consente di non creare un file manifest per le voci\n -i genera informazioni sull'indice per i file jar specificati\n -C imposta la directory specificata e include il file seguente\nSe un file \u00E8 una directory, verr\u00E0 elaborato in modo ricorsivo.\nIl nome del file manifest, del file di archivio e del punto di ingresso devono\nessere specificati nello stesso ordine dei flag 'm', 'f' ed 'e'.\n\nEsempio 1: archiviazione di due file di classe in un archivio con il nome classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nEsempio 2: utilizzo del file manifest esistente 'mymanifest' e archiviazione di tutti i\n file della directory foo/ in 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_ja.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_ja.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_ja extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "\u30D5\u30E9\u30B0'c'\u3067\u306F\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u307E\u305F\u306F\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059\u3002" },
|
||||
{ "error.bad.eflag", "'e'\u30D5\u30E9\u30B0\u3068'Main-Class'\u5C5E\u6027\u3092\u6301\u3064\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u306F\u540C\u6642\u306B\n\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093\u3002" },
|
||||
{ "error.bad.option", "\u30AA\u30D7\u30B7\u30E7\u30F3-{ctxu}\u306E\u3046\u3061\u306E1\u3064\u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002" },
|
||||
{ "error.bad.uflag", "\u30D5\u30E9\u30B0'u'\u3067\u306F\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304B'e'\u30D5\u30E9\u30B0\u3001\u307E\u305F\u306F\u5165\u529B\u30D5\u30A1\u30A4\u30EB\u306E\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059\u3002" },
|
||||
{ "error.cant.open", "{0}\u3092\u958B\u304F\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093 " },
|
||||
{ "error.create.dir", "\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA{0}\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F" },
|
||||
{ "error.create.tempfile", "\u4E00\u6642\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F" },
|
||||
{ "error.illegal.option", "\u4E0D\u6B63\u306A\u30AA\u30D7\u30B7\u30E7\u30F3: {0}" },
|
||||
{ "error.incorrect.length", "{0}\u306E\u51E6\u7406\u4E2D\u306B\u4E0D\u6B63\u306A\u9577\u3055\u304C\u3042\u308A\u307E\u3057\u305F" },
|
||||
{ "error.nosuch.fileordir", "{0}\u3068\u3044\u3046\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306F\u3042\u308A\u307E\u305B\u3093" },
|
||||
{ "error.write.file", "\u65E2\u5B58jar\u30D5\u30A1\u30A4\u30EB\u306E\u66F8\u8FBC\u307F\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F" },
|
||||
{ "out.added.manifest", "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u8FFD\u52A0\u3055\u308C\u307E\u3057\u305F" },
|
||||
{ "out.adding", "{0}\u3092\u8FFD\u52A0\u4E2D\u3067\u3059" },
|
||||
{ "out.create", " {0}\u304C\u4F5C\u6210\u3055\u308C\u307E\u3057\u305F" },
|
||||
{ "out.deflated", "({0}%\u53CE\u7E2E\u3055\u308C\u307E\u3057\u305F)" },
|
||||
{ "out.extracted", "{0}\u304C\u62BD\u51FA\u3055\u308C\u307E\u3057\u305F" },
|
||||
{ "out.ignore.entry", "\u30A8\u30F3\u30C8\u30EA{0}\u3092\u7121\u8996\u3057\u307E\u3059" },
|
||||
{ "out.inflated", " {0}\u304C\u5C55\u958B\u3055\u308C\u307E\u3057\u305F" },
|
||||
{ "out.size", "(\u5165={0})(\u51FA={1})" },
|
||||
{ "out.stored", "(0%\u683C\u7D0D\u3055\u308C\u307E\u3057\u305F)" },
|
||||
{ "out.update.manifest", "\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u304C\u66F4\u65B0\u3055\u308C\u307E\u3057\u305F" },
|
||||
{ "usage", "\u4F7F\u7528\u65B9\u6CD5: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u30AA\u30D7\u30B7\u30E7\u30F3:\n -c \u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B\n -t \u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u5185\u5BB9\u3092\u4E00\u89A7\u8868\u793A\u3059\u308B\n -x \u6307\u5B9A\u306E(\u307E\u305F\u306F\u3059\u3079\u3066\u306E)\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6\u304B\u3089\u62BD\u51FA\u3059\u308B\n -u \u65E2\u5B58\u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u66F4\u65B0\u3059\u308B\n -v \u6A19\u6E96\u51FA\u529B\u306B\u8A73\u7D30\u306A\u51FA\u529B\u3092\u751F\u6210\u3059\u308B\n -f \u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3059\u308B\n -m \u6307\u5B9A\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u60C5\u5831\u3092\u53D6\u308A\u8FBC\u3080\n -n \u65B0\u898F\u30A2\u30FC\u30AB\u30A4\u30D6\u306E\u4F5C\u6210\u5F8C\u306BPack200\u6B63\u898F\u5316\u3092\u5B9F\u884C\u3059\u308B\n -e \u5B9F\u884C\u53EF\u80FDjar\u30D5\u30A1\u30A4\u30EB\u306B\u30D0\u30F3\u30C9\u30EB\u3055\u308C\u305F\u30B9\u30BF\u30F3\u30C9\u30A2\u30ED\u30F3\u30FB\n \u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u3092\u6307\u5B9A\u3059\u308B\n -0 \u683C\u7D0D\u306E\u307F\u3002ZIP\u5727\u7E2E\u3092\u4F7F\u7528\u3057\u306A\u3044\n -P \u30D5\u30A1\u30A4\u30EB\u540D\u306E\u5148\u982D\u306E'/' (\u7D76\u5BFE\u30D1\u30B9)\u304A\u3088\u3073\\\"..\\\" (\u89AA\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA)\u30B3\u30F3\u30DD\u30FC\u30CD\u30F3\u30C8\u3092\u4FDD\u6301\u3059\u308B\n -M \u30A8\u30F3\u30C8\u30EA\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u4F5C\u6210\u3057\u306A\u3044\n -i \u6307\u5B9A\u306Ejar\u30D5\u30A1\u30A4\u30EB\u306E\u7D22\u5F15\u60C5\u5831\u3092\u751F\u6210\u3059\u308B\n -C \u6307\u5B9A\u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306B\u5909\u66F4\u3057\u3001\u6B21\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u53D6\u308A\u8FBC\u3080\n\u30D5\u30A1\u30A4\u30EB\u304C\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\u5834\u5408\u306F\u518D\u5E30\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\n\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u3001\u30A2\u30FC\u30AB\u30A4\u30D6\u30FB\u30D5\u30A1\u30A4\u30EB\u540D\u304A\u3088\u3073\u30A8\u30F3\u30C8\u30EA\u30FB\u30DD\u30A4\u30F3\u30C8\u540D\u306F\u3001\n\u30D5\u30E9\u30B0'm'\u3001'f'\u3001'e'\u306E\u6307\u5B9A\u3068\u540C\u3058\u9806\u756A\u3067\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002\n\n\u4F8B1: 2\u3064\u306E\u30AF\u30E9\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u30A2\u30FC\u30AB\u30A4\u30D6classes.jar\u306B\u4FDD\u5B58\u3059\u308B: \n jar cvf classes.jar Foo.class Bar.class \n\u4F8B2: \u65E2\u5B58\u306E\u30DE\u30CB\u30D5\u30A7\u30B9\u30C8\u30FB\u30D5\u30A1\u30A4\u30EB'mymanifest'\u3092\u4F7F\u7528\u3057\u3001foo/\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306E\n \u5168\u30D5\u30A1\u30A4\u30EB\u3092'classes.jar'\u306B\u30A2\u30FC\u30AB\u30A4\u30D6\u3059\u308B: \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_ko.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_ko.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_ko extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "'c' \uD50C\uB798\uADF8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 Manifest \uB610\uB294 \uC785\uB825 \uD30C\uC77C\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4!" },
|
||||
{ "error.bad.eflag", "'e' \uD50C\uB798\uADF8 \uBC0F Manifest\uB97C 'Main-Class' \uC18D\uC131\uACFC \uD568\uAED8 \uC9C0\uC815\uD560 \uC218\n\uC5C6\uC2B5\uB2C8\uB2E4!" },
|
||||
{ "error.bad.option", "\uC635\uC158 -{ctxu} \uC911 \uD558\uB098\uB97C \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4." },
|
||||
{ "error.bad.uflag", "'u' \uD50C\uB798\uADF8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 Manifest, 'e' \uD50C\uB798\uADF8 \uB610\uB294 \uC785\uB825 \uD30C\uC77C\uC744 \uC9C0\uC815\uD574\uC57C \uD569\uB2C8\uB2E4!" },
|
||||
{ "error.cant.open", "\uC5F4 \uC218 \uC5C6\uC74C: {0} " },
|
||||
{ "error.create.dir", "{0}: \uB514\uB809\uD1A0\uB9AC\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4." },
|
||||
{ "error.create.tempfile", "\uC784\uC2DC \uD30C\uC77C\uC744 \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4." },
|
||||
{ "error.illegal.option", "\uC798\uBABB\uB41C \uC635\uC158: {0}" },
|
||||
{ "error.incorrect.length", "\uCC98\uB9AC \uC911 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC740 \uAE38\uC774\uAC00 \uBC1C\uACAC\uB428: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0}: \uD574\uB2F9 \uD30C\uC77C \uB610\uB294 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4." },
|
||||
{ "error.write.file", "\uAE30\uC874 jar \uD30C\uC77C\uC5D0 \uC4F0\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4." },
|
||||
{ "out.added.manifest", "Manifest\uB97C \uCD94\uAC00\uD568" },
|
||||
{ "out.adding", "\uCD94\uAC00\uD558\uB294 \uC911: {0}" },
|
||||
{ "out.create", " \uC0DD\uC131\uB428: {0}" },
|
||||
{ "out.deflated", "({0}%\uB97C \uAC10\uC18C\uD568)" },
|
||||
{ "out.extracted", "\uCD94\uCD9C\uB428: {0}" },
|
||||
{ "out.ignore.entry", "{0} \uD56D\uBAA9\uC744 \uBB34\uC2DC\uD558\uB294 \uC911" },
|
||||
{ "out.inflated", " \uC99D\uAC00\uB428: {0}" },
|
||||
{ "out.size", "(\uC785\uB825 = {0}) (\uCD9C\uB825 = {1})" },
|
||||
{ "out.stored", "(0%\uB97C \uC800\uC7A5\uD568)" },
|
||||
{ "out.update.manifest", "Manifest\uB97C \uC5C5\uB370\uC774\uD2B8\uD568" },
|
||||
{ "usage", "\uC0AC\uC6A9\uBC95: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\uC635\uC158:\n -c \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -t \uC544\uCE74\uC774\uBE0C\uC5D0 \uB300\uD55C \uBAA9\uCC28\uB97C \uB098\uC5F4\uD569\uB2C8\uB2E4.\n -x \uBA85\uBA85\uB41C(\uB610\uB294 \uBAA8\uB4E0) \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uC5D0\uC11C \uCD94\uCD9C\uD569\uB2C8\uB2E4.\n -u \uAE30\uC874 \uC544\uCE74\uC774\uBE0C\uB97C \uC5C5\uB370\uC774\uD2B8\uD569\uB2C8\uB2E4.\n -v \uD45C\uC900 \uCD9C\uB825\uC5D0 \uC0C1\uC138 \uC815\uBCF4 \uCD9C\uB825\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -f \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -m \uC9C0\uC815\uB41C Manifest \uD30C\uC77C\uC758 Manifest \uC815\uBCF4\uB97C \uD3EC\uD568\uD569\uB2C8\uB2E4.\n -n \uC0C8 \uC544\uCE74\uC774\uBE0C\uB97C \uC0DD\uC131\uD55C \uD6C4 Pack200 \uC815\uADDC\uD654\uB97C \uC218\uD589\uD569\uB2C8\uB2E4.\n -e jar \uC2E4\uD589 \uD30C\uC77C\uC5D0 \uBC88\uB4E4\uB85C \uC81C\uACF5\uB41C \uB3C5\uB9BD\uD615 \uC560\uD50C\uB9AC\uCF00\uC774\uC158\uC758 \n \uC560\uD50C\uB9AC\uCF00\uC774\uC158 \uC2DC\uC791 \uC9C0\uC810\uC744 \uC9C0\uC815\uD569\uB2C8\uB2E4.\n -0 \uC800\uC7A5 \uC804\uC6A9: ZIP \uC555\uCD95\uC744 \uC0AC\uC6A9\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -P \uD30C\uC77C \uC774\uB984\uC5D0\uC11C \uC120\uD589 '/'(\uC808\uB300 \uACBD\uB85C) \uBC0F \"..\"(\uC0C1\uC704 \uB514\uB809\uD1A0\uB9AC) \uAD6C\uC131\uC694\uC18C\uB97C \uC720\uC9C0\uD569\uB2C8\uB2E4.\n -M \uD56D\uBAA9\uC5D0 \uB300\uD574 Manifest \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n -i \uC9C0\uC815\uB41C jar \uD30C\uC77C\uC5D0 \uB300\uD55C \uC778\uB371\uC2A4 \uC815\uBCF4\uB97C \uC0DD\uC131\uD569\uB2C8\uB2E4.\n -C \uC9C0\uC815\uB41C \uB514\uB809\uD1A0\uB9AC\uB85C \uBCC0\uACBD\uD558\uACE0 \uB2E4\uC74C \uD30C\uC77C\uC744 \uD3EC\uD568\uD569\uB2C8\uB2E4.\n\uD2B9\uC815 \uD30C\uC77C\uC774 \uB514\uB809\uD1A0\uB9AC\uC77C \uACBD\uC6B0 \uC21C\uD658\uC801\uC73C\uB85C \uCC98\uB9AC\uB429\uB2C8\uB2E4.\nManifest \uD30C\uC77C \uC774\uB984, \uC544\uCE74\uC774\uBE0C \uD30C\uC77C \uC774\uB984 \uBC0F \uC2DC\uC791 \uC9C0\uC810 \uC774\uB984\uC740\n'm', 'f' \uBC0F 'e' \uD50C\uB798\uADF8\uC640 \uB3D9\uC77C\uD55C \uC21C\uC11C\uB85C \uC9C0\uC815\uB429\uB2C8\uB2E4.\n\n\uC608 1: classes.jar\uB77C\uB294 \uC544\uCE74\uC774\uBE0C\uC5D0 \uB450 \uD074\uB798\uC2A4 \uD30C\uC77C\uC744 \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvf classes.jar Foo.class Bar.class \n\uC608 2: \uAE30\uC874 Manifest \uD30C\uC77C 'mymanifest'\uB97C \uC0AC\uC6A9\uD558\uC5EC\n foo/ \uB514\uB809\uD1A0\uB9AC\uC758 \uBAA8\uB4E0 \uD30C\uC77C\uC744 'classes.jar'\uB85C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uBC29\uBC95: \n jar cvfm classes.jar mymanifest -C foo/ ." },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_pt_BR.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_pt_BR.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_pt_BR extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "flag 'c' requer que os arquivos de manifesto ou entrada sejam especificados!" },
|
||||
{ "error.bad.eflag", "o flag 'e' e manifesto com o atributo 'Main-Class' n\u00E3o podem ser especificados \njuntos!" },
|
||||
{ "error.bad.option", "Uma das op\u00E7\u00F5es -{ctxu} deve ser especificada." },
|
||||
{ "error.bad.uflag", "o flag 'u' requer que arquivos de manifesto, o flag 'e' ou arquivos de entrada sejam especificados!" },
|
||||
{ "error.cant.open", "n\u00E3o \u00E9 poss\u00EDvel abrir: {0} " },
|
||||
{ "error.create.dir", "{0} : n\u00E3o foi poss\u00EDvel criar o diret\u00F3rio" },
|
||||
{ "error.create.tempfile", "N\u00E3o foi poss\u00EDvel criar um arquivo tempor\u00E1rio" },
|
||||
{ "error.illegal.option", "Op\u00E7\u00E3o inv\u00E1lida: {0}" },
|
||||
{ "error.incorrect.length", "largura incorreta durante o processamento: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0} : n\u00E3o h\u00E1 tal arquivo ou diret\u00F3rio" },
|
||||
{ "error.write.file", "Erro ao gravar o arquivo jar existente" },
|
||||
{ "out.added.manifest", "manifesto adicionado" },
|
||||
{ "out.adding", "adicionando: {0}" },
|
||||
{ "out.create", " criado: {0}" },
|
||||
{ "out.deflated", "(compactado {0}%)" },
|
||||
{ "out.extracted", "extra\u00EDdo: {0}" },
|
||||
{ "out.ignore.entry", "ignorando entrada {0}" },
|
||||
{ "out.inflated", " inflado: {0}" },
|
||||
{ "out.size", "(entrada = {0}) (sa\u00EDda= {1})" },
|
||||
{ "out.stored", "(armazenado 0%)" },
|
||||
{ "out.update.manifest", "manifesto atualizado" },
|
||||
{ "usage", "Uso: jar {ctxui}[vfmn0Mek] [jar-file] [manifest-file] [entry-point] [-C dir] arquivos ...\nOp\u00E7\u00F5es:\n -c cria novo arquivo compactado\n -t lista o sum\u00E1rio do arquivo compactado\n -x extrai arquivos com o nome (ou todos) do arquivo compactado\n -u atualiza o arquivo compactado existente\n -v gera sa\u00EDda detalhada na sa\u00EDda padr\u00E3o\n -f especifica o nome do arquivo do arquivo compactado\n -m inclui as informa\u00E7\u00F5es do manifesto do arquivo de manifesto especificado\n -n executa a normaliza\u00E7\u00E3o Pack200 ap\u00F3s a cria\u00E7\u00E3o de um novo arquivo compactado\n -e especifica o ponto de entrada da aplicativo para aplicativo stand-alone \n empacotada em um arquivo jar execut\u00E1vel\n -0 armazena somente; n\u00E3o usa compacta\u00E7\u00E3o ZIP\n -P preserva os componentes '/' inicial (caminho absoluto) e \"..\" (diret\u00F3rio pai) nos nomes dos arquivos\n -M n\u00E3o cria um arquivo de manifesto para as entradas\n -i gera informa\u00E7\u00F5es de \u00EDndice para os arquivos especificados\n -C passa para o diret\u00F3rio especificado e inclui o arquivo a seguir\nSe um arquivo tamb\u00E9m for um diret\u00F3rio, ele ser\u00E1 processado repetidamente.\nO nome do arquivo de manifesto, o nome do arquivo compactado e o nome do ponto de entrada s\u00E3o\nespecificados na mesma ordem dos flags 'm', 'f' e 'e'.\n\nExemplo 1: para arquivar dois arquivos de classe em um arquivo compactado denominado classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExemplo 2: use um arquivo de manifesto existente 'mymanifest' e arquive todos os\n arquivos no diret\u00F3rio foo/ na 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_sv.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_sv.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_sv extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "f\u00F6r c-flaggan m\u00E5ste manifest- eller indatafiler anges." },
|
||||
{ "error.bad.eflag", "e-flaggan och manifest med attributet Main-Class kan inte anges \ntillsammans." },
|
||||
{ "error.bad.option", "Ett av alternativen -{ctxu} m\u00E5ste anges." },
|
||||
{ "error.bad.uflag", "f\u00F6r u-flaggan m\u00E5ste manifest-, e-flagg- eller indatafiler anges." },
|
||||
{ "error.cant.open", "kan inte \u00F6ppna: {0} " },
|
||||
{ "error.create.dir", "{0} : kunde inte skapa n\u00E5gon katalog" },
|
||||
{ "error.create.tempfile", "Kunde inte skapa en tillf\u00E4llig fil" },
|
||||
{ "error.illegal.option", "Otill\u00E5tet alternativ: {0}" },
|
||||
{ "error.incorrect.length", "ogiltig l\u00E4ngd vid bearbetning: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0} : det finns ingen s\u00E5dan fil eller katalog" },
|
||||
{ "error.write.file", "Ett fel intr\u00E4ffade vid skrivning till befintlig jar-fil." },
|
||||
{ "out.added.manifest", "tillagt manifestfil" },
|
||||
{ "out.adding", "l\u00E4gger till: {0}" },
|
||||
{ "out.create", " skapad: {0}" },
|
||||
{ "out.deflated", "({0}% packat)" },
|
||||
{ "out.extracted", "extraherat: {0}" },
|
||||
{ "out.ignore.entry", "ignorerar posten {0}" },
|
||||
{ "out.inflated", " uppackat: {0}" },
|
||||
{ "out.size", "(in = {0}) (ut = {1})" },
|
||||
{ "out.stored", "(0% lagrat)" },
|
||||
{ "out.update.manifest", "uppdaterat manifest" },
|
||||
{ "usage", "Syntax: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\nAlternativ:\n -c skapa nytt arkiv\n -t lista inneh\u00E5llsf\u00F6rteckning f\u00F6r arkiv\n -x extrahera namngivna (eller alla) filer fr\u00E5n arkivet\n -u uppdatera befintligt arkiv\n -v generera utf\u00F6rliga utdata vid standardutmatning\n -f ange arkivfilens namn\n -m inkludera manifestinformation fr\u00E5n angivet manifest\n -n utf\u00F6r Pack200-normalisering efter att ett nytt arkiv har skapats\n -e ange programstartpunkt f\u00F6r frist\u00E5ende applikation \n som medf\u00F6ljer i en jar-programfil\n -0 lagra endast; anv\u00E4nd inte zip-komprimering\n -P beh\u00E5ll komponenter f\u00F6r inledande '/' (absolut s\u00F6kv\u00E4g) och \"..\" (\u00F6verordnad katalog) fr\u00E5n filnamn\n -M skapa inte n\u00E5gon manifestfil f\u00F6r posterna\n -i generera indexinformation f\u00F6r de angivna jar-filerna\n -C \u00E4ndra till den angivna katalogen och inkludera f\u00F6ljande fil\nOm en fil \u00E4r en katalog bearbetas den rekursivt.\nNamnen p\u00E5 manifestfilen, arkivfilen och startpunkten anges i samma\nordning som flaggorna 'm', 'f' och 'e'.\n\nExempel 1: S\u00E5 h\u00E4r arkiverar du tv\u00E5 klassfiler i ett arkiv med namnet classes.jar: \n jar cvf classes.jar Foo.class Bar.class \nExempel 2: Anv\u00E4nd en befintlig manifestfil (mymanifest) och arkivera alla\n filer fr\u00E5n katalogen 'foo/' till 'classes.jar': \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_zh_CN.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_zh_CN.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_zh_CN extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "'c' \u6807\u8BB0\u8981\u6C42\u6307\u5B9A\u6E05\u5355\u6216\u8F93\u5165\u6587\u4EF6!" },
|
||||
{ "error.bad.eflag", "\u4E0D\u80FD\u540C\u65F6\u6307\u5B9A 'e' \u6807\u8BB0\u548C\u5177\u6709 'Main-Class' \u5C5E\u6027\u7684\n\u6E05\u5355!" },
|
||||
{ "error.bad.option", "\u5FC5\u987B\u6307\u5B9A {ctxu} \u4E2D\u7684\u4EFB\u4E00\u9009\u9879\u3002" },
|
||||
{ "error.bad.uflag", "'u' \u6807\u8BB0\u8981\u6C42\u6307\u5B9A\u6E05\u5355, 'e' \u6807\u8BB0\u6216\u8F93\u5165\u6587\u4EF6!" },
|
||||
{ "error.cant.open", "\u65E0\u6CD5\u6253\u5F00: {0} " },
|
||||
{ "error.create.dir", "{0}: \u65E0\u6CD5\u521B\u5EFA\u76EE\u5F55" },
|
||||
{ "error.create.tempfile", "\u65E0\u6CD5\u521B\u5EFA\u4E34\u65F6\u6587\u4EF6" },
|
||||
{ "error.illegal.option", "\u975E\u6CD5\u9009\u9879: {0}" },
|
||||
{ "error.incorrect.length", "\u5904\u7406\u65F6\u9047\u5230\u4E0D\u6B63\u786E\u7684\u957F\u5EA6: {0}" },
|
||||
{ "error.nosuch.fileordir", "{0}: \u6CA1\u6709\u8FD9\u4E2A\u6587\u4EF6\u6216\u76EE\u5F55" },
|
||||
{ "error.write.file", "\u5199\u5165\u73B0\u6709\u7684 jar \u6587\u4EF6\u65F6\u51FA\u9519" },
|
||||
{ "out.added.manifest", "\u5DF2\u6DFB\u52A0\u6E05\u5355" },
|
||||
{ "out.adding", "\u6B63\u5728\u6DFB\u52A0: {0}" },
|
||||
{ "out.create", " \u5DF2\u521B\u5EFA: {0}" },
|
||||
{ "out.deflated", "(\u538B\u7F29\u4E86 {0}%)" },
|
||||
{ "out.extracted", "\u5DF2\u63D0\u53D6: {0}" },
|
||||
{ "out.ignore.entry", "\u6B63\u5728\u5FFD\u7565\u6761\u76EE{0}" },
|
||||
{ "out.inflated", " \u5DF2\u89E3\u538B: {0}" },
|
||||
{ "out.size", "(\u8F93\u5165 = {0}) (\u8F93\u51FA = {1})" },
|
||||
{ "out.stored", "(\u5B58\u50A8\u4E86 0%)" },
|
||||
{ "out.update.manifest", "\u5DF2\u66F4\u65B0\u6E05\u5355" },
|
||||
{ "usage", "\u7528\u6CD5: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] files ...\n\u9009\u9879:\n -c \u521B\u5EFA\u65B0\u6863\u6848\n -t \u5217\u51FA\u6863\u6848\u76EE\u5F55\n -x \u4ECE\u6863\u6848\u4E2D\u63D0\u53D6\u6307\u5B9A\u7684 (\u6216\u6240\u6709) \u6587\u4EF6\n -u \u66F4\u65B0\u73B0\u6709\u6863\u6848\n -v \u5728\u6807\u51C6\u8F93\u51FA\u4E2D\u751F\u6210\u8BE6\u7EC6\u8F93\u51FA\n -f \u6307\u5B9A\u6863\u6848\u6587\u4EF6\u540D\n -m \u5305\u542B\u6307\u5B9A\u6E05\u5355\u6587\u4EF6\u4E2D\u7684\u6E05\u5355\u4FE1\u606F\n -n \u521B\u5EFA\u65B0\u6863\u6848\u540E\u6267\u884C Pack200 \u89C4\u8303\u5316\n -e \u4E3A\u6346\u7ED1\u5230\u53EF\u6267\u884C jar \u6587\u4EF6\u7684\u72EC\u7ACB\u5E94\u7528\u7A0B\u5E8F\n \u6307\u5B9A\u5E94\u7528\u7A0B\u5E8F\u5165\u53E3\u70B9\n -0 \u4EC5\u5B58\u50A8; \u4E0D\u4F7F\u7528\u4EFB\u4F55 ZIP \u538B\u7F29\n -P \u4FDD\u7559\u6587\u4EF6\u540D\u4E2D\u7684\u524D\u5BFC '/' (\u7EDD\u5BF9\u8DEF\u5F84) \u548C \"..\" (\u7236\u76EE\u5F55) \u7EC4\u4EF6\n -M \u4E0D\u521B\u5EFA\u6761\u76EE\u7684\u6E05\u5355\u6587\u4EF6\n -i \u4E3A\u6307\u5B9A\u7684 jar \u6587\u4EF6\u751F\u6210\u7D22\u5F15\u4FE1\u606F\n -C \u66F4\u6539\u4E3A\u6307\u5B9A\u7684\u76EE\u5F55\u5E76\u5305\u542B\u4EE5\u4E0B\u6587\u4EF6\n\u5982\u679C\u4EFB\u4F55\u6587\u4EF6\u4E3A\u76EE\u5F55, \u5219\u5BF9\u5176\u8FDB\u884C\u9012\u5F52\u5904\u7406\u3002\n\u6E05\u5355\u6587\u4EF6\u540D, \u6863\u6848\u6587\u4EF6\u540D\u548C\u5165\u53E3\u70B9\u540D\u79F0\u7684\u6307\u5B9A\u987A\u5E8F\n\u4E0E 'm', 'f' \u548C 'e' \u6807\u8BB0\u7684\u6307\u5B9A\u987A\u5E8F\u76F8\u540C\u3002\n\n\u793A\u4F8B 1: \u5C06\u4E24\u4E2A\u7C7B\u6587\u4EF6\u5F52\u6863\u5230\u4E00\u4E2A\u540D\u4E3A classes.jar \u7684\u6863\u6848\u4E2D: \n jar cvf classes.jar Foo.class Bar.class \n\u793A\u4F8B 2: \u4F7F\u7528\u73B0\u6709\u7684\u6E05\u5355\u6587\u4EF6 'mymanifest' \u5E76\n \u5C06 foo/ \u76EE\u5F55\u4E2D\u7684\u6240\u6709\u6587\u4EF6\u5F52\u6863\u5230 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_zh_HK.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_zh_HK.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_zh_HK extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "'c' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u6216\u8F38\u5165\u6A94\u6848\uFF01" },
|
||||
{ "error.bad.eflag", "\u7121\u6CD5\u540C\u6642\u6307\u5B9A 'e' \u65D7\u6A19\u548C\u5177\u6709 'Main-Class' \u5C6C\u6027\u7684\n\u8CC7\u8A0A\u6E05\u55AE\uFF01" },
|
||||
{ "error.bad.option", "\u5176\u4E2D\u4E00\u500B\u9078\u9805 -{ctxu} \u5FC5\u9808\u52A0\u4EE5\u6307\u5B9A\u3002" },
|
||||
{ "error.bad.uflag", "'u' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u3001'e' \u65D7\u6A19\u6216\u8F38\u5165\u6A94\u6848\uFF01" },
|
||||
{ "error.cant.open", "\u7121\u6CD5\u958B\u555F: {0} " },
|
||||
{ "error.create.dir", "{0} : \u7121\u6CD5\u5EFA\u7ACB\u76EE\u9304" },
|
||||
{ "error.create.tempfile", "\u7121\u6CD5\u5EFA\u7ACB\u66AB\u5B58\u6A94\u6848" },
|
||||
{ "error.illegal.option", "\u7121\u6548\u7684\u9078\u9805: {0}" },
|
||||
{ "error.incorrect.length", "\u8655\u7406 {0} \u6642\u9577\u5EA6\u4E0D\u6B63\u78BA" },
|
||||
{ "error.nosuch.fileordir", "{0} : \u6C92\u6709\u9019\u985E\u6A94\u6848\u6216\u76EE\u9304" },
|
||||
{ "error.write.file", "\u5BEB\u5165\u73FE\u6709\u7684 jar \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4" },
|
||||
{ "out.added.manifest", "\u5DF2\u65B0\u589E\u8CC7\u8A0A\u6E05\u55AE" },
|
||||
{ "out.adding", "\u65B0\u589E: {0}" },
|
||||
{ "out.create", " \u5EFA\u7ACB: {0}" },
|
||||
{ "out.deflated", "(\u58D3\u7E2E {0}%)" },
|
||||
{ "out.extracted", "\u64F7\u53D6: {0}" },
|
||||
{ "out.ignore.entry", "\u5FFD\u7565\u9805\u76EE {0}" },
|
||||
{ "out.inflated", " \u64F4\u5C55: {0}" },
|
||||
{ "out.size", " (\u8B80={0})(\u5BEB={1})" },
|
||||
{ "out.stored", "(\u5132\u5B58 0%)" },
|
||||
{ "out.update.manifest", "\u5DF2\u66F4\u65B0\u8CC7\u8A0A\u6E05\u55AE" },
|
||||
{ "usage", "\u7528\u6CD5: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] \u6A94\u6848 ...\n\u9078\u9805:\n -c \u5EFA\u7ACB\u65B0\u7684\u6B78\u6A94\n -t \u5217\u51FA\u6B78\u6A94\u7684\u76EE\u9304\n -x \u5F9E\u6B78\u6A94\u4E2D\u64F7\u53D6\u6307\u5B9A (\u6216\u6240\u6709) \u6A94\u6848\n -u \u66F4\u65B0\u73FE\u6709\u6B78\u6A94\n -v \u5728\u6A19\u6E96\u8F38\u51FA\u4E2D\u7522\u751F\u8A73\u7D30\u8F38\u51FA\n -f \u6307\u5B9A\u6B78\u6A94\u6A94\u6848\u540D\u7A31\n -m \u5305\u542B\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u4E2D\u7684\u8CC7\u8A0A\u6E05\u55AE\u8CC7\u8A0A\n -n \u5728\u5EFA\u7ACB\u65B0\u6B78\u6A94\u4E4B\u5F8C\u57F7\u884C Pack200 \u6B63\u898F\u5316\n -e \u70BA\u5DF2\u96A8\u9644\u65BC\u53EF\u57F7\u884C jar \u6A94\u6848\u4E2D\u7684\u7368\u7ACB\u61C9\u7528\u7A0B\u5F0F\n \u6307\u5B9A\u61C9\u7528\u7A0B\u5F0F\u9032\u5165\u9EDE\n -0 \u50C5\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F\n -P \u4FDD\u7559\u6A94\u6848\u540D\u7A31\u524D\u9762\u7684 '/' (\u7D55\u5C0D\u8DEF\u5F91) \u548C \"..\" (\u4E0A\u5C64\u76EE\u9304) \u5143\u4EF6\n -M \u4E0D\u70BA\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\n -i \u70BA\u6307\u5B9A\u7684 jar \u6A94\u6848\u7522\u751F\u7D22\u5F15\u8CC7\u8A0A\n -C \u8B8A\u66F4\u81F3\u6307\u5B9A\u76EE\u9304\u4E26\u5305\u542B\u5F8C\u9762\u6240\u5217\u7684\u6A94\u6848\n\u5982\u679C\u6709\u4EFB\u4F55\u6A94\u6848\u662F\u76EE\u9304\uFF0C\u5247\u6703\u5C0D\u5176\u9032\u884C\u905E\u8FF4\u8655\u7406\u3002\n\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u540D\u7A31\u3001\u6B78\u6A94\u6A94\u6848\u540D\u7A31\u548C\u9032\u5165\u9EDE\u540D\u7A31\n\u7684\u6307\u5B9A\u9806\u5E8F\u8207\u6307\u5B9A 'm' \u65D7\u6A19\u3001'f' \u65D7\u6A19\u548C 'e' \u65D7\u6A19\u7684\u9806\u5E8F\u76F8\u540C\u3002\n\n\u7BC4\u4F8B 1: \u5C07\u5169\u500B\u985E\u5225\u6A94\u6848\u6B78\u6A94\u81F3\u540D\u70BA classes.jar \u7684\u6B78\u6A94\u4E2D: \n jar cvf classes.jar Foo.class Bar.class\n\u7BC4\u4F8B 2: \u4F7F\u7528\u73FE\u6709\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848 'mymanifest' \u4E26\u5C07\n foo/ \u76EE\u9304\u4E2D\u7684\u6240\u6709\u6A94\u6848\u6B78\u6A94\u81F3 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_zh_TW.java
Normal file
32
jdkSrc/jdk8/sun/tools/jar/resources/jar_zh_TW.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package sun.tools.jar.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jar_zh_TW extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "error.bad.cflag", "'c' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u6216\u8F38\u5165\u6A94\u6848\uFF01" },
|
||||
{ "error.bad.eflag", "\u7121\u6CD5\u540C\u6642\u6307\u5B9A 'e' \u65D7\u6A19\u548C\u5177\u6709 'Main-Class' \u5C6C\u6027\u7684\n\u8CC7\u8A0A\u6E05\u55AE\uFF01" },
|
||||
{ "error.bad.option", "\u5176\u4E2D\u4E00\u500B\u9078\u9805 -{ctxu} \u5FC5\u9808\u52A0\u4EE5\u6307\u5B9A\u3002" },
|
||||
{ "error.bad.uflag", "'u' \u65D7\u6A19\u8981\u6C42\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u3001'e' \u65D7\u6A19\u6216\u8F38\u5165\u6A94\u6848\uFF01" },
|
||||
{ "error.cant.open", "\u7121\u6CD5\u958B\u555F: {0} " },
|
||||
{ "error.create.dir", "{0} : \u7121\u6CD5\u5EFA\u7ACB\u76EE\u9304" },
|
||||
{ "error.create.tempfile", "\u7121\u6CD5\u5EFA\u7ACB\u66AB\u5B58\u6A94\u6848" },
|
||||
{ "error.illegal.option", "\u7121\u6548\u7684\u9078\u9805: {0}" },
|
||||
{ "error.incorrect.length", "\u8655\u7406 {0} \u6642\u9577\u5EA6\u4E0D\u6B63\u78BA" },
|
||||
{ "error.nosuch.fileordir", "{0} : \u6C92\u6709\u9019\u985E\u6A94\u6848\u6216\u76EE\u9304" },
|
||||
{ "error.write.file", "\u5BEB\u5165\u73FE\u6709\u7684 jar \u6A94\u6848\u6642\u767C\u751F\u932F\u8AA4" },
|
||||
{ "out.added.manifest", "\u5DF2\u65B0\u589E\u8CC7\u8A0A\u6E05\u55AE" },
|
||||
{ "out.adding", "\u65B0\u589E: {0}" },
|
||||
{ "out.create", " \u5EFA\u7ACB: {0}" },
|
||||
{ "out.deflated", "(\u58D3\u7E2E {0}%)" },
|
||||
{ "out.extracted", "\u64F7\u53D6: {0}" },
|
||||
{ "out.ignore.entry", "\u5FFD\u7565\u9805\u76EE {0}" },
|
||||
{ "out.inflated", " \u64F4\u5C55: {0}" },
|
||||
{ "out.size", " (\u8B80={0})(\u5BEB={1})" },
|
||||
{ "out.stored", "(\u5132\u5B58 0%)" },
|
||||
{ "out.update.manifest", "\u5DF2\u66F4\u65B0\u8CC7\u8A0A\u6E05\u55AE" },
|
||||
{ "usage", "\u7528\u6CD5: jar {ctxui}[vfmn0PMek] [jar-file] [manifest-file] [entry-point] [-C dir] \u6A94\u6848 ...\n\u9078\u9805:\n -c \u5EFA\u7ACB\u65B0\u7684\u6B78\u6A94\n -t \u5217\u51FA\u6B78\u6A94\u7684\u76EE\u9304\n -x \u5F9E\u6B78\u6A94\u4E2D\u64F7\u53D6\u6307\u5B9A (\u6216\u6240\u6709) \u6A94\u6848\n -u \u66F4\u65B0\u73FE\u6709\u6B78\u6A94\n -v \u5728\u6A19\u6E96\u8F38\u51FA\u4E2D\u7522\u751F\u8A73\u7D30\u8F38\u51FA\n -f \u6307\u5B9A\u6B78\u6A94\u6A94\u6848\u540D\u7A31\n -m \u5305\u542B\u6307\u5B9A\u8CC7\u8A0A\u6E05\u55AE\u4E2D\u7684\u8CC7\u8A0A\u6E05\u55AE\u8CC7\u8A0A\n -n \u5728\u5EFA\u7ACB\u65B0\u6B78\u6A94\u4E4B\u5F8C\u57F7\u884C Pack200 \u6B63\u898F\u5316\n -e \u70BA\u5DF2\u96A8\u9644\u65BC\u53EF\u57F7\u884C jar \u6A94\u6848\u4E2D\u7684\u7368\u7ACB\u61C9\u7528\u7A0B\u5F0F\n \u6307\u5B9A\u61C9\u7528\u7A0B\u5F0F\u9032\u5165\u9EDE\n -0 \u50C5\u5132\u5B58; \u4E0D\u4F7F\u7528 ZIP \u58D3\u7E2E\u65B9\u5F0F\n -P \u4FDD\u7559\u6A94\u6848\u540D\u7A31\u524D\u9762\u7684 '/' (\u7D55\u5C0D\u8DEF\u5F91) \u548C \"..\" (\u4E0A\u5C64\u76EE\u9304) \u5143\u4EF6\n -M \u4E0D\u70BA\u9805\u76EE\u5EFA\u7ACB\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\n -i \u70BA\u6307\u5B9A\u7684 jar \u6A94\u6848\u7522\u751F\u7D22\u5F15\u8CC7\u8A0A\n -C \u8B8A\u66F4\u81F3\u6307\u5B9A\u76EE\u9304\u4E26\u5305\u542B\u5F8C\u9762\u6240\u5217\u7684\u6A94\u6848\n\u5982\u679C\u6709\u4EFB\u4F55\u6A94\u6848\u662F\u76EE\u9304\uFF0C\u5247\u6703\u5C0D\u5176\u9032\u884C\u905E\u8FF4\u8655\u7406\u3002\n\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848\u540D\u7A31\u3001\u6B78\u6A94\u6A94\u6848\u540D\u7A31\u548C\u9032\u5165\u9EDE\u540D\u7A31\n\u7684\u6307\u5B9A\u9806\u5E8F\u8207\u6307\u5B9A 'm' \u65D7\u6A19\u3001'f' \u65D7\u6A19\u548C 'e' \u65D7\u6A19\u7684\u9806\u5E8F\u76F8\u540C\u3002\n\n\u7BC4\u4F8B 1: \u5C07\u5169\u500B\u985E\u5225\u6A94\u6848\u6B78\u6A94\u81F3\u540D\u70BA classes.jar \u7684\u6B78\u6A94\u4E2D: \n jar cvf classes.jar Foo.class Bar.class\n\u7BC4\u4F8B 2: \u4F7F\u7528\u73FE\u6709\u8CC7\u8A0A\u6E05\u55AE\u6A94\u6848 'mymanifest' \u4E26\u5C07\n foo/ \u76EE\u9304\u4E2D\u7684\u6240\u6709\u6A94\u6848\u6B78\u6A94\u81F3 'classes.jar' \u4E2D: \n jar cvfm classes.jar mymanifest -C foo/ .\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
53
jdkSrc/jdk8/sun/tools/java/AmbiguousClass.java
Normal file
53
jdkSrc/jdk8/sun/tools/java/AmbiguousClass.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This exception is thrown when an unqualified class name
|
||||
* is used that can be resolved in more than one way.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
public
|
||||
class AmbiguousClass extends ClassNotFound {
|
||||
/**
|
||||
* The class that was not found
|
||||
*/
|
||||
public Identifier name1;
|
||||
public Identifier name2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AmbiguousClass(Identifier name1, Identifier name2) {
|
||||
super(name1.getName());
|
||||
this.name1 = name1;
|
||||
this.name2 = name2;
|
||||
}
|
||||
}
|
||||
54
jdkSrc/jdk8/sun/tools/java/AmbiguousMember.java
Normal file
54
jdkSrc/jdk8/sun/tools/java/AmbiguousMember.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a field reference is
|
||||
* ambiguous.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public
|
||||
class AmbiguousMember extends Exception {
|
||||
/**
|
||||
* The field that was not found
|
||||
*/
|
||||
public MemberDefinition field1;
|
||||
public MemberDefinition field2;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AmbiguousMember(MemberDefinition field1, MemberDefinition field2) {
|
||||
super(field1.getName() + " + " + field2.getName());
|
||||
this.field1 = field1;
|
||||
this.field2 = field2;
|
||||
}
|
||||
}
|
||||
65
jdkSrc/jdk8/sun/tools/java/ArrayType.java
Normal file
65
jdkSrc/jdk8/sun/tools/java/ArrayType.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This class represents an Java array type.
|
||||
* It overrides the relevant methods in class Type.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public final
|
||||
class ArrayType extends Type {
|
||||
/**
|
||||
* The type of the element.
|
||||
*/
|
||||
Type elemType;
|
||||
|
||||
/**
|
||||
* Construct an array type. Use Type.tArray to create
|
||||
* a new array type.
|
||||
*/
|
||||
ArrayType(String typeSig, Type elemType) {
|
||||
super(TC_ARRAY, typeSig);
|
||||
this.elemType = elemType;
|
||||
}
|
||||
|
||||
public Type getElementType() {
|
||||
return elemType;
|
||||
}
|
||||
|
||||
public int getArrayDimension() {
|
||||
return elemType.getArrayDimension() + 1;
|
||||
}
|
||||
|
||||
public String typeString(String id, boolean abbrev, boolean ret) {
|
||||
return getElementType().typeString(id, abbrev, ret) + "[]";
|
||||
}
|
||||
}
|
||||
112
jdkSrc/jdk8/sun/tools/java/BinaryAttribute.java
Normal file
112
jdkSrc/jdk8/sun/tools/java/BinaryAttribute.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
/**
|
||||
* This class is used to represent an attribute from a binary class.
|
||||
* This class should go away once arrays are objects.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class BinaryAttribute implements Constants {
|
||||
Identifier name;
|
||||
byte data[];
|
||||
BinaryAttribute next;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
BinaryAttribute(Identifier name, byte data[], BinaryAttribute next) {
|
||||
this.name = name;
|
||||
this.data = data;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a list of attributes
|
||||
*/
|
||||
public static BinaryAttribute load(DataInputStream in, BinaryConstantPool cpool, int mask) throws IOException {
|
||||
BinaryAttribute atts = null;
|
||||
int natt = in.readUnsignedShort(); // JVM 4.6 method_info.attrutes_count
|
||||
|
||||
for (int i = 0 ; i < natt ; i++) {
|
||||
// id from JVM 4.7 attribute_info.attribute_name_index
|
||||
Identifier id = cpool.getIdentifier(in.readUnsignedShort());
|
||||
// id from JVM 4.7 attribute_info.attribute_length
|
||||
int len = in.readInt();
|
||||
|
||||
if (id.equals(idCode) && ((mask & ATT_CODE) == 0)) {
|
||||
in.skipBytes(len);
|
||||
} else {
|
||||
byte data[] = new byte[len];
|
||||
in.readFully(data);
|
||||
atts = new BinaryAttribute(id, data, atts);
|
||||
}
|
||||
}
|
||||
return atts;
|
||||
}
|
||||
|
||||
// write out the Binary attributes to the given stream
|
||||
// (note that attributes may be null)
|
||||
static void write(BinaryAttribute attributes, DataOutputStream out,
|
||||
BinaryConstantPool cpool, Environment env) throws IOException {
|
||||
// count the number of attributes
|
||||
int attributeCount = 0;
|
||||
for (BinaryAttribute att = attributes; att != null; att = att.next)
|
||||
attributeCount++;
|
||||
out.writeShort(attributeCount);
|
||||
|
||||
// write out each attribute
|
||||
for (BinaryAttribute att = attributes; att != null; att = att.next) {
|
||||
Identifier name = att.name;
|
||||
byte data[] = att.data;
|
||||
// write the identifier
|
||||
out.writeShort(cpool.indexString(name.toString(), env));
|
||||
// write the length
|
||||
out.writeInt(data.length);
|
||||
// write the data
|
||||
out.write(data, 0, data.length);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
|
||||
public Identifier getName() { return name; }
|
||||
|
||||
public byte getData()[] { return data; }
|
||||
|
||||
public BinaryAttribute getNextAttribute() { return next; }
|
||||
|
||||
}
|
||||
534
jdkSrc/jdk8/sun/tools/java/BinaryClass.java
Normal file
534
jdkSrc/jdk8/sun/tools/java/BinaryClass.java
Normal file
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2006, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class BinaryClass extends ClassDefinition implements Constants {
|
||||
BinaryConstantPool cpool;
|
||||
BinaryAttribute atts;
|
||||
Vector dependencies;
|
||||
private boolean haveLoadedNested = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public BinaryClass(Object source, ClassDeclaration declaration, int modifiers,
|
||||
ClassDeclaration superClass, ClassDeclaration interfaces[],
|
||||
Vector dependencies) {
|
||||
super(source, 0, declaration, modifiers, null, null);
|
||||
this.dependencies = dependencies;
|
||||
this.superClass = superClass;
|
||||
this.interfaces = interfaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags used by basicCheck() to avoid duplicate calls.
|
||||
* (Part of fix for 4105911)
|
||||
*/
|
||||
private boolean basicCheckDone = false;
|
||||
private boolean basicChecking = false;
|
||||
|
||||
/**
|
||||
* Ready a BinaryClass for further checking. Note that, until recently,
|
||||
* BinaryClass relied on the default basicCheck() provided by
|
||||
* ClassDefinition. The definition here has been added to ensure that
|
||||
* the information generated by collectInheritedMethods is available
|
||||
* for BinaryClasses.
|
||||
*/
|
||||
protected void basicCheck(Environment env) throws ClassNotFound {
|
||||
if (tracing) env.dtEnter("BinaryClass.basicCheck: " + getName());
|
||||
|
||||
// We need to guard against duplicate calls to basicCheck(). They
|
||||
// can lead to calling collectInheritedMethods() for this class
|
||||
// from within a previous call to collectInheritedMethods() for
|
||||
// this class. That is not allowed.
|
||||
// (Part of fix for 4105911)
|
||||
if (basicChecking || basicCheckDone) {
|
||||
if (tracing) env.dtExit("BinaryClass.basicCheck: OK " + getName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (tracing) env.dtEvent("BinaryClass.basicCheck: CHECKING " + getName());
|
||||
basicChecking = true;
|
||||
|
||||
super.basicCheck(env);
|
||||
|
||||
// Collect inheritance information.
|
||||
if (doInheritanceChecks) {
|
||||
collectInheritedMethods(env);
|
||||
}
|
||||
|
||||
basicCheckDone = true;
|
||||
basicChecking = false;
|
||||
if (tracing) env.dtExit("BinaryClass.basicCheck: " + getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a binary class
|
||||
*/
|
||||
public static BinaryClass load(Environment env, DataInputStream in) throws IOException {
|
||||
return load(env, in, ~(ATT_CODE|ATT_ALLCLASSES));
|
||||
}
|
||||
|
||||
public static BinaryClass load(Environment env,
|
||||
DataInputStream in, int mask) throws IOException {
|
||||
// Read the header
|
||||
int magic = in.readInt(); // JVM 4.1 ClassFile.magic
|
||||
if (magic != JAVA_MAGIC) {
|
||||
throw new ClassFormatError("wrong magic: " + magic + ", expected " + JAVA_MAGIC);
|
||||
}
|
||||
int minor_version = in.readUnsignedShort(); // JVM 4.1 ClassFile.minor_version
|
||||
int version = in.readUnsignedShort(); // JVM 4.1 ClassFile.major_version
|
||||
if (version < JAVA_MIN_SUPPORTED_VERSION) {
|
||||
throw new ClassFormatError(
|
||||
sun.tools.javac.Main.getText(
|
||||
"javac.err.version.too.old",
|
||||
String.valueOf(version)));
|
||||
} else if ((version > JAVA_MAX_SUPPORTED_VERSION)
|
||||
|| (version == JAVA_MAX_SUPPORTED_VERSION
|
||||
&& minor_version > JAVA_MAX_SUPPORTED_MINOR_VERSION)) {
|
||||
throw new ClassFormatError(
|
||||
sun.tools.javac.Main.getText(
|
||||
"javac.err.version.too.recent",
|
||||
version+"."+minor_version));
|
||||
}
|
||||
|
||||
// Read the constant pool
|
||||
BinaryConstantPool cpool = new BinaryConstantPool(in);
|
||||
|
||||
// The dependencies of this class
|
||||
Vector dependencies = cpool.getDependencies(env);
|
||||
|
||||
// Read modifiers
|
||||
int classMod = in.readUnsignedShort() & ACCM_CLASS; // JVM 4.1 ClassFile.access_flags
|
||||
|
||||
// Read the class name - from JVM 4.1 ClassFile.this_class
|
||||
ClassDeclaration classDecl = cpool.getDeclaration(env, in.readUnsignedShort());
|
||||
|
||||
// Read the super class name (may be null) - from JVM 4.1 ClassFile.super_class
|
||||
ClassDeclaration superClassDecl = cpool.getDeclaration(env, in.readUnsignedShort());
|
||||
|
||||
// Read the interface names - from JVM 4.1 ClassFile.interfaces_count
|
||||
ClassDeclaration interfaces[] = new ClassDeclaration[in.readUnsignedShort()];
|
||||
for (int i = 0 ; i < interfaces.length ; i++) {
|
||||
// JVM 4.1 ClassFile.interfaces[]
|
||||
interfaces[i] = cpool.getDeclaration(env, in.readUnsignedShort());
|
||||
}
|
||||
|
||||
// Allocate the class
|
||||
BinaryClass c = new BinaryClass(null, classDecl, classMod, superClassDecl,
|
||||
interfaces, dependencies);
|
||||
c.cpool = cpool;
|
||||
|
||||
// Add any additional dependencies
|
||||
c.addDependency(superClassDecl);
|
||||
|
||||
// Read the fields
|
||||
int nfields = in.readUnsignedShort(); // JVM 4.1 ClassFile.fields_count
|
||||
for (int i = 0 ; i < nfields ; i++) {
|
||||
// JVM 4.5 field_info.access_flags
|
||||
int fieldMod = in.readUnsignedShort() & ACCM_FIELD;
|
||||
// JVM 4.5 field_info.name_index
|
||||
Identifier fieldName = cpool.getIdentifier(in.readUnsignedShort());
|
||||
// JVM 4.5 field_info.descriptor_index
|
||||
Type fieldType = cpool.getType(in.readUnsignedShort());
|
||||
BinaryAttribute atts = BinaryAttribute.load(in, cpool, mask);
|
||||
c.addMember(new BinaryMember(c, fieldMod, fieldType, fieldName, atts));
|
||||
}
|
||||
|
||||
// Read the methods
|
||||
int nmethods = in.readUnsignedShort(); // JVM 4.1 ClassFile.methods_count
|
||||
for (int i = 0 ; i < nmethods ; i++) {
|
||||
// JVM 4.6 method_info.access_flags
|
||||
int methMod = in.readUnsignedShort() & ACCM_METHOD;
|
||||
// JVM 4.6 method_info.name_index
|
||||
Identifier methName = cpool.getIdentifier(in.readUnsignedShort());
|
||||
// JVM 4.6 method_info.descriptor_index
|
||||
Type methType = cpool.getType(in.readUnsignedShort());
|
||||
BinaryAttribute atts = BinaryAttribute.load(in, cpool, mask);
|
||||
c.addMember(new BinaryMember(c, methMod, methType, methName, atts));
|
||||
}
|
||||
|
||||
// Read the class attributes
|
||||
c.atts = BinaryAttribute.load(in, cpool, mask);
|
||||
|
||||
// See if the SourceFile is known
|
||||
byte data[] = c.getAttribute(idSourceFile);
|
||||
if (data != null) {
|
||||
DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(data));
|
||||
// JVM 4.7.2 SourceFile_attribute.sourcefile_index
|
||||
c.source = cpool.getString(dataStream.readUnsignedShort());
|
||||
}
|
||||
|
||||
// See if the Documentation is know
|
||||
data = c.getAttribute(idDocumentation);
|
||||
if (data != null) {
|
||||
c.documentation = new DataInputStream(new ByteArrayInputStream(data)).readUTF();
|
||||
}
|
||||
|
||||
// Was it compiled as deprecated?
|
||||
if (c.getAttribute(idDeprecated) != null) {
|
||||
c.modifiers |= M_DEPRECATED;
|
||||
}
|
||||
|
||||
// Was it synthesized by the compiler?
|
||||
if (c.getAttribute(idSynthetic) != null) {
|
||||
c.modifiers |= M_SYNTHETIC;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an environment ties a binary definition to a declaration.
|
||||
* At this point, auxiliary definitions may be loaded.
|
||||
*/
|
||||
|
||||
public void loadNested(Environment env) {
|
||||
loadNested(env, 0);
|
||||
}
|
||||
|
||||
public void loadNested(Environment env, int flags) {
|
||||
// Sanity check.
|
||||
if (haveLoadedNested) {
|
||||
// Duplicate calls most likely should not occur, but they do
|
||||
// in javap. Be tolerant of them for the time being.
|
||||
// throw new CompilerError("multiple loadNested");
|
||||
if (tracing) env.dtEvent("loadNested: DUPLICATE CALL SKIPPED");
|
||||
return;
|
||||
}
|
||||
haveLoadedNested = true;
|
||||
// Read class-nesting information.
|
||||
try {
|
||||
byte data[];
|
||||
data = getAttribute(idInnerClasses);
|
||||
if (data != null) {
|
||||
initInnerClasses(env, data, flags);
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
// The inner classes attribute is not well-formed.
|
||||
// It may, for example, contain no data. Report this.
|
||||
// We used to throw a CompilerError here (bug 4095108).
|
||||
env.error(0, "malformed.attribute", getClassDeclaration(),
|
||||
idInnerClasses);
|
||||
if (tracing)
|
||||
env.dtEvent("loadNested: MALFORMED ATTRIBUTE (InnerClasses)");
|
||||
}
|
||||
}
|
||||
|
||||
private void initInnerClasses(Environment env,
|
||||
byte data[],
|
||||
int flags) throws IOException {
|
||||
DataInputStream ds = new DataInputStream(new ByteArrayInputStream(data));
|
||||
int nrec = ds.readUnsignedShort(); // InnerClasses_attribute.number_of_classes
|
||||
for (int i = 0; i < nrec; i++) {
|
||||
// For each inner class name transformation, we have a record
|
||||
// with the following fields:
|
||||
//
|
||||
// u2 inner_class_info_index; // CONSTANT_Class_info index
|
||||
// u2 outer_class_info_index; // CONSTANT_Class_info index
|
||||
// u2 inner_name_index; // CONSTANT_Utf8_info index
|
||||
// u2 inner_class_access_flags; // access_flags bitmask
|
||||
//
|
||||
// The spec states that outer_class_info_index is 0 iff
|
||||
// the inner class is not a member of its enclosing class (i.e.
|
||||
// it is a local or anonymous class). The spec also states
|
||||
// that if a class is anonymous then inner_name_index should
|
||||
// be 0.
|
||||
//
|
||||
// Prior to jdk1.2, javac did not implement the spec. Instead
|
||||
// it <em>always</em> set outer_class_info_index to the
|
||||
// enclosing outer class and if the class was anonymous,
|
||||
// it set inner_name_index to be the index of a CONSTANT_Utf8
|
||||
// entry containing the null string "" (idNull). This code is
|
||||
// designed to handle either kind of class file.
|
||||
//
|
||||
// See also the compileClass() method in SourceClass.java.
|
||||
|
||||
// Read in the inner_class_info
|
||||
// InnerClasses_attribute.classes.inner_class_info_index
|
||||
int inner_index = ds.readUnsignedShort();
|
||||
// could check for zero.
|
||||
ClassDeclaration inner = cpool.getDeclaration(env, inner_index);
|
||||
|
||||
// Read in the outer_class_info. Note that the index will be
|
||||
// zero if the class is "not a member".
|
||||
ClassDeclaration outer = null;
|
||||
// InnerClasses_attribute.classes.outer_class_info_index
|
||||
int outer_index = ds.readUnsignedShort();
|
||||
if (outer_index != 0) {
|
||||
outer = cpool.getDeclaration(env, outer_index);
|
||||
}
|
||||
|
||||
// Read in the inner_name_index. This may be zero. An anonymous
|
||||
// class will either have an inner_nm_index of zero (as the spec
|
||||
// dictates) or it will have an inner_nm of idNull (for classes
|
||||
// generated by pre-1.2 compilers). Handle both.
|
||||
Identifier inner_nm = idNull;
|
||||
// InnerClasses_attribute.classes.inner_name_index
|
||||
int inner_nm_index = ds.readUnsignedShort();
|
||||
if (inner_nm_index != 0) {
|
||||
inner_nm = Identifier.lookup(cpool.getString(inner_nm_index));
|
||||
}
|
||||
|
||||
// Read in the modifiers for the inner class.
|
||||
// InnerClasses_attribute.classes.inner_name_index
|
||||
int mods = ds.readUnsignedShort();
|
||||
|
||||
// Is the class accessible?
|
||||
// The old code checked for
|
||||
//
|
||||
// (!inner_nm.equals(idNull) && (mods & M_PRIVATE) == 0)
|
||||
//
|
||||
// which we will preserve to keep it working for class files
|
||||
// generated by 1.1 compilers. In addition we check for
|
||||
//
|
||||
// (outer != null)
|
||||
//
|
||||
// as an additional check that only makes sense with 1.2
|
||||
// generated files. Note that it is entirely possible that
|
||||
// the M_PRIVATE bit is always enough. We are being
|
||||
// conservative here.
|
||||
//
|
||||
// The ATT_ALLCLASSES flag causes the M_PRIVATE modifier
|
||||
// to be ignored, and is used by tools such as 'javap' that
|
||||
// wish to examine all classes regardless of the normal access
|
||||
// controls that apply during compilation. Note that anonymous
|
||||
// and local classes are still not considered accessible, though
|
||||
// named local classes in jdk1.1 may slip through. Note that
|
||||
// this accessibility test is an optimization, and it is safe to
|
||||
// err on the side of greater accessibility.
|
||||
boolean accessible =
|
||||
(outer != null) &&
|
||||
(!inner_nm.equals(idNull)) &&
|
||||
((mods & M_PRIVATE) == 0 ||
|
||||
(flags & ATT_ALLCLASSES) != 0);
|
||||
|
||||
// The reader should note that there has been a significant change
|
||||
// in the way that the InnerClasses attribute is being handled.
|
||||
// In particular, previously the compiler called initInner() for
|
||||
// <em>every</em> inner class. Now the compiler does not call
|
||||
// initInner() if the inner class is inaccessible. This means
|
||||
// that inaccessible inner classes don't have any of the processing
|
||||
// from initInner() done for them: fixing the access flags,
|
||||
// setting outerClass, setting outerMember in their outerClass,
|
||||
// etc. We believe this is fine: if the class is inaccessible
|
||||
// and binary, then everyone who needs to see its internals
|
||||
// has already been compiled. Hopefully.
|
||||
|
||||
if (accessible) {
|
||||
Identifier nm =
|
||||
Identifier.lookupInner(outer.getName(), inner_nm);
|
||||
|
||||
// Tell the type module about the nesting relation:
|
||||
Type.tClass(nm);
|
||||
|
||||
if (inner.equals(getClassDeclaration())) {
|
||||
// The inner class in the record is this class.
|
||||
try {
|
||||
ClassDefinition outerClass = outer.getClassDefinition(env);
|
||||
initInner(outerClass, mods);
|
||||
} catch (ClassNotFound e) {
|
||||
// report the error elsewhere
|
||||
}
|
||||
} else if (outer.equals(getClassDeclaration())) {
|
||||
// The outer class in the record is this class.
|
||||
try {
|
||||
ClassDefinition innerClass =
|
||||
inner.getClassDefinition(env);
|
||||
initOuter(innerClass, mods);
|
||||
} catch (ClassNotFound e) {
|
||||
// report the error elsewhere
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initInner(ClassDefinition outerClass, int mods) {
|
||||
if (getOuterClass() != null)
|
||||
return; // already done
|
||||
/******
|
||||
// Maybe set static, protected, or private.
|
||||
if ((modifiers & M_PUBLIC) != 0)
|
||||
mods &= M_STATIC;
|
||||
else
|
||||
mods &= M_PRIVATE | M_PROTECTED | M_STATIC;
|
||||
modifiers |= mods;
|
||||
******/
|
||||
// For an inner class, the class access may have been weakened
|
||||
// from that originally declared the source. We must take the
|
||||
// actual access permissions against which we check any source
|
||||
// we are currently compiling from the InnerClasses attribute.
|
||||
// We attempt to guard here against bogus combinations of modifiers.
|
||||
if ((mods & M_PRIVATE) != 0) {
|
||||
// Private cannot be combined with public or protected.
|
||||
mods &= ~(M_PUBLIC | M_PROTECTED);
|
||||
} else if ((mods & M_PROTECTED) != 0) {
|
||||
// Protected cannot be combined with public.
|
||||
mods &= ~M_PUBLIC;
|
||||
}
|
||||
if ((mods & M_INTERFACE) != 0) {
|
||||
// All interfaces are implicitly abstract.
|
||||
// All interfaces that are members of a type are implicitly static.
|
||||
mods |= (M_ABSTRACT | M_STATIC);
|
||||
}
|
||||
if (outerClass.isInterface()) {
|
||||
// All types that are members of interfaces are implicitly
|
||||
// public and static.
|
||||
mods |= (M_PUBLIC | M_STATIC);
|
||||
mods &= ~(M_PRIVATE | M_PROTECTED);
|
||||
}
|
||||
modifiers = mods;
|
||||
|
||||
setOuterClass(outerClass);
|
||||
|
||||
for (MemberDefinition field = getFirstMember();
|
||||
field != null;
|
||||
field = field.getNextMember()) {
|
||||
if (field.isUplevelValue()
|
||||
&& outerClass.getType().equals(field.getType())
|
||||
&& field.getName().toString().startsWith(prefixThis)) {
|
||||
setOuterMember(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initOuter(ClassDefinition innerClass, int mods) {
|
||||
if (innerClass instanceof BinaryClass)
|
||||
((BinaryClass)innerClass).initInner(this, mods);
|
||||
addMember(new BinaryMember(innerClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the class out to a given stream. This function mirrors the loader.
|
||||
*/
|
||||
public void write(Environment env, OutputStream out) throws IOException {
|
||||
DataOutputStream data = new DataOutputStream(out);
|
||||
|
||||
// write out the header
|
||||
data.writeInt(JAVA_MAGIC);
|
||||
data.writeShort(env.getMinorVersion());
|
||||
data.writeShort(env.getMajorVersion());
|
||||
|
||||
// Write out the constant pool
|
||||
cpool.write(data, env);
|
||||
|
||||
// Write class information
|
||||
data.writeShort(getModifiers() & ACCM_CLASS);
|
||||
data.writeShort(cpool.indexObject(getClassDeclaration(), env));
|
||||
data.writeShort((getSuperClass() != null)
|
||||
? cpool.indexObject(getSuperClass(), env) : 0);
|
||||
data.writeShort(interfaces.length);
|
||||
for (int i = 0 ; i < interfaces.length ; i++) {
|
||||
data.writeShort(cpool.indexObject(interfaces[i], env));
|
||||
}
|
||||
|
||||
// count the fields and the methods
|
||||
int fieldCount = 0, methodCount = 0;
|
||||
for (MemberDefinition f = firstMember; f != null; f = f.getNextMember())
|
||||
if (f.isMethod()) methodCount++; else fieldCount++;
|
||||
|
||||
// write out each the field count, and then each field
|
||||
data.writeShort(fieldCount);
|
||||
for (MemberDefinition f = firstMember; f != null; f = f.getNextMember()) {
|
||||
if (!f.isMethod()) {
|
||||
data.writeShort(f.getModifiers() & ACCM_FIELD);
|
||||
String name = f.getName().toString();
|
||||
String signature = f.getType().getTypeSignature();
|
||||
data.writeShort(cpool.indexString(name, env));
|
||||
data.writeShort(cpool.indexString(signature, env));
|
||||
BinaryAttribute.write(((BinaryMember)f).atts, data, cpool, env);
|
||||
}
|
||||
}
|
||||
|
||||
// write out each method count, and then each method
|
||||
data.writeShort(methodCount);
|
||||
for (MemberDefinition f = firstMember; f != null; f = f.getNextMember()) {
|
||||
if (f.isMethod()) {
|
||||
data.writeShort(f.getModifiers() & ACCM_METHOD);
|
||||
String name = f.getName().toString();
|
||||
String signature = f.getType().getTypeSignature();
|
||||
data.writeShort(cpool.indexString(name, env));
|
||||
data.writeShort(cpool.indexString(signature, env));
|
||||
BinaryAttribute.write(((BinaryMember)f).atts, data, cpool, env);
|
||||
}
|
||||
}
|
||||
|
||||
// write out the class attributes
|
||||
BinaryAttribute.write(atts, data, cpool, env);
|
||||
data.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dependencies
|
||||
*/
|
||||
public Enumeration getDependencies() {
|
||||
return dependencies.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a dependency
|
||||
*/
|
||||
public void addDependency(ClassDeclaration c) {
|
||||
if ((c != null) && !dependencies.contains(c)) {
|
||||
dependencies.addElement(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the constant pool
|
||||
*/
|
||||
public BinaryConstantPool getConstants() {
|
||||
return cpool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a class attribute
|
||||
*/
|
||||
public byte getAttribute(Identifier name)[] {
|
||||
for (BinaryAttribute att = atts ; att != null ; att = att.next) {
|
||||
if (att.name.equals(name)) {
|
||||
return att.data;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
111
jdkSrc/jdk8/sun/tools/java/BinaryCode.java
Normal file
111
jdkSrc/jdk8/sun/tools/java/BinaryCode.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public class BinaryCode implements Constants {
|
||||
int maxStack; // maximum stack used by code
|
||||
int maxLocals; // maximum locals used by code
|
||||
BinaryExceptionHandler exceptionHandlers[];
|
||||
BinaryAttribute atts; // code attributes
|
||||
BinaryConstantPool cpool; // constant pool of the class
|
||||
byte code[]; // the byte code
|
||||
|
||||
/**
|
||||
* Construct the binary code from the code attribute
|
||||
*/
|
||||
|
||||
public
|
||||
BinaryCode(byte data[], BinaryConstantPool cpool, Environment env) {
|
||||
DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
|
||||
try {
|
||||
this.cpool = cpool;
|
||||
// JVM 4.7.4 CodeAttribute.max_stack
|
||||
this.maxStack = in.readUnsignedShort();
|
||||
// JVM 4.7.4 CodeAttribute.max_locals
|
||||
this.maxLocals = in.readUnsignedShort();
|
||||
// JVM 4.7.4 CodeAttribute.code_length
|
||||
int code_length = in.readInt();
|
||||
this.code = new byte[code_length];
|
||||
// JVM 4.7.4 CodeAttribute.code[]
|
||||
in.read(this.code);
|
||||
// JVM 4.7.4 CodeAttribute.exception_table_length
|
||||
int exception_count = in.readUnsignedShort();
|
||||
this.exceptionHandlers = new BinaryExceptionHandler[exception_count];
|
||||
for (int i = 0; i < exception_count; i++) {
|
||||
// JVM 4.7.4 CodeAttribute.exception_table.start_pc
|
||||
int start = in.readUnsignedShort();
|
||||
// JVM 4.7.4 CodeAttribute.exception_table.end_pc
|
||||
int end = in.readUnsignedShort();
|
||||
// JVM 4.7.4 CodeAttribute.exception_table.handler_pc
|
||||
int handler = in.readUnsignedShort();
|
||||
// JVM 4.7.4 CodeAttribute.exception_table.catch_type
|
||||
ClassDeclaration xclass = cpool.getDeclaration(env, in.readUnsignedShort());
|
||||
this.exceptionHandlers[i] =
|
||||
new BinaryExceptionHandler(start, end, handler, xclass);
|
||||
}
|
||||
this.atts = BinaryAttribute.load(in, cpool, ~0);
|
||||
if (in.available() != 0) {
|
||||
System.err.println("Should have exhausted input stream!");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CompilerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
|
||||
public BinaryExceptionHandler getExceptionHandlers()[] {
|
||||
return exceptionHandlers;
|
||||
}
|
||||
|
||||
public byte getCode()[] { return code; }
|
||||
|
||||
public int getMaxStack() { return maxStack; }
|
||||
|
||||
public int getMaxLocals() { return maxLocals; }
|
||||
|
||||
public BinaryAttribute getAttributes() { return atts; }
|
||||
|
||||
/**
|
||||
* Load a binary class
|
||||
*/
|
||||
public static
|
||||
BinaryCode load(BinaryMember bf, BinaryConstantPool cpool, Environment env) {
|
||||
byte code[] = bf.getAttribute(idCode);
|
||||
return (code != null) ? new BinaryCode(code, cpool, env) : null;
|
||||
}
|
||||
}
|
||||
351
jdkSrc/jdk8/sun/tools/java/BinaryConstantPool.java
Normal file
351
jdkSrc/jdk8/sun/tools/java/BinaryConstantPool.java
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* This class is used to represent a constant table once
|
||||
* it is read from a class file.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class BinaryConstantPool implements Constants {
|
||||
private byte types[];
|
||||
private Object cpool[];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
BinaryConstantPool(DataInputStream in) throws IOException {
|
||||
// JVM 4.1 ClassFile.constant_pool_count
|
||||
types = new byte[in.readUnsignedShort()];
|
||||
cpool = new Object[types.length];
|
||||
for (int i = 1 ; i < cpool.length ; i++) {
|
||||
int j = i;
|
||||
// JVM 4.4 cp_info.tag
|
||||
switch(types[i] = in.readByte()) {
|
||||
case CONSTANT_UTF8:
|
||||
cpool[i] = in.readUTF();
|
||||
break;
|
||||
|
||||
case CONSTANT_INTEGER:
|
||||
cpool[i] = new Integer(in.readInt());
|
||||
break;
|
||||
case CONSTANT_FLOAT:
|
||||
cpool[i] = new Float(in.readFloat());
|
||||
break;
|
||||
case CONSTANT_LONG:
|
||||
cpool[i++] = new Long(in.readLong());
|
||||
break;
|
||||
case CONSTANT_DOUBLE:
|
||||
cpool[i++] = new Double(in.readDouble());
|
||||
break;
|
||||
|
||||
case CONSTANT_CLASS:
|
||||
case CONSTANT_STRING:
|
||||
// JVM 4.4.3 CONSTANT_String_info.string_index
|
||||
// or JVM 4.4.1 CONSTANT_Class_info.name_index
|
||||
cpool[i] = new Integer(in.readUnsignedShort());
|
||||
break;
|
||||
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
case CONSTANT_NAMEANDTYPE:
|
||||
// JVM 4.4.2 CONSTANT_*ref_info.class_index & name_and_type_index
|
||||
cpool[i] = new Integer((in.readUnsignedShort() << 16) | in.readUnsignedShort());
|
||||
break;
|
||||
|
||||
case CONSTANT_METHODHANDLE:
|
||||
cpool[i] = readBytes(in, 3);
|
||||
break;
|
||||
case CONSTANT_METHODTYPE:
|
||||
cpool[i] = readBytes(in, 2);
|
||||
break;
|
||||
case CONSTANT_INVOKEDYNAMIC:
|
||||
cpool[i] = readBytes(in, 4);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
throw new ClassFormatError("invalid constant type: " + (int)types[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] readBytes(DataInputStream in, int cnt) throws IOException {
|
||||
byte[] b = new byte[cnt];
|
||||
in.readFully(b);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a integer
|
||||
*/
|
||||
public int getInteger(int n) {
|
||||
return (n == 0) ? 0 : ((Number)cpool[n]).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* get a value
|
||||
*/
|
||||
public Object getValue(int n) {
|
||||
return (n == 0) ? null : cpool[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* get a string
|
||||
*/
|
||||
public String getString(int n) {
|
||||
return (n == 0) ? null : (String)cpool[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* get an identifier
|
||||
*/
|
||||
public Identifier getIdentifier(int n) {
|
||||
return (n == 0) ? null : Identifier.lookup(getString(n));
|
||||
}
|
||||
|
||||
/**
|
||||
* get class declaration
|
||||
*/
|
||||
public ClassDeclaration getDeclarationFromName(Environment env, int n) {
|
||||
return (n == 0) ? null : env.getClassDeclaration(Identifier.lookup(getString(n).replace('/','.')));
|
||||
}
|
||||
|
||||
/**
|
||||
* get class declaration
|
||||
*/
|
||||
public ClassDeclaration getDeclaration(Environment env, int n) {
|
||||
return (n == 0) ? null : getDeclarationFromName(env, getInteger(n));
|
||||
}
|
||||
|
||||
/**
|
||||
* get a type from a type signature
|
||||
*/
|
||||
public Type getType(int n) {
|
||||
return Type.tType(getString(n));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the type of constant given an index
|
||||
*/
|
||||
public int getConstantType(int n) {
|
||||
return types[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* get the n-th constant from the constant pool
|
||||
*/
|
||||
public Object getConstant(int n, Environment env) {
|
||||
int constant_type = getConstantType(n);
|
||||
switch (constant_type) {
|
||||
case CONSTANT_INTEGER:
|
||||
case CONSTANT_FLOAT:
|
||||
case CONSTANT_LONG:
|
||||
case CONSTANT_DOUBLE:
|
||||
case CONSTANT_METHODHANDLE:
|
||||
case CONSTANT_METHODTYPE:
|
||||
case CONSTANT_INVOKEDYNAMIC:
|
||||
return getValue(n);
|
||||
|
||||
case CONSTANT_CLASS:
|
||||
return getDeclaration(env, n);
|
||||
|
||||
case CONSTANT_STRING:
|
||||
return getString(getInteger(n));
|
||||
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
try {
|
||||
int key = getInteger(n);
|
||||
ClassDefinition clazz =
|
||||
getDeclaration(env, key >> 16).getClassDefinition(env);
|
||||
int name_and_type = getInteger(key & 0xFFFF);
|
||||
Identifier id = getIdentifier(name_and_type >> 16);
|
||||
Type type = getType(name_and_type & 0xFFFF);
|
||||
|
||||
for (MemberDefinition field = clazz.getFirstMatch(id);
|
||||
field != null;
|
||||
field = field.getNextMatch()) {
|
||||
Type field_type = field.getType();
|
||||
if ((constant_type == CONSTANT_FIELD)
|
||||
? (field_type == type)
|
||||
: (field_type.equalArguments(type)))
|
||||
return field;
|
||||
}
|
||||
} catch (ClassNotFound e) {
|
||||
}
|
||||
return null;
|
||||
|
||||
default:
|
||||
throw new ClassFormatError("invalid constant type: " +
|
||||
constant_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of dependencies, ie: all the classes referenced in this
|
||||
* constant pool.
|
||||
*/
|
||||
public Vector getDependencies(Environment env) {
|
||||
Vector v = new Vector();
|
||||
for (int i = 1 ; i < cpool.length ; i++) {
|
||||
switch(types[i]) {
|
||||
case CONSTANT_CLASS:
|
||||
v.addElement(getDeclarationFromName(env, getInteger(i)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
Hashtable indexHashObject, indexHashAscii;
|
||||
Vector MoreStuff;
|
||||
|
||||
/**
|
||||
* Find the index of an Object in the constant pool
|
||||
*/
|
||||
public int indexObject(Object obj, Environment env) {
|
||||
if (indexHashObject == null)
|
||||
createIndexHash(env);
|
||||
Integer result = (Integer)indexHashObject.get(obj);
|
||||
if (result == null)
|
||||
throw new IndexOutOfBoundsException("Cannot find object " + obj + " of type " +
|
||||
obj.getClass() + " in constant pool");
|
||||
return result.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of an ascii string in the constant pool. If it's not in
|
||||
* the constant pool, then add it at the end.
|
||||
*/
|
||||
public int indexString(String string, Environment env) {
|
||||
if (indexHashObject == null)
|
||||
createIndexHash(env);
|
||||
Integer result = (Integer)indexHashAscii.get(string);
|
||||
if (result == null) {
|
||||
if (MoreStuff == null) MoreStuff = new Vector();
|
||||
result = new Integer(cpool.length + MoreStuff.size());
|
||||
MoreStuff.addElement(string);
|
||||
indexHashAscii.put(string, result);
|
||||
}
|
||||
return result.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hash table of all the items in the constant pool that could
|
||||
* possibly be referenced from the outside.
|
||||
*/
|
||||
|
||||
public void createIndexHash(Environment env) {
|
||||
indexHashObject = new Hashtable();
|
||||
indexHashAscii = new Hashtable();
|
||||
for (int i = 1; i < cpool.length; i++) {
|
||||
if (types[i] == CONSTANT_UTF8) {
|
||||
indexHashAscii.put(cpool[i], new Integer(i));
|
||||
} else {
|
||||
try {
|
||||
indexHashObject.put(getConstant(i, env), new Integer(i));
|
||||
} catch (ClassFormatError e) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write out the contents of the constant pool, including any additions
|
||||
* that have been added.
|
||||
*/
|
||||
public void write(DataOutputStream out, Environment env) throws IOException {
|
||||
int length = cpool.length;
|
||||
if (MoreStuff != null)
|
||||
length += MoreStuff.size();
|
||||
out.writeShort(length);
|
||||
for (int i = 1 ; i < cpool.length; i++) {
|
||||
int type = types[i];
|
||||
Object x = cpool[i];
|
||||
out.writeByte(type);
|
||||
switch (type) {
|
||||
case CONSTANT_UTF8:
|
||||
out.writeUTF((String) x);
|
||||
break;
|
||||
case CONSTANT_INTEGER:
|
||||
out.writeInt(((Number)x).intValue());
|
||||
break;
|
||||
case CONSTANT_FLOAT:
|
||||
out.writeFloat(((Number)x).floatValue());
|
||||
break;
|
||||
case CONSTANT_LONG:
|
||||
out.writeLong(((Number)x).longValue());
|
||||
i++;
|
||||
break;
|
||||
case CONSTANT_DOUBLE:
|
||||
out.writeDouble(((Number)x).doubleValue());
|
||||
i++;
|
||||
break;
|
||||
case CONSTANT_CLASS:
|
||||
case CONSTANT_STRING:
|
||||
out.writeShort(((Number)x).intValue());
|
||||
break;
|
||||
case CONSTANT_FIELD:
|
||||
case CONSTANT_METHOD:
|
||||
case CONSTANT_INTERFACEMETHOD:
|
||||
case CONSTANT_NAMEANDTYPE: {
|
||||
int value = ((Number)x).intValue();
|
||||
out.writeShort(value >> 16);
|
||||
out.writeShort(value & 0xFFFF);
|
||||
break;
|
||||
}
|
||||
case CONSTANT_METHODHANDLE:
|
||||
case CONSTANT_METHODTYPE:
|
||||
case CONSTANT_INVOKEDYNAMIC:
|
||||
out.write((byte[])x, 0, ((byte[])x).length);
|
||||
break;
|
||||
default:
|
||||
throw new ClassFormatError("invalid constant type: "
|
||||
+ (int)types[i]);
|
||||
}
|
||||
}
|
||||
for (int i = cpool.length; i < length; i++) {
|
||||
String string = (String)(MoreStuff.elementAt(i - cpool.length));
|
||||
out.writeByte(CONSTANT_UTF8);
|
||||
out.writeUTF(string);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
49
jdkSrc/jdk8/sun/tools/java/BinaryExceptionHandler.java
Normal file
49
jdkSrc/jdk8/sun/tools/java/BinaryExceptionHandler.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* A single exception handler. This class hangs off BinaryCode.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
public class BinaryExceptionHandler {
|
||||
public int startPC;
|
||||
public int endPC;
|
||||
public int handlerPC;
|
||||
public ClassDeclaration exceptionClass;
|
||||
|
||||
BinaryExceptionHandler(int start, int end,
|
||||
int handler, ClassDeclaration xclass) {
|
||||
startPC = start;
|
||||
endPC = end;
|
||||
handlerPC = handler;
|
||||
exceptionClass = xclass;
|
||||
}
|
||||
}
|
||||
260
jdkSrc/jdk8/sun/tools/java/BinaryMember.java
Normal file
260
jdkSrc/jdk8/sun/tools/java/BinaryMember.java
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import sun.tools.tree.*;
|
||||
import java.util.Vector;
|
||||
import java.util.Hashtable;
|
||||
import java.io.IOException;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
/**
|
||||
* This class represents a binary member
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public final
|
||||
class BinaryMember extends MemberDefinition {
|
||||
Expression value;
|
||||
BinaryAttribute atts;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public BinaryMember(ClassDefinition clazz, int modifiers, Type type,
|
||||
Identifier name, BinaryAttribute atts) {
|
||||
super(0, clazz, modifiers, type, name, null, null);
|
||||
this.atts = atts;
|
||||
|
||||
// Was it compiled as deprecated?
|
||||
if (getAttribute(idDeprecated) != null) {
|
||||
this.modifiers |= M_DEPRECATED;
|
||||
}
|
||||
|
||||
// Was it synthesized by the compiler?
|
||||
if (getAttribute(idSynthetic) != null) {
|
||||
this.modifiers |= M_SYNTHETIC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for an inner class.
|
||||
*/
|
||||
public BinaryMember(ClassDefinition innerClass) {
|
||||
super(innerClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline allowed (currently only allowed for the constructor of Object).
|
||||
*/
|
||||
public boolean isInlineable(Environment env, boolean fromFinal) {
|
||||
// It is possible for 'getSuperClass()' to return null due to error
|
||||
// recovery from cyclic inheritace. Can this cause a problem here?
|
||||
return isConstructor() && (getClassDefinition().getSuperClass() == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get arguments
|
||||
*/
|
||||
public Vector getArguments() {
|
||||
if (isConstructor() && (getClassDefinition().getSuperClass() == null)) {
|
||||
Vector v = new Vector();
|
||||
v.addElement(new LocalMember(0, getClassDefinition(), 0,
|
||||
getClassDefinition().getType(), idThis));
|
||||
return v;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get exceptions
|
||||
*/
|
||||
public ClassDeclaration[] getExceptions(Environment env) {
|
||||
if ((!isMethod()) || (exp != null)) {
|
||||
return exp;
|
||||
}
|
||||
byte data[] = getAttribute(idExceptions);
|
||||
if (data == null) {
|
||||
return new ClassDeclaration[0];
|
||||
}
|
||||
|
||||
try {
|
||||
BinaryConstantPool cpool = ((BinaryClass)getClassDefinition()).getConstants();
|
||||
DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
|
||||
// JVM 4.7.5 Exceptions_attribute.number_of_exceptions
|
||||
int n = in.readUnsignedShort();
|
||||
exp = new ClassDeclaration[n];
|
||||
for (int i = 0 ; i < n ; i++) {
|
||||
// JVM 4.7.5 Exceptions_attribute.exception_index_table[]
|
||||
exp[i] = cpool.getDeclaration(env, in.readUnsignedShort());
|
||||
}
|
||||
return exp;
|
||||
} catch (IOException e) {
|
||||
throw new CompilerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documentation
|
||||
*/
|
||||
public String getDocumentation() {
|
||||
if (documentation != null) {
|
||||
return documentation;
|
||||
}
|
||||
byte data[] = getAttribute(idDocumentation);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return documentation = new DataInputStream(new ByteArrayInputStream(data)).readUTF();
|
||||
} catch (IOException e) {
|
||||
throw new CompilerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if constant: Will it inline away to a constant?
|
||||
* This override is needed to solve bug 4128266. It is also
|
||||
* integral to the solution of 4119776.
|
||||
*/
|
||||
private boolean isConstantCache = false;
|
||||
private boolean isConstantCached = false;
|
||||
public boolean isConstant() {
|
||||
if (!isConstantCached) {
|
||||
isConstantCache = isFinal()
|
||||
&& isVariable()
|
||||
&& getAttribute(idConstantValue) != null;
|
||||
isConstantCached = true;
|
||||
}
|
||||
return isConstantCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value
|
||||
*/
|
||||
public Node getValue(Environment env) {
|
||||
if (isMethod()) {
|
||||
return null;
|
||||
}
|
||||
if (!isFinal()) {
|
||||
return null;
|
||||
}
|
||||
if (getValue() != null) {
|
||||
return (Expression)getValue();
|
||||
}
|
||||
byte data[] = getAttribute(idConstantValue);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
BinaryConstantPool cpool = ((BinaryClass)getClassDefinition()).getConstants();
|
||||
// JVM 4.7.3 ConstantValue.constantvalue_index
|
||||
Object obj = cpool.getValue(new DataInputStream(new ByteArrayInputStream(data)).readUnsignedShort());
|
||||
switch (getType().getTypeCode()) {
|
||||
case TC_BOOLEAN:
|
||||
setValue(new BooleanExpression(0, ((Number)obj).intValue() != 0));
|
||||
break;
|
||||
case TC_BYTE:
|
||||
case TC_SHORT:
|
||||
case TC_CHAR:
|
||||
case TC_INT:
|
||||
setValue(new IntExpression(0, ((Number)obj).intValue()));
|
||||
break;
|
||||
case TC_LONG:
|
||||
setValue(new LongExpression(0, ((Number)obj).longValue()));
|
||||
break;
|
||||
case TC_FLOAT:
|
||||
setValue(new FloatExpression(0, ((Number)obj).floatValue()));
|
||||
break;
|
||||
case TC_DOUBLE:
|
||||
setValue(new DoubleExpression(0, ((Number)obj).doubleValue()));
|
||||
break;
|
||||
case TC_CLASS:
|
||||
setValue(new StringExpression(0, (String)cpool.getValue(((Number)obj).intValue())));
|
||||
break;
|
||||
}
|
||||
return (Expression)getValue();
|
||||
} catch (IOException e) {
|
||||
throw new CompilerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field attribute
|
||||
*/
|
||||
public byte[] getAttribute(Identifier name) {
|
||||
for (BinaryAttribute att = atts ; att != null ; att = att.next) {
|
||||
if (att.name.equals(name)) {
|
||||
return att.data;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean deleteAttribute(Identifier name) {
|
||||
BinaryAttribute walker = null, next = null;
|
||||
|
||||
boolean succeed = false;
|
||||
|
||||
while (atts.name.equals(name)) {
|
||||
atts = atts.next;
|
||||
succeed = true;
|
||||
}
|
||||
for (walker = atts; walker != null; walker = next) {
|
||||
next = walker.next;
|
||||
if (next != null) {
|
||||
if (next.name.equals(name)) {
|
||||
walker.next = next.next;
|
||||
next = next.next;
|
||||
succeed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (walker = atts; walker != null; walker = walker.next) {
|
||||
if (walker.name.equals(name)) {
|
||||
throw new InternalError("Found attribute " + name);
|
||||
}
|
||||
}
|
||||
|
||||
return succeed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Add an attribute to a field
|
||||
*/
|
||||
public void addAttribute(Identifier name, byte data[], Environment env) {
|
||||
this.atts = new BinaryAttribute(name, data, this.atts);
|
||||
// Make sure that the new attribute is in the constant pool
|
||||
((BinaryClass)(this.clazz)).cpool.indexString(name.toString(), env);
|
||||
}
|
||||
|
||||
}
|
||||
270
jdkSrc/jdk8/sun/tools/java/ClassDeclaration.java
Normal file
270
jdkSrc/jdk8/sun/tools/java/ClassDeclaration.java
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This class represents an Java class declaration. It refers
|
||||
* to either a binary or source definition.
|
||||
*
|
||||
* ClassDefinitions are loaded on demand, this means that
|
||||
* class declarations are late bound. The definition of the
|
||||
* class is obtained in stages. The status field describes
|
||||
* the state of the class definition:
|
||||
*
|
||||
* CS_UNDEFINED - the definition is not yet loaded
|
||||
* CS_UNDECIDED - a binary definition is loaded, but it is
|
||||
* still unclear if the source definition need to
|
||||
* be loaded
|
||||
* CS_BINARY - the binary class is loaded
|
||||
* CS_PARSED - the class is loaded from the source file, the
|
||||
* type information is available, but the class has
|
||||
* not yet been compiled.
|
||||
* CS_CHECKED - the class is loaded from the source file and has
|
||||
* been type-checked.
|
||||
* CS_COMPILED - the class has been type checked, compiled,
|
||||
* and written out.
|
||||
* CS_NOTFOUND - no class definition could be found
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
public final
|
||||
class ClassDeclaration implements Constants {
|
||||
int status;
|
||||
Type type;
|
||||
ClassDefinition definition;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ClassDeclaration(Identifier name) {
|
||||
this.type = Type.tClass(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status of the class
|
||||
*/
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the class
|
||||
*/
|
||||
public Identifier getName() {
|
||||
return type.getClassName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the class
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the class is defined
|
||||
*/
|
||||
public boolean isDefined() {
|
||||
switch (status) {
|
||||
case CS_BINARY:
|
||||
case CS_PARSED:
|
||||
case CS_CHECKED:
|
||||
case CS_COMPILED:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the definition of this class. Returns null if
|
||||
* the class is not yet defined.
|
||||
*/
|
||||
public ClassDefinition getClassDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a flag for use by getClassDefinition(env). It is
|
||||
* used to mark that a class has been successfully looked up
|
||||
* by that method before.
|
||||
*/
|
||||
private boolean found = false;
|
||||
|
||||
/**
|
||||
* Get the definition of this class, if the class is not
|
||||
* yet defined, load the definition. Loading a class may
|
||||
* throw various exceptions.
|
||||
*/
|
||||
public ClassDefinition getClassDefinition(Environment env)
|
||||
throws ClassNotFound {
|
||||
if (tracing) env.dtEvent("getClassDefinition: " +
|
||||
getName() + ", status " + getStatus());
|
||||
|
||||
// The majority of calls to getClassDefinition() are duplicates.
|
||||
// This check makes them fast. It also allows us to avoid
|
||||
// duplicate, useless calls to basicCheck(). In the future it
|
||||
// would be good to add an additional status value, CS_BASICCHECKED.
|
||||
if (found) {
|
||||
return definition;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
switch (status) {
|
||||
case CS_UNDEFINED:
|
||||
case CS_UNDECIDED:
|
||||
case CS_SOURCE:
|
||||
env.loadDefinition(this);
|
||||
break;
|
||||
|
||||
case CS_BINARY:
|
||||
case CS_PARSED:
|
||||
//+FIX FOR BUGID 4056065
|
||||
//definition.basicCheck(env);
|
||||
if (!definition.isInsideLocal()) {
|
||||
// Classes inside a block, including anonymous classes,
|
||||
// are checked when their surrounding member is checked.
|
||||
definition.basicCheck(env);
|
||||
}
|
||||
//-FIX FOR BUGID 4056065
|
||||
found = true;
|
||||
return definition;
|
||||
|
||||
case CS_CHECKED:
|
||||
case CS_COMPILED:
|
||||
found = true;
|
||||
return definition;
|
||||
|
||||
default:
|
||||
throw new ClassNotFound(getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the definition of this class, if the class is not
|
||||
* yet defined, load the definition. Loading a class may
|
||||
* throw various exceptions. Perform no basicCheck() on this
|
||||
* class.
|
||||
*/
|
||||
public ClassDefinition getClassDefinitionNoCheck(Environment env) throws ClassNotFound {
|
||||
if (tracing) env.dtEvent("getClassDefinition: " +
|
||||
getName() + ", status " + getStatus());
|
||||
for(;;) {
|
||||
switch (status) {
|
||||
case CS_UNDEFINED:
|
||||
case CS_UNDECIDED:
|
||||
case CS_SOURCE:
|
||||
env.loadDefinition(this);
|
||||
break;
|
||||
|
||||
case CS_BINARY:
|
||||
case CS_PARSED:
|
||||
case CS_CHECKED:
|
||||
case CS_COMPILED:
|
||||
return definition;
|
||||
|
||||
default:
|
||||
throw new ClassNotFound(getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class definition
|
||||
*/
|
||||
public void setDefinition(ClassDefinition definition, int status) {
|
||||
|
||||
// Sanity checks.
|
||||
|
||||
// The name of the definition should match that of the declaration.
|
||||
if ((definition != null) && !getName().equals(definition.getName())) {
|
||||
throw new CompilerError("setDefinition: name mismatch: " +
|
||||
this + ", " + definition);
|
||||
}
|
||||
|
||||
// The status states can be considered ordered in the same
|
||||
// manner as their numerical values. We expect classes to
|
||||
// progress through a sequence of monotonically increasing
|
||||
// states. NOTE: There are currently exceptions to this rule
|
||||
// which are believed to be legitimate. In particular, a
|
||||
// class may be checked more than once, though we believe that
|
||||
// this is unnecessary and may be avoided.
|
||||
/*-----------------*
|
||||
if (status <= this.status) {
|
||||
System.out.println("STATUS REGRESSION: " +
|
||||
this + " FROM " + this.status + " TO " + status);
|
||||
}
|
||||
*------------------*/
|
||||
|
||||
this.definition = definition;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equality
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ClassDeclaration) {
|
||||
return type.equals(((ClassDeclaration)obj).type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return type.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* toString
|
||||
*/
|
||||
public String toString() {
|
||||
String name = getName().toString();
|
||||
String type = "type ";
|
||||
String nested = getName().isInner() ? "nested " : "";
|
||||
if (getClassDefinition() != null) {
|
||||
if (getClassDefinition().isInterface()) {
|
||||
type = "interface ";
|
||||
} else {
|
||||
type = "class ";
|
||||
}
|
||||
if (!getClassDefinition().isTopLevel()) {
|
||||
nested = "inner ";
|
||||
if (getClassDefinition().isLocal()) {
|
||||
nested = "local ";
|
||||
if (!getClassDefinition().isAnonymous()) {
|
||||
name = getClassDefinition().getLocalName() +
|
||||
" (" + name + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nested + type + name;
|
||||
}
|
||||
}
|
||||
2085
jdkSrc/jdk8/sun/tools/java/ClassDefinition.java
Normal file
2085
jdkSrc/jdk8/sun/tools/java/ClassDefinition.java
Normal file
File diff suppressed because it is too large
Load Diff
162
jdkSrc/jdk8/sun/tools/java/ClassFile.java
Normal file
162
jdkSrc/jdk8/sun/tools/java/ClassFile.java
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.*;
|
||||
|
||||
/**
|
||||
* This class is used to represent a file loaded from the class path, and
|
||||
* can either be a regular file or a zip file entry.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public
|
||||
class ClassFile {
|
||||
/*
|
||||
* Non-null if this represents a regular file
|
||||
*/
|
||||
private File file;
|
||||
|
||||
/*
|
||||
* Non-null if this represents a zip file entry
|
||||
*/
|
||||
private ZipFile zipFile;
|
||||
private ZipEntry zipEntry;
|
||||
|
||||
/**
|
||||
* Constructor for instance representing a regular file
|
||||
*/
|
||||
public ClassFile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for instance representing a zip file entry
|
||||
*/
|
||||
public ClassFile(ZipFile zf, ZipEntry ze) {
|
||||
this.zipFile = zf;
|
||||
this.zipEntry = ze;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is zip file entry
|
||||
*/
|
||||
public boolean isZipped() {
|
||||
return zipFile != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns input stream to either regular file or zip file entry
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException {
|
||||
if (file != null) {
|
||||
return new FileInputStream(file);
|
||||
} else {
|
||||
try {
|
||||
return zipFile.getInputStream(zipEntry);
|
||||
} catch (ZipException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if file exists.
|
||||
*/
|
||||
public boolean exists() {
|
||||
return file != null ? file.exists() : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a directory.
|
||||
*/
|
||||
public boolean isDirectory() {
|
||||
return file != null ? file.isDirectory() :
|
||||
zipEntry.getName().endsWith("/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return last modification time
|
||||
*/
|
||||
public long lastModified() {
|
||||
return file != null ? file.lastModified() : zipEntry.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file path. The path for a zip file entry will also include
|
||||
* the zip file name.
|
||||
*/
|
||||
public String getPath() {
|
||||
if (file != null) {
|
||||
return file.getPath();
|
||||
} else {
|
||||
return zipFile.getName() + "(" + zipEntry.getName() + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of file entry excluding directory name
|
||||
*/
|
||||
public String getName() {
|
||||
return file != null ? file.getName() : zipEntry.getName();
|
||||
}
|
||||
|
||||
//JCOV
|
||||
/**
|
||||
* Get absolute name of file entry
|
||||
*/
|
||||
public String getAbsoluteName() {
|
||||
String absoluteName;
|
||||
if (file != null) {
|
||||
try {
|
||||
absoluteName = file.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
absoluteName = file.getAbsolutePath();
|
||||
}
|
||||
} else {
|
||||
absoluteName = zipFile.getName() + "(" + zipEntry.getName() + ")";
|
||||
}
|
||||
return absoluteName;
|
||||
}
|
||||
// end JCOV
|
||||
|
||||
/**
|
||||
* Get length of file
|
||||
*/
|
||||
public long length() {
|
||||
return file != null ? file.length() : zipEntry.getSize();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return (file != null) ? file.toString() : zipEntry.toString();
|
||||
}
|
||||
}
|
||||
50
jdkSrc/jdk8/sun/tools/java/ClassNotFound.java
Normal file
50
jdkSrc/jdk8/sun/tools/java/ClassNotFound.java
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a class definition is needed
|
||||
* and the class can't be found.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public
|
||||
class ClassNotFound extends Exception {
|
||||
/**
|
||||
* The class that was not found
|
||||
*/
|
||||
public Identifier name;
|
||||
|
||||
/**
|
||||
* Create a ClassNotFound exception
|
||||
*/
|
||||
public ClassNotFound(Identifier nm) {
|
||||
super(nm.toString());
|
||||
name = nm;
|
||||
}
|
||||
}
|
||||
314
jdkSrc/jdk8/sun/tools/java/ClassPath.java
Normal file
314
jdkSrc/jdk8/sun/tools/java/ClassPath.java
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.*;
|
||||
|
||||
/**
|
||||
* This class is used to represent a class path, which can contain both
|
||||
* directories and zip files.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public
|
||||
class ClassPath {
|
||||
static final char dirSeparator = File.pathSeparatorChar;
|
||||
|
||||
/**
|
||||
* The original class path string
|
||||
*/
|
||||
String pathstr;
|
||||
|
||||
/**
|
||||
* List of class path entries
|
||||
*/
|
||||
private ClassPathEntry[] path;
|
||||
|
||||
/**
|
||||
* Build a class path from the specified path string
|
||||
*/
|
||||
public ClassPath(String pathstr) {
|
||||
init(pathstr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a class path from the specified array of class path
|
||||
* element strings. This constructor, and the corresponding
|
||||
* "init" method, were added as part of the fix for 6473331, which
|
||||
* adds support for Class-Path manifest entries in JAR files to
|
||||
* rmic. It is conceivable that the value of a Class-Path
|
||||
* manifest entry will contain a path separator, which would cause
|
||||
* incorrect behavior if the expanded path were passed to the
|
||||
* previous constructor as a single path-separator-delimited
|
||||
* string; use of this constructor avoids that problem.
|
||||
*/
|
||||
public ClassPath(String[] patharray) {
|
||||
init(patharray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a default class path from the path strings specified by
|
||||
* the properties sun.boot.class.path and env.class.path, in that
|
||||
* order.
|
||||
*/
|
||||
public ClassPath() {
|
||||
String syscp = System.getProperty("sun.boot.class.path");
|
||||
String envcp = System.getProperty("env.class.path");
|
||||
if (envcp == null) envcp = ".";
|
||||
String cp = syscp + File.pathSeparator + envcp;
|
||||
init(cp);
|
||||
}
|
||||
|
||||
private void init(String pathstr) {
|
||||
int i, j, n;
|
||||
// Save original class path string
|
||||
this.pathstr = pathstr;
|
||||
|
||||
if (pathstr.length() == 0) {
|
||||
this.path = new ClassPathEntry[0];
|
||||
}
|
||||
|
||||
// Count the number of path separators
|
||||
i = n = 0;
|
||||
while ((i = pathstr.indexOf(dirSeparator, i)) != -1) {
|
||||
n++; i++;
|
||||
}
|
||||
// Build the class path
|
||||
ClassPathEntry[] path = new ClassPathEntry[n+1];
|
||||
int len = pathstr.length();
|
||||
for (i = n = 0; i < len; i = j + 1) {
|
||||
if ((j = pathstr.indexOf(dirSeparator, i)) == -1) {
|
||||
j = len;
|
||||
}
|
||||
if (i == j) {
|
||||
path[n] = new ClassPathEntry();
|
||||
path[n++].dir = new File(".");
|
||||
} else {
|
||||
File file = new File(pathstr.substring(i, j));
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
ZipFile zip = new ZipFile(file);
|
||||
path[n] = new ClassPathEntry();
|
||||
path[n++].zip = zip;
|
||||
} catch (ZipException e) {
|
||||
} catch (IOException e) {
|
||||
// Ignore exceptions, at least for now...
|
||||
}
|
||||
} else {
|
||||
path[n] = new ClassPathEntry();
|
||||
path[n++].dir = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Trim class path to exact size
|
||||
this.path = new ClassPathEntry[n];
|
||||
System.arraycopy((Object)path, 0, (Object)this.path, 0, n);
|
||||
}
|
||||
|
||||
private void init(String[] patharray) {
|
||||
// Save original class path string
|
||||
if (patharray.length == 0) {
|
||||
this.pathstr = "";
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder(patharray[0]);
|
||||
for (int i = 1; i < patharray.length; i++) {
|
||||
sb.append(File.pathSeparatorChar);
|
||||
sb.append(patharray[i]);
|
||||
}
|
||||
this.pathstr = sb.toString();
|
||||
}
|
||||
|
||||
// Build the class path
|
||||
ClassPathEntry[] path = new ClassPathEntry[patharray.length];
|
||||
int n = 0;
|
||||
for (String name : patharray) {
|
||||
File file = new File(name);
|
||||
if (file.isFile()) {
|
||||
try {
|
||||
ZipFile zip = new ZipFile(file);
|
||||
path[n] = new ClassPathEntry();
|
||||
path[n++].zip = zip;
|
||||
} catch (ZipException e) {
|
||||
} catch (IOException e) {
|
||||
// Ignore exceptions, at least for now...
|
||||
}
|
||||
} else {
|
||||
path[n] = new ClassPathEntry();
|
||||
path[n++].dir = file;
|
||||
}
|
||||
}
|
||||
// Trim class path to exact size
|
||||
this.path = new ClassPathEntry[n];
|
||||
System.arraycopy((Object)path, 0, (Object)this.path, 0, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the specified directory in the class path
|
||||
*/
|
||||
public ClassFile getDirectory(String name) {
|
||||
return getFile(name, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the specified file from the class path
|
||||
*/
|
||||
public ClassFile getFile(String name) {
|
||||
return getFile(name, false);
|
||||
}
|
||||
|
||||
private final String fileSeparatorChar = "" + File.separatorChar;
|
||||
|
||||
private ClassFile getFile(String name, boolean isDirectory) {
|
||||
String subdir = name;
|
||||
String basename = "";
|
||||
if (!isDirectory) {
|
||||
int i = name.lastIndexOf(File.separatorChar);
|
||||
subdir = name.substring(0, i + 1);
|
||||
basename = name.substring(i + 1);
|
||||
} else if (!subdir.equals("")
|
||||
&& !subdir.endsWith(fileSeparatorChar)) {
|
||||
// zip files are picky about "foo" vs. "foo/".
|
||||
// also, the getFiles caches are keyed with a trailing /
|
||||
subdir = subdir + File.separatorChar;
|
||||
name = subdir; // Note: isDirectory==true & basename==""
|
||||
}
|
||||
for (int i = 0; i < path.length; i++) {
|
||||
if (path[i].zip != null) {
|
||||
String newname = name.replace(File.separatorChar, '/');
|
||||
ZipEntry entry = path[i].zip.getEntry(newname);
|
||||
if (entry != null) {
|
||||
return new ClassFile(path[i].zip, entry);
|
||||
}
|
||||
} else {
|
||||
File file = new File(path[i].dir.getPath(), name);
|
||||
String list[] = path[i].getFiles(subdir);
|
||||
if (isDirectory) {
|
||||
if (list.length > 0) {
|
||||
return new ClassFile(file);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < list.length; j++) {
|
||||
if (basename.equals(list[j])) {
|
||||
// Don't bother checking !file.isDir,
|
||||
// since we only look for names which
|
||||
// cannot already be packages (foo.java, etc).
|
||||
return new ClassFile(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of files given a package name and extension.
|
||||
*/
|
||||
public Enumeration getFiles(String pkg, String ext) {
|
||||
Hashtable files = new Hashtable();
|
||||
for (int i = path.length; --i >= 0; ) {
|
||||
if (path[i].zip != null) {
|
||||
Enumeration e = path[i].zip.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry)e.nextElement();
|
||||
String name = entry.getName();
|
||||
name = name.replace('/', File.separatorChar);
|
||||
if (name.startsWith(pkg) && name.endsWith(ext)) {
|
||||
files.put(name, new ClassFile(path[i].zip, entry));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String[] list = path[i].getFiles(pkg);
|
||||
for (int j = 0; j < list.length; j++) {
|
||||
String name = list[j];
|
||||
if (name.endsWith(ext)) {
|
||||
name = pkg + File.separatorChar + name;
|
||||
File file = new File(path[i].dir.getPath(), name);
|
||||
files.put(name, new ClassFile(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return files.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Release resources.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
for (int i = path.length; --i >= 0; ) {
|
||||
if (path[i].zip != null) {
|
||||
path[i].zip.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns original class path string
|
||||
*/
|
||||
public String toString() {
|
||||
return pathstr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class path entry, which can either be a directory or an open zip file.
|
||||
*/
|
||||
class ClassPathEntry {
|
||||
File dir;
|
||||
ZipFile zip;
|
||||
|
||||
Hashtable subdirs = new Hashtable(29); // cache of sub-directory listings
|
||||
String[] getFiles(String subdir) {
|
||||
String files[] = (String[]) subdirs.get(subdir);
|
||||
if (files == null) {
|
||||
// search the directory, exactly once
|
||||
File sd = new File(dir.getPath(), subdir);
|
||||
if (sd.isDirectory()) {
|
||||
files = sd.list();
|
||||
if (files == null) {
|
||||
// should not happen, but just in case, fail silently
|
||||
files = new String[0];
|
||||
}
|
||||
if (files.length == 0) {
|
||||
String nonEmpty[] = { "" };
|
||||
files = nonEmpty;
|
||||
}
|
||||
} else {
|
||||
files = new String[0];
|
||||
}
|
||||
subdirs.put(subdir, files);
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
}
|
||||
64
jdkSrc/jdk8/sun/tools/java/ClassType.java
Normal file
64
jdkSrc/jdk8/sun/tools/java/ClassType.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This class represents an Java class type.
|
||||
* It overrides the relevant methods in class Type.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public final
|
||||
class ClassType extends Type {
|
||||
/**
|
||||
* The fully qualified class name.
|
||||
*/
|
||||
Identifier className;
|
||||
|
||||
/**
|
||||
* Construct a class type. Use Type.tClass to create
|
||||
* a new class type.
|
||||
*/
|
||||
ClassType(String typeSig, Identifier className) {
|
||||
super(TC_CLASS, typeSig);
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public Identifier getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public String typeString(String id, boolean abbrev, boolean ret) {
|
||||
String s = (abbrev ? getClassName().getFlatName() :
|
||||
Identifier.lookup(getClassName().getQualifier(),
|
||||
getClassName().getFlatName())).toString();
|
||||
return (id.length() > 0) ? s + " " + id : s;
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/sun/tools/java/CompilerError.java
Normal file
62
jdkSrc/jdk8/sun/tools/java/CompilerError.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This exception is thrown when an internal compiler error occurs
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
public
|
||||
class CompilerError extends Error {
|
||||
Throwable e;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public CompilerError(String msg) {
|
||||
super(msg);
|
||||
this.e = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an exception given another exception.
|
||||
*/
|
||||
public CompilerError(Exception e) {
|
||||
super(e.getMessage());
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
public void printStackTrace() {
|
||||
if (e == this)
|
||||
super.printStackTrace();
|
||||
else
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
591
jdkSrc/jdk8/sun/tools/java/Constants.java
Normal file
591
jdkSrc/jdk8/sun/tools/java/Constants.java
Normal file
@@ -0,0 +1,591 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This interface defines constant that are used
|
||||
* throughout the compiler. It inherits from RuntimeConstants,
|
||||
* which is an autogenerated class that contains contstants
|
||||
* defined in the interpreter.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
|
||||
public
|
||||
interface Constants extends RuntimeConstants {
|
||||
|
||||
/*
|
||||
* Enable/disable inclusion of certain debug tracing code in the
|
||||
* compiler. When included, the tracing code may be selectively
|
||||
* enabled at runtime, otherwise we save the space/time overhead.
|
||||
* Should normally be 'false' for a release version.
|
||||
*/
|
||||
public static final boolean tracing = true;
|
||||
|
||||
/*
|
||||
* Frequently used identifiers
|
||||
*/
|
||||
Identifier idAppend = Identifier.lookup("append");
|
||||
Identifier idClassInit = Identifier.lookup("<clinit>");
|
||||
Identifier idCode = Identifier.lookup("Code");
|
||||
Identifier idInit = Identifier.lookup("<init>");
|
||||
Identifier idLength = Identifier.lookup("length");
|
||||
Identifier idNull = Identifier.lookup("");
|
||||
Identifier idStar = Identifier.lookup("*");
|
||||
Identifier idSuper = Identifier.lookup("super");
|
||||
Identifier idThis = Identifier.lookup("this");
|
||||
Identifier idClass = Identifier.lookup("class");
|
||||
Identifier idToString = Identifier.lookup("toString");
|
||||
Identifier idValueOf = Identifier.lookup("valueOf");
|
||||
Identifier idNew = Identifier.lookup("new");
|
||||
Identifier idGetClass = Identifier.lookup("getClass");
|
||||
Identifier idTYPE = Identifier.lookup("TYPE");
|
||||
Identifier idFinallyReturnValue = Identifier.lookup("<return>");
|
||||
|
||||
Identifier idJavaLang = Identifier.lookup("java.lang");
|
||||
|
||||
Identifier idJavaLangCloneable = Identifier.lookup("java.lang.Cloneable");
|
||||
|
||||
Identifier idJavaLangError = Identifier.lookup("java.lang.Error");
|
||||
Identifier idJavaLangException = Identifier.lookup("java.lang.Exception");
|
||||
Identifier idJavaLangObject = Identifier.lookup("java.lang.Object");
|
||||
Identifier idJavaLangClass = Identifier.lookup("java.lang.Class");
|
||||
Identifier idJavaLangRuntimeException =
|
||||
Identifier.lookup("java.lang.RuntimeException");
|
||||
Identifier idJavaLangString = Identifier.lookup("java.lang.String");
|
||||
Identifier idJavaLangStringBuffer =
|
||||
Identifier.lookup("java.lang.StringBuffer");
|
||||
Identifier idJavaLangThrowable = Identifier.lookup("java.lang.Throwable");
|
||||
|
||||
Identifier idJavaIoSerializable = Identifier.lookup("java.io.Serializable");
|
||||
|
||||
|
||||
Identifier idConstantValue = Identifier.lookup("ConstantValue");
|
||||
Identifier idLocalVariableTable = Identifier.lookup("LocalVariableTable");
|
||||
Identifier idLineNumberTable = Identifier.lookup("LineNumberTable");
|
||||
// JCOV
|
||||
Identifier idCoverageTable = Identifier.lookup("CoverageTable");
|
||||
// end JCOV
|
||||
Identifier idSourceFile = Identifier.lookup("SourceFile");
|
||||
Identifier idDocumentation = Identifier.lookup("Documentation");
|
||||
Identifier idDeprecated = Identifier.lookup("Deprecated");
|
||||
Identifier idSynthetic = Identifier.lookup("Synthetic");
|
||||
Identifier idExceptions = Identifier.lookup("Exceptions");
|
||||
Identifier idInnerClasses = Identifier.lookup("InnerClasses");
|
||||
|
||||
/* methods we need to know about */
|
||||
Identifier idClone = Identifier.lookup("clone");
|
||||
|
||||
|
||||
/* This is not a real signature marker, since it is also
|
||||
* an identifier constituent character.
|
||||
*/
|
||||
char SIGC_INNERCLASS = '$';
|
||||
String SIG_INNERCLASS = "$";
|
||||
|
||||
String prefixThis = "this$";
|
||||
String prefixVal = "val$";
|
||||
String prefixLoc = "loc$";
|
||||
String prefixAccess = "access$";
|
||||
String prefixClass = "class$";
|
||||
String prefixArray = "array$";
|
||||
|
||||
/*
|
||||
* Flags
|
||||
*/
|
||||
int F_VERBOSE = 1 << 0;
|
||||
int F_DUMP = 1 << 1;
|
||||
int F_WARNINGS = 1 << 2;
|
||||
|
||||
// The meaning of -g has changed, so F_DEBUG flag is removed.
|
||||
// public static final int F_DEBUG = 1 << 3;
|
||||
int F_DEBUG_LINES = 1 << 12;
|
||||
int F_DEBUG_VARS = 1 << 13;
|
||||
int F_DEBUG_SOURCE = 1 << 18;
|
||||
|
||||
// The meaning of -O has changed, so F_OPTIMIZE flag is removed.
|
||||
// public static final int F_OPTIMIZE = 1 << 4;
|
||||
int F_OPT = 1 << 14;
|
||||
int F_OPT_INTERCLASS = 1 << 15;
|
||||
|
||||
int F_DEPENDENCIES = 1 << 5;
|
||||
|
||||
// JCOV
|
||||
int F_COVERAGE = 1 << 6;
|
||||
int F_COVDATA = 1 << 7;
|
||||
// end JCOV
|
||||
|
||||
int F_DEPRECATION = 1 << 9;
|
||||
int F_PRINT_DEPENDENCIES = 1 << 10;
|
||||
int F_VERSION12 = 1 << 11;
|
||||
|
||||
|
||||
int F_ERRORSREPORTED = 1 << 16;
|
||||
|
||||
int F_STRICTDEFAULT = 1 << 17;
|
||||
|
||||
/*
|
||||
* Modifiers.
|
||||
*
|
||||
* There has been much confusion regarding modifiers. There
|
||||
* are a number of distinct usages:
|
||||
*
|
||||
* - in classfiles to annotate classes, as per JVM pg. 102.
|
||||
* - in classfiles to annotate methods, as per JVM pg. 104.
|
||||
* - in classfiles to annotate InnerClass attributes, as per
|
||||
* http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses
|
||||
* - in the compiler to record java source level modifiers,
|
||||
* as per JLS pg. 157 et al., plus misc. info such as whether
|
||||
* a method is deprecated
|
||||
* - in the JVM to record misc. info, such as whether a method has
|
||||
* has been compiled
|
||||
*
|
||||
* To make matters worse, the terms "access flags" and "modifiers"
|
||||
* are often used interchangably, and some information that might
|
||||
* make sense as a flag is expressed using attributes (ie. Synthetic).
|
||||
*
|
||||
* The constants defined herein have been divided by whether they
|
||||
* make sense only within the compiler (M_* and MM_*) or whether
|
||||
* they only make sense to the JVM (ACC_* and ACCM_*). At an earlier
|
||||
* time these were all lumped together. Future maintenance should
|
||||
* strive to keep the distinction clear.
|
||||
*
|
||||
* Note that modifier M_STRICTFP is not in general recoverable from
|
||||
* the ACC_STRICT bit in classfiles.
|
||||
*
|
||||
* Note also that the modifiers M_LOCAL and M_ANONYMOUS do not appear
|
||||
* in the InnerClass attribute, as they are above the first 16 bits.
|
||||
*/
|
||||
|
||||
// Modifiers meaningful to both Java source and the JVM. These
|
||||
// have been kept the same bit in the M_* and ACC_* forms
|
||||
// to avoid destabilizing the compiler.
|
||||
int M_PUBLIC = ACC_PUBLIC;
|
||||
int M_PRIVATE = ACC_PRIVATE;
|
||||
int M_PROTECTED = ACC_PROTECTED;
|
||||
int M_STATIC = ACC_STATIC;
|
||||
int M_TRANSIENT = ACC_TRANSIENT;
|
||||
int M_SYNCHRONIZED = ACC_SYNCHRONIZED; // collides with ACC_SUPER
|
||||
int M_ABSTRACT = ACC_ABSTRACT;
|
||||
int M_NATIVE = ACC_NATIVE;
|
||||
int M_FINAL = ACC_FINAL;
|
||||
int M_VOLATILE = ACC_VOLATILE;
|
||||
int M_INTERFACE = ACC_INTERFACE;
|
||||
|
||||
// Modifiers not meaningful to the JVM. The JVM only allows 16 bits
|
||||
// for modifiers, so keeping these in the unusable bits after the first
|
||||
// 16 is a good idea.
|
||||
int M_ANONYMOUS = 0x00010000;
|
||||
int M_LOCAL = 0x00020000;
|
||||
int M_DEPRECATED = 0x00040000;
|
||||
int M_SYNTHETIC = 0x00080000;
|
||||
int M_INLINEABLE = 0x00100000;
|
||||
|
||||
int M_STRICTFP = 0x00200000;
|
||||
|
||||
String paraDeprecated = "@deprecated";
|
||||
|
||||
// Masks for modifiers that apply to Java source code
|
||||
int MM_CLASS = M_PUBLIC
|
||||
| M_INTERFACE
|
||||
| M_FINAL
|
||||
| M_ABSTRACT
|
||||
| M_STRICTFP;
|
||||
int MM_MEMBER = M_PUBLIC
|
||||
| M_PRIVATE
|
||||
| M_PROTECTED
|
||||
| M_FINAL
|
||||
| M_STATIC;
|
||||
int MM_FIELD = MM_MEMBER
|
||||
| M_TRANSIENT
|
||||
| M_VOLATILE;
|
||||
int MM_METHOD = MM_MEMBER
|
||||
| M_SYNCHRONIZED
|
||||
| M_ABSTRACT
|
||||
| M_NATIVE
|
||||
| M_STRICTFP;
|
||||
|
||||
// Masks for modifiers that apply to class files.
|
||||
// Note that the M_SYNTHETIC modifier is never written out to a class file.
|
||||
// Synthetic members are indicated using the "Synthetic" attribute.
|
||||
int ACCM_CLASS = ACC_PUBLIC
|
||||
| ACC_INTERFACE
|
||||
| ACC_FINAL
|
||||
| ACC_ABSTRACT
|
||||
| ACC_SUPER
|
||||
| ACC_STRICT;
|
||||
int ACCM_MEMBER = ACC_PUBLIC
|
||||
| ACC_PRIVATE
|
||||
| ACC_PROTECTED
|
||||
| ACC_FINAL
|
||||
| ACC_STATIC;
|
||||
// The M_ANONYMOUS and M_LOCAL modifiers are not mentioned in the
|
||||
// inner classes specification and are never written to classfiles.
|
||||
// Also note that ACC_SUPER should never be set in an InnerClass
|
||||
// attribute.
|
||||
int ACCM_INNERCLASS = ACC_PUBLIC
|
||||
| ACC_PRIVATE
|
||||
| ACC_PROTECTED
|
||||
| ACC_STATIC
|
||||
| ACC_ABSTRACT
|
||||
| ACC_FINAL
|
||||
| ACC_INTERFACE
|
||||
| ACC_STRICT;
|
||||
int ACCM_FIELD = ACCM_MEMBER
|
||||
| ACC_TRANSIENT
|
||||
| ACC_VOLATILE;
|
||||
int ACCM_METHOD = ACCM_MEMBER
|
||||
| ACC_SYNCHRONIZED
|
||||
| ACC_ABSTRACT
|
||||
| ACC_NATIVE
|
||||
| ACC_STRICT;
|
||||
|
||||
/*
|
||||
* Type codes
|
||||
*/
|
||||
int TC_BOOLEAN = 0;
|
||||
int TC_BYTE = 1;
|
||||
int TC_CHAR = 2;
|
||||
int TC_SHORT = 3;
|
||||
int TC_INT = 4;
|
||||
int TC_LONG = 5;
|
||||
int TC_FLOAT = 6;
|
||||
int TC_DOUBLE = 7;
|
||||
int TC_NULL = 8;
|
||||
int TC_ARRAY = 9;
|
||||
int TC_CLASS = 10;
|
||||
int TC_VOID = 11;
|
||||
int TC_METHOD = 12;
|
||||
int TC_ERROR = 13;
|
||||
|
||||
// JCOV
|
||||
/*
|
||||
* Cover's types
|
||||
*/
|
||||
int CT_FIRST_KIND = 1;
|
||||
int CT_METHOD = 1;
|
||||
int CT_FIKT_METHOD = 2;
|
||||
int CT_BLOCK = 3;
|
||||
int CT_FIKT_RET = 4;
|
||||
int CT_CASE = 5;
|
||||
int CT_SWITH_WO_DEF = 6;
|
||||
int CT_BRANCH_TRUE = 7;
|
||||
int CT_BRANCH_FALSE = 8;
|
||||
int CT_LAST_KIND = 8;
|
||||
// end JCOV
|
||||
|
||||
/*
|
||||
* Type Masks
|
||||
*/
|
||||
int TM_NULL = 1 << TC_NULL;
|
||||
int TM_VOID = 1 << TC_VOID;
|
||||
int TM_BOOLEAN = 1 << TC_BOOLEAN;
|
||||
int TM_BYTE = 1 << TC_BYTE;
|
||||
int TM_CHAR = 1 << TC_CHAR;
|
||||
int TM_SHORT = 1 << TC_SHORT;
|
||||
int TM_INT = 1 << TC_INT;
|
||||
int TM_LONG = 1 << TC_LONG;
|
||||
int TM_FLOAT = 1 << TC_FLOAT;
|
||||
int TM_DOUBLE = 1 << TC_DOUBLE;
|
||||
int TM_ARRAY = 1 << TC_ARRAY;
|
||||
int TM_CLASS = 1 << TC_CLASS;
|
||||
int TM_METHOD = 1 << TC_METHOD;
|
||||
int TM_ERROR = 1 << TC_ERROR;
|
||||
|
||||
int TM_INT32 = TM_BYTE | TM_SHORT | TM_CHAR | TM_INT;
|
||||
int TM_NUM32 = TM_INT32 | TM_FLOAT;
|
||||
int TM_NUM64 = TM_LONG | TM_DOUBLE;
|
||||
int TM_INTEGER = TM_INT32 | TM_LONG;
|
||||
int TM_REAL = TM_FLOAT | TM_DOUBLE;
|
||||
int TM_NUMBER = TM_INTEGER | TM_REAL;
|
||||
int TM_REFERENCE = TM_ARRAY | TM_CLASS | TM_NULL;
|
||||
|
||||
/*
|
||||
* Class status
|
||||
*/
|
||||
int CS_UNDEFINED = 0;
|
||||
int CS_UNDECIDED = 1;
|
||||
int CS_BINARY = 2;
|
||||
int CS_SOURCE = 3;
|
||||
int CS_PARSED = 4;
|
||||
int CS_CHECKED = 5;
|
||||
int CS_COMPILED = 6;
|
||||
int CS_NOTFOUND = 7;
|
||||
|
||||
|
||||
/*
|
||||
* Attributes
|
||||
*/
|
||||
int ATT_ALL = 0xFFFFFFFF;
|
||||
int ATT_CODE = 1 << 1;
|
||||
int ATT_ALLCLASSES = 1 << 2;
|
||||
|
||||
/*
|
||||
* Number of bits used in file offsets. The line number and
|
||||
* file offset are concatenated into a long, with enough room
|
||||
* for other information to be added later if desired (such as
|
||||
* token lengths). For the moment explicit bit manipulations
|
||||
* are used to modify the fields. This makes sense for efficiency
|
||||
* but at some point these ought to be better encapsulated.
|
||||
*/
|
||||
int WHEREOFFSETBITS = 32;
|
||||
long MAXFILESIZE = (1L << WHEREOFFSETBITS) - 1;
|
||||
long MAXLINENUMBER = (1L << (64 - WHEREOFFSETBITS)) - 1;
|
||||
|
||||
/*
|
||||
* Operators
|
||||
*/
|
||||
int COMMA = 0;
|
||||
int ASSIGN = 1;
|
||||
|
||||
int ASGMUL = 2;
|
||||
int ASGDIV = 3;
|
||||
int ASGREM = 4;
|
||||
int ASGADD = 5;
|
||||
int ASGSUB = 6;
|
||||
int ASGLSHIFT = 7;
|
||||
int ASGRSHIFT = 8;
|
||||
int ASGURSHIFT = 9;
|
||||
int ASGBITAND = 10;
|
||||
int ASGBITOR = 11;
|
||||
int ASGBITXOR = 12;
|
||||
|
||||
int COND = 13;
|
||||
int OR = 14;
|
||||
int AND = 15;
|
||||
int BITOR = 16;
|
||||
int BITXOR = 17;
|
||||
int BITAND = 18;
|
||||
int NE = 19;
|
||||
int EQ = 20;
|
||||
int GE = 21;
|
||||
int GT = 22;
|
||||
int LE = 23;
|
||||
int LT = 24;
|
||||
int INSTANCEOF = 25;
|
||||
int LSHIFT = 26;
|
||||
int RSHIFT = 27;
|
||||
int URSHIFT = 28;
|
||||
int ADD = 29;
|
||||
int SUB = 30;
|
||||
int DIV = 31;
|
||||
int REM = 32;
|
||||
int MUL = 33;
|
||||
int CAST = 34; // (x)y
|
||||
int POS = 35; // +x
|
||||
int NEG = 36; // -x
|
||||
int NOT = 37;
|
||||
int BITNOT = 38;
|
||||
int PREINC = 39; // ++x
|
||||
int PREDEC = 40; // --x
|
||||
int NEWARRAY = 41;
|
||||
int NEWINSTANCE = 42;
|
||||
int NEWFROMNAME = 43;
|
||||
int POSTINC = 44; // x++
|
||||
int POSTDEC = 45; // x--
|
||||
int FIELD = 46;
|
||||
int METHOD = 47; // x(y)
|
||||
int ARRAYACCESS = 48; // x[y]
|
||||
int NEW = 49;
|
||||
int INC = 50;
|
||||
int DEC = 51;
|
||||
|
||||
int CONVERT = 55; // implicit conversion
|
||||
int EXPR = 56; // (x)
|
||||
int ARRAY = 57; // {x, y, ...}
|
||||
int GOTO = 58;
|
||||
|
||||
/*
|
||||
* Value tokens
|
||||
*/
|
||||
int IDENT = 60;
|
||||
int BOOLEANVAL = 61;
|
||||
int BYTEVAL = 62;
|
||||
int CHARVAL = 63;
|
||||
int SHORTVAL = 64;
|
||||
int INTVAL = 65;
|
||||
int LONGVAL = 66;
|
||||
int FLOATVAL = 67;
|
||||
int DOUBLEVAL = 68;
|
||||
int STRINGVAL = 69;
|
||||
|
||||
/*
|
||||
* Type keywords
|
||||
*/
|
||||
int BYTE = 70;
|
||||
int CHAR = 71;
|
||||
int SHORT = 72;
|
||||
int INT = 73;
|
||||
int LONG = 74;
|
||||
int FLOAT = 75;
|
||||
int DOUBLE = 76;
|
||||
int VOID = 77;
|
||||
int BOOLEAN = 78;
|
||||
|
||||
/*
|
||||
* Expression keywords
|
||||
*/
|
||||
int TRUE = 80;
|
||||
int FALSE = 81;
|
||||
int THIS = 82;
|
||||
int SUPER = 83;
|
||||
int NULL = 84;
|
||||
|
||||
/*
|
||||
* Statement keywords
|
||||
*/
|
||||
int IF = 90;
|
||||
int ELSE = 91;
|
||||
int FOR = 92;
|
||||
int WHILE = 93;
|
||||
int DO = 94;
|
||||
int SWITCH = 95;
|
||||
int CASE = 96;
|
||||
int DEFAULT = 97;
|
||||
int BREAK = 98;
|
||||
int CONTINUE = 99;
|
||||
int RETURN = 100;
|
||||
int TRY = 101;
|
||||
int CATCH = 102;
|
||||
int FINALLY = 103;
|
||||
int THROW = 104;
|
||||
int STAT = 105;
|
||||
int EXPRESSION = 106;
|
||||
int DECLARATION = 107;
|
||||
int VARDECLARATION = 108;
|
||||
|
||||
/*
|
||||
* Declaration keywords
|
||||
*/
|
||||
int IMPORT = 110;
|
||||
int CLASS = 111;
|
||||
int EXTENDS = 112;
|
||||
int IMPLEMENTS = 113;
|
||||
int INTERFACE = 114;
|
||||
int PACKAGE = 115;
|
||||
|
||||
/*
|
||||
* Modifier keywords
|
||||
*/
|
||||
int PRIVATE = 120;
|
||||
int PUBLIC = 121;
|
||||
int PROTECTED = 122;
|
||||
int CONST = 123;
|
||||
int STATIC = 124;
|
||||
int TRANSIENT = 125;
|
||||
int SYNCHRONIZED = 126;
|
||||
int NATIVE = 127;
|
||||
int FINAL = 128;
|
||||
int VOLATILE = 129;
|
||||
int ABSTRACT = 130;
|
||||
int STRICTFP = 131;
|
||||
|
||||
/*
|
||||
* Punctuation
|
||||
*/
|
||||
int SEMICOLON = 135;
|
||||
int COLON = 136;
|
||||
int QUESTIONMARK = 137;
|
||||
int LBRACE = 138;
|
||||
int RBRACE = 139;
|
||||
int LPAREN = 140;
|
||||
int RPAREN = 141;
|
||||
int LSQBRACKET = 142;
|
||||
int RSQBRACKET = 143;
|
||||
int THROWS = 144;
|
||||
|
||||
/*
|
||||
* Special tokens
|
||||
*/
|
||||
int ERROR = 145; // an error
|
||||
int COMMENT = 146; // not used anymore.
|
||||
int TYPE = 147;
|
||||
int LENGTH = 148;
|
||||
int INLINERETURN = 149;
|
||||
int INLINEMETHOD = 150;
|
||||
int INLINENEWINSTANCE = 151;
|
||||
|
||||
/*
|
||||
* Operator precedence
|
||||
*/
|
||||
int opPrecedence[] = {
|
||||
10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
18, 19, 19, 19, 19, 19, 20, 20, 20, 21,
|
||||
21, 22, 22, 22, 23, 24, 24, 24, 24, 24,
|
||||
24, 25, 25, 26, 26, 26, 26, 26, 26
|
||||
};
|
||||
|
||||
/*
|
||||
* Operator names
|
||||
*/
|
||||
String opNames[] = {
|
||||
",", "=", "*=", "/=", "%=",
|
||||
"+=", "-=", "<<=", ">>=", ">>>=",
|
||||
"&=", "|=", "^=", "?:", "||",
|
||||
"&&", "|", "^", "&", "!=",
|
||||
"==", ">=", ">", "<=", "<",
|
||||
"instanceof", "<<", ">>", ">>>", "+",
|
||||
"-", "/", "%", "*", "cast",
|
||||
"+", "-", "!", "~", "++",
|
||||
"--", "new", "new", "new", "++",
|
||||
"--", "field","method","[]", "new",
|
||||
"++", "--", null, null, null,
|
||||
|
||||
"convert", "expr", "array", "goto", null,
|
||||
|
||||
"Identifier", "boolean", "byte", "char", "short",
|
||||
"int", "long", "float", "double", "string",
|
||||
|
||||
"byte", "char", "short", "int", "long",
|
||||
"float", "double", "void", "boolean", null,
|
||||
|
||||
"true", "false", "this", "super", "null",
|
||||
null, null, null, null, null,
|
||||
|
||||
"if", "else", "for", "while","do",
|
||||
"switch", "case", "default", "break", "continue",
|
||||
"return", "try", "catch", "finally", "throw",
|
||||
"stat", "expression", "declaration", "declaration", null,
|
||||
|
||||
"import", "class", "extends", "implements", "interface",
|
||||
"package", null, null, null, null,
|
||||
|
||||
"private", "public", "protected", "const", "static",
|
||||
"transient", "synchronized", "native", "final", "volatile",
|
||||
"abstract", "strictfp", null, null, null,
|
||||
|
||||
";", ":", "?", "{", "}",
|
||||
"(", ")", "[", "]", "throws",
|
||||
"error", "comment", "type", "length", "inline-return",
|
||||
"inline-method", "inline-new"
|
||||
};
|
||||
}
|
||||
998
jdkSrc/jdk8/sun/tools/java/Environment.java
Normal file
998
jdkSrc/jdk8/sun/tools/java/Environment.java
Normal file
@@ -0,0 +1,998 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.Stack;
|
||||
import java.io.IOException;
|
||||
import sun.tools.tree.Context;
|
||||
//JCOV
|
||||
import java.io.File;
|
||||
//end JCOV
|
||||
|
||||
/**
|
||||
* This class defines the environment for a compilation.
|
||||
* It is used to load classes, resolve class names and
|
||||
* report errors. It is an abstract class, a subclass
|
||||
* must define implementations for some of the functions.<p>
|
||||
*
|
||||
* An environment has a source object associated with it.
|
||||
* This is the thing against which errors are reported, it
|
||||
* is usually a file name, a field or a class.<p>
|
||||
*
|
||||
* Environments can be nested to change the source object.<p>
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
|
||||
public class Environment implements Constants {
|
||||
/**
|
||||
* The actual environment to which everything is forwarded.
|
||||
*/
|
||||
Environment env;
|
||||
|
||||
/**
|
||||
* External character encoding name
|
||||
*/
|
||||
String encoding;
|
||||
|
||||
/**
|
||||
* The object that is currently being parsed/compiled.
|
||||
* It is either a file name (String) or a field (MemberDefinition)
|
||||
* or a class (ClassDeclaration or ClassDefinition).
|
||||
*/
|
||||
Object source;
|
||||
|
||||
public Environment(Environment env, Object source) {
|
||||
if (env != null && env.env != null && env.getClass() == this.getClass())
|
||||
env = env.env; // a small optimization
|
||||
this.env = env;
|
||||
this.source = source;
|
||||
}
|
||||
public Environment() {
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether an Identifier refers to a package which should be
|
||||
* exempt from the "exists" check in Imports#resolve().
|
||||
*/
|
||||
public boolean isExemptPackage(Identifier id) {
|
||||
return env.isExemptPackage(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a class declaration given a fully qualified class name.
|
||||
*/
|
||||
public ClassDeclaration getClassDeclaration(Identifier nm) {
|
||||
return env.getClassDeclaration(nm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a class definition given a fully qualified class name.
|
||||
* <p>
|
||||
* Should be called only with 'internal' class names, i.e., the result
|
||||
* of a call to 'resolveName' or a synthetic class name.
|
||||
*/
|
||||
public final ClassDefinition getClassDefinition(Identifier nm) throws ClassNotFound {
|
||||
if (nm.isInner()) {
|
||||
ClassDefinition c = getClassDefinition(nm.getTopName());
|
||||
Identifier tail = nm.getFlatName();
|
||||
walkTail:
|
||||
while (tail.isQualified()) {
|
||||
tail = tail.getTail();
|
||||
Identifier head = tail.getHead();
|
||||
//System.out.println("CLASS: " + c + " HEAD: " + head + " TAIL: " + tail);
|
||||
String hname = head.toString();
|
||||
// If the name is of the form 'ClassName.N$localName', where N is
|
||||
// a number, the field 'N$localName' may not necessarily be a member
|
||||
// of the class named by 'ClassName', but might be a member of some
|
||||
// inaccessible class contained within it. We use 'getLocalClass'
|
||||
// to do the lookup in this case. This is part of a fix for bugid
|
||||
// 4054523 and 4030421. See also 'BatchEnvironment.makeClassDefinition'.
|
||||
// This should also work for anonymous class names of the form
|
||||
// 'ClassName.N'. Note that the '.' qualifications get converted to
|
||||
// '$' characters when determining the external name of the class and
|
||||
// the name of the class file.
|
||||
if (hname.length() > 0
|
||||
&& Character.isDigit(hname.charAt(0))) {
|
||||
ClassDefinition localClass = c.getLocalClass(hname);
|
||||
if (localClass != null) {
|
||||
c = localClass;
|
||||
continue walkTail;
|
||||
}
|
||||
} else {
|
||||
for (MemberDefinition f = c.getFirstMatch(head);
|
||||
f != null; f = f.getNextMatch()) {
|
||||
if (f.isInnerClass()) {
|
||||
c = f.getInnerClass();
|
||||
continue walkTail;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ClassNotFound(Identifier.lookupInner(c.getName(), head));
|
||||
}
|
||||
//System.out.println("FOUND " + c + " FOR " + nm);
|
||||
return c;
|
||||
}
|
||||
return getClassDeclaration(nm).getClassDefinition(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a class declaration given a type. Only works for
|
||||
* class types.
|
||||
*/
|
||||
public ClassDeclaration getClassDeclaration(Type t) {
|
||||
return getClassDeclaration(t.getClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a class definition given a type. Only works for
|
||||
* class types.
|
||||
*/
|
||||
public final ClassDefinition getClassDefinition(Type t) throws ClassNotFound {
|
||||
return getClassDefinition(t.getClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a class exists (without actually loading it).
|
||||
* (Since inner classes cannot in general be examined without
|
||||
* loading source, this method does not accept inner names.)
|
||||
*/
|
||||
public boolean classExists(Identifier nm) {
|
||||
return env.classExists(nm);
|
||||
}
|
||||
|
||||
public final boolean classExists(Type t) {
|
||||
return !t.isType(TC_CLASS) || classExists(t.getClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the package path for a package
|
||||
*/
|
||||
public Package getPackage(Identifier pkg) throws IOException {
|
||||
return env.getPackage(pkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the definition of a class.
|
||||
*/
|
||||
public void loadDefinition(ClassDeclaration c) {
|
||||
env.loadDefinition(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the source of the environment (ie: the thing being compiled/parsed).
|
||||
*/
|
||||
public final Object getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a type. Make sure that all the classes referred to by
|
||||
* the type have a definition. Report errors. Return true if
|
||||
* the type is well-formed. Presently used for types appearing
|
||||
* in member declarations, which represent named types internally as
|
||||
* qualified identifiers. Type names appearing in local variable
|
||||
* declarations and within expressions are represented as identifier
|
||||
* or field expressions, and are resolved by 'toType', which delegates
|
||||
* handling of the non-inner portion of the name to this method.
|
||||
* <p>
|
||||
* In 'toType', the various stages of qualification are represented by
|
||||
* separate AST nodes. Here, we are given a single identifier which
|
||||
* contains the entire qualification structure. It is not possible in
|
||||
* general to set the error location to the exact position of a component
|
||||
* that is in error, so an error message must refer to the entire qualified
|
||||
* name. An attempt to keep track of the string length of the components of
|
||||
* the name and to offset the location accordingly fails because the initial
|
||||
* prefix of the name may have been rewritten by an earlier call to
|
||||
* 'resolveName'. See 'SourceMember.resolveTypeStructure'. The situation
|
||||
* is actually even worse than this, because only a single location is
|
||||
* passed in for an entire declaration, which may contain many type names.
|
||||
* All error messages are thus poorly localized. These checks should be
|
||||
* done while traversing the parse tree for the type, not the type descriptor.
|
||||
* <p>
|
||||
* DESIGN NOTE:
|
||||
* As far as I can tell, the two-stage resolution of names represented in
|
||||
* string form is an artifact of the late implementation of inner classes
|
||||
* and the use of mangled names internally within the compiler. All
|
||||
* qualified names should have their hiearchical structure made explicit
|
||||
* in the parse tree at the phase at which they are presented for static
|
||||
* semantic checking. This would affect class names appearing in 'extends',
|
||||
* 'implements', and 'throws' clauses, as well as in member declarations.
|
||||
*/
|
||||
public boolean resolve(long where, ClassDefinition c, Type t) {
|
||||
switch (t.getTypeCode()) {
|
||||
case TC_CLASS: {
|
||||
ClassDefinition def;
|
||||
try {
|
||||
Identifier nm = t.getClassName();
|
||||
if (!nm.isQualified() && !nm.isInner() && !classExists(nm)) {
|
||||
resolve(nm); // elicit complaints about ambiguity
|
||||
}
|
||||
def = getQualifiedClassDefinition(where, nm, c, false);
|
||||
if (!c.canAccess(this, def.getClassDeclaration())) {
|
||||
// Reported error location may be imprecise
|
||||
// if the name is qualified.
|
||||
error(where, "cant.access.class", def);
|
||||
return true; // return false later
|
||||
}
|
||||
def.noteUsedBy(c, where, env);
|
||||
} catch (AmbiguousClass ee) {
|
||||
error(where, "ambig.class", ee.name1, ee.name2);
|
||||
return false;
|
||||
} catch (ClassNotFound e) {
|
||||
// For now, report "class.and.package" only when the code
|
||||
// is going to fail anyway.
|
||||
try {
|
||||
if (e.name.isInner() &&
|
||||
getPackage(e.name.getTopName()).exists()) {
|
||||
env.error(where, "class.and.package",
|
||||
e.name.getTopName());
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
env.error(where, "io.exception", "package check");
|
||||
}
|
||||
// This error message is also emitted for 'new' expressions.
|
||||
// error(where, "class.not.found", e.name, "declaration");
|
||||
error(where, "class.not.found.no.context", e.name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case TC_ARRAY:
|
||||
return resolve(where, c, t.getElementType());
|
||||
|
||||
case TC_METHOD:
|
||||
boolean ok = resolve(where, c, t.getReturnType());
|
||||
Type args[] = t.getArgumentTypes();
|
||||
for (int i = args.length ; i-- > 0 ; ) {
|
||||
ok &= resolve(where, c, args[i]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given its fully-qualified name, verify that a class is defined and accessible.
|
||||
* Used to check components of qualified names in contexts where a class is expected.
|
||||
* Like 'resolve', but is given a single type name, not a type descriptor.
|
||||
*/
|
||||
public boolean resolveByName(long where, ClassDefinition c, Identifier nm) {
|
||||
return resolveByName(where, c, nm, false);
|
||||
}
|
||||
|
||||
public boolean resolveExtendsByName(long where, ClassDefinition c, Identifier nm) {
|
||||
return resolveByName(where, c, nm, true);
|
||||
}
|
||||
|
||||
private boolean resolveByName(long where, ClassDefinition c,
|
||||
Identifier nm, boolean isExtends) {
|
||||
ClassDefinition def;
|
||||
try {
|
||||
if (!nm.isQualified() && !nm.isInner() && !classExists(nm)) {
|
||||
resolve(nm); // elicit complaints about ambiguity
|
||||
}
|
||||
def = getQualifiedClassDefinition(where, nm, c, isExtends);
|
||||
ClassDeclaration decl = def.getClassDeclaration();
|
||||
if (!((!isExtends && c.canAccess(this, decl))
|
||||
||
|
||||
(isExtends && c.extendsCanAccess(this, decl)))) {
|
||||
error(where, "cant.access.class", def);
|
||||
return true; // return false later
|
||||
}
|
||||
} catch (AmbiguousClass ee) {
|
||||
error(where, "ambig.class", ee.name1, ee.name2);
|
||||
return false;
|
||||
} catch (ClassNotFound e) {
|
||||
// For now, report "class.and.package" only when the code
|
||||
// is going to fail anyway.
|
||||
try {
|
||||
if (e.name.isInner() &&
|
||||
getPackage(e.name.getTopName()).exists()) {
|
||||
env.error(where, "class.and.package",
|
||||
e.name.getTopName());
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
env.error(where, "io.exception", "package check");
|
||||
}
|
||||
error(where, "class.not.found", e.name, "type name");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like 'getClassDefinition(env)', but check access on each component.
|
||||
* Currently called only by 'resolve' above. It is doubtful that calls
|
||||
* to 'getClassDefinition(env)' are appropriate now.
|
||||
*/
|
||||
public final ClassDefinition
|
||||
getQualifiedClassDefinition(long where,
|
||||
Identifier nm,
|
||||
ClassDefinition ctxClass,
|
||||
boolean isExtends) throws ClassNotFound {
|
||||
if (nm.isInner()) {
|
||||
ClassDefinition c = getClassDefinition(nm.getTopName());
|
||||
Identifier tail = nm.getFlatName();
|
||||
walkTail:
|
||||
while (tail.isQualified()) {
|
||||
tail = tail.getTail();
|
||||
Identifier head = tail.getHead();
|
||||
// System.out.println("CLASS: " + c + " HEAD: " + head + " TAIL: " + tail);
|
||||
String hname = head.toString();
|
||||
// Handle synthesized names of local and anonymous classes.
|
||||
// See 'getClassDefinition(env)' above.
|
||||
if (hname.length() > 0
|
||||
&& Character.isDigit(hname.charAt(0))) {
|
||||
ClassDefinition localClass = c.getLocalClass(hname);
|
||||
if (localClass != null) {
|
||||
c = localClass;
|
||||
continue walkTail;
|
||||
}
|
||||
} else {
|
||||
for (MemberDefinition f = c.getFirstMatch(head);
|
||||
f != null; f = f.getNextMatch()) {
|
||||
if (f.isInnerClass()) {
|
||||
ClassDeclaration rdecl = c.getClassDeclaration();
|
||||
c = f.getInnerClass();
|
||||
ClassDeclaration fdecl = c.getClassDeclaration();
|
||||
// This check is presumably applicable even if the
|
||||
// original source-code name (expanded by 'resolveNames')
|
||||
// was a simple, unqualified name. Hopefully, JLS 2e
|
||||
// will clarify the matter.
|
||||
if ((!isExtends
|
||||
&& !ctxClass.canAccess(env, fdecl))
|
||||
||
|
||||
(isExtends
|
||||
&& !ctxClass.extendsCanAccess(env, fdecl))) {
|
||||
// Reported error location is imprecise.
|
||||
env.error(where, "no.type.access", head, rdecl, ctxClass);
|
||||
}
|
||||
// The JLS 6.6.2 restrictions on access to protected members
|
||||
// depend in an essential way upon the syntactic form of the name.
|
||||
// Since the compiler has previously expanded the class names
|
||||
// here into fully-qualified form ('resolveNames'), this check
|
||||
// cannot be performed here. Unfortunately, the original names
|
||||
// are clobbered during 'basicCheck', which is also the phase that
|
||||
// resolves the inheritance structure, required to implement the
|
||||
// access restrictions. Pending a large-scale revision of the
|
||||
// name-resolution machinery, we forgo this check, with the result
|
||||
// that the JLS 6.6.2 restrictions are not enforced for some cases
|
||||
// of qualified access to inner classes. Some qualified names are
|
||||
// resolved elsewhere via a different mechanism, and will be
|
||||
// treated correctly -- see 'FieldExpression.checkCommon'.
|
||||
/*---------------------------------------*
|
||||
if (f.isProtected()) {
|
||||
Type rty = Type.tClass(rdecl.getName()); // hack
|
||||
if (!ctxClass.protectedAccess(env, f, rty)) {
|
||||
// Reported error location is imprecise.
|
||||
env.error(where, "invalid.protected.type.use",
|
||||
head, ctxClass, rty);
|
||||
}
|
||||
}
|
||||
*---------------------------------------*/
|
||||
continue walkTail;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ClassNotFound(Identifier.lookupInner(c.getName(), head));
|
||||
}
|
||||
//System.out.println("FOUND " + c + " FOR " + nm);
|
||||
return c;
|
||||
}
|
||||
return getClassDeclaration(nm).getClassDefinition(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the names within a type, returning the adjusted type.
|
||||
* Adjust class names to reflect scoping.
|
||||
* Do not report errors.
|
||||
* <p>
|
||||
* NOTE: It would be convenient to check for errors here, such as
|
||||
* verifying that each component of a qualified name exists and is
|
||||
* accessible. Why must this be done in a separate phase?
|
||||
* <p>
|
||||
* If the 'synth' argument is true, indicating that the member whose
|
||||
* type is being resolved is synthetic, names are resolved with respect
|
||||
* to the package scope. (Fix for 4097882)
|
||||
*/
|
||||
public Type resolveNames(ClassDefinition c, Type t, boolean synth) {
|
||||
if (tracing) dtEvent("Environment.resolveNames: " + c + ", " + t);
|
||||
switch (t.getTypeCode()) {
|
||||
case TC_CLASS: {
|
||||
Identifier name = t.getClassName();
|
||||
Identifier rname;
|
||||
if (synth) {
|
||||
rname = resolvePackageQualifiedName(name);
|
||||
} else {
|
||||
rname = c.resolveName(this, name);
|
||||
}
|
||||
if (name != rname) {
|
||||
t = Type.tClass(rname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TC_ARRAY:
|
||||
t = Type.tArray(resolveNames(c, t.getElementType(), synth));
|
||||
break;
|
||||
|
||||
case TC_METHOD: {
|
||||
Type ret = t.getReturnType();
|
||||
Type rret = resolveNames(c, ret, synth);
|
||||
Type args[] = t.getArgumentTypes();
|
||||
Type rargs[] = new Type[args.length];
|
||||
boolean changed = (ret != rret);
|
||||
for (int i = args.length ; i-- > 0 ; ) {
|
||||
Type arg = args[i];
|
||||
Type rarg = resolveNames(c, arg, synth);
|
||||
rargs[i] = rarg;
|
||||
if (arg != rarg) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
t = Type.tMethod(rret, rargs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a class name, using only package and import directives.
|
||||
* Report no errors.
|
||||
* <p>
|
||||
*/
|
||||
public Identifier resolveName(Identifier name) {
|
||||
// This logic is pretty exactly parallel to that of
|
||||
// ClassDefinition.resolveName().
|
||||
if (name.isQualified()) {
|
||||
// Try to resolve the first identifier component,
|
||||
// because inner class names take precedence over
|
||||
// package prefixes. (Cf. ClassDefinition.resolveName.)
|
||||
Identifier rhead = resolveName(name.getHead());
|
||||
|
||||
if (rhead.hasAmbigPrefix()) {
|
||||
// The first identifier component refers to an
|
||||
// ambiguous class. Limp on. We throw away the
|
||||
// rest of the classname as it is irrelevant.
|
||||
// (part of solution for 4059855).
|
||||
return rhead;
|
||||
}
|
||||
|
||||
if (!this.classExists(rhead)) {
|
||||
return this.resolvePackageQualifiedName(name);
|
||||
}
|
||||
try {
|
||||
return this.getClassDefinition(rhead).
|
||||
resolveInnerClass(this, name.getTail());
|
||||
} catch (ClassNotFound ee) {
|
||||
// return partially-resolved name someone else can fail on
|
||||
return Identifier.lookupInner(rhead, name.getTail());
|
||||
}
|
||||
}
|
||||
try {
|
||||
return resolve(name);
|
||||
} catch (AmbiguousClass ee) {
|
||||
// Don't force a resolution of the name if it is ambiguous.
|
||||
// Forcing the resolution would tack the current package
|
||||
// name onto the front of the class, which would be wrong.
|
||||
// Instead, mark the name as ambiguous and let a later stage
|
||||
// find the error by calling env.resolve(name).
|
||||
// (part of solution for 4059855).
|
||||
|
||||
if (name.hasAmbigPrefix()) {
|
||||
return name;
|
||||
} else {
|
||||
return name.addAmbigPrefix();
|
||||
}
|
||||
} catch (ClassNotFound ee) {
|
||||
// last chance to make something halfway sensible
|
||||
Imports imports = getImports();
|
||||
if (imports != null)
|
||||
return imports.forceResolve(this, name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Discover if name consists of a package prefix, followed by the
|
||||
* name of a class (that actually exists), followed possibly by
|
||||
* some inner class names. If we can't find a class that exists,
|
||||
* return the name unchanged.
|
||||
* <p>
|
||||
* This routine is used after a class name fails to
|
||||
* be resolved by means of imports or inner classes.
|
||||
* However, import processing uses this routine directly,
|
||||
* since import names must be exactly qualified to start with.
|
||||
*/
|
||||
public final Identifier resolvePackageQualifiedName(Identifier name) {
|
||||
Identifier tail = null;
|
||||
for (;;) {
|
||||
if (classExists(name)) {
|
||||
break;
|
||||
}
|
||||
if (!name.isQualified()) {
|
||||
name = (tail == null) ? name : Identifier.lookup(name, tail);
|
||||
tail = null;
|
||||
break;
|
||||
}
|
||||
Identifier nm = name.getName();
|
||||
tail = (tail == null)? nm: Identifier.lookup(nm, tail);
|
||||
name = name.getQualifier();
|
||||
}
|
||||
if (tail != null)
|
||||
name = Identifier.lookupInner(name, tail);
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a class name, using only package and import directives.
|
||||
*/
|
||||
public Identifier resolve(Identifier nm) throws ClassNotFound {
|
||||
if (env == null) return nm; // a pretty useless no-op
|
||||
return env.resolve(nm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the imports used to resolve class names.
|
||||
*/
|
||||
public Imports getImports() {
|
||||
if (env == null) return null; // lame default
|
||||
return env.getImports();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new class.
|
||||
*/
|
||||
public ClassDefinition makeClassDefinition(Environment origEnv, long where,
|
||||
IdentifierToken name,
|
||||
String doc, int modifiers,
|
||||
IdentifierToken superClass,
|
||||
IdentifierToken interfaces[],
|
||||
ClassDefinition outerClass) {
|
||||
if (env == null) return null; // lame default
|
||||
return env.makeClassDefinition(origEnv, where, name,
|
||||
doc, modifiers,
|
||||
superClass, interfaces, outerClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new field.
|
||||
*/
|
||||
public MemberDefinition makeMemberDefinition(Environment origEnv, long where,
|
||||
ClassDefinition clazz,
|
||||
String doc, int modifiers,
|
||||
Type type, Identifier name,
|
||||
IdentifierToken argNames[],
|
||||
IdentifierToken expIds[],
|
||||
Object value) {
|
||||
if (env == null) return null; // lame default
|
||||
return env.makeMemberDefinition(origEnv, where, clazz, doc, modifiers,
|
||||
type, name, argNames, expIds, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given method is applicable to the given arguments
|
||||
*/
|
||||
|
||||
public boolean isApplicable(MemberDefinition m, Type args[]) throws ClassNotFound {
|
||||
Type mType = m.getType();
|
||||
if (!mType.isType(TC_METHOD))
|
||||
return false;
|
||||
Type mArgs[] = mType.getArgumentTypes();
|
||||
if (args.length != mArgs.length)
|
||||
return false;
|
||||
for (int i = args.length ; --i >= 0 ;)
|
||||
if (!isMoreSpecific(args[i], mArgs[i]))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if "best" is in every argument at least as good as "other"
|
||||
*/
|
||||
public boolean isMoreSpecific(MemberDefinition best, MemberDefinition other)
|
||||
throws ClassNotFound {
|
||||
Type bestType = best.getClassDeclaration().getType();
|
||||
Type otherType = other.getClassDeclaration().getType();
|
||||
boolean result = isMoreSpecific(bestType, otherType)
|
||||
&& isApplicable(other, best.getType().getArgumentTypes());
|
||||
// System.out.println("isMoreSpecific: " + best + "/" + other
|
||||
// + " => " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if "from" is a more specific type than "to"
|
||||
*/
|
||||
|
||||
public boolean isMoreSpecific(Type from, Type to) throws ClassNotFound {
|
||||
return implicitCast(from, to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if an implicit cast from this type to
|
||||
* the given type is allowed.
|
||||
*/
|
||||
public boolean implicitCast(Type from, Type to) throws ClassNotFound {
|
||||
if (from == to)
|
||||
return true;
|
||||
|
||||
int toTypeCode = to.getTypeCode();
|
||||
|
||||
switch(from.getTypeCode()) {
|
||||
case TC_BYTE:
|
||||
if (toTypeCode == TC_SHORT)
|
||||
return true;
|
||||
case TC_SHORT:
|
||||
case TC_CHAR:
|
||||
if (toTypeCode == TC_INT) return true;
|
||||
case TC_INT:
|
||||
if (toTypeCode == TC_LONG) return true;
|
||||
case TC_LONG:
|
||||
if (toTypeCode == TC_FLOAT) return true;
|
||||
case TC_FLOAT:
|
||||
if (toTypeCode == TC_DOUBLE) return true;
|
||||
case TC_DOUBLE:
|
||||
default:
|
||||
return false;
|
||||
|
||||
case TC_NULL:
|
||||
return to.inMask(TM_REFERENCE);
|
||||
|
||||
case TC_ARRAY:
|
||||
if (!to.isType(TC_ARRAY)) {
|
||||
return (to == Type.tObject || to == Type.tCloneable
|
||||
|| to == Type.tSerializable);
|
||||
} else {
|
||||
// both are arrays. recurse down both until one isn't an array
|
||||
do {
|
||||
from = from.getElementType();
|
||||
to = to.getElementType();
|
||||
} while (from.isType(TC_ARRAY) && to.isType(TC_ARRAY));
|
||||
if ( from.inMask(TM_ARRAY|TM_CLASS)
|
||||
&& to.inMask(TM_ARRAY|TM_CLASS)) {
|
||||
return isMoreSpecific(from, to);
|
||||
} else {
|
||||
return (from.getTypeCode() == to.getTypeCode());
|
||||
}
|
||||
}
|
||||
|
||||
case TC_CLASS:
|
||||
if (toTypeCode == TC_CLASS) {
|
||||
ClassDefinition fromDef = getClassDefinition(from);
|
||||
ClassDefinition toDef = getClassDefinition(to);
|
||||
return toDef.implementedBy(this,
|
||||
fromDef.getClassDeclaration());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if an explicit cast from this type to
|
||||
* the given type is allowed.
|
||||
*/
|
||||
public boolean explicitCast(Type from, Type to) throws ClassNotFound {
|
||||
if (implicitCast(from, to)) {
|
||||
return true;
|
||||
}
|
||||
if (from.inMask(TM_NUMBER)) {
|
||||
return to.inMask(TM_NUMBER);
|
||||
}
|
||||
if (from.isType(TC_CLASS) && to.isType(TC_CLASS)) {
|
||||
ClassDefinition fromClass = getClassDefinition(from);
|
||||
ClassDefinition toClass = getClassDefinition(to);
|
||||
if (toClass.isFinal()) {
|
||||
return fromClass.implementedBy(this,
|
||||
toClass.getClassDeclaration());
|
||||
}
|
||||
if (fromClass.isFinal()) {
|
||||
return toClass.implementedBy(this,
|
||||
fromClass.getClassDeclaration());
|
||||
}
|
||||
|
||||
// The code here used to omit this case. If both types
|
||||
// involved in a cast are interfaces, then JLS 5.5 requires
|
||||
// that we do a simple test -- make sure none of the methods
|
||||
// in toClass and fromClass have the same signature but
|
||||
// different return types. (bug number 4028359)
|
||||
if (toClass.isInterface() && fromClass.isInterface()) {
|
||||
return toClass.couldImplement(fromClass);
|
||||
}
|
||||
|
||||
return toClass.isInterface() ||
|
||||
fromClass.isInterface() ||
|
||||
fromClass.superClassOf(this, toClass.getClassDeclaration());
|
||||
}
|
||||
if (to.isType(TC_ARRAY)) {
|
||||
if (from.isType(TC_ARRAY)) {
|
||||
Type t1 = from.getElementType();
|
||||
Type t2 = to.getElementType();
|
||||
while ((t1.getTypeCode() == TC_ARRAY)
|
||||
&& (t2.getTypeCode() == TC_ARRAY)) {
|
||||
t1 = t1.getElementType();
|
||||
t2 = t2.getElementType();
|
||||
}
|
||||
if (t1.inMask(TM_ARRAY|TM_CLASS) &&
|
||||
t2.inMask(TM_ARRAY|TM_CLASS)) {
|
||||
return explicitCast(t1, t2);
|
||||
}
|
||||
} else if (from == Type.tObject || from == Type.tCloneable
|
||||
|| from == Type.tSerializable)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flags.
|
||||
*/
|
||||
public int getFlags() {
|
||||
return env.getFlags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Debugging flags. There used to be a method debug()
|
||||
* that has been replaced because -g has changed meaning
|
||||
* (it now cooperates with -O and line number, variable
|
||||
* range and source file info can be toggled separately).
|
||||
*/
|
||||
public final boolean debug_lines() {
|
||||
return (getFlags() & F_DEBUG_LINES) != 0;
|
||||
}
|
||||
public final boolean debug_vars() {
|
||||
return (getFlags() & F_DEBUG_VARS) != 0;
|
||||
}
|
||||
public final boolean debug_source() {
|
||||
return (getFlags() & F_DEBUG_SOURCE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimization flags. There used to be a method optimize()
|
||||
* that has been replaced because -O has changed meaning in
|
||||
* javac to be replaced with -O and -O:interclass.
|
||||
*/
|
||||
public final boolean opt() {
|
||||
return (getFlags() & F_OPT) != 0;
|
||||
}
|
||||
public final boolean opt_interclass() {
|
||||
return (getFlags() & F_OPT_INTERCLASS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verbose
|
||||
*/
|
||||
public final boolean verbose() {
|
||||
return (getFlags() & F_VERBOSE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump debugging stuff
|
||||
*/
|
||||
public final boolean dump() {
|
||||
return (getFlags() & F_DUMP) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verbose
|
||||
*/
|
||||
public final boolean warnings() {
|
||||
return (getFlags() & F_WARNINGS) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
public final boolean dependencies() {
|
||||
return (getFlags() & F_DEPENDENCIES) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print Dependencies to stdout
|
||||
*/
|
||||
public final boolean print_dependencies() {
|
||||
return (getFlags() & F_PRINT_DEPENDENCIES) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecation warnings are enabled.
|
||||
*/
|
||||
public final boolean deprecation() {
|
||||
return (getFlags() & F_DEPRECATION) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not support virtual machines before version 1.2.
|
||||
* This option is not supported and is only here for testing purposes.
|
||||
*/
|
||||
public final boolean version12() {
|
||||
return (getFlags() & F_VERSION12) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Floating point is strict by default
|
||||
*/
|
||||
public final boolean strictdefault() {
|
||||
return (getFlags() & F_STRICTDEFAULT) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release resources, if any.
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (env != null) {
|
||||
env.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue an error.
|
||||
* source - the input source, usually a file name string
|
||||
* offset - the offset in the source of the error
|
||||
* err - the error number (as defined in this interface)
|
||||
* arg1 - an optional argument to the error (null if not applicable)
|
||||
* arg2 - a second optional argument to the error (null if not applicable)
|
||||
* arg3 - a third optional argument to the error (null if not applicable)
|
||||
*/
|
||||
public void error(Object source, long where, String err, Object arg1, Object arg2, Object arg3) {
|
||||
env.error(source, where, err, arg1, arg2, arg3);
|
||||
}
|
||||
public final void error(long where, String err, Object arg1, Object arg2, Object arg3) {
|
||||
error(source, where, err, arg1, arg2, arg3);
|
||||
}
|
||||
public final void error(long where, String err, Object arg1, Object arg2) {
|
||||
error(source, where, err, arg1, arg2, null);
|
||||
}
|
||||
public final void error(long where, String err, Object arg1) {
|
||||
error(source, where, err, arg1, null, null);
|
||||
}
|
||||
public final void error(long where, String err) {
|
||||
error(source, where, err, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a string. This can either be an error message or something
|
||||
* for debugging. This should be used instead of println.
|
||||
*/
|
||||
public void output(String msg) {
|
||||
env.output(msg);
|
||||
}
|
||||
|
||||
private static boolean debugging = (System.getProperty("javac.debug") != null);
|
||||
|
||||
public static void debugOutput(Object msg) {
|
||||
if (Environment.debugging)
|
||||
System.out.println(msg.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* set character encoding name
|
||||
*/
|
||||
public void setCharacterEncoding(String encoding) {
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return character encoding name
|
||||
*/
|
||||
public String getCharacterEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return major version to use in generated class files.
|
||||
*/
|
||||
public short getMajorVersion() {
|
||||
if (env==null) return JAVA_DEFAULT_VERSION; // needed for javah
|
||||
return env.getMajorVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return minor version to use in generated class files.
|
||||
*/
|
||||
public short getMinorVersion() {
|
||||
if (env==null) return JAVA_DEFAULT_MINOR_VERSION; // needed for javah
|
||||
return env.getMinorVersion();
|
||||
}
|
||||
|
||||
// JCOV
|
||||
/**
|
||||
* get coverage flag
|
||||
*/
|
||||
public final boolean coverage() {
|
||||
return (getFlags() & F_COVERAGE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get flag of generation the coverage data file
|
||||
*/
|
||||
public final boolean covdata() {
|
||||
return (getFlags() & F_COVDATA) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the coverage data file
|
||||
*/
|
||||
public File getcovFile() {
|
||||
return env.getcovFile();
|
||||
}
|
||||
|
||||
// end JCOV
|
||||
|
||||
/**
|
||||
* Debug tracing.
|
||||
* Currently, this code is used only for tracing the loading and
|
||||
* checking of classes, particularly the demand-driven aspects.
|
||||
* This code should probably be integrated with 'debugOutput' above,
|
||||
* but we need to give more thought to the issue of classifying debugging
|
||||
* messages and allowing those only those of interest to be enabled.
|
||||
*
|
||||
* Calls to these methods are generally conditioned on the final variable
|
||||
* 'Constants.tracing', which allows the calls to be completely omitted
|
||||
* in a production release to avoid space and time overhead.
|
||||
*/
|
||||
|
||||
private static boolean dependtrace =
|
||||
(System.getProperty("javac.trace.depend") != null);
|
||||
|
||||
public void dtEnter(String s) {
|
||||
if (dependtrace) System.out.println(">>> " + s);
|
||||
}
|
||||
|
||||
public void dtExit(String s) {
|
||||
if (dependtrace) System.out.println("<<< " + s);
|
||||
}
|
||||
|
||||
public void dtEvent(String s) {
|
||||
if (dependtrace) System.out.println(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable diagnostic dump of class modifier bits, including those
|
||||
* in InnerClasses attributes, as they are written to the classfile.
|
||||
* In the future, may also enable dumping field and method modifiers.
|
||||
*/
|
||||
|
||||
private static boolean dumpmodifiers =
|
||||
(System.getProperty("javac.dump.modifiers") != null);
|
||||
|
||||
public boolean dumpModifiers() { return dumpmodifiers; }
|
||||
|
||||
}
|
||||
329
jdkSrc/jdk8/sun/tools/java/Identifier.java
Normal file
329
jdkSrc/jdk8/sun/tools/java/Identifier.java
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* A class to represent identifiers.<p>
|
||||
*
|
||||
* An identifier instance is very similar to a String. The difference
|
||||
* is that identifier can't be instanciated directly, instead they are
|
||||
* looked up in a hash table. This means that identifiers with the same
|
||||
* name map to the same identifier object. This makes comparisons of
|
||||
* identifiers much faster.<p>
|
||||
*
|
||||
* A lot of identifiers are qualified, that is they have '.'s in them.
|
||||
* Each qualified identifier is chopped up into the qualifier and the
|
||||
* name. The qualifier is cached in the value field.<p>
|
||||
*
|
||||
* Unqualified identifiers can have a type. This type is an integer that
|
||||
* can be used by a scanner as a token value. This value has to be set
|
||||
* using the setType method.<p>
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
|
||||
public final
|
||||
class Identifier implements Constants {
|
||||
/**
|
||||
* The hashtable of identifiers
|
||||
*/
|
||||
static Hashtable hash = new Hashtable(3001, 0.5f);
|
||||
|
||||
/**
|
||||
* The name of the identifier
|
||||
*/
|
||||
String name;
|
||||
|
||||
/**
|
||||
* The value of the identifier, for keywords this is an
|
||||
* instance of class Integer, for qualified names this is
|
||||
* another identifier (the qualifier).
|
||||
*/
|
||||
Object value;
|
||||
|
||||
/**
|
||||
* The Type which corresponds to this Identifier. This is used as
|
||||
* cache for Type.tClass() and shouldn't be used outside of that
|
||||
* context.
|
||||
*/
|
||||
Type typeObject = null;
|
||||
|
||||
/**
|
||||
* The index of INNERCLASS_PREFIX in the name, or -1 if none.
|
||||
*/
|
||||
private int ipos;
|
||||
|
||||
/**
|
||||
* Construct an identifier. Don't call this directly,
|
||||
* use lookup instead.
|
||||
* @see Identifier.lookup
|
||||
*/
|
||||
private Identifier(String name) {
|
||||
this.name = name;
|
||||
this.ipos = name.indexOf(INNERCLASS_PREFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the identifier.
|
||||
*/
|
||||
int getType() {
|
||||
return ((value != null) && (value instanceof Integer)) ?
|
||||
((Integer)value).intValue() : IDENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of the identifier.
|
||||
*/
|
||||
void setType(int t) {
|
||||
value = new Integer(t);
|
||||
//System.out.println("type(" + this + ")=" + t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup an identifier.
|
||||
*/
|
||||
public static synchronized Identifier lookup(String s) {
|
||||
//System.out.println("lookup(" + s + ")");
|
||||
Identifier id = (Identifier)hash.get(s);
|
||||
if (id == null) {
|
||||
hash.put(s, id = new Identifier(s));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a qualified identifier.
|
||||
*/
|
||||
public static Identifier lookup(Identifier q, Identifier n) {
|
||||
// lookup("", x) => x
|
||||
if (q == idNull) return n;
|
||||
// lookup(lookupInner(c, ""), n) => lookupInner(c, lookup("", n))
|
||||
if (q.name.charAt(q.name.length()-1) == INNERCLASS_PREFIX)
|
||||
return lookup(q.name+n.name);
|
||||
Identifier id = lookup(q + "." + n);
|
||||
if (!n.isQualified() && !q.isInner())
|
||||
id.value = q;
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup an inner identifier.
|
||||
* (Note: n can be idNull.)
|
||||
*/
|
||||
public static Identifier lookupInner(Identifier c, Identifier n) {
|
||||
Identifier id;
|
||||
if (c.isInner()) {
|
||||
if (c.name.charAt(c.name.length()-1) == INNERCLASS_PREFIX)
|
||||
id = lookup(c.name+n);
|
||||
else
|
||||
id = lookup(c, n);
|
||||
} else {
|
||||
id = lookup(c + "." + INNERCLASS_PREFIX + n);
|
||||
}
|
||||
id.value = c.value;
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a string.
|
||||
*/
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the name is qualified (ie: it contains a '.').
|
||||
*/
|
||||
public boolean isQualified() {
|
||||
if (value == null) {
|
||||
int idot = ipos;
|
||||
if (idot <= 0)
|
||||
idot = name.length();
|
||||
else
|
||||
idot -= 1; // back up over previous dot
|
||||
int index = name.lastIndexOf('.', idot-1);
|
||||
value = (index < 0) ? idNull : Identifier.lookup(name.substring(0, index));
|
||||
}
|
||||
return (value instanceof Identifier) && (value != idNull);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the qualifier. The null identifier is returned if
|
||||
* the name was not qualified. The qualifier does not include
|
||||
* any inner part of the name.
|
||||
*/
|
||||
public Identifier getQualifier() {
|
||||
return isQualified() ? (Identifier)value : idNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the unqualified name.
|
||||
* In the case of an inner name, the unqualified name
|
||||
* will itself contain components.
|
||||
*/
|
||||
public Identifier getName() {
|
||||
return isQualified() ?
|
||||
Identifier.lookup(name.substring(((Identifier)value).name.length() + 1)) : this;
|
||||
}
|
||||
|
||||
/** A space character, which precedes the first inner class
|
||||
* name in a qualified name, and thus marks the qualification
|
||||
* as involving inner classes, instead of merely packages.<p>
|
||||
* Ex: <tt>java.util.Vector. Enumerator</tt>.
|
||||
*/
|
||||
public static final char INNERCLASS_PREFIX = ' ';
|
||||
|
||||
/* Explanation:
|
||||
* Since much of the compiler's low-level name resolution code
|
||||
* operates in terms of Identifier objects. This includes the
|
||||
* code which walks around the file system and reports what
|
||||
* classes are where. It is important to get nesting information
|
||||
* right as early as possible, since it affects the spelling of
|
||||
* signatures. Thus, the low-level import and resolve code must
|
||||
* be able Identifier type must be able to report the nesting
|
||||
* of types, which implied that that information must be carried
|
||||
* by Identifiers--or that the low-level interfaces be significantly
|
||||
* changed.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check if the name is inner (ie: it contains a ' ').
|
||||
*/
|
||||
public boolean isInner() {
|
||||
return (ipos > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class name, without its qualifier,
|
||||
* and with any nesting flattened into a new qualfication structure.
|
||||
* If the original identifier is inner,
|
||||
* the result will be qualified, and can be further
|
||||
* decomposed by means of <tt>getQualifier</tt> and <tt>getName</tt>.
|
||||
* <p>
|
||||
* For example:
|
||||
* <pre>
|
||||
* Identifier id = Identifier.lookup("pkg.Foo. Bar");
|
||||
* id.getName().name => "Foo. Bar"
|
||||
* id.getFlatName().name => "Foo.Bar"
|
||||
* </pre>
|
||||
*/
|
||||
public Identifier getFlatName() {
|
||||
if (isQualified()) {
|
||||
return getName().getFlatName();
|
||||
}
|
||||
if (ipos > 0 && name.charAt(ipos-1) == '.') {
|
||||
if (ipos+1 == name.length()) {
|
||||
// last component is idNull
|
||||
return Identifier.lookup(name.substring(0,ipos-1));
|
||||
}
|
||||
String n = name.substring(ipos+1);
|
||||
String t = name.substring(0,ipos);
|
||||
return Identifier.lookup(t+n);
|
||||
}
|
||||
// Not inner. Just return the same as getName()
|
||||
return this;
|
||||
}
|
||||
|
||||
public Identifier getTopName() {
|
||||
if (!isInner()) return this;
|
||||
return Identifier.lookup(getQualifier(), getFlatName().getHead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Yet another way to slice qualified identifiers:
|
||||
* The head of an identifier is its first qualifier component,
|
||||
* and the tail is the rest of them.
|
||||
*/
|
||||
public Identifier getHead() {
|
||||
Identifier id = this;
|
||||
while (id.isQualified())
|
||||
id = id.getQualifier();
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see getHead
|
||||
*/
|
||||
public Identifier getTail() {
|
||||
Identifier id = getHead();
|
||||
if (id == this)
|
||||
return idNull;
|
||||
else
|
||||
return Identifier.lookup(name.substring(id.name.length() + 1));
|
||||
}
|
||||
|
||||
// Unfortunately, the current structure of the compiler requires
|
||||
// that the resolveName() family of methods (which appear in
|
||||
// Environment.java, Context.java, and ClassDefinition.java) raise
|
||||
// no exceptions and emit no errors. When we are in resolveName()
|
||||
// and we find a method that is ambiguous, we need to
|
||||
// unambiguously mark it as such, so that later stages of the
|
||||
// compiler realize that they should give an ambig.class rather than
|
||||
// a class.not.found error. To mark it we add a special prefix
|
||||
// which cannot occur in the program source. The routines below
|
||||
// are used to check, add, and remove this prefix.
|
||||
// (part of solution for 4059855).
|
||||
|
||||
/**
|
||||
* A special prefix to add to ambiguous names.
|
||||
*/
|
||||
private static final String ambigPrefix = "<<ambiguous>>";
|
||||
|
||||
/**
|
||||
* Determine whether an Identifier has been marked as ambiguous.
|
||||
*/
|
||||
public boolean hasAmbigPrefix() {
|
||||
return (name.startsWith(ambigPrefix));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ambigPrefix to `this' to make a new Identifier marked as
|
||||
* ambiguous. It is important that this new Identifier not refer
|
||||
* to an existing class.
|
||||
*/
|
||||
public Identifier addAmbigPrefix() {
|
||||
return Identifier.lookup(ambigPrefix + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the ambigPrefix from `this' to get the original identifier.
|
||||
*/
|
||||
public Identifier removeAmbigPrefix() {
|
||||
if (hasAmbigPrefix()) {
|
||||
return Identifier.lookup(name.substring(ambigPrefix.length()));
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
jdkSrc/jdk8/sun/tools/java/IdentifierToken.java
Normal file
91
jdkSrc/jdk8/sun/tools/java/IdentifierToken.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* Information about the occurrence of an identifier.
|
||||
* The parser produces these to represent name which cannot yet be
|
||||
* bound to field definitions.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @see
|
||||
*/
|
||||
|
||||
public
|
||||
class IdentifierToken {
|
||||
long where;
|
||||
int modifiers;
|
||||
Identifier id;
|
||||
|
||||
public IdentifierToken(long where, Identifier id) {
|
||||
this.where = where;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/** Use this constructor when the identifier is synthesized.
|
||||
* The location will be 0.
|
||||
*/
|
||||
public IdentifierToken(Identifier id) {
|
||||
this.where = 0;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public IdentifierToken(long where, Identifier id, int modifiers) {
|
||||
this.where = where;
|
||||
this.id = id;
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
/** The source location of this identifier occurrence. */
|
||||
public long getWhere() {
|
||||
return where;
|
||||
}
|
||||
|
||||
/** The identifier itself (possibly qualified). */
|
||||
public Identifier getName() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/** The modifiers associated with the occurrence, if any. */
|
||||
public int getModifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return id.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return defaultWhere if id is null or id.where is missing (0).
|
||||
* Otherwise, return id.where.
|
||||
*/
|
||||
public static long getWhere(IdentifierToken id, long defaultWhere) {
|
||||
return (id != null && id.where != 0) ? id.where : defaultWhere;
|
||||
}
|
||||
}
|
||||
503
jdkSrc/jdk8/sun/tools/java/Imports.java
Normal file
503
jdkSrc/jdk8/sun/tools/java/Imports.java
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class describes the classes and packages imported
|
||||
* from a source file. A Hashtable called bindings is maintained
|
||||
* to quickly map symbol names to classes. This table is flushed
|
||||
* everytime a new import is added.
|
||||
*
|
||||
* A class name is resolved as follows:
|
||||
* - if it is a qualified name then return the corresponding class
|
||||
* - if the name corresponds to an individually imported class then return that class
|
||||
* - check if the class is defined in any of the imported packages,
|
||||
* if it is then return it, make sure it is defined in only one package
|
||||
* - assume that the class is defined in the current package
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
public
|
||||
class Imports implements Constants {
|
||||
/**
|
||||
* The current package, which is implicitly imported,
|
||||
* and has precedence over other imported packages.
|
||||
*/
|
||||
Identifier currentPackage = idNull;
|
||||
|
||||
/**
|
||||
* A location for the current package declaration. Used to
|
||||
* report errors against the current package.
|
||||
*/
|
||||
long currentPackageWhere = 0;
|
||||
|
||||
/**
|
||||
* The imported classes, including memoized imports from packages.
|
||||
*/
|
||||
Hashtable classes = new Hashtable();
|
||||
|
||||
/**
|
||||
* The imported package identifiers. This will not contain duplicate
|
||||
* imports for the same package. It will also not contain the
|
||||
* current package.
|
||||
*/
|
||||
Vector packages = new Vector();
|
||||
|
||||
/**
|
||||
* The (originally) imported classes.
|
||||
* A vector of IdentifierToken.
|
||||
*/
|
||||
Vector singles = new Vector();
|
||||
|
||||
/**
|
||||
* Are the import names checked yet?
|
||||
*/
|
||||
protected int checked;
|
||||
|
||||
/**
|
||||
* Constructor, always import java.lang.
|
||||
*/
|
||||
public Imports(Environment env) {
|
||||
addPackage(idJavaLang);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the names of the imports.
|
||||
*/
|
||||
public synchronized void resolve(Environment env) {
|
||||
if (checked != 0) {
|
||||
return;
|
||||
}
|
||||
checked = -1;
|
||||
|
||||
// After all class information has been read, now we can
|
||||
// safely inspect import information for errors.
|
||||
// If we did this before all parsing was finished,
|
||||
// we could get vicious circularities, since files can
|
||||
// import each others' classes.
|
||||
|
||||
// A note: the resolution of the package java.lang takes place
|
||||
// in the sun.tools.javac.BatchEnvironment#setExemptPackages().
|
||||
|
||||
// Make sure that the current package's name does not collide
|
||||
// with the name of an existing class. (bug 4101529)
|
||||
//
|
||||
// This change has been backed out because, on WIN32, it
|
||||
// failed to distinguish between java.awt.event and
|
||||
// java.awt.Event when looking for a directory. We will
|
||||
// add this back in later.
|
||||
//
|
||||
// if (currentPackage != idNull) {
|
||||
// Identifier resolvedName =
|
||||
// env.resolvePackageQualifiedName(currentPackage);
|
||||
//
|
||||
// Identifier className = resolvedName.getTopName();
|
||||
//
|
||||
// if (importable(className, env)) {
|
||||
// // The name of the current package is also the name
|
||||
// // of a class.
|
||||
// env.error(currentPackageWhere, "package.class.conflict",
|
||||
// currentPackage, className);
|
||||
// }
|
||||
// }
|
||||
|
||||
Vector resolvedPackages = new Vector();
|
||||
for (Enumeration e = packages.elements() ; e.hasMoreElements() ;) {
|
||||
IdentifierToken t = (IdentifierToken)e.nextElement();
|
||||
Identifier nm = t.getName();
|
||||
long where = t.getWhere();
|
||||
|
||||
// Check to see if this package is exempt from the "exists"
|
||||
// check. See the note in
|
||||
// sun.tools.javac.BatchEnvironment#setExemptPackages()
|
||||
// for more information.
|
||||
if (env.isExemptPackage(nm)) {
|
||||
resolvedPackages.addElement(t);
|
||||
continue;
|
||||
}
|
||||
|
||||
// (Note: This code is moved from BatchParser.importPackage().)
|
||||
try {
|
||||
Identifier rnm = env.resolvePackageQualifiedName(nm);
|
||||
if (importable(rnm, env)) {
|
||||
// This name is a real class; better not be a package too.
|
||||
if (env.getPackage(rnm.getTopName()).exists()) {
|
||||
env.error(where, "class.and.package",
|
||||
rnm.getTopName());
|
||||
}
|
||||
// Pass an "inner" name to the imports.
|
||||
if (!rnm.isInner())
|
||||
rnm = Identifier.lookupInner(rnm, idNull);
|
||||
nm = rnm;
|
||||
} else if (!env.getPackage(nm).exists()) {
|
||||
env.error(where, "package.not.found", nm, "import");
|
||||
} else if (rnm.isInner()) {
|
||||
// nm exists, and rnm.getTopName() is a parent package
|
||||
env.error(where, "class.and.package", rnm.getTopName());
|
||||
}
|
||||
resolvedPackages.addElement(new IdentifierToken(where, nm));
|
||||
} catch (IOException ee) {
|
||||
env.error(where, "io.exception", "import");
|
||||
}
|
||||
}
|
||||
packages = resolvedPackages;
|
||||
|
||||
for (Enumeration e = singles.elements() ; e.hasMoreElements() ;) {
|
||||
IdentifierToken t = (IdentifierToken)e.nextElement();
|
||||
Identifier nm = t.getName();
|
||||
long where = t.getWhere();
|
||||
Identifier pkg = nm.getQualifier();
|
||||
|
||||
// (Note: This code is moved from BatchParser.importClass().)
|
||||
nm = env.resolvePackageQualifiedName(nm);
|
||||
if (!env.classExists(nm.getTopName())) {
|
||||
env.error(where, "class.not.found", nm, "import");
|
||||
}
|
||||
|
||||
// (Note: This code is moved from Imports.addClass().)
|
||||
Identifier snm = nm.getFlatName().getName();
|
||||
|
||||
// make sure it isn't already imported explicitly
|
||||
Identifier className = (Identifier)classes.get(snm);
|
||||
if (className != null) {
|
||||
Identifier f1 = Identifier.lookup(className.getQualifier(),
|
||||
className.getFlatName());
|
||||
Identifier f2 = Identifier.lookup(nm.getQualifier(),
|
||||
nm.getFlatName());
|
||||
if (!f1.equals(f2)) {
|
||||
env.error(where, "ambig.class", nm, className);
|
||||
}
|
||||
}
|
||||
classes.put(snm, nm);
|
||||
|
||||
|
||||
// The code here needs to check to see, if we
|
||||
// are importing an inner class, that all of its
|
||||
// enclosing classes are visible to us. To check this,
|
||||
// we need to construct a definition for the class.
|
||||
// The code here used to call...
|
||||
//
|
||||
// ClassDefinition def = env.getClassDefinition(nm);
|
||||
//
|
||||
// ...but that interfered with the basicCheck()'ing of
|
||||
// interfaces in certain cases (bug no. 4086139). Never
|
||||
// fear. Instead we load the class with a call to the
|
||||
// new getClassDefinitionNoCheck() which does no basicCheck() and
|
||||
// lets us answer the questions we are interested in w/o
|
||||
// interfering with the demand-driven nature of basicCheck().
|
||||
|
||||
try {
|
||||
// Get a declaration
|
||||
ClassDeclaration decl = env.getClassDeclaration(nm);
|
||||
|
||||
// Get the definition (no env argument)
|
||||
ClassDefinition def = decl.getClassDefinitionNoCheck(env);
|
||||
|
||||
// Get the true name of the package containing this class.
|
||||
// `pkg' from above is insufficient. It includes the
|
||||
// names of our enclosing classes. Fix for 4086815.
|
||||
Identifier importedPackage = def.getName().getQualifier();
|
||||
|
||||
// Walk out the outerClass chain, ensuring that each level
|
||||
// is visible from our perspective.
|
||||
for (; def != null; def = def.getOuterClass()) {
|
||||
if (def.isPrivate()
|
||||
|| !(def.isPublic()
|
||||
|| importedPackage.equals(currentPackage))) {
|
||||
env.error(where, "cant.access.class", def);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (AmbiguousClass ee) {
|
||||
env.error(where, "ambig.class", ee.name1, ee.name2);
|
||||
} catch (ClassNotFound ee) {
|
||||
env.error(where, "class.not.found", ee.name, "import");
|
||||
}
|
||||
}
|
||||
checked = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a class, given the current set of imports,
|
||||
* AmbiguousClass exception is thrown if the name can be
|
||||
* resolved in more than one way. A ClassNotFound exception
|
||||
* is thrown if the class is not found in the imported classes
|
||||
* and packages.
|
||||
*/
|
||||
public synchronized Identifier resolve(Environment env, Identifier nm) throws ClassNotFound {
|
||||
if (tracing) env.dtEnter("Imports.resolve: " + nm);
|
||||
|
||||
// If the class has the special ambiguous prefix, then we will
|
||||
// get the original AmbiguousClass exception by removing the
|
||||
// prefix and proceeding in the normal fashion.
|
||||
// (part of solution for 4059855)
|
||||
if (nm.hasAmbigPrefix()) {
|
||||
nm = nm.removeAmbigPrefix();
|
||||
}
|
||||
|
||||
if (nm.isQualified()) {
|
||||
// Don't bother it is already qualified
|
||||
if (tracing) env.dtExit("Imports.resolve: QUALIFIED " + nm);
|
||||
return nm;
|
||||
}
|
||||
|
||||
if (checked <= 0) {
|
||||
checked = 0;
|
||||
resolve(env);
|
||||
}
|
||||
|
||||
// Check if it was imported before
|
||||
Identifier className = (Identifier)classes.get(nm);
|
||||
if (className != null) {
|
||||
if (tracing) env.dtExit("Imports.resolve: PREVIOUSLY IMPORTED " + nm);
|
||||
return className;
|
||||
}
|
||||
|
||||
// Note: the section below has changed a bit during the fix
|
||||
// for bug 4093217. The current package is no longer grouped
|
||||
// with the rest of the import-on-demands; it is now checked
|
||||
// separately. Also, the list of import-on-demands is now
|
||||
// guarranteed to be duplicate-free, so the code below can afford
|
||||
// to be a bit simpler.
|
||||
|
||||
// First we look in the current package. The current package
|
||||
// is given precedence over the rest of the import-on-demands,
|
||||
// which means, among other things, that a class in the current
|
||||
// package cannot be ambiguous.
|
||||
Identifier id = Identifier.lookup(currentPackage, nm);
|
||||
if (importable(id, env)) {
|
||||
className = id;
|
||||
} else {
|
||||
// If it isn't in the current package, try to find it in
|
||||
// our import-on-demands.
|
||||
Enumeration e = packages.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
IdentifierToken t = (IdentifierToken)e.nextElement();
|
||||
id = Identifier.lookup(t.getName(), nm);
|
||||
|
||||
if (importable(id, env)) {
|
||||
if (className == null) {
|
||||
// We haven't found any other matching classes yet.
|
||||
// Set className to what we've found and continue
|
||||
// looking for an ambiguity.
|
||||
className = id;
|
||||
} else {
|
||||
if (tracing)
|
||||
env.dtExit("Imports.resolve: AMBIGUOUS " + nm);
|
||||
|
||||
// We've found an ambiguity.
|
||||
throw new AmbiguousClass(className, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure a class was found
|
||||
if (className == null) {
|
||||
if (tracing) env.dtExit("Imports.resolve: NOT FOUND " + nm);
|
||||
throw new ClassNotFound(nm);
|
||||
}
|
||||
|
||||
// Remember the binding
|
||||
classes.put(nm, className);
|
||||
if (tracing) env.dtExit("Imports.resolve: FIRST IMPORT " + nm);
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if 'id' names an importable class in `env'.
|
||||
* This method was made public and static for utility.
|
||||
*/
|
||||
static public boolean importable(Identifier id, Environment env) {
|
||||
if (!id.isInner()) {
|
||||
return env.classExists(id);
|
||||
} else if (!env.classExists(id.getTopName())) {
|
||||
return false;
|
||||
} else {
|
||||
// load the top class and look inside it
|
||||
try {
|
||||
// There used to be a call to...
|
||||
// env.getClassDeclaration(id.getTopName());
|
||||
// ...here. It has been replaced with the
|
||||
// two statements below. These should be functionally
|
||||
// the same except for the fact that
|
||||
// getClassDefinitionNoCheck() does not call
|
||||
// basicCheck(). This allows us to avoid a circular
|
||||
// need to do basicChecking that can arise with
|
||||
// certain patterns of importing and inheritance.
|
||||
// This is a fix for a variant of bug 4086139.
|
||||
//
|
||||
// Note: the special case code in env.getClassDefinition()
|
||||
// which handles inner class names is not replicated below.
|
||||
// This should be okay, as we are looking up id.getTopName(),
|
||||
// not id.
|
||||
ClassDeclaration decl =
|
||||
env.getClassDeclaration(id.getTopName());
|
||||
ClassDefinition c =
|
||||
decl.getClassDefinitionNoCheck(env);
|
||||
|
||||
return c.innerClassExists(id.getFlatName().getTail());
|
||||
} catch (ClassNotFound ee) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppose a resolve() call has failed.
|
||||
* This routine can be used silently to give a reasonable
|
||||
* default qualification (the current package) to the identifier.
|
||||
* This decision is recorded for future reference.
|
||||
*/
|
||||
public synchronized Identifier forceResolve(Environment env, Identifier nm) {
|
||||
if (nm.isQualified())
|
||||
return nm;
|
||||
|
||||
Identifier className = (Identifier)classes.get(nm);
|
||||
if (className != null) {
|
||||
return className;
|
||||
}
|
||||
|
||||
className = Identifier.lookup(currentPackage, nm);
|
||||
|
||||
classes.put(nm, className);
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a class import
|
||||
*/
|
||||
public synchronized void addClass(IdentifierToken t) {
|
||||
singles.addElement(t);
|
||||
}
|
||||
// for compatibility
|
||||
public void addClass(Identifier nm) throws AmbiguousClass {
|
||||
addClass(new IdentifierToken(nm));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a package import, or perhaps an inner class scope.
|
||||
* Ignore any duplicate imports.
|
||||
*/
|
||||
public synchronized void addPackage(IdentifierToken t) {
|
||||
final Identifier name = t.getName();
|
||||
|
||||
// If this is a duplicate import for the current package,
|
||||
// ignore it.
|
||||
if (name == currentPackage) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a duplicate of a package which has already been
|
||||
// added to the list, ignore it.
|
||||
final int size = packages.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (name == ((IdentifierToken)packages.elementAt(i)).getName()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the package to the list.
|
||||
packages.addElement(t);
|
||||
}
|
||||
// for compatibility
|
||||
public void addPackage(Identifier id) {
|
||||
addPackage(new IdentifierToken(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the current package with an IdentifierToken.
|
||||
*/
|
||||
public synchronized void setCurrentPackage(IdentifierToken t) {
|
||||
currentPackage = t.getName();
|
||||
currentPackageWhere = t.getWhere();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the current package
|
||||
*/
|
||||
public synchronized void setCurrentPackage(Identifier id) {
|
||||
currentPackage = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the current package
|
||||
*/
|
||||
public Identifier getCurrentPackage() {
|
||||
return currentPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an unmodifiable list of IdentifierToken representing
|
||||
* packages specified as imports.
|
||||
*/
|
||||
public List getImportedPackages() {
|
||||
return Collections.unmodifiableList(packages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an unmodifiable list of IdentifierToken representing
|
||||
* classes specified as imports.
|
||||
*/
|
||||
public List getImportedClasses() {
|
||||
return Collections.unmodifiableList(singles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend an environment with my resolve() method.
|
||||
*/
|
||||
public Environment newEnvironment(Environment env) {
|
||||
return new ImportEnvironment(env, this);
|
||||
}
|
||||
}
|
||||
|
||||
final
|
||||
class ImportEnvironment extends Environment {
|
||||
Imports imports;
|
||||
|
||||
ImportEnvironment(Environment env, Imports imports) {
|
||||
super(env, env.getSource());
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
public Identifier resolve(Identifier nm) throws ClassNotFound {
|
||||
return imports.resolve(this, nm);
|
||||
}
|
||||
|
||||
public Imports getImports() {
|
||||
return imports;
|
||||
}
|
||||
}
|
||||
1007
jdkSrc/jdk8/sun/tools/java/MemberDefinition.java
Normal file
1007
jdkSrc/jdk8/sun/tools/java/MemberDefinition.java
Normal file
File diff suppressed because it is too large
Load Diff
278
jdkSrc/jdk8/sun/tools/java/MethodSet.java
Normal file
278
jdkSrc/jdk8/sun/tools/java/MethodSet.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The MethodSet structure is used to store methods for a class.
|
||||
* It maintains the invariant that it never stores two methods
|
||||
* with the same signature. MethodSets are able to lookup
|
||||
* all methods with a given name and the unique method with a given
|
||||
* signature (name, args).
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
public
|
||||
class MethodSet {
|
||||
|
||||
/**
|
||||
* A Map containing Lists of MemberDefinitions. The Lists
|
||||
* contain methods which share the same name.
|
||||
*/
|
||||
private final Map lookupMap;
|
||||
|
||||
/**
|
||||
* The number of methods stored in the MethodSet.
|
||||
*/
|
||||
private int count;
|
||||
|
||||
/**
|
||||
* Is this MethodSet currently frozen? See freeze() for more details.
|
||||
*/
|
||||
private boolean frozen;
|
||||
|
||||
/**
|
||||
* Creates a brand new MethodSet
|
||||
*/
|
||||
public MethodSet() {
|
||||
frozen = false;
|
||||
lookupMap = new HashMap();
|
||||
count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of distinct methods stored in the MethodSet.
|
||||
*/
|
||||
public int size() {
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `method' to the MethodSet. No method of the same signature
|
||||
* should be already defined.
|
||||
*/
|
||||
public void add(MemberDefinition method) {
|
||||
// Check for late additions.
|
||||
if (frozen) {
|
||||
throw new CompilerError("add()");
|
||||
}
|
||||
|
||||
// todo: Check for method??
|
||||
|
||||
Identifier name = method.getName();
|
||||
|
||||
// Get a List containing all methods of this name.
|
||||
List methodList = (List) lookupMap.get(name);
|
||||
|
||||
if (methodList == null) {
|
||||
// There is no method with this name already.
|
||||
// Create a List, and insert it into the hash.
|
||||
methodList = new ArrayList();
|
||||
lookupMap.put(name, methodList);
|
||||
}
|
||||
|
||||
// Make sure that no method with the same signature has already
|
||||
// been added to the MethodSet.
|
||||
int size = methodList.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (((MemberDefinition) methodList.get(i))
|
||||
.getType().equalArguments(method.getType())) {
|
||||
throw new CompilerError("duplicate addition");
|
||||
}
|
||||
}
|
||||
|
||||
// We add the method to the appropriate list.
|
||||
methodList.add(method);
|
||||
count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `method' to the MethodSet, replacing any previous definition
|
||||
* with the same signature.
|
||||
*/
|
||||
public void replace(MemberDefinition method) {
|
||||
// Check for late additions.
|
||||
if (frozen) {
|
||||
throw new CompilerError("replace()");
|
||||
}
|
||||
|
||||
// todo: Check for method??
|
||||
|
||||
Identifier name = method.getName();
|
||||
|
||||
// Get a List containing all methods of this name.
|
||||
List methodList = (List) lookupMap.get(name);
|
||||
|
||||
if (methodList == null) {
|
||||
// There is no method with this name already.
|
||||
// Create a List, and insert it into the hash.
|
||||
methodList = new ArrayList();
|
||||
lookupMap.put(name, methodList);
|
||||
}
|
||||
|
||||
// Replace the element which has the same signature as
|
||||
// `method'.
|
||||
int size = methodList.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (((MemberDefinition) methodList.get(i))
|
||||
.getType().equalArguments(method.getType())) {
|
||||
methodList.set(i, method);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We add the method to the appropriate list.
|
||||
methodList.add(method);
|
||||
count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the MethodSet contains a method with the same signature
|
||||
* then lookup() returns it. Otherwise, this method returns null.
|
||||
*/
|
||||
public MemberDefinition lookupSig(Identifier name, Type type) {
|
||||
// Go through all methods of the same name and see if any
|
||||
// have the right signature.
|
||||
Iterator matches = lookupName(name);
|
||||
MemberDefinition candidate;
|
||||
|
||||
while (matches.hasNext()) {
|
||||
candidate = (MemberDefinition) matches.next();
|
||||
if (candidate.getType().equalArguments(type)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
// No match.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator of all methods contained in the
|
||||
* MethodSet which have a given name.
|
||||
*/
|
||||
public Iterator lookupName(Identifier name) {
|
||||
// Find the List containing all methods of this name, and
|
||||
// return that List's Iterator.
|
||||
List methodList = (List) lookupMap.get(name);
|
||||
if (methodList == null) {
|
||||
// If there is no method of this name, return a bogus, empty
|
||||
// Iterator.
|
||||
return Collections.emptyIterator();
|
||||
}
|
||||
return methodList.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator of all methods in the MethodSet
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
|
||||
//----------------------------------------------------------
|
||||
// The inner class MethodIterator is used to create our
|
||||
// Iterator of all methods in the MethodSet.
|
||||
class MethodIterator implements Iterator {
|
||||
Iterator hashIter = lookupMap.values().iterator();
|
||||
Iterator listIter = Collections.emptyIterator();
|
||||
|
||||
public boolean hasNext() {
|
||||
if (listIter.hasNext()) {
|
||||
return true;
|
||||
} else {
|
||||
if (hashIter.hasNext()) {
|
||||
listIter = ((List) hashIter.next())
|
||||
.iterator();
|
||||
|
||||
// The following should be always true.
|
||||
if (listIter.hasNext()) {
|
||||
return true;
|
||||
} else {
|
||||
throw new
|
||||
CompilerError("iterator() in MethodSet");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We've run out of Lists.
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
return listIter.next();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
// end MethodIterator
|
||||
//----------------------------------------------------------
|
||||
|
||||
// A one-liner.
|
||||
return new MethodIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* After freeze() is called, the MethodSet becomes (mostly)
|
||||
* immutable. Any calls to add() or addMeet() lead to
|
||||
* CompilerErrors. Note that the entries themselves are still
|
||||
* (unfortunately) open for mischievous and wanton modification.
|
||||
*/
|
||||
public void freeze() {
|
||||
frozen = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether freeze() has been called on this MethodSet.
|
||||
*/
|
||||
public boolean isFrozen() {
|
||||
return frozen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a (big) string representation of this MethodSet
|
||||
*/
|
||||
public String toString() {
|
||||
int len = size();
|
||||
StringBuffer buf = new StringBuffer();
|
||||
Iterator all = iterator();
|
||||
buf.append("{");
|
||||
|
||||
while (all.hasNext()) {
|
||||
buf.append(all.next().toString());
|
||||
len--;
|
||||
if (len > 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
}
|
||||
buf.append("}");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
107
jdkSrc/jdk8/sun/tools/java/MethodType.java
Normal file
107
jdkSrc/jdk8/sun/tools/java/MethodType.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* This class represents an Java method type.
|
||||
* It overrides the relevant methods in class Type.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public final
|
||||
class MethodType extends Type {
|
||||
/**
|
||||
* The return type.
|
||||
*/
|
||||
Type returnType;
|
||||
|
||||
/**
|
||||
* The argument types.
|
||||
*/
|
||||
Type argTypes[];
|
||||
|
||||
/**
|
||||
* Construct a method type. Use Type.tMethod to create
|
||||
* a new method type.
|
||||
* @see Type.tMethod
|
||||
*/
|
||||
MethodType(String typeSig, Type returnType, Type argTypes[]) {
|
||||
super(TC_METHOD, typeSig);
|
||||
this.returnType = returnType;
|
||||
this.argTypes = argTypes;
|
||||
}
|
||||
|
||||
public Type getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public Type getArgumentTypes()[] {
|
||||
return argTypes;
|
||||
}
|
||||
|
||||
public boolean equalArguments(Type t) {
|
||||
if (t.typeCode != TC_METHOD) {
|
||||
return false;
|
||||
}
|
||||
MethodType m = (MethodType)t;
|
||||
if (argTypes.length != m.argTypes.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = argTypes.length - 1 ; i >= 0 ; i--) {
|
||||
if (argTypes[i] != m.argTypes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int stackSize() {
|
||||
int n = 0;
|
||||
for (int i = 0 ; i < argTypes.length ; i++) {
|
||||
n += argTypes[i].stackSize();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public String typeString(String id, boolean abbrev, boolean ret) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(id);
|
||||
buf.append('(');
|
||||
for (int i = 0 ; i < argTypes.length ; i++) {
|
||||
if (i > 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
buf.append(argTypes[i].typeString("", abbrev, ret));
|
||||
}
|
||||
buf.append(')');
|
||||
|
||||
return ret ? getReturnType().typeString(buf.toString(), abbrev, ret) : buf.toString();
|
||||
}
|
||||
}
|
||||
161
jdkSrc/jdk8/sun/tools/java/Package.java
Normal file
161
jdkSrc/jdk8/sun/tools/java/Package.java
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class is used to represent the classes in a package.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public
|
||||
class Package {
|
||||
/**
|
||||
* The path which we use to locate source files.
|
||||
*/
|
||||
ClassPath sourcePath;
|
||||
|
||||
/**
|
||||
* The path which we use to locate class (binary) files.
|
||||
*/
|
||||
ClassPath binaryPath;
|
||||
|
||||
/**
|
||||
* The path name of the package.
|
||||
*/
|
||||
String pkg;
|
||||
|
||||
/**
|
||||
* Create a package given a class path, and package name.
|
||||
*/
|
||||
public Package(ClassPath path, Identifier pkg) throws IOException {
|
||||
this(path, path, pkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a package given a source path, binary path, and package
|
||||
* name.
|
||||
*/
|
||||
public Package(ClassPath sourcePath,
|
||||
ClassPath binaryPath,
|
||||
Identifier pkg)
|
||||
throws IOException {
|
||||
if (pkg.isInner())
|
||||
pkg = Identifier.lookup(pkg.getQualifier(), pkg.getFlatName());
|
||||
this.sourcePath = sourcePath;
|
||||
this.binaryPath = binaryPath;
|
||||
this.pkg = pkg.toString().replace('.', File.separatorChar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a class is defined in this package.
|
||||
* (If it is an inner class name, it is assumed to exist
|
||||
* only if its binary file exists. This is somewhat pessimistic.)
|
||||
*/
|
||||
public boolean classExists(Identifier className) {
|
||||
return getBinaryFile(className) != null ||
|
||||
!className.isInner() &&
|
||||
getSourceFile(className) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the package exists
|
||||
*/
|
||||
public boolean exists() {
|
||||
// Look for the directory on our binary path.
|
||||
ClassFile dir = binaryPath.getDirectory(pkg);
|
||||
if (dir != null && dir.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sourcePath != binaryPath) {
|
||||
// Look for the directory on our source path.
|
||||
dir = sourcePath.getDirectory(pkg);
|
||||
if (dir != null && dir.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Accommodate ZIP files without CEN entries for directories
|
||||
* (packages): look on class path for at least one binary
|
||||
* file or one source file with the right package prefix
|
||||
*/
|
||||
String prefix = pkg + File.separator;
|
||||
|
||||
return binaryPath.getFiles(prefix, ".class").hasMoreElements()
|
||||
|| sourcePath.getFiles(prefix, ".java").hasMoreElements();
|
||||
}
|
||||
|
||||
private String makeName(String fileName) {
|
||||
return pkg.equals("") ? fileName : pkg + File.separator + fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the .class file of a class
|
||||
*/
|
||||
public ClassFile getBinaryFile(Identifier className) {
|
||||
className = Type.mangleInnerType(className);
|
||||
String fileName = className.toString() + ".class";
|
||||
return binaryPath.getFile(makeName(fileName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the .java file of a class
|
||||
*/
|
||||
public ClassFile getSourceFile(Identifier className) {
|
||||
// The source file of an inner class is that of its outer class.
|
||||
className = className.getTopName();
|
||||
String fileName = className.toString() + ".java";
|
||||
return sourcePath.getFile(makeName(fileName));
|
||||
}
|
||||
|
||||
public ClassFile getSourceFile(String fileName) {
|
||||
if (fileName.endsWith(".java")) {
|
||||
return sourcePath.getFile(makeName(fileName));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Enumeration getSourceFiles() {
|
||||
return sourcePath.getFiles(pkg, ".java");
|
||||
}
|
||||
|
||||
public Enumeration getBinaryFiles() {
|
||||
return binaryPath.getFiles(pkg, ".class");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (pkg.equals("")) {
|
||||
return "unnamed package";
|
||||
}
|
||||
return "package " + pkg;
|
||||
}
|
||||
}
|
||||
2130
jdkSrc/jdk8/sun/tools/java/Parser.java
Normal file
2130
jdkSrc/jdk8/sun/tools/java/Parser.java
Normal file
File diff suppressed because it is too large
Load Diff
87
jdkSrc/jdk8/sun/tools/java/ParserActions.java
Normal file
87
jdkSrc/jdk8/sun/tools/java/ParserActions.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import sun.tools.tree.*;
|
||||
|
||||
/**
|
||||
* This is the protocol by which a Parser makes callbacks
|
||||
* to the later phases of the compiler.
|
||||
* <p>
|
||||
* (As a backwards compatibility trick, Parser implements
|
||||
* this protocol, so that an instance of a Parser subclass
|
||||
* can handle its own actions. The preferred way to use a
|
||||
* Parser, however, is to instantiate it directly with a
|
||||
* reference to your own ParserActions implementation.)
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author John R. Rose
|
||||
*/
|
||||
public interface ParserActions {
|
||||
/**
|
||||
* package declaration
|
||||
*/
|
||||
void packageDeclaration(long off, IdentifierToken nm);
|
||||
|
||||
/**
|
||||
* import class
|
||||
*/
|
||||
void importClass(long off, IdentifierToken nm);
|
||||
|
||||
/**
|
||||
* import package
|
||||
*/
|
||||
void importPackage(long off, IdentifierToken nm);
|
||||
|
||||
/**
|
||||
* Define class
|
||||
* @return a cookie for the class
|
||||
* This cookie is used by the parser when calling defineField
|
||||
* and endClass, and is not examined otherwise.
|
||||
*/
|
||||
ClassDefinition beginClass(long off, String doc,
|
||||
int mod, IdentifierToken nm,
|
||||
IdentifierToken sup, IdentifierToken impl[]);
|
||||
|
||||
|
||||
/**
|
||||
* End class
|
||||
* @param c a cookie returned by the corresponding beginClass call
|
||||
*/
|
||||
void endClass(long off, ClassDefinition c);
|
||||
|
||||
/**
|
||||
* Define a field
|
||||
* @param c a cookie returned by the corresponding beginClass call
|
||||
*/
|
||||
void defineField(long where, ClassDefinition c,
|
||||
String doc, int mod, Type t,
|
||||
IdentifierToken nm, IdentifierToken args[],
|
||||
IdentifierToken exp[], Node val);
|
||||
}
|
||||
742
jdkSrc/jdk8/sun/tools/java/RuntimeConstants.java
Normal file
742
jdkSrc/jdk8/sun/tools/java/RuntimeConstants.java
Normal file
@@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
public interface RuntimeConstants {
|
||||
|
||||
/* Signature Characters */
|
||||
char SIGC_VOID = 'V';
|
||||
String SIG_VOID = "V";
|
||||
char SIGC_BOOLEAN = 'Z';
|
||||
String SIG_BOOLEAN = "Z";
|
||||
char SIGC_BYTE = 'B';
|
||||
String SIG_BYTE = "B";
|
||||
char SIGC_CHAR = 'C';
|
||||
String SIG_CHAR = "C";
|
||||
char SIGC_SHORT = 'S';
|
||||
String SIG_SHORT = "S";
|
||||
char SIGC_INT = 'I';
|
||||
String SIG_INT = "I";
|
||||
char SIGC_LONG = 'J';
|
||||
String SIG_LONG = "J";
|
||||
char SIGC_FLOAT = 'F';
|
||||
String SIG_FLOAT = "F";
|
||||
char SIGC_DOUBLE = 'D';
|
||||
String SIG_DOUBLE = "D";
|
||||
char SIGC_ARRAY = '[';
|
||||
String SIG_ARRAY = "[";
|
||||
char SIGC_CLASS = 'L';
|
||||
String SIG_CLASS = "L";
|
||||
char SIGC_METHOD = '(';
|
||||
String SIG_METHOD = "(";
|
||||
char SIGC_ENDCLASS = ';';
|
||||
String SIG_ENDCLASS = ";";
|
||||
char SIGC_ENDMETHOD = ')';
|
||||
String SIG_ENDMETHOD = ")";
|
||||
char SIGC_PACKAGE = '/';
|
||||
String SIG_PACKAGE = "/";
|
||||
|
||||
/* Class File Constants */
|
||||
int JAVA_MAGIC = 0xcafebabe;
|
||||
int JAVA_MIN_SUPPORTED_VERSION = 45;
|
||||
int JAVA_MAX_SUPPORTED_VERSION = 52;
|
||||
int JAVA_MAX_SUPPORTED_MINOR_VERSION = 0;
|
||||
|
||||
/* Generate class file version for 1.1 by default */
|
||||
int JAVA_DEFAULT_VERSION = 45;
|
||||
int JAVA_DEFAULT_MINOR_VERSION = 3;
|
||||
|
||||
/* Constant table */
|
||||
int CONSTANT_UTF8 = 1;
|
||||
int CONSTANT_UNICODE = 2;
|
||||
int CONSTANT_INTEGER = 3;
|
||||
int CONSTANT_FLOAT = 4;
|
||||
int CONSTANT_LONG = 5;
|
||||
int CONSTANT_DOUBLE = 6;
|
||||
int CONSTANT_CLASS = 7;
|
||||
int CONSTANT_STRING = 8;
|
||||
int CONSTANT_FIELD = 9;
|
||||
int CONSTANT_METHOD = 10;
|
||||
int CONSTANT_INTERFACEMETHOD = 11;
|
||||
int CONSTANT_NAMEANDTYPE = 12;
|
||||
int CONSTANT_METHODHANDLE = 15;
|
||||
int CONSTANT_METHODTYPE = 16;
|
||||
int CONSTANT_INVOKEDYNAMIC = 18;
|
||||
|
||||
/* Access and modifier flags */
|
||||
int ACC_PUBLIC = 0x00000001;
|
||||
int ACC_PRIVATE = 0x00000002;
|
||||
int ACC_PROTECTED = 0x00000004;
|
||||
int ACC_STATIC = 0x00000008;
|
||||
int ACC_FINAL = 0x00000010;
|
||||
int ACC_SYNCHRONIZED = 0x00000020;
|
||||
int ACC_VOLATILE = 0x00000040;
|
||||
int ACC_TRANSIENT = 0x00000080;
|
||||
int ACC_NATIVE = 0x00000100;
|
||||
int ACC_INTERFACE = 0x00000200;
|
||||
int ACC_ABSTRACT = 0x00000400;
|
||||
int ACC_SUPER = 0x00000020;
|
||||
int ACC_STRICT = 0x00000800;
|
||||
|
||||
/* Type codes */
|
||||
int T_CLASS = 0x00000002;
|
||||
int T_BOOLEAN = 0x00000004;
|
||||
int T_CHAR = 0x00000005;
|
||||
int T_FLOAT = 0x00000006;
|
||||
int T_DOUBLE = 0x00000007;
|
||||
int T_BYTE = 0x00000008;
|
||||
int T_SHORT = 0x00000009;
|
||||
int T_INT = 0x0000000a;
|
||||
int T_LONG = 0x0000000b;
|
||||
|
||||
/* Opcodes */
|
||||
int opc_try = -3;
|
||||
int opc_dead = -2;
|
||||
int opc_label = -1;
|
||||
int opc_nop = 0;
|
||||
int opc_aconst_null = 1;
|
||||
int opc_iconst_m1 = 2;
|
||||
int opc_iconst_0 = 3;
|
||||
int opc_iconst_1 = 4;
|
||||
int opc_iconst_2 = 5;
|
||||
int opc_iconst_3 = 6;
|
||||
int opc_iconst_4 = 7;
|
||||
int opc_iconst_5 = 8;
|
||||
int opc_lconst_0 = 9;
|
||||
int opc_lconst_1 = 10;
|
||||
int opc_fconst_0 = 11;
|
||||
int opc_fconst_1 = 12;
|
||||
int opc_fconst_2 = 13;
|
||||
int opc_dconst_0 = 14;
|
||||
int opc_dconst_1 = 15;
|
||||
int opc_bipush = 16;
|
||||
int opc_sipush = 17;
|
||||
int opc_ldc = 18;
|
||||
int opc_ldc_w = 19;
|
||||
int opc_ldc2_w = 20;
|
||||
int opc_iload = 21;
|
||||
int opc_lload = 22;
|
||||
int opc_fload = 23;
|
||||
int opc_dload = 24;
|
||||
int opc_aload = 25;
|
||||
int opc_iload_0 = 26;
|
||||
int opc_iload_1 = 27;
|
||||
int opc_iload_2 = 28;
|
||||
int opc_iload_3 = 29;
|
||||
int opc_lload_0 = 30;
|
||||
int opc_lload_1 = 31;
|
||||
int opc_lload_2 = 32;
|
||||
int opc_lload_3 = 33;
|
||||
int opc_fload_0 = 34;
|
||||
int opc_fload_1 = 35;
|
||||
int opc_fload_2 = 36;
|
||||
int opc_fload_3 = 37;
|
||||
int opc_dload_0 = 38;
|
||||
int opc_dload_1 = 39;
|
||||
int opc_dload_2 = 40;
|
||||
int opc_dload_3 = 41;
|
||||
int opc_aload_0 = 42;
|
||||
int opc_aload_1 = 43;
|
||||
int opc_aload_2 = 44;
|
||||
int opc_aload_3 = 45;
|
||||
int opc_iaload = 46;
|
||||
int opc_laload = 47;
|
||||
int opc_faload = 48;
|
||||
int opc_daload = 49;
|
||||
int opc_aaload = 50;
|
||||
int opc_baload = 51;
|
||||
int opc_caload = 52;
|
||||
int opc_saload = 53;
|
||||
int opc_istore = 54;
|
||||
int opc_lstore = 55;
|
||||
int opc_fstore = 56;
|
||||
int opc_dstore = 57;
|
||||
int opc_astore = 58;
|
||||
int opc_istore_0 = 59;
|
||||
int opc_istore_1 = 60;
|
||||
int opc_istore_2 = 61;
|
||||
int opc_istore_3 = 62;
|
||||
int opc_lstore_0 = 63;
|
||||
int opc_lstore_1 = 64;
|
||||
int opc_lstore_2 = 65;
|
||||
int opc_lstore_3 = 66;
|
||||
int opc_fstore_0 = 67;
|
||||
int opc_fstore_1 = 68;
|
||||
int opc_fstore_2 = 69;
|
||||
int opc_fstore_3 = 70;
|
||||
int opc_dstore_0 = 71;
|
||||
int opc_dstore_1 = 72;
|
||||
int opc_dstore_2 = 73;
|
||||
int opc_dstore_3 = 74;
|
||||
int opc_astore_0 = 75;
|
||||
int opc_astore_1 = 76;
|
||||
int opc_astore_2 = 77;
|
||||
int opc_astore_3 = 78;
|
||||
int opc_iastore = 79;
|
||||
int opc_lastore = 80;
|
||||
int opc_fastore = 81;
|
||||
int opc_dastore = 82;
|
||||
int opc_aastore = 83;
|
||||
int opc_bastore = 84;
|
||||
int opc_castore = 85;
|
||||
int opc_sastore = 86;
|
||||
int opc_pop = 87;
|
||||
int opc_pop2 = 88;
|
||||
int opc_dup = 89;
|
||||
int opc_dup_x1 = 90;
|
||||
int opc_dup_x2 = 91;
|
||||
int opc_dup2 = 92;
|
||||
int opc_dup2_x1 = 93;
|
||||
int opc_dup2_x2 = 94;
|
||||
int opc_swap = 95;
|
||||
int opc_iadd = 96;
|
||||
int opc_ladd = 97;
|
||||
int opc_fadd = 98;
|
||||
int opc_dadd = 99;
|
||||
int opc_isub = 100;
|
||||
int opc_lsub = 101;
|
||||
int opc_fsub = 102;
|
||||
int opc_dsub = 103;
|
||||
int opc_imul = 104;
|
||||
int opc_lmul = 105;
|
||||
int opc_fmul = 106;
|
||||
int opc_dmul = 107;
|
||||
int opc_idiv = 108;
|
||||
int opc_ldiv = 109;
|
||||
int opc_fdiv = 110;
|
||||
int opc_ddiv = 111;
|
||||
int opc_irem = 112;
|
||||
int opc_lrem = 113;
|
||||
int opc_frem = 114;
|
||||
int opc_drem = 115;
|
||||
int opc_ineg = 116;
|
||||
int opc_lneg = 117;
|
||||
int opc_fneg = 118;
|
||||
int opc_dneg = 119;
|
||||
int opc_ishl = 120;
|
||||
int opc_lshl = 121;
|
||||
int opc_ishr = 122;
|
||||
int opc_lshr = 123;
|
||||
int opc_iushr = 124;
|
||||
int opc_lushr = 125;
|
||||
int opc_iand = 126;
|
||||
int opc_land = 127;
|
||||
int opc_ior = 128;
|
||||
int opc_lor = 129;
|
||||
int opc_ixor = 130;
|
||||
int opc_lxor = 131;
|
||||
int opc_iinc = 132;
|
||||
int opc_i2l = 133;
|
||||
int opc_i2f = 134;
|
||||
int opc_i2d = 135;
|
||||
int opc_l2i = 136;
|
||||
int opc_l2f = 137;
|
||||
int opc_l2d = 138;
|
||||
int opc_f2i = 139;
|
||||
int opc_f2l = 140;
|
||||
int opc_f2d = 141;
|
||||
int opc_d2i = 142;
|
||||
int opc_d2l = 143;
|
||||
int opc_d2f = 144;
|
||||
int opc_i2b = 145;
|
||||
int opc_i2c = 146;
|
||||
int opc_i2s = 147;
|
||||
int opc_lcmp = 148;
|
||||
int opc_fcmpl = 149;
|
||||
int opc_fcmpg = 150;
|
||||
int opc_dcmpl = 151;
|
||||
int opc_dcmpg = 152;
|
||||
int opc_ifeq = 153;
|
||||
int opc_ifne = 154;
|
||||
int opc_iflt = 155;
|
||||
int opc_ifge = 156;
|
||||
int opc_ifgt = 157;
|
||||
int opc_ifle = 158;
|
||||
int opc_if_icmpeq = 159;
|
||||
int opc_if_icmpne = 160;
|
||||
int opc_if_icmplt = 161;
|
||||
int opc_if_icmpge = 162;
|
||||
int opc_if_icmpgt = 163;
|
||||
int opc_if_icmple = 164;
|
||||
int opc_if_acmpeq = 165;
|
||||
int opc_if_acmpne = 166;
|
||||
int opc_goto = 167;
|
||||
int opc_jsr = 168;
|
||||
int opc_ret = 169;
|
||||
int opc_tableswitch = 170;
|
||||
int opc_lookupswitch = 171;
|
||||
int opc_ireturn = 172;
|
||||
int opc_lreturn = 173;
|
||||
int opc_freturn = 174;
|
||||
int opc_dreturn = 175;
|
||||
int opc_areturn = 176;
|
||||
int opc_return = 177;
|
||||
int opc_getstatic = 178;
|
||||
int opc_putstatic = 179;
|
||||
int opc_getfield = 180;
|
||||
int opc_putfield = 181;
|
||||
int opc_invokevirtual = 182;
|
||||
int opc_invokespecial = 183;
|
||||
int opc_invokestatic = 184;
|
||||
int opc_invokeinterface = 185;
|
||||
int opc_invokedynamic = 186;
|
||||
int opc_new = 187;
|
||||
int opc_newarray = 188;
|
||||
int opc_anewarray = 189;
|
||||
int opc_arraylength = 190;
|
||||
int opc_athrow = 191;
|
||||
int opc_checkcast = 192;
|
||||
int opc_instanceof = 193;
|
||||
int opc_monitorenter = 194;
|
||||
int opc_monitorexit = 195;
|
||||
int opc_wide = 196;
|
||||
int opc_multianewarray = 197;
|
||||
int opc_ifnull = 198;
|
||||
int opc_ifnonnull = 199;
|
||||
int opc_goto_w = 200;
|
||||
int opc_jsr_w = 201;
|
||||
int opc_breakpoint = 202;
|
||||
|
||||
/* Opcode Names */
|
||||
String opcNames[] = {
|
||||
"nop",
|
||||
"aconst_null",
|
||||
"iconst_m1",
|
||||
"iconst_0",
|
||||
"iconst_1",
|
||||
"iconst_2",
|
||||
"iconst_3",
|
||||
"iconst_4",
|
||||
"iconst_5",
|
||||
"lconst_0",
|
||||
"lconst_1",
|
||||
"fconst_0",
|
||||
"fconst_1",
|
||||
"fconst_2",
|
||||
"dconst_0",
|
||||
"dconst_1",
|
||||
"bipush",
|
||||
"sipush",
|
||||
"ldc",
|
||||
"ldc_w",
|
||||
"ldc2_w",
|
||||
"iload",
|
||||
"lload",
|
||||
"fload",
|
||||
"dload",
|
||||
"aload",
|
||||
"iload_0",
|
||||
"iload_1",
|
||||
"iload_2",
|
||||
"iload_3",
|
||||
"lload_0",
|
||||
"lload_1",
|
||||
"lload_2",
|
||||
"lload_3",
|
||||
"fload_0",
|
||||
"fload_1",
|
||||
"fload_2",
|
||||
"fload_3",
|
||||
"dload_0",
|
||||
"dload_1",
|
||||
"dload_2",
|
||||
"dload_3",
|
||||
"aload_0",
|
||||
"aload_1",
|
||||
"aload_2",
|
||||
"aload_3",
|
||||
"iaload",
|
||||
"laload",
|
||||
"faload",
|
||||
"daload",
|
||||
"aaload",
|
||||
"baload",
|
||||
"caload",
|
||||
"saload",
|
||||
"istore",
|
||||
"lstore",
|
||||
"fstore",
|
||||
"dstore",
|
||||
"astore",
|
||||
"istore_0",
|
||||
"istore_1",
|
||||
"istore_2",
|
||||
"istore_3",
|
||||
"lstore_0",
|
||||
"lstore_1",
|
||||
"lstore_2",
|
||||
"lstore_3",
|
||||
"fstore_0",
|
||||
"fstore_1",
|
||||
"fstore_2",
|
||||
"fstore_3",
|
||||
"dstore_0",
|
||||
"dstore_1",
|
||||
"dstore_2",
|
||||
"dstore_3",
|
||||
"astore_0",
|
||||
"astore_1",
|
||||
"astore_2",
|
||||
"astore_3",
|
||||
"iastore",
|
||||
"lastore",
|
||||
"fastore",
|
||||
"dastore",
|
||||
"aastore",
|
||||
"bastore",
|
||||
"castore",
|
||||
"sastore",
|
||||
"pop",
|
||||
"pop2",
|
||||
"dup",
|
||||
"dup_x1",
|
||||
"dup_x2",
|
||||
"dup2",
|
||||
"dup2_x1",
|
||||
"dup2_x2",
|
||||
"swap",
|
||||
"iadd",
|
||||
"ladd",
|
||||
"fadd",
|
||||
"dadd",
|
||||
"isub",
|
||||
"lsub",
|
||||
"fsub",
|
||||
"dsub",
|
||||
"imul",
|
||||
"lmul",
|
||||
"fmul",
|
||||
"dmul",
|
||||
"idiv",
|
||||
"ldiv",
|
||||
"fdiv",
|
||||
"ddiv",
|
||||
"irem",
|
||||
"lrem",
|
||||
"frem",
|
||||
"drem",
|
||||
"ineg",
|
||||
"lneg",
|
||||
"fneg",
|
||||
"dneg",
|
||||
"ishl",
|
||||
"lshl",
|
||||
"ishr",
|
||||
"lshr",
|
||||
"iushr",
|
||||
"lushr",
|
||||
"iand",
|
||||
"land",
|
||||
"ior",
|
||||
"lor",
|
||||
"ixor",
|
||||
"lxor",
|
||||
"iinc",
|
||||
"i2l",
|
||||
"i2f",
|
||||
"i2d",
|
||||
"l2i",
|
||||
"l2f",
|
||||
"l2d",
|
||||
"f2i",
|
||||
"f2l",
|
||||
"f2d",
|
||||
"d2i",
|
||||
"d2l",
|
||||
"d2f",
|
||||
"i2b",
|
||||
"i2c",
|
||||
"i2s",
|
||||
"lcmp",
|
||||
"fcmpl",
|
||||
"fcmpg",
|
||||
"dcmpl",
|
||||
"dcmpg",
|
||||
"ifeq",
|
||||
"ifne",
|
||||
"iflt",
|
||||
"ifge",
|
||||
"ifgt",
|
||||
"ifle",
|
||||
"if_icmpeq",
|
||||
"if_icmpne",
|
||||
"if_icmplt",
|
||||
"if_icmpge",
|
||||
"if_icmpgt",
|
||||
"if_icmple",
|
||||
"if_acmpeq",
|
||||
"if_acmpne",
|
||||
"goto",
|
||||
"jsr",
|
||||
"ret",
|
||||
"tableswitch",
|
||||
"lookupswitch",
|
||||
"ireturn",
|
||||
"lreturn",
|
||||
"freturn",
|
||||
"dreturn",
|
||||
"areturn",
|
||||
"return",
|
||||
"getstatic",
|
||||
"putstatic",
|
||||
"getfield",
|
||||
"putfield",
|
||||
"invokevirtual",
|
||||
"invokespecial",
|
||||
"invokestatic",
|
||||
"invokeinterface",
|
||||
"invokedynamic",
|
||||
"new",
|
||||
"newarray",
|
||||
"anewarray",
|
||||
"arraylength",
|
||||
"athrow",
|
||||
"checkcast",
|
||||
"instanceof",
|
||||
"monitorenter",
|
||||
"monitorexit",
|
||||
"wide",
|
||||
"multianewarray",
|
||||
"ifnull",
|
||||
"ifnonnull",
|
||||
"goto_w",
|
||||
"jsr_w",
|
||||
"breakpoint"
|
||||
};
|
||||
|
||||
/* Opcode Lengths */
|
||||
int opcLengths[] = {
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
2,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
2,
|
||||
99,
|
||||
99,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
5,
|
||||
5,
|
||||
3,
|
||||
2,
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
3,
|
||||
3,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
4,
|
||||
3,
|
||||
3,
|
||||
5,
|
||||
5,
|
||||
1
|
||||
};
|
||||
|
||||
}
|
||||
1341
jdkSrc/jdk8/sun/tools/java/Scanner.java
Normal file
1341
jdkSrc/jdk8/sun/tools/java/Scanner.java
Normal file
File diff suppressed because it is too large
Load Diff
242
jdkSrc/jdk8/sun/tools/java/ScannerInputReader.java
Normal file
242
jdkSrc/jdk8/sun/tools/java/ScannerInputReader.java
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (c) 1995, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FilterReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* An input stream for java programs. The stream treats either "\n", "\r"
|
||||
* or "\r\n" as the end of a line, it always returns \n. It also parses
|
||||
* UNICODE characters expressed as \uffff. However, if it sees "\\", the
|
||||
* second slash cannot begin a unicode sequence. It keeps track of the current
|
||||
* position in the input stream.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
|
||||
public
|
||||
class ScannerInputReader extends FilterReader implements Constants {
|
||||
// A note. This class does not really properly subclass FilterReader.
|
||||
// Since this class only overrides the single character read method,
|
||||
// and not the multi-character read method, any use of the latter
|
||||
// will not work properly. Any attempt to use this code outside of
|
||||
// the compiler should take that into account.
|
||||
//
|
||||
// For efficiency, it might be worth moving this code to Scanner and
|
||||
// getting rid of this class.
|
||||
|
||||
Environment env;
|
||||
long pos;
|
||||
|
||||
private long chpos;
|
||||
private int pushBack = -1;
|
||||
|
||||
public ScannerInputReader(Environment env, InputStream in)
|
||||
throws UnsupportedEncodingException
|
||||
{
|
||||
// ScannerInputStream has been modified to no longer use
|
||||
// BufferedReader. It now does its own buffering for
|
||||
// performance.
|
||||
super(env.getCharacterEncoding() != null ?
|
||||
new InputStreamReader(in, env.getCharacterEncoding()) :
|
||||
new InputStreamReader(in));
|
||||
|
||||
// Start out the buffer empty.
|
||||
currentIndex = 0;
|
||||
numChars = 0;
|
||||
|
||||
this.env = env;
|
||||
chpos = Scanner.LINEINC;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Buffering code.
|
||||
|
||||
// The size of our buffer.
|
||||
private static final int BUFFERLEN = 10 * 1024;
|
||||
|
||||
// A character buffer.
|
||||
private final char[] buffer = new char[BUFFERLEN];
|
||||
|
||||
// The index of the next character to be "read" from the buffer.
|
||||
private int currentIndex;
|
||||
|
||||
// The number of characters in the buffer. -1 if EOF is reached.
|
||||
private int numChars;
|
||||
|
||||
/**
|
||||
* Get the next character from our buffer.
|
||||
* Note: this method has been inlined by hand in the `read' method
|
||||
* below. Any changes made to this method should be equally applied
|
||||
* to that code.
|
||||
*/
|
||||
private int getNextChar() throws IOException {
|
||||
// Check to see if we have either run out of characters in our
|
||||
// buffer or gotten to EOF on a previous call.
|
||||
if (currentIndex >= numChars) {
|
||||
numChars = in.read(buffer);
|
||||
if (numChars == -1) {
|
||||
// We have reached EOF.
|
||||
return -1;
|
||||
}
|
||||
|
||||
// No EOF. currentIndex points to first char in buffer.
|
||||
currentIndex = 0;
|
||||
}
|
||||
|
||||
return buffer[currentIndex++];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
public int read(char[] buffer, int off, int len) {
|
||||
throw new CompilerError(
|
||||
"ScannerInputReader is not a fully implemented reader.");
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
pos = chpos;
|
||||
chpos += Scanner.OFFSETINC;
|
||||
|
||||
int c = pushBack;
|
||||
if (c == -1) {
|
||||
getchar: try {
|
||||
// Here the call...
|
||||
// c = getNextChar();
|
||||
// has been inlined by hand for performance.
|
||||
|
||||
if (currentIndex >= numChars) {
|
||||
numChars = in.read(buffer);
|
||||
if (numChars == -1) {
|
||||
// We have reached EOF.
|
||||
c = -1;
|
||||
break getchar;
|
||||
}
|
||||
|
||||
// No EOF. currentIndex points to first char in buffer.
|
||||
currentIndex = 0;
|
||||
}
|
||||
c = buffer[currentIndex++];
|
||||
|
||||
} catch (java.io.CharConversionException e) {
|
||||
env.error(pos, "invalid.encoding.char");
|
||||
// this is fatal error
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
pushBack = -1;
|
||||
}
|
||||
|
||||
// parse special characters
|
||||
switch (c) {
|
||||
case -2:
|
||||
// -2 is a special code indicating a pushback of a backslash that
|
||||
// definitely isn't the start of a unicode sequence.
|
||||
return '\\';
|
||||
|
||||
case '\\':
|
||||
if ((c = getNextChar()) != 'u') {
|
||||
pushBack = (c == '\\' ? -2 : c);
|
||||
return '\\';
|
||||
}
|
||||
// we have a unicode sequence
|
||||
chpos += Scanner.OFFSETINC;
|
||||
while ((c = getNextChar()) == 'u') {
|
||||
chpos += Scanner.OFFSETINC;
|
||||
}
|
||||
|
||||
// unicode escape sequence
|
||||
int d = 0;
|
||||
for (int i = 0 ; i < 4 ; i++, chpos += Scanner.OFFSETINC, c = getNextChar()) {
|
||||
switch (c) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
d = (d << 4) + c - '0';
|
||||
break;
|
||||
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
d = (d << 4) + 10 + c - 'a';
|
||||
break;
|
||||
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
d = (d << 4) + 10 + c - 'A';
|
||||
break;
|
||||
|
||||
default:
|
||||
env.error(pos, "invalid.escape.char");
|
||||
pushBack = c;
|
||||
return d;
|
||||
}
|
||||
}
|
||||
pushBack = c;
|
||||
|
||||
// To read the following line, switch \ and /...
|
||||
// Handle /u000a, /u000A, /u000d, /u000D properly as
|
||||
// line terminators as per JLS 3.4, even though they are encoded
|
||||
// (this properly respects the order given in JLS 3.2).
|
||||
switch (d) {
|
||||
case '\n':
|
||||
chpos += Scanner.LINEINC;
|
||||
return '\n';
|
||||
case '\r':
|
||||
if ((c = getNextChar()) != '\n') {
|
||||
pushBack = c;
|
||||
} else {
|
||||
chpos += Scanner.OFFSETINC;
|
||||
}
|
||||
chpos += Scanner.LINEINC;
|
||||
return '\n';
|
||||
default:
|
||||
return d;
|
||||
}
|
||||
|
||||
case '\n':
|
||||
chpos += Scanner.LINEINC;
|
||||
return '\n';
|
||||
|
||||
case '\r':
|
||||
if ((c = getNextChar()) != '\n') {
|
||||
pushBack = c;
|
||||
} else {
|
||||
chpos += Scanner.OFFSETINC;
|
||||
}
|
||||
chpos += Scanner.LINEINC;
|
||||
return '\n';
|
||||
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
39
jdkSrc/jdk8/sun/tools/java/SyntaxError.java
Normal file
39
jdkSrc/jdk8/sun/tools/java/SyntaxError.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
/**
|
||||
* Syntax errors, should always be caught inside the
|
||||
* parser for error recovery.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
|
||||
public
|
||||
class SyntaxError extends Exception {
|
||||
}
|
||||
455
jdkSrc/jdk8/sun/tools/java/Type.java
Normal file
455
jdkSrc/jdk8/sun/tools/java/Type.java
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.java;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* This class represents an Java Type.<p>
|
||||
*
|
||||
* It encapsulates an Java type signature and it provides
|
||||
* quick access to the components of the type. Note that
|
||||
* all types are hashed into a hashtable (typeHash), that
|
||||
* means that each distinct type is only allocated once,
|
||||
* saving space and making equality checks cheap.<p>
|
||||
*
|
||||
* For simple types use the constants defined in this class.
|
||||
* (Type.tInt, Type.tShort, ...). To create complex types use
|
||||
* the static methods Type.tArray, Type.tMethod or Type.tClass.
|
||||
*
|
||||
* For classes, arrays and method types a sub class of class
|
||||
* type is created which defines the extra type components.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @see ArrayType
|
||||
* @see ClassType
|
||||
* @see MethodType
|
||||
* @author Arthur van Hoff
|
||||
*/
|
||||
public
|
||||
class Type implements Constants {
|
||||
/**
|
||||
* This hashtable is used to cache types
|
||||
*/
|
||||
private static final Hashtable typeHash = new Hashtable(231);
|
||||
|
||||
/**
|
||||
* The TypeCode of this type. The value of this field is one
|
||||
* of the TC_* contant values defined in Constants.
|
||||
* @see Constants
|
||||
*/
|
||||
protected int typeCode;
|
||||
|
||||
/**
|
||||
* The TypeSignature of this type. This type signature is
|
||||
* equivalent to the runtime type signatures used by the
|
||||
* interpreter.
|
||||
*/
|
||||
protected String typeSig;
|
||||
|
||||
/*
|
||||
* Predefined types.
|
||||
*/
|
||||
public static final Type noArgs[] = new Type[0];
|
||||
public static final Type tError = new Type(TC_ERROR, "?");
|
||||
public static final Type tPackage = new Type(TC_ERROR, ".");
|
||||
public static final Type tNull = new Type(TC_NULL, "*");
|
||||
public static final Type tVoid = new Type(TC_VOID, SIG_VOID);
|
||||
public static final Type tBoolean = new Type(TC_BOOLEAN, SIG_BOOLEAN);
|
||||
public static final Type tByte = new Type(TC_BYTE, SIG_BYTE);
|
||||
public static final Type tChar = new Type(TC_CHAR, SIG_CHAR);
|
||||
public static final Type tShort = new Type(TC_SHORT, SIG_SHORT);
|
||||
public static final Type tInt = new Type(TC_INT, SIG_INT);
|
||||
public static final Type tFloat = new Type(TC_FLOAT, SIG_FLOAT);
|
||||
public static final Type tLong = new Type(TC_LONG, SIG_LONG);
|
||||
public static final Type tDouble = new Type(TC_DOUBLE, SIG_DOUBLE);
|
||||
public static final Type tObject = Type.tClass(idJavaLangObject);
|
||||
public static final Type tClassDesc = Type.tClass(idJavaLangClass);
|
||||
public static final Type tString = Type.tClass(idJavaLangString);
|
||||
public static final Type tCloneable = Type.tClass(idJavaLangCloneable);
|
||||
public static final Type tSerializable = Type.tClass(idJavaIoSerializable);
|
||||
|
||||
/**
|
||||
* Create a type given a typecode and a type signature.
|
||||
*/
|
||||
protected Type(int typeCode, String typeSig) {
|
||||
this.typeCode = typeCode;
|
||||
this.typeSig = typeSig;
|
||||
typeHash.put(typeSig, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Java type signature.
|
||||
*/
|
||||
public final String getTypeSignature() {
|
||||
return typeSig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type code.
|
||||
*/
|
||||
public final int getTypeCode() {
|
||||
return typeCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type mask. The bits in this mask correspond
|
||||
* to the TM_* constants defined in Constants. Only one bit
|
||||
* is set at a type.
|
||||
* @see Constants
|
||||
*/
|
||||
public final int getTypeMask() {
|
||||
return 1 << typeCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a certain type.
|
||||
*/
|
||||
public final boolean isType(int tc) {
|
||||
return typeCode == tc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this is the bogus type "array of void"
|
||||
*
|
||||
* Although this highly degenerate "type" is not constructable from
|
||||
* the grammar, the Parser accepts it. Rather than monkey with the
|
||||
* Parser, we check for the bogus type at specific points and give
|
||||
* a nice error.
|
||||
*/
|
||||
public boolean isVoidArray() {
|
||||
// a void type is not a void array.
|
||||
if (!isType(TC_ARRAY)) {
|
||||
return false;
|
||||
}
|
||||
// If this is an array, find out what its element type is.
|
||||
Type type = this;
|
||||
while (type.isType(TC_ARRAY))
|
||||
type = type.getElementType();
|
||||
|
||||
return type.isType(TC_VOID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check for a certain set of types.
|
||||
*/
|
||||
public final boolean inMask(int tm) {
|
||||
return ((1 << typeCode) & tm) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an array type.
|
||||
*/
|
||||
public static synchronized Type tArray(Type elem) {
|
||||
String sig = new String(SIG_ARRAY + elem.getTypeSignature());
|
||||
Type t = (Type)typeHash.get(sig);
|
||||
if (t == null) {
|
||||
t = new ArrayType(sig, elem);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the element type of an array type. Only works
|
||||
* for array types.
|
||||
*/
|
||||
public Type getElementType() {
|
||||
throw new CompilerError("getElementType");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the array dimension. Only works for
|
||||
* array types.
|
||||
*/
|
||||
public int getArrayDimension() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a class type.
|
||||
* @arg className the fully qualified class name
|
||||
*/
|
||||
public static synchronized Type tClass(Identifier className) {
|
||||
if (className.isInner()) {
|
||||
Type t = tClass(mangleInnerType(className));
|
||||
if (t.getClassName() != className)
|
||||
// Somebody got here first with a mangled name.
|
||||
// (Perhaps it came from a binary.)
|
||||
changeClassName(t.getClassName(), className);
|
||||
return t;
|
||||
}
|
||||
// see if we've cached the object in the Identifier
|
||||
if (className.typeObject != null) {
|
||||
return className.typeObject;
|
||||
}
|
||||
String sig =
|
||||
new String(SIG_CLASS +
|
||||
className.toString().replace('.', SIGC_PACKAGE) +
|
||||
SIG_ENDCLASS);
|
||||
Type t = (Type)typeHash.get(sig);
|
||||
if (t == null) {
|
||||
t = new ClassType(sig, className);
|
||||
}
|
||||
|
||||
className.typeObject = t; // cache the Type object in the Identifier
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ClassName. Only works on class types.
|
||||
*/
|
||||
public Identifier getClassName() {
|
||||
throw new CompilerError("getClassName:" + this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an inner identifier, return the non-inner, mangled
|
||||
* representation used to manage signatures.
|
||||
*
|
||||
* Note: It is changed to 'public' for Jcov file generation.
|
||||
* (see Assembler.java)
|
||||
*/
|
||||
|
||||
public static Identifier mangleInnerType(Identifier className) {
|
||||
// Map "pkg.Foo. Bar" to "pkg.Foo$Bar".
|
||||
if (!className.isInner()) return className;
|
||||
Identifier mname = Identifier.lookup(
|
||||
className.getFlatName().toString().
|
||||
replace('.', SIGC_INNERCLASS) );
|
||||
if (mname.isInner()) throw new CompilerError("mangle "+mname);
|
||||
return Identifier.lookup(className.getQualifier(), mname);
|
||||
}
|
||||
|
||||
/**
|
||||
* We have learned that a signature means something other
|
||||
* that what we thought it meant. Live with it: Change all
|
||||
* affected data structures to reflect the new name of the old type.
|
||||
* <p>
|
||||
* (This is necessary because of an ambiguity between the
|
||||
* low-level signatures of inner types and their manglings.
|
||||
* Note that the latter are also valid class names.)
|
||||
*/
|
||||
static void changeClassName(Identifier oldName, Identifier newName) {
|
||||
// Note: If we are upgrading "pkg.Foo$Bar" to "pkg.Foo. Bar",
|
||||
// we assume someone else will come along and deal with any types
|
||||
// inner within Bar. So, there's only one change to make.
|
||||
((ClassType)Type.tClass(oldName)).className = newName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a method type with no arguments.
|
||||
*/
|
||||
public static synchronized Type tMethod(Type ret) {
|
||||
return tMethod(ret, noArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a method type with arguments.
|
||||
*/
|
||||
public static synchronized Type tMethod(Type returnType, Type argTypes[]) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append(SIG_METHOD);
|
||||
for (int i = 0 ; i < argTypes.length ; i++) {
|
||||
buf.append(argTypes[i].getTypeSignature());
|
||||
}
|
||||
buf.append(SIG_ENDMETHOD);
|
||||
buf.append(returnType.getTypeSignature());
|
||||
|
||||
String sig = buf.toString();
|
||||
Type t = (Type)typeHash.get(sig);
|
||||
if (t == null) {
|
||||
t = new MethodType(sig, returnType, argTypes);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the return type. Only works for method types.
|
||||
*/
|
||||
public Type getReturnType() {
|
||||
throw new CompilerError("getReturnType");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the argument types. Only works for method types.
|
||||
*/
|
||||
public Type getArgumentTypes()[] {
|
||||
throw new CompilerError("getArgumentTypes");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Type from an Java type signature.
|
||||
* @exception CompilerError invalid type signature.
|
||||
*/
|
||||
public static synchronized Type tType(String sig) {
|
||||
Type t = (Type)typeHash.get(sig);
|
||||
if (t != null) {
|
||||
return t;
|
||||
}
|
||||
|
||||
switch (sig.charAt(0)) {
|
||||
case SIGC_ARRAY:
|
||||
return Type.tArray(tType(sig.substring(1)));
|
||||
|
||||
case SIGC_CLASS:
|
||||
return Type.tClass(Identifier.lookup(sig.substring(1, sig.length() - 1).replace(SIGC_PACKAGE, '.')));
|
||||
|
||||
case SIGC_METHOD: {
|
||||
Type argv[] = new Type[8];
|
||||
int argc = 0;
|
||||
int i, j;
|
||||
|
||||
for (i = 1 ; sig.charAt(i) != SIGC_ENDMETHOD ; i = j) {
|
||||
for (j = i ; sig.charAt(j) == SIGC_ARRAY ; j++);
|
||||
if (sig.charAt(j++) == SIGC_CLASS) {
|
||||
while (sig.charAt(j++) != SIGC_ENDCLASS);
|
||||
}
|
||||
if (argc == argv.length) {
|
||||
Type newargv[] = new Type[argc * 2];
|
||||
System.arraycopy(argv, 0, newargv, 0, argc);
|
||||
argv = newargv;
|
||||
}
|
||||
argv[argc++] = tType(sig.substring(i, j));
|
||||
}
|
||||
|
||||
Type argtypes[] = new Type[argc];
|
||||
System.arraycopy(argv, 0, argtypes, 0, argc);
|
||||
return Type.tMethod(tType(sig.substring(i + 1)), argtypes);
|
||||
}
|
||||
}
|
||||
|
||||
throw new CompilerError("invalid TypeSignature:" + sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the type arguments are the same.
|
||||
* @return true if both types are method types and the
|
||||
* argument types are identical.
|
||||
*/
|
||||
public boolean equalArguments(Type t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the amount of space this type takes up on the
|
||||
* Java operand stack. For a method this is equal to the
|
||||
* total space taken up by the arguments.
|
||||
*/
|
||||
public int stackSize() {
|
||||
switch (typeCode) {
|
||||
case TC_ERROR:
|
||||
case TC_VOID:
|
||||
return 0;
|
||||
case TC_BOOLEAN:
|
||||
case TC_BYTE:
|
||||
case TC_SHORT:
|
||||
case TC_CHAR:
|
||||
case TC_INT:
|
||||
case TC_FLOAT:
|
||||
case TC_ARRAY:
|
||||
case TC_CLASS:
|
||||
return 1;
|
||||
case TC_LONG:
|
||||
case TC_DOUBLE:
|
||||
return 2;
|
||||
}
|
||||
throw new CompilerError("stackSize " + toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type code offset. This offset can be added to
|
||||
* an opcode to get the right opcode type. Most opcodes
|
||||
* are ordered: int, long, float, double, array. For
|
||||
* example: iload, lload fload, dload, aload. So the
|
||||
* appropriate opcode is iadd + type.getTypeCodeOffset().
|
||||
*/
|
||||
public int getTypeCodeOffset() {
|
||||
switch (typeCode) {
|
||||
case TC_BOOLEAN:
|
||||
case TC_BYTE:
|
||||
case TC_SHORT:
|
||||
case TC_CHAR:
|
||||
case TC_INT:
|
||||
return 0;
|
||||
case TC_LONG:
|
||||
return 1;
|
||||
case TC_FLOAT:
|
||||
return 2;
|
||||
case TC_DOUBLE:
|
||||
return 3;
|
||||
case TC_NULL:
|
||||
case TC_ARRAY:
|
||||
case TC_CLASS:
|
||||
return 4;
|
||||
}
|
||||
throw new CompilerError("invalid typecode: " + typeCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Type to a string, if abbrev is true class names are
|
||||
* not fully qualified, if ret is true the return type is included.
|
||||
*/
|
||||
public String typeString(String id, boolean abbrev, boolean ret) {
|
||||
String s = null;
|
||||
|
||||
switch (typeCode) {
|
||||
case TC_NULL: s = "null"; break;
|
||||
case TC_VOID: s = "void"; break;
|
||||
case TC_BOOLEAN: s = "boolean"; break;
|
||||
case TC_BYTE: s = "byte"; break;
|
||||
case TC_CHAR: s = "char"; break;
|
||||
case TC_SHORT: s = "short"; break;
|
||||
case TC_INT: s = "int"; break;
|
||||
case TC_LONG: s = "long"; break;
|
||||
case TC_FLOAT: s = "float"; break;
|
||||
case TC_DOUBLE: s = "double"; break;
|
||||
case TC_ERROR: s = "<error>";
|
||||
if (this==tPackage) s = "<package>";
|
||||
break;
|
||||
default: s = "unknown";
|
||||
}
|
||||
|
||||
return (id.length() > 0) ? s + " " + id : s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a type string, given an identifier.
|
||||
*/
|
||||
public String typeString(String id) {
|
||||
return typeString(id, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a String
|
||||
*/
|
||||
public String toString() {
|
||||
return typeString("", false, true);
|
||||
}
|
||||
}
|
||||
1372
jdkSrc/jdk8/sun/tools/javac/BatchEnvironment.java
Normal file
1372
jdkSrc/jdk8/sun/tools/javac/BatchEnvironment.java
Normal file
File diff suppressed because it is too large
Load Diff
313
jdkSrc/jdk8/sun/tools/javac/BatchParser.java
Normal file
313
jdkSrc/jdk8/sun/tools/javac/BatchParser.java
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.javac;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import sun.tools.tree.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* Batch file parser, this needs more work.
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
@Deprecated
|
||||
public
|
||||
class BatchParser extends Parser {
|
||||
/**
|
||||
* The current package
|
||||
*/
|
||||
protected Identifier pkg;
|
||||
|
||||
/**
|
||||
* The current imports
|
||||
*/
|
||||
protected Imports imports;
|
||||
|
||||
/**
|
||||
* The classes defined in this file
|
||||
*/
|
||||
protected Vector classes;
|
||||
|
||||
|
||||
/**
|
||||
* The current class
|
||||
*/
|
||||
protected SourceClass sourceClass;
|
||||
|
||||
/**
|
||||
* The toplevel environment
|
||||
*/
|
||||
protected Environment toplevelEnv;
|
||||
|
||||
/**
|
||||
* Create a batch file parser
|
||||
*/
|
||||
public BatchParser(Environment env, InputStream in) throws IOException {
|
||||
super(env, in);
|
||||
|
||||
imports = new Imports(env);
|
||||
classes = new Vector();
|
||||
toplevelEnv = imports.newEnvironment(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Package declaration
|
||||
*/
|
||||
public void packageDeclaration(long where, IdentifierToken t) {
|
||||
Identifier nm = t.getName();
|
||||
//System.out.println("package " + nm);
|
||||
if (pkg == null) {
|
||||
// This code has been changed to pass an IdentifierToken,
|
||||
// rather than an Identifier, to setCurrentPackage(). Imports
|
||||
// now needs the location of the token.
|
||||
pkg = t.getName();
|
||||
imports.setCurrentPackage(t);
|
||||
} else {
|
||||
env.error(where, "package.repeated");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Import class
|
||||
*/
|
||||
public void importClass(long pos, IdentifierToken t) {
|
||||
//System.out.println("import class " + t);
|
||||
imports.addClass(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import package
|
||||
*/
|
||||
public void importPackage(long pos, IdentifierToken t) {
|
||||
//System.out.println("import package " + t);
|
||||
imports.addPackage(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define class
|
||||
*/
|
||||
public ClassDefinition beginClass(long where, String doc, int mod,
|
||||
IdentifierToken t,
|
||||
IdentifierToken sup,
|
||||
IdentifierToken interfaces[]) {
|
||||
|
||||
// If this class is nested, the modifier bits set here will
|
||||
// be copied into the 'SourceMember' object for the inner class
|
||||
// created during the call to 'makeClassDefinition' below.
|
||||
// When writing the class file, we will look there for the
|
||||
// 'untransformed' modifiers. The modifiers in the ClassDefinition
|
||||
// object will end up as the 'transformed' modifiers. Note that
|
||||
// there are some bits set here that are not legal class modifiers
|
||||
// according to the JVMS, e.g., M_PRIVATE and M_STATIC. These are
|
||||
// masked off while writing the class file, but are preserved in
|
||||
// the InnerClasses attributes.
|
||||
|
||||
if (tracing) toplevelEnv.dtEnter("beginClass: " + sourceClass);
|
||||
|
||||
SourceClass outerClass = sourceClass;
|
||||
|
||||
if (outerClass == null && pkg != null) {
|
||||
t = new IdentifierToken(t.getWhere(),
|
||||
Identifier.lookup(pkg, t.getName()));
|
||||
}
|
||||
|
||||
// The defaults for anonymous and local classes should be documented!
|
||||
|
||||
if ((mod & M_ANONYMOUS) != 0) {
|
||||
mod |= (M_FINAL | M_PRIVATE);
|
||||
}
|
||||
if ((mod & M_LOCAL) != 0) {
|
||||
mod |= M_PRIVATE;
|
||||
}
|
||||
|
||||
// Certain modifiers are implied as follows:
|
||||
//
|
||||
// 1. Any interface (nested or not) is implicitly deemed to be abstract,
|
||||
// whether it is explicitly marked so or not. (Java 1.0.)
|
||||
// 2. A interface which is a member of a type is implicitly deemed to
|
||||
// be static, whether it is explicitly marked so or not. (InnerClasses)
|
||||
// 3a. A type which is a member of an interface is implicitly deemed
|
||||
// to be public, whether it is explicitly marked so or not. (InnerClasses)
|
||||
// 3b. A type which is a member of an interface is implicitly deemed
|
||||
// to be static, whether it is explicitly marked so or not. (InnerClasses)
|
||||
|
||||
if ((mod & M_INTERFACE) != 0) {
|
||||
// Rule 1.
|
||||
mod |= M_ABSTRACT;
|
||||
if (outerClass != null) {
|
||||
// Rule 2.
|
||||
mod |= M_STATIC;
|
||||
}
|
||||
}
|
||||
|
||||
if (outerClass != null && outerClass.isInterface()) {
|
||||
// Rule 3a.
|
||||
// For interface members, neither 'private' nor 'protected'
|
||||
// are legal modifiers. We avoid setting M_PUBLIC in some
|
||||
// cases in order to avoid interfering with error detection
|
||||
// and reporting. This is patched up, after reporting an
|
||||
// error, by 'SourceClass.addMember'.
|
||||
if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)
|
||||
mod |= M_PUBLIC;
|
||||
// Rule 3b.
|
||||
mod |= M_STATIC;
|
||||
}
|
||||
|
||||
// For nested classes, we must transform 'protected' to 'public'
|
||||
// and 'private' to package scope. This must be done later,
|
||||
// because any modifiers set here will be copied into the
|
||||
// 'MemberDefinition' for the nested class, which must represent
|
||||
// the original untransformed modifiers. Also, compile-time
|
||||
// checks should be performed against the actual, untransformed
|
||||
// modifiers. This is in contrast to transformations that implement
|
||||
// implicit modifiers, such as M_STATIC and M_FINAL for fields
|
||||
// of interfaces.
|
||||
|
||||
sourceClass = (SourceClass)
|
||||
toplevelEnv.makeClassDefinition(toplevelEnv, where, t,
|
||||
doc, mod, sup,
|
||||
interfaces, outerClass);
|
||||
|
||||
sourceClass.getClassDeclaration().setDefinition(sourceClass, CS_PARSED);
|
||||
env = new Environment(toplevelEnv, sourceClass);
|
||||
|
||||
if (tracing) toplevelEnv.dtEvent("beginClass: SETTING UP DEPENDENCIES");
|
||||
|
||||
// The code which adds artificial dependencies between
|
||||
// classes in the same source file has been moved to
|
||||
// BatchEnvironment#parseFile().
|
||||
|
||||
if (tracing) toplevelEnv.dtEvent("beginClass: ADDING TO CLASS LIST");
|
||||
|
||||
classes.addElement(sourceClass);
|
||||
|
||||
if (tracing) toplevelEnv.dtExit("beginClass: " + sourceClass);
|
||||
|
||||
return sourceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the current class under construction.
|
||||
*/
|
||||
public ClassDefinition getCurrentClass() {
|
||||
return sourceClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* End class
|
||||
*/
|
||||
public void endClass(long where, ClassDefinition c) {
|
||||
|
||||
if (tracing) toplevelEnv.dtEnter("endClass: " + sourceClass);
|
||||
|
||||
// c == sourceClass; don't bother to check
|
||||
sourceClass.setEndPosition(where);
|
||||
SourceClass outerClass = (SourceClass) sourceClass.getOuterClass();
|
||||
sourceClass = outerClass;
|
||||
env = toplevelEnv;
|
||||
if (sourceClass != null)
|
||||
env = new Environment(env, sourceClass);
|
||||
|
||||
if (tracing) toplevelEnv.dtExit("endClass: " + sourceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a method
|
||||
*/
|
||||
public void defineField(long where, ClassDefinition c,
|
||||
String doc, int mod, Type t,
|
||||
IdentifierToken name, IdentifierToken args[],
|
||||
IdentifierToken exp[], Node val) {
|
||||
// c == sourceClass; don't bother to check
|
||||
Identifier nm = name.getName();
|
||||
// Members that are nested classes are not created with 'defineField',
|
||||
// so these transformations do not apply to them. See 'beginClass' above.
|
||||
if (sourceClass.isInterface()) {
|
||||
// Members of interfaces are implicitly public.
|
||||
if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)
|
||||
// For interface members, neither 'private' nor 'protected'
|
||||
// are legal modifiers. Avoid setting M_PUBLIC in some cases
|
||||
// to avoid interfering with later error detection. This will
|
||||
// be fixed up after the error is reported.
|
||||
mod |= M_PUBLIC;
|
||||
// Methods of interfaces are implicitly abstract.
|
||||
// Fields of interfaces are implicitly static and final.
|
||||
if (t.isType(TC_METHOD)) {
|
||||
mod |= M_ABSTRACT;
|
||||
} else {
|
||||
mod |= M_STATIC | M_FINAL;
|
||||
}
|
||||
}
|
||||
if (nm.equals(idInit)) {
|
||||
// The parser reports "idInit" when in reality it has found
|
||||
// that there is no method name at all present.
|
||||
// So, decide if it's really a constructor, or a syntax error.
|
||||
Type rt = t.getReturnType();
|
||||
Identifier retname = !rt.isType(TC_CLASS) ? idStar /*no match*/
|
||||
: rt.getClassName();
|
||||
Identifier clsname = sourceClass.getLocalName();
|
||||
if (clsname.equals(retname)) {
|
||||
t = Type.tMethod(Type.tVoid, t.getArgumentTypes());
|
||||
} else if (clsname.equals(retname.getFlatName().getName())) {
|
||||
// It appears to be a constructor with spurious qualification.
|
||||
t = Type.tMethod(Type.tVoid, t.getArgumentTypes());
|
||||
env.error(where, "invalid.method.decl.qual");
|
||||
} else if (retname.isQualified() || retname.equals(idStar)) {
|
||||
// It appears to be a type name with no method name.
|
||||
env.error(where, "invalid.method.decl.name");
|
||||
return;
|
||||
} else {
|
||||
// We assume the type name is missing, even though the
|
||||
// simple name that's present might have been intended
|
||||
// to be a type: "String (){}" vs. "toString(){}".
|
||||
env.error(where, "invalid.method.decl");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (args == null && t.isType(TC_METHOD)) {
|
||||
args = new IdentifierToken[0];
|
||||
}
|
||||
|
||||
if (exp == null && t.isType(TC_METHOD)) {
|
||||
exp = new IdentifierToken[0];
|
||||
}
|
||||
|
||||
MemberDefinition f = env.makeMemberDefinition(env, where, sourceClass,
|
||||
doc, mod, t, nm,
|
||||
args, exp, val);
|
||||
if (env.dump()) {
|
||||
f.print(System.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
jdkSrc/jdk8/sun/tools/javac/CompilerMember.java
Normal file
67
jdkSrc/jdk8/sun/tools/javac/CompilerMember.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.javac;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import sun.tools.asm.Assembler;
|
||||
|
||||
/**
|
||||
* This class is used to represents fields while they are
|
||||
* being compiled
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
@Deprecated
|
||||
final
|
||||
class CompilerMember implements Comparable {
|
||||
MemberDefinition field;
|
||||
Assembler asm;
|
||||
Object value;
|
||||
String name;
|
||||
String sig;
|
||||
String key;
|
||||
|
||||
CompilerMember(MemberDefinition field, Assembler asm) {
|
||||
this.field = field;
|
||||
this.asm = asm;
|
||||
name = field.getName().toString();
|
||||
sig = field.getType().getTypeSignature();
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
CompilerMember cm = (CompilerMember) o;
|
||||
return getKey().compareTo(cm.getKey());
|
||||
}
|
||||
|
||||
String getKey() {
|
||||
if (key==null)
|
||||
key = name+sig;
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
42
jdkSrc/jdk8/sun/tools/javac/ErrorConsumer.java
Normal file
42
jdkSrc/jdk8/sun/tools/javac/ErrorConsumer.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.javac;
|
||||
|
||||
/**
|
||||
* Allows for easier parsing of errors and warnings from the compiler
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
@Deprecated
|
||||
public
|
||||
interface ErrorConsumer {
|
||||
public void pushError(String errorFileName,
|
||||
int line,
|
||||
String message,
|
||||
String referenceText, String referenceTextPointer);
|
||||
};
|
||||
49
jdkSrc/jdk8/sun/tools/javac/ErrorMessage.java
Normal file
49
jdkSrc/jdk8/sun/tools/javac/ErrorMessage.java
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.javac;
|
||||
|
||||
/**
|
||||
* A sorted list of error messages
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
@Deprecated
|
||||
final
|
||||
class ErrorMessage {
|
||||
long where;
|
||||
String message;
|
||||
ErrorMessage next;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
ErrorMessage(long where, String message) {
|
||||
this.where = where;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
751
jdkSrc/jdk8/sun/tools/javac/Main.java
Normal file
751
jdkSrc/jdk8/sun/tools/javac/Main.java
Normal file
@@ -0,0 +1,751 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.javac;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import sun.tools.util.CommandLine;
|
||||
// JCOV
|
||||
import sun.tools.asm.Assembler;
|
||||
// end JCOV
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/**
|
||||
* Main program of the Java compiler
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*
|
||||
* @deprecated As of J2SE 1.3, the preferred way to compile Java
|
||||
* language sources is by using the new compiler,
|
||||
* com.sun.tools.javac.Main.
|
||||
*/
|
||||
@Deprecated
|
||||
public
|
||||
class Main implements Constants {
|
||||
/**
|
||||
* Name of the program.
|
||||
*/
|
||||
String program;
|
||||
|
||||
/**
|
||||
* The stream where error message are printed.
|
||||
*/
|
||||
OutputStream out;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public Main(OutputStream out, String program) {
|
||||
this.out = out;
|
||||
this.program = program;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit status.
|
||||
* We introduce a separate integer status variable, and do not alter the
|
||||
* convention that 'compile' returns a boolean true upon a successful
|
||||
* compilation with no errors. (JavaTest relies on this.)
|
||||
*/
|
||||
|
||||
public static final int EXIT_OK = 0; // Compilation completed with no errors.
|
||||
public static final int EXIT_ERROR = 1; // Compilation completed but reported errors.
|
||||
public static final int EXIT_CMDERR = 2; // Bad command-line arguments and/or switches.
|
||||
public static final int EXIT_SYSERR = 3; // System error or resource exhaustion.
|
||||
public static final int EXIT_ABNORMAL = 4; // Compiler terminated abnormally.
|
||||
|
||||
private int exitStatus;
|
||||
|
||||
public int getExitStatus() {
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
public boolean compilationPerformedSuccessfully() {
|
||||
return exitStatus == EXIT_OK || exitStatus == EXIT_ERROR;
|
||||
}
|
||||
|
||||
public boolean compilationReportedErrors () {
|
||||
return exitStatus != EXIT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a message.
|
||||
*/
|
||||
private void output(String msg) {
|
||||
PrintStream out =
|
||||
this.out instanceof PrintStream ? (PrintStream)this.out
|
||||
: new PrintStream(this.out, true);
|
||||
out.println(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Top level error message. This method is called when the
|
||||
* environment could not be set up yet.
|
||||
*/
|
||||
private void error(String msg) {
|
||||
exitStatus = EXIT_CMDERR;
|
||||
output(getText(msg));
|
||||
}
|
||||
|
||||
private void error(String msg, String arg1) {
|
||||
exitStatus = EXIT_CMDERR;
|
||||
output(getText(msg, arg1));
|
||||
}
|
||||
|
||||
private void error(String msg, String arg1, String arg2) {
|
||||
exitStatus = EXIT_CMDERR;
|
||||
output(getText(msg, arg1, arg2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print usage message and make exit status an error.
|
||||
* Note: 'javac' invoked without any arguments is considered
|
||||
* be an error.
|
||||
*/
|
||||
public void usage_error() {
|
||||
error("main.usage", program);
|
||||
}
|
||||
|
||||
private static ResourceBundle messageRB;
|
||||
|
||||
/**
|
||||
* Initialize ResourceBundle
|
||||
*/
|
||||
static void initResource() {
|
||||
try {
|
||||
messageRB =
|
||||
ResourceBundle.getBundle("sun.tools.javac.resources.javac");
|
||||
} catch (MissingResourceException e) {
|
||||
throw new Error("Fatal: Resource for javac is missing");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get and format message string from resource
|
||||
*/
|
||||
public static String getText(String key) {
|
||||
return getText(key, (String)null);
|
||||
}
|
||||
|
||||
public static String getText(String key, int num) {
|
||||
return getText(key, Integer.toString(num));
|
||||
}
|
||||
|
||||
public static String getText(String key, String fixed) {
|
||||
return getText(key, fixed, null);
|
||||
}
|
||||
|
||||
public static String getText(String key, String fixed1, String fixed2) {
|
||||
return getText(key, fixed1, fixed2, null);
|
||||
}
|
||||
|
||||
public static String getText(String key, String fixed1,
|
||||
String fixed2, String fixed3) {
|
||||
if (messageRB == null) {
|
||||
initResource();
|
||||
}
|
||||
try {
|
||||
String message = messageRB.getString(key);
|
||||
return MessageFormat.format(message, fixed1, fixed2, fixed3);
|
||||
} catch (MissingResourceException e) {
|
||||
if (fixed1 == null) fixed1 = "null";
|
||||
if (fixed2 == null) fixed2 = "null";
|
||||
if (fixed3 == null) fixed3 = "null";
|
||||
String message = "JAVAC MESSAGE FILE IS BROKEN: key={0}, arguments={1}, {2}, {3}";
|
||||
return MessageFormat.format(message, key, fixed1, fixed2, fixed3);
|
||||
}
|
||||
}
|
||||
|
||||
// What major and minor version numbers to use for the -target flag.
|
||||
// This should grow every time the minor version number accepted by
|
||||
// the VM is incremented.
|
||||
private static final String[] releases = { "1.1", "1.2", "1.3", "1.4" };
|
||||
private static final short[] majorVersions = { 45, 46, 47, 48 };
|
||||
private static final short[] minorVersions = { 3, 0, 0, 0 };
|
||||
|
||||
/**
|
||||
* Run the compiler
|
||||
*/
|
||||
public synchronized boolean compile(String argv[]) {
|
||||
String sourcePathArg = null;
|
||||
String classPathArg = null;
|
||||
String sysClassPathArg = null;
|
||||
String extDirsArg = null;
|
||||
boolean verbosePath = false;
|
||||
|
||||
String targetArg = null;
|
||||
short majorVersion = JAVA_DEFAULT_VERSION;
|
||||
short minorVersion = JAVA_DEFAULT_MINOR_VERSION;
|
||||
|
||||
File destDir = null;
|
||||
//JCOV
|
||||
File covFile = null;
|
||||
String optJcov = "-Xjcov";
|
||||
String optJcovFile = "-Xjcov:file=";
|
||||
//end JCOV
|
||||
int flags = F_WARNINGS | F_DEBUG_LINES | F_DEBUG_SOURCE;
|
||||
long tm = System.currentTimeMillis();
|
||||
Vector v = new Vector();
|
||||
boolean nowrite = false;
|
||||
String props = null;
|
||||
String encoding = null;
|
||||
|
||||
// These flags are used to make sure conflicting -O and -g
|
||||
// options aren't given.
|
||||
String prior_g = null;
|
||||
String prior_O = null;
|
||||
|
||||
exitStatus = EXIT_OK;
|
||||
|
||||
// Pre-process command line for @file arguments
|
||||
try {
|
||||
argv = CommandLine.parse(argv);
|
||||
} catch (FileNotFoundException e) {
|
||||
error("javac.err.cant.read", e.getMessage());
|
||||
System.exit(1);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Parse arguments
|
||||
for (int i = 0 ; i < argv.length ; i++) {
|
||||
if (argv[i].equals("-g")) {
|
||||
if (prior_g!=null && !(prior_g.equals("-g")))
|
||||
error("main.conflicting.options", prior_g, "-g");
|
||||
prior_g = "-g";
|
||||
flags |= F_DEBUG_LINES;
|
||||
flags |= F_DEBUG_VARS;
|
||||
flags |= F_DEBUG_SOURCE;
|
||||
} else if (argv[i].equals("-g:none")) {
|
||||
if (prior_g!=null && !(prior_g.equals("-g:none")))
|
||||
error("main.conflicting.options", prior_g, "-g:none");
|
||||
prior_g = "-g:none";
|
||||
flags &= ~F_DEBUG_LINES;
|
||||
flags &= ~F_DEBUG_VARS;
|
||||
flags &= ~F_DEBUG_SOURCE;
|
||||
} else if (argv[i].startsWith("-g:")) {
|
||||
// We choose to have debugging options conflict even
|
||||
// if they amount to the same thing (for example,
|
||||
// -g:source,lines and -g:lines,source). However, multiple
|
||||
// debugging options are allowed if they are textually
|
||||
// identical.
|
||||
if (prior_g!=null && !(prior_g.equals(argv[i])))
|
||||
error("main.conflicting.options", prior_g, argv[i]);
|
||||
prior_g = argv[i];
|
||||
String args = argv[i].substring("-g:".length());
|
||||
flags &= ~F_DEBUG_LINES;
|
||||
flags &= ~F_DEBUG_VARS;
|
||||
flags &= ~F_DEBUG_SOURCE;
|
||||
while (true) {
|
||||
if (args.startsWith("lines")) {
|
||||
flags |= F_DEBUG_LINES;
|
||||
args = args.substring("lines".length());
|
||||
} else if (args.startsWith("vars")) {
|
||||
flags |= F_DEBUG_VARS;
|
||||
args = args.substring("vars".length());
|
||||
} else if (args.startsWith("source")) {
|
||||
flags |= F_DEBUG_SOURCE;
|
||||
args = args.substring("source".length());
|
||||
} else {
|
||||
error("main.bad.debug.option",argv[i]);
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
if (args.length() == 0) break;
|
||||
if (args.startsWith(","))
|
||||
args = args.substring(",".length());
|
||||
}
|
||||
} else if (argv[i].equals("-O")) {
|
||||
// -O is accepted for backward compatibility, but
|
||||
// is no longer effective. Use the undocumented
|
||||
// -XO option to get the old behavior.
|
||||
if (prior_O!=null && !(prior_O.equals("-O")))
|
||||
error("main.conflicting.options", prior_O, "-O");
|
||||
prior_O = "-O";
|
||||
} else if (argv[i].equals("-nowarn")) {
|
||||
flags &= ~F_WARNINGS;
|
||||
} else if (argv[i].equals("-deprecation")) {
|
||||
flags |= F_DEPRECATION;
|
||||
} else if (argv[i].equals("-verbose")) {
|
||||
flags |= F_VERBOSE;
|
||||
} else if (argv[i].equals("-nowrite")) {
|
||||
nowrite = true;
|
||||
} else if (argv[i].equals("-classpath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (classPathArg!=null) {
|
||||
error("main.option.already.seen","-classpath");
|
||||
}
|
||||
classPathArg = argv[++i];
|
||||
} else {
|
||||
error("main.option.requires.argument","-classpath");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else if (argv[i].equals("-sourcepath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (sourcePathArg != null) {
|
||||
error("main.option.already.seen","-sourcepath");
|
||||
}
|
||||
sourcePathArg = argv[++i];
|
||||
} else {
|
||||
error("main.option.requires.argument","-sourcepath");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else if (argv[i].equals("-sysclasspath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (sysClassPathArg != null) {
|
||||
error("main.option.already.seen","-sysclasspath");
|
||||
}
|
||||
sysClassPathArg = argv[++i];
|
||||
} else {
|
||||
error("main.option.requires.argument","-sysclasspath");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else if (argv[i].equals("-bootclasspath")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (sysClassPathArg != null) {
|
||||
error("main.option.already.seen","-bootclasspath");
|
||||
}
|
||||
sysClassPathArg = argv[++i];
|
||||
} else {
|
||||
error("main.option.requires.argument","-bootclasspath");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else if (argv[i].equals("-extdirs")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (extDirsArg != null) {
|
||||
error("main.option.already.seen","-extdirs");
|
||||
}
|
||||
extDirsArg = argv[++i];
|
||||
} else {
|
||||
error("main.option.requires.argument","-extdirs");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else if (argv[i].equals("-encoding")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (encoding!=null)
|
||||
error("main.option.already.seen","-encoding");
|
||||
encoding = argv[++i];
|
||||
} else {
|
||||
error("main.option.requires.argument","-encoding");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else if (argv[i].equals("-target")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (targetArg!=null)
|
||||
error("main.option.already.seen","-target");
|
||||
targetArg = argv[++i];
|
||||
int j;
|
||||
for (j=0; j<releases.length; j++) {
|
||||
if (releases[j].equals(targetArg)) {
|
||||
majorVersion = majorVersions[j];
|
||||
minorVersion = minorVersions[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j==releases.length) {
|
||||
error("main.unknown.release",targetArg);
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else {
|
||||
error("main.option.requires.argument","-target");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else if (argv[i].equals("-d")) {
|
||||
if ((i + 1) < argv.length) {
|
||||
if (destDir!=null)
|
||||
error("main.option.already.seen","-d");
|
||||
destDir = new File(argv[++i]);
|
||||
if (!destDir.exists()) {
|
||||
error("main.no.such.directory",destDir.getPath());
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
} else {
|
||||
error("main.option.requires.argument","-d");
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
// JCOV
|
||||
} else if (argv[i].equals(optJcov)) {
|
||||
flags |= F_COVERAGE;
|
||||
flags &= ~F_OPT;
|
||||
flags &= ~F_OPT_INTERCLASS;
|
||||
} else if ((argv[i].startsWith(optJcovFile)) &&
|
||||
(argv[i].length() > optJcovFile.length())) {
|
||||
covFile = new File(argv[i].substring(optJcovFile.length()));
|
||||
flags &= ~F_OPT;
|
||||
flags &= ~F_OPT_INTERCLASS;
|
||||
flags |= F_COVERAGE;
|
||||
flags |= F_COVDATA;
|
||||
// end JCOV
|
||||
} else if (argv[i].equals("-XO")) {
|
||||
// This is what -O used to be. Now undocumented.
|
||||
if (prior_O!=null && !(prior_O.equals("-XO")))
|
||||
error("main.conflicting.options", prior_O, "-XO");
|
||||
prior_O = "-XO";
|
||||
flags |= F_OPT;
|
||||
} else if (argv[i].equals("-Xinterclass")) {
|
||||
if (prior_O!=null && !(prior_O.equals("-Xinterclass")))
|
||||
error("main.conflicting.options", prior_O, "-Xinterclass");
|
||||
prior_O = "-Xinterclass";
|
||||
flags |= F_OPT;
|
||||
flags |= F_OPT_INTERCLASS;
|
||||
flags |= F_DEPENDENCIES;
|
||||
} else if (argv[i].equals("-Xdepend")) {
|
||||
flags |= F_DEPENDENCIES;
|
||||
} else if (argv[i].equals("-Xdebug")) {
|
||||
flags |= F_DUMP;
|
||||
// Unadvertised option used by JWS. The non-X version should
|
||||
// be removed, but we'll leave it in until we find out for
|
||||
// sure that no one still depends on that option syntax.
|
||||
} else if (argv[i].equals("-xdepend") || argv[i].equals("-Xjws")) {
|
||||
flags |= F_PRINT_DEPENDENCIES;
|
||||
// change the default output in this case:
|
||||
if (out == System.err) {
|
||||
out = System.out;
|
||||
}
|
||||
} else if (argv[i].equals("-Xstrictdefault")) {
|
||||
// Make strict floating point the default
|
||||
flags |= F_STRICTDEFAULT;
|
||||
} else if (argv[i].equals("-Xverbosepath")) {
|
||||
verbosePath = true;
|
||||
} else if (argv[i].equals("-Xstdout")) {
|
||||
out = System.out;
|
||||
} else if (argv[i].equals("-X")) {
|
||||
error("main.unsupported.usage");
|
||||
return false; // Stop processing now
|
||||
} else if (argv[i].equals("-Xversion1.2")) {
|
||||
// Inform the compiler that it need not target VMs
|
||||
// earlier than version 1.2. This option is here
|
||||
// for testing purposes only. It is deliberately
|
||||
// kept orthogonal to the -target option in 1.2.0
|
||||
// for the sake of stability. These options will
|
||||
// be merged in a future release.
|
||||
flags |= F_VERSION12;
|
||||
} else if (argv[i].endsWith(".java")) {
|
||||
v.addElement(argv[i]);
|
||||
} else {
|
||||
error("main.no.such.option",argv[i]);
|
||||
usage_error();
|
||||
return false; // Stop processing now
|
||||
}
|
||||
}
|
||||
if (v.size() == 0 || exitStatus == EXIT_CMDERR) {
|
||||
usage_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create our Environment.
|
||||
BatchEnvironment env = BatchEnvironment.create(out,
|
||||
sourcePathArg,
|
||||
classPathArg,
|
||||
sysClassPathArg,
|
||||
extDirsArg);
|
||||
if (verbosePath) {
|
||||
output(getText("main.path.msg",
|
||||
env.sourcePath.toString(),
|
||||
env.binaryPath.toString()));
|
||||
}
|
||||
|
||||
env.flags |= flags;
|
||||
env.majorVersion = majorVersion;
|
||||
env.minorVersion = minorVersion;
|
||||
// JCOV
|
||||
env.covFile = covFile;
|
||||
// end JCOV
|
||||
env.setCharacterEncoding(encoding);
|
||||
|
||||
// Preload the "out of memory" error string just in case we run
|
||||
// out of memory during the compile.
|
||||
String noMemoryErrorString = getText("main.no.memory");
|
||||
String stackOverflowErrorString = getText("main.stack.overflow");
|
||||
|
||||
env.error(0, "warn.class.is.deprecated", "sun.tools.javac.Main");
|
||||
|
||||
try {
|
||||
// Parse all input files
|
||||
for (Enumeration e = v.elements() ; e.hasMoreElements() ;) {
|
||||
File file = new File((String)e.nextElement());
|
||||
try {
|
||||
env.parseFile(new ClassFile(file));
|
||||
} catch (FileNotFoundException ee) {
|
||||
env.error(0, "cant.read", file.getPath());
|
||||
exitStatus = EXIT_CMDERR;
|
||||
}
|
||||
}
|
||||
|
||||
// Do a post-read check on all newly-parsed classes,
|
||||
// after they have all been read.
|
||||
for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
|
||||
ClassDeclaration c = (ClassDeclaration)e.nextElement();
|
||||
if (c.getStatus() == CS_PARSED) {
|
||||
if (c.getClassDefinition().isLocal())
|
||||
continue;
|
||||
try {
|
||||
c.getClassDefinition(env);
|
||||
} catch (ClassNotFound ee) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compile all classes that need compilation
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream(4096);
|
||||
boolean done;
|
||||
|
||||
do {
|
||||
done = true;
|
||||
env.flushErrors();
|
||||
for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
|
||||
ClassDeclaration c = (ClassDeclaration)e.nextElement();
|
||||
SourceClass src;
|
||||
|
||||
switch (c.getStatus()) {
|
||||
case CS_UNDEFINED:
|
||||
if (!env.dependencies()) {
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
|
||||
case CS_SOURCE:
|
||||
if (tracing)
|
||||
env.dtEvent("Main.compile (SOURCE): loading, " + c);
|
||||
done = false;
|
||||
env.loadDefinition(c);
|
||||
if (c.getStatus() != CS_PARSED) {
|
||||
if (tracing)
|
||||
env.dtEvent("Main.compile (SOURCE): not parsed, " + c);
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
|
||||
case CS_PARSED:
|
||||
if (c.getClassDefinition().isInsideLocal()) {
|
||||
// the enclosing block will check this one
|
||||
if (tracing)
|
||||
env.dtEvent("Main.compile (PARSED): skipping local class, " + c);
|
||||
continue;
|
||||
}
|
||||
done = false;
|
||||
if (tracing) env.dtEvent("Main.compile (PARSED): checking, " + c);
|
||||
src = (SourceClass)c.getClassDefinition(env);
|
||||
src.check(env);
|
||||
c.setDefinition(src, CS_CHECKED);
|
||||
// fall through
|
||||
|
||||
case CS_CHECKED:
|
||||
src = (SourceClass)c.getClassDefinition(env);
|
||||
// bail out if there were any errors
|
||||
if (src.getError()) {
|
||||
if (tracing)
|
||||
env.dtEvent("Main.compile (CHECKED): bailing out on error, " + c);
|
||||
c.setDefinition(src, CS_COMPILED);
|
||||
break;
|
||||
}
|
||||
done = false;
|
||||
buf.reset();
|
||||
if (tracing)
|
||||
env.dtEvent("Main.compile (CHECKED): compiling, " + c);
|
||||
src.compile(buf);
|
||||
c.setDefinition(src, CS_COMPILED);
|
||||
src.cleanup(env);
|
||||
|
||||
if (src.getNestError() || nowrite) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String pkgName = c.getName().getQualifier().toString().replace('.', File.separatorChar);
|
||||
String className = c.getName().getFlatName().toString().replace('.', SIGC_INNERCLASS) + ".class";
|
||||
|
||||
File file;
|
||||
if (destDir != null) {
|
||||
if (pkgName.length() > 0) {
|
||||
file = new File(destDir, pkgName);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
file = new File(file, className);
|
||||
} else {
|
||||
file = new File(destDir, className);
|
||||
}
|
||||
} else {
|
||||
ClassFile classfile = (ClassFile)src.getSource();
|
||||
if (classfile.isZipped()) {
|
||||
env.error(0, "cant.write", classfile.getPath());
|
||||
exitStatus = EXIT_CMDERR;
|
||||
continue;
|
||||
}
|
||||
file = new File(classfile.getPath());
|
||||
file = new File(file.getParent(), className);
|
||||
}
|
||||
|
||||
// Create the file
|
||||
try {
|
||||
FileOutputStream out = new FileOutputStream(file.getPath());
|
||||
buf.writeTo(out);
|
||||
out.close();
|
||||
|
||||
if (env.verbose()) {
|
||||
output(getText("main.wrote", file.getPath()));
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
env.error(0, "cant.write", file.getPath());
|
||||
exitStatus = EXIT_CMDERR;
|
||||
}
|
||||
|
||||
// Print class dependencies if requested (-xdepend)
|
||||
if (env.print_dependencies()) {
|
||||
src.printClassDependencies(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!done);
|
||||
} catch (OutOfMemoryError ee) {
|
||||
// The compiler has run out of memory. Use the error string
|
||||
// which we preloaded.
|
||||
env.output(noMemoryErrorString);
|
||||
exitStatus = EXIT_SYSERR;
|
||||
return false;
|
||||
} catch (StackOverflowError ee) {
|
||||
env.output(stackOverflowErrorString);
|
||||
exitStatus = EXIT_SYSERR;
|
||||
return false;
|
||||
} catch (Error ee) {
|
||||
// We allow the compiler to take an exception silently if a program
|
||||
// error has previously been detected. Presumably, this makes the
|
||||
// compiler more robust in the face of bad error recovery.
|
||||
if (env.nerrors == 0 || env.dump()) {
|
||||
ee.printStackTrace();
|
||||
env.error(0, "fatal.error");
|
||||
exitStatus = EXIT_ABNORMAL;
|
||||
}
|
||||
} catch (Exception ee) {
|
||||
if (env.nerrors == 0 || env.dump()) {
|
||||
ee.printStackTrace();
|
||||
env.error(0, "fatal.exception");
|
||||
exitStatus = EXIT_ABNORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
int ndepfiles = env.deprecationFiles.size();
|
||||
if (ndepfiles > 0 && env.warnings()) {
|
||||
int ndeps = env.ndeprecations;
|
||||
Object file1 = env.deprecationFiles.elementAt(0);
|
||||
if (env.deprecation()) {
|
||||
if (ndepfiles > 1) {
|
||||
env.error(0, "warn.note.deprecations",
|
||||
new Integer(ndepfiles), new Integer(ndeps));
|
||||
} else {
|
||||
env.error(0, "warn.note.1deprecation",
|
||||
file1, new Integer(ndeps));
|
||||
}
|
||||
} else {
|
||||
if (ndepfiles > 1) {
|
||||
env.error(0, "warn.note.deprecations.silent",
|
||||
new Integer(ndepfiles), new Integer(ndeps));
|
||||
} else {
|
||||
env.error(0, "warn.note.1deprecation.silent",
|
||||
file1, new Integer(ndeps));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
env.flushErrors();
|
||||
env.shutdown();
|
||||
|
||||
boolean status = true;
|
||||
if (env.nerrors > 0) {
|
||||
String msg = "";
|
||||
if (env.nerrors > 1) {
|
||||
msg = getText("main.errors", env.nerrors);
|
||||
} else {
|
||||
msg = getText("main.1error");
|
||||
}
|
||||
if (env.nwarnings > 0) {
|
||||
if (env.nwarnings > 1) {
|
||||
msg += ", " + getText("main.warnings", env.nwarnings);
|
||||
} else {
|
||||
msg += ", " + getText("main.1warning");
|
||||
}
|
||||
}
|
||||
output(msg);
|
||||
if (exitStatus == EXIT_OK) {
|
||||
// Allow EXIT_CMDERR or EXIT_ABNORMAL to take precedence.
|
||||
exitStatus = EXIT_ERROR;
|
||||
}
|
||||
status = false;
|
||||
} else {
|
||||
if (env.nwarnings > 0) {
|
||||
if (env.nwarnings > 1) {
|
||||
output(getText("main.warnings", env.nwarnings));
|
||||
} else {
|
||||
output(getText("main.1warning"));
|
||||
}
|
||||
}
|
||||
}
|
||||
//JCOV
|
||||
if (env.covdata()) {
|
||||
Assembler CovAsm = new Assembler();
|
||||
CovAsm.GenJCov(env);
|
||||
}
|
||||
// end JCOV
|
||||
|
||||
// We're done
|
||||
if (env.verbose()) {
|
||||
tm = System.currentTimeMillis() - tm;
|
||||
output(getText("main.done_in", Long.toString(tm)));
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
public static void main(String argv[]) {
|
||||
OutputStream out = System.err;
|
||||
|
||||
// This is superceeded by the -Xstdout option, but we leave
|
||||
// in the old property check for compatibility.
|
||||
if (Boolean.getBoolean("javac.pipe.output")) {
|
||||
out = System.out;
|
||||
}
|
||||
|
||||
Main compiler = new Main(out, "javac");
|
||||
System.exit(compiler.compile(argv) ? 0 : compiler.exitStatus);
|
||||
}
|
||||
}
|
||||
2674
jdkSrc/jdk8/sun/tools/javac/SourceClass.java
Normal file
2674
jdkSrc/jdk8/sun/tools/javac/SourceClass.java
Normal file
File diff suppressed because it is too large
Load Diff
907
jdkSrc/jdk8/sun/tools/javac/SourceMember.java
Normal file
907
jdkSrc/jdk8/sun/tools/javac/SourceMember.java
Normal file
@@ -0,0 +1,907 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.javac;
|
||||
|
||||
import sun.tools.java.*;
|
||||
import sun.tools.tree.*;
|
||||
import sun.tools.asm.*;
|
||||
import java.util.Vector;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* A Source Member
|
||||
*
|
||||
* WARNING: The contents of this source file are not part of any
|
||||
* supported API. Code that depends on them does so at its own risk:
|
||||
* they are subject to change or removal without notice.
|
||||
*/
|
||||
@Deprecated
|
||||
public
|
||||
class SourceMember extends MemberDefinition implements Constants {
|
||||
/**
|
||||
* The argument names (if it is a method)
|
||||
*/
|
||||
Vector args;
|
||||
|
||||
// set to the MemberDefinition in the interface if we have this field because
|
||||
// it has been forced on us
|
||||
MemberDefinition abstractSource;
|
||||
|
||||
/**
|
||||
* The status of the field
|
||||
*/
|
||||
int status;
|
||||
|
||||
static final int PARSED = 0;
|
||||
static final int CHECKING = 1;
|
||||
static final int CHECKED = 2;
|
||||
static final int INLINING = 3;
|
||||
static final int INLINED = 4;
|
||||
static final int ERROR = 5;
|
||||
|
||||
public Vector getArguments() {
|
||||
return args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param argNames a vector of IdentifierToken
|
||||
*/
|
||||
public SourceMember(long where, ClassDefinition clazz,
|
||||
String doc, int modifiers, Type type,
|
||||
Identifier name, Vector argNames,
|
||||
IdentifierToken exp[], Node value) {
|
||||
super(where, clazz, modifiers, type, name, exp, value);
|
||||
this.documentation = doc;
|
||||
this.args = argNames; // for the moment
|
||||
// not until type names are resolved: createArgumentFields(argNames);
|
||||
|
||||
if (ClassDefinition.containsDeprecated(documentation)) {
|
||||
this.modifiers |= M_DEPRECATED;
|
||||
}
|
||||
}
|
||||
|
||||
void createArgumentFields(Vector argNames) {
|
||||
// Create a list of arguments
|
||||
if (isMethod()) {
|
||||
args = new Vector();
|
||||
|
||||
if (isConstructor() || !(isStatic() || isInitializer())) {
|
||||
args.addElement(((SourceClass)clazz).getThisArgument());
|
||||
}
|
||||
|
||||
if (argNames != null) {
|
||||
Enumeration e = argNames.elements();
|
||||
Type argTypes[] = getType().getArgumentTypes();
|
||||
for (int i = 0 ; i < argTypes.length ; i++) {
|
||||
Object x = e.nextElement();
|
||||
if (x instanceof LocalMember) {
|
||||
// This should not happen, but it does
|
||||
// in cases of vicious cyclic inheritance.
|
||||
args = argNames;
|
||||
return;
|
||||
}
|
||||
Identifier id;
|
||||
int mod;
|
||||
long where;
|
||||
if (x instanceof Identifier) {
|
||||
// allow argNames to be simple Identifiers (deprecated!)
|
||||
id = (Identifier)x;
|
||||
mod = 0;
|
||||
where = getWhere();
|
||||
} else {
|
||||
IdentifierToken token = (IdentifierToken)x;
|
||||
id = token.getName();
|
||||
mod = token.getModifiers();
|
||||
where = token.getWhere();
|
||||
}
|
||||
args.addElement(new LocalMember(where, clazz, mod,
|
||||
argTypes[i], id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The methods addOuterThis() and addUplevelArguments() were
|
||||
// both originally part of a single method called addUplevelArguments()
|
||||
// which took a single boolean parameter describing which of the
|
||||
// two behaviors it wanted.
|
||||
//
|
||||
// The original addUplevelArguments() claimed to keep the arguments in
|
||||
// the following order:
|
||||
//
|
||||
// (1) <this> <early outer this> <uplevel arguments...> <true arguments...>
|
||||
//
|
||||
// (By <early outer this> I am referring to the clientOuterField added
|
||||
// to some constructors when they are created. If an outer this is
|
||||
// added later, on demand, then this is mixed in with the rest of the
|
||||
// uplevel arguments and is added by addUplevelArguments.)
|
||||
//
|
||||
// In reality, the `args' Vector was generated in this order, but the
|
||||
// Type array `argTypes' was generated as:
|
||||
//
|
||||
// (2) <this> <uplevel arguments...> <early outer this> <true arguments...>
|
||||
//
|
||||
// This didn't make a difference in the common case -- that is, when
|
||||
// a class had an <outer.this> or <uplevel arguments...> but not both.
|
||||
// Both can happen in the case that a member class is declared inside
|
||||
// of a local class. It seems that the calling sequences, generated
|
||||
// in places like NewInstanceExpression.codeCommon(), use order (2),
|
||||
// so I have changed the code below to stick with that order. Since
|
||||
// the only time this happens is in classes which are insideLocal, no
|
||||
// one should be able to tell the difference between these orders.
|
||||
// (bug number 4085633)
|
||||
|
||||
LocalMember outerThisArg = null;
|
||||
|
||||
/**
|
||||
* Get outer instance link, or null if none.
|
||||
*/
|
||||
|
||||
public LocalMember getOuterThisArg() {
|
||||
return outerThisArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the outer.this argument to the list of arguments for this
|
||||
* constructor. This is called from resolveTypeStructure. Any
|
||||
* additional uplevel arguments get added later by addUplevelArguments().
|
||||
*/
|
||||
|
||||
void addOuterThis() {
|
||||
UplevelReference refs = clazz.getReferences();
|
||||
|
||||
// See if we have a client outer field.
|
||||
while (refs != null &&
|
||||
!refs.isClientOuterField()) {
|
||||
refs = refs.getNext();
|
||||
}
|
||||
|
||||
// There is no outer this argument. Quit.
|
||||
if (refs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the old arg types.
|
||||
Type oldArgTypes[] = type.getArgumentTypes();
|
||||
|
||||
// And make an array for the new ones with space for one more.
|
||||
Type argTypes[] = new Type[oldArgTypes.length + 1];
|
||||
|
||||
LocalMember arg = refs.getLocalArgument();
|
||||
outerThisArg = arg;
|
||||
|
||||
// args is our list of arguments. It contains a `this', so
|
||||
// we insert at position 1. The list of types does not have a
|
||||
// this, so we insert at position 0.
|
||||
args.insertElementAt(arg, 1);
|
||||
argTypes[0] = arg.getType();
|
||||
|
||||
// Add on the rest of the constructor arguments.
|
||||
for (int i = 0; i < oldArgTypes.length; i++) {
|
||||
argTypes[i + 1] = oldArgTypes[i];
|
||||
}
|
||||
|
||||
type = Type.tMethod(type.getReturnType(), argTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend argument names and argument types for local variable references.
|
||||
* This information is never seen by the type-check phase,
|
||||
* but it affects code generation, which is the earliest moment
|
||||
* we have comprehensive information on uplevel references.
|
||||
* The code() methods tweaks the constructor calls, prepending
|
||||
* the proper values to the argument list.
|
||||
*/
|
||||
void addUplevelArguments() {
|
||||
UplevelReference refs = clazz.getReferences();
|
||||
clazz.getReferencesFrozen();
|
||||
|
||||
// Count how many uplevels we have to add.
|
||||
int count = 0;
|
||||
for (UplevelReference r = refs; r != null; r = r.getNext()) {
|
||||
if (!r.isClientOuterField()) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
// None to add, quit.
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the old argument types.
|
||||
Type oldArgTypes[] = type.getArgumentTypes();
|
||||
|
||||
// Make an array with enough room for the new.
|
||||
Type argTypes[] = new Type[oldArgTypes.length + count];
|
||||
|
||||
// Add all of the late uplevel references to args and argTypes.
|
||||
// Note that they are `off-by-one' because of the `this'.
|
||||
int ins = 0;
|
||||
for (UplevelReference r = refs; r != null; r = r.getNext()) {
|
||||
if (!r.isClientOuterField()) {
|
||||
LocalMember arg = r.getLocalArgument();
|
||||
|
||||
args.insertElementAt(arg, 1 + ins);
|
||||
argTypes[ins] = arg.getType();
|
||||
|
||||
ins++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the rest of the old arguments.
|
||||
for (int i = 0; i < oldArgTypes.length; i++) {
|
||||
argTypes[ins + i] = oldArgTypes[i];
|
||||
}
|
||||
|
||||
type = Type.tMethod(type.getReturnType(), argTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for an inner class.
|
||||
*/
|
||||
public SourceMember(ClassDefinition innerClass) {
|
||||
super(innerClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Used only to generate an abstract copy of a method that a class
|
||||
* inherits from an interface
|
||||
*/
|
||||
public SourceMember(MemberDefinition f, ClassDefinition c, Environment env) {
|
||||
this(f.getWhere(), c, f.getDocumentation(),
|
||||
f.getModifiers() | M_ABSTRACT, f.getType(), f.getName(), null,
|
||||
f.getExceptionIds(), null);
|
||||
this.args = f.getArguments();
|
||||
this.abstractSource = f;
|
||||
this.exp = f.getExceptions(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get exceptions
|
||||
*/
|
||||
public ClassDeclaration[] getExceptions(Environment env) {
|
||||
if ((!isMethod()) || (exp != null)) {
|
||||
return exp;
|
||||
}
|
||||
if (expIds == null) {
|
||||
// (should not happen)
|
||||
exp = new ClassDeclaration[0];
|
||||
return exp;
|
||||
}
|
||||
// be sure to get the imports right:
|
||||
env = ((SourceClass)getClassDefinition()).setupEnv(env);
|
||||
exp = new ClassDeclaration[expIds.length];
|
||||
for (int i = 0; i < exp.length; i++) {
|
||||
Identifier e = expIds[i].getName();
|
||||
Identifier rexp = getClassDefinition().resolveName(env, e);
|
||||
exp[i] = env.getClassDeclaration(rexp);
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set array of name-resolved exceptions directly, e.g., for access methods.
|
||||
*/
|
||||
public void setExceptions(ClassDeclaration[] exp) {
|
||||
this.exp = exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve types in a field, after parsing.
|
||||
* @see ClassDefinition.resolveTypeStructure
|
||||
*/
|
||||
|
||||
public boolean resolved = false;
|
||||
|
||||
public void resolveTypeStructure(Environment env) {
|
||||
if (tracing) env.dtEnter("SourceMember.resolveTypeStructure: " + this);
|
||||
|
||||
// A member should only be resolved once. For a constructor, it is imperative
|
||||
// that 'addOuterThis' be called only once, else the outer instance argument may
|
||||
// be inserted into the argument list multiple times.
|
||||
|
||||
if (resolved) {
|
||||
if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: OK " + this);
|
||||
// This case shouldn't be happening. It is the responsibility
|
||||
// of our callers to avoid attempting multiple resolutions of a member.
|
||||
// *** REMOVE FOR SHIPMENT? ***
|
||||
throw new CompilerError("multiple member type resolution");
|
||||
//return;
|
||||
} else {
|
||||
if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: RESOLVING " + this);
|
||||
resolved = true;
|
||||
}
|
||||
|
||||
super.resolveTypeStructure(env);
|
||||
if (isInnerClass()) {
|
||||
ClassDefinition nc = getInnerClass();
|
||||
if (nc instanceof SourceClass && !nc.isLocal()) {
|
||||
((SourceClass)nc).resolveTypeStructure(env);
|
||||
}
|
||||
type = innerClass.getType();
|
||||
} else {
|
||||
// Expand all class names in 'type', including those that are not
|
||||
// fully-qualified or refer to inner classes, into fully-qualified
|
||||
// names. Local and anonymous classes get synthesized names here,
|
||||
// corresponding to the class files that will be generated. This is
|
||||
// currently the only place where 'resolveNames' is used.
|
||||
type = env.resolveNames(getClassDefinition(), type, isSynthetic());
|
||||
|
||||
// do the throws also:
|
||||
getExceptions(env);
|
||||
|
||||
if (isMethod()) {
|
||||
Vector argNames = args; args = null;
|
||||
createArgumentFields(argNames);
|
||||
// Add outer instance argument for constructors.
|
||||
if (isConstructor()) {
|
||||
addOuterThis();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tracing) env.dtExit("SourceMember.resolveTypeStructure: " + this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class declaration in which the field is actually defined
|
||||
*/
|
||||
public ClassDeclaration getDefiningClassDeclaration() {
|
||||
if (abstractSource == null)
|
||||
return super.getDefiningClassDeclaration();
|
||||
else
|
||||
return abstractSource.getDefiningClassDeclaration();
|
||||
}
|
||||
|
||||
/**
|
||||
* A source field never reports deprecation, since the compiler
|
||||
* allows access to deprecated features that are being compiled
|
||||
* in the same job.
|
||||
*/
|
||||
public boolean reportDeprecated(Environment env) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check this field.
|
||||
* <p>
|
||||
* This is the method which requests checking.
|
||||
* The real work is done by
|
||||
* <tt>Vset check(Environment, Context, Vset)</tt>.
|
||||
*/
|
||||
public void check(Environment env) throws ClassNotFound {
|
||||
if (tracing) env.dtEnter("SourceMember.check: " +
|
||||
getName() + ", status = " + status);
|
||||
// rely on the class to check all fields in the proper order
|
||||
if (status == PARSED) {
|
||||
if (isSynthetic() && getValue() == null) {
|
||||
// break a big cycle for small synthetic variables
|
||||
status = CHECKED;
|
||||
if (tracing)
|
||||
env.dtExit("SourceMember.check: BREAKING CYCLE");
|
||||
return;
|
||||
}
|
||||
if (tracing) env.dtEvent("SourceMember.check: CHECKING CLASS");
|
||||
clazz.check(env);
|
||||
if (status == PARSED) {
|
||||
if (getClassDefinition().getError()) {
|
||||
status = ERROR;
|
||||
} else {
|
||||
if (tracing)
|
||||
env.dtExit("SourceMember.check: CHECK FAILED");
|
||||
throw new CompilerError("check failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tracing) env.dtExit("SourceMember.check: DONE " +
|
||||
getName() + ", status = " + status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a field.
|
||||
* @param vset tells which uplevel variables are definitely assigned
|
||||
* The vset is also used to track the initialization of blank finals
|
||||
* by whichever fields which are relevant to them.
|
||||
*/
|
||||
public Vset check(Environment env, Context ctx, Vset vset) throws ClassNotFound {
|
||||
if (tracing) env.dtEvent("SourceMember.check: MEMBER " +
|
||||
getName() + ", status = " + status);
|
||||
if (status == PARSED) {
|
||||
if (isInnerClass()) {
|
||||
// some classes are checked separately
|
||||
ClassDefinition nc = getInnerClass();
|
||||
if (nc instanceof SourceClass && !nc.isLocal()
|
||||
&& nc.isInsideLocal()) {
|
||||
status = CHECKING;
|
||||
vset = ((SourceClass)nc).checkInsideClass(env, ctx, vset);
|
||||
}
|
||||
status = CHECKED;
|
||||
return vset;
|
||||
}
|
||||
if (env.dump()) {
|
||||
System.out.println("[check field " + getClassDeclaration().getName() + "." + getName() + "]");
|
||||
if (getValue() != null) {
|
||||
getValue().print(System.out);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
env = new Environment(env, this);
|
||||
|
||||
// This is where all checking of names appearing within the type
|
||||
// of the member is done. Includes return type and argument types.
|
||||
// Since only one location ('where') for error messages is provided,
|
||||
// localization of errors is poor. Throws clauses are handled below.
|
||||
env.resolve(where, getClassDefinition(), getType());
|
||||
|
||||
// Make sure that all the classes that we claim to throw really
|
||||
// are subclasses of Throwable, and are classes that we can reach
|
||||
if (isMethod()) {
|
||||
ClassDeclaration throwable =
|
||||
env.getClassDeclaration(idJavaLangThrowable);
|
||||
ClassDeclaration exp[] = getExceptions(env);
|
||||
for (int i = 0 ; i < exp.length ; i++) {
|
||||
ClassDefinition def;
|
||||
long where = getWhere();
|
||||
if (expIds != null && i < expIds.length) {
|
||||
where = IdentifierToken.getWhere(expIds[i], where);
|
||||
}
|
||||
try {
|
||||
def = exp[i].getClassDefinition(env);
|
||||
|
||||
// Validate access for all inner-class components
|
||||
// of a qualified name, not just the last one, which
|
||||
// is checked below. Yes, this is a dirty hack...
|
||||
// Part of fix for 4094658.
|
||||
env.resolveByName(where, getClassDefinition(), def.getName());
|
||||
|
||||
} catch (ClassNotFound e) {
|
||||
env.error(where, "class.not.found", e.name, "throws");
|
||||
break;
|
||||
}
|
||||
def.noteUsedBy(getClassDefinition(), where, env);
|
||||
if (!getClassDefinition().
|
||||
canAccess(env, def.getClassDeclaration())) {
|
||||
env.error(where, "cant.access.class", def);
|
||||
} else if (!def.subClassOf(env, throwable)) {
|
||||
env.error(where, "throws.not.throwable", def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status = CHECKING;
|
||||
|
||||
if (isMethod() && args != null) {
|
||||
int length = args.size();
|
||||
outer_loop:
|
||||
for (int i = 0; i < length; i++) {
|
||||
LocalMember lf = (LocalMember)(args.elementAt(i));
|
||||
Identifier name_i = lf.getName();
|
||||
for (int j = i + 1; j < length; j++) {
|
||||
LocalMember lf2 = (LocalMember)(args.elementAt(j));
|
||||
Identifier name_j = lf2.getName();
|
||||
if (name_i.equals(name_j)) {
|
||||
env.error(lf2.getWhere(), "duplicate.argument",
|
||||
name_i);
|
||||
break outer_loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (getValue() != null) {
|
||||
ctx = new Context(ctx, this);
|
||||
|
||||
if (isMethod()) {
|
||||
Statement s = (Statement)getValue();
|
||||
// initialize vset, indication that each of the arguments
|
||||
// to the function has a value
|
||||
|
||||
for (Enumeration e = args.elements(); e.hasMoreElements();){
|
||||
LocalMember f = (LocalMember)e.nextElement();
|
||||
vset.addVar(ctx.declare(env, f));
|
||||
}
|
||||
|
||||
if (isConstructor()) {
|
||||
// Undefine "this" in some constructors, until after
|
||||
// the super constructor has been called.
|
||||
vset.clearVar(ctx.getThisNumber());
|
||||
|
||||
// If the first thing in the definition isn't a call
|
||||
// to either super() or this(), then insert one.
|
||||
Expression supCall = s.firstConstructor();
|
||||
if ((supCall == null)
|
||||
&& (getClassDefinition().getSuperClass() != null)) {
|
||||
supCall = getDefaultSuperCall(env);
|
||||
Statement scs = new ExpressionStatement(where,
|
||||
supCall);
|
||||
s = Statement.insertStatement(scs, s);
|
||||
setValue(s);
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("VSET = " + vset);
|
||||
ClassDeclaration exp[] = getExceptions(env);
|
||||
int htsize = (exp.length > 3) ? 17 : 7;
|
||||
Hashtable thrown = new Hashtable(htsize);
|
||||
|
||||
vset = s.checkMethod(env, ctx, vset, thrown);
|
||||
|
||||
ClassDeclaration ignore1 =
|
||||
env.getClassDeclaration(idJavaLangError);
|
||||
ClassDeclaration ignore2 =
|
||||
env.getClassDeclaration(idJavaLangRuntimeException);
|
||||
|
||||
for (Enumeration e = thrown.keys(); e.hasMoreElements();) {
|
||||
ClassDeclaration c = (ClassDeclaration)e.nextElement();
|
||||
ClassDefinition def = c.getClassDefinition(env);
|
||||
if (def.subClassOf(env, ignore1)
|
||||
|| def.subClassOf(env, ignore2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean ok = false;
|
||||
if (!isInitializer()) {
|
||||
for (int i = 0 ; i < exp.length ; i++) {
|
||||
if (def.subClassOf(env, exp[i])) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
Node n = (Node)thrown.get(c);
|
||||
long where = n.getWhere();
|
||||
String errorMsg;
|
||||
|
||||
if (isConstructor()) {
|
||||
if (where ==
|
||||
getClassDefinition().getWhere()) {
|
||||
|
||||
// If this message is being generated for
|
||||
// a default constructor, we should give
|
||||
// a different error message. Currently
|
||||
// we check for this by seeing if the
|
||||
// constructor has the same "where" as
|
||||
// its class. This is a bit kludgy, but
|
||||
// works. (bug id 4034836)
|
||||
errorMsg = "def.constructor.exception";
|
||||
} else {
|
||||
// Constructor with uncaught exception.
|
||||
errorMsg = "constructor.exception";
|
||||
}
|
||||
} else if (isInitializer()) {
|
||||
// Initializer with uncaught exception.
|
||||
errorMsg = "initializer.exception";
|
||||
} else {
|
||||
// Method with uncaught exception.
|
||||
errorMsg = "uncaught.exception";
|
||||
}
|
||||
env.error(where, errorMsg, c.getName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Hashtable thrown = new Hashtable(3); // small & throw-away
|
||||
Expression val = (Expression)getValue();
|
||||
|
||||
vset = val.checkInitializer(env, ctx, vset,
|
||||
getType(), thrown);
|
||||
setValue(val.convert(env, ctx, getType(), val));
|
||||
|
||||
// Complain about static final members of inner classes that
|
||||
// do not have an initializer that is a constant expression.
|
||||
// In general, static members are not permitted for inner
|
||||
// classes, but an exception is made for named constants.
|
||||
// Other cases of static members, including non-final ones,
|
||||
// are handled in 'SourceClass'. Part of fix for 4095568.
|
||||
if (isStatic() && isFinal() && !clazz.isTopLevel()) {
|
||||
if (!((Expression)getValue()).isConstant()) {
|
||||
env.error(where, "static.inner.field", getName(), this);
|
||||
setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Both RuntimeExceptions and Errors should be
|
||||
// allowed in initializers. Fix for bug 4102541.
|
||||
ClassDeclaration except =
|
||||
env.getClassDeclaration(idJavaLangThrowable);
|
||||
ClassDeclaration ignore1 =
|
||||
env.getClassDeclaration(idJavaLangError);
|
||||
ClassDeclaration ignore2 =
|
||||
env.getClassDeclaration(idJavaLangRuntimeException);
|
||||
|
||||
for (Enumeration e = thrown.keys(); e.hasMoreElements(); ) {
|
||||
ClassDeclaration c = (ClassDeclaration)e.nextElement();
|
||||
ClassDefinition def = c.getClassDefinition(env);
|
||||
|
||||
if (!def.subClassOf(env, ignore1)
|
||||
&& !def.subClassOf(env, ignore2)
|
||||
&& def.subClassOf(env, except)) {
|
||||
Node n = (Node)thrown.get(c);
|
||||
env.error(n.getWhere(),
|
||||
"initializer.exception", c.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (env.dump()) {
|
||||
getValue().print(System.out);
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
status = getClassDefinition().getError() ? ERROR : CHECKED;
|
||||
}
|
||||
|
||||
|
||||
// Initializers (static and instance) must be able to complete normally.
|
||||
if (isInitializer() && vset.isDeadEnd()) {
|
||||
env.error(where, "init.no.normal.completion");
|
||||
vset = vset.clearDeadEnd();
|
||||
}
|
||||
|
||||
return vset;
|
||||
}
|
||||
|
||||
// helper to check(): synthesize a missing super() call
|
||||
private Expression getDefaultSuperCall(Environment env) {
|
||||
Expression se = null;
|
||||
ClassDefinition sclass = getClassDefinition().getSuperClass().getClassDefinition();
|
||||
// does the superclass constructor require an enclosing instance?
|
||||
ClassDefinition reqc = (sclass == null) ? null
|
||||
: sclass.isTopLevel() ? null
|
||||
: sclass.getOuterClass();
|
||||
ClassDefinition thisc = getClassDefinition();
|
||||
if (reqc != null && !Context.outerLinkExists(env, reqc, thisc)) {
|
||||
se = new SuperExpression(where, new NullExpression(where));
|
||||
env.error(where, "no.default.outer.arg", reqc, getClassDefinition());
|
||||
}
|
||||
if (se == null) {
|
||||
se = new SuperExpression(where);
|
||||
}
|
||||
return new MethodExpression(where, se, idInit, new Expression[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline the field
|
||||
*/
|
||||
void inline(Environment env) throws ClassNotFound {
|
||||
switch (status) {
|
||||
case PARSED:
|
||||
check(env);
|
||||
inline(env);
|
||||
break;
|
||||
|
||||
case CHECKED:
|
||||
if (env.dump()) {
|
||||
System.out.println("[inline field " + getClassDeclaration().getName() + "." + getName() + "]");
|
||||
}
|
||||
status = INLINING;
|
||||
env = new Environment(env, this);
|
||||
|
||||
if (isMethod()) {
|
||||
if ((!isNative()) && (!isAbstract())) {
|
||||
Statement s = (Statement)getValue();
|
||||
Context ctx = new Context((Context)null, this);
|
||||
for (Enumeration e = args.elements() ; e.hasMoreElements() ;) {
|
||||
LocalMember local = (LocalMember)e.nextElement();
|
||||
ctx.declare(env, local);
|
||||
}
|
||||
setValue(s.inline(env, ctx));
|
||||
}
|
||||
} else if (isInnerClass()) {
|
||||
// some classes are checked and inlined separately
|
||||
ClassDefinition nc = getInnerClass();
|
||||
if (nc instanceof SourceClass && !nc.isLocal()
|
||||
&& nc.isInsideLocal()) {
|
||||
status = INLINING;
|
||||
((SourceClass)nc).inlineLocalClass(env);
|
||||
}
|
||||
status = INLINED;
|
||||
break;
|
||||
} else {
|
||||
if (getValue() != null) {
|
||||
Context ctx = new Context((Context)null, this);
|
||||
if (!isStatic()) {
|
||||
// Cf. "thisArg" in SourceClass.checkMembers().
|
||||
Context ctxInst = new Context(ctx, this);
|
||||
LocalMember thisArg =
|
||||
((SourceClass)clazz).getThisArgument();
|
||||
ctxInst.declare(env, thisArg);
|
||||
setValue(((Expression)getValue())
|
||||
.inlineValue(env, ctxInst));
|
||||
} else {
|
||||
setValue(((Expression)getValue())
|
||||
.inlineValue(env, ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (env.dump()) {
|
||||
System.out.println("[inlined field " + getClassDeclaration().getName() + "." + getName() + "]");
|
||||
if (getValue() != null) {
|
||||
getValue().print(System.out);
|
||||
System.out.println();
|
||||
} else {
|
||||
System.out.println("<empty>");
|
||||
}
|
||||
}
|
||||
status = INLINED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the field (or null if the value can't be determined)
|
||||
*/
|
||||
public Node getValue(Environment env) throws ClassNotFound {
|
||||
Node value = getValue();
|
||||
if (value != null && status != INLINED) {
|
||||
// be sure to get the imports right:
|
||||
env = ((SourceClass)clazz).setupEnv(env);
|
||||
inline(env);
|
||||
value = (status == INLINED) ? getValue() : null;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean isInlineable(Environment env, boolean fromFinal) throws ClassNotFound {
|
||||
if (super.isInlineable(env, fromFinal)) {
|
||||
getValue(env);
|
||||
return (status == INLINED) && !getClassDefinition().getError();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the initial value of the field
|
||||
*/
|
||||
public Object getInitialValue() {
|
||||
if (isMethod() || (getValue() == null) || (!isFinal()) || (status != INLINED)) {
|
||||
return null;
|
||||
}
|
||||
return ((Expression)getValue()).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate code
|
||||
*/
|
||||
public void code(Environment env, Assembler asm) throws ClassNotFound {
|
||||
switch (status) {
|
||||
case PARSED:
|
||||
check(env);
|
||||
code(env, asm);
|
||||
return;
|
||||
|
||||
case CHECKED:
|
||||
inline(env);
|
||||
code(env, asm);
|
||||
return;
|
||||
|
||||
case INLINED:
|
||||
// Actually generate code
|
||||
if (env.dump()) {
|
||||
System.out.println("[code field " + getClassDeclaration().getName() + "." + getName() + "]");
|
||||
}
|
||||
if (isMethod() && (!isNative()) && (!isAbstract())) {
|
||||
env = new Environment(env, this);
|
||||
Context ctx = new Context((Context)null, this);
|
||||
Statement s = (Statement)getValue();
|
||||
|
||||
for (Enumeration e = args.elements() ; e.hasMoreElements() ; ) {
|
||||
LocalMember f = (LocalMember)e.nextElement();
|
||||
ctx.declare(env, f);
|
||||
//ctx.declare(env, (LocalMember)e.nextElement());
|
||||
}
|
||||
|
||||
/*
|
||||
if (isConstructor() && ((s == null) || (s.firstConstructor() == null))) {
|
||||
ClassDeclaration c = getClassDefinition().getSuperClass();
|
||||
if (c != null) {
|
||||
MemberDefinition field = c.getClassDefinition(env).matchMethod(env, getClassDefinition(), idInit);
|
||||
asm.add(getWhere(), opc_aload, new Integer(0));
|
||||
asm.add(getWhere(), opc_invokespecial, field);
|
||||
asm.add(getWhere(), opc_pop);
|
||||
}
|
||||
|
||||
// Output initialization code
|
||||
for (MemberDefinition f = getClassDefinition().getFirstMember() ; f != null ; f = f.getNextMember()) {
|
||||
if (!f.isStatic()) {
|
||||
f.codeInit(env, ctx, asm);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (s != null) {
|
||||
s.code(env, ctx, asm);
|
||||
}
|
||||
if (getType().getReturnType().isType(TC_VOID) && !isInitializer()) {
|
||||
asm.add(getWhere(), opc_return, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void codeInit(Environment env, Context ctx, Assembler asm) throws ClassNotFound {
|
||||
if (isMethod()) {
|
||||
return;
|
||||
}
|
||||
switch (status) {
|
||||
case PARSED:
|
||||
check(env);
|
||||
codeInit(env, ctx, asm);
|
||||
return;
|
||||
|
||||
case CHECKED:
|
||||
inline(env);
|
||||
codeInit(env, ctx, asm);
|
||||
return;
|
||||
|
||||
case INLINED:
|
||||
// Actually generate code
|
||||
if (env.dump()) {
|
||||
System.out.println("[code initializer " + getClassDeclaration().getName() + "." + getName() + "]");
|
||||
}
|
||||
if (getValue() != null) {
|
||||
Expression e = (Expression)getValue();
|
||||
// The JLS Section 8.5 specifies that static (non-final)
|
||||
// initializers should be executed in textual order. Eliding
|
||||
// initializations to default values can interfere with this,
|
||||
// so the tests for !e.equalsDefault() have been eliminated,
|
||||
// below.
|
||||
if (isStatic()) {
|
||||
if (getInitialValue() == null) {
|
||||
// removed: && !e.equalsDefault()) {
|
||||
e.codeValue(env, ctx, asm);
|
||||
asm.add(getWhere(), opc_putstatic, this);
|
||||
}
|
||||
} else { // removed: if (!e.equalsDefault()) {
|
||||
// This code doesn't appear to be reached for
|
||||
// instance initializers. Code for these is generated
|
||||
// in the makeVarInits() method of the class
|
||||
// MethodExpression.
|
||||
asm.add(getWhere(), opc_aload, new Integer(0));
|
||||
e.codeValue(env, ctx, asm);
|
||||
asm.add(getWhere(), opc_putfield, this);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print for debugging
|
||||
*/
|
||||
public void print(PrintStream out) {
|
||||
super.print(out);
|
||||
if (getValue() != null) {
|
||||
getValue().print(out);
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
129
jdkSrc/jdk8/sun/tools/jcmd/Arguments.java
Normal file
129
jdkSrc/jdk8/sun/tools/jcmd/Arguments.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jcmd;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
class Arguments {
|
||||
private boolean listProcesses = false;
|
||||
private boolean listCounters = false;
|
||||
private boolean showUsage = false;
|
||||
private int pid = -1;
|
||||
private String command = null;
|
||||
private String processSubstring;
|
||||
|
||||
public boolean isListProcesses() { return listProcesses; }
|
||||
public boolean isListCounters() { return listCounters; }
|
||||
public boolean isShowUsage() { return showUsage; }
|
||||
public int getPid() { return pid; }
|
||||
public String getCommand() { return command; }
|
||||
public String getProcessSubstring() { return processSubstring; }
|
||||
|
||||
public Arguments(String[] args) {
|
||||
if (args.length == 0 || args[0].equals("-l")) {
|
||||
listProcesses = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[0].equals("-h") || args[0].equals("-help") ) {
|
||||
showUsage = true;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
pid = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException ex) {
|
||||
// use as a partial class-name instead
|
||||
if (args[0].charAt(0) != '-') {
|
||||
// unless it starts with a '-'
|
||||
processSubstring = args[0];
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
if (args[i].equals("-f")) {
|
||||
if (args.length == i + 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"No file specified for parameter -f");
|
||||
} else if (args.length == i + 2) {
|
||||
try {
|
||||
readCommandFile(args[i + 1]);
|
||||
} catch(IOException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not read from file specified with -f option: "
|
||||
+ args[i + 1]);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Options after -f are not allowed");
|
||||
}
|
||||
} else if (args[i].equals("PerfCounter.print")) {
|
||||
listCounters = true;
|
||||
} else {
|
||||
sb.append(args[i]).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
if (listCounters != true && sb.length() == 0) {
|
||||
throw new IllegalArgumentException("No command specified");
|
||||
}
|
||||
|
||||
command = sb.toString().trim();
|
||||
}
|
||||
|
||||
private void readCommandFile(String path) throws IOException {
|
||||
try (BufferedReader bf = new BufferedReader(new FileReader(path));) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s;
|
||||
while ((s = bf.readLine()) != null) {
|
||||
sb.append(s).append("\n");
|
||||
}
|
||||
command = sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static void usage() {
|
||||
System.out.println("Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>");
|
||||
System.out.println(" or: jcmd -l ");
|
||||
System.out.println(" or: jcmd -h ");
|
||||
System.out.println(" ");
|
||||
System.out.println(" command must be a valid jcmd command for the selected jvm. ");
|
||||
System.out.println(" Use the command \"help\" to see which commands are available. ");
|
||||
System.out.println(" If the pid is 0, commands will be sent to all Java processes. ");
|
||||
System.out.println(" The main class argument will be used to match (either partially ");
|
||||
System.out.println(" or fully) the class used to start Java. ");
|
||||
System.out.println(" If no options are given, lists Java processes (same as -p). ");
|
||||
System.out.println(" ");
|
||||
System.out.println(" PerfCounter.print display the counters exposed by this process ");
|
||||
System.out.println(" -f read and execute commands from the file ");
|
||||
System.out.println(" -l list JVM processes on the local machine ");
|
||||
System.out.println(" -h this help ");
|
||||
}
|
||||
}
|
||||
244
jdkSrc/jdk8/sun/tools/jcmd/JCmd.java
Normal file
244
jdkSrc/jdk8/sun/tools/jcmd/JCmd.java
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jcmd;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import com.sun.tools.attach.AttachOperationFailedException;
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.sun.tools.attach.AgentLoadException;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
|
||||
import sun.tools.attach.HotSpotVirtualMachine;
|
||||
import sun.tools.jstat.JStatLogger;
|
||||
import sun.jvmstat.monitor.Monitor;
|
||||
import sun.jvmstat.monitor.MonitoredHost;
|
||||
import sun.jvmstat.monitor.MonitoredVm;
|
||||
import sun.jvmstat.monitor.MonitoredVmUtil;
|
||||
import sun.jvmstat.monitor.MonitorException;
|
||||
import sun.jvmstat.monitor.VmIdentifier;
|
||||
|
||||
public class JCmd {
|
||||
public static void main(String[] args) {
|
||||
Arguments arg = null;
|
||||
try {
|
||||
arg = new Arguments(args);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
System.err.println("Error parsing arguments: " + ex.getMessage()
|
||||
+ "\n");
|
||||
Arguments.usage();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (arg.isShowUsage()) {
|
||||
Arguments.usage();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (arg.isListProcesses()) {
|
||||
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
|
||||
for (VirtualMachineDescriptor vmd : vmds) {
|
||||
System.out.println(vmd.id() + " " + vmd.displayName());
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
List<String> pids = new ArrayList<String>();
|
||||
if (arg.getPid() == 0) {
|
||||
// find all VMs
|
||||
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
|
||||
for (VirtualMachineDescriptor vmd : vmds) {
|
||||
if (!isJCmdProcess(vmd)) {
|
||||
pids.add(vmd.id());
|
||||
}
|
||||
}
|
||||
} else if (arg.getProcessSubstring() != null) {
|
||||
// use the partial class-name match
|
||||
List<VirtualMachineDescriptor> vmds = VirtualMachine.list();
|
||||
for (VirtualMachineDescriptor vmd : vmds) {
|
||||
if (isJCmdProcess(vmd)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
String mainClass = getMainClass(vmd);
|
||||
if (mainClass != null
|
||||
&& mainClass.indexOf(arg.getProcessSubstring()) != -1) {
|
||||
pids.add(vmd.id());
|
||||
}
|
||||
} catch (MonitorException|URISyntaxException e) {
|
||||
if (e.getMessage() != null) {
|
||||
System.err.println(e.getMessage());
|
||||
} else {
|
||||
Throwable cause = e.getCause();
|
||||
if ((cause != null) && (cause.getMessage() != null)) {
|
||||
System.err.println(cause.getMessage());
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pids.isEmpty()) {
|
||||
System.err.println("Could not find any processes matching : '"
|
||||
+ arg.getProcessSubstring() + "'");
|
||||
System.exit(1);
|
||||
}
|
||||
} else if (arg.getPid() == -1) {
|
||||
System.err.println("Invalid pid specified");
|
||||
System.exit(1);
|
||||
} else {
|
||||
// Use the found pid
|
||||
pids.add(arg.getPid() + "");
|
||||
}
|
||||
|
||||
boolean success = true;
|
||||
for (String pid : pids) {
|
||||
System.out.println(pid + ":");
|
||||
if (arg.isListCounters()) {
|
||||
listCounters(pid);
|
||||
} else {
|
||||
try {
|
||||
executeCommandForPid(pid, arg.getCommand());
|
||||
} catch(AttachOperationFailedException ex) {
|
||||
System.err.println(ex.getMessage());
|
||||
success = false;
|
||||
} catch(Exception ex) {
|
||||
ex.printStackTrace();
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.exit(success ? 0 : 1);
|
||||
}
|
||||
|
||||
private static void executeCommandForPid(String pid, String command)
|
||||
throws AttachNotSupportedException, IOException,
|
||||
UnsupportedEncodingException {
|
||||
VirtualMachine vm = VirtualMachine.attach(pid);
|
||||
|
||||
// Cast to HotSpotVirtualMachine as this is an
|
||||
// implementation specific method.
|
||||
HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) vm;
|
||||
String lines[] = command.split("\\n");
|
||||
for (String line : lines) {
|
||||
if (line.trim().equals("stop")) {
|
||||
break;
|
||||
}
|
||||
try (InputStream in = hvm.executeJCmd(line);) {
|
||||
// read to EOF and just print output
|
||||
byte b[] = new byte[256];
|
||||
int n;
|
||||
boolean messagePrinted = false;
|
||||
do {
|
||||
n = in.read(b);
|
||||
if (n > 0) {
|
||||
String s = new String(b, 0, n, "UTF-8");
|
||||
System.out.print(s);
|
||||
messagePrinted = true;
|
||||
}
|
||||
} while (n > 0);
|
||||
if (!messagePrinted) {
|
||||
System.out.println("Command executed successfully");
|
||||
}
|
||||
}
|
||||
}
|
||||
vm.detach();
|
||||
}
|
||||
|
||||
private static void listCounters(String pid) {
|
||||
// Code from JStat (can't call it directly since it does System.exit)
|
||||
VmIdentifier vmId = null;
|
||||
try {
|
||||
vmId = new VmIdentifier(pid);
|
||||
} catch (URISyntaxException e) {
|
||||
System.err.println("Malformed VM Identifier: " + pid);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
|
||||
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1);
|
||||
JStatLogger logger = new JStatLogger(monitoredVm);
|
||||
logger.printSnapShot("\\w*", // all names
|
||||
new AscendingMonitorComparator(), // comparator
|
||||
false, // not verbose
|
||||
true, // show unsupported
|
||||
System.out);
|
||||
monitoredHost.detach(monitoredVm);
|
||||
} catch (MonitorException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isJCmdProcess(VirtualMachineDescriptor vmd) {
|
||||
try {
|
||||
String mainClass = getMainClass(vmd);
|
||||
return mainClass != null && mainClass.equals(JCmd.class.getName());
|
||||
} catch (URISyntaxException|MonitorException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMainClass(VirtualMachineDescriptor vmd)
|
||||
throws URISyntaxException, MonitorException {
|
||||
try {
|
||||
String mainClass = null;
|
||||
VmIdentifier vmId = new VmIdentifier(vmd.id());
|
||||
MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
|
||||
MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1);
|
||||
mainClass = MonitoredVmUtil.mainClass(monitoredVm, true);
|
||||
monitoredHost.detach(monitoredVm);
|
||||
return mainClass;
|
||||
} catch(NullPointerException e) {
|
||||
// There is a potential race, where a running java app is being
|
||||
// queried, unfortunately the java app has shutdown after this
|
||||
// method is started but before getMonitoredVM is called.
|
||||
// If this is the case, then the /tmp/hsperfdata_xxx/pid file
|
||||
// will have disappeared and we will get a NullPointerException.
|
||||
// Handle this gracefully....
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to compare two Monitor objects by name in ascending order.
|
||||
* (from jstat)
|
||||
*/
|
||||
static class AscendingMonitorComparator implements Comparator<Monitor> {
|
||||
|
||||
public int compare(Monitor m1, Monitor m2) {
|
||||
String name1 = m1.getName();
|
||||
String name2 = m2.getName();
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
}
|
||||
}
|
||||
197
jdkSrc/jdk8/sun/tools/jconsole/AboutDialog.java
Normal file
197
jdkSrc/jdk8/sun/tools/jconsole/AboutDialog.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.net.URI;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import static sun.misc.Version.jdkMinorVersion;
|
||||
|
||||
import static java.awt.BorderLayout.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AboutDialog extends InternalDialog {
|
||||
|
||||
private static final Color textColor = new Color(87, 88, 89);
|
||||
private static final Color bgColor = new Color(232, 237, 241);
|
||||
private static final Color borderColor = Color.black;
|
||||
|
||||
private Icon mastheadIcon =
|
||||
new MastheadIcon(Messages.HELP_ABOUT_DIALOG_MASTHEAD_TITLE);
|
||||
|
||||
private static AboutDialog aboutDialog;
|
||||
|
||||
private JLabel statusBar;
|
||||
private Action closeAction;
|
||||
|
||||
public AboutDialog(JConsole jConsole) {
|
||||
super(jConsole, Messages.HELP_ABOUT_DIALOG_TITLE, false);
|
||||
|
||||
setAccessibleDescription(this, Messages.HELP_ABOUT_DIALOG_ACCESSIBLE_DESCRIPTION);
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setResizable(false);
|
||||
JComponent cp = (JComponent)getContentPane();
|
||||
|
||||
createActions();
|
||||
|
||||
JLabel mastheadLabel = new JLabel(mastheadIcon);
|
||||
setAccessibleName(mastheadLabel,
|
||||
Messages.HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME);
|
||||
|
||||
JPanel mainPanel = new TPanel(0, 0);
|
||||
mainPanel.add(mastheadLabel, NORTH);
|
||||
|
||||
String jConsoleVersion = Version.getVersion();
|
||||
String vmName = System.getProperty("java.vm.name");
|
||||
String vmVersion = System.getProperty("java.vm.version");
|
||||
String urlStr = getOnlineDocUrl();
|
||||
if (isBrowseSupported()) {
|
||||
urlStr = "<a style='color:#35556b' href=\"" + urlStr + "\">" + urlStr + "</a>";
|
||||
}
|
||||
|
||||
JPanel infoAndLogoPanel = new JPanel(new BorderLayout(10, 10));
|
||||
infoAndLogoPanel.setBackground(bgColor);
|
||||
|
||||
String colorStr = String.format("%06x", textColor.getRGB() & 0xFFFFFF);
|
||||
JEditorPane helpLink = new JEditorPane("text/html",
|
||||
"<html><font color=#"+ colorStr + ">" +
|
||||
Resources.format(Messages.HELP_ABOUT_DIALOG_JCONSOLE_VERSION, jConsoleVersion) +
|
||||
"<p>" + Resources.format(Messages.HELP_ABOUT_DIALOG_JAVA_VERSION, (vmName +", "+ vmVersion)) +
|
||||
"<p>" + urlStr + "</html>");
|
||||
helpLink.setOpaque(false);
|
||||
helpLink.setEditable(false);
|
||||
helpLink.setForeground(textColor);
|
||||
mainPanel.setBorder(BorderFactory.createLineBorder(borderColor));
|
||||
infoAndLogoPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
helpLink.addHyperlinkListener(new HyperlinkListener() {
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
browse(e.getDescription());
|
||||
}
|
||||
}
|
||||
});
|
||||
infoAndLogoPanel.add(helpLink, NORTH);
|
||||
|
||||
ImageIcon brandLogoIcon = new ImageIcon(getClass().getResource("resources/brandlogo.png"));
|
||||
JLabel brandLogo = new JLabel(brandLogoIcon, JLabel.LEADING);
|
||||
|
||||
JButton closeButton = new JButton(closeAction);
|
||||
|
||||
JPanel bottomPanel = new TPanel(0, 0);
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
|
||||
buttonPanel.setOpaque(false);
|
||||
|
||||
mainPanel.add(infoAndLogoPanel, CENTER);
|
||||
cp.add(bottomPanel, SOUTH);
|
||||
|
||||
infoAndLogoPanel.add(brandLogo, SOUTH);
|
||||
|
||||
buttonPanel.setBorder(new EmptyBorder(2, 12, 2, 12));
|
||||
buttonPanel.add(closeButton);
|
||||
bottomPanel.add(buttonPanel, NORTH);
|
||||
|
||||
statusBar = new JLabel(" ");
|
||||
bottomPanel.add(statusBar, SOUTH);
|
||||
|
||||
cp.add(mainPanel, NORTH);
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(jConsole);
|
||||
Utilities.updateTransparency(this);
|
||||
}
|
||||
|
||||
public void showDialog() {
|
||||
statusBar.setText(" ");
|
||||
setVisible(true);
|
||||
try {
|
||||
// Bring to front of other dialogs
|
||||
setSelected(true);
|
||||
} catch (PropertyVetoException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private static AboutDialog getAboutDialog(JConsole jConsole) {
|
||||
if (aboutDialog == null) {
|
||||
aboutDialog = new AboutDialog(jConsole);
|
||||
}
|
||||
return aboutDialog;
|
||||
}
|
||||
|
||||
static void showAboutDialog(JConsole jConsole) {
|
||||
getAboutDialog(jConsole).showDialog();
|
||||
}
|
||||
|
||||
static void browseUserGuide(JConsole jConsole) {
|
||||
getAboutDialog(jConsole).browse(getOnlineDocUrl());
|
||||
}
|
||||
|
||||
static boolean isBrowseSupported() {
|
||||
return (Desktop.isDesktopSupported() &&
|
||||
Desktop.getDesktop().isSupported(Desktop.Action.BROWSE));
|
||||
}
|
||||
|
||||
void browse(String urlStr) {
|
||||
try {
|
||||
Desktop.getDesktop().browse(new URI(urlStr));
|
||||
} catch (Exception ex) {
|
||||
showDialog();
|
||||
statusBar.setText(ex.getLocalizedMessage());
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
closeAction = new AbstractAction(Messages.CLOSE) {
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static String getOnlineDocUrl() {
|
||||
String version = Integer.toString(jdkMinorVersion());
|
||||
return Resources.format(Messages.HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL,
|
||||
version);
|
||||
}
|
||||
|
||||
private static class TPanel extends JPanel {
|
||||
TPanel(int hgap, int vgap) {
|
||||
super(new BorderLayout(hgap, vgap));
|
||||
setOpaque(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
564
jdkSrc/jdk8/sun/tools/jconsole/BorderedComponent.java
Normal file
564
jdkSrc/jdk8/sun/tools/jconsole/BorderedComponent.java
Normal file
@@ -0,0 +1,564 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.*;
|
||||
import javax.swing.plaf.basic.BasicGraphicsUtils;
|
||||
|
||||
|
||||
import static javax.swing.SwingConstants.*;
|
||||
|
||||
import static sun.tools.jconsole.JConsole.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class BorderedComponent extends JPanel implements ActionListener {
|
||||
JButton moreOrLessButton;
|
||||
String valueLabelStr;
|
||||
JLabel label;
|
||||
JComponent comp;
|
||||
boolean collapsed = false;
|
||||
|
||||
private Icon collapseIcon;
|
||||
private Icon expandIcon;
|
||||
|
||||
private static Image getImage(String name) {
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
name = "resources/" + name + ".png";
|
||||
return tk.getImage(BorderedComponent.class.getResource(name));
|
||||
}
|
||||
|
||||
public BorderedComponent(String text) {
|
||||
this(text, null, false);
|
||||
}
|
||||
|
||||
public BorderedComponent(String text, JComponent comp) {
|
||||
this(text, comp, false);
|
||||
}
|
||||
|
||||
public BorderedComponent(String text, JComponent comp, boolean collapsible) {
|
||||
super(null);
|
||||
|
||||
this.comp = comp;
|
||||
|
||||
// Only add border if text is not null
|
||||
if (text != null) {
|
||||
TitledBorder border;
|
||||
if (collapsible) {
|
||||
final JLabel textLabel = new JLabel(text);
|
||||
JPanel borderLabel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 0)) {
|
||||
public int getBaseline(int w, int h) {
|
||||
Dimension dim = textLabel.getPreferredSize();
|
||||
return textLabel.getBaseline(dim.width, dim.height) + textLabel.getY();
|
||||
}
|
||||
};
|
||||
borderLabel.add(textLabel);
|
||||
border = new LabeledBorder(borderLabel);
|
||||
textLabel.setForeground(border.getTitleColor());
|
||||
|
||||
if (IS_WIN) {
|
||||
collapseIcon = new ImageIcon(getImage("collapse-winlf"));
|
||||
expandIcon = new ImageIcon(getImage("expand-winlf"));
|
||||
} else {
|
||||
collapseIcon = new ArrowIcon(SOUTH, textLabel);
|
||||
expandIcon = new ArrowIcon(EAST, textLabel);
|
||||
}
|
||||
|
||||
moreOrLessButton = new JButton(collapseIcon);
|
||||
moreOrLessButton.setContentAreaFilled(false);
|
||||
moreOrLessButton.setBorderPainted(false);
|
||||
moreOrLessButton.setMargin(new Insets(0, 0, 0, 0));
|
||||
moreOrLessButton.addActionListener(this);
|
||||
String toolTip =
|
||||
Messages.BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP;
|
||||
moreOrLessButton.setToolTipText(toolTip);
|
||||
borderLabel.add(moreOrLessButton);
|
||||
borderLabel.setSize(borderLabel.getPreferredSize());
|
||||
add(borderLabel);
|
||||
} else {
|
||||
border = new TitledBorder(text);
|
||||
}
|
||||
setBorder(new CompoundBorder(new FocusBorder(this), border));
|
||||
} else {
|
||||
setBorder(new FocusBorder(this));
|
||||
}
|
||||
if (comp != null) {
|
||||
add(comp);
|
||||
}
|
||||
}
|
||||
|
||||
public void setComponent(JComponent comp) {
|
||||
if (this.comp != null) {
|
||||
remove(this.comp);
|
||||
}
|
||||
this.comp = comp;
|
||||
if (!collapsed) {
|
||||
LayoutManager lm = getLayout();
|
||||
if (lm instanceof BorderLayout) {
|
||||
add(comp, BorderLayout.CENTER);
|
||||
} else {
|
||||
add(comp);
|
||||
}
|
||||
}
|
||||
revalidate();
|
||||
}
|
||||
|
||||
public void setValueLabel(String str) {
|
||||
this.valueLabelStr = str;
|
||||
if (label != null) {
|
||||
label.setText(Resources.format(Messages.CURRENT_VALUE,
|
||||
valueLabelStr));
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
if (collapsed) {
|
||||
if (label != null) {
|
||||
remove(label);
|
||||
}
|
||||
add(comp);
|
||||
moreOrLessButton.setIcon(collapseIcon);
|
||||
} else {
|
||||
remove(comp);
|
||||
if (valueLabelStr != null) {
|
||||
if (label == null) {
|
||||
label = new JLabel(Resources.format(Messages.CURRENT_VALUE,
|
||||
valueLabelStr));
|
||||
}
|
||||
add(label);
|
||||
}
|
||||
moreOrLessButton.setIcon(expandIcon);
|
||||
}
|
||||
collapsed = !collapsed;
|
||||
|
||||
JComponent container = (JComponent)getParent();
|
||||
if (container != null &&
|
||||
container.getLayout() instanceof VariableGridLayout) {
|
||||
|
||||
((VariableGridLayout)container.getLayout()).setFillRow(this, !collapsed);
|
||||
container.revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize() {
|
||||
if (getLayout() != null) {
|
||||
// A layout manager has been set, so delegate to it
|
||||
return super.getMinimumSize();
|
||||
}
|
||||
|
||||
if (moreOrLessButton != null) {
|
||||
Dimension d = moreOrLessButton.getMinimumSize();
|
||||
Insets i = getInsets();
|
||||
d.width += i.left + i.right;
|
||||
d.height += i.top + i.bottom;
|
||||
return d;
|
||||
} else {
|
||||
return super.getMinimumSize();
|
||||
}
|
||||
}
|
||||
|
||||
public void doLayout() {
|
||||
if (getLayout() != null) {
|
||||
// A layout manager has been set, so delegate to it
|
||||
super.doLayout();
|
||||
return;
|
||||
}
|
||||
|
||||
Dimension d = getSize();
|
||||
Insets i = getInsets();
|
||||
|
||||
if (collapsed) {
|
||||
if (label != null) {
|
||||
Dimension p = label.getPreferredSize();
|
||||
label.setBounds(i.left,
|
||||
i.top + (d.height - i.top - i.bottom - p.height) / 2,
|
||||
p.width,
|
||||
p.height);
|
||||
}
|
||||
} else {
|
||||
if (comp != null) {
|
||||
comp.setBounds(i.left,
|
||||
i.top,
|
||||
d.width - i.left - i.right,
|
||||
d.height - i.top - i.bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrowIcon implements Icon {
|
||||
private int direction;
|
||||
private JLabel textLabel;
|
||||
|
||||
public ArrowIcon(int direction, JLabel textLabel) {
|
||||
this.direction = direction;
|
||||
this.textLabel = textLabel;
|
||||
}
|
||||
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
int w = getIconWidth();
|
||||
int h = w;
|
||||
Polygon p = new Polygon();
|
||||
switch (direction) {
|
||||
case EAST:
|
||||
p.addPoint(x + 2, y);
|
||||
p.addPoint(x + w - 2, y + h / 2);
|
||||
p.addPoint(x + 2, y + h - 1);
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
p.addPoint(x, y + 2);
|
||||
p.addPoint(x + w / 2, y + h - 2);
|
||||
p.addPoint(x + w - 1, y + 2);
|
||||
break;
|
||||
}
|
||||
g.fillPolygon(p);
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
return getIconHeight();
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
Graphics g = textLabel.getGraphics();
|
||||
if (g != null) {
|
||||
int h = g.getFontMetrics(textLabel.getFont()).getAscent() * 6/10;
|
||||
if (h % 2 == 0) {
|
||||
h += 1; // Make it odd
|
||||
}
|
||||
return h;
|
||||
} else {
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A subclass of <code>TitledBorder</code> which implements an arbitrary border
|
||||
* with the addition of a JComponent (JLabel, JPanel, etc) in the
|
||||
* default position.
|
||||
* <p>
|
||||
* If the border property value is not
|
||||
* specified in the constructor or by invoking the appropriate
|
||||
* set method, the property value will be defined by the current
|
||||
* look and feel, using the following property name in the
|
||||
* Defaults Table:
|
||||
* <ul>
|
||||
* <li>"TitledBorder.border"
|
||||
* </ul>
|
||||
*/
|
||||
protected static class LabeledBorder extends TitledBorder {
|
||||
protected JComponent label;
|
||||
|
||||
private Point compLoc = new Point();
|
||||
|
||||
/**
|
||||
* Creates a LabeledBorder instance.
|
||||
*
|
||||
* @param label the label the border should display
|
||||
*/
|
||||
public LabeledBorder(JComponent label) {
|
||||
this(null, label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LabeledBorder instance with the specified border
|
||||
* and an empty label.
|
||||
*
|
||||
* @param border the border
|
||||
*/
|
||||
public LabeledBorder(Border border) {
|
||||
this(border, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a LabeledBorder instance with the specified border and
|
||||
* label.
|
||||
*
|
||||
* @param border the border
|
||||
* @param label the label the border should display
|
||||
*/
|
||||
public LabeledBorder(Border border, JComponent label) {
|
||||
super(border);
|
||||
|
||||
this.label = label;
|
||||
|
||||
if (label instanceof JLabel &&
|
||||
label.getForeground() instanceof ColorUIResource) {
|
||||
|
||||
label.setForeground(getTitleColor());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Paints the border for the specified component with the
|
||||
* specified position and size.
|
||||
* @param c the component for which this border is being painted
|
||||
* @param g the paint graphics
|
||||
* @param x the x position of the painted border
|
||||
* @param y the y position of the painted border
|
||||
* @param width the width of the painted border
|
||||
* @param height the height of the painted border
|
||||
*/
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
|
||||
Border border = getBorder();
|
||||
|
||||
if (label == null) {
|
||||
if (border != null) {
|
||||
border.paintBorder(c, g, x, y, width, height);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Rectangle grooveRect = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,
|
||||
width - (EDGE_SPACING * 2),
|
||||
height - (EDGE_SPACING * 2));
|
||||
|
||||
Dimension labelDim = label.getPreferredSize();
|
||||
int baseline = label.getBaseline(labelDim.width, labelDim.height);
|
||||
int ascent = Math.max(0, baseline);
|
||||
int descent = labelDim.height - ascent;
|
||||
int diff;
|
||||
Insets insets;
|
||||
|
||||
if (border != null) {
|
||||
insets = border.getBorderInsets(c);
|
||||
} else {
|
||||
insets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
diff = Math.max(0, ascent/2 + TEXT_SPACING - EDGE_SPACING);
|
||||
grooveRect.y += diff;
|
||||
grooveRect.height -= diff;
|
||||
compLoc.y = grooveRect.y + insets.top/2 - (ascent + descent) / 2 - 1;
|
||||
|
||||
int justification;
|
||||
if (c.getComponentOrientation().isLeftToRight()) {
|
||||
justification = LEFT;
|
||||
} else {
|
||||
justification = RIGHT;
|
||||
}
|
||||
|
||||
switch (justification) {
|
||||
case LEFT:
|
||||
compLoc.x = grooveRect.x + TEXT_INSET_H + insets.left;
|
||||
break;
|
||||
case RIGHT:
|
||||
compLoc.x = (grooveRect.x + grooveRect.width
|
||||
- (labelDim.width + TEXT_INSET_H + insets.right));
|
||||
break;
|
||||
}
|
||||
|
||||
// If title is positioned in middle of border AND its fontsize
|
||||
// is greater than the border's thickness, we'll need to paint
|
||||
// the border in sections to leave space for the component's background
|
||||
// to show through the title.
|
||||
//
|
||||
if (border != null) {
|
||||
if (grooveRect.y > compLoc.y - ascent) {
|
||||
Rectangle clipRect = new Rectangle();
|
||||
|
||||
// save original clip
|
||||
Rectangle saveClip = g.getClipBounds();
|
||||
|
||||
// paint strip left of text
|
||||
clipRect.setBounds(saveClip);
|
||||
if (computeIntersection(clipRect, x, y, compLoc.x-1-x, height)) {
|
||||
g.setClip(clipRect);
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
// paint strip right of text
|
||||
clipRect.setBounds(saveClip);
|
||||
if (computeIntersection(clipRect, compLoc.x+ labelDim.width +1, y,
|
||||
x+width-(compLoc.x+ labelDim.width +1), height)) {
|
||||
g.setClip(clipRect);
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
// paint strip below text
|
||||
clipRect.setBounds(saveClip);
|
||||
if (computeIntersection(clipRect,
|
||||
compLoc.x - 1, compLoc.y + ascent + descent,
|
||||
labelDim.width + 2,
|
||||
y + height - compLoc.y - ascent - descent)) {
|
||||
g.setClip(clipRect);
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
// restore clip
|
||||
g.setClip(saveClip);
|
||||
|
||||
} else {
|
||||
border.paintBorder(c, g, grooveRect.x, grooveRect.y,
|
||||
grooveRect.width, grooveRect.height);
|
||||
}
|
||||
|
||||
label.setLocation(compLoc);
|
||||
label.setSize(labelDim);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reinitialize the insets parameter with this Border's current Insets.
|
||||
* @param c the component for which this border insets value applies
|
||||
* @param insets the object to be reinitialized
|
||||
*/
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
Border border = getBorder();
|
||||
if (border != null) {
|
||||
if (border instanceof AbstractBorder) {
|
||||
((AbstractBorder)border).getBorderInsets(c, insets);
|
||||
} else {
|
||||
// Can't reuse border insets because the Border interface
|
||||
// can't be enhanced.
|
||||
Insets i = border.getBorderInsets(c);
|
||||
insets.top = i.top;
|
||||
insets.right = i.right;
|
||||
insets.bottom = i.bottom;
|
||||
insets.left = i.left;
|
||||
}
|
||||
} else {
|
||||
insets.left = insets.top = insets.right = insets.bottom = 0;
|
||||
}
|
||||
|
||||
insets.left += EDGE_SPACING + TEXT_SPACING;
|
||||
insets.right += EDGE_SPACING + TEXT_SPACING;
|
||||
insets.top += EDGE_SPACING + TEXT_SPACING;
|
||||
insets.bottom += EDGE_SPACING + TEXT_SPACING;
|
||||
|
||||
if (c == null || label == null) {
|
||||
return insets;
|
||||
}
|
||||
|
||||
insets.top += label.getHeight();
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the label of the labeled border.
|
||||
*/
|
||||
public JComponent getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the title of the titled border.
|
||||
* param title the title for the border
|
||||
*/
|
||||
public void setLabel(JComponent label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the minimum dimensions this border requires
|
||||
* in order to fully display the border and title.
|
||||
* @param c the component where this border will be drawn
|
||||
*/
|
||||
public Dimension getMinimumSize(Component c) {
|
||||
Insets insets = getBorderInsets(c);
|
||||
Dimension minSize = new Dimension(insets.right + insets.left,
|
||||
insets.top + insets.bottom);
|
||||
minSize.width += label.getWidth();
|
||||
|
||||
return minSize;
|
||||
}
|
||||
|
||||
|
||||
private static boolean computeIntersection(Rectangle dest,
|
||||
int rx, int ry, int rw, int rh) {
|
||||
int x1 = Math.max(rx, dest.x);
|
||||
int x2 = Math.min(rx + rw, dest.x + dest.width);
|
||||
int y1 = Math.max(ry, dest.y);
|
||||
int y2 = Math.min(ry + rh, dest.y + dest.height);
|
||||
dest.x = x1;
|
||||
dest.y = y1;
|
||||
dest.width = x2 - x1;
|
||||
dest.height = y2 - y1;
|
||||
|
||||
if (dest.width <= 0 || dest.height <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static class FocusBorder extends AbstractBorder implements FocusListener {
|
||||
private Component comp;
|
||||
private Color focusColor;
|
||||
private boolean focusLostTemporarily = false;
|
||||
|
||||
public FocusBorder(Component comp) {
|
||||
this.comp = comp;
|
||||
|
||||
comp.addFocusListener(this);
|
||||
|
||||
// This is the best guess for a L&F specific color
|
||||
focusColor = UIManager.getColor("TabbedPane.focus");
|
||||
}
|
||||
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
if (comp.hasFocus() || focusLostTemporarily) {
|
||||
Color color = g.getColor();
|
||||
g.setColor(focusColor);
|
||||
BasicGraphicsUtils.drawDashedRect(g, x, y, width, height);
|
||||
g.setColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
public Insets getBorderInsets(Component c, Insets insets) {
|
||||
insets.set(2, 2, 2, 2);
|
||||
return insets;
|
||||
}
|
||||
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
comp.repaint();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
// We will still paint focus even if lost temporarily
|
||||
focusLostTemporarily = e.isTemporary();
|
||||
if (!focusLostTemporarily) {
|
||||
comp.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
248
jdkSrc/jdk8/sun/tools/jconsole/ClassTab.java
Normal file
248
jdkSrc/jdk8/sun/tools/jconsole/ClassTab.java
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static sun.tools.jconsole.Formatter.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class ClassTab extends Tab implements ActionListener {
|
||||
PlotterPanel loadedClassesMeter;
|
||||
TimeComboBox timeComboBox;
|
||||
private JCheckBox verboseCheckBox;
|
||||
private HTMLPane details;
|
||||
private ClassOverviewPanel overviewPanel;
|
||||
private boolean plotterListening = false;
|
||||
|
||||
private static final String loadedPlotterKey = "loaded";
|
||||
private static final String totalLoadedPlotterKey = "totalLoaded";
|
||||
private static final Color loadedPlotterColor = Plotter.defaultColor;
|
||||
private static final Color totalLoadedPlotterColor = Color.red;
|
||||
|
||||
/*
|
||||
Hierarchy of panels and layouts for this tab:
|
||||
|
||||
ClassTab (BorderLayout)
|
||||
|
||||
North: topPanel (BorderLayout)
|
||||
|
||||
Center: controlPanel (FlowLayout)
|
||||
timeComboBox
|
||||
|
||||
East: topRightPanel (FlowLayout)
|
||||
verboseCheckBox
|
||||
|
||||
Center: plotterPanel (BorderLayout)
|
||||
|
||||
Center: plotter
|
||||
|
||||
South: bottomPanel (BorderLayout)
|
||||
|
||||
Center: details
|
||||
*/
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.CLASSES;
|
||||
}
|
||||
|
||||
public ClassTab(VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
setBorder(new EmptyBorder(4, 4, 3, 4));
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
JPanel plotterPanel = new JPanel(new BorderLayout());
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
add(plotterPanel, BorderLayout.CENTER);
|
||||
add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
|
||||
topPanel.add(controlPanel, BorderLayout.CENTER);
|
||||
|
||||
verboseCheckBox = new JCheckBox(Messages.VERBOSE_OUTPUT);
|
||||
verboseCheckBox.addActionListener(this);
|
||||
verboseCheckBox.setToolTipText(Messages.VERBOSE_OUTPUT_TOOLTIP);
|
||||
JPanel topRightPanel = new JPanel();
|
||||
topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
|
||||
topRightPanel.add(verboseCheckBox);
|
||||
topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
|
||||
|
||||
loadedClassesMeter = new PlotterPanel(Messages.NUMBER_OF_LOADED_CLASSES,
|
||||
Plotter.Unit.NONE, false);
|
||||
loadedClassesMeter.plotter.createSequence(loadedPlotterKey,
|
||||
Messages.LOADED,
|
||||
loadedPlotterColor,
|
||||
true);
|
||||
loadedClassesMeter.plotter.createSequence(totalLoadedPlotterKey,
|
||||
Messages.TOTAL_LOADED,
|
||||
totalLoadedPlotterColor,
|
||||
true);
|
||||
setAccessibleName(loadedClassesMeter.plotter,
|
||||
Messages.CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME);
|
||||
plotterPanel.add(loadedClassesMeter);
|
||||
|
||||
timeComboBox = new TimeComboBox(loadedClassesMeter.plotter);
|
||||
controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
|
||||
Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
|
||||
timeComboBox));
|
||||
|
||||
LabeledComponent.layout(plotterPanel);
|
||||
|
||||
bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
|
||||
new EmptyBorder(10, 10, 10, 10)));
|
||||
|
||||
details = new HTMLPane();
|
||||
setAccessibleName(details, Messages.DETAILS);
|
||||
JScrollPane scrollPane = new JScrollPane(details);
|
||||
scrollPane.setPreferredSize(new Dimension(0, 150));
|
||||
bottomPanel.add(scrollPane, BorderLayout.SOUTH);
|
||||
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
final boolean b = verboseCheckBox.isSelected();
|
||||
workerAdd(new Runnable() {
|
||||
public void run() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
try {
|
||||
proxyClient.getClassLoadingMXBean().setVerbose(b);
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
} catch (IOException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
final ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
|
||||
if (!plotterListening) {
|
||||
proxyClient.addWeakPropertyChangeListener(loadedClassesMeter.plotter);
|
||||
plotterListening = true;
|
||||
}
|
||||
|
||||
return new SwingWorker<Boolean, Object>() {
|
||||
private long clCount, cuCount, ctCount;
|
||||
private boolean isVerbose;
|
||||
private String detailsStr;
|
||||
private long timeStamp;
|
||||
|
||||
public Boolean doInBackground() {
|
||||
try {
|
||||
ClassLoadingMXBean classLoadingMBean = proxyClient.getClassLoadingMXBean();
|
||||
|
||||
clCount = classLoadingMBean.getLoadedClassCount();
|
||||
cuCount = classLoadingMBean.getUnloadedClassCount();
|
||||
ctCount = classLoadingMBean.getTotalLoadedClassCount();
|
||||
isVerbose = classLoadingMBean.isVerbose();
|
||||
detailsStr = formatDetails();
|
||||
timeStamp = System.currentTimeMillis();
|
||||
|
||||
return true;
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void done() {
|
||||
try {
|
||||
if (get()) {
|
||||
loadedClassesMeter.plotter.addValues(timeStamp, clCount, ctCount);
|
||||
|
||||
if (overviewPanel != null) {
|
||||
overviewPanel.updateClassInfo(ctCount, clCount);
|
||||
overviewPanel.getPlotter().addValues(timeStamp, clCount);
|
||||
}
|
||||
|
||||
loadedClassesMeter.setValueLabel(clCount + "");
|
||||
verboseCheckBox.setSelected(isVerbose);
|
||||
details.setText(detailsStr);
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
} catch (ExecutionException ex) {
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String formatDetails() {
|
||||
String text = "<table cellspacing=0 cellpadding=0>";
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
String timeStamp = formatDateTime(time);
|
||||
text += newRow(Messages.TIME, timeStamp);
|
||||
text += newRow(Messages.CURRENT_CLASSES_LOADED, justify(clCount, 5));
|
||||
text += newRow(Messages.TOTAL_CLASSES_LOADED, justify(ctCount, 5));
|
||||
text += newRow(Messages.TOTAL_CLASSES_UNLOADED, justify(cuCount, 5));
|
||||
|
||||
return text;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
OverviewPanel[] getOverviewPanels() {
|
||||
if (overviewPanel == null) {
|
||||
overviewPanel = new ClassOverviewPanel();
|
||||
}
|
||||
return new OverviewPanel[] { overviewPanel };
|
||||
}
|
||||
|
||||
private static class ClassOverviewPanel extends OverviewPanel {
|
||||
ClassOverviewPanel() {
|
||||
super(Messages.CLASSES, loadedPlotterKey, Messages.LOADED, null);
|
||||
}
|
||||
|
||||
private void updateClassInfo(long total, long loaded) {
|
||||
long unloaded = (total - loaded);
|
||||
getInfoLabel().setText(Resources.format(Messages.CLASS_TAB_INFO_LABEL_FORMAT,
|
||||
loaded, unloaded, total));
|
||||
}
|
||||
}
|
||||
}
|
||||
768
jdkSrc/jdk8/sun/tools/jconsole/ConnectDialog.java
Normal file
768
jdkSrc/jdk8/sun/tools/jconsole/ConnectDialog.java
Normal file
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.util.List;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.plaf.basic.BasicRadioButtonUI;
|
||||
import javax.swing.table.*;
|
||||
|
||||
|
||||
|
||||
import static java.awt.BorderLayout.*;
|
||||
import static javax.swing.ListSelectionModel.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ConnectDialog extends InternalDialog
|
||||
implements DocumentListener, FocusListener,
|
||||
ItemListener, ListSelectionListener, KeyListener {
|
||||
|
||||
private static final int COL_NAME = 0;
|
||||
private static final int COL_PID = 1;
|
||||
|
||||
|
||||
JConsole jConsole;
|
||||
JTextField userNameTF, passwordTF;
|
||||
JRadioButton localRadioButton, remoteRadioButton;
|
||||
JLabel localMessageLabel, remoteMessageLabel;
|
||||
JTextField remoteTF;
|
||||
JButton connectButton, cancelButton;
|
||||
JPanel radioButtonPanel;
|
||||
|
||||
private Icon mastheadIcon =
|
||||
new MastheadIcon(Messages.CONNECT_DIALOG_MASTHEAD_TITLE);
|
||||
private Color hintTextColor, disabledTableCellColor;
|
||||
|
||||
// The table of managed VM (local process)
|
||||
JTable vmTable;
|
||||
ManagedVmTableModel vmModel = null;
|
||||
|
||||
JScrollPane localTableScrollPane = null;
|
||||
|
||||
private Action connectAction, cancelAction;
|
||||
|
||||
|
||||
public ConnectDialog(JConsole jConsole) {
|
||||
super(jConsole, Messages.CONNECT_DIALOG_TITLE, true);
|
||||
|
||||
this.jConsole = jConsole;
|
||||
setAccessibleDescription(this,
|
||||
Messages.CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION);
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setResizable(false);
|
||||
Container cp = (JComponent)getContentPane();
|
||||
|
||||
radioButtonPanel = new JPanel(new BorderLayout(0, 12));
|
||||
radioButtonPanel.setBorder(new EmptyBorder(6, 12, 12, 12));
|
||||
ButtonGroup radioButtonGroup = new ButtonGroup();
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
|
||||
statusBar = new JLabel(" ", JLabel.CENTER);
|
||||
setAccessibleName(statusBar,
|
||||
Messages.CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME);
|
||||
|
||||
Font normalLabelFont = statusBar.getFont();
|
||||
Font boldLabelFont = normalLabelFont.deriveFont(Font.BOLD);
|
||||
Font smallLabelFont = normalLabelFont.deriveFont(normalLabelFont.getSize2D() - 1);
|
||||
|
||||
JLabel mastheadLabel = new JLabel(mastheadIcon);
|
||||
setAccessibleName(mastheadLabel,
|
||||
Messages.CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME);
|
||||
|
||||
cp.add(mastheadLabel, NORTH);
|
||||
cp.add(radioButtonPanel, CENTER);
|
||||
cp.add(bottomPanel, SOUTH);
|
||||
|
||||
createActions();
|
||||
|
||||
remoteTF = new JTextField();
|
||||
remoteTF.addActionListener(connectAction);
|
||||
remoteTF.getDocument().addDocumentListener(this);
|
||||
remoteTF.addFocusListener(this);
|
||||
remoteTF.setPreferredSize(remoteTF.getPreferredSize());
|
||||
setAccessibleName(remoteTF,
|
||||
Messages.REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME);
|
||||
|
||||
//
|
||||
// If the VM supports the local attach mechanism (is: Sun
|
||||
// implementation) then the Local Process panel is created.
|
||||
//
|
||||
if (JConsole.isLocalAttachAvailable()) {
|
||||
vmModel = new ManagedVmTableModel();
|
||||
vmTable = new LocalTabJTable(vmModel);
|
||||
vmTable.setSelectionMode(SINGLE_SELECTION);
|
||||
vmTable.setPreferredScrollableViewportSize(new Dimension(400, 250));
|
||||
vmTable.setColumnSelectionAllowed(false);
|
||||
vmTable.addFocusListener(this);
|
||||
vmTable.getSelectionModel().addListSelectionListener(this);
|
||||
|
||||
TableColumnModel columnModel = vmTable.getColumnModel();
|
||||
|
||||
TableColumn pidColumn = columnModel.getColumn(COL_PID);
|
||||
pidColumn.setMaxWidth(getLabelWidth("9999999"));
|
||||
pidColumn.setResizable(false);
|
||||
|
||||
TableColumn cmdLineColumn = columnModel.getColumn(COL_NAME);
|
||||
cmdLineColumn.setResizable(false);
|
||||
|
||||
localRadioButton = new JRadioButton(Messages.LOCAL_PROCESS_COLON);
|
||||
localRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.LOCAL_PROCESS_COLON));
|
||||
localRadioButton.setFont(boldLabelFont);
|
||||
localRadioButton.addItemListener(this);
|
||||
radioButtonGroup.add(localRadioButton);
|
||||
|
||||
JPanel localPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel localTablePanel = new JPanel(new BorderLayout());
|
||||
|
||||
radioButtonPanel.add(localPanel, NORTH);
|
||||
|
||||
localPanel.add(localRadioButton, NORTH);
|
||||
localPanel.add(new Padder(localRadioButton), LINE_START);
|
||||
localPanel.add(localTablePanel, CENTER);
|
||||
|
||||
localTableScrollPane = new JScrollPane(vmTable);
|
||||
|
||||
localTablePanel.add(localTableScrollPane, NORTH);
|
||||
|
||||
localMessageLabel = new JLabel(" ");
|
||||
localMessageLabel.setFont(smallLabelFont);
|
||||
localMessageLabel.setForeground(hintTextColor);
|
||||
localTablePanel.add(localMessageLabel, SOUTH);
|
||||
}
|
||||
|
||||
remoteRadioButton = new JRadioButton(Messages.REMOTE_PROCESS_COLON);
|
||||
remoteRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.REMOTE_PROCESS_COLON));
|
||||
remoteRadioButton.setFont(boldLabelFont);
|
||||
radioButtonGroup.add(remoteRadioButton);
|
||||
|
||||
JPanel remotePanel = new JPanel(new BorderLayout());
|
||||
if (localRadioButton != null) {
|
||||
remotePanel.add(remoteRadioButton, NORTH);
|
||||
remotePanel.add(new Padder(remoteRadioButton), LINE_START);
|
||||
|
||||
Action nextRadioButtonAction =
|
||||
new AbstractAction("nextRadioButton") {
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
JRadioButton rb =
|
||||
(ev.getSource() == localRadioButton) ? remoteRadioButton
|
||||
: localRadioButton;
|
||||
rb.doClick();
|
||||
rb.requestFocus();
|
||||
}
|
||||
};
|
||||
|
||||
localRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
|
||||
remoteRadioButton.getActionMap().put("nextRadioButton", nextRadioButtonAction);
|
||||
|
||||
localRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0),
|
||||
"nextRadioButton");
|
||||
remoteRadioButton.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),
|
||||
"nextRadioButton");
|
||||
} else {
|
||||
JLabel remoteLabel = new JLabel(remoteRadioButton.getText());
|
||||
remoteLabel.setFont(boldLabelFont);
|
||||
remotePanel.add(remoteLabel, NORTH);
|
||||
}
|
||||
radioButtonPanel.add(remotePanel, SOUTH);
|
||||
|
||||
JPanel remoteTFPanel = new JPanel(new BorderLayout());
|
||||
remotePanel.add(remoteTFPanel, CENTER);
|
||||
|
||||
remoteTFPanel.add(remoteTF, NORTH);
|
||||
|
||||
remoteMessageLabel = new JLabel("<html>" + Messages.REMOTE_TF_USAGE + "</html>");
|
||||
remoteMessageLabel.setFont(smallLabelFont);
|
||||
remoteMessageLabel.setForeground(hintTextColor);
|
||||
remoteTFPanel.add(remoteMessageLabel, CENTER);
|
||||
|
||||
JPanel userPwdPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0));
|
||||
userPwdPanel.setBorder(new EmptyBorder(12, 0, 0, 0)); // top padding
|
||||
|
||||
int tfWidth = JConsole.IS_WIN ? 12 : 8;
|
||||
|
||||
userNameTF = new JTextField(tfWidth);
|
||||
userNameTF.addActionListener(connectAction);
|
||||
userNameTF.getDocument().addDocumentListener(this);
|
||||
userNameTF.addFocusListener(this);
|
||||
setAccessibleName(userNameTF,
|
||||
Messages.USERNAME_ACCESSIBLE_NAME);
|
||||
LabeledComponent lc;
|
||||
lc = new LabeledComponent(Messages.USERNAME_COLON_,
|
||||
Resources.getMnemonicInt(Messages.USERNAME_COLON_),
|
||||
userNameTF);
|
||||
lc.label.setFont(boldLabelFont);
|
||||
userPwdPanel.add(lc);
|
||||
|
||||
passwordTF = new JPasswordField(tfWidth);
|
||||
// Heights differ, so fix here
|
||||
passwordTF.setPreferredSize(userNameTF.getPreferredSize());
|
||||
passwordTF.addActionListener(connectAction);
|
||||
passwordTF.getDocument().addDocumentListener(this);
|
||||
passwordTF.addFocusListener(this);
|
||||
setAccessibleName(passwordTF,
|
||||
Messages.PASSWORD_ACCESSIBLE_NAME);
|
||||
|
||||
lc = new LabeledComponent(Messages.PASSWORD_COLON_,
|
||||
Resources.getMnemonicInt(Messages.PASSWORD_COLON_),
|
||||
passwordTF);
|
||||
lc.setBorder(new EmptyBorder(0, 12, 0, 0)); // Left padding
|
||||
lc.label.setFont(boldLabelFont);
|
||||
userPwdPanel.add(lc);
|
||||
|
||||
remoteTFPanel.add(userPwdPanel, SOUTH);
|
||||
|
||||
String connectButtonToolTipText =
|
||||
Messages.CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP;
|
||||
connectButton = new JButton(connectAction);
|
||||
connectButton.setToolTipText(connectButtonToolTipText);
|
||||
|
||||
cancelButton = new JButton(cancelAction);
|
||||
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
|
||||
buttonPanel.setBorder(new EmptyBorder(12, 12, 2, 12));
|
||||
if (JConsole.IS_GTK) {
|
||||
buttonPanel.add(cancelButton);
|
||||
buttonPanel.add(connectButton);
|
||||
} else {
|
||||
buttonPanel.add(connectButton);
|
||||
buttonPanel.add(cancelButton);
|
||||
}
|
||||
bottomPanel.add(buttonPanel, NORTH);
|
||||
|
||||
bottomPanel.add(statusBar, SOUTH);
|
||||
|
||||
updateButtonStates();
|
||||
Utilities.updateTransparency(this);
|
||||
}
|
||||
|
||||
public void revalidate() {
|
||||
// Adjust some colors
|
||||
Color disabledForeground = UIManager.getColor("Label.disabledForeground");
|
||||
if (disabledForeground == null) {
|
||||
// fall back for Nimbus that doesn't support 'Label.disabledForeground'
|
||||
disabledForeground = UIManager.getColor("Label.disabledText");
|
||||
}
|
||||
hintTextColor =
|
||||
ensureContrast(disabledForeground,
|
||||
UIManager.getColor("Panel.background"));
|
||||
disabledTableCellColor =
|
||||
ensureContrast(new Color(0x808080),
|
||||
UIManager.getColor("Table.background"));
|
||||
|
||||
if (remoteMessageLabel != null) {
|
||||
remoteMessageLabel.setForeground(hintTextColor);
|
||||
// Update html color setting
|
||||
String colorStr =
|
||||
String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
|
||||
remoteMessageLabel.setText("<html><font color=#" + colorStr + ">" +
|
||||
Messages.REMOTE_TF_USAGE);
|
||||
}
|
||||
if (localMessageLabel != null) {
|
||||
localMessageLabel.setForeground(hintTextColor);
|
||||
// Update html color setting
|
||||
valueChanged(null);
|
||||
}
|
||||
|
||||
super.revalidate();
|
||||
}
|
||||
|
||||
private void createActions() {
|
||||
connectAction = new AbstractAction(Messages.CONNECT) {
|
||||
/* init */ {
|
||||
putValue(Action.MNEMONIC_KEY, Resources.getMnemonicInt(Messages.CONNECT));
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
if (!isEnabled() || !isVisible()) {
|
||||
return;
|
||||
}
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
|
||||
if (remoteRadioButton.isSelected()) {
|
||||
String txt = remoteTF.getText().trim();
|
||||
String userName = userNameTF.getText().trim();
|
||||
userName = userName.equals("") ? null : userName;
|
||||
String password = passwordTF.getText();
|
||||
password = password.equals("") ? null : password;
|
||||
try {
|
||||
if (txt.startsWith(JConsole.ROOT_URL)) {
|
||||
String url = txt;
|
||||
jConsole.addUrl(url, userName, password, false);
|
||||
remoteTF.setText(JConsole.ROOT_URL);
|
||||
return;
|
||||
} else {
|
||||
String host = remoteTF.getText().trim();
|
||||
String port = "0";
|
||||
int index = host.lastIndexOf(":");
|
||||
if (index >= 0) {
|
||||
port = host.substring(index + 1);
|
||||
host = host.substring(0, index);
|
||||
}
|
||||
if (host.length() > 0 && port.length() > 0) {
|
||||
int p = Integer.parseInt(port.trim());
|
||||
jConsole.addHost(host, p, userName, password);
|
||||
remoteTF.setText("");
|
||||
userNameTF.setText("");
|
||||
passwordTF.setText("");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
statusBar.setText(ex.toString());
|
||||
}
|
||||
setVisible(true);
|
||||
} else if (localRadioButton != null && localRadioButton.isSelected()) {
|
||||
// Try to connect to selected VM. If a connection
|
||||
// cannot be established for some reason (the process has
|
||||
// terminated for example) then keep the dialog open showing
|
||||
// the connect error.
|
||||
//
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
jConsole.addVmid(vmModel.vmAt(row));
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cancelAction = new AbstractAction(Messages.CANCEL) {
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// a label used solely for calculating the width
|
||||
private static JLabel tmpLabel = new JLabel();
|
||||
public static int getLabelWidth(String text) {
|
||||
tmpLabel.setText(text);
|
||||
return (int) tmpLabel.getPreferredSize().getWidth() + 1;
|
||||
}
|
||||
|
||||
private class LocalTabJTable extends JTable {
|
||||
ManagedVmTableModel vmModel;
|
||||
Border rendererBorder = new EmptyBorder(0, 6, 0, 6);
|
||||
|
||||
public LocalTabJTable(ManagedVmTableModel model) {
|
||||
super(model);
|
||||
this.vmModel = model;
|
||||
|
||||
// Remove vertical lines, expect for GTK L&F.
|
||||
// (because GTK doesn't show header dividers)
|
||||
if (!JConsole.IS_GTK) {
|
||||
setShowVerticalLines(false);
|
||||
setIntercellSpacing(new Dimension(0, 1));
|
||||
}
|
||||
|
||||
// Double-click handler
|
||||
addMouseListener(new MouseAdapter() {
|
||||
public void mouseClicked(MouseEvent evt) {
|
||||
if (evt.getClickCount() == 2) {
|
||||
connectButton.doClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Enter should call default action
|
||||
getActionMap().put("connect", connectAction);
|
||||
InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "connect");
|
||||
}
|
||||
|
||||
public String getToolTipText(MouseEvent e) {
|
||||
String tip = null;
|
||||
java.awt.Point p = e.getPoint();
|
||||
int rowIndex = rowAtPoint(p);
|
||||
int colIndex = columnAtPoint(p);
|
||||
int realColumnIndex = convertColumnIndexToModel(colIndex);
|
||||
|
||||
if (realColumnIndex == COL_NAME) {
|
||||
LocalVirtualMachine vmd = vmModel.vmAt(rowIndex);
|
||||
tip = vmd.toString();
|
||||
}
|
||||
return tip;
|
||||
}
|
||||
|
||||
public TableCellRenderer getCellRenderer(int row, int column) {
|
||||
return new DefaultTableCellRenderer() {
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
Object value,
|
||||
boolean isSelected,
|
||||
boolean hasFocus,
|
||||
int row,
|
||||
int column) {
|
||||
Component comp =
|
||||
super.getTableCellRendererComponent(table, value, isSelected,
|
||||
hasFocus, row, column);
|
||||
|
||||
if (!isSelected) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(row);
|
||||
if (!lvm.isManageable() && !lvm.isAttachable()) {
|
||||
comp.setForeground(disabledTableCellColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (comp instanceof JLabel) {
|
||||
JLabel label = (JLabel)comp;
|
||||
label.setBorder(rendererBorder);
|
||||
|
||||
if (value instanceof Integer) {
|
||||
label.setHorizontalAlignment(JLabel.RIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void setConnectionParameters(String url,
|
||||
String host,
|
||||
int port,
|
||||
String userName,
|
||||
String password,
|
||||
String msg) {
|
||||
if ((url != null && url.length() > 0) ||
|
||||
(host != null && host.length() > 0 && port > 0)) {
|
||||
|
||||
remoteRadioButton.setSelected(true);
|
||||
if (url != null && url.length() > 0) {
|
||||
remoteTF.setText(url);
|
||||
} else {
|
||||
remoteTF.setText(host+":"+port);
|
||||
}
|
||||
userNameTF.setText((userName != null) ? userName : "");
|
||||
passwordTF.setText((password != null) ? password : "");
|
||||
|
||||
statusBar.setText((msg != null) ? msg : "");
|
||||
if (getPreferredSize().width > getWidth()) {
|
||||
pack();
|
||||
}
|
||||
remoteTF.requestFocus();
|
||||
remoteTF.selectAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void itemStateChanged(ItemEvent ev) {
|
||||
if (!localRadioButton.isSelected()) {
|
||||
vmTable.getSelectionModel().clearSelection();
|
||||
}
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
private void updateButtonStates() {
|
||||
boolean connectEnabled = false;
|
||||
|
||||
if (remoteRadioButton.isSelected()) {
|
||||
connectEnabled = JConsole.isValidRemoteString(remoteTF.getText());
|
||||
} else if (localRadioButton != null && localRadioButton.isSelected()) {
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(row);
|
||||
connectEnabled = (lvm.isManageable() || lvm.isAttachable());
|
||||
}
|
||||
}
|
||||
|
||||
connectAction.setEnabled(connectEnabled);
|
||||
}
|
||||
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void focusGained(FocusEvent e) {
|
||||
Object source = e.getSource();
|
||||
Component opposite = e.getOppositeComponent();
|
||||
|
||||
if (!e.isTemporary() &&
|
||||
source instanceof JTextField &&
|
||||
opposite instanceof JComponent &&
|
||||
SwingUtilities.getRootPane(opposite) == getRootPane()) {
|
||||
|
||||
((JTextField)source).selectAll();
|
||||
}
|
||||
|
||||
if (source == remoteTF) {
|
||||
remoteRadioButton.setSelected(true);
|
||||
} else if (source == vmTable) {
|
||||
localRadioButton.setSelected(true);
|
||||
if (vmModel.getRowCount() == 1) {
|
||||
// if there's only one process then select the row
|
||||
vmTable.setRowSelectionInterval(0, 0);
|
||||
}
|
||||
}
|
||||
updateButtonStates();
|
||||
}
|
||||
|
||||
public void focusLost(FocusEvent e) {
|
||||
}
|
||||
|
||||
public void keyTyped(KeyEvent e) {
|
||||
char c = e.getKeyChar();
|
||||
if (c == KeyEvent.VK_ESCAPE) {
|
||||
setVisible(false);
|
||||
} else if (!(Character.isDigit(c) ||
|
||||
c == KeyEvent.VK_BACK_SPACE ||
|
||||
c == KeyEvent.VK_DELETE)) {
|
||||
getToolkit().beep();
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisible(boolean b) {
|
||||
boolean wasVisible = isVisible();
|
||||
super.setVisible(b);
|
||||
if (b && !wasVisible) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (remoteRadioButton.isSelected()) {
|
||||
remoteTF.requestFocus();
|
||||
remoteTF.selectAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void keyPressed(KeyEvent e) {
|
||||
}
|
||||
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
|
||||
// ListSelectionListener interface
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
updateButtonStates();
|
||||
String labelText = " "; // Non-empty to reserve vertical space
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(row);
|
||||
if (!lvm.isManageable()) {
|
||||
if (lvm.isAttachable()) {
|
||||
labelText = Messages.MANAGEMENT_WILL_BE_ENABLED;
|
||||
} else {
|
||||
labelText = Messages.MANAGEMENT_NOT_ENABLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
String colorStr =
|
||||
String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
|
||||
localMessageLabel.setText("<html><font color=#" + colorStr + ">" + labelText);
|
||||
}
|
||||
// ----
|
||||
|
||||
|
||||
// Refresh the list of managed VMs
|
||||
public void refresh() {
|
||||
if (vmModel != null) {
|
||||
// Remember selection
|
||||
LocalVirtualMachine selected = null;
|
||||
int row = vmTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
selected = vmModel.vmAt(row);
|
||||
}
|
||||
|
||||
vmModel.refresh();
|
||||
|
||||
int selectRow = -1;
|
||||
int n = vmModel.getRowCount();
|
||||
if (selected != null) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
LocalVirtualMachine lvm = vmModel.vmAt(i);
|
||||
if (selected.vmid() == lvm.vmid() &&
|
||||
selected.toString().equals(lvm.toString())) {
|
||||
|
||||
selectRow = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selectRow > -1) {
|
||||
vmTable.setRowSelectionInterval(selectRow, selectRow);
|
||||
} else {
|
||||
vmTable.getSelectionModel().clearSelection();
|
||||
}
|
||||
|
||||
Dimension dim = vmTable.getPreferredSize();
|
||||
|
||||
// Tricky. Reduce height by one to avoid double line at bottom,
|
||||
// but that causes a scroll bar to appear, so remove it.
|
||||
dim.height = Math.min(dim.height-1, 100);
|
||||
localTableScrollPane.setVerticalScrollBarPolicy((dim.height < 100)
|
||||
? JScrollPane.VERTICAL_SCROLLBAR_NEVER
|
||||
: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
|
||||
localTableScrollPane.getViewport().setMinimumSize(dim);
|
||||
localTableScrollPane.getViewport().setPreferredSize(dim);
|
||||
}
|
||||
pack();
|
||||
setLocationRelativeTo(jConsole);
|
||||
}
|
||||
|
||||
// Represents the list of managed VMs as a tabular data model.
|
||||
private static class ManagedVmTableModel extends AbstractTableModel {
|
||||
private static String[] columnNames = {
|
||||
Messages.COLUMN_NAME,
|
||||
Messages.COLUMN_PID,
|
||||
};
|
||||
|
||||
private List<LocalVirtualMachine> vmList;
|
||||
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
public String getColumnName(int col) {
|
||||
return columnNames[col];
|
||||
}
|
||||
|
||||
public synchronized int getRowCount() {
|
||||
return vmList.size();
|
||||
}
|
||||
|
||||
public synchronized Object getValueAt(int row, int col) {
|
||||
assert col >= 0 && col <= columnNames.length;
|
||||
LocalVirtualMachine vm = vmList.get(row);
|
||||
switch (col) {
|
||||
case COL_NAME: return vm.displayName();
|
||||
case COL_PID: return vm.vmid();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Class<?> getColumnClass(int column) {
|
||||
switch (column) {
|
||||
case COL_NAME: return String.class;
|
||||
case COL_PID: return Integer.class;
|
||||
default: return super.getColumnClass(column);
|
||||
}
|
||||
}
|
||||
|
||||
public ManagedVmTableModel() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
public synchronized LocalVirtualMachine vmAt(int pos) {
|
||||
return vmList.get(pos);
|
||||
}
|
||||
|
||||
public synchronized void refresh() {
|
||||
Map<Integer, LocalVirtualMachine> map =
|
||||
LocalVirtualMachine.getAllVirtualMachines();
|
||||
vmList = new ArrayList<LocalVirtualMachine>();
|
||||
vmList.addAll(map.values());
|
||||
|
||||
// data has changed
|
||||
fireTableDataChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// A blank component that takes up as much space as the
|
||||
// button part of a JRadioButton.
|
||||
private static class Padder extends JPanel {
|
||||
JRadioButton radioButton;
|
||||
|
||||
Padder(JRadioButton radioButton) {
|
||||
this.radioButton = radioButton;
|
||||
|
||||
setAccessibleName(this, Messages.BLANK);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
Rectangle r = getTextRectangle(radioButton);
|
||||
int w = (r != null && r.x > 8) ? r.x : 22;
|
||||
|
||||
return new Dimension(w, 0);
|
||||
}
|
||||
|
||||
private static Rectangle getTextRectangle(AbstractButton button) {
|
||||
String text = button.getText();
|
||||
Icon icon = (button.isEnabled()) ? button.getIcon() : button.getDisabledIcon();
|
||||
|
||||
if (icon == null && button.getUI() instanceof BasicRadioButtonUI) {
|
||||
icon = ((BasicRadioButtonUI)button.getUI()).getDefaultIcon();
|
||||
}
|
||||
|
||||
if ((icon == null) && (text == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Rectangle paintIconR = new Rectangle();
|
||||
Rectangle paintTextR = new Rectangle();
|
||||
Rectangle paintViewR = new Rectangle();
|
||||
Insets paintViewInsets = new Insets(0, 0, 0, 0);
|
||||
|
||||
paintViewInsets = button.getInsets(paintViewInsets);
|
||||
paintViewR.x = paintViewInsets.left;
|
||||
paintViewR.y = paintViewInsets.top;
|
||||
paintViewR.width = button.getWidth() - (paintViewInsets.left + paintViewInsets.right);
|
||||
paintViewR.height = button.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
|
||||
|
||||
Graphics g = button.getGraphics();
|
||||
if (g == null) {
|
||||
return null;
|
||||
}
|
||||
SwingUtilities.layoutCompoundLabel(button,
|
||||
g.getFontMetrics(),
|
||||
text,
|
||||
icon,
|
||||
button.getVerticalAlignment(),
|
||||
button.getHorizontalAlignment(),
|
||||
button.getVerticalTextPosition(),
|
||||
button.getHorizontalTextPosition(),
|
||||
paintViewR,
|
||||
paintIconR,
|
||||
paintTextR,
|
||||
button.getIconTextGap());
|
||||
|
||||
return paintTextR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
197
jdkSrc/jdk8/sun/tools/jconsole/CreateMBeanDialog.java
Normal file
197
jdkSrc/jdk8/sun/tools/jconsole/CreateMBeanDialog.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
|
||||
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class CreateMBeanDialog extends InternalDialog
|
||||
implements ActionListener {
|
||||
JConsole jConsole;
|
||||
JComboBox<ProxyClient> connections;
|
||||
JButton createMBeanButton, unregisterMBeanButton, cancelButton;
|
||||
|
||||
private static final String HOTSPOT_MBEAN =
|
||||
"sun.management.HotspotInternal";
|
||||
private static final String HOTSPOT_MBEAN_OBJECTNAME =
|
||||
"sun.management:type=HotspotInternal";
|
||||
public CreateMBeanDialog(JConsole jConsole) {
|
||||
super(jConsole, "JConsole: Hotspot MBeans", true);
|
||||
|
||||
this.jConsole = jConsole;
|
||||
setAccessibleDescription(this,
|
||||
Messages.HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION);
|
||||
Container cp = getContentPane();
|
||||
((JComponent)cp).setBorder(new EmptyBorder(10, 10, 4, 10));
|
||||
|
||||
JPanel centerPanel = new JPanel(new VariableGridLayout(0,
|
||||
1,
|
||||
4,
|
||||
4,
|
||||
false,
|
||||
true));
|
||||
cp.add(centerPanel, BorderLayout.CENTER);
|
||||
connections = new JComboBox<ProxyClient>();
|
||||
updateConnections();
|
||||
|
||||
centerPanel.add(new LabeledComponent(Resources.format(Messages.MANAGE_HOTSPOT_MBEANS_IN_COLON_),
|
||||
connections));
|
||||
|
||||
JPanel bottomPanel = new JPanel(new BorderLayout());
|
||||
cp.add(bottomPanel, BorderLayout.SOUTH);
|
||||
|
||||
JPanel buttonPanel = new JPanel();
|
||||
bottomPanel.add(buttonPanel, BorderLayout.NORTH);
|
||||
buttonPanel.add(createMBeanButton =
|
||||
new JButton(Messages.CREATE));
|
||||
buttonPanel.add(unregisterMBeanButton =
|
||||
new JButton(Messages.UNREGISTER));
|
||||
buttonPanel.add(cancelButton =
|
||||
new JButton(Messages.CANCEL));
|
||||
|
||||
statusBar = new JLabel(" ", JLabel.CENTER);
|
||||
bottomPanel.add(statusBar, BorderLayout.SOUTH);
|
||||
|
||||
createMBeanButton.addActionListener(this);
|
||||
unregisterMBeanButton.addActionListener(this);
|
||||
cancelButton.addActionListener(this);
|
||||
|
||||
LabeledComponent.layout(centerPanel);
|
||||
pack();
|
||||
setLocationRelativeTo(jConsole);
|
||||
}
|
||||
|
||||
private void updateConnections() {
|
||||
List<VMInternalFrame> frames = jConsole.getInternalFrames();
|
||||
TreeSet<ProxyClient> data =
|
||||
new TreeSet<ProxyClient>(new Comparator<ProxyClient>() {
|
||||
public int compare(ProxyClient o1, ProxyClient o2) {
|
||||
// TODO: Need to understand how this method being used?
|
||||
return o1.connectionName().compareTo(o2.connectionName());
|
||||
}
|
||||
});
|
||||
|
||||
if (frames.size() == 0) {
|
||||
JComponent cp = (JComponent)jConsole.getContentPane();
|
||||
Component comp = ((BorderLayout)cp.getLayout()).
|
||||
getLayoutComponent(BorderLayout.CENTER);
|
||||
if (comp instanceof VMPanel) {
|
||||
VMPanel vmpanel = (VMPanel) comp;
|
||||
ProxyClient client = vmpanel.getProxyClient(false);
|
||||
if (client != null && client.hasPlatformMXBeans()) {
|
||||
data.add(client);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (VMInternalFrame f : frames) {
|
||||
ProxyClient client = f.getVMPanel().getProxyClient(false);
|
||||
if (client != null && client.hasPlatformMXBeans()) {
|
||||
data.add(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
connections.invalidate();
|
||||
connections.setModel(new DefaultComboBoxModel<ProxyClient>
|
||||
(data.toArray(new ProxyClient[data.size()])));
|
||||
connections.validate();
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent ev) {
|
||||
setVisible(false);
|
||||
statusBar.setText("");
|
||||
if (ev.getSource() != cancelButton) {
|
||||
new Thread("CreateMBeanDialog.actionPerformed") {
|
||||
public void run() {
|
||||
try {
|
||||
Object c = connections.getSelectedItem();
|
||||
if(c == null) return;
|
||||
if(ev.getSource() == createMBeanButton) {
|
||||
MBeanServerConnection connection =
|
||||
((ProxyClient) c).
|
||||
getMBeanServerConnection();
|
||||
connection.createMBean(HOTSPOT_MBEAN, null);
|
||||
} else {
|
||||
if(ev.getSource() == unregisterMBeanButton) {
|
||||
MBeanServerConnection connection =
|
||||
((ProxyClient) c).
|
||||
getMBeanServerConnection();
|
||||
connection.unregisterMBean(new
|
||||
ObjectName(HOTSPOT_MBEAN_OBJECTNAME));
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch(InstanceAlreadyExistsException e) {
|
||||
statusBar.setText(Messages.ERROR_COLON_MBEANS_ALREADY_EXIST);
|
||||
} catch(InstanceNotFoundException e) {
|
||||
statusBar.setText(Messages.ERROR_COLON_MBEANS_DO_NOT_EXIST);
|
||||
} catch(Exception e) {
|
||||
statusBar.setText(e.toString());
|
||||
}
|
||||
setVisible(true);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void setVisible(boolean b) {
|
||||
boolean wasVisible = isVisible();
|
||||
|
||||
if(b) {
|
||||
setLocationRelativeTo(jConsole);
|
||||
invalidate();
|
||||
updateConnections();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
super.setVisible(b);
|
||||
|
||||
|
||||
if (b && !wasVisible) {
|
||||
// Need to delay this to make focus stick
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
connections.requestFocus();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
126
jdkSrc/jdk8/sun/tools/jconsole/ExceptionSafePlugin.java
Normal file
126
jdkSrc/jdk8/sun/tools/jconsole/ExceptionSafePlugin.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import com.sun.tools.jconsole.JConsolePlugin;
|
||||
|
||||
/**
|
||||
* Proxy that shields GUI from plug-in exceptions.
|
||||
*
|
||||
*/
|
||||
final class ExceptionSafePlugin extends JConsolePlugin {
|
||||
|
||||
private static boolean ignoreExceptions;
|
||||
private final JConsolePlugin plugin;
|
||||
|
||||
public ExceptionSafePlugin(JConsolePlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, JPanel> getTabs() {
|
||||
try {
|
||||
return plugin.getTabs();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
try {
|
||||
return plugin.newSwingWorker();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
plugin.dispose();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void executeSwingWorker(SwingWorker<?, ?> sw) {
|
||||
try {
|
||||
sw.execute();
|
||||
} catch (RuntimeException e) {
|
||||
handleException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleException(Exception e) {
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Plug-in exception:");
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
if (!ignoreExceptions) {
|
||||
showExceptionDialog(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showExceptionDialog(Exception e) {
|
||||
Object[] buttonTexts = {
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_OK,
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT,
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE
|
||||
};
|
||||
|
||||
String message = String.format(
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_MESSAGE,
|
||||
plugin.getClass().getSimpleName(),
|
||||
String.valueOf(e.getMessage())
|
||||
);
|
||||
|
||||
int buttonIndex = JOptionPane.showOptionDialog(
|
||||
null,
|
||||
message,
|
||||
Messages.PLUGIN_EXCEPTION_DIALOG_TITLE,
|
||||
JOptionPane.YES_NO_CANCEL_OPTION,
|
||||
JOptionPane.ERROR_MESSAGE,
|
||||
null,
|
||||
buttonTexts,
|
||||
buttonTexts[0]
|
||||
);
|
||||
|
||||
if (buttonIndex == 1) {
|
||||
System.exit(0);
|
||||
}
|
||||
ignoreExceptions = buttonIndex == 2;
|
||||
}
|
||||
}
|
||||
272
jdkSrc/jdk8/sun/tools/jconsole/Formatter.java
Normal file
272
jdkSrc/jdk8/sun/tools/jconsole/Formatter.java
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
class Formatter {
|
||||
final static long SECOND = 1000;
|
||||
final static long MINUTE = 60 * SECOND;
|
||||
final static long HOUR = 60 * MINUTE;
|
||||
final static long DAY = 24 * HOUR;
|
||||
|
||||
final static String cr = System.getProperty("line.separator");
|
||||
|
||||
final static DateFormat timeDF = new SimpleDateFormat("HH:mm");
|
||||
private final static DateFormat timeWithSecondsDF = new SimpleDateFormat("HH:mm:ss");
|
||||
private final static DateFormat dateDF = new SimpleDateFormat("yyyy-MM-dd");
|
||||
private final static String decimalZero =
|
||||
new DecimalFormatSymbols().getDecimalSeparator() + "0";
|
||||
|
||||
static String formatTime(long t) {
|
||||
String str;
|
||||
if (t < 1 * MINUTE) {
|
||||
String seconds = String.format("%.3f", t / (double)SECOND);
|
||||
str = Resources.format(Messages.DURATION_SECONDS, seconds);
|
||||
} else {
|
||||
long remaining = t;
|
||||
long days = remaining / DAY;
|
||||
remaining %= 1 * DAY;
|
||||
long hours = remaining / HOUR;
|
||||
remaining %= 1 * HOUR;
|
||||
long minutes = remaining / MINUTE;
|
||||
|
||||
if (t >= 1 * DAY) {
|
||||
str = Resources.format(Messages.DURATION_DAYS_HOURS_MINUTES,
|
||||
days, hours, minutes);
|
||||
} else if (t >= 1 * HOUR) {
|
||||
str = Resources.format(Messages.DURATION_HOURS_MINUTES,
|
||||
hours, minutes);
|
||||
} else {
|
||||
str = Resources.format(Messages.DURATION_MINUTES, minutes);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static String formatNanoTime(long t) {
|
||||
long ms = t / 1000000;
|
||||
return formatTime(ms);
|
||||
}
|
||||
|
||||
|
||||
static String formatClockTime(long time) {
|
||||
return timeDF.format(time);
|
||||
}
|
||||
|
||||
static String formatDate(long time) {
|
||||
return dateDF.format(time);
|
||||
}
|
||||
|
||||
static String formatDateTime(long time) {
|
||||
return dateDF.format(time) + " " + timeWithSecondsDF.format(time);
|
||||
}
|
||||
|
||||
static DateFormat getDateTimeFormat(String dtfStr) {
|
||||
int dateStyle = -1;
|
||||
int timeStyle = -1;
|
||||
|
||||
if (dtfStr.startsWith("SHORT")) {
|
||||
dateStyle = DateFormat.SHORT;
|
||||
} else if (dtfStr.startsWith("MEDIUM")) {
|
||||
dateStyle = DateFormat.MEDIUM;
|
||||
} else if (dtfStr.startsWith("LONG")) {
|
||||
dateStyle = DateFormat.LONG;
|
||||
} else if (dtfStr.startsWith("FULL")) {
|
||||
dateStyle = DateFormat.FULL;
|
||||
}
|
||||
|
||||
if (dtfStr.endsWith("SHORT")) {
|
||||
timeStyle = DateFormat.SHORT;
|
||||
} else if (dtfStr.endsWith("MEDIUM")) {
|
||||
timeStyle = DateFormat.MEDIUM;
|
||||
} else if (dtfStr.endsWith("LONG")) {
|
||||
timeStyle = DateFormat.LONG;
|
||||
} else if (dtfStr.endsWith("FULL")) {
|
||||
timeStyle = DateFormat.FULL;
|
||||
}
|
||||
|
||||
if (dateStyle != -1 && timeStyle != -1) {
|
||||
return DateFormat.getDateTimeInstance(dateStyle, timeStyle);
|
||||
} else if (dtfStr.length() > 0) {
|
||||
return new SimpleDateFormat(dtfStr);
|
||||
} else {
|
||||
return DateFormat.getDateTimeInstance();
|
||||
}
|
||||
}
|
||||
|
||||
static double toExcelTime(long time) {
|
||||
// Excel is bug compatible with Lotus 1-2-3 and pretends
|
||||
// that 1900 was a leap year, so count from 1899-12-30.
|
||||
// Note that the month index is zero-based in Calendar.
|
||||
Calendar cal = new GregorianCalendar(1899, 11, 30);
|
||||
|
||||
// Adjust for the fact that now may be DST but then wasn't
|
||||
Calendar tmpCal = new GregorianCalendar();
|
||||
tmpCal.setTimeInMillis(time);
|
||||
int dst = tmpCal.get(Calendar.DST_OFFSET);
|
||||
if (dst > 0) {
|
||||
cal.set(Calendar.DST_OFFSET, dst);
|
||||
}
|
||||
|
||||
long millisSince1900 = time - cal.getTimeInMillis();
|
||||
double value = (double)millisSince1900 / (24 * 60 * 60 * 1000);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static String[] formatKByteStrings(long... bytes) {
|
||||
int n = bytes.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (bytes[i] > 0) {
|
||||
bytes[i] /= 1024;
|
||||
}
|
||||
}
|
||||
String[] strings = formatLongs(bytes);
|
||||
for (int i = 0; i < n; i++) {
|
||||
strings[i] = Resources.format(Messages.KBYTES, strings[i]);
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
static String formatKBytes(long bytes) {
|
||||
if (bytes == -1) {
|
||||
return Resources.format(Messages.KBYTES, "-1");
|
||||
}
|
||||
|
||||
long kb = bytes / 1024;
|
||||
return Resources.format(Messages.KBYTES, justify(kb, 10));
|
||||
}
|
||||
|
||||
|
||||
static String formatBytes(long v, boolean html) {
|
||||
return formatBytes(v, v, html);
|
||||
}
|
||||
|
||||
static String formatBytes(long v, long vMax) {
|
||||
return formatBytes(v, vMax, false);
|
||||
}
|
||||
|
||||
static String formatBytes(long v, long vMax, boolean html) {
|
||||
String s;
|
||||
|
||||
int exp = (int)Math.log10((double)vMax);
|
||||
|
||||
if (exp < 3) {
|
||||
s = Resources.format(Messages.SIZE_BYTES, v);
|
||||
} else if (exp < 6) {
|
||||
s = Resources.format(Messages.SIZE_KB, trimDouble(v / Math.pow(10.0, 3)));
|
||||
} else if (exp < 9) {
|
||||
s = Resources.format(Messages.SIZE_MB, trimDouble(v / Math.pow(10.0, 6)));
|
||||
} else {
|
||||
s = Resources.format(Messages.SIZE_GB, trimDouble(v / Math.pow(10.0, 9)));
|
||||
}
|
||||
if (html) {
|
||||
s = s.replace(" ", " ");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the input value rounded to one decimal place. If after
|
||||
* rounding the string ends in the (locale-specific) decimal point
|
||||
* followed by a zero then trim that off as well.
|
||||
*/
|
||||
private static String trimDouble(double d) {
|
||||
String s = String.format("%.1f", d);
|
||||
if (s.length() > 3 && s.endsWith(decimalZero)) {
|
||||
s = s.substring(0, s.length()-2);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static String formatLong(long value) {
|
||||
return String.format("%,d", value);
|
||||
}
|
||||
|
||||
static String[] formatLongs(long... longs) {
|
||||
int n = longs.length;
|
||||
int size = 0;
|
||||
String[] strings = new String[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
strings[i] = formatLong(longs[i]);
|
||||
size = Math.max(size, strings[i].length());
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
strings[i] = justify(strings[i], size);
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
|
||||
// A poor attempt at right-justifying for numerical data
|
||||
static String justify(long value, int size) {
|
||||
return justify(formatLong(value), size);
|
||||
}
|
||||
|
||||
static String justify(String str, int size) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
buf.append("<TT>");
|
||||
int n = size - str.length();
|
||||
for (int i = 0; i < n; i++) {
|
||||
buf.append(" ");
|
||||
}
|
||||
buf.append(str);
|
||||
buf.append("</TT>");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
static String newRow(String label, String value) {
|
||||
return newRow(label, value, 2);
|
||||
}
|
||||
|
||||
static String newRow(String label, String value, int columnPerRow) {
|
||||
if (label == null) {
|
||||
label = "";
|
||||
} else {
|
||||
label += ": ";
|
||||
}
|
||||
label = "<th nowrap align=right valign=top>" + label;
|
||||
value = "<td colspan=" + (columnPerRow-1) + "> <font size =-1>" + value;
|
||||
|
||||
return "<tr>" + label + value + "</tr>";
|
||||
}
|
||||
|
||||
static String newRow(String label1, String value1,
|
||||
String label2, String value2) {
|
||||
label1 = "<th nowrap align=right valign=top>" + label1 + ": ";
|
||||
value1 = "<td><font size =-1>" + value1;
|
||||
label2 = "<th nowrap align=right valign=top>" + label2 + ": ";
|
||||
value2 = "<td><font size =-1>" + value2;
|
||||
|
||||
return "<tr>" + label1 + value1 + label2 + value2 + "</tr>";
|
||||
}
|
||||
|
||||
}
|
||||
65
jdkSrc/jdk8/sun/tools/jconsole/HTMLPane.java
Normal file
65
jdkSrc/jdk8/sun/tools/jconsole/HTMLPane.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class HTMLPane extends JEditorPane {
|
||||
private boolean hasSelection = false;
|
||||
|
||||
public HTMLPane() {
|
||||
setContentType("text/html");
|
||||
setEditable(false);
|
||||
((DefaultCaret)getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
|
||||
addCaretListener(new CaretListener() {
|
||||
// Listen for selection changes
|
||||
public void caretUpdate(CaretEvent e) {
|
||||
setHasSelection(e.getDot() != e.getMark());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void setHasSelection(boolean b) {
|
||||
hasSelection = b;
|
||||
}
|
||||
|
||||
public synchronized boolean getHasSelection() {
|
||||
return hasSelection;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
// Apply update only if a selection is not active
|
||||
if (!getHasSelection()) {
|
||||
// JEditorPane does not automatically pick up fg color
|
||||
String textColor =
|
||||
String.format("%06x", getForeground().getRGB() & 0xFFFFFF);
|
||||
super.setText("<html><body text=#"+textColor+">" + text + "</body></html>");
|
||||
}
|
||||
}
|
||||
}
|
||||
127
jdkSrc/jdk8/sun/tools/jconsole/InternalDialog.java
Normal file
127
jdkSrc/jdk8/sun/tools/jconsole/InternalDialog.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
|
||||
import static javax.swing.JLayeredPane.*;
|
||||
|
||||
/**
|
||||
* Used instead of JDialog in a JDesktopPane/JInternalFrame environment.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class InternalDialog extends JInternalFrame {
|
||||
protected JLabel statusBar;
|
||||
|
||||
public InternalDialog(JConsole jConsole, String title, boolean modal) {
|
||||
super(title, true, true, false, false);
|
||||
|
||||
setLayer(PALETTE_LAYER);
|
||||
putClientProperty("JInternalFrame.frameType", "optionDialog");
|
||||
|
||||
jConsole.getDesktopPane().add(this);
|
||||
|
||||
|
||||
getActionMap().put("cancel", new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
setVisible(false);
|
||||
if (statusBar != null) {
|
||||
statusBar.setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
InputMap inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel");
|
||||
}
|
||||
|
||||
public void setLocationRelativeTo(Component c) {
|
||||
setLocation((c.getWidth() - getWidth()) / 2,
|
||||
(c.getHeight() - getHeight()) / 2);
|
||||
}
|
||||
|
||||
protected class MastheadIcon implements Icon {
|
||||
// Important: Assume image background is white!
|
||||
private ImageIcon leftIcon =
|
||||
new ImageIcon(InternalDialog.class.getResource("resources/masthead-left.png"));
|
||||
private ImageIcon rightIcon =
|
||||
new ImageIcon(InternalDialog.class.getResource("resources/masthead-right.png"));
|
||||
|
||||
private Font font = Font.decode(Messages.MASTHEAD_FONT);
|
||||
private int gap = 10;
|
||||
private String title;
|
||||
|
||||
public MastheadIcon(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
// Clone the Graphics object
|
||||
g = g.create();
|
||||
|
||||
// Ignore x to make sure we fill entire component width
|
||||
x = 0;
|
||||
int width = c.getWidth();
|
||||
int lWidth = leftIcon.getIconWidth();
|
||||
int rWidth = rightIcon.getIconWidth();
|
||||
int height = getIconHeight();
|
||||
int textHeight = g.getFontMetrics(font).getAscent();
|
||||
|
||||
g.setColor(Color.white);
|
||||
g.fillRect(x, y, width, height);
|
||||
|
||||
leftIcon.paintIcon(c, g, x, y);
|
||||
rightIcon.paintIcon(c, g, width - rWidth, y);
|
||||
|
||||
g.setFont(font);
|
||||
((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
|
||||
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
g.setColor(new Color(0x35556b));
|
||||
g.drawString(title, lWidth + gap, height/2 + textHeight/2);
|
||||
}
|
||||
|
||||
public int getIconWidth() {
|
||||
int textWidth = 0;
|
||||
Graphics g = getGraphics();
|
||||
if (g != null) {
|
||||
FontMetrics fm = g.getFontMetrics(font);
|
||||
if (fm != null) {
|
||||
textWidth = fm.stringWidth(title);
|
||||
}
|
||||
}
|
||||
return (leftIcon.getIconWidth() + gap + textWidth +
|
||||
gap + rightIcon.getIconWidth());
|
||||
}
|
||||
|
||||
|
||||
public int getIconHeight() {
|
||||
return leftIcon.getIconHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
1112
jdkSrc/jdk8/sun/tools/jconsole/JConsole.java
Normal file
1112
jdkSrc/jdk8/sun/tools/jconsole/JConsole.java
Normal file
File diff suppressed because it is too large
Load Diff
103
jdkSrc/jdk8/sun/tools/jconsole/LabeledComponent.java
Normal file
103
jdkSrc/jdk8/sun/tools/jconsole/LabeledComponent.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class LabeledComponent extends JPanel {
|
||||
JPanel rightPanel;
|
||||
String labelStr, valueLabelStr, compoundStr;
|
||||
JLabel label;
|
||||
JComponent comp;
|
||||
|
||||
public LabeledComponent(String text, JComponent comp) {
|
||||
this(text, 0, comp);
|
||||
}
|
||||
|
||||
public LabeledComponent(String text, int mnemonic, JComponent comp) {
|
||||
super(new BorderLayout(6, 6));
|
||||
|
||||
this.labelStr = text;
|
||||
this.label = new JLabel(text, JLabel.RIGHT);
|
||||
this.comp = comp;
|
||||
|
||||
label.setLabelFor(comp);
|
||||
if (mnemonic > 0) {
|
||||
label.setDisplayedMnemonic(mnemonic);
|
||||
}
|
||||
|
||||
add(label, BorderLayout.WEST);
|
||||
add(comp, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void setLabel(String str) {
|
||||
this.labelStr = str;
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
public void setValueLabel(String str) {
|
||||
this.valueLabelStr = str;
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
private void updateLabel() {
|
||||
String str = labelStr;
|
||||
label.setText(str);
|
||||
this.compoundStr = str;
|
||||
JComponent container = (JComponent)getParent();
|
||||
LabeledComponent.layout(container);
|
||||
}
|
||||
|
||||
public static void layout(Container container) {
|
||||
int wMax = 0;
|
||||
|
||||
for (Component c : container.getComponents()) {
|
||||
if (c instanceof LabeledComponent) {
|
||||
LabeledComponent lc = (LabeledComponent)c;
|
||||
lc.label.setPreferredSize(null);
|
||||
// int w = lc.label.getMinimumSize().width;
|
||||
int w = lc.label.getPreferredSize().width;
|
||||
if (w > wMax) {
|
||||
wMax = w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Component c : container.getComponents()) {
|
||||
if (c instanceof LabeledComponent) {
|
||||
LabeledComponent lc = (LabeledComponent)c;
|
||||
JLabel label = lc.label;
|
||||
int h = label.getPreferredSize().height;
|
||||
|
||||
label.setPreferredSize(new Dimension(wMax, h));
|
||||
label.setHorizontalAlignment(JLabel.RIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
247
jdkSrc/jdk8/sun/tools/jconsole/LocalVirtualMachine.java
Normal file
247
jdkSrc/jdk8/sun/tools/jconsole/LocalVirtualMachine.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
// Sun specific
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
import com.sun.tools.attach.VirtualMachineDescriptor;
|
||||
import com.sun.tools.attach.AttachNotSupportedException;
|
||||
|
||||
// Sun private
|
||||
import sun.management.ConnectorAddressLink;
|
||||
import sun.jvmstat.monitor.HostIdentifier;
|
||||
import sun.jvmstat.monitor.MonitoredHost;
|
||||
import sun.jvmstat.monitor.MonitoredVm;
|
||||
import sun.jvmstat.monitor.MonitoredVmUtil;
|
||||
import sun.jvmstat.monitor.MonitorException;
|
||||
import sun.jvmstat.monitor.VmIdentifier;
|
||||
|
||||
public class LocalVirtualMachine {
|
||||
private String address;
|
||||
private String commandLine;
|
||||
private String displayName;
|
||||
private int vmid;
|
||||
private boolean isAttachSupported;
|
||||
|
||||
public LocalVirtualMachine(int vmid, String commandLine, boolean canAttach, String connectorAddress) {
|
||||
this.vmid = vmid;
|
||||
this.commandLine = commandLine;
|
||||
this.address = connectorAddress;
|
||||
this.isAttachSupported = canAttach;
|
||||
this.displayName = getDisplayName(commandLine);
|
||||
}
|
||||
|
||||
private static String getDisplayName(String commandLine) {
|
||||
// trim the pathname of jar file if it's a jar
|
||||
String[] res = commandLine.split(" ", 2);
|
||||
if (res[0].endsWith(".jar")) {
|
||||
File jarfile = new File(res[0]);
|
||||
String displayName = jarfile.getName();
|
||||
if (res.length == 2) {
|
||||
displayName += " " + res[1];
|
||||
}
|
||||
return displayName;
|
||||
}
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
public int vmid() {
|
||||
return vmid;
|
||||
}
|
||||
|
||||
public boolean isManageable() {
|
||||
return (address != null);
|
||||
}
|
||||
|
||||
public boolean isAttachable() {
|
||||
return isAttachSupported;
|
||||
}
|
||||
|
||||
public void startManagementAgent() throws IOException {
|
||||
if (address != null) {
|
||||
// already started
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAttachable()) {
|
||||
throw new IOException("This virtual machine \"" + vmid +
|
||||
"\" does not support dynamic attach.");
|
||||
}
|
||||
|
||||
loadManagementAgent();
|
||||
// fails to load or start the management agent
|
||||
if (address == null) {
|
||||
// should never reach here
|
||||
throw new IOException("Fails to find connector address");
|
||||
}
|
||||
}
|
||||
|
||||
public String connectorAddress() {
|
||||
// return null if not available or no JMX agent
|
||||
return address;
|
||||
}
|
||||
|
||||
public String displayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return commandLine;
|
||||
}
|
||||
|
||||
// This method returns the list of all virtual machines currently
|
||||
// running on the machine
|
||||
public static Map<Integer, LocalVirtualMachine> getAllVirtualMachines() {
|
||||
Map<Integer, LocalVirtualMachine> map =
|
||||
new HashMap<Integer, LocalVirtualMachine>();
|
||||
getMonitoredVMs(map);
|
||||
getAttachableVMs(map);
|
||||
return map;
|
||||
}
|
||||
|
||||
private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {
|
||||
MonitoredHost host;
|
||||
Set<Integer> vms;
|
||||
try {
|
||||
host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
|
||||
vms = host.activeVms();
|
||||
} catch (java.net.URISyntaxException | MonitorException x) {
|
||||
throw new InternalError(x.getMessage(), x);
|
||||
}
|
||||
for (Object vmid: vms) {
|
||||
if (vmid instanceof Integer) {
|
||||
int pid = ((Integer) vmid).intValue();
|
||||
String name = vmid.toString(); // default to pid if name not available
|
||||
boolean attachable = false;
|
||||
String address = null;
|
||||
try {
|
||||
MonitoredVm mvm = host.getMonitoredVm(new VmIdentifier(name));
|
||||
// use the command line as the display name
|
||||
name = MonitoredVmUtil.commandLine(mvm);
|
||||
attachable = MonitoredVmUtil.isAttachable(mvm);
|
||||
address = ConnectorAddressLink.importFrom(pid);
|
||||
mvm.detach();
|
||||
} catch (Exception x) {
|
||||
// ignore
|
||||
}
|
||||
map.put((Integer) vmid,
|
||||
new LocalVirtualMachine(pid, name, attachable, address));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
|
||||
"com.sun.management.jmxremote.localConnectorAddress";
|
||||
|
||||
private static void getAttachableVMs(Map<Integer, LocalVirtualMachine> map) {
|
||||
List<VirtualMachineDescriptor> vms = VirtualMachine.list();
|
||||
for (VirtualMachineDescriptor vmd : vms) {
|
||||
try {
|
||||
Integer vmid = Integer.valueOf(vmd.id());
|
||||
if (!map.containsKey(vmid)) {
|
||||
boolean attachable = false;
|
||||
String address = null;
|
||||
try {
|
||||
VirtualMachine vm = VirtualMachine.attach(vmd);
|
||||
attachable = true;
|
||||
Properties agentProps = vm.getAgentProperties();
|
||||
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
|
||||
vm.detach();
|
||||
} catch (AttachNotSupportedException x) {
|
||||
// not attachable
|
||||
} catch (IOException x) {
|
||||
// ignore
|
||||
}
|
||||
map.put(vmid, new LocalVirtualMachine(vmid.intValue(),
|
||||
vmd.displayName(),
|
||||
attachable,
|
||||
address));
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// do not support vmid different than pid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static LocalVirtualMachine getLocalVirtualMachine(int vmid) {
|
||||
Map<Integer, LocalVirtualMachine> map = getAllVirtualMachines();
|
||||
LocalVirtualMachine lvm = map.get(vmid);
|
||||
if (lvm == null) {
|
||||
// Check if the VM is attachable but not included in the list
|
||||
// if it's running with a different security context.
|
||||
// For example, Windows services running
|
||||
// local SYSTEM account are attachable if you have Adminstrator
|
||||
// privileges.
|
||||
boolean attachable = false;
|
||||
String address = null;
|
||||
String name = String.valueOf(vmid); // default display name to pid
|
||||
try {
|
||||
VirtualMachine vm = VirtualMachine.attach(name);
|
||||
attachable = true;
|
||||
Properties agentProps = vm.getAgentProperties();
|
||||
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
|
||||
vm.detach();
|
||||
lvm = new LocalVirtualMachine(vmid, name, attachable, address);
|
||||
} catch (AttachNotSupportedException x) {
|
||||
// not attachable
|
||||
if (JConsole.isDebug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
} catch (IOException x) {
|
||||
// ignore
|
||||
if (JConsole.isDebug()) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return lvm;
|
||||
}
|
||||
|
||||
// load the management agent into the target VM
|
||||
private void loadManagementAgent() throws IOException {
|
||||
VirtualMachine vm = null;
|
||||
String name = String.valueOf(vmid);
|
||||
try {
|
||||
vm = VirtualMachine.attach(name);
|
||||
} catch (AttachNotSupportedException x) {
|
||||
IOException ioe = new IOException(x.getMessage());
|
||||
ioe.initCause(x);
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
vm.startLocalManagementAgent();
|
||||
|
||||
// get the connector address
|
||||
Properties agentProps = vm.getAgentProperties();
|
||||
address = (String) agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
|
||||
|
||||
vm.detach();
|
||||
}
|
||||
}
|
||||
281
jdkSrc/jdk8/sun/tools/jconsole/MBeansTab.java
Normal file
281
jdkSrc/jdk8/sun/tools/jconsole/MBeansTab.java
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.beans.*;
|
||||
import java.io.*;
|
||||
import java.util.Set;
|
||||
import javax.management.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.tree.*;
|
||||
import sun.tools.jconsole.ProxyClient.SnapshotMBeanServerConnection;
|
||||
import sun.tools.jconsole.inspector.*;
|
||||
|
||||
import com.sun.tools.jconsole.JConsoleContext;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class MBeansTab extends Tab implements
|
||||
NotificationListener, PropertyChangeListener,
|
||||
TreeSelectionListener, TreeWillExpandListener {
|
||||
|
||||
private XTree tree;
|
||||
private XSheet sheet;
|
||||
private XDataViewer viewer;
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.MBEANS;
|
||||
}
|
||||
|
||||
public MBeansTab(final VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
addPropertyChangeListener(this);
|
||||
setupTab();
|
||||
}
|
||||
|
||||
public XDataViewer getDataViewer() {
|
||||
return viewer;
|
||||
}
|
||||
|
||||
public XTree getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public XSheet getSheet() {
|
||||
return sheet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
sheet.dispose();
|
||||
}
|
||||
|
||||
public int getUpdateInterval() {
|
||||
return vmPanel.getUpdateInterval();
|
||||
}
|
||||
|
||||
private void buildMBeanServerView() {
|
||||
new SwingWorker<Set<ObjectName>, Void>() {
|
||||
@Override
|
||||
public Set<ObjectName> doInBackground() {
|
||||
// Register listener for MBean registration/unregistration
|
||||
//
|
||||
try {
|
||||
getMBeanServerConnection().addNotificationListener(
|
||||
MBeanServerDelegate.DELEGATE_NAME,
|
||||
MBeansTab.this,
|
||||
null,
|
||||
null);
|
||||
} catch (InstanceNotFoundException e) {
|
||||
// Should never happen because the MBeanServerDelegate
|
||||
// is always present in any standard MBeanServer
|
||||
//
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
vmPanel.getProxyClient().markAsDead();
|
||||
return null;
|
||||
}
|
||||
// Retrieve MBeans from MBeanServer
|
||||
//
|
||||
Set<ObjectName> mbeans = null;
|
||||
try {
|
||||
mbeans = getMBeanServerConnection().queryNames(null, null);
|
||||
} catch (IOException e) {
|
||||
if (JConsole.isDebug()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
vmPanel.getProxyClient().markAsDead();
|
||||
return null;
|
||||
}
|
||||
return mbeans;
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
try {
|
||||
// Wait for mbsc.queryNames() result
|
||||
Set<ObjectName> mbeans = get();
|
||||
// Do not display anything until the new tree has been built
|
||||
//
|
||||
tree.setVisible(false);
|
||||
// Cleanup current tree
|
||||
//
|
||||
tree.removeAll();
|
||||
// Add MBeans to tree
|
||||
//
|
||||
tree.addMBeansToView(mbeans);
|
||||
// Display the new tree
|
||||
//
|
||||
tree.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
Throwable t = Utils.getActualException(e);
|
||||
if (JConsole.isDebug()) {
|
||||
System.err.println("Problem at MBean tree construction");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
public MBeanServerConnection getMBeanServerConnection() {
|
||||
return vmPanel.getProxyClient().getMBeanServerConnection();
|
||||
}
|
||||
|
||||
public SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() {
|
||||
return vmPanel.getProxyClient().getSnapshotMBeanServerConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// Ping the connection to see if it is still alive. At
|
||||
// some point the ProxyClient class should centralize
|
||||
// the connection aliveness monitoring and no longer
|
||||
// rely on the custom tabs to ping the connections.
|
||||
//
|
||||
try {
|
||||
getMBeanServerConnection().getDefaultDomain();
|
||||
} catch (IOException ex) {
|
||||
vmPanel.getProxyClient().markAsDead();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupTab() {
|
||||
// set up the split pane with the MBean tree and MBean sheet panels
|
||||
setLayout(new BorderLayout());
|
||||
JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
||||
mainSplit.setDividerLocation(160);
|
||||
mainSplit.setBorder(BorderFactory.createEmptyBorder());
|
||||
|
||||
// set up the MBean tree panel (left pane)
|
||||
tree = new XTree(this);
|
||||
tree.setCellRenderer(new XTreeRenderer());
|
||||
tree.getSelectionModel().setSelectionMode(
|
||||
TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
tree.addTreeSelectionListener(this);
|
||||
tree.addTreeWillExpandListener(this);
|
||||
tree.addMouseListener(ml);
|
||||
JScrollPane theScrollPane = new JScrollPane(
|
||||
tree,
|
||||
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
|
||||
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
JPanel treePanel = new JPanel(new BorderLayout());
|
||||
treePanel.add(theScrollPane, BorderLayout.CENTER);
|
||||
mainSplit.add(treePanel, JSplitPane.LEFT, 0);
|
||||
|
||||
// set up the MBean sheet panel (right pane)
|
||||
viewer = new XDataViewer(this);
|
||||
sheet = new XSheet(this);
|
||||
mainSplit.add(sheet, JSplitPane.RIGHT, 0);
|
||||
|
||||
add(mainSplit);
|
||||
}
|
||||
|
||||
/* notification listener: handleNotification */
|
||||
public void handleNotification(
|
||||
final Notification notification, Object handback) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (notification instanceof MBeanServerNotification) {
|
||||
ObjectName mbean =
|
||||
((MBeanServerNotification) notification).getMBeanName();
|
||||
if (notification.getType().equals(
|
||||
MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
|
||||
tree.addMBeanToView(mbean);
|
||||
} else if (notification.getType().equals(
|
||||
MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
|
||||
tree.removeMBeanFromView(mbean);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* property change listener: propertyChange */
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {
|
||||
boolean connected = (Boolean) evt.getNewValue();
|
||||
if (connected) {
|
||||
buildMBeanServerView();
|
||||
} else {
|
||||
sheet.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tree selection listener: valueChanged */
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
DefaultMutableTreeNode node =
|
||||
(DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
|
||||
sheet.displayNode(node);
|
||||
}
|
||||
/* tree mouse listener: mousePressed */
|
||||
private MouseListener ml = new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (e.getClickCount() == 1) {
|
||||
int selRow = tree.getRowForLocation(e.getX(), e.getY());
|
||||
if (selRow != -1) {
|
||||
TreePath selPath =
|
||||
tree.getPathForLocation(e.getX(), e.getY());
|
||||
DefaultMutableTreeNode node =
|
||||
(DefaultMutableTreeNode) selPath.getLastPathComponent();
|
||||
if (sheet.isMBeanNode(node)) {
|
||||
tree.expandPath(selPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* tree will expand listener: treeWillExpand */
|
||||
public void treeWillExpand(TreeExpansionEvent e)
|
||||
throws ExpandVetoException {
|
||||
TreePath path = e.getPath();
|
||||
if (!tree.hasBeenExpanded(path)) {
|
||||
DefaultMutableTreeNode node =
|
||||
(DefaultMutableTreeNode) path.getLastPathComponent();
|
||||
if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) {
|
||||
tree.addMetadataNodes(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tree will expand listener: treeWillCollapse */
|
||||
public void treeWillCollapse(TreeExpansionEvent e)
|
||||
throws ExpandVetoException {
|
||||
}
|
||||
}
|
||||
345
jdkSrc/jdk8/sun/tools/jconsole/MaximizableInternalFrame.java
Normal file
345
jdkSrc/jdk8/sun/tools/jconsole/MaximizableInternalFrame.java
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.beans.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.plaf.basic.*;
|
||||
|
||||
|
||||
/**
|
||||
* This class is a temporary workaround for bug 4834918:
|
||||
* Win L&F: JInternalFrame should merge with JMenuBar when maximized.
|
||||
* It is not a general solution, but intended for use within the
|
||||
* limited scope of JConsole when running with XP/Vista styles.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class MaximizableInternalFrame extends JInternalFrame {
|
||||
private boolean isXP;
|
||||
private JFrame mainFrame;
|
||||
private JMenuBar mainMenuBar;
|
||||
private String mainTitle;
|
||||
private JComponent titlePane;
|
||||
private Border normalBorder;
|
||||
private PropertyChangeListener pcl;
|
||||
|
||||
public MaximizableInternalFrame(String title, boolean resizable,
|
||||
boolean closable, boolean maximizable,
|
||||
boolean iconifiable) {
|
||||
super(title, resizable, closable, maximizable, iconifiable);
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
normalBorder = getBorder();
|
||||
isXP = normalBorder.getClass().getName().endsWith("XPBorder");
|
||||
if (isXP) {
|
||||
setRootPaneCheckingEnabled(false);
|
||||
titlePane = ((BasicInternalFrameUI)getUI()).getNorthPane();
|
||||
|
||||
if (pcl == null) {
|
||||
pcl = new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent ev) {
|
||||
String prop = ev.getPropertyName();
|
||||
if (prop.equals("icon") ||
|
||||
prop.equals("maximum") ||
|
||||
prop.equals("closed")) {
|
||||
|
||||
updateFrame();
|
||||
}
|
||||
}
|
||||
};
|
||||
addPropertyChangeListener(pcl);
|
||||
}
|
||||
} else if (pcl != null) {
|
||||
removePropertyChangeListener(pcl);
|
||||
pcl = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFrame() {
|
||||
JFrame mainFrame;
|
||||
if (!isXP || (mainFrame = getMainFrame()) == null) {
|
||||
return;
|
||||
}
|
||||
JMenuBar menuBar = getMainMenuBar();
|
||||
BasicInternalFrameUI ui = (BasicInternalFrameUI)getUI();
|
||||
if (isMaximum() && !isIcon() && !isClosed()) {
|
||||
if (ui.getNorthPane() != null) {
|
||||
// Merge title bar into menu bar
|
||||
mainTitle = mainFrame.getTitle();
|
||||
mainFrame.setTitle(mainTitle + " - " + getTitle());
|
||||
if (menuBar != null) {
|
||||
// Move buttons to menu bar
|
||||
updateButtonStates();
|
||||
menuBar.add(Box.createGlue());
|
||||
for (Component c : titlePane.getComponents()) {
|
||||
if (c instanceof JButton) {
|
||||
menuBar.add(c);
|
||||
} else if (c instanceof JLabel) {
|
||||
// This is the system menu icon
|
||||
menuBar.add(Box.createHorizontalStrut(3), 0);
|
||||
menuBar.add(c, 1);
|
||||
menuBar.add(Box.createHorizontalStrut(3), 2);
|
||||
}
|
||||
}
|
||||
ui.setNorthPane(null);
|
||||
setBorder(null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ui.getNorthPane() == null) {
|
||||
// Restore title bar
|
||||
mainFrame.setTitle(mainTitle);
|
||||
if (menuBar != null) {
|
||||
// Move buttons back to title bar
|
||||
for (Component c : menuBar.getComponents()) {
|
||||
if (c instanceof JButton || c instanceof JLabel) {
|
||||
titlePane.add(c);
|
||||
} else if (c instanceof Box.Filler) {
|
||||
menuBar.remove(c);
|
||||
}
|
||||
}
|
||||
menuBar.repaint();
|
||||
updateButtonStates();
|
||||
ui.setNorthPane(titlePane);
|
||||
setBorder(normalBorder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateUI() {
|
||||
boolean isMax = (isXP && getBorder() == null);
|
||||
if (isMax) {
|
||||
try {
|
||||
setMaximum(false);
|
||||
} catch (PropertyVetoException ex) { }
|
||||
}
|
||||
super.updateUI();
|
||||
init();
|
||||
if (isMax) {
|
||||
try {
|
||||
setMaximum(true);
|
||||
} catch (PropertyVetoException ex) { }
|
||||
}
|
||||
}
|
||||
|
||||
private JFrame getMainFrame() {
|
||||
if (mainFrame == null) {
|
||||
JDesktopPane desktop = getDesktopPane();
|
||||
if (desktop != null) {
|
||||
mainFrame = (JFrame)SwingUtilities.getWindowAncestor(desktop);
|
||||
}
|
||||
}
|
||||
return mainFrame;
|
||||
}
|
||||
|
||||
private JMenuBar getMainMenuBar() {
|
||||
if (mainMenuBar == null) {
|
||||
JFrame mainFrame = getMainFrame();
|
||||
if (mainFrame != null) {
|
||||
mainMenuBar = mainFrame.getJMenuBar();
|
||||
if (mainMenuBar != null &&
|
||||
!(mainMenuBar.getLayout() instanceof FixedMenuBarLayout)) {
|
||||
|
||||
mainMenuBar.setLayout(new FixedMenuBarLayout(mainMenuBar,
|
||||
BoxLayout.X_AXIS));
|
||||
}
|
||||
}
|
||||
}
|
||||
return mainMenuBar;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
if (isXP && isMaximum()) {
|
||||
if (getMainFrame() != null) {
|
||||
getMainFrame().setTitle(mainTitle + " - " + title);
|
||||
}
|
||||
}
|
||||
super.setTitle(title);
|
||||
}
|
||||
|
||||
|
||||
private class FixedMenuBarLayout extends BoxLayout {
|
||||
public FixedMenuBarLayout(Container target, int axis) {
|
||||
super(target, axis);
|
||||
}
|
||||
|
||||
public void layoutContainer(Container target) {
|
||||
super.layoutContainer(target);
|
||||
|
||||
for (Component c : target.getComponents()) {
|
||||
if (c instanceof JButton) {
|
||||
int y = (target.getHeight() - c.getHeight()) / 2;
|
||||
c.setLocation(c.getX(), Math.max(2, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The rest of this class is messy and should not be relied upon. It
|
||||
// uses reflection to access private, undocumented, and unsupported
|
||||
// classes and fields.
|
||||
//
|
||||
// Install icon wrappers to display MDI icons when the buttons
|
||||
// are in the menubar.
|
||||
//
|
||||
// Please note that this will very likely fail in a future version
|
||||
// of Swing, but at least it should fail silently.
|
||||
//
|
||||
private static Object WP_MINBUTTON, WP_RESTOREBUTTON, WP_CLOSEBUTTON,
|
||||
WP_MDIMINBUTTON, WP_MDIRESTOREBUTTON, WP_MDICLOSEBUTTON;
|
||||
static {
|
||||
if (JConsole.IS_WIN) {
|
||||
try {
|
||||
Class<?> Part =
|
||||
Class.forName("com.sun.java.swing.plaf.windows.TMSchema$Part");
|
||||
if (Part != null) {
|
||||
WP_MINBUTTON = Part.getField("WP_MINBUTTON").get(null);
|
||||
WP_RESTOREBUTTON = Part.getField("WP_RESTOREBUTTON").get(null);
|
||||
WP_CLOSEBUTTON = Part.getField("WP_CLOSEBUTTON").get(null);
|
||||
WP_MDIMINBUTTON = Part.getField("WP_MDIMINBUTTON").get(null);
|
||||
WP_MDIRESTOREBUTTON = Part.getField("WP_MDIRESTOREBUTTON").get(null);
|
||||
WP_MDICLOSEBUTTON = Part.getField("WP_MDICLOSEBUTTON").get(null);
|
||||
}
|
||||
|
||||
for (String str : new String[] { "maximize", "minimize",
|
||||
"iconify", "close" }) {
|
||||
String key = "InternalFrame." + str + "Icon";
|
||||
UIManager.put(key,
|
||||
new MDIButtonIcon(UIManager.getIcon(key)));
|
||||
}
|
||||
} catch (ClassNotFoundException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} catch (NoSuchFieldException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A wrapper class for the title pane button icons.
|
||||
// This code should really go in the WindowsIconsFactory class.
|
||||
private static class MDIButtonIcon implements Icon {
|
||||
Icon windowsIcon;
|
||||
Field part;
|
||||
|
||||
MDIButtonIcon(Icon icon) {
|
||||
windowsIcon = icon;
|
||||
|
||||
if (WP_MINBUTTON != null) {
|
||||
try {
|
||||
part = windowsIcon.getClass().getDeclaredField("part");
|
||||
part.setAccessible(true);
|
||||
} catch (NoSuchFieldException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
if (part != null) {
|
||||
try {
|
||||
Object v = part.get(windowsIcon);
|
||||
|
||||
if (c.getParent() instanceof JMenuBar) {
|
||||
// Use MDI icons
|
||||
if (v == WP_MINBUTTON) {
|
||||
part.set(windowsIcon, WP_MDIMINBUTTON);
|
||||
} else if (v == WP_RESTOREBUTTON) {
|
||||
part.set(windowsIcon, WP_MDIRESTOREBUTTON);
|
||||
} else if (v == WP_CLOSEBUTTON) {
|
||||
part.set(windowsIcon, WP_MDICLOSEBUTTON);
|
||||
}
|
||||
} else {
|
||||
// Use regular icons
|
||||
if (v == WP_MDIMINBUTTON) {
|
||||
part.set(windowsIcon, WP_MINBUTTON);
|
||||
} else if (v == WP_MDIRESTOREBUTTON) {
|
||||
part.set(windowsIcon, WP_RESTOREBUTTON);
|
||||
} else if (v == WP_MDICLOSEBUTTON) {
|
||||
part.set(windowsIcon, WP_CLOSEBUTTON);
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
windowsIcon.paintIcon(c, g, x, y);
|
||||
}
|
||||
|
||||
public int getIconWidth(){
|
||||
return windowsIcon.getIconWidth();
|
||||
}
|
||||
|
||||
public int getIconHeight() {
|
||||
return windowsIcon.getIconHeight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use reflection to invoke protected methods in BasicInternalFrameTitlePane
|
||||
private Method setButtonIcons;
|
||||
private Method enableActions;
|
||||
|
||||
private void updateButtonStates() {
|
||||
try {
|
||||
if (setButtonIcons == null) {
|
||||
Class<? extends JComponent> cls = titlePane.getClass();
|
||||
Class<?> superCls = cls.getSuperclass();
|
||||
setButtonIcons = cls.getDeclaredMethod("setButtonIcons");
|
||||
enableActions = superCls.getDeclaredMethod("enableActions");
|
||||
setButtonIcons.setAccessible(true);
|
||||
enableActions.setAccessible(true);
|
||||
}
|
||||
setButtonIcons.invoke(titlePane);
|
||||
enableActions.invoke(titlePane);
|
||||
} catch (Exception ex) {
|
||||
if (JConsole.debug) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
125
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolProxy.java
Normal file
125
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolProxy.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import javax.management.ObjectName;
|
||||
import java.lang.management.MemoryPoolMXBean;
|
||||
import java.lang.management.MemoryUsage;
|
||||
import com.sun.management.GarbageCollectorMXBean;
|
||||
import com.sun.management.GcInfo;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.lang.management.ManagementFactory.*;
|
||||
|
||||
public class MemoryPoolProxy {
|
||||
private String poolName;
|
||||
private ProxyClient client;
|
||||
private MemoryPoolMXBean pool;
|
||||
private Map<ObjectName,Long> gcMBeans;
|
||||
private GcInfo lastGcInfo;
|
||||
|
||||
public MemoryPoolProxy(ProxyClient client, ObjectName poolName) throws java.io.IOException {
|
||||
this.client = client;
|
||||
this.pool = client.getMXBean(poolName, MemoryPoolMXBean.class);
|
||||
this.poolName = this.pool.getName();
|
||||
this.gcMBeans = new HashMap<ObjectName,Long>();
|
||||
this.lastGcInfo = null;
|
||||
|
||||
String[] mgrNames = pool.getMemoryManagerNames();
|
||||
for (String name : mgrNames) {
|
||||
try {
|
||||
ObjectName mbeanName = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
|
||||
",name=" + name);
|
||||
if (client.isRegistered(mbeanName)) {
|
||||
gcMBeans.put(mbeanName, new Long(0));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
assert false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCollectedMemoryPool() {
|
||||
return (gcMBeans.size() != 0);
|
||||
}
|
||||
|
||||
public MemoryPoolStat getStat() throws java.io.IOException {
|
||||
long usageThreshold = (pool.isUsageThresholdSupported()
|
||||
? pool.getUsageThreshold()
|
||||
: -1);
|
||||
long collectThreshold = (pool.isCollectionUsageThresholdSupported()
|
||||
? pool.getCollectionUsageThreshold()
|
||||
: -1);
|
||||
long lastGcStartTime = 0;
|
||||
long lastGcEndTime = 0;
|
||||
MemoryUsage beforeGcUsage = null;
|
||||
MemoryUsage afterGcUsage = null;
|
||||
long gcId = 0;
|
||||
if (lastGcInfo != null) {
|
||||
gcId = lastGcInfo.getId();
|
||||
lastGcStartTime = lastGcInfo.getStartTime();
|
||||
lastGcEndTime = lastGcInfo.getEndTime();
|
||||
beforeGcUsage = lastGcInfo.getMemoryUsageBeforeGc().get(poolName);
|
||||
afterGcUsage = lastGcInfo.getMemoryUsageAfterGc().get(poolName);
|
||||
}
|
||||
|
||||
Set<Map.Entry<ObjectName,Long>> set = gcMBeans.entrySet();
|
||||
for (Map.Entry<ObjectName,Long> e : set) {
|
||||
GarbageCollectorMXBean gc =
|
||||
client.getMXBean(e.getKey(),
|
||||
com.sun.management.GarbageCollectorMXBean.class);
|
||||
Long gcCount = e.getValue();
|
||||
Long newCount = gc.getCollectionCount();
|
||||
if (newCount > gcCount) {
|
||||
gcMBeans.put(e.getKey(), new Long(newCount));
|
||||
lastGcInfo = gc.getLastGcInfo();
|
||||
if (lastGcInfo.getEndTime() > lastGcEndTime) {
|
||||
gcId = lastGcInfo.getId();
|
||||
lastGcStartTime = lastGcInfo.getStartTime();
|
||||
lastGcEndTime = lastGcInfo.getEndTime();
|
||||
beforeGcUsage = lastGcInfo.getMemoryUsageBeforeGc().get(poolName);
|
||||
afterGcUsage = lastGcInfo.getMemoryUsageAfterGc().get(poolName);
|
||||
assert(beforeGcUsage != null);
|
||||
assert(afterGcUsage != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemoryUsage usage = pool.getUsage();
|
||||
return new MemoryPoolStat(poolName,
|
||||
usageThreshold,
|
||||
usage,
|
||||
gcId,
|
||||
lastGcStartTime,
|
||||
lastGcEndTime,
|
||||
collectThreshold,
|
||||
beforeGcUsage,
|
||||
afterGcUsage);
|
||||
}
|
||||
}
|
||||
134
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolStat.java
Normal file
134
jdkSrc/jdk8/sun/tools/jconsole/MemoryPoolStat.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.lang.management.MemoryUsage;
|
||||
|
||||
public class MemoryPoolStat {
|
||||
private String poolName;
|
||||
private long usageThreshold;
|
||||
private MemoryUsage usage;
|
||||
private long lastGcId;
|
||||
private long lastGcStartTime;
|
||||
private long lastGcEndTime;
|
||||
private long collectThreshold;
|
||||
private MemoryUsage beforeGcUsage;
|
||||
private MemoryUsage afterGcUsage;
|
||||
|
||||
MemoryPoolStat(String name,
|
||||
long usageThreshold,
|
||||
MemoryUsage usage,
|
||||
long lastGcId,
|
||||
long lastGcStartTime,
|
||||
long lastGcEndTime,
|
||||
long collectThreshold,
|
||||
MemoryUsage beforeGcUsage,
|
||||
MemoryUsage afterGcUsage) {
|
||||
this.poolName = name;
|
||||
this.usageThreshold = usageThreshold;
|
||||
this.usage = usage;
|
||||
this.lastGcId = lastGcId;
|
||||
this.lastGcStartTime = lastGcStartTime;
|
||||
this.lastGcEndTime = lastGcEndTime;
|
||||
this.collectThreshold = collectThreshold;
|
||||
this.beforeGcUsage = beforeGcUsage;
|
||||
this.afterGcUsage = afterGcUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory pool name.
|
||||
*/
|
||||
public String getPoolName() {
|
||||
return poolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current memory usage.
|
||||
*/
|
||||
public MemoryUsage getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current usage threshold.
|
||||
* -1 if not supported.
|
||||
*/
|
||||
public long getUsageThreshold() {
|
||||
return usageThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current collection usage threshold.
|
||||
* -1 if not supported.
|
||||
*/
|
||||
public long getCollectionUsageThreshold() {
|
||||
return collectThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Id of GC.
|
||||
*/
|
||||
public long getLastGcId() {
|
||||
return lastGcId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the start time of the most recent GC on
|
||||
* the memory pool for this statistics in milliseconds.
|
||||
*
|
||||
* Return 0 if no GC occurs.
|
||||
*/
|
||||
public long getLastGcStartTime() {
|
||||
return lastGcStartTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end time of the most recent GC on
|
||||
* the memory pool for this statistics in milliseconds.
|
||||
*
|
||||
* Return 0 if no GC occurs.
|
||||
*/
|
||||
public long getLastGcEndTime() {
|
||||
return lastGcEndTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory usage before the most recent GC started.
|
||||
* null if no GC occurs.
|
||||
*/
|
||||
public MemoryUsage getBeforeGcUsage() {
|
||||
return beforeGcUsage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the memory usage after the most recent GC finished.
|
||||
* null if no GC occurs.
|
||||
*/
|
||||
public MemoryUsage getAfterGcUsage() {
|
||||
return afterGcUsage;
|
||||
}
|
||||
}
|
||||
768
jdkSrc/jdk8/sun/tools/jconsole/MemoryTab.java
Normal file
768
jdkSrc/jdk8/sun/tools/jconsole/MemoryTab.java
Normal file
@@ -0,0 +1,768 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.lang.management.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import javax.accessibility.*;
|
||||
import javax.management.*;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
|
||||
|
||||
import static sun.tools.jconsole.Formatter.*;
|
||||
import static sun.tools.jconsole.Utilities.*;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class MemoryTab extends Tab implements ActionListener, ItemListener {
|
||||
JComboBox<Plotter> plotterChoice;
|
||||
TimeComboBox timeComboBox;
|
||||
JButton gcButton;
|
||||
|
||||
PlotterPanel plotterPanel;
|
||||
JPanel bottomPanel;
|
||||
HTMLPane details;
|
||||
PoolChart poolChart;
|
||||
|
||||
ArrayList<Plotter> plotterList;
|
||||
Plotter heapPlotter, nonHeapPlotter;
|
||||
|
||||
private MemoryOverviewPanel overviewPanel;
|
||||
|
||||
private static final String usedKey = "used";
|
||||
private static final String committedKey = "committed";
|
||||
private static final String maxKey = "max";
|
||||
private static final String thresholdKey = "threshold";
|
||||
private static final Color usedColor = Plotter.defaultColor;
|
||||
private static final Color committedColor = null;
|
||||
private static final Color maxColor = null;
|
||||
private static final Color thresholdColor = Color.red;
|
||||
|
||||
/*
|
||||
Hierarchy of panels and layouts for this tab:
|
||||
|
||||
MemoryTab (BorderLayout)
|
||||
|
||||
North: topPanel (BorderLayout)
|
||||
|
||||
Center: controlPanel (FlowLayout)
|
||||
plotterChoice, timeComboBox
|
||||
|
||||
East: topRightPanel (FlowLayout)
|
||||
gcButton
|
||||
|
||||
Center: plotterPanel
|
||||
|
||||
Center: plotter
|
||||
|
||||
South: bottomPanel (BorderLayout)
|
||||
|
||||
Center: details
|
||||
East: poolChart
|
||||
*/
|
||||
|
||||
|
||||
public static String getTabName() {
|
||||
return Messages.MEMORY;
|
||||
}
|
||||
|
||||
public MemoryTab(VMPanel vmPanel) {
|
||||
super(vmPanel, getTabName());
|
||||
|
||||
setLayout(new BorderLayout(0, 0));
|
||||
setBorder(new EmptyBorder(4, 4, 3, 4));
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
plotterPanel = new PlotterPanel(null);
|
||||
bottomPanel = new JPanel(new BorderLayout());
|
||||
|
||||
add(topPanel, BorderLayout.NORTH);
|
||||
add(plotterPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 20, 5));
|
||||
topPanel.add(controlPanel, BorderLayout.CENTER);
|
||||
|
||||
// Plotter choice
|
||||
plotterChoice = new JComboBox<Plotter>();
|
||||
plotterChoice.addItemListener(this);
|
||||
controlPanel.add(new LabeledComponent(Messages.CHART_COLON,
|
||||
Resources.getMnemonicInt(Messages.CHART_COLON),
|
||||
plotterChoice));
|
||||
|
||||
// Range control
|
||||
timeComboBox = new TimeComboBox();
|
||||
controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
|
||||
Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
|
||||
timeComboBox));
|
||||
|
||||
gcButton = new JButton(Messages.PERFORM_GC);
|
||||
gcButton.setMnemonic(Resources.getMnemonicInt(Messages.PERFORM_GC));
|
||||
gcButton.addActionListener(this);
|
||||
gcButton.setToolTipText(Messages.PERFORM_GC_TOOLTIP);
|
||||
JPanel topRightPanel = new JPanel();
|
||||
topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
|
||||
topRightPanel.add(gcButton);
|
||||
topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
|
||||
|
||||
bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
|
||||
new EmptyBorder(10, 10, 10, 10)));
|
||||
|
||||
details = new HTMLPane();
|
||||
setAccessibleName(details, Messages.DETAILS);
|
||||
bottomPanel.add(new JScrollPane(details), BorderLayout.CENTER);
|
||||
|
||||
poolChart = new PoolChart();
|
||||
bottomPanel.add(poolChart, BorderLayout.AFTER_LINE_ENDS);
|
||||
}
|
||||
|
||||
|
||||
private void createPlotters() throws IOException {
|
||||
plotterList = new ArrayList<Plotter>();
|
||||
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
|
||||
heapPlotter = new Plotter(Plotter.Unit.BYTES) {
|
||||
public String toString() {
|
||||
return Messages.HEAP_MEMORY_USAGE;
|
||||
}
|
||||
};
|
||||
proxyClient.addWeakPropertyChangeListener(heapPlotter);
|
||||
|
||||
nonHeapPlotter = new Plotter(Plotter.Unit.BYTES) {
|
||||
public String toString() {
|
||||
return Messages.NON_HEAP_MEMORY_USAGE;
|
||||
}
|
||||
};
|
||||
|
||||
setAccessibleName(heapPlotter,
|
||||
Messages.MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME);
|
||||
setAccessibleName(nonHeapPlotter,
|
||||
Messages.MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME);
|
||||
|
||||
proxyClient.addWeakPropertyChangeListener(nonHeapPlotter);
|
||||
|
||||
heapPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
|
||||
heapPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
|
||||
heapPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
|
||||
|
||||
nonHeapPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
|
||||
nonHeapPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
|
||||
nonHeapPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
|
||||
|
||||
plotterList.add(heapPlotter);
|
||||
plotterList.add(nonHeapPlotter);
|
||||
|
||||
// Now add memory pools
|
||||
Map<ObjectName, MBeanInfo> mBeanMap = proxyClient.getMBeans("java.lang");
|
||||
Set<ObjectName> keys = mBeanMap.keySet();
|
||||
ObjectName[] objectNames = keys.toArray(new ObjectName[keys.size()]);
|
||||
ArrayList<PoolPlotter> nonHeapPlotters = new ArrayList<PoolPlotter>(2);
|
||||
for (ObjectName objectName : objectNames) {
|
||||
String type = objectName.getKeyProperty("type");
|
||||
if (type.equals("MemoryPool")) {
|
||||
String name = Resources.format(Messages.MEMORY_POOL_LABEL,
|
||||
objectName.getKeyProperty("name"));
|
||||
// Heap or non-heap?
|
||||
boolean isHeap = false;
|
||||
AttributeList al =
|
||||
proxyClient.getAttributes(objectName,
|
||||
new String[] { "Type" });
|
||||
if (al.size() > 0) {
|
||||
isHeap = MemoryType.HEAP.name().equals(((Attribute)al.get(0)).getValue());
|
||||
}
|
||||
PoolPlotter poolPlotter = new PoolPlotter(objectName, name, isHeap);
|
||||
proxyClient.addWeakPropertyChangeListener(poolPlotter);
|
||||
|
||||
poolPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
|
||||
poolPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
|
||||
poolPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
|
||||
poolPlotter.createSequence(thresholdKey, Messages.THRESHOLD, thresholdColor, false);
|
||||
poolPlotter.setUseDashedTransitions(thresholdKey, true);
|
||||
|
||||
if (isHeap) {
|
||||
plotterList.add(poolPlotter);
|
||||
} else {
|
||||
// Will be added to plotterList below
|
||||
nonHeapPlotters.add(poolPlotter);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add non-heap plotters last
|
||||
for (PoolPlotter poolPlotter : nonHeapPlotters) {
|
||||
plotterList.add(poolPlotter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void itemStateChanged(ItemEvent ev) {
|
||||
if (ev.getStateChange() == ItemEvent.SELECTED) {
|
||||
Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
|
||||
plotterPanel.setPlotter(plotter);
|
||||
plotterPanel.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public void gc() {
|
||||
new Thread("MemoryPanel.gc") {
|
||||
public void run() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
try {
|
||||
proxyClient.getMemoryMXBean().gc();
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
public SwingWorker<?, ?> newSwingWorker() {
|
||||
return new SwingWorker<Boolean, Object>() {
|
||||
private long[] used, committed, max, threshold;
|
||||
private long timeStamp;
|
||||
private String detailsStr;
|
||||
private boolean initialRun = false;
|
||||
|
||||
public Boolean doInBackground() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
|
||||
if (plotterList == null) {
|
||||
try {
|
||||
createPlotters();
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
return false;
|
||||
} catch (final IOException ex) {
|
||||
return false;
|
||||
}
|
||||
initialRun = true;
|
||||
}
|
||||
|
||||
int n = plotterList.size();
|
||||
used = new long[n];
|
||||
committed = new long[n];
|
||||
max = new long[n];
|
||||
threshold = new long[n];
|
||||
timeStamp = System.currentTimeMillis();
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Plotter plotter = plotterList.get(i);
|
||||
MemoryUsage mu = null;
|
||||
used[i] = -1L;
|
||||
threshold[i] = -1L;
|
||||
|
||||
try {
|
||||
if (plotter instanceof PoolPlotter) {
|
||||
PoolPlotter poolPlotter = (PoolPlotter)plotter;
|
||||
ObjectName objectName = poolPlotter.objectName;
|
||||
AttributeList al =
|
||||
proxyClient.getAttributes(objectName,
|
||||
new String[] { "Usage", "UsageThreshold" });
|
||||
if (al.size() > 0) {
|
||||
CompositeData cd = (CompositeData)((Attribute)al.get(0)).getValue();
|
||||
mu = MemoryUsage.from(cd);
|
||||
|
||||
if (al.size() > 1) {
|
||||
threshold[i] = (Long)((Attribute)al.get(1)).getValue();
|
||||
}
|
||||
}
|
||||
} else if (plotter == heapPlotter) {
|
||||
mu = proxyClient.getMemoryMXBean().getHeapMemoryUsage();
|
||||
} else if (plotter == nonHeapPlotter) {
|
||||
mu = proxyClient.getMemoryMXBean().getNonHeapMemoryUsage();
|
||||
}
|
||||
} catch (UndeclaredThrowableException e) {
|
||||
proxyClient.markAsDead();
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
// Skip this plotter
|
||||
}
|
||||
|
||||
if (mu != null) {
|
||||
used[i] = mu.getUsed();
|
||||
committed[i] = mu.getCommitted();
|
||||
max[i] = mu.getMax();
|
||||
}
|
||||
}
|
||||
detailsStr = formatDetails();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void done() {
|
||||
try {
|
||||
if (!get()) {
|
||||
return;
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
return;
|
||||
} catch (ExecutionException ex) {
|
||||
if (JConsole.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (initialRun) {
|
||||
// Add Memory Pools
|
||||
for (Plotter p : plotterList) {
|
||||
plotterChoice.addItem(p);
|
||||
timeComboBox.addPlotter(p);
|
||||
}
|
||||
add(bottomPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
|
||||
int n = plotterList.size();
|
||||
int poolCount = 0;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
Plotter plotter = plotterList.get(i);
|
||||
if (used[i] >= 0L) {
|
||||
if (plotter instanceof PoolPlotter) {
|
||||
plotter.addValues(timeStamp, used[i], committed[i], max[i], threshold[i]);
|
||||
if (threshold[i] > 0L) {
|
||||
plotter.setIsPlotted(thresholdKey, true);
|
||||
}
|
||||
poolChart.setValue(poolCount++, (PoolPlotter)plotter,
|
||||
used[i], threshold[i], max[i]);
|
||||
} else {
|
||||
plotter.addValues(timeStamp, used[i], committed[i], max[i]);
|
||||
}
|
||||
|
||||
if (plotter == heapPlotter && overviewPanel != null) {
|
||||
overviewPanel.getPlotter().addValues(timeStamp, used[i]);
|
||||
overviewPanel.updateMemoryInfo(used[i], committed[i], max[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
details.setText(detailsStr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private String formatDetails() {
|
||||
ProxyClient proxyClient = vmPanel.getProxyClient();
|
||||
if (proxyClient.isDead()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String text = "<table cellspacing=0 cellpadding=0>";
|
||||
|
||||
Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
|
||||
if (plotter == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
//long time = plotter.getLastTimeStamp();
|
||||
long time = System.currentTimeMillis();
|
||||
String timeStamp = formatDateTime(time);
|
||||
text += newRow(Messages.TIME, timeStamp);
|
||||
|
||||
long used = plotter.getLastValue(usedKey);
|
||||
long committed = plotter.getLastValue(committedKey);
|
||||
long max = plotter.getLastValue(maxKey);
|
||||
long threshold = plotter.getLastValue(thresholdKey);
|
||||
|
||||
text += newRow(Messages.USED, formatKBytes(used));
|
||||
if (committed > 0L) {
|
||||
text += newRow(Messages.COMMITTED, formatKBytes(committed));
|
||||
}
|
||||
if (max > 0L) {
|
||||
text += newRow(Messages.MAX, formatKBytes(max));
|
||||
}
|
||||
if (threshold > 0L) {
|
||||
text += newRow(Messages.USAGE_THRESHOLD, formatKBytes(threshold));
|
||||
}
|
||||
|
||||
try {
|
||||
Collection<GarbageCollectorMXBean> garbageCollectors =
|
||||
proxyClient.getGarbageCollectorMXBeans();
|
||||
|
||||
boolean descPrinted = false;
|
||||
for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) {
|
||||
String gcName = garbageCollectorMBean.getName();
|
||||
long gcCount = garbageCollectorMBean.getCollectionCount();
|
||||
long gcTime = garbageCollectorMBean.getCollectionTime();
|
||||
String str = Resources.format(Messages.GC_TIME_DETAILS, justify(formatTime(gcTime), 14),
|
||||
gcName,
|
||||
String.format("%,d",gcCount));
|
||||
if (!descPrinted) {
|
||||
text += newRow(Messages.GC_TIME, str);
|
||||
descPrinted = true;
|
||||
} else {
|
||||
text += newRow(null, str);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
Object src = ev.getSource();
|
||||
if (src == gcButton) {
|
||||
gc();
|
||||
}
|
||||
}
|
||||
|
||||
private class PoolPlotter extends Plotter {
|
||||
ObjectName objectName;
|
||||
String name;
|
||||
boolean isHeap;
|
||||
long value, threshold, max;
|
||||
int barX;
|
||||
|
||||
public PoolPlotter(ObjectName objectName, String name, boolean isHeap) {
|
||||
super(Plotter.Unit.BYTES);
|
||||
|
||||
this.objectName = objectName;
|
||||
this.name = name;
|
||||
this.isHeap = isHeap;
|
||||
|
||||
setAccessibleName(this,
|
||||
Resources.format(Messages.MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME,
|
||||
name));
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
private class PoolChart extends BorderedComponent
|
||||
implements Accessible, MouseListener {
|
||||
final int height = 150;
|
||||
final int leftMargin = 50;
|
||||
final int rightMargin = 23;
|
||||
final int bottomMargin = 35;
|
||||
final int barWidth = 22;
|
||||
final int barGap = 3;
|
||||
final int groupGap = 8;
|
||||
final int barHeight = height * 2 / 3;
|
||||
|
||||
final Color greenBar = new Color(100, 255, 100);
|
||||
final Color greenBarBackground = new Color(210, 255, 210);
|
||||
final Color redBarBackground = new Color(255, 210, 210);
|
||||
|
||||
Font smallFont = null;
|
||||
|
||||
ArrayList<PoolPlotter> poolPlotters = new ArrayList<PoolPlotter>(5);
|
||||
|
||||
int nHeapPools = 0;
|
||||
int nNonHeapPools = 0;
|
||||
Rectangle heapRect = new Rectangle(leftMargin, height - bottomMargin + 6, barWidth, 20);
|
||||
Rectangle nonHeapRect = new Rectangle(leftMargin + groupGap, height - bottomMargin + 6, barWidth, 20);
|
||||
|
||||
public PoolChart() {
|
||||
super(null, null);
|
||||
|
||||
setFocusable(true);
|
||||
addMouseListener(this);
|
||||
ToolTipManager.sharedInstance().registerComponent(this);
|
||||
}
|
||||
|
||||
public void setValue(int poolIndex, PoolPlotter poolPlotter,
|
||||
long value, long threshold, long max) {
|
||||
poolPlotter.value = value;
|
||||
poolPlotter.threshold = threshold;
|
||||
poolPlotter.max = max;
|
||||
|
||||
if (poolIndex == poolPlotters.size()) {
|
||||
poolPlotters.add(poolPlotter);
|
||||
if (poolPlotter.isHeap) {
|
||||
poolPlotter.barX = nHeapPools * (barWidth + barGap);
|
||||
nHeapPools++;
|
||||
heapRect.width = nHeapPools * barWidth + (nHeapPools - 1) * barGap;
|
||||
nonHeapRect.x = leftMargin + heapRect.width + groupGap;
|
||||
} else {
|
||||
poolPlotter.barX = nonHeapRect.x - leftMargin + nNonHeapPools * (barWidth + barGap);
|
||||
nNonHeapPools++;
|
||||
nonHeapRect.width = nNonHeapPools * barWidth + (nNonHeapPools - 1) * barGap;
|
||||
}
|
||||
} else {
|
||||
poolPlotters.set(poolIndex, poolPlotter);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void paintPoolBar(Graphics g, PoolPlotter poolPlotter) {
|
||||
Rectangle barRect = getBarRect(poolPlotter);
|
||||
g.setColor(Color.gray);
|
||||
g.drawRect(barRect.x, barRect.y, barRect.width, barRect.height);
|
||||
|
||||
long value = poolPlotter.value;
|
||||
long max = poolPlotter.max;
|
||||
if (max > 0L) {
|
||||
g.translate(barRect.x, barRect.y);
|
||||
|
||||
// Paint green background
|
||||
g.setColor(greenBarBackground);
|
||||
g.fillRect(1, 1, barRect.width - 1, barRect.height - 1);
|
||||
|
||||
int greenHeight = (int)(value * barRect.height / max);
|
||||
long threshold = poolPlotter.threshold;
|
||||
if (threshold > 0L) {
|
||||
int redHeight = (int)(threshold * barRect.height / max);
|
||||
|
||||
// Paint red background
|
||||
g.setColor(redBarBackground);
|
||||
g.fillRect(1, 1, barRect.width - 1, barRect.height - redHeight);
|
||||
|
||||
if (value > threshold) {
|
||||
// Over threshold, paint red bar
|
||||
g.setColor(thresholdColor);
|
||||
g.fillRect(1, barRect.height - greenHeight,
|
||||
barRect.width - 1, greenHeight - redHeight);
|
||||
greenHeight = redHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Paint green bar
|
||||
g.setColor(greenBar);
|
||||
g.fillRect(1, barRect.height - greenHeight,
|
||||
barRect.width - 1, greenHeight);
|
||||
|
||||
g.translate(-barRect.x, -barRect.y);
|
||||
}
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
if (poolPlotters.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (smallFont == null) {
|
||||
smallFont = g.getFont().deriveFont(9.0F);
|
||||
}
|
||||
|
||||
// Paint background for chart area
|
||||
g.setColor(getBackground());
|
||||
Rectangle r = g.getClipBounds();
|
||||
g.fillRect(r.x, r.y, r.width, r.height);
|
||||
|
||||
g.setFont(smallFont);
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int fontDescent = fm.getDescent();
|
||||
|
||||
// Paint percentage axis
|
||||
g.setColor(getForeground());
|
||||
for (int pc : new int[] { 0, 25, 50, 75, 100 }) {
|
||||
String str = pc + "% --";
|
||||
g.drawString(str,
|
||||
leftMargin - fm.stringWidth(str) - 4,
|
||||
height - bottomMargin - (pc * barHeight / 100) + fontDescent + 1);
|
||||
}
|
||||
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
paintPoolBar(g, poolPlotter);
|
||||
}
|
||||
|
||||
g.setColor(Color.gray);
|
||||
g.drawRect(heapRect.x, heapRect.y, heapRect.width, heapRect.height);
|
||||
g.drawRect(nonHeapRect.x, nonHeapRect.y, nonHeapRect.width, nonHeapRect.height);
|
||||
|
||||
Color heapColor = greenBar;
|
||||
Color nonHeapColor = greenBar;
|
||||
|
||||
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
if (poolPlotter.threshold > 0L && poolPlotter.value > poolPlotter.threshold) {
|
||||
if (poolPlotter.isHeap) {
|
||||
heapColor = thresholdColor;
|
||||
} else {
|
||||
nonHeapColor = thresholdColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
g.setColor(heapColor);
|
||||
g.fillRect(heapRect.x + 1, heapRect.y + 1, heapRect.width - 1, heapRect.height - 1);
|
||||
g.setColor(nonHeapColor);
|
||||
g.fillRect(nonHeapRect.x + 1, nonHeapRect.y + 1, nonHeapRect.width - 1, nonHeapRect.height - 1);
|
||||
|
||||
String str = Messages.HEAP;
|
||||
int stringWidth = fm.stringWidth(str);
|
||||
int x = heapRect.x + (heapRect.width - stringWidth) / 2;
|
||||
int y = heapRect.y + heapRect.height - 6;
|
||||
g.setColor(Color.white);
|
||||
g.drawString(str, x-1, y-1);
|
||||
g.drawString(str, x+1, y-1);
|
||||
g.drawString(str, x-1, y+1);
|
||||
g.drawString(str, x+1, y+1);
|
||||
g.setColor(Color.black);
|
||||
g.drawString(str, x, y);
|
||||
|
||||
str = Messages.NON_HEAP;
|
||||
stringWidth = fm.stringWidth(str);
|
||||
x = nonHeapRect.x + (nonHeapRect.width - stringWidth) / 2;
|
||||
y = nonHeapRect.y + nonHeapRect.height - 6;
|
||||
g.setColor(Color.white);
|
||||
g.drawString(str, x-1, y-1);
|
||||
g.drawString(str, x+1, y-1);
|
||||
g.drawString(str, x-1, y+1);
|
||||
g.drawString(str, x+1, y+1);
|
||||
g.setColor(Color.black);
|
||||
g.drawString(str, x, y);
|
||||
|
||||
// Highlight current plotter
|
||||
g.setColor(Color.blue);
|
||||
r = null;
|
||||
Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
|
||||
if (plotter == heapPlotter) {
|
||||
r = heapRect;
|
||||
} else if (plotter == nonHeapPlotter) {
|
||||
r = nonHeapRect;
|
||||
} else if (plotter instanceof PoolPlotter) {
|
||||
r = getBarRect((PoolPlotter)plotter);
|
||||
}
|
||||
if (r != null) {
|
||||
g.drawRect(r.x - 1, r.y - 1, r.width + 2, r.height + 2);
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle getBarRect(PoolPlotter poolPlotter) {
|
||||
return new Rectangle(leftMargin + poolPlotter.barX,
|
||||
height - bottomMargin - barHeight,
|
||||
barWidth, barHeight);
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(nonHeapRect.x + nonHeapRect.width + rightMargin,
|
||||
height);
|
||||
}
|
||||
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
requestFocusInWindow();
|
||||
Plotter plotter = getPlotter(e);
|
||||
|
||||
if (plotter != null && plotter != plotterChoice.getSelectedItem()) {
|
||||
plotterChoice.setSelectedItem(plotter);
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public String getToolTipText(MouseEvent e) {
|
||||
Plotter plotter = getPlotter(e);
|
||||
|
||||
return (plotter != null) ? plotter.toString() : null;
|
||||
}
|
||||
|
||||
private Plotter getPlotter(MouseEvent e) {
|
||||
Point p = e.getPoint();
|
||||
Plotter plotter = null;
|
||||
|
||||
if (heapRect.contains(p)) {
|
||||
plotter = heapPlotter;
|
||||
} else if (nonHeapRect.contains(p)) {
|
||||
plotter = nonHeapPlotter;
|
||||
} else {
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
if (getBarRect(poolPlotter).contains(p)) {
|
||||
plotter = poolPlotter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return plotter;
|
||||
}
|
||||
|
||||
public void mousePressed(MouseEvent e) {}
|
||||
public void mouseReleased(MouseEvent e) {}
|
||||
public void mouseEntered(MouseEvent e) {}
|
||||
public void mouseExited(MouseEvent e) {}
|
||||
|
||||
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessiblePoolChart();
|
||||
}
|
||||
return accessibleContext;
|
||||
}
|
||||
|
||||
protected class AccessiblePoolChart extends AccessibleJPanel {
|
||||
public String getAccessibleName() {
|
||||
String name = Messages.MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME;
|
||||
|
||||
String keyValueList = "";
|
||||
for (PoolPlotter poolPlotter : poolPlotters) {
|
||||
String value = (poolPlotter.value * 100 / poolPlotter.max) + "%";
|
||||
// Assume format string ends with newline
|
||||
keyValueList +=
|
||||
Resources.format(Messages.PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE,
|
||||
poolPlotter.toString(), value);
|
||||
if (poolPlotter.threshold > 0L) {
|
||||
String threshold =
|
||||
(poolPlotter.threshold * 100 / poolPlotter.max) + "%";
|
||||
if (poolPlotter.value > poolPlotter.threshold) {
|
||||
keyValueList +=
|
||||
Resources.format(Messages.MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD,
|
||||
threshold);
|
||||
} else {
|
||||
keyValueList +=
|
||||
Resources.format(Messages.MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD,
|
||||
threshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return name + "\n" + keyValueList + ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
OverviewPanel[] getOverviewPanels() {
|
||||
if (overviewPanel == null) {
|
||||
overviewPanel = new MemoryOverviewPanel();
|
||||
}
|
||||
return new OverviewPanel[] { overviewPanel };
|
||||
}
|
||||
|
||||
private static class MemoryOverviewPanel extends OverviewPanel {
|
||||
MemoryOverviewPanel() {
|
||||
super(Messages.HEAP_MEMORY_USAGE, usedKey, Messages.USED, Plotter.Unit.BYTES);
|
||||
}
|
||||
|
||||
private void updateMemoryInfo(long used, long committed, long max) {
|
||||
getInfoLabel().setText(Resources.format(Messages.MEMORY_TAB_INFO_LABEL_FORMAT,
|
||||
formatBytes(used, true),
|
||||
formatBytes(committed, true),
|
||||
formatBytes(max, true)));
|
||||
}
|
||||
}
|
||||
}
|
||||
325
jdkSrc/jdk8/sun/tools/jconsole/Messages.java
Normal file
325
jdkSrc/jdk8/sun/tools/jconsole/Messages.java
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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 sun.tools.jconsole;
|
||||
|
||||
|
||||
/**
|
||||
* Class that contains localized messages.
|
||||
*
|
||||
*/
|
||||
final public class Messages {
|
||||
private static final String BUNDLE_NAME = "sun.tools.jconsole.resources.messages";
|
||||
|
||||
static {
|
||||
Resources.initializeMessages(Messages.class, BUNDLE_NAME);
|
||||
}
|
||||
// TODO:
|
||||
// The names of some of the constants below look strange.
|
||||
// That's because they were generated programmatically
|
||||
// from the messages. They should be cleaned up,
|
||||
// ___ should be removed etc.
|
||||
public static String ONE_DAY;
|
||||
public static String ONE_HOUR;
|
||||
public static String ONE_MIN;
|
||||
public static String ONE_MONTH;
|
||||
public static String ONE_YEAR;
|
||||
public static String TWO_HOURS;
|
||||
public static String THREE_HOURS;
|
||||
public static String THREE_MONTHS;
|
||||
public static String FIVE_MIN;
|
||||
public static String SIX_HOURS;
|
||||
public static String SIX_MONTHS;
|
||||
public static String SEVEN_DAYS;
|
||||
public static String TEN_MIN;
|
||||
public static String TWELVE_HOURS;
|
||||
public static String THIRTY_MIN;
|
||||
public static String LESS_THAN;
|
||||
public static String A_LOT_LESS_THAN;
|
||||
public static String GREATER_THAN;
|
||||
public static String ACTION_CAPITALIZED;
|
||||
public static String ACTION_INFO_CAPITALIZED;
|
||||
public static String ALL;
|
||||
public static String ARCHITECTURE;
|
||||
public static String ATTRIBUTE;
|
||||
public static String ATTRIBUTE_VALUE;
|
||||
public static String ATTRIBUTE_VALUES;
|
||||
public static String ATTRIBUTES;
|
||||
public static String BLANK;
|
||||
public static String BLOCKED_COUNT_WAITED_COUNT;
|
||||
public static String BOOT_CLASS_PATH;
|
||||
public static String BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP;
|
||||
public static String CPU_USAGE;
|
||||
public static String CPU_USAGE_FORMAT;
|
||||
public static String CANCEL;
|
||||
public static String CASCADE;
|
||||
public static String CHART_COLON;
|
||||
public static String CLASS_PATH;
|
||||
public static String CLASS_NAME;
|
||||
public static String CLASS_TAB_INFO_LABEL_FORMAT;
|
||||
public static String CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String CLASSES;
|
||||
public static String CLOSE;
|
||||
public static String COLUMN_NAME;
|
||||
public static String COLUMN_PID;
|
||||
public static String COMMITTED_MEMORY;
|
||||
public static String COMMITTED_VIRTUAL_MEMORY;
|
||||
public static String COMMITTED;
|
||||
public static String CONNECT;
|
||||
public static String CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP;
|
||||
public static String CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION;
|
||||
public static String CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
|
||||
public static String CONNECT_DIALOG_MASTHEAD_TITLE;
|
||||
public static String CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME;
|
||||
public static String CONNECT_DIALOG_TITLE;
|
||||
public static String CONNECTED_PUNCTUATION_CLICK_TO_DISCONNECT_;
|
||||
public static String CONNECTION_FAILED;
|
||||
public static String CONNECTION;
|
||||
public static String CONNECTION_NAME;
|
||||
public static String CONNECTION_NAME__DISCONNECTED_;
|
||||
public static String CONSTRUCTOR;
|
||||
public static String CURRENT_CLASSES_LOADED;
|
||||
public static String CURRENT_HEAP_SIZE;
|
||||
public static String CURRENT_VALUE;
|
||||
public static String CREATE;
|
||||
public static String DAEMON_THREADS;
|
||||
public static String DISCONNECTED_PUNCTUATION_CLICK_TO_CONNECT_;
|
||||
public static String DOUBLE_CLICK_TO_EXPAND_FORWARD_SLASH_COLLAPSE;
|
||||
public static String DOUBLE_CLICK_TO_VISUALIZE;
|
||||
public static String DESCRIPTION;
|
||||
public static String DESCRIPTOR;
|
||||
public static String DETAILS;
|
||||
public static String DETECT_DEADLOCK;
|
||||
public static String DETECT_DEADLOCK_TOOLTIP;
|
||||
public static String DIMENSION_IS_NOT_SUPPORTED_COLON;
|
||||
public static String DISCARD_CHART;
|
||||
public static String DURATION_DAYS_HOURS_MINUTES;
|
||||
public static String DURATION_HOURS_MINUTES;
|
||||
public static String DURATION_MINUTES;
|
||||
public static String DURATION_SECONDS;
|
||||
public static String EMPTY_ARRAY;
|
||||
public static String ERROR;
|
||||
public static String ERROR_COLON_MBEANS_ALREADY_EXIST;
|
||||
public static String ERROR_COLON_MBEANS_DO_NOT_EXIST;
|
||||
public static String EVENT;
|
||||
public static String EXIT;
|
||||
public static String FAIL_TO_LOAD_PLUGIN;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_CANCEL_OPTION;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_MESSAGE;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_OK_OPTION;
|
||||
public static String FILE_CHOOSER_FILE_EXISTS_TITLE;
|
||||
public static String FILE_CHOOSER_SAVED_FILE;
|
||||
public static String FILE_CHOOSER_SAVE_FAILED_MESSAGE;
|
||||
public static String FILE_CHOOSER_SAVE_FAILED_TITLE;
|
||||
public static String FREE_PHYSICAL_MEMORY;
|
||||
public static String FREE_SWAP_SPACE;
|
||||
public static String GARBAGE_COLLECTOR;
|
||||
public static String GC_INFO;
|
||||
public static String GC_TIME;
|
||||
public static String GC_TIME_DETAILS;
|
||||
public static String HEAP_MEMORY_USAGE;
|
||||
public static String HEAP;
|
||||
public static String HELP_ABOUT_DIALOG_ACCESSIBLE_DESCRIPTION;
|
||||
public static String HELP_ABOUT_DIALOG_JCONSOLE_VERSION;
|
||||
public static String HELP_ABOUT_DIALOG_JAVA_VERSION;
|
||||
public static String HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
|
||||
public static String HELP_ABOUT_DIALOG_MASTHEAD_TITLE;
|
||||
public static String HELP_ABOUT_DIALOG_TITLE;
|
||||
public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL;
|
||||
public static String HELP_MENU_ABOUT_TITLE;
|
||||
public static String HELP_MENU_USER_GUIDE_TITLE;
|
||||
public static String HELP_MENU_TITLE;
|
||||
public static String HOTSPOT_MBEANS_ELLIPSIS;
|
||||
public static String HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION;
|
||||
public static String IMPACT;
|
||||
public static String INFO;
|
||||
public static String INFO_CAPITALIZED;
|
||||
public static String INSECURE;
|
||||
public static String INVALID_PLUGIN_PATH;
|
||||
public static String INVALID_URL;
|
||||
public static String IS;
|
||||
public static String JAVA_MONITORING___MANAGEMENT_CONSOLE;
|
||||
public static String JCONSOLE_COLON_;
|
||||
public static String JCONSOLE_VERSION; // in version template
|
||||
public static String JCONSOLE_ACCESSIBLE_DESCRIPTION;
|
||||
public static String JIT_COMPILER;
|
||||
public static String LIBRARY_PATH;
|
||||
public static String LIVE_THREADS;
|
||||
public static String LOADED;
|
||||
public static String LOCAL_PROCESS_COLON;
|
||||
public static String MASTHEAD_FONT;
|
||||
public static String MANAGEMENT_NOT_ENABLED;
|
||||
public static String MANAGEMENT_WILL_BE_ENABLED;
|
||||
public static String MBEAN_ATTRIBUTE_INFO;
|
||||
public static String MBEAN_INFO;
|
||||
public static String MBEAN_NOTIFICATION_INFO;
|
||||
public static String MBEAN_OPERATION_INFO;
|
||||
public static String MBEANS;
|
||||
public static String MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON;
|
||||
public static String MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP;
|
||||
public static String MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE;
|
||||
public static String MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE;
|
||||
public static String MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON;
|
||||
public static String MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP;
|
||||
public static String MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON;
|
||||
public static String MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP;
|
||||
public static String MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE;
|
||||
public static String MBEANS_TAB_TABULAR_NAVIGATION_SINGLE;
|
||||
public static String MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON;
|
||||
public static String MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP;
|
||||
public static String MANAGE_HOTSPOT_MBEANS_IN_COLON_;
|
||||
public static String MAX;
|
||||
public static String MAXIMUM_HEAP_SIZE;
|
||||
public static String MEMORY;
|
||||
public static String MEMORY_POOL_LABEL;
|
||||
public static String MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String MEMORY_TAB_INFO_LABEL_FORMAT;
|
||||
public static String MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD;
|
||||
public static String MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME;
|
||||
public static String MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD;
|
||||
public static String MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String MESSAGE;
|
||||
public static String METHOD_SUCCESSFULLY_INVOKED;
|
||||
public static String MINIMIZE_ALL;
|
||||
public static String MONITOR_LOCKED;
|
||||
public static String NAME;
|
||||
public static String NAME_STATE;
|
||||
public static String NAME_STATE_LOCK_NAME;
|
||||
public static String NAME_STATE_LOCK_NAME_LOCK_OWNER;
|
||||
public static String NAME_AND_BUILD;// in version template
|
||||
public static String NEW_CONNECTION_ELLIPSIS;
|
||||
public static String NO_DEADLOCK_DETECTED;
|
||||
public static String NON_HEAP_MEMORY_USAGE;
|
||||
public static String NON_HEAP;
|
||||
public static String NOTIFICATION;
|
||||
public static String NOTIFICATION_BUFFER;
|
||||
public static String NOTIFICATIONS;
|
||||
public static String NOTIF_TYPES;
|
||||
public static String NUMBER_OF_THREADS;
|
||||
public static String NUMBER_OF_LOADED_CLASSES;
|
||||
public static String NUMBER_OF_PROCESSORS;
|
||||
public static String OBJECT_NAME;
|
||||
public static String OPERATING_SYSTEM;
|
||||
public static String OPERATION;
|
||||
public static String OPERATION_INVOCATION;
|
||||
public static String OPERATION_RETURN_VALUE;
|
||||
public static String OPERATIONS;
|
||||
public static String OVERVIEW;
|
||||
public static String OVERVIEW_PANEL_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String PARAMETER;
|
||||
public static String PASSWORD_COLON_;
|
||||
public static String PASSWORD_ACCESSIBLE_NAME;
|
||||
public static String PEAK;
|
||||
public static String PERFORM_GC;
|
||||
public static String PERFORM_GC_TOOLTIP;
|
||||
public static String PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE;
|
||||
public static String PLOTTER_ACCESSIBLE_NAME_NO_DATA;
|
||||
public static String PLOTTER_SAVE_AS_MENU_ITEM;
|
||||
public static String PLOTTER_TIME_RANGE_MENU;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_EXIT;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_IGNORE;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_BUTTON_OK;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_MESSAGE;
|
||||
public static String PLUGIN_EXCEPTION_DIALOG_TITLE;
|
||||
public static String PROBLEM_ADDING_LISTENER;
|
||||
public static String PROBLEM_DISPLAYING_MBEAN;
|
||||
public static String PROBLEM_INVOKING;
|
||||
public static String PROBLEM_REMOVING_LISTENER;
|
||||
public static String PROBLEM_SETTING_ATTRIBUTE;
|
||||
public static String PROCESS_CPU_TIME;
|
||||
public static String READABLE;
|
||||
public static String RECONNECT;
|
||||
public static String REMOTE_PROCESS_COLON;
|
||||
public static String REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME;
|
||||
public static String RESTORE_ALL;
|
||||
public static String RETURN_TYPE;
|
||||
public static String SEQ_NUM;
|
||||
public static String SIZE_BYTES;
|
||||
public static String SIZE_GB;
|
||||
public static String SIZE_KB;
|
||||
public static String SIZE_MB;
|
||||
public static String SOURCE;
|
||||
public static String STACK_TRACE;
|
||||
public static String SUMMARY_TAB_HEADER_DATE_TIME_FORMAT;
|
||||
public static String SUMMARY_TAB_PENDING_FINALIZATION_LABEL;
|
||||
public static String SUMMARY_TAB_PENDING_FINALIZATION_VALUE;
|
||||
public static String SUMMARY_TAB_TAB_NAME;
|
||||
public static String SUMMARY_TAB_VM_VERSION;
|
||||
public static String THREADS;
|
||||
public static String THREAD_TAB_INFO_LABEL_FORMAT;
|
||||
public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME;
|
||||
public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME;
|
||||
public static String THREAD_TAB_INITIAL_STACK_TRACE_MESSAGE;
|
||||
public static String THRESHOLD;
|
||||
public static String TILE;
|
||||
public static String TIME_RANGE_COLON;
|
||||
public static String TIME;
|
||||
public static String TIME_STAMP;
|
||||
public static String TOTAL_LOADED;
|
||||
public static String TOTAL_CLASSES_LOADED;
|
||||
public static String TOTAL_CLASSES_UNLOADED;
|
||||
public static String TOTAL_COMPILE_TIME;
|
||||
public static String TOTAL_PHYSICAL_MEMORY;
|
||||
public static String TOTAL_THREADS_STARTED;
|
||||
public static String TOTAL_SWAP_SPACE;
|
||||
public static String TYPE;
|
||||
public static String UNAVAILABLE;
|
||||
public static String UNKNOWN_CAPITALIZED;
|
||||
public static String UNKNOWN_HOST;
|
||||
public static String UNREGISTER;
|
||||
public static String UPTIME;
|
||||
public static String USAGE_THRESHOLD;
|
||||
public static String REMOTE_TF_USAGE;
|
||||
public static String USED;
|
||||
public static String USERNAME_COLON_;
|
||||
public static String USERNAME_ACCESSIBLE_NAME;
|
||||
public static String USER_DATA;
|
||||
public static String VIRTUAL_MACHINE;
|
||||
public static String VM_ARGUMENTS;
|
||||
public static String VMINTERNAL_FRAME_ACCESSIBLE_DESCRIPTION;
|
||||
public static String VALUE;
|
||||
public static String VENDOR;
|
||||
public static String VERBOSE_OUTPUT;
|
||||
public static String VERBOSE_OUTPUT_TOOLTIP;
|
||||
public static String VIEW;
|
||||
public static String WINDOW;
|
||||
public static String WINDOWS;
|
||||
public static String WRITABLE;
|
||||
public static String CONNECTION_FAILED1;
|
||||
public static String CONNECTION_FAILED2;
|
||||
public static String CONNECTION_FAILED_SSL1;
|
||||
public static String CONNECTION_FAILED_SSL2;
|
||||
public static String CONNECTION_LOST1;
|
||||
public static String CONNECTING_TO1;
|
||||
public static String CONNECTING_TO2;
|
||||
public static String DEADLOCK_TAB;
|
||||
public static String DEADLOCK_TAB_N;
|
||||
public static String EXPAND;
|
||||
public static String KBYTES;
|
||||
public static String PLOT;
|
||||
public static String VISUALIZE;
|
||||
public static String ZZ_USAGE_TEXT;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user