|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.tools.javac; |
|
|
|
import sun.tools.java.*; |
|
import sun.tools.tree.*; |
|
|
|
import java.io.IOException; |
|
import java.io.InputStream; |
|
import java.util.Vector; |
|
import java.util.Enumeration; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
@Deprecated |
|
public |
|
class BatchParser extends Parser { |
|
|
|
|
|
*/ |
|
protected Identifier pkg; |
|
|
|
|
|
|
|
*/ |
|
protected Imports imports; |
|
|
|
|
|
|
|
*/ |
|
protected Vector classes; |
|
|
|
|
|
|
|
|
|
*/ |
|
protected SourceClass sourceClass; |
|
|
|
|
|
|
|
*/ |
|
protected Environment toplevelEnv; |
|
|
|
|
|
|
|
*/ |
|
public BatchParser(Environment env, InputStream in) throws IOException { |
|
super(env, in); |
|
|
|
imports = new Imports(env); |
|
classes = new Vector(); |
|
toplevelEnv = imports.newEnvironment(env); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void packageDeclaration(long where, IdentifierToken t) { |
|
Identifier nm = t.getName(); |
|
|
|
if (pkg == null) { |
|
// This code has been changed to pass an IdentifierToken, |
|
// rather than an Identifier, to setCurrentPackage(). Imports |
|
|
|
pkg = t.getName(); |
|
imports.setCurrentPackage(t); |
|
} else { |
|
env.error(where, "package.repeated"); |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void importClass(long pos, IdentifierToken t) { |
|
|
|
imports.addClass(t); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void importPackage(long pos, IdentifierToken t) { |
|
|
|
imports.addPackage(t); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public ClassDefinition beginClass(long where, String doc, int mod, |
|
IdentifierToken t, |
|
IdentifierToken sup, |
|
IdentifierToken interfaces[]) { |
|
|
|
// If this class is nested, the modifier bits set here will |
|
// be copied into the 'SourceMember' object for the inner class |
|
// created during the call to 'makeClassDefinition' below. |
|
// When writing the class file, we will look there for the |
|
// 'untransformed' modifiers. The modifiers in the ClassDefinition |
|
// object will end up as the 'transformed' modifiers. Note that |
|
// there are some bits set here that are not legal class modifiers |
|
// according to the JVMS, e.g., M_PRIVATE and M_STATIC. These are |
|
// masked off while writing the class file, but are preserved in |
|
// the InnerClasses attributes. |
|
|
|
if (tracing) toplevelEnv.dtEnter("beginClass: " + sourceClass); |
|
|
|
SourceClass outerClass = sourceClass; |
|
|
|
if (outerClass == null && pkg != null) { |
|
t = new IdentifierToken(t.getWhere(), |
|
Identifier.lookup(pkg, t.getName())); |
|
} |
|
|
|
// The defaults for anonymous and local classes should be documented! |
|
|
|
if ((mod & M_ANONYMOUS) != 0) { |
|
mod |= (M_FINAL | M_PRIVATE); |
|
} |
|
if ((mod & M_LOCAL) != 0) { |
|
mod |= M_PRIVATE; |
|
} |
|
|
|
// Certain modifiers are implied as follows: |
|
// |
|
// 1. Any interface (nested or not) is implicitly deemed to be abstract, |
|
// whether it is explicitly marked so or not. (Java 1.0.) |
|
// 2. A interface which is a member of a type is implicitly deemed to |
|
// be static, whether it is explicitly marked so or not. (InnerClasses) |
|
// 3a. A type which is a member of an interface is implicitly deemed |
|
// to be public, whether it is explicitly marked so or not. (InnerClasses) |
|
// 3b. A type which is a member of an interface is implicitly deemed |
|
// to be static, whether it is explicitly marked so or not. (InnerClasses) |
|
|
|
if ((mod & M_INTERFACE) != 0) { |
|
|
|
mod |= M_ABSTRACT; |
|
if (outerClass != null) { |
|
|
|
mod |= M_STATIC; |
|
} |
|
} |
|
|
|
if (outerClass != null && outerClass.isInterface()) { |
|
// Rule 3a. |
|
// For interface members, neither 'private' nor 'protected' |
|
// are legal modifiers. We avoid setting M_PUBLIC in some |
|
// cases in order to avoid interfering with error detection |
|
// and reporting. This is patched up, after reporting an |
|
|
|
if ((mod & (M_PRIVATE | M_PROTECTED)) == 0) |
|
mod |= M_PUBLIC; |
|
|
|
mod |= M_STATIC; |
|
} |
|
|
|
// For nested classes, we must transform 'protected' to 'public' |
|
// and 'private' to package scope. This must be done later, |
|
// because any modifiers set here will be copied into the |
|
// 'MemberDefinition' for the nested class, which must represent |
|
// the original untransformed modifiers. Also, compile-time |
|
// checks should be performed against the actual, untransformed |
|
// modifiers. This is in contrast to transformations that implement |
|
// implicit modifiers, such as M_STATIC and M_FINAL for fields |
|
// of interfaces. |
|
|
|
sourceClass = (SourceClass) |
|
toplevelEnv.makeClassDefinition(toplevelEnv, where, t, |
|
doc, mod, sup, |
|
interfaces, outerClass); |
|
|
|
sourceClass.getClassDeclaration().setDefinition(sourceClass, CS_PARSED); |
|
env = new Environment(toplevelEnv, sourceClass); |
|
|
|
if (tracing) toplevelEnv.dtEvent("beginClass: SETTING UP DEPENDENCIES"); |
|
|
|
// The code which adds artificial dependencies between |
|
// classes in the same source file has been moved to |
|
// BatchEnvironment#parseFile(). |
|
|
|
if (tracing) toplevelEnv.dtEvent("beginClass: ADDING TO CLASS LIST"); |
|
|
|
classes.addElement(sourceClass); |
|
|
|
if (tracing) toplevelEnv.dtExit("beginClass: " + sourceClass); |
|
|
|
return sourceClass; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public ClassDefinition getCurrentClass() { |
|
return sourceClass; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void endClass(long where, ClassDefinition c) { |
|
|
|
if (tracing) toplevelEnv.dtEnter("endClass: " + sourceClass); |
|
|
|
|
|
sourceClass.setEndPosition(where); |
|
SourceClass outerClass = (SourceClass) sourceClass.getOuterClass(); |
|
sourceClass = outerClass; |
|
env = toplevelEnv; |
|
if (sourceClass != null) |
|
env = new Environment(env, sourceClass); |
|
|
|
if (tracing) toplevelEnv.dtExit("endClass: " + sourceClass); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void defineField(long where, ClassDefinition c, |
|
String doc, int mod, Type t, |
|
IdentifierToken name, IdentifierToken args[], |
|
IdentifierToken exp[], Node val) { |
|
|
|
Identifier nm = name.getName(); |
|
// Members that are nested classes are not created with 'defineField', |
|
|
|
if (sourceClass.isInterface()) { |
|
|
|
if ((mod & (M_PRIVATE | M_PROTECTED)) == 0) |
|
// For interface members, neither 'private' nor 'protected' |
|
// are legal modifiers. Avoid setting M_PUBLIC in some cases |
|
// to avoid interfering with later error detection. This will |
|
|
|
mod |= M_PUBLIC; |
|
// Methods of interfaces are implicitly abstract. |
|
|
|
if (t.isType(TC_METHOD)) { |
|
mod |= M_ABSTRACT; |
|
} else { |
|
mod |= M_STATIC | M_FINAL; |
|
} |
|
} |
|
if (nm.equals(idInit)) { |
|
// The parser reports "idInit" when in reality it has found |
|
// that there is no method name at all present. |
|
|
|
Type rt = t.getReturnType(); |
|
Identifier retname = !rt.isType(TC_CLASS) ? idStar |
|
: rt.getClassName(); |
|
Identifier clsname = sourceClass.getLocalName(); |
|
if (clsname.equals(retname)) { |
|
t = Type.tMethod(Type.tVoid, t.getArgumentTypes()); |
|
} else if (clsname.equals(retname.getFlatName().getName())) { |
|
|
|
t = Type.tMethod(Type.tVoid, t.getArgumentTypes()); |
|
env.error(where, "invalid.method.decl.qual"); |
|
} else if (retname.isQualified() || retname.equals(idStar)) { |
|
|
|
env.error(where, "invalid.method.decl.name"); |
|
return; |
|
} else { |
|
// We assume the type name is missing, even though the |
|
// simple name that's present might have been intended |
|
|
|
env.error(where, "invalid.method.decl"); |
|
return; |
|
} |
|
} |
|
|
|
if (args == null && t.isType(TC_METHOD)) { |
|
args = new IdentifierToken[0]; |
|
} |
|
|
|
if (exp == null && t.isType(TC_METHOD)) { |
|
exp = new IdentifierToken[0]; |
|
} |
|
|
|
MemberDefinition f = env.makeMemberDefinition(env, where, sourceClass, |
|
doc, mod, t, nm, |
|
args, exp, val); |
|
if (env.dump()) { |
|
f.print(System.out); |
|
} |
|
} |
|
} |