/* * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.tools.javac; import sun.tools.java.*;import sun.tools.tree.*; import java.io.IOException;import java.io.InputStream;import java.util.Vector;import java.util.Enumeration; /** * Batch file parser, this needs more work. * * WARNING: The contents of this source file are not part of any * supported API. Code that depends on them does so at its own risk: * they are subject to change or removal without notice. */@Deprecatedpublicclass BatchParser extends Parser { /** * The current package */ protected Identifier pkg; /** * The current imports */ protected Imports imports; /** * The classes defined in this file */ protected Vector classes; /** * The current class */ protected SourceClass sourceClass; /** * The toplevel environment */ protected Environment toplevelEnv; /** * Create a batch file parser */ public BatchParser(Environment env, InputStream in) throws IOException { super(env, in); imports = new Imports(env); classes = new Vector(); toplevelEnv = imports.newEnvironment(env); } /** * Package declaration */ public void packageDeclaration(long where, IdentifierToken t) { Identifier nm = t.getName(); //System.out.println("package " + nm); if (pkg == null) { // This code has been changed to pass an IdentifierToken, // rather than an Identifier, to setCurrentPackage(). Imports // now needs the location of the token. pkg = t.getName(); imports.setCurrentPackage(t); } else { env.error(where, "package.repeated"); } } /** * Import class */ public void importClass(long pos, IdentifierToken t) { //System.out.println("import class " + t); imports.addClass(t); } /** * Import package */ public void importPackage(long pos, IdentifierToken t) { //System.out.println("import package " + t); imports.addPackage(t); } /** * Define class */ public ClassDefinition beginClass(long where, String doc, int mod, IdentifierToken t, IdentifierToken sup, IdentifierToken interfaces[]) { // If this class is nested, the modifier bits set here will // be copied into the 'SourceMember' object for the inner class // created during the call to 'makeClassDefinition' below. // When writing the class file, we will look there for the // 'untransformed' modifiers. The modifiers in the ClassDefinition // object will end up as the 'transformed' modifiers. Note that // there are some bits set here that are not legal class modifiers // according to the JVMS, e.g., M_PRIVATE and M_STATIC. These are // masked off while writing the class file, but are preserved in // the InnerClasses attributes. if (tracing) toplevelEnv.dtEnter("beginClass: " + sourceClass); SourceClass outerClass = sourceClass; if (outerClass == null && pkg != null) { t = new IdentifierToken(t.getWhere(), Identifier.lookup(pkg, t.getName())); } // The defaults for anonymous and local classes should be documented! if ((mod & M_ANONYMOUS) != 0) { mod |= (M_FINAL | M_PRIVATE); } if ((mod & M_LOCAL) != 0) { mod |= M_PRIVATE; } // Certain modifiers are implied as follows: // // 1. Any interface (nested or not) is implicitly deemed to be abstract, // whether it is explicitly marked so or not. (Java 1.0.) // 2. A interface which is a member of a type is implicitly deemed to // be static, whether it is explicitly marked so or not. (InnerClasses) // 3a. A type which is a member of an interface is implicitly deemed // to be public, whether it is explicitly marked so or not. (InnerClasses) // 3b. A type which is a member of an interface is implicitly deemed // to be static, whether it is explicitly marked so or not. (InnerClasses) if ((mod & M_INTERFACE) != 0) { // Rule 1. mod |= M_ABSTRACT; if (outerClass != null) { // Rule 2. mod |= M_STATIC; } } if (outerClass != null && outerClass.isInterface()) { // Rule 3a. // For interface members, neither 'private' nor 'protected' // are legal modifiers. We avoid setting M_PUBLIC in some // cases in order to avoid interfering with error detection // and reporting. This is patched up, after reporting an // error, by 'SourceClass.addMember'. if ((mod & (M_PRIVATE | M_PROTECTED)) == 0) mod |= M_PUBLIC; // Rule 3b. mod |= M_STATIC; } // For nested classes, we must transform 'protected' to 'public' // and 'private' to package scope. This must be done later, // because any modifiers set here will be copied into the // 'MemberDefinition' for the nested class, which must represent // the original untransformed modifiers. Also, compile-time // checks should be performed against the actual, untransformed // modifiers. This is in contrast to transformations that implement // implicit modifiers, such as M_STATIC and M_FINAL for fields // of interfaces. sourceClass = (SourceClass) toplevelEnv.makeClassDefinition(toplevelEnv, where, t, doc, mod, sup, interfaces, outerClass); sourceClass.getClassDeclaration().setDefinition(sourceClass, CS_PARSED); env = new Environment(toplevelEnv, sourceClass); if (tracing) toplevelEnv.dtEvent("beginClass: SETTING UP DEPENDENCIES"); // The code which adds artificial dependencies between // classes in the same source file has been moved to // BatchEnvironment#parseFile(). if (tracing) toplevelEnv.dtEvent("beginClass: ADDING TO CLASS LIST"); classes.addElement(sourceClass); if (tracing) toplevelEnv.dtExit("beginClass: " + sourceClass); return sourceClass; } /** * Report the current class under construction. */ public ClassDefinition getCurrentClass() { return sourceClass; } /** * End class */ public void endClass(long where, ClassDefinition c) { if (tracing) toplevelEnv.dtEnter("endClass: " + sourceClass); // c == sourceClass; don't bother to check sourceClass.setEndPosition(where); SourceClass outerClass = (SourceClass) sourceClass.getOuterClass(); sourceClass = outerClass; env = toplevelEnv; if (sourceClass != null) env = new Environment(env, sourceClass); if (tracing) toplevelEnv.dtExit("endClass: " + sourceClass); } /** * Define a method */ public void defineField(long where, ClassDefinition c, String doc, int mod, Type t, IdentifierToken name, IdentifierToken args[], IdentifierToken exp[], Node val) { // c == sourceClass; don't bother to check Identifier nm = name.getName(); // Members that are nested classes are not created with 'defineField', // so these transformations do not apply to them. See 'beginClass' above. if (sourceClass.isInterface()) { // Members of interfaces are implicitly public. if ((mod & (M_PRIVATE | M_PROTECTED)) == 0) // For interface members, neither 'private' nor 'protected' // are legal modifiers. Avoid setting M_PUBLIC in some cases // to avoid interfering with later error detection. This will // be fixed up after the error is reported. mod |= M_PUBLIC; // Methods of interfaces are implicitly abstract. // Fields of interfaces are implicitly static and final. if (t.isType(TC_METHOD)) { mod |= M_ABSTRACT; } else { mod |= M_STATIC | M_FINAL; } } if (nm.equals(idInit)) { // The parser reports "idInit" when in reality it has found // that there is no method name at all present. // So, decide if it's really a constructor, or a syntax error. Type rt = t.getReturnType(); Identifier retname = !rt.isType(TC_CLASS) ? idStar /*no match*/ : rt.getClassName(); Identifier clsname = sourceClass.getLocalName(); if (clsname.equals(retname)) { t = Type.tMethod(Type.tVoid, t.getArgumentTypes()); } else if (clsname.equals(retname.getFlatName().getName())) { // It appears to be a constructor with spurious qualification. t = Type.tMethod(Type.tVoid, t.getArgumentTypes()); env.error(where, "invalid.method.decl.qual"); } else if (retname.isQualified() || retname.equals(idStar)) { // It appears to be a type name with no method name. env.error(where, "invalid.method.decl.name"); return; } else { // We assume the type name is missing, even though the // simple name that's present might have been intended // to be a type: "String (){}" vs. "toString(){}". env.error(where, "invalid.method.decl"); return; } } if (args == null && t.isType(TC_METHOD)) { args = new IdentifierToken[0]; } if (exp == null && t.isType(TC_METHOD)) { exp = new IdentifierToken[0]; } MemberDefinition f = env.makeMemberDefinition(env, where, sourceClass, doc, mod, t, nm, args, exp, val); if (env.dump()) { f.print(System.out); } }}
/*
* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.javac;
import sun.tools.java.*;
import sun.tools.tree.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import java.util.Enumeration;
/**
* Batch file parser, this needs more work.
*
* WARNING: The contents of this source file are not part of any
* supported API. Code that depends on them does so at its own risk:
* they are subject to change or removal without notice.
*/
@Deprecated
public
class BatchParser extends Parser {
/**
* The current package
*/
protected Identifier pkg;
/**
* The current imports
*/
protected Imports imports;
/**
* The classes defined in this file
*/
protected Vector classes;
/**
* The current class
*/
protected SourceClass sourceClass;
/**
* The toplevel environment
*/
protected Environment toplevelEnv;
/**
* Create a batch file parser
*/
public BatchParser(Environment env, InputStream in) throws IOException {
super(env, in);
imports = new Imports(env);
classes = new Vector();
toplevelEnv = imports.newEnvironment(env);
}
/**
* Package declaration
*/
public void packageDeclaration(long where, IdentifierToken t) {
Identifier nm = t.getName();
//System.out.println("package " + nm);
if (pkg == null) {
// This code has been changed to pass an IdentifierToken,
// rather than an Identifier, to setCurrentPackage(). Imports
// now needs the location of the token.
pkg = t.getName();
imports.setCurrentPackage(t);
} else {
env.error(where, "package.repeated");
}
}
/**
* Import class
*/
public void importClass(long pos, IdentifierToken t) {
//System.out.println("import class " + t);
imports.addClass(t);
}
/**
* Import package
*/
public void importPackage(long pos, IdentifierToken t) {
//System.out.println("import package " + t);
imports.addPackage(t);
}
/**
* Define class
*/
public ClassDefinition beginClass(long where, String doc, int mod,
IdentifierToken t,
IdentifierToken sup,
IdentifierToken interfaces[]) {
// If this class is nested, the modifier bits set here will
// be copied into the 'SourceMember' object for the inner class
// created during the call to 'makeClassDefinition' below.
// When writing the class file, we will look there for the
// 'untransformed' modifiers. The modifiers in the ClassDefinition
// object will end up as the 'transformed' modifiers. Note that
// there are some bits set here that are not legal class modifiers
// according to the JVMS, e.g., M_PRIVATE and M_STATIC. These are
// masked off while writing the class file, but are preserved in
// the InnerClasses attributes.
if (tracing) toplevelEnv.dtEnter("beginClass: " + sourceClass);
SourceClass outerClass = sourceClass;
if (outerClass == null && pkg != null) {
t = new IdentifierToken(t.getWhere(),
Identifier.lookup(pkg, t.getName()));
}
// The defaults for anonymous and local classes should be documented!
if ((mod & M_ANONYMOUS) != 0) {
mod |= (M_FINAL | M_PRIVATE);
}
if ((mod & M_LOCAL) != 0) {
mod |= M_PRIVATE;
}
// Certain modifiers are implied as follows:
//
// 1. Any interface (nested or not) is implicitly deemed to be abstract,
// whether it is explicitly marked so or not. (Java 1.0.)
// 2. A interface which is a member of a type is implicitly deemed to
// be static, whether it is explicitly marked so or not. (InnerClasses)
// 3a. A type which is a member of an interface is implicitly deemed
// to be public, whether it is explicitly marked so or not. (InnerClasses)
// 3b. A type which is a member of an interface is implicitly deemed
// to be static, whether it is explicitly marked so or not. (InnerClasses)
if ((mod & M_INTERFACE) != 0) {
// Rule 1.
mod |= M_ABSTRACT;
if (outerClass != null) {
// Rule 2.
mod |= M_STATIC;
}
}
if (outerClass != null && outerClass.isInterface()) {
// Rule 3a.
// For interface members, neither 'private' nor 'protected'
// are legal modifiers. We avoid setting M_PUBLIC in some
// cases in order to avoid interfering with error detection
// and reporting. This is patched up, after reporting an
// error, by 'SourceClass.addMember'.
if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)
mod |= M_PUBLIC;
// Rule 3b.
mod |= M_STATIC;
}
// For nested classes, we must transform 'protected' to 'public'
// and 'private' to package scope. This must be done later,
// because any modifiers set here will be copied into the
// 'MemberDefinition' for the nested class, which must represent
// the original untransformed modifiers. Also, compile-time
// checks should be performed against the actual, untransformed
// modifiers. This is in contrast to transformations that implement
// implicit modifiers, such as M_STATIC and M_FINAL for fields
// of interfaces.
sourceClass = (SourceClass)
toplevelEnv.makeClassDefinition(toplevelEnv, where, t,
doc, mod, sup,
interfaces, outerClass);
sourceClass.getClassDeclaration().setDefinition(sourceClass, CS_PARSED);
env = new Environment(toplevelEnv, sourceClass);
if (tracing) toplevelEnv.dtEvent("beginClass: SETTING UP DEPENDENCIES");
// The code which adds artificial dependencies between
// classes in the same source file has been moved to
// BatchEnvironment#parseFile().
if (tracing) toplevelEnv.dtEvent("beginClass: ADDING TO CLASS LIST");
classes.addElement(sourceClass);
if (tracing) toplevelEnv.dtExit("beginClass: " + sourceClass);
return sourceClass;
}
/**
* Report the current class under construction.
*/
public ClassDefinition getCurrentClass() {
return sourceClass;
}
/**
* End class
*/
public void endClass(long where, ClassDefinition c) {
if (tracing) toplevelEnv.dtEnter("endClass: " + sourceClass);
// c == sourceClass; don't bother to check
sourceClass.setEndPosition(where);
SourceClass outerClass = (SourceClass) sourceClass.getOuterClass();
sourceClass = outerClass;
env = toplevelEnv;
if (sourceClass != null)
env = new Environment(env, sourceClass);
if (tracing) toplevelEnv.dtExit("endClass: " + sourceClass);
}
/**
* Define a method
*/
public void defineField(long where, ClassDefinition c,
String doc, int mod, Type t,
IdentifierToken name, IdentifierToken args[],
IdentifierToken exp[], Node val) {
// c == sourceClass; don't bother to check
Identifier nm = name.getName();
// Members that are nested classes are not created with 'defineField',
// so these transformations do not apply to them. See 'beginClass' above.
if (sourceClass.isInterface()) {
// Members of interfaces are implicitly public.
if ((mod & (M_PRIVATE | M_PROTECTED)) == 0)
// For interface members, neither 'private' nor 'protected'
// are legal modifiers. Avoid setting M_PUBLIC in some cases
// to avoid interfering with later error detection. This will
// be fixed up after the error is reported.
mod |= M_PUBLIC;
// Methods of interfaces are implicitly abstract.
// Fields of interfaces are implicitly static and final.
if (t.isType(TC_METHOD)) {
mod |= M_ABSTRACT;
} else {
mod |= M_STATIC | M_FINAL;
}
}
if (nm.equals(idInit)) {
// The parser reports "idInit" when in reality it has found
// that there is no method name at all present.
// So, decide if it's really a constructor, or a syntax error.
Type rt = t.getReturnType();
Identifier retname = !rt.isType(TC_CLASS) ? idStar /*no match*/
: rt.getClassName();
Identifier clsname = sourceClass.getLocalName();
if (clsname.equals(retname)) {
t = Type.tMethod(Type.tVoid, t.getArgumentTypes());
} else if (clsname.equals(retname.getFlatName().getName())) {
// It appears to be a constructor with spurious qualification.
t = Type.tMethod(Type.tVoid, t.getArgumentTypes());
env.error(where, "invalid.method.decl.qual");
} else if (retname.isQualified() || retname.equals(idStar)) {
// It appears to be a type name with no method name.
env.error(where, "invalid.method.decl.name");
return;
} else {
// We assume the type name is missing, even though the
// simple name that's present might have been intended
// to be a type: "String (){}" vs. "toString(){}".
env.error(where, "invalid.method.decl");
return;
}
}
if (args == null && t.isType(TC_METHOD)) {
args = new IdentifierToken[0];
}
if (exp == null && t.isType(TC_METHOD)) {
exp = new IdentifierToken[0];
}
MemberDefinition f = env.makeMemberDefinition(env, where, sourceClass,
doc, mod, t, nm,
args, exp, val);
if (env.dump()) {
f.print(System.out);
}
}
}