1 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 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 } 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 toString() { 59 StringBuffer buf = new StringBuffer ("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 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 130 reduce(type); 131 132 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 toString() { 162 StringBuffer buf = new StringBuffer (); 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 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 } 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 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 |