001: /*
002: * Copyright 1994-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.tree;
027:
028: import sun.tools.java.*;
029: import sun.tools.asm.Assembler;
030: import sun.tools.asm.Label;
031: import java.io.PrintStream;
032: import java.util.Hashtable;
033:
034: /**
035: * WARNING: The contents of this source file are not part of any
036: * supported API. Code that depends on them does so at its own risk:
037: * they are subject to change or removal without notice.
038: */
039: public class CompoundStatement extends Statement {
040: Statement args[];
041:
042: /**
043: * Constructor
044: */
045: public CompoundStatement(long where, Statement args[]) {
046: super (STAT, where);
047: this .args = args;
048: // To avoid the need for subsequent null checks:
049: for (int i = 0; i < args.length; i++) {
050: if (args[i] == null) {
051: args[i] = new CompoundStatement(where, new Statement[0]);
052: }
053: }
054: }
055:
056: /**
057: * Insert a new statement at the front.
058: * This is used to introduce an implicit super-class constructor call.
059: */
060: public void insertStatement(Statement s) {
061: Statement newargs[] = new Statement[1 + args.length];
062: newargs[0] = s;
063: for (int i = 0; i < args.length; i++) {
064: newargs[i + 1] = args[i];
065: }
066: this .args = newargs;
067: }
068:
069: /**
070: * Check statement
071: */
072: Vset check(Environment env, Context ctx, Vset vset, Hashtable exp) {
073: checkLabel(env, ctx);
074: if (args.length > 0) {
075: vset = reach(env, vset);
076: CheckContext newctx = new CheckContext(ctx, this );
077: // In this environment, 'resolveName' will look for local classes.
078: Environment newenv = Context.newEnvironment(env, newctx);
079: for (int i = 0; i < args.length; i++) {
080: vset = args[i].checkBlockStatement(newenv, newctx,
081: vset, exp);
082: }
083: vset = vset.join(newctx.vsBreak);
084: }
085: return ctx.removeAdditionalVars(vset);
086: }
087:
088: /**
089: * Inline
090: */
091: public Statement inline(Environment env, Context ctx) {
092: ctx = new Context(ctx, this );
093: boolean expand = false;
094: int count = 0;
095: for (int i = 0; i < args.length; i++) {
096: Statement s = args[i];
097: if (s != null) {
098: if ((s = s.inline(env, ctx)) != null) {
099: if ((s.op == STAT) && (s.labels == null)) {
100: count += ((CompoundStatement) s).args.length;
101: } else {
102: count++;
103: }
104: expand = true;
105: }
106: args[i] = s;
107: }
108: }
109: switch (count) {
110: case 0:
111: return null;
112:
113: case 1:
114: for (int i = args.length; i-- > 0;) {
115: if (args[i] != null) {
116: return eliminate(env, args[i]);
117: }
118: }
119: break;
120: }
121: if (expand || (count != args.length)) {
122: Statement newArgs[] = new Statement[count];
123: for (int i = args.length; i-- > 0;) {
124: Statement s = args[i];
125: if (s != null) {
126: if ((s.op == STAT) && (s.labels == null)) {
127: Statement a[] = ((CompoundStatement) s).args;
128: for (int j = a.length; j-- > 0;) {
129: newArgs[--count] = a[j];
130: }
131: } else {
132: newArgs[--count] = s;
133: }
134: }
135: }
136: args = newArgs;
137: }
138: return this ;
139: }
140:
141: /**
142: * Create a copy of the statement for method inlining
143: */
144: public Statement copyInline(Context ctx, boolean valNeeded) {
145: CompoundStatement s = (CompoundStatement) clone();
146: s.args = new Statement[args.length];
147: for (int i = 0; i < args.length; i++) {
148: s.args[i] = args[i].copyInline(ctx, valNeeded);
149: }
150: return s;
151: }
152:
153: /**
154: * The cost of inlining this statement
155: */
156: public int costInline(int thresh, Environment env, Context ctx) {
157: int cost = 0;
158: for (int i = 0; (i < args.length) && (cost < thresh); i++) {
159: cost += args[i].costInline(thresh, env, ctx);
160: }
161: return cost;
162: }
163:
164: /**
165: * Code
166: */
167: public void code(Environment env, Context ctx, Assembler asm) {
168: CodeContext newctx = new CodeContext(ctx, this );
169: for (int i = 0; i < args.length; i++) {
170: args[i].code(env, newctx, asm);
171: }
172: asm.add(newctx.breakLabel);
173: }
174:
175: /**
176: * Check if the first thing is a constructor invocation
177: */
178: public Expression firstConstructor() {
179: return (args.length > 0) ? args[0].firstConstructor() : null;
180: }
181:
182: /**
183: * Print
184: */
185: public void print(PrintStream out, int indent) {
186: super .print(out, indent);
187: out.print("{\n");
188: for (int i = 0; i < args.length; i++) {
189: printIndent(out, indent + 1);
190: if (args[i] != null) {
191: args[i].print(out, indent + 1);
192: } else {
193: out.print("<empty>");
194: }
195: out.print("\n");
196: }
197: printIndent(out, indent);
198: out.print("}");
199: }
200: }
|