feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user