Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/javac/SourceMember.java
38918 views
/*1* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.tools.javac;2627import sun.tools.java.*;28import sun.tools.tree.*;29import sun.tools.asm.*;30import java.util.Vector;31import java.util.Enumeration;32import java.util.Hashtable;33import java.io.PrintStream;3435/**36* A Source Member37*38* WARNING: The contents of this source file are not part of any39* supported API. Code that depends on them does so at its own risk:40* they are subject to change or removal without notice.41*/42@Deprecated43public44class SourceMember extends MemberDefinition implements Constants {45/**46* The argument names (if it is a method)47*/48Vector args;4950// set to the MemberDefinition in the interface if we have this field because51// it has been forced on us52MemberDefinition abstractSource;5354/**55* The status of the field56*/57int status;5859static final int PARSED = 0;60static final int CHECKING = 1;61static final int CHECKED = 2;62static final int INLINING = 3;63static final int INLINED = 4;64static final int ERROR = 5;6566public Vector getArguments() {67return args;68}6970/**71* Constructor72* @param argNames a vector of IdentifierToken73*/74public SourceMember(long where, ClassDefinition clazz,75String doc, int modifiers, Type type,76Identifier name, Vector argNames,77IdentifierToken exp[], Node value) {78super(where, clazz, modifiers, type, name, exp, value);79this.documentation = doc;80this.args = argNames; // for the moment81// not until type names are resolved: createArgumentFields(argNames);8283if (ClassDefinition.containsDeprecated(documentation)) {84this.modifiers |= M_DEPRECATED;85}86}8788void createArgumentFields(Vector argNames) {89// Create a list of arguments90if (isMethod()) {91args = new Vector();9293if (isConstructor() || !(isStatic() || isInitializer())) {94args.addElement(((SourceClass)clazz).getThisArgument());95}9697if (argNames != null) {98Enumeration e = argNames.elements();99Type argTypes[] = getType().getArgumentTypes();100for (int i = 0 ; i < argTypes.length ; i++) {101Object x = e.nextElement();102if (x instanceof LocalMember) {103// This should not happen, but it does104// in cases of vicious cyclic inheritance.105args = argNames;106return;107}108Identifier id;109int mod;110long where;111if (x instanceof Identifier) {112// allow argNames to be simple Identifiers (deprecated!)113id = (Identifier)x;114mod = 0;115where = getWhere();116} else {117IdentifierToken token = (IdentifierToken)x;118id = token.getName();119mod = token.getModifiers();120where = token.getWhere();121}122args.addElement(new LocalMember(where, clazz, mod,123argTypes[i], id));124}125}126}127}128129// The methods addOuterThis() and addUplevelArguments() were130// both originally part of a single method called addUplevelArguments()131// which took a single boolean parameter describing which of the132// two behaviors it wanted.133//134// The original addUplevelArguments() claimed to keep the arguments in135// the following order:136//137// (1) <this> <early outer this> <uplevel arguments...> <true arguments...>138//139// (By <early outer this> I am referring to the clientOuterField added140// to some constructors when they are created. If an outer this is141// added later, on demand, then this is mixed in with the rest of the142// uplevel arguments and is added by addUplevelArguments.)143//144// In reality, the `args' Vector was generated in this order, but the145// Type array `argTypes' was generated as:146//147// (2) <this> <uplevel arguments...> <early outer this> <true arguments...>148//149// This didn't make a difference in the common case -- that is, when150// a class had an <outer.this> or <uplevel arguments...> but not both.151// Both can happen in the case that a member class is declared inside152// of a local class. It seems that the calling sequences, generated153// in places like NewInstanceExpression.codeCommon(), use order (2),154// so I have changed the code below to stick with that order. Since155// the only time this happens is in classes which are insideLocal, no156// one should be able to tell the difference between these orders.157// (bug number 4085633)158159LocalMember outerThisArg = null;160161/**162* Get outer instance link, or null if none.163*/164165public LocalMember getOuterThisArg() {166return outerThisArg;167}168169/**170* Add the outer.this argument to the list of arguments for this171* constructor. This is called from resolveTypeStructure. Any172* additional uplevel arguments get added later by addUplevelArguments().173*/174175void addOuterThis() {176UplevelReference refs = clazz.getReferences();177178// See if we have a client outer field.179while (refs != null &&180!refs.isClientOuterField()) {181refs = refs.getNext();182}183184// There is no outer this argument. Quit.185if (refs == null) {186return;187}188189// Get the old arg types.190Type oldArgTypes[] = type.getArgumentTypes();191192// And make an array for the new ones with space for one more.193Type argTypes[] = new Type[oldArgTypes.length + 1];194195LocalMember arg = refs.getLocalArgument();196outerThisArg = arg;197198// args is our list of arguments. It contains a `this', so199// we insert at position 1. The list of types does not have a200// this, so we insert at position 0.201args.insertElementAt(arg, 1);202argTypes[0] = arg.getType();203204// Add on the rest of the constructor arguments.205for (int i = 0; i < oldArgTypes.length; i++) {206argTypes[i + 1] = oldArgTypes[i];207}208209type = Type.tMethod(type.getReturnType(), argTypes);210}211212/**213* Prepend argument names and argument types for local variable references.214* This information is never seen by the type-check phase,215* but it affects code generation, which is the earliest moment216* we have comprehensive information on uplevel references.217* The code() methods tweaks the constructor calls, prepending218* the proper values to the argument list.219*/220void addUplevelArguments() {221UplevelReference refs = clazz.getReferences();222clazz.getReferencesFrozen();223224// Count how many uplevels we have to add.225int count = 0;226for (UplevelReference r = refs; r != null; r = r.getNext()) {227if (!r.isClientOuterField()) {228count += 1;229}230}231232if (count == 0) {233// None to add, quit.234return;235}236237// Get the old argument types.238Type oldArgTypes[] = type.getArgumentTypes();239240// Make an array with enough room for the new.241Type argTypes[] = new Type[oldArgTypes.length + count];242243// Add all of the late uplevel references to args and argTypes.244// Note that they are `off-by-one' because of the `this'.245int ins = 0;246for (UplevelReference r = refs; r != null; r = r.getNext()) {247if (!r.isClientOuterField()) {248LocalMember arg = r.getLocalArgument();249250args.insertElementAt(arg, 1 + ins);251argTypes[ins] = arg.getType();252253ins++;254}255}256257// Add the rest of the old arguments.258for (int i = 0; i < oldArgTypes.length; i++) {259argTypes[ins + i] = oldArgTypes[i];260}261262type = Type.tMethod(type.getReturnType(), argTypes);263}264265/**266* Constructor for an inner class.267*/268public SourceMember(ClassDefinition innerClass) {269super(innerClass);270}271272/**273* Constructor.274* Used only to generate an abstract copy of a method that a class275* inherits from an interface276*/277public SourceMember(MemberDefinition f, ClassDefinition c, Environment env) {278this(f.getWhere(), c, f.getDocumentation(),279f.getModifiers() | M_ABSTRACT, f.getType(), f.getName(), null,280f.getExceptionIds(), null);281this.args = f.getArguments();282this.abstractSource = f;283this.exp = f.getExceptions(env);284}285286/**287* Get exceptions288*/289public ClassDeclaration[] getExceptions(Environment env) {290if ((!isMethod()) || (exp != null)) {291return exp;292}293if (expIds == null) {294// (should not happen)295exp = new ClassDeclaration[0];296return exp;297}298// be sure to get the imports right:299env = ((SourceClass)getClassDefinition()).setupEnv(env);300exp = new ClassDeclaration[expIds.length];301for (int i = 0; i < exp.length; i++) {302Identifier e = expIds[i].getName();303Identifier rexp = getClassDefinition().resolveName(env, e);304exp[i] = env.getClassDeclaration(rexp);305}306return exp;307}308309/**310* Set array of name-resolved exceptions directly, e.g., for access methods.311*/312public void setExceptions(ClassDeclaration[] exp) {313this.exp = exp;314}315316/**317* Resolve types in a field, after parsing.318* @see ClassDefinition.resolveTypeStructure319*/320321public boolean resolved = false;322323public void resolveTypeStructure(Environment env) {324if (tracing) env.dtEnter("SourceMember.resolveTypeStructure: " + this);325326// A member should only be resolved once. For a constructor, it is imperative327// that 'addOuterThis' be called only once, else the outer instance argument may328// be inserted into the argument list multiple times.329330if (resolved) {331if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: OK " + this);332// This case shouldn't be happening. It is the responsibility333// of our callers to avoid attempting multiple resolutions of a member.334// *** REMOVE FOR SHIPMENT? ***335throw new CompilerError("multiple member type resolution");336//return;337} else {338if (tracing) env.dtEvent("SourceMember.resolveTypeStructure: RESOLVING " + this);339resolved = true;340}341342super.resolveTypeStructure(env);343if (isInnerClass()) {344ClassDefinition nc = getInnerClass();345if (nc instanceof SourceClass && !nc.isLocal()) {346((SourceClass)nc).resolveTypeStructure(env);347}348type = innerClass.getType();349} else {350// Expand all class names in 'type', including those that are not351// fully-qualified or refer to inner classes, into fully-qualified352// names. Local and anonymous classes get synthesized names here,353// corresponding to the class files that will be generated. This is354// currently the only place where 'resolveNames' is used.355type = env.resolveNames(getClassDefinition(), type, isSynthetic());356357// do the throws also:358getExceptions(env);359360if (isMethod()) {361Vector argNames = args; args = null;362createArgumentFields(argNames);363// Add outer instance argument for constructors.364if (isConstructor()) {365addOuterThis();366}367}368}369if (tracing) env.dtExit("SourceMember.resolveTypeStructure: " + this);370}371372/**373* Get the class declaration in which the field is actually defined374*/375public ClassDeclaration getDefiningClassDeclaration() {376if (abstractSource == null)377return super.getDefiningClassDeclaration();378else379return abstractSource.getDefiningClassDeclaration();380}381382/**383* A source field never reports deprecation, since the compiler384* allows access to deprecated features that are being compiled385* in the same job.386*/387public boolean reportDeprecated(Environment env) {388return false;389}390391/**392* Check this field.393* <p>394* This is the method which requests checking.395* The real work is done by396* <tt>Vset check(Environment, Context, Vset)</tt>.397*/398public void check(Environment env) throws ClassNotFound {399if (tracing) env.dtEnter("SourceMember.check: " +400getName() + ", status = " + status);401// rely on the class to check all fields in the proper order402if (status == PARSED) {403if (isSynthetic() && getValue() == null) {404// break a big cycle for small synthetic variables405status = CHECKED;406if (tracing)407env.dtExit("SourceMember.check: BREAKING CYCLE");408return;409}410if (tracing) env.dtEvent("SourceMember.check: CHECKING CLASS");411clazz.check(env);412if (status == PARSED) {413if (getClassDefinition().getError()) {414status = ERROR;415} else {416if (tracing)417env.dtExit("SourceMember.check: CHECK FAILED");418throw new CompilerError("check failed");419}420}421}422if (tracing) env.dtExit("SourceMember.check: DONE " +423getName() + ", status = " + status);424}425426/**427* Check a field.428* @param vset tells which uplevel variables are definitely assigned429* The vset is also used to track the initialization of blank finals430* by whichever fields which are relevant to them.431*/432public Vset check(Environment env, Context ctx, Vset vset) throws ClassNotFound {433if (tracing) env.dtEvent("SourceMember.check: MEMBER " +434getName() + ", status = " + status);435if (status == PARSED) {436if (isInnerClass()) {437// some classes are checked separately438ClassDefinition nc = getInnerClass();439if (nc instanceof SourceClass && !nc.isLocal()440&& nc.isInsideLocal()) {441status = CHECKING;442vset = ((SourceClass)nc).checkInsideClass(env, ctx, vset);443}444status = CHECKED;445return vset;446}447if (env.dump()) {448System.out.println("[check field " + getClassDeclaration().getName() + "." + getName() + "]");449if (getValue() != null) {450getValue().print(System.out);451System.out.println();452}453}454env = new Environment(env, this);455456// This is where all checking of names appearing within the type457// of the member is done. Includes return type and argument types.458// Since only one location ('where') for error messages is provided,459// localization of errors is poor. Throws clauses are handled below.460env.resolve(where, getClassDefinition(), getType());461462// Make sure that all the classes that we claim to throw really463// are subclasses of Throwable, and are classes that we can reach464if (isMethod()) {465ClassDeclaration throwable =466env.getClassDeclaration(idJavaLangThrowable);467ClassDeclaration exp[] = getExceptions(env);468for (int i = 0 ; i < exp.length ; i++) {469ClassDefinition def;470long where = getWhere();471if (expIds != null && i < expIds.length) {472where = IdentifierToken.getWhere(expIds[i], where);473}474try {475def = exp[i].getClassDefinition(env);476477// Validate access for all inner-class components478// of a qualified name, not just the last one, which479// is checked below. Yes, this is a dirty hack...480// Part of fix for 4094658.481env.resolveByName(where, getClassDefinition(), def.getName());482483} catch (ClassNotFound e) {484env.error(where, "class.not.found", e.name, "throws");485break;486}487def.noteUsedBy(getClassDefinition(), where, env);488if (!getClassDefinition().489canAccess(env, def.getClassDeclaration())) {490env.error(where, "cant.access.class", def);491} else if (!def.subClassOf(env, throwable)) {492env.error(where, "throws.not.throwable", def);493}494}495}496497status = CHECKING;498499if (isMethod() && args != null) {500int length = args.size();501outer_loop:502for (int i = 0; i < length; i++) {503LocalMember lf = (LocalMember)(args.elementAt(i));504Identifier name_i = lf.getName();505for (int j = i + 1; j < length; j++) {506LocalMember lf2 = (LocalMember)(args.elementAt(j));507Identifier name_j = lf2.getName();508if (name_i.equals(name_j)) {509env.error(lf2.getWhere(), "duplicate.argument",510name_i);511break outer_loop;512}513}514}515}516517if (getValue() != null) {518ctx = new Context(ctx, this);519520if (isMethod()) {521Statement s = (Statement)getValue();522// initialize vset, indication that each of the arguments523// to the function has a value524525for (Enumeration e = args.elements(); e.hasMoreElements();){526LocalMember f = (LocalMember)e.nextElement();527vset.addVar(ctx.declare(env, f));528}529530if (isConstructor()) {531// Undefine "this" in some constructors, until after532// the super constructor has been called.533vset.clearVar(ctx.getThisNumber());534535// If the first thing in the definition isn't a call536// to either super() or this(), then insert one.537Expression supCall = s.firstConstructor();538if ((supCall == null)539&& (getClassDefinition().getSuperClass() != null)) {540supCall = getDefaultSuperCall(env);541Statement scs = new ExpressionStatement(where,542supCall);543s = Statement.insertStatement(scs, s);544setValue(s);545}546}547548//System.out.println("VSET = " + vset);549ClassDeclaration exp[] = getExceptions(env);550int htsize = (exp.length > 3) ? 17 : 7;551Hashtable thrown = new Hashtable(htsize);552553vset = s.checkMethod(env, ctx, vset, thrown);554555ClassDeclaration ignore1 =556env.getClassDeclaration(idJavaLangError);557ClassDeclaration ignore2 =558env.getClassDeclaration(idJavaLangRuntimeException);559560for (Enumeration e = thrown.keys(); e.hasMoreElements();) {561ClassDeclaration c = (ClassDeclaration)e.nextElement();562ClassDefinition def = c.getClassDefinition(env);563if (def.subClassOf(env, ignore1)564|| def.subClassOf(env, ignore2)) {565continue;566}567568boolean ok = false;569if (!isInitializer()) {570for (int i = 0 ; i < exp.length ; i++) {571if (def.subClassOf(env, exp[i])) {572ok = true;573}574}575}576if (!ok) {577Node n = (Node)thrown.get(c);578long where = n.getWhere();579String errorMsg;580581if (isConstructor()) {582if (where ==583getClassDefinition().getWhere()) {584585// If this message is being generated for586// a default constructor, we should give587// a different error message. Currently588// we check for this by seeing if the589// constructor has the same "where" as590// its class. This is a bit kludgy, but591// works. (bug id 4034836)592errorMsg = "def.constructor.exception";593} else {594// Constructor with uncaught exception.595errorMsg = "constructor.exception";596}597} else if (isInitializer()) {598// Initializer with uncaught exception.599errorMsg = "initializer.exception";600} else {601// Method with uncaught exception.602errorMsg = "uncaught.exception";603}604env.error(where, errorMsg, c.getName());605}606}607} else {608Hashtable thrown = new Hashtable(3); // small & throw-away609Expression val = (Expression)getValue();610611vset = val.checkInitializer(env, ctx, vset,612getType(), thrown);613setValue(val.convert(env, ctx, getType(), val));614615// Complain about static final members of inner classes that616// do not have an initializer that is a constant expression.617// In general, static members are not permitted for inner618// classes, but an exception is made for named constants.619// Other cases of static members, including non-final ones,620// are handled in 'SourceClass'. Part of fix for 4095568.621if (isStatic() && isFinal() && !clazz.isTopLevel()) {622if (!((Expression)getValue()).isConstant()) {623env.error(where, "static.inner.field", getName(), this);624setValue(null);625}626}627628629// Both RuntimeExceptions and Errors should be630// allowed in initializers. Fix for bug 4102541.631ClassDeclaration except =632env.getClassDeclaration(idJavaLangThrowable);633ClassDeclaration ignore1 =634env.getClassDeclaration(idJavaLangError);635ClassDeclaration ignore2 =636env.getClassDeclaration(idJavaLangRuntimeException);637638for (Enumeration e = thrown.keys(); e.hasMoreElements(); ) {639ClassDeclaration c = (ClassDeclaration)e.nextElement();640ClassDefinition def = c.getClassDefinition(env);641642if (!def.subClassOf(env, ignore1)643&& !def.subClassOf(env, ignore2)644&& def.subClassOf(env, except)) {645Node n = (Node)thrown.get(c);646env.error(n.getWhere(),647"initializer.exception", c.getName());648}649}650}651if (env.dump()) {652getValue().print(System.out);653System.out.println();654}655}656status = getClassDefinition().getError() ? ERROR : CHECKED;657}658659660// Initializers (static and instance) must be able to complete normally.661if (isInitializer() && vset.isDeadEnd()) {662env.error(where, "init.no.normal.completion");663vset = vset.clearDeadEnd();664}665666return vset;667}668669// helper to check(): synthesize a missing super() call670private Expression getDefaultSuperCall(Environment env) {671Expression se = null;672ClassDefinition sclass = getClassDefinition().getSuperClass().getClassDefinition();673// does the superclass constructor require an enclosing instance?674ClassDefinition reqc = (sclass == null) ? null675: sclass.isTopLevel() ? null676: sclass.getOuterClass();677ClassDefinition thisc = getClassDefinition();678if (reqc != null && !Context.outerLinkExists(env, reqc, thisc)) {679se = new SuperExpression(where, new NullExpression(where));680env.error(where, "no.default.outer.arg", reqc, getClassDefinition());681}682if (se == null) {683se = new SuperExpression(where);684}685return new MethodExpression(where, se, idInit, new Expression[0]);686}687688/**689* Inline the field690*/691void inline(Environment env) throws ClassNotFound {692switch (status) {693case PARSED:694check(env);695inline(env);696break;697698case CHECKED:699if (env.dump()) {700System.out.println("[inline field " + getClassDeclaration().getName() + "." + getName() + "]");701}702status = INLINING;703env = new Environment(env, this);704705if (isMethod()) {706if ((!isNative()) && (!isAbstract())) {707Statement s = (Statement)getValue();708Context ctx = new Context((Context)null, this);709for (Enumeration e = args.elements() ; e.hasMoreElements() ;) {710LocalMember local = (LocalMember)e.nextElement();711ctx.declare(env, local);712}713setValue(s.inline(env, ctx));714}715} else if (isInnerClass()) {716// some classes are checked and inlined separately717ClassDefinition nc = getInnerClass();718if (nc instanceof SourceClass && !nc.isLocal()719&& nc.isInsideLocal()) {720status = INLINING;721((SourceClass)nc).inlineLocalClass(env);722}723status = INLINED;724break;725} else {726if (getValue() != null) {727Context ctx = new Context((Context)null, this);728if (!isStatic()) {729// Cf. "thisArg" in SourceClass.checkMembers().730Context ctxInst = new Context(ctx, this);731LocalMember thisArg =732((SourceClass)clazz).getThisArgument();733ctxInst.declare(env, thisArg);734setValue(((Expression)getValue())735.inlineValue(env, ctxInst));736} else {737setValue(((Expression)getValue())738.inlineValue(env, ctx));739}740}741}742if (env.dump()) {743System.out.println("[inlined field " + getClassDeclaration().getName() + "." + getName() + "]");744if (getValue() != null) {745getValue().print(System.out);746System.out.println();747} else {748System.out.println("<empty>");749}750}751status = INLINED;752break;753}754}755756/**757* Get the value of the field (or null if the value can't be determined)758*/759public Node getValue(Environment env) throws ClassNotFound {760Node value = getValue();761if (value != null && status != INLINED) {762// be sure to get the imports right:763env = ((SourceClass)clazz).setupEnv(env);764inline(env);765value = (status == INLINED) ? getValue() : null;766}767return value;768}769770public boolean isInlineable(Environment env, boolean fromFinal) throws ClassNotFound {771if (super.isInlineable(env, fromFinal)) {772getValue(env);773return (status == INLINED) && !getClassDefinition().getError();774}775return false;776}777778779/**780* Get the initial value of the field781*/782public Object getInitialValue() {783if (isMethod() || (getValue() == null) || (!isFinal()) || (status != INLINED)) {784return null;785}786return ((Expression)getValue()).getValue();787}788789/**790* Generate code791*/792public void code(Environment env, Assembler asm) throws ClassNotFound {793switch (status) {794case PARSED:795check(env);796code(env, asm);797return;798799case CHECKED:800inline(env);801code(env, asm);802return;803804case INLINED:805// Actually generate code806if (env.dump()) {807System.out.println("[code field " + getClassDeclaration().getName() + "." + getName() + "]");808}809if (isMethod() && (!isNative()) && (!isAbstract())) {810env = new Environment(env, this);811Context ctx = new Context((Context)null, this);812Statement s = (Statement)getValue();813814for (Enumeration e = args.elements() ; e.hasMoreElements() ; ) {815LocalMember f = (LocalMember)e.nextElement();816ctx.declare(env, f);817//ctx.declare(env, (LocalMember)e.nextElement());818}819820/*821if (isConstructor() && ((s == null) || (s.firstConstructor() == null))) {822ClassDeclaration c = getClassDefinition().getSuperClass();823if (c != null) {824MemberDefinition field = c.getClassDefinition(env).matchMethod(env, getClassDefinition(), idInit);825asm.add(getWhere(), opc_aload, new Integer(0));826asm.add(getWhere(), opc_invokespecial, field);827asm.add(getWhere(), opc_pop);828}829830// Output initialization code831for (MemberDefinition f = getClassDefinition().getFirstMember() ; f != null ; f = f.getNextMember()) {832if (!f.isStatic()) {833f.codeInit(env, ctx, asm);834}835}836}837*/838if (s != null) {839s.code(env, ctx, asm);840}841if (getType().getReturnType().isType(TC_VOID) && !isInitializer()) {842asm.add(getWhere(), opc_return, true);843}844}845return;846}847}848849public void codeInit(Environment env, Context ctx, Assembler asm) throws ClassNotFound {850if (isMethod()) {851return;852}853switch (status) {854case PARSED:855check(env);856codeInit(env, ctx, asm);857return;858859case CHECKED:860inline(env);861codeInit(env, ctx, asm);862return;863864case INLINED:865// Actually generate code866if (env.dump()) {867System.out.println("[code initializer " + getClassDeclaration().getName() + "." + getName() + "]");868}869if (getValue() != null) {870Expression e = (Expression)getValue();871// The JLS Section 8.5 specifies that static (non-final)872// initializers should be executed in textual order. Eliding873// initializations to default values can interfere with this,874// so the tests for !e.equalsDefault() have been eliminated,875// below.876if (isStatic()) {877if (getInitialValue() == null) {878// removed: && !e.equalsDefault()) {879e.codeValue(env, ctx, asm);880asm.add(getWhere(), opc_putstatic, this);881}882} else { // removed: if (!e.equalsDefault()) {883// This code doesn't appear to be reached for884// instance initializers. Code for these is generated885// in the makeVarInits() method of the class886// MethodExpression.887asm.add(getWhere(), opc_aload, new Integer(0));888e.codeValue(env, ctx, asm);889asm.add(getWhere(), opc_putfield, this);890}891}892return;893}894}895896/**897* Print for debugging898*/899public void print(PrintStream out) {900super.print(out);901if (getValue() != null) {902getValue().print(out);903out.println();904}905}906}907908909