|
Java example source code file (SourceMember.java)
This example Java source code file (SourceMember.java) is included in the alvinalexander.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
Learn more about this Java project at its project page.
The SourceMember.java Java example source code
/*
* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.tools.javac;
import sun.tools.java.*;
import sun.tools.tree.*;
import sun.tools.asm.*;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Hashtable;
import java.io.PrintStream;
/**
* A Source Member
*
* WARNING: The contents of this source file are not part of any
* supported API. Code that depends on them does so at its own risk:
* they are subject to change or removal without notice.
*/
@Deprecated
public
class SourceMember extends MemberDefinition implements Constants {
/**
* The argument names (if it is a method)
*/
Vector args;
// set to the MemberDefinition in the interface if we have this field because
// it has been forced on us
MemberDefinition abstractSource;
/**
* The status of the field
*/
int status;
static final int PARSED = 0;
static final int CHECKING = 1;
static final int CHECKED = 2;
static final int INLINING = 3;
static final int INLINED = 4;
static final int ERROR = 5;
public Vector getArguments() {
return args;
}
/**
* Constructor
* @param argNames a vector of IdentifierToken
*/
public SourceMember(long where, ClassDefinition clazz,
String doc, int modifiers, Type type,
Identifier name, Vector argNames,
IdentifierToken exp[], Node value) {
super(where, clazz, modifiers, type, name, exp, value);
this.documentation = doc;
this.args = argNames; // for the moment
// not until type names are resolved: createArgumentFields(argNames);
if (ClassDefinition.containsDeprecated(documentation)) {
this.modifiers |= M_DEPRECATED;
}
}
void createArgumentFields(Vector argNames) {
// Create a list of arguments
if (isMethod()) {
args = new Vector();
if (isConstructor() || !(isStatic() || isInitializer())) {
args.addElement(((SourceClass)clazz).getThisArgument());
}
if (argNames != null) {
Enumeration e = argNames.elements();
Type argTypes[] = getType().getArgumentTypes();
for (int i = 0 ; i < argTypes.length ; i++) {
Object x = e.nextElement();
if (x instanceof LocalMember) {
// This should not happen, but it does
// in cases of vicious cyclic inheritance.
args = argNames;
return;
}
Identifier id;
int mod;
long where;
if (x instanceof Identifier) {
// allow argNames to be simple Identifiers (deprecated!)
id = (Identifier)x;
mod = 0;
where = getWhere();
} else {
IdentifierToken token = (IdentifierToken)x;
id = token.getName();
mod = token.getModifiers();
where = token.getWhere();
}
args.addElement(new LocalMember(where, clazz, mod,
argTypes[i], id));
}
}
}
}
// The methods addOuterThis() and addUplevelArguments() were
// both originally part of a single method called addUplevelArguments()
// which took a single boolean parameter describing which of the
// two behaviors it wanted.
//
// The original addUplevelArguments() claimed to keep the arguments in
// the following order:
//
// (1) <this>
//
// (By <early outer this> I am referring to the clientOuterField added
// to some constructors when they are created. If an outer this is
// added later, on demand, then this is mixed in with the rest of the
// uplevel arguments and is added by addUplevelArguments.)
//
// In reality, the `args' Vector was generated in this order, but the
// Type array `argTypes' was generated as:
//
// (2) <this>
//
// This didn't make a difference in the common case -- that is, when
// a class had an <outer.this> or but not both.
// Both can happen in the case that a member class is declared inside
// of a local class. It seems that the calling sequences, generated
// in places like NewInstanceExpression.codeCommon(), use order (2),
// so I have changed the code below to stick with that order. Since
// the only time this happens is in classes which are insideLocal, no
// one should be able to tell the difference between these orders.
// (bug number 4085633)
LocalMember outerThisArg = null;
/**
* Get outer instance link, or null if none.
*/
public LocalMember getOuterThisArg() {
return outerThisArg;
}
/**
* Add the outer.this argument to the list of arguments for this
* constructor. This is called from resolveTypeStructure. Any
* additional uplevel arguments get added later by addUplevelArguments().
*/
void addOuterThis() {
UplevelReference refs = clazz.getReferences();
// See if we have a client outer field.
while (refs != null &&
!refs.isClientOuterField()) {
refs = refs.getNext();
}
// There is no outer this argument. Quit.
if (refs == null) {
return;
}
// Get the old arg types.
Type oldArgTypes[] = type.getArgumentTypes();
// And make an array for the new ones with space for one more.
Type argTypes[] = new Type[oldArgTypes.length + 1];
LocalMember arg = refs.getLocalArgument();
outerThisArg = arg;
// args is our list of arguments. It contains a `this', so
// we insert at position 1. The list of types does not have a
// this, so we insert at position 0.
args.insertElementAt(arg, 1);
argTypes[0] = arg.getType();
// Add on the rest of the constructor arguments.
for (int i = 0; i < oldArgTypes.length; i++) {
argTypes[i + 1] = oldArgTypes[i];
}
type = Type.tMethod(type.getReturnType(), argTypes);
}
/**
* Prepend argument names and argument types for local variable references.
* This information is never seen by the type-check phase,
* but it affects code generation, which is the earliest moment
* we have comprehensive information on uplevel references.
* The code() methods tweaks the constructor calls, prepending
* the proper values to the argument list.
*/
void addUplevelArguments() {
UplevelReference refs = clazz.getReferences();
clazz.getReferencesFrozen();
// Count how many uplevels we have to add.
int count = 0;
for (UplevelReference r = refs; r != null; r = r.getNext()) {
if (!r.isClientOuterField()) {
count += 1;
}
}
if (count == 0) {
// None to add, quit.
return;
}
// Get the old argument types.
Type oldArgTypes[] = type.getArgumentTypes();
// Make an array with enough room for the new.
Type argTypes[] = new Type[oldArgTypes.length + count];
// Add all of the late uplevel references to args and argTypes.
// Note that they are `off-by-one' because of the `this'.
int ins = 0;
for (UplevelReference r = refs; r != null; r = r.getNext()) {
if (!r.isClientOuterField()) {
LocalMember arg = r.getLocalArgument();
args.insertElementAt(arg, 1 + ins);
argTypes[ins] = arg.getType();
ins++;
}
}
// Add the rest of the old arguments.
for (int i = 0; i < oldArgTypes.length; i++) {
argTypes[ins + i] = oldArgTypes[i];
}
type = Type.tMethod(type.getReturnType(), argTypes);
}
/**
* Constructor for an inner class.
*/
public SourceMember(ClassDefinition innerClass) {
super(innerClass);
}
/**
* Constructor.
* Used only to generate an abstract copy of a method that a class
* inherits from an interface
*/
public SourceMember(MemberDefinition f, ClassDefinition c, Environment env) {
this(f.getWhere(), c, f.getDocumentation(),
f.getModifiers() | M_ABSTRACT, f.getType(), f.getName(), null,
f.getExceptionIds(), null);
this.args = f.getArguments();
this.abstractSource = f;
this.exp = f.getExceptions(env);
}
/**
* Get exceptions
*/
public ClassDeclaration[] getExceptions(Environment env) {
if ((!isMethod()) || (exp != null)) {
return exp;
}
if (expIds == null) {
// (should not happen)
exp = new ClassDeclaration[0];
return exp;
}
// be sure to get the imports right:
env = ((SourceClass)getClassDefinition()).setupEnv(env);
exp = new ClassDeclaration[expIds.length];
for (int i = 0; i < exp.length; i++) {
Identifier e = expIds[i].getName();
Identifier rexp = getClassDefinition().resolveName(env, e);
exp[i] = env.getClassDeclaration(rexp);
}
return exp;
}
/**
* Set array of name-resolved exceptions directly, e.g., for access methods.
*/
public void setExceptions(ClassDeclaration[] exp) {
this.exp = exp;
}
/**
* Resolve types in a field, after parsing.
* @see ClassDefinition.resolveTypeStructure
*/
public boolean resolved = false;
public void resolveTypeStructure(Environment env) {
if (tracing) env.dtEnter("SourceMember.resolveTypeStructure: " + this);
// A member should only be resolved once. For a constructor, it is imperative
// that 'addOuterThis' be called only once, else the outer instance argument may
// be inserted into the argument list multiple times.
if (resolved) {
if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: OK " + this);
// This case shouldn't be happening. It is the responsibility
// of our callers to avoid attempting multiple resolutions of a member.
// *** REMOVE FOR SHIPMENT? ***
throw new CompilerError("multiple member type resolution");
//return;
} else {
if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: RESOLVING " + this);
resolved = true;
}
super.resolveTypeStructure(env);
if (isInnerClass()) {
ClassDefinition nc = getInnerClass();
if (nc instanceof SourceClass && !nc.isLocal()) {
((SourceClass)nc).resolveTypeStructure(env);
}
type = innerClass.getType();
} else {
// Expand all class names in 'type', including those that are not
// fully-qualified or refer to inner classes, into fully-qualified
// names. Local and anonymous classes get synthesized names here,
// corresponding to the class files that will be generated. This is
// currently the only place where 'resolveNames' is used.
type = env.resolveNames(getClassDefinition(), type, isSynthetic());
// do the throws also:
getExceptions(env);
if (isMethod()) {
Vector argNames = args; args = null;
createArgumentFields(argNames);
// Add outer instance argument for constructors.
if (isConstructor()) {
addOuterThis();
}
}
}
if (tracing) env.dtExit("SourceMember.resolveTypeStructure: " + this);
}
/**
* Get the class declaration in which the field is actually defined
*/
public ClassDeclaration getDefiningClassDeclaration() {
if (abstractSource == null)
return super.getDefiningClassDeclaration();
else
return abstractSource.getDefiningClassDeclaration();
}
/**
* A source field never reports deprecation, since the compiler
* allows access to deprecated features that are being compiled
* in the same job.
*/
public boolean reportDeprecated(Environment env) {
return false;
}
/**
* Check this field.
* <p>
* This is the method which requests checking.
* The real work is done by
* <tt>Vset check(Environment, Context, Vset).
*/
public void check(Environment env) throws ClassNotFound {
if (tracing) env.dtEnter("SourceMember.check: " +
getName() + ", status = " + status);
// rely on the class to check all fields in the proper order
if (status == PARSED) {
if (isSynthetic() && getValue() == null) {
// break a big cycle for small synthetic variables
status = CHECKED;
if (tracing)
env.dtExit("SourceMember.check: BREAKING CYCLE");
return;
}
if (tracing) env.dtEvent("SourceMember.check: CHECKING CLASS");
clazz.check(env);
if (status == PARSED) {
if (getClassDefinition().getError()) {
status = ERROR;
} else {
if (tracing)
env.dtExit("SourceMember.check: CHECK FAILED");
throw new CompilerError("check failed");
}
}
}
if (tracing) env.dtExit("SourceMember.check: DONE " +
getName() + ", status = " + status);
}
/**
* Check a field.
* @param vset tells which uplevel variables are definitely assigned
* The vset is also used to track the initialization of blank finals
* by whichever fields which are relevant to them.
*/
public Vset check(Environment env, Context ctx, Vset vset) throws ClassNotFound {
if (tracing) env.dtEvent("SourceMember.check: MEMBER " +
getName() + ", status = " + status);
if (status == PARSED) {
if (isInnerClass()) {
// some classes are checked separately
ClassDefinition nc = getInnerClass();
if (nc instanceof SourceClass && !nc.isLocal()
&& nc.isInsideLocal()) {
status = CHECKING;
vset = ((SourceClass)nc).checkInsideClass(env, ctx, vset);
}
status = CHECKED;
return vset;
}
if (env.dump()) {
System.out.println("[check field " + getClassDeclaration().getName() + "." + getName() + "]");
if (getValue() != null) {
getValue().print(System.out);
System.out.println();
}
}
env = new Environment(env, this);
// This is where all checking of names appearing within the type
// of the member is done. Includes return type and argument types.
// Since only one location ('where') for error messages is provided,
// localization of errors is poor. Throws clauses are handled below.
env.resolve(where, getClassDefinition(), getType());
// Make sure that all the classes that we claim to throw really
// are subclasses of Throwable, and are classes that we can reach
if (isMethod()) {
ClassDeclaration throwable =
env.getClassDeclaration(idJavaLangThrowable);
ClassDeclaration exp[] = getExceptions(env);
for (int i = 0 ; i < exp.length ; i++) {
ClassDefinition def;
long where = getWhere();
if (expIds != null && i < expIds.length) {
where = IdentifierToken.getWhere(expIds[i], where);
}
try {
def = exp[i].getClassDefinition(env);
// Validate access for all inner-class components
// of a qualified name, not just the last one, which
// is checked below. Yes, this is a dirty hack...
// Part of fix for 4094658.
env.resolveByName(where, getClassDefinition(), def.getName());
} catch (ClassNotFound e) {
env.error(where, "class.not.found", e.name, "throws");
break;
}
def.noteUsedBy(getClassDefinition(), where, env);
if (!getClassDefinition().
canAccess(env, def.getClassDeclaration())) {
env.error(where, "cant.access.class", def);
} else if (!def.subClassOf(env, throwable)) {
env.error(where, "throws.not.throwable", def);
}
}
}
status = CHECKING;
if (isMethod() && args != null) {
int length = args.size();
outer_loop:
for (int i = 0; i < length; i++) {
LocalMember lf = (LocalMember)(args.elementAt(i));
Identifier name_i = lf.getName();
for (int j = i + 1; j < length; j++) {
LocalMember lf2 = (LocalMember)(args.elementAt(j));
Identifier name_j = lf2.getName();
if (name_i.equals(name_j)) {
env.error(lf2.getWhere(), "duplicate.argument",
name_i);
break outer_loop;
}
}
}
}
if (getValue() != null) {
ctx = new Context(ctx, this);
if (isMethod()) {
Statement s = (Statement)getValue();
// initialize vset, indication that each of the arguments
// to the function has a value
for (Enumeration e = args.elements(); e.hasMoreElements();){
LocalMember f = (LocalMember)e.nextElement();
vset.addVar(ctx.declare(env, f));
}
if (isConstructor()) {
// Undefine "this" in some constructors, until after
// the super constructor has been called.
vset.clearVar(ctx.getThisNumber());
// If the first thing in the definition isn't a call
// to either super() or this(), then insert one.
Expression supCall = s.firstConstructor();
if ((supCall == null)
&& (getClassDefinition().getSuperClass() != null)) {
supCall = getDefaultSuperCall(env);
Statement scs = new ExpressionStatement(where,
supCall);
s = Statement.insertStatement(scs, s);
setValue(s);
}
}
//System.out.println("VSET = " + vset);
ClassDeclaration exp[] = getExceptions(env);
int htsize = (exp.length > 3) ? 17 : 7;
Hashtable thrown = new Hashtable(htsize);
vset = s.checkMethod(env, ctx, vset, thrown);
ClassDeclaration ignore1 =
env.getClassDeclaration(idJavaLangError);
ClassDeclaration ignore2 =
env.getClassDeclaration(idJavaLangRuntimeException);
for (Enumeration e = thrown.keys(); e.hasMoreElements();) {
ClassDeclaration c = (ClassDeclaration)e.nextElement();
ClassDefinition def = c.getClassDefinition(env);
if (def.subClassOf(env, ignore1)
|| def.subClassOf(env, ignore2)) {
continue;
}
boolean ok = false;
if (!isInitializer()) {
for (int i = 0 ; i < exp.length ; i++) {
if (def.subClassOf(env, exp[i])) {
ok = true;
}
}
}
if (!ok) {
Node n = (Node)thrown.get(c);
long where = n.getWhere();
String errorMsg;
if (isConstructor()) {
if (where ==
getClassDefinition().getWhere()) {
// If this message is being generated for
// a default constructor, we should give
// a different error message. Currently
// we check for this by seeing if the
// constructor has the same "where" as
// its class. This is a bit kludgy, but
// works. (bug id 4034836)
errorMsg = "def.constructor.exception";
} else {
// Constructor with uncaught exception.
errorMsg = "constructor.exception";
}
} else if (isInitializer()) {
// Initializer with uncaught exception.
errorMsg = "initializer.exception";
} else {
// Method with uncaught exception.
errorMsg = "uncaught.exception";
}
env.error(where, errorMsg, c.getName());
}
}
} else {
Hashtable thrown = new Hashtable(3); // small & throw-away
Expression val = (Expression)getValue();
vset = val.checkInitializer(env, ctx, vset,
getType(), thrown);
setValue(val.convert(env, ctx, getType(), val));
// Complain about static final members of inner classes that
// do not have an initializer that is a constant expression.
// In general, static members are not permitted for inner
// classes, but an exception is made for named constants.
// Other cases of static members, including non-final ones,
// are handled in 'SourceClass'. Part of fix for 4095568.
if (isStatic() && isFinal() && !clazz.isTopLevel()) {
if (!((Expression)getValue()).isConstant()) {
env.error(where, "static.inner.field", getName(), this);
setValue(null);
}
}
// Both RuntimeExceptions and Errors should be
// allowed in initializers. Fix for bug 4102541.
ClassDeclaration except =
env.getClassDeclaration(idJavaLangThrowable);
ClassDeclaration ignore1 =
env.getClassDeclaration(idJavaLangError);
ClassDeclaration ignore2 =
env.getClassDeclaration(idJavaLangRuntimeException);
for (Enumeration e = thrown.keys(); e.hasMoreElements(); ) {
ClassDeclaration c = (ClassDeclaration)e.nextElement();
ClassDefinition def = c.getClassDefinition(env);
if (!def.subClassOf(env, ignore1)
&& !def.subClassOf(env, ignore2)
&& def.subClassOf(env, except)) {
Node n = (Node)thrown.get(c);
env.error(n.getWhere(),
"initializer.exception", c.getName());
}
}
}
if (env.dump()) {
getValue().print(System.out);
System.out.println();
}
}
status = getClassDefinition().getError() ? ERROR : CHECKED;
}
// Initializers (static and instance) must be able to complete normally.
if (isInitializer() && vset.isDeadEnd()) {
env.error(where, "init.no.normal.completion");
vset = vset.clearDeadEnd();
}
return vset;
}
// helper to check(): synthesize a missing super() call
private Expression getDefaultSuperCall(Environment env) {
Expression se = null;
ClassDefinition sclass = getClassDefinition().getSuperClass().getClassDefinition();
// does the superclass constructor require an enclosing instance?
ClassDefinition reqc = (sclass == null) ? null
: sclass.isTopLevel() ? null
: sclass.getOuterClass();
ClassDefinition thisc = getClassDefinition();
if (reqc != null && !Context.outerLinkExists(env, reqc, thisc)) {
se = new SuperExpression(where, new NullExpression(where));
env.error(where, "no.default.outer.arg", reqc, getClassDefinition());
}
if (se == null) {
se = new SuperExpression(where);
}
return new MethodExpression(where, se, idInit, new Expression[0]);
}
/**
* Inline the field
*/
void inline(Environment env) throws ClassNotFound {
switch (status) {
case PARSED:
check(env);
inline(env);
break;
case CHECKED:
if (env.dump()) {
System.out.println("[inline field " + getClassDeclaration().getName() + "." + getName() + "]");
}
status = INLINING;
env = new Environment(env, this);
if (isMethod()) {
if ((!isNative()) && (!isAbstract())) {
Statement s = (Statement)getValue();
Context ctx = new Context((Context)null, this);
for (Enumeration e = args.elements() ; e.hasMoreElements() ;) {
LocalMember local = (LocalMember)e.nextElement();
ctx.declare(env, local);
}
setValue(s.inline(env, ctx));
}
} else if (isInnerClass()) {
// some classes are checked and inlined separately
ClassDefinition nc = getInnerClass();
if (nc instanceof SourceClass && !nc.isLocal()
&& nc.isInsideLocal()) {
status = INLINING;
((SourceClass)nc).inlineLocalClass(env);
}
status = INLINED;
break;
} else {
if (getValue() != null) {
Context ctx = new Context((Context)null, this);
if (!isStatic()) {
// Cf. "thisArg" in SourceClass.checkMembers().
Context ctxInst = new Context(ctx, this);
LocalMember thisArg =
((SourceClass)clazz).getThisArgument();
ctxInst.declare(env, thisArg);
setValue(((Expression)getValue())
.inlineValue(env, ctxInst));
} else {
setValue(((Expression)getValue())
.inlineValue(env, ctx));
}
}
}
if (env.dump()) {
System.out.println("[inlined field " + getClassDeclaration().getName() + "." + getName() + "]");
if (getValue() != null) {
getValue().print(System.out);
System.out.println();
} else {
System.out.println("<empty>");
}
}
status = INLINED;
break;
}
}
/**
* Get the value of the field (or null if the value can't be determined)
*/
public Node getValue(Environment env) throws ClassNotFound {
Node value = getValue();
if (value != null && status != INLINED) {
// be sure to get the imports right:
env = ((SourceClass)clazz).setupEnv(env);
inline(env);
value = (status == INLINED) ? getValue() : null;
}
return value;
}
public boolean isInlineable(Environment env, boolean fromFinal) throws ClassNotFound {
if (super.isInlineable(env, fromFinal)) {
getValue(env);
return (status == INLINED) && !getClassDefinition().getError();
}
return false;
}
/**
* Get the initial value of the field
*/
public Object getInitialValue() {
if (isMethod() || (getValue() == null) || (!isFinal()) || (status != INLINED)) {
return null;
}
return ((Expression)getValue()).getValue();
}
/**
* Generate code
*/
public void code(Environment env, Assembler asm) throws ClassNotFound {
switch (status) {
case PARSED:
check(env);
code(env, asm);
return;
case CHECKED:
inline(env);
code(env, asm);
return;
case INLINED:
// Actually generate code
if (env.dump()) {
System.out.println("[code field " + getClassDeclaration().getName() + "." + getName() + "]");
}
if (isMethod() && (!isNative()) && (!isAbstract())) {
env = new Environment(env, this);
Context ctx = new Context((Context)null, this);
Statement s = (Statement)getValue();
for (Enumeration e = args.elements() ; e.hasMoreElements() ; ) {
LocalMember f = (LocalMember)e.nextElement();
ctx.declare(env, f);
//ctx.declare(env, (LocalMember)e.nextElement());
}
/*
if (isConstructor() && ((s == null) || (s.firstConstructor() == null))) {
ClassDeclaration c = getClassDefinition().getSuperClass();
if (c != null) {
MemberDefinition field = c.getClassDefinition(env).matchMethod(env, getClassDefinition(), idInit);
asm.add(getWhere(), opc_aload, new Integer(0));
asm.add(getWhere(), opc_invokespecial, field);
asm.add(getWhere(), opc_pop);
}
// Output initialization code
for (MemberDefinition f = getClassDefinition().getFirstMember() ; f != null ; f = f.getNextMember()) {
if (!f.isStatic()) {
f.codeInit(env, ctx, asm);
}
}
}
*/
if (s != null) {
s.code(env, ctx, asm);
}
if (getType().getReturnType().isType(TC_VOID) && !isInitializer()) {
asm.add(getWhere(), opc_return, true);
}
}
return;
}
}
public void codeInit(Environment env, Context ctx, Assembler asm) throws ClassNotFound {
if (isMethod()) {
return;
}
switch (status) {
case PARSED:
check(env);
codeInit(env, ctx, asm);
return;
case CHECKED:
inline(env);
codeInit(env, ctx, asm);
return;
case INLINED:
// Actually generate code
if (env.dump()) {
System.out.println("[code initializer " + getClassDeclaration().getName() + "." + getName() + "]");
}
if (getValue() != null) {
Expression e = (Expression)getValue();
// The JLS Section 8.5 specifies that static (non-final)
// initializers should be executed in textual order. Eliding
// initializations to default values can interfere with this,
// so the tests for !e.equalsDefault() have been eliminated,
// below.
if (isStatic()) {
if (getInitialValue() == null) {
// removed: && !e.equalsDefault()) {
e.codeValue(env, ctx, asm);
asm.add(getWhere(), opc_putstatic, this);
}
} else { // removed: if (!e.equalsDefault()) {
// This code doesn't appear to be reached for
// instance initializers. Code for these is generated
// in the makeVarInits() method of the class
// MethodExpression.
asm.add(getWhere(), opc_aload, new Integer(0));
e.codeValue(env, ctx, asm);
asm.add(getWhere(), opc_putfield, this);
}
}
return;
}
}
/**
* Print for debugging
*/
public void print(PrintStream out) {
super.print(out);
if (getValue() != null) {
getValue().print(out);
out.println();
}
}
}
Other Java examples (source code examples)
Here is a short list of links related to this Java SourceMember.java source code file:
|