KickJava   Java API By Example, From Geeks To Geeks.

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


1 /* -*- Mode: Java; 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 org.aspectj.compiler.base.JavaCompiler;
28 import org.aspectj.compiler.base.AssignmentCheckerPass;
29 import org.aspectj.compiler.base.CodeWriter;
30 import org.aspectj.compiler.base.FlowCheckerPass;
31 import org.aspectj.compiler.base.ByteCodeCleanupPass;
32
33 import org.aspectj.compiler.base.bcg.CodeBuilder;
34 import org.aspectj.compiler.base.bcg.Label;
35
36 /**
37  * @grammar test ? true: false
38  * @child Expr test
39  * @child Expr true
40  * @child Expr false
41  */

42 public class TriTestExpr extends Expr {
43
44     // XXX this is wrong, most of this checking should be done after constant folding.
45
public Type discoverType() {
46         Type testTy = getTest().getType();
47         if (testTy != getTypeManager().booleanType) {
48             showError("Incompatable type for ?: Can't convert " + testTy.getString() + " to boolean");
49         }
50         Expr trueExpr = getTrue();
51         Expr falseExpr = getFalse();
52         Type trueTy = trueExpr.getType();
53         Type falseTy = falseExpr.getType();
54
55         if (trueTy == falseTy) {
56             return trueTy;
57         } else if (trueTy.isNumeric() && falseTy.isNumeric()) {
58             if ((trueTy instanceof ShortType && falseTy instanceof ByteType) ||
59                 (trueTy instanceof ByteType && falseTy instanceof ShortType)) {
60                 return getTypeManager().shortType;
61             } else if (trueExpr instanceof IntLiteralExpr &&
62                        trueTy instanceof IntType &&
63                        trueExpr.isAssignableTo(falseTy)) {
64                 return falseTy;
65             } else if (falseExpr instanceof IntLiteralExpr &&
66                        falseTy instanceof IntType &&
67                        falseExpr.isAssignableTo(trueTy)) {
68                 return trueTy;
69             } else {
70                 return getTypeManager().binaryNumericPromotion(trueTy, falseTy);
71             }
72         } else if (trueTy.isReferenceType() && falseTy.isReferenceType()) {
73             if (trueTy.isAssignableFrom(falseTy)) {
74                 return trueTy;
75             } else if (falseTy.isAssignableFrom(trueTy)) {
76                 return falseTy;
77             } else {
78                 showError("Incompatable type for ?: Can't convert between " + trueTy.getString() + " and " + falseTy.getString());
79                 return trueTy;
80             }
81         } else {
82             showError("Incompatable type for ?: Can't convert between " + trueTy.getString() + " and " + falseTy.getString());
83             return trueTy;
84         }
85     }
86
87     public void checkSpec() {
88         // silly rule from grammar in JLS 15.25 restricting _false only
89
if (_false instanceof AssignExpr) {
90             _false.showError("assignment expression not allowed here");
91         }
92     }
93
94     public void preAssignmentCheck(AssignmentCheckerPass walker) {
95         getType();
96     }
97
98     public ASTObject postAssignmentCheck(AssignmentCheckerPass walker) {
99         setType(null);
100         if ((getTrue() instanceof LiteralExpr) &&
101             (getFalse() instanceof LiteralExpr)) {
102             if (getTest().isConstantTrue()) {
103                 return getTrue();
104             } else if (getTest().isConstantFalse()) {
105                 return getFalse();
106             }
107         }
108         return this;
109     }
110
111     public void unparse(CodeWriter writer) {
112         writer.write(test);
113         writer.writeOp("?");
114         writer.write(_true);
115         writer.writeOp(":");
116         writer.write(_false);
117     }
118
119     // ------------------------------
120
// INTRO from FlowCheckerPass
121

122     public void walkFlow(FlowCheckerPass w) {
123         // w.setArgs(w.getArgs());
124
w.processBoolean(getTest());
125         FlowCheckerPass.Vars p0 = w.getVars();
126
127         if (getType().isBoolean()) {
128             w.setVars(p0.getTrue());
129             w.processBoolean(getTrue());
130             FlowCheckerPass.Vars p1 = w.getVars();
131
132             w.setVars(p0.getFalse());
133             w.processBoolean(getFalse());
134             FlowCheckerPass.Vars p2 = w.getVars();
135
136             w.setVars(p1.getTrue().join(p2.getTrue()),
137                       p1.getFalse().join(p2.getFalse()));
138         } else {
139             w.setVars(p0.getTrue());
140             w.process(getTrue());
141             FlowCheckerPass.Vars t1 = w.getVars();
142
143             w.setVars(p0.getFalse());
144             w.process(getFalse());
145             FlowCheckerPass.Vars t2 = w.getVars();
146
147             w.setVars(t1.join(t2));
148         }
149     }
150
151     public void normalizeFlow(FlowCheckerPass w) {}
152
153     // ------------------------------
154
// INTRO from ByteCodeCleanupPass
155

156     public ASTObject postCleanup(ByteCodeCleanupPass w) {
157         if (getTest().isConstantTrue()) {
158             return getTrue();
159         } else if (getTest().isConstantFalse()) {
160             return getFalse();
161         } else {
162             return this;
163         }
164     }
165
166     // ------------------------------
167
// bcg
168
protected void cgValue(CodeBuilder cb) {
169         Type ty = getType();
170         Label trueLab = cb.genLabel();
171         Label falseLab = cb.genLabel();
172         Label endLab = cb.genLabel();
173         test.cgTest(cb, trueLab, falseLab);
174         cb.emitLabel(trueLab);
175         _true.cgValue(cb, ty);
176         cb.emitJump(endLab);
177         cb.emitLabel(falseLab);
178         cb.popStack(ty.getSlotCount());
179         _false.cgValue(cb, ty);
180         cb.emitLabel(endLab);
181     }
182     protected void cgEffect(CodeBuilder cb) {
183         Label trueLab = cb.genLabel();
184         Label falseLab = cb.genLabel();
185         Label endLab = cb.genLabel();
186         test.cgTest(cb, trueLab, falseLab);
187         cb.emitLabel(trueLab);
188         _true.cgEffect(cb);
189         cb.emitJump(endLab);
190         cb.emitLabel(falseLab);
191         _false.cgEffect(cb);
192         cb.emitLabel(endLab);
193     }
194     protected void cgTest(CodeBuilder cb, Label tdest, Label fdest) {
195         Label trueLab = cb.genLabel();
196         Label falseLab = cb.genLabel();
197         test.cgTest(cb, trueLab, falseLab);
198         cb.emitLabel(trueLab);
199         _true.cgTest(cb, tdest, fdest);
200         cb.emitLabel(falseLab);
201         _false.cgTest(cb, tdest, fdest);
202     }
203
204     //BEGIN: Generated from @child and @property
205
protected Expr test;
206     public Expr getTest() { return test; }
207     public void setTest(Expr _test) {
208         if (_test != null) _test.setParent(this);
209         test = _test;
210     }
211
212     protected Expr _true;
213     public Expr getTrue() { return _true; }
214     public void setTrue(Expr __true) {
215         if (__true != null) __true.setParent(this);
216         _true = __true;
217     }
218
219     protected Expr _false;
220     public Expr getFalse() { return _false; }
221     public void setFalse(Expr __false) {
222         if (__false != null) __false.setParent(this);
223         _false = __false;
224     }
225
226     public TriTestExpr(SourceLocation location, Expr _test, Expr __true, Expr __false) {
227         super(location);
228         setTest(_test);
229         setTrue(__true);
230         setFalse(__false);
231     }
232     protected TriTestExpr(SourceLocation source) {
233         super(source);
234     }
235
236     public ASTObject copyWalk(CopyWalker walker) {
237         TriTestExpr ret = new TriTestExpr(getSourceLocation());
238         ret.preCopy(walker, this);
239         if (test != null) ret.setTest( (Expr)walker.process(test) );
240         if (_true != null) ret.setTrue( (Expr)walker.process(_true) );
241         if (_false != null) ret.setFalse( (Expr)walker.process(_false) );
242         return ret;
243     }
244
245     public ASTObject getChildAt(int childIndex) {
246         switch(childIndex) {
247         case 0: return test;
248         case 1: return _true;
249         case 2: return _false;
250         default: return super.getChildAt(childIndex);
251         }
252     }
253      public String JavaDoc getChildNameAt(int childIndex) {
254         switch(childIndex) {
255         case 0: return "test";
256         case 1: return "true";
257         case 2: return "false";
258         default: return super.getChildNameAt(childIndex);
259         }
260     }
261      public void setChildAt(int childIndex, ASTObject child) {
262         switch(childIndex) {
263         case 0: setTest((Expr)child); return;
264         case 1: setTrue((Expr)child); return;
265         case 2: setFalse((Expr)child); return;
266         default: super.setChildAt(childIndex, child); return;
267         }
268     }
269      public int getChildCount() {
270         return 3;
271     }
272
273     public String JavaDoc getDefaultDisplayName() {
274         return "TriTestExpr()";
275     }
276
277     //END: Generated from @child and @property
278
}
279
Popular Tags