KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > crosscuts > joinpoints > InstanceTest


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.crosscuts.joinpoints;
26
27 import org.aspectj.compiler.crosscuts.ast.*;
28 import org.aspectj.compiler.base.ast.*;
29
30 import org.aspectj.compiler.base.CompilerObject;
31 import org.aspectj.compiler.base.JavaCompiler;
32
33 import java.util.*;
34
35 /**
36  */

37
38 public class InstanceTest extends CompilerObject {
39     private List andBlocks = new ArrayList();
40
41     private InstanceTest(JavaCompiler compiler) {
42         this(compiler,new ArrayList());
43     }
44
45     private InstanceTest(JavaCompiler compiler, Type type, boolean isTrue) {
46         this(compiler);
47         addOr(type, isTrue);
48         //System.out.println("new InstanceTest(" + type + ": " + isTrue);
49
}
50
51     private InstanceTest(JavaCompiler compiler, List andBlocks) {
52         super(compiler);
53         this.andBlocks = andBlocks;
54     }
55
56     public int size() { return andBlocks.size(); }
57
58     public String JavaDoc toString() {
59         StringBuffer JavaDoc buf = new StringBuffer JavaDoc("ITest(");
60         for (int i=0; i < andBlocks.size(); i++) {
61             AndBlock block1 = (AndBlock)andBlocks.get(i);
62             if (i > 0) buf.append(" || ");
63             buf.append(block1.toString());
64         }
65         buf.append(")");
66         return buf.toString();
67     }
68
69
70     public void addOr(Type typeDec, boolean isTrue) {
71         //System.out.println("add: " + typeDec + " to " + andBlocks.size());
72
andBlocks.add(new AndBlock(getCompiler(),typeDec, isTrue));
73     }
74
75     public InstanceTest intersect(InstanceTest other) {
76         List newBlocks = new ArrayList();
77         for (int i=0; i < andBlocks.size(); i++) {
78             AndBlock block1 = (AndBlock)andBlocks.get(i);
79             for (int j=0; j < other.andBlocks.size(); j++) {
80                 AndBlock block2 = (AndBlock)other.andBlocks.get(j);
81                 newBlocks.add(block1.intersect(block2));
82             }
83         }
84         return new InstanceTest(getCompiler(),newBlocks);
85     }
86
87     public InstanceTest union(InstanceTest other) {
88         List newBlocks = new ArrayList(andBlocks);
89         newBlocks.addAll(other.andBlocks);
90         return new InstanceTest(getCompiler(),newBlocks);
91     }
92
93     public InstanceTest complement() {
94         InstanceTest ret = null;
95         for (int i=0; i < andBlocks.size(); i++) {
96             AndBlock block = (AndBlock)andBlocks.get(i);
97             InstanceTest test = block.complement();
98             if (ret == null) {
99                 ret = test;
100             } else {
101                 ret = ret.intersect(test);
102             }
103         }
104         return ret;
105     }
106
107     private void reduce(Type staticType) {
108         if (staticType == null) {
109             System.out.println("troubled..." + this);
110             return;
111         }
112
113         List newBlocks = new ArrayList();
114
115         for (int i=0; i < andBlocks.size(); i++) {
116             AndBlock block = (AndBlock)andBlocks.get(i);
117             block = block.reduce(staticType);
118             if (block != null) {
119                 newBlocks.add(block);
120             }
121         }
122
123         this.andBlocks = newBlocks;
124     }
125
126     public Expr makeExpr(Expr thisExpr) {
127         Type type = thisExpr.getType();
128         //System.out.println(" instance test: " + type + ", " + this);
129

130         reduce(type);
131
132         //System.out.println(" -> " + this);
133

134
135         Expr ret = null;
136         for (int i=0; i < andBlocks.size(); i++) {
137             AndBlock block = (AndBlock)andBlocks.get(i);
138             Expr blockExpr = block.makeExpr(thisExpr);
139             if (ret == null) {
140                 ret = blockExpr;
141             } else {
142                 ret = getAST().makeBinop("||", ret, blockExpr);
143             }
144         }
145         return ret;
146     }
147
148     private static class AndBlock extends CompilerObject {
149         private List trueTypes = new ArrayList();
150         private List falseTypes = new ArrayList();
151
152         public AndBlock(JavaCompiler compiler, Type typeDec, boolean isTrue) {
153             super(compiler);
154             if (isTrue) {
155                 trueTypes.add(typeDec);
156             } else {
157                 falseTypes.add(typeDec);
158             }
159         }
160
161         public String JavaDoc toString() {
162             StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
163             int i;
164             for (i = 0; i < trueTypes.size(); i++) {
165                 if (i > 0) buf.append(" && ");
166                 buf.append(((Type)trueTypes.get(i)).toShortString());
167             }
168
169             for (i = 0; i < falseTypes.size(); i++) {
170                 if (i > 0 || trueTypes.size() > 0) buf.append(" && ");
171                 buf.append("!");
172                 buf.append(((Type)falseTypes.get(i)).toShortString());
173             }
174             return buf.toString();
175         }
176
177         public InstanceTest complement() {
178             List newBlocks = new ArrayList(trueTypes.size() + falseTypes.size());
179             int i;
180             for (i = 0; i < trueTypes.size(); i++) {
181                 newBlocks.add(new AndBlock(getCompiler(),(Type)trueTypes.get(i), false));
182             }
183
184             for (i = 0; i < falseTypes.size(); i++) {
185                 newBlocks.add(new AndBlock(getCompiler(),(Type)falseTypes.get(i), true));
186             }
187             return new InstanceTest(getCompiler(),newBlocks);
188         }
189
190         public AndBlock intersect(AndBlock other) {
191             trueTypes.addAll(other.trueTypes);
192             falseTypes.addAll(other.falseTypes);
193             //XXX destructive
194
return this;
195         }
196
197         public AndBlock reduce(Type staticType) {
198             {
199                 for (Iterator i = trueTypes.iterator(); i.hasNext(); ) {
200                     Type trueType = (Type)i.next();
201                     if (staticType.isSubtypeOf(trueType)) i.remove();
202                     //??? add a check that the other way is possible
203
}
204             }
205
206             {
207                 for (Iterator i = falseTypes.iterator(); i.hasNext(); ) {
208                     Type falseType = (Type)i.next();
209                     if (!falseType.isSubtypeOf(staticType) &&
210                         !staticType.isSubtypeOf(falseType))
211                     {
212                         i.remove();
213                     }
214                 }
215             }
216
217             if (trueTypes.size() == 0 && falseTypes.size() == 0) return null;
218             //??? destructive
219
return this;
220         }
221
222         private Expr makeInstanceOfExpr(Expr expr, Type checkType) {
223             return getAST().makeParen(getAST().makeInstanceof(expr, checkType));
224         }
225
226         private Expr intersectExpr(Expr e1, Expr e2) {
227             if (e1 == null) return e2;
228             return getAST().makeBinop("&&", e1, e2);
229         }
230
231
232         public Expr makeExpr(Expr thisExpr) {
233             Expr ret = null;
234             int i;
235             for (i = 0; i < trueTypes.size(); i++) {
236                 Expr testExpr = makeInstanceOfExpr(thisExpr, (Type)trueTypes.get(i));
237                 ret = intersectExpr(ret, testExpr);
238             }
239
240             for (i = 0; i < falseTypes.size(); i++) {
241                 Expr testExpr = makeInstanceOfExpr(thisExpr, (Type)falseTypes.get(i));
242                 testExpr = getAST().makeUnop("!", testExpr);
243                 ret = intersectExpr(ret, testExpr);
244             }
245
246             if (ret instanceof UnopExpr) return ret;
247             return getAST().makeParen(ret);
248         }
249     }
250 }
251
Popular Tags