View Javadoc
1   /*
2    * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package sun.tools.tree;
27  
28  import sun.tools.java.*;
29  import sun.tools.asm.Assembler;
30  import sun.tools.asm.Label;
31  import java.io.PrintStream;
32  import java.util.Hashtable;
33  
34  /**
35   * WARNING: The contents of this source file are not part of any
36   * supported API.  Code that depends on them does so at its own risk:
37   * they are subject to change or removal without notice.
38   */
39  public
40  class CompoundStatement extends Statement {
41      Statement args[];
42  
43      /**
44       * Constructor
45       */
46      public CompoundStatement(long where, Statement args[]) {
47          super(STAT, where);
48          this.args = args;
49          // To avoid the need for subsequent null checks:
50          for (int i = 0 ; i < args.length ; i++) {
51              if (args[i] == null) {
52                  args[i] = new CompoundStatement(where, new Statement[0]);
53              }
54          }
55      }
56  
57      /**
58       * Insert a new statement at the front.
59       * This is used to introduce an implicit super-class constructor call.
60       */
61      public void insertStatement(Statement s) {
62          Statement newargs[] = new Statement[1+args.length];
63          newargs[0] = s;
64          for (int i = 0 ; i < args.length ; i++) {
65              newargs[i+1] = args[i];
66          }
67          this.args = newargs;
68      }
69  
70      /**
71       * Check statement
72       */
73      Vset check(Environment env, Context ctx, Vset vset, Hashtable exp) {
74          checkLabel(env, ctx);
75          if (args.length > 0) {
76              vset = reach(env, vset);
77              CheckContext newctx = new CheckContext(ctx, this);
78              // In this environment, 'resolveName' will look for local classes.
79              Environment newenv = Context.newEnvironment(env, newctx);
80              for (int i = 0 ; i < args.length ; i++) {
81                  vset = args[i].checkBlockStatement(newenv, newctx, vset, exp);
82              }
83              vset = vset.join(newctx.vsBreak);
84          }
85          return ctx.removeAdditionalVars(vset);
86      }
87  
88      /**
89       * Inline
90       */
91      public Statement inline(Environment env, Context ctx) {
92          ctx = new Context(ctx, this);
93          boolean expand = false;
94          int count = 0;
95          for (int i = 0 ; i < args.length ; i++) {
96              Statement s = args[i];
97              if (s != null) {
98                  if ((s = s.inline(env, ctx)) != null) {
99                      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 }