KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > ast > ControlContext


1 /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base.ast;
26
27 import java.util.List JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.NoSuchElementException JavaDoc;
31
32 /**
33     A representation of the control context, the lexical context of
34     statements that affect control flow. This is used to handle the
35     control issues arising from labeled statements, breaks and
36     continues, returns and throws, tries and continues, loops (for,
37     while, do), and switches.
38
39     @see LabeledStmt
40     @see WhileStmt
41     @see DoStmt
42     @see ForStmt
43     @see SwitchStmt
44
45     @see WindingStmt
46     @see TryStmt
47     @see SynchronizedStmt
48
49     @see BreakStmt
50     @see ContinueStmt
51     @see ReturnStmt
52     @see ThrowStmt
53 */

54
55 public final class ControlContext {
56
57     private List JavaDoc context = new ArrayList JavaDoc();
58
59     /** Enters the context of a control-effecting statement.
60
61         @param the control-effecting statement entered.
62      */

63     public void enter(Stmt s) {
64         context.add(s);
65     }
66
67     /** Exits the context of a previously-entered control-effecting statement.
68      */

69     public void exit() {
70         context.remove(context.size() - 1);
71     }
72
73     /** Returns the target statement of a break statement.
74
75         @param label label of break statement, or null
76         @return the target of the break statement.
77         @exception java.util.NoSuchElementException there is no target
78      */

79     public Stmt getBreakTarget(String JavaDoc label) {
80         return getTarget(label, true);
81     }
82
83     /** Returns the target statement of a continue statement.
84
85         @param label label of continue statement, or null
86         @return the target of the continue statement.
87         @exception java.util.NoSuchElementException there is no target
88         @exception UnsupportedOperationException the target is not continuable
89     */

90     public Stmt getContinueTarget(String JavaDoc label) {
91         return getTarget(label, false);
92     }
93
94     /** Returns true if a {@link LabeledStmt} with a
95         label is in the context.
96
97         @return true if label is used in the context, false otherwise.
98         @param label label to check for. */

99     public boolean isLabelUsed(String JavaDoc label) {
100         for (int i = context.size() - 1; i >= 0; i--) {
101             Object JavaDoc s = context.get(i);
102             if (s instanceof LabeledStmt &&
103                 label.equals(((LabeledStmt)s).getLabel()))
104                 return true;
105         }
106         return false;
107     }
108
109     private Stmt getTarget(String JavaDoc target, boolean isBreak) {
110 // System.err.println("CC " + context);
111
// System.err.println("-- " + target);
112
// System.err.println("-- " + (isBreak ? "break" : "continue"));
113
int i = context.size() - 1;
114         if (target == null) {
115             if (isBreak) {
116                 for (; i >= 0; i--) {
117                     Stmt s = (Stmt) context.get(i);
118                     if (s.isBreakable()) return s;
119                 }
120             } else {
121                 for (; i >= 0; i--) {
122                     Stmt s = (Stmt) context.get(i);
123                     if (s.isContinuable()) return s;
124                 }
125             }
126         } else {
127             for (; i >= 0; i--) {
128                 Stmt s = (Stmt) context.get(i);
129                 if (s instanceof LabeledStmt
130                         && target.equals(((LabeledStmt)s).getLabel())) {
131                     if (isBreak) return s;
132                     s = ((LabeledStmt) s).getStmt();
133 // while (s instanceof LabeledStmt) {
134
// s = ((LabeledStmt) s).getStmt();
135
// }
136
if (s.isContinuable()) return s;
137                     throw new UnsupportedOperationException JavaDoc();
138                 }
139             }
140         }
141         throw new NoSuchElementException JavaDoc();
142     }
143
144     /** Returns an iterator view of the winding statements up to a
145         control target. If null is passed in, will return all winding
146         statements. This iterator is not only non-thread-safe, it
147         cannot be stored anywhere either, since it shares its backing
148         with the context. So as soon as it is returned, it should be
149         iterated over.
150
151         @return an iterator view of the winding statements up to a control target.
152         @param end the control-effecting statement enclosing the winding statements.
153     */

154     public Iterator JavaDoc getWindsUntil(final Stmt end) {
155         return new Iterator JavaDoc() {
156                 private int i = context.size() - 1;
157                 private boolean live = true;
158                 private void search() {
159                     for (; i >= 0; i--) {
160                         Object JavaDoc o = context.get(i);
161                         if (o == end) {
162                             break;
163                         } else if (o instanceof WindingStmt) {
164                             return;
165                         }
166                     }
167                     live = false;
168                 }
169                 {
170                     search();
171                 }
172                 public boolean hasNext() { return live; }
173                 public Object JavaDoc next() {
174                     if (! live) throw new NoSuchElementException JavaDoc();
175                     Object JavaDoc o = context.get(i--);
176                     search();
177                     return o;
178                 }
179                 public void remove() {
180                     throw new UnsupportedOperationException JavaDoc();
181                 }
182             };
183     }
184 }
185
Popular Tags