1 19 20 package org.netbeans.modules.java.source.script; 21 22 import org.netbeans.modules.java.source.engine.ASTModel; 23 import com.sun.source.tree.Tree.Kind; 24 import org.netbeans.modules.java.source.builder.ASTService; 25 import org.netbeans.modules.java.source.engine.ASTModel; 26 import org.openide.util.NbBundle; 27 28 import com.sun.tools.javac.tree.*; 29 import com.sun.tools.javac.code.*; 30 import com.sun.tools.javac.tree.JCTree.*; 31 import com.sun.tools.javac.parser.*; 32 import com.sun.tools.javac.util.*; 33 34 import java.io.*; 35 import java.text.MessageFormat ; 36 import java.util.Arrays ; 37 import java.util.Collection ; 38 import java.util.HashMap ; 39 import java.util.Iterator ; 40 import org.netbeans.api.java.source.transform.Transformer; 41 42 import static com.sun.tools.javac.parser.Token.*; 43 44 public class TransformParser extends ScriptParser { 45 final Name impliesToken = names.fromString("=>"); 46 final Name suchthatToken = names.fromString("::"); 47 final Name doSomethingToken = names.fromString("=:"); 48 final Collection <Name> newTokens = 49 Arrays.asList(impliesToken, suchthatToken, doSomethingToken); 50 final Name nullName = tokenName(Token.NULL); 51 final Name trueName = tokenName(Token.TRUE); 52 final Name falseName = tokenName(Token.FALSE); 53 String fileName; 54 String javacpath; 55 String queryDescription; 56 String transformDescription; 57 long fileLastModified; 58 protected Position.LineMap lineMap; 59 protected final ASTModel model; 60 61 public TransformParser(Reader in, String javacpath) { 62 this("Rules", "Rules", null, in, 0L, javacpath); 63 } 64 public TransformParser(String path, String queryName, String transformName, 65 Reader in, long lastModified, String javacpath) { 66 super(); 67 model = ASTService.instance(context); 68 setIn(path, in); 69 fileName = queryName; 70 fileLastModified = lastModified; 71 this.javacpath = javacpath; 72 queryDescription = queryName; 73 transformDescription = transformName; 74 lineMap = scanner.getLineMap(); 75 nameConstMap = new HashMap <Name,String >(); 76 nameConstMap.put(trueName,"names._true"); 77 nameConstMap.put(falseName,"names._false"); 78 } 79 80 protected Context createContext() { 81 Context ctx = super.createContext(); 82 new Keywords(ctx) { 83 public Token key(Name name) { 84 if (newTokens.contains(name)) 85 return CUSTOM; 86 return super.key(name); 87 } 88 }; 89 Factory.instance(ctx); return ctx; 91 } 92 93 protected String returnTypeDecl() { return "JCTree"; } 94 protected String returnType() { return "JCTree"; } 95 protected String returnTypeImport() { return "\n"; } 96 protected String baseType() { return "GeneratedMatcher"; } 97 protected String failureReturn() { return "t"; } 98 protected String scriptTitle(String filename) { 99 StringBuffer sb = new StringBuffer ("{ queryDescription=\""); 100 sb.append(queryDescription); 101 if (transformDescription != null) { 102 sb.append("\"; refactoringDescription=\""); 103 sb.append(transformDescription); 104 } 105 sb.append("\"; script=\""); 106 sb.append(filename); 107 sb.append("\"; }\n"); 108 return sb.toString(); 109 } 110 public Rule parseRules() { 111 if(scanner.token() == EOF || scanner.token() == RBRACE) return null; 112 if(scanner.token() == IDENTIFIER && scanner.name() == mapclassName) { 113 scanner.nextToken(); 114 JCTree original = parser.qualident(); 115 if(!isToken(impliesToken)) 116 logError(scanner.pos(), "no.suchthat.for.mapclass"); 117 else { 118 scanner.nextToken(); 119 JCTree rep = parser.qualident(); 120 parser.accept(SEMI); 121 if(!hasErrors()) 122 mapClass.put(original,rep); 123 } 124 return parseRules(); 125 } 126 Rule ret = Rule.invalidRule; 127 int rulePos = scanner.pos(); 128 JCTree pat = javaFragment(); 129 if (pat instanceof JCErroneous) { 130 do { 132 scanner.nextToken(); 133 } while (scanner.token() != EOF && scanner.token() != SEMI); 134 scanner.nextToken(); 135 } 136 else { 137 JCTree replacement = null; 138 JCExpression suchthat = null; 139 JCTree code = null; 140 while(true) 141 if(isToken(impliesToken)) { 142 scanner.nextToken(); 143 if (scanner.token() == ASSERT) { 144 scanner.nextToken(); 145 JCExpression assertion = expression(); 146 JCExpression message = null; 147 if (scanner.token() == COLON) { 148 scanner.nextToken(); 149 message = expression(); 150 } 151 replacement = make.Assert(assertion, message); 152 parser.accept(SEMI); 153 } 154 else 155 replacement = javaFragment(); 156 if(scanner.token() == IDENTIFIER && scanner.name() == inlineName) { 157 if(replacement instanceof JCBlock) 158 ((JCBlock)replacement).flags |= Flags.BLOCK; 159 else logError(replacement.pos, "illegal.inline"); 160 scanner.nextToken(); 161 } 162 if(!isToken(suchthatToken) && !isToken(doSomethingToken)) break; 163 } 164 else if(isToken(suchthatToken)) 165 while(true) { 166 scanner.nextToken(); 167 JCExpression t = expression(); 168 suchthat = suchthat==null ? t : make.Binary(JCTree.AND, suchthat, t); 169 if(scanner.token() != COMMA) break; 170 } 171 else if(scanner.token() == SEMI) { 172 scanner.nextToken(); 173 break; 174 } 175 else if(isToken(doSomethingToken)) { 176 scanner.nextToken(); 177 code = statement(); 178 logger.info("Added code fragment to "+pat+"\n\t"+code); 179 break; 180 } 181 else { 182 if (suchthat == null) 183 logError(rulePos, "no.suchthat", pat); 184 else 185 logError(rulePos, "bad.syntax"); 186 break; 187 } 188 if (!hasErrors()) 189 ret = new Rule(pat,replacement,suchthat,code,lineMap.getLineNumber(rulePos)); 190 } 191 if( scanner.token() != EOF && scanner.token() != RBRACE) 192 ret.next = parseRules(); 193 return rules = ret; 194 } 195 196 private JCTree javaFragment() { 197 JCTree pat; 198 switch (scanner.token()) { 199 case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: 200 case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK: 201 case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: 202 pat = statement(); 203 break; 204 default: 205 pat = expression(); 206 break; 207 } 208 if (scanner.token() != SEMI && 209 (pat instanceof JCIdent || pat instanceof JCFieldAccess) && 210 scanner.token() == IDENTIFIER && scanner.name() != inlineName) { 211 JCModifiers mods = make.at(Position.NOPOS).Modifiers(0); 212 ListBuffer<JCStatement> stats = 213 parser.variableDeclarators(mods, (JCExpression)pat, new ListBuffer<JCStatement>()); 214 assert stats.length() == 1; 215 pat = stats.first(); 216 } 217 if(scanner.token() == SEMI) 218 scanner.nextToken(); 219 return pat; 220 } 221 222 private void logError(int pos, String key, Object ... args) { 223 String format = NbBundle.getBundle(TransformParser.class).getString("TransformParser." + key); 224 String msg = MessageFormat.format(format, args); 225 log.rawError(pos, msg); 226 } 227 public boolean hasErrors() { 228 return super.hasErrors() || pc!=null && pc.hasErrors(); 229 } 230 public String getErrors() { 231 return super.hasErrors() ? super.getErrors() 232 : pc!=null ? pc.getErrors() 233 : null; 234 } 235 public boolean hasRules() { 236 return rules != null || mapClass.size() > 0; 237 } 238 239 private JCTree deblock(JCTree t) { 240 t = (JCTree)Transformer.deblock(t); 241 return t instanceof JCExpressionStatement ? ((JCExpressionStatement)t).expr : t; 242 } 243 244 245 protected String passthrough() { 246 return ""; 247 } 248 249 private static final boolean ENABLE_CACHE = false; 250 251 public Rule rules; 252 protected PluginCompiler pc; 253 public Class codeRules() throws IOException { 254 if(!hasRules()) return null; 255 rootHead = null; 256 rootTail = null; 257 pc = new PluginCompiler(); 258 if(pc.needsGeneration(fileName, fileLastModified, !ENABLE_CACHE)) { 259 pc.startGeneration(); 260 pc.write("import org.netbeans.api.java.source.TreeMaker;\n"); 261 pc.write("import org.netbeans.api.java.source.query.*;\n"); 262 pc.write("import org.netbeans.api.java.source.transform.*;\n"); 263 pc.write("import org.netbeans.modules.java.source.script.*;\n"); 264 pc.write("import com.sun.source.tree.*;\n"); 265 pc.write("import com.sun.source.tree.Tree.Kind;\n"); 266 pc.write("import javax.lang.model.SourceVersion;\n\n"); 267 pc.write("import javax.lang.model.element.*;\n\n"); 268 pc.write("import com.sun.tools.javac.code.*;\n"); 269 pc.write("import com.sun.tools.javac.tree.*;\n"); 270 pc.write("import com.sun.tools.javac.tree.JCTree.*;\n"); 271 pc.write("import com.sun.tools.javac.util.*;\n"); 272 pc.write(returnTypeImport()); 273 pc.write("public class "); 274 pc.writeClassName(); 275 pc.write(" extends "); 276 pc.write(baseType()); 277 pc.write(" {\n "); 278 pc.write(scriptTitle(fileName)); 279 pc.write(passthrough()); 280 pc.write("\n public "); 281 pc.write(returnTypeDecl()); 282 pc.write(" rewrite("); 283 pc.write(returnType()); 284 pc.write(" t) {\n"); 285 for(Rule r = rules; r!=null; r = r.next) { 286 metaslot = 0; 287 tempslot = 0; 288 head = null; 289 tail = null; 290 genMatch("t", r.pattern); 291 genSuchThat(r.suchthat, false); 292 addReplacement(r); 293 if(head!=null) { 294 if(rootHead==null) rootHead = head; 295 else rootTail.ifFail = head; 296 rootTail = head; 297 } 298 } 299 if(rootHead!=null) { 300 rootHead = optimize(rootHead); 301 rootTail.ifFail = new Guard("", 0, Guard.DECLARATION); 302 rootHead.writeAll(pc,0); 303 } 304 pc.write("\treturn "); 305 pc.write(failureReturn()); 306 pc.write(";\n"); 307 pc.write(" }\n"); 308 dumpNameConsts(pc); 309 pc.write("}\n"); 310 pc.getWriter().flush(); 311 if(hasErrors()) 312 return null; 313 } 314 return pc.loadClass(javacpath); 315 } 316 317 Guard rootHead, rootTail; 318 Guard head, tail; 319 int metaslot = 0; 320 int tempslot = 0; 321 Name[] metakeys = new Name[20]; 322 boolean[] isName = new boolean[20]; 323 int[] isList = new int[20]; 324 String [] metavalues = new String [20]; 325 326 Coder coder = makeCoder(); 327 protected Coder makeCoder() { return new Coder(context); } 328 Constructor constructor = makeConstructor(); 329 protected Constructor makeConstructor() { return new RewriteConstructor(); } 330 public class Constructor extends Visitor { 331 public void generate(JCTree t) { 332 try { 333 if(t==null) pc.write("null"); 334 else if(t.tag==JCTree.IDENT) { 335 t.accept(this); 336 } else { 337 pc.write("rewrite0("); 338 t.accept(this); 339 pc.write(")"); 340 } 341 } catch(IOException ioe) {} 342 } 343 public void generate(long l) throws IOException { 344 pc.write(l); 345 if(l>(1L<<31)-1 || l<-(1L<<31)) pc.write('L'); 346 } 347 public <T extends JCTree> void generate(List<T> t) { 348 generate(t,false); 349 } 350 public <T extends JCTree> void generate(List<T> t, boolean statements) { 351 generate(t, statements, statements ? "JCStatement" : "JCTree"); 352 } 353 public <T extends JCTree> void generate2(List<T> t, boolean statements, String listType) { 354 generate(t,statements,listType); 355 } 356 public <T extends JCTree> void generate(List<T> t, boolean statements, String listType) { 357 try { 358 if(t==null) pc.write("null"); 359 else if(t.isEmpty()) { 360 pc.write("List.<"); 361 pc.write(listType); 362 pc.write(">nil()"); 363 } 364 else { 365 JCTree head = deblock(t.head); 366 if(head.tag==JCTree.IDENT) { 367 Name id = ((JCIdent)head).name; 368 for(int i = metavars.length; --i>=0; ) 369 if(id==metavars[i]){ 370 if(isList[i]==0) pc.write(metavals[i]); 371 else if(isList[i]>0) { 372 pc.write("slice("); 373 pc.write(metavals[i]); 374 pc.write(", len_"); 375 pc.write(i); 376 pc.write(","); 377 generate2(t.tail,statements,listType); 378 pc.write(")"); 379 } else break; 380 return; 381 } 382 } 383 generate2(t.tail,statements,listType); 384 pc.write(".prepend("); 385 if("JCTree"!=listType) { 386 pc.write('('); 387 pc.write(listType); 388 pc.write(')'); 389 } 390 if(statements) pc.write("statement("); 391 generate(head); 392 if(statements) pc.write(")"); 393 pc.write(")"); 394 } 395 } catch(IOException ioe) {} 396 } 397 PluginCompiler pc; 398 protected Name[] metavars; 399 protected String [] metavals; 400 boolean[] isName; 401 int[] isList; 402 } 403 class RewriteConstructor extends Constructor { 404 public void generate(Name n) throws IOException { 405 if(n==null) pc.write("null"); 406 else { 407 pc.write("jcmake.Ident("); 408 pc.write(nameConst(n)); 409 pc.write(")"); 410 } 411 } 412 public void generateName(Name n) throws IOException { 413 if(n==null) pc.write("null"); 414 else 415 pc.write(nameConst(n)); 416 } 417 418 public void visitTopLevel(JCCompilationUnit that) { visitTree(that); } 419 public void visitImport(JCImport that) { 420 try { 421 pc.write("jcmake.Import("); 422 generate(that.qualid); 423 pc.write(","); 424 pc.write(litName(that.staticImport)); 425 pc.write(')'); 426 } catch(IOException ioe) {} 427 } 428 public void visitClassDef(JCClassDecl def) { 429 try { 430 if(def==null) pc.write("null"); 431 else { 432 pc.write("\n\tjcmake.ClassDef((JCModifiers)"); 433 generate(def.mods); 434 pc.write(' '); 435 generateName(def.name); 436 pc.write(",\n\t\t"); 437 generate(def.typarams,false,"JCTypeParameter"); 438 pc.write(",\n\t\t"); 439 generate(def.extending); 440 pc.write(",\n\t\t"); 441 generate(def.implementing,false,"JCExpression"); 442 pc.write(",\n\t\t"); 443 generate(def.defs); 444 pc.write(')'); 445 } 446 } catch(IOException ioe) {} 447 } 448 public void visitMethodDef(JCMethodDecl def) { 449 try { 450 if(def==null) pc.write("null"); 451 else { 452 pc.write("\n\t\tjcmake.MethodDef((JCModifiers)"); 453 generate(def.mods); 454 pc.write(' '); 455 generateName(def.name); 456 pc.write(",\n\t\t\t(JCExpression)"); 457 generate(def.restype); 458 pc.write(",\n\t\t\t"); 459 generate(def.typarams,false,"JCTypeParameter"); 460 pc.write(",\n\t\t\t"); 461 generate(def.params,false,"JCVariableDecl"); 462 pc.write(",\n\t\t\t"); 463 generate(def.thrown,false,"JCExpression"); 464 pc.write(",\n\t\t\tblock("); 465 generate(def.body); 466 pc.write(",(JCExpression)"); 467 generate(def.defaultValue); 468 pc.write("))"); 469 } 470 } catch(IOException ioe) {} 471 } 472 public void visitSkip(JCSkip that) { 473 try { 474 pc.write("jcmake.Skip()"); 475 } catch(IOException ioe) {} 476 } 477 public void visitBlock(JCBlock that) { 478 try { 479 pc.write("block("); 480 pc.write(that.flags); 481 pc.write(","); 482 generate(that.stats, true); 483 pc.write(")"); 484 } catch(IOException ioe) {} 485 } 486 public void visitDoLoop(JCDoWhileLoop that) { 487 try { 488 pc.write("jcmake.DoLoop((JCStatement)"); 489 generate(that.body); 490 pc.write(",(JCExpression)"); 491 generate(that.cond); 492 pc.write(')'); 493 } catch(IOException ioe) {} 494 } 495 public void visitWhileLoop(JCWhileLoop that) { 496 try { 497 pc.write("jcmake.WhileLoop((JCExpression)"); 498 generate(that.cond); 499 pc.write(",(JCStatement)"); 500 generate(that.body); 501 pc.write(')'); 502 } catch(IOException ioe) {} 503 } 504 public void visitForLoop(JCForLoop that) { 505 try { 506 pc.write("jcmake.ForLoop((JCExpression)"); 507 generate(that.init, true); 508 pc.write(",(JCExpression)"); 509 generate(that.cond); 510 pc.write(",(JCStatement)"); 511 generate(that.body); 512 pc.write(')'); 513 } catch(IOException ioe) {} 514 } 515 public void visitForeachLoop(JCEnhancedForLoop that) { 516 try { 517 pc.write("jcmake.ForeachLoop((JCVariableDecl)"); 518 generate(that.var); 519 pc.write(",(JCExpression)"); 520 generate(that.expr); 521 pc.write(",(JCStatement)"); 522 generate(that.body); 523 pc.write(')'); 524 } catch(IOException ioe) {} 525 } 526 public void visitLabelled(JCLabeledStatement that) { 527 try { 528 pc.write("jcmake.Labelled("); 529 referenceName(that.label, true); 530 pc.write(",(JCStatement)"); 531 generate(that.body); 532 pc.write(')'); 533 } catch(IOException ioe) {} 534 } 535 public void visitSwitch(JCSwitch that) { 536 try { 537 pc.write("jcmake.Switch((JCExpression)"); 538 generate(that.selector); 539 pc.write(","); 540 generate(that.cases, false, "JCCase"); 541 pc.write(')'); 542 } catch(IOException ioe) {} 543 } 544 public void visitCase(JCCase that) { 545 try { 546 pc.write("jcmake.Switch((JCExpression)"); 547 generate(that.pat); 548 pc.write(","); 549 generate(that.stats, true, "JCStatement"); 550 pc.write(')'); 551 } catch(IOException ioe) {} 552 } 553 public void visitSynchronized(JCSynchronized that) { 554 try { 555 pc.write("jcmake.Synchronized((JCExpression)"); 556 generate(that.lock); 557 pc.write(",(JCBlock)"); 558 generate(that.body); 559 pc.write(')'); 560 } catch(IOException ioe) {} 561 } 562 public void visitTry(JCTry that) { 563 try { 564 pc.write("jcmake.Try((JCBlock)"); 565 generate(that.body); 566 pc.write(","); 567 generate(that.catchers, false, "JCCatch"); 568 pc.write(",(JCBlock)"); 569 generate(that.finalizer); 570 pc.write(')'); 571 } catch(IOException ioe) {} 572 } 573 public void visitCatch(JCCatch that) { 574 try { 575 pc.write("jcmake.Catch((JCVariableDecl)"); 576 generate(that.param); 577 pc.write(",(JCBlock)"); 578 generate(that.body); 579 pc.write(')'); 580 } catch(IOException ioe) {} 581 } 582 public void visitTypeCast(JCTypeCast that) { 583 try { 584 pc.write("jcmake.TypeCast("); 585 generate(that.clazz); 586 pc.write(",(JCExpression)"); 587 generate(that.expr); 588 pc.write(')'); 589 } catch(IOException ioe) {} 590 } 591 public void visitTypeTest(JCInstanceOf that) { 592 try { 593 pc.write("jcmake.TypeTest((JCExpression)"); 594 generate(that.expr); 595 pc.write(','); 596 generate(that.clazz); 597 pc.write(')'); 598 } catch(IOException ioe) {} 599 } 600 public void visitConditional(JCConditional that) { 601 try { 602 pc.write("jcmake.Conditional((JCExpression)"); 603 generate(that.cond); 604 pc.write(",(JCExpression)"); 605 generate(that.truepart); 606 pc.write(",(JCExpression)"); 607 generate(that.falsepart); 608 pc.write(')'); 609 } catch(IOException ioe) {} 610 } 611 public void visitIf(JCIf that) { 612 try { 613 pc.write("jcmake.If("); 614 generate(that.cond); 615 pc.write(",(JCStatement)"); 616 generate(that.thenpart); 617 pc.write(",(JCStatement)"); 618 generate(that.elsepart); 619 pc.write(')'); 620 } catch(IOException ioe) {} 621 } 622 public void visitApply(JCMethodInvocation that) { 623 try { 624 pc.write("jcmake.Apply("); 625 generate(that.typeargs,false,"JCExpression"); 626 pc.write(",(JCExpression)"); 627 generate(that.meth); 628 pc.write(','); 629 generate(that.args,false,"JCExpression"); 630 pc.write(')'); 631 } catch(IOException ioe) {} 632 } 633 public void visitExec(JCExpressionStatement that) { 634 try { 635 pc.write("jcmake.Exec((JCExpression)"); 636 generate(that.expr); 637 pc.write(')'); 638 } catch(IOException ioe) {} 639 } 640 public void visitBreak(JCBreak that) { 641 try { 642 pc.write("jcmake.Break("); 643 referenceName(that.label, true); 644 pc.write(")"); 645 } catch(IOException ioe) {} 646 } 647 public void visitContinue(JCContinue that) { 648 try { 649 pc.write("jcmake.Continue("); 650 referenceName(that.label, true); 651 pc.write(")"); 652 } catch(IOException ioe) {} 653 } 654 public void visitReturn(JCReturn that) { 655 try { 656 pc.write("jcmake.Return((JCExpression)"); 657 generate(that.expr); 658 pc.write(')'); 659 } catch(IOException ioe) {} 660 } 661 public void visitThrow(JCThrow that) { 662 try { 663 pc.write("jcmake.Throw("); 664 generate(that.expr); 665 pc.write(')'); 666 } catch(IOException ioe) {} 667 } 668 public void visitAssert(JCAssert that) { 669 try { 670 pc.write("jcmake.Assert((JCJCExpression)"); 671 generate(that.cond); 672 pc.write(",(JCExpression)"); 673 generate(that.detail); 674 pc.write(')'); 675 } catch(IOException ioe) {} 676 } 677 public void visitNewClass(JCNewClass that) { 678 try { 679 pc.write("jcmake.NewClass((JCExpression)"); 680 generate(that.encl); 681 pc.write(','); 682 generate(that.typeargs,false,"JCExpression"); 683 pc.write(",(JCExpression)"); 684 generate(that.clazz); 685 pc.write(','); 686 generate(that.args,false,"JCExpression"); 687 pc.write(",(JCClassDecl)"); 688 generate(that.def); 689 pc.write(')'); 690 } catch(IOException ioe) {} 691 } 692 public void visitNewArray(JCNewArray that) { 693 try { 694 pc.write("jcmake.NewArray((JCExpression)"); 695 generate(that.elemtype); 696 pc.write(','); 697 generate(that.dims,false,"JCExpression"); 698 pc.write(','); 699 generate(that.elems,false,"JCExpression"); 700 pc.write(')'); 701 } catch(IOException ioe) {} 702 } 703 public void visitParens(JCParens that) { 704 that.expr.accept(this); 705 } 706 public void visitAssign(JCAssign that) { 707 try { 708 pc.write("jcmake.Assign((JCExpression)"); 709 generate(that.lhs); 710 pc.write(",(JCExpression)"); 711 generate(that.rhs); 712 pc.write(')'); 713 } catch(IOException ioe) {} 714 } 715 public void visitAssignop(JCAssignOp that) { 716 try { 717 pc.write("jcmake.AssignOp("); 718 pc.write(that.tag); 719 pc.write(','); 720 generate(that.lhs); 721 pc.write(','); 722 generate(that.rhs); 723 pc.write(')'); 724 } catch(IOException ioe) {} 725 } 726 public void visitUnary(JCUnary that) { 727 try { 728 pc.write("jcmake.Unary("); 729 pc.write(that.tag); 730 pc.write(",(JCExpression)"); 731 generate(that.arg); 732 pc.write(')'); 733 } catch(IOException ioe) {} 734 } 735 public void visitBinary(JCBinary that) { 736 try { 737 pc.write("jcmake.Binary("); 738 pc.write(that.tag); 739 pc.write(",(JCExpression)"); 740 generate(that.lhs); 741 pc.write(",(JCExpression)"); 742 generate(that.rhs); 743 pc.write(')'); 744 } catch(IOException ioe) {} 745 } 746 public void visitIndexed(JCArrayAccess that) { 747 try { 748 pc.write("jcmake.Indexed("); 749 generate(that.indexed); 750 pc.write(",(JCExpression)"); 751 generate(that.index); 752 pc.write(')'); 753 } catch(IOException ioe) {} 754 } 755 public void visitSelect(JCFieldAccess that) { 756 try { 757 pc.write("resolve(jcmake.Select((JCExpression)"); 758 generate(that.selected); 759 pc.write(','); 760 referenceName(that.name,true); 761 pc.write("))"); 762 } catch(IOException ioe) {} 763 } 764 private void referenceName(Name id, boolean asName) { 765 try { 766 for(int i = metavars.length; --i>=0; ) 767 if(id==metavars[i]) { 768 if(isName[i]==asName) pc.write(metavals[i]); 769 else if(asName) { 770 pc.write("TreeInfo.name("); 771 pc.write(metavals[i]); 772 pc.write(")"); 773 } else { 774 pc.write("jcmake.Ident("); 775 pc.write(metavals[i]); 776 pc.write(")"); 777 } 778 return; 779 } 780 if(asName) pc.write(nameConst(id)); 781 else generate(id); 782 } catch(IOException ioe) {} 783 } 784 public void visitIdent(JCIdent that) { 785 referenceName(that.name, false); 786 } 787 public void visitVarDef(JCVariableDecl that) { 788 try { 789 pc.write("jcmake.VarDef((JCModifiers)"); 790 generate(that.mods); 791 pc.write(","); 792 referenceName(that.name, true); 793 pc.write(",(JCExpression)"); 794 generate(that.vartype); 795 pc.write(",(JCExpression)"); 796 generate(that.init); 797 pc.write(")"); 798 } catch(IOException ioe) {} 799 } 800 public void visitLiteral(JCLiteral that) { 801 try { 802 pc.write("jcmake.Literal("); 803 pc.write(that.typetag); 804 pc.write(", "); 805 if(that.value instanceof String ) 806 pc.writeQuoted((String )that.value); 807 else 808 pc.write(litName(that.value)); 809 pc.write(')'); 810 } catch(IOException ioe) {} 811 } 812 public void visitTypeIdent(JCPrimitiveTypeTree that) { 813 try { 814 pc.write("jcmake.TypeIdent("); 815 generate(that.typetag); 816 pc.write(')'); 817 } catch(IOException ioe) {} 818 } 819 public void visitTypeArray(JCArrayTypeTree that) { 820 try { 821 pc.write("jcmake.TypeArray((JCExpression)"); 822 generate(that.elemtype); 823 pc.write(')'); 824 } catch(IOException ioe) {} 825 } 826 public void visitTypeApply(JCTypeApply that) { 827 try { 828 pc.write("jcmake.TypeApply((JCExpression)"); 829 generate(that.clazz); 830 pc.write(", "); 831 generate(that.arguments); 832 pc.write(')'); 833 } catch(IOException ioe) {} 834 } 835 public void visitTypeParameter(JCTypeParameter that) { 836 try { 837 pc.write("jcmake.TypeParameter("); 838 generate(that.name); 839 pc.write(", "); 840 generate(that.bounds,false,"JCExpression"); 841 pc.write(')'); 842 } catch(IOException ioe) {} 843 } 844 public void visitWildcard(JCWildcard that) { 845 try { 846 pc.write("jcmake.Wildcard("); 847 pc.write("jcmake.TypeBoundKind(BoundKind."); 848 pc.write(that.kind.toString()); 849 pc.write("), "); 850 generate(that.inner); 851 pc.write(')'); 852 } catch(IOException ioe) {} 853 } 854 public void visitAnnotation(JCAnnotation that) { 855 try { 856 pc.write("jcmake.Annotation("); 857 generate(that.annotationType); 858 pc.write(", "); 859 generate(that.args); 860 pc.write(')'); 861 } catch(IOException ioe) {} 862 } 863 public void visitModifiers(JCModifiers that) { 864 try { 865 pc.write("jcmake.Modifiers("); 866 generate(that.flags); 867 pc.write(", "); 868 generate(that.annotations, false, "JCAnnotation"); 869 pc.write(')'); 870 } catch(IOException ioe) {} 871 } 872 public void visitErroneous(JCErroneous that) { visitTree(that); } 873 874 public void visitTree(JCTree that) { 875 try { 876 pc.write("/* can't generate code for "+that.getClass().getSimpleName()+"\n\t"+that+" */"); 877 } catch(IOException ioe) {} 878 } 879 } 880 881 final HashMap <JCTree,JCTree> mapClass = new HashMap <JCTree,JCTree>(); 882 void dumpMapclass() throws IOException { 883 if(mapClass.size()<=0) return; 884 pc.write(" public Symbol replacesymbol(Symbol s) {\n"); 885 for(Iterator <JCTree> in = mapClass.keySet().iterator(); in.hasNext(); ) { 886 JCTree t0 = in.next(); 887 JCTree t1 = mapClass.get(t0); 888 pc.write("\tif(s=="); 889 pc.write(classSymConst(TreeInfo.fullName(t0))); 890 pc.write(") {\n\t\tcomment = \""); 891 pc.write(TreeInfo.name(t0).toString()); 892 pc.write("=>"); 893 pc.write(TreeInfo.name(t1).toString()); 894 pc.write("\";\n\t\treturn "); 895 pc.write(classSymConst(TreeInfo.fullName(t1))); 896 pc.write(";\n\t}\n"); 897 } 898 pc.write("\treturn s;\n }\n"); 899 } 900 901 final HashMap <Name,String > nameConstMap; 902 String nameConst(Name n) { 903 if(n==null) return "null"; 904 String s = nameConstMap.get(n); 905 if(s==null) { 906 s = ("nameConstant_"+n).replace('.','_'); 907 nameConstMap.put(n,s); 908 } 909 return s; 910 } 911 912 final HashMap <Name,String > classSymConstMap = new HashMap <Name,String >(); 913 String classSymConst(Name n) { 914 if(n==null) return "null"; 915 String s = classSymConstMap.get(n); 916 if(s==null) { 917 s = ("classSymConstant_"+n).replace('.','_'); 918 classSymConstMap.put(n,s); 919 nameConst(n); 920 } 921 return s; 922 } 923 924 private final HashMap <Object ,String > litNameMap = new HashMap <Object ,String >(); 925 private int litIndex = 1; 926 String litName(Object o) { 927 if(o==null) return "null"; 928 String s = litNameMap.get(o); 929 if(s==null) { 930 s = "litConstant_"+litIndex++; 931 litNameMap.put(o,s); 932 } 933 return s; 934 } 935 936 public void dumpNameConsts(PluginCompiler pc) throws IOException { 937 dumpMapclass(); 938 for(Iterator <Name> in = nameConstMap.keySet().iterator(); in.hasNext(); ) { 939 Name n = in.next(); 940 String s = nameConstMap.get(n); 941 if(!s.startsWith("names.")) { 942 pc.write(" private com.sun.tools.javac.util.Name "); 943 pc.write(s); 944 pc.write(";\n"); 945 } 946 } 947 for(Iterator <String > in = classMap.keySet().iterator(); in.hasNext(); ) { 948 pc.write(" private "); 949 String key = in.next(); 950 String var = classMap.get(key); 951 int sep = key.indexOf(':'); 952 assert(sep>=0); 953 String jar = key.substring(0,sep); 954 String clazz = key.substring(sep+1); 955 pc.write(clazz); 956 pc.write(' '); 957 pc.write(var); 958 pc.write(" = ("); 959 pc.write(clazz); 960 pc.write(") findClass(\""); 961 pc.write(jar); 962 pc.write("\",\""); 963 pc.write(clazz); 964 pc.write("\");\n"); 965 } 966 for(Iterator <Name> in = classSymConstMap.keySet().iterator(); in.hasNext(); ) { 967 Name n = in.next(); 968 String s = classSymConstMap.get(n); 969 pc.write(" private Symbol.ClassSymbol "); 970 pc.write(s); 971 pc.write(";\n"); 972 } 973 for(Iterator <Object > io = litNameMap.keySet().iterator(); io.hasNext(); ) { 974 Object o = io.next(); 975 pc.write(" private static final Object "); 976 pc.write(litNameMap.get(o)); 977 pc.write(" = new "); 978 pc.write(o.getClass().getName()); 979 pc.write("("); 980 pc.write(o.toString()); 981 pc.write(");\n"); 982 } 983 pc.write(" protected void initializeKeywords() throws ClassNotFoundException {\n"); 984 for(Iterator <Name> in = nameConstMap.keySet().iterator(); in.hasNext(); ) { 985 Name n = in.next(); 986 String s = nameConstMap.get(n); 987 if(!s.startsWith("names.")) { 988 pc.write("\t"); 989 pc.write(s); 990 pc.write(" = names.fromString("); 991 pc.writeQuoted(n.toString()); 992 pc.write(");\n"); 993 pc.write("\tif("+s+"==null)\n\t System.err.println(\"NULL name "+s+"\");\n"); 994 } 995 } 996 for(Iterator <Name> in = classSymConstMap.keySet().iterator(); in.hasNext(); ) { 997 Name n = in.next(); 998 String s = classSymConstMap.get(n); 999 pc.write("\t"); 1000 pc.write(s); 1001 pc.write(" = resolveClass("); 1002 pc.write(nameConst(n)); 1003 pc.write(");\n"); 1004 pc.write("\tif("+s+"==null)\n\t System.err.println(\"NULL sym "+s+"\");\n"); 1005 } 1006 pc.write(" }\n"); 1007 } 1008 1009 private void genSuchThat(JCTree t, boolean invert) throws IOException { 1010 if(t==null) return; 1011 switch(t.tag) { 1012 default: 1013 if(funcNames[t.tag]!=null && !invert) { 1014 addKnown(t); 1015 addBoolean(knownValue(t)+"==Boolean.TRUE"); 1016 } else 1017 addBoolean(genSuchThatTerm(t,invert)); 1018 break; 1019 case JCTree.AND: 1020 if(invert) { 1021 addBoolean(genSuchThatTerm(t,invert)); 1022 } else { 1023 genSuchThat(((JCBinary)t).lhs, false); 1024 genSuchThat(((JCBinary)t).rhs, false); 1025 } 1026 break; 1027 case JCTree.OR: 1028 if(!invert) { 1029 addBoolean(genSuchThatTerm(t,invert)); 1030 } else { 1031 genSuchThat(((JCBinary)t).lhs, true); 1032 genSuchThat(((JCBinary)t).rhs, true); 1033 } 1034 break; 1035 case JCTree.NOT: 1036 genSuchThat(((JCUnary)t).arg, !invert); 1037 break; 1038 case JCTree.PARENS: 1039 genSuchThat(((JCParens)t).expr, invert); 1040 break; 1041 } 1042 } 1043 private String genSuchThatTerm(JCTree t,boolean invert) { 1044 String result = "true"; 1045 if(t!=null) 1046 switch(t.tag) { 1047 case JCTree.NOT: 1048 return genSuchThatTerm(((JCUnary)t).arg,!invert); 1049 case JCTree.PARENS: 1050 return genSuchThatTerm(((JCParens)t).expr, invert); 1051 case JCTree.AND: 1052 return "("+genSuchThatTerm(((JCBinary)t).lhs,invert) 1053 +(invert?"||":"&&") 1054 +genSuchThatTerm(((JCBinary)t).rhs,invert)+")"; 1055 case JCTree.OR: 1056 return "("+genSuchThatTerm(((JCBinary)t).lhs,invert) 1057 +(invert?"&&":"||") 1058 +genSuchThatTerm(((JCBinary)t).rhs,invert)+")"; 1059 case JCTree.TYPETEST: { 1061 JCInstanceOf tt = (JCInstanceOf) t; 1062 result = "isInstance(" + metaValue(tt.expr) + ", "; 1063 if (isMetaValue(tt.clazz)) 1064 result += "getElement(" + metaValue(tt.clazz) + "))"; 1065 else 1066 result += classSymConst(TreeInfo.fullName(tt.clazz)) + ")"; 1068 } 1069 break; 1070 default: 1071 if(funcNames[t.tag]!=null) return genKnown(t, invert); 1072 logError(t.pos, "illegal.guard", t); 1073 break; 1074 case JCTree.APPLY: 1075 JCMethodInvocation mcall = (JCMethodInvocation) t; 1076 try { 1077 if(mcall.meth.tag==JCTree.IDENT) { 1078 Name nm = ((JCIdent)mcall.meth).name; 1079 if(nm==assignedInName) { 1080 checkLen(mcall.args,2); 1081 result = "assignedIn("+arg(mcall.args,0)+","+arg(mcall.args,1)+")"; 1082 break; 1083 } 1084 else if(nm==declaredInName) { 1085 checkLen(mcall.args,2); 1086 result = "declaredIn("+arg(mcall.args,0)+","+arg(mcall.args,1)+")"; 1087 break; 1088 } 1089 Method m = methodRegistry.get(nm.toString()); 1090 if(m!=null) { 1091 checkLen(mcall.args,1); 1092 result = m.genInvoke(this,arg(mcall.args,0)); 1093 break; 1094 } 1095 } 1096 logError(t.pos, "illegal.guard", t); 1097 } catch(ArgError ae) { 1098 ae.printStackTrace(); 1099 logError(t.pos, "illegal.argument.in.guard", ae.getMessage(), t); 1100 } 1101 break; 1102 case JCTree.IDENT: 1103 Name idn = ((JCIdent)t).name; 1104 if(idn==statementcontextName) 1105 result="isStatement(parent())"; 1106 else 1107 logError(t.pos, "illegal.guard", t); 1108 break; 1109 } 1110 if(invert) result = "!"+result; 1111 return result; 1112 } 1113 private String genKnown(JCTree t, boolean invert) { 1114 return (invert ? "!(" : "(") + isKnown(t) + 1115 knownValue(t)+"==Boolean.TRUE)"; 1116 } 1117 private String isKnown(JCTree t) { 1118 if(t==null) return ""; 1119 if(funcNames[t.tag]!=null) 1120 return isKnown(((JCBinary)t).lhs)+isKnown(((JCBinary)t).rhs); 1121 if(t instanceof JCLiteral) 1122 return ""; 1123 if(t instanceof JCIdent) { 1124 String s = metaValue(t); 1125 if(s!=null) return "constant("+s+") && "; 1126 } 1127 logError(t.pos, "guaranteed.unknown", t); 1128 return "false &&"; 1129 } 1130 private void addKnown(JCTree t) { 1131 if(t==null) return; 1132 int tag = t.tag; 1133 if(funcNames[tag] != null) { 1134 addKnown(((JCBinary)t).lhs); 1135 addKnown(((JCBinary)t).rhs); 1136 return; 1137 } 1138 if(tag==JCTree.LITERAL) return; 1139 if(tag==JCTree.IDENT) { 1140 addBoolean("constant("+metaValue(t)+")"); 1141 return; 1142 } 1143 logError(t.pos, "unhandled.op", t); 1144 addBoolean("false"); 1145 } 1146 private static final String [] funcNames = new String [JCTree.MOD_ASG+1]; 1147 static { 1148 funcNames[JCTree.BITOR] = "opBITOR"; 1149 funcNames[JCTree.BITXOR] = "opBITXOR"; 1150 funcNames[JCTree.BITAND] = "opBITAND"; 1151 funcNames[JCTree.SL] = "opSL"; 1152 funcNames[JCTree.SR] = "opSR"; 1153 funcNames[JCTree.USR] = "opUSR"; 1154 funcNames[JCTree.PLUS] = "opPLUS"; 1155 funcNames[JCTree.MINUS] = "opMINUS"; 1156 funcNames[JCTree.MUL] = "opMUL"; 1157 funcNames[JCTree.DIV] = "opDIV"; 1158 funcNames[JCTree.MOD] = "opMOD"; 1159 funcNames[JCTree.EQ] = "opEQ"; 1160 funcNames[JCTree.NE] = "opNE"; 1161 funcNames[JCTree.LE] = "opLE"; 1162 funcNames[JCTree.GE] = "opGE"; 1163 funcNames[JCTree.LT] = "opLT"; 1164 funcNames[JCTree.GT] = "opGT"; 1165 } 1166 1167 private String knownValue(JCTree t) { 1168 if(t==null) return "intZero"; 1169 if(funcNames[t.tag]!=null) 1170 return funcNames[t.tag]+"("+knownValue(((JCBinary)t).lhs)+","+knownValue(((JCBinary)t).rhs)+")"; 1171 if(t instanceof JCLiteral) { 1172 Object o = ((JCLiteral)t).value; 1173 if(o instanceof String ) { 1174 StringBuffer sb = new StringBuffer (); 1175 String s = o.toString(); 1176 int limit = s.length(); 1177 sb.append('"'); 1178 for(int i = 0; i<limit; i++) { 1179 char c = s.charAt(i); 1180 if(c<0177 && c>=040 && c!='"' && c!='\\') sb.append(c); 1181 else if(c<=0377) { 1182 sb.append('\\'); 1183 sb.append('0'+((c>>6)&7)); 1184 sb.append('0'+((c>>3)&7)); 1185 sb.append('0'+((c )&7)); 1186 } else { 1187 sb.append('\\'); 1188 sb.append('u'); 1189 sb.append(Character.forDigit((c>>12)&15,16)); 1190 sb.append(Character.forDigit((c>> 8)&15,16)); 1191 sb.append(Character.forDigit((c>> 4)&15,16)); 1192 sb.append(Character.forDigit((c )&15,16)); 1193 } 1194 } 1195 sb.append('"'); 1196 o = sb; 1197 return o.toString(); 1198 } 1199 return litName(o); 1200 } 1201 if(t instanceof JCIdent) 1202 return "valueOf("+metaValue(t)+")"; 1203 return "0"; 1204 } 1205 public static class ArgError extends Exception { 1206 public ArgError(String s) { super(s); } 1207 } 1208 private void checkLen(List<? extends JCTree> t, int len) throws ArgError { 1209 while(len>0) { 1210 if(t==null || t.isEmpty()) throw new ArgError(len+" too few arguments"); 1211 t = t.tail; 1212 len--; 1213 } 1214 if(!t.isEmpty()) throw new ArgError("too many arguments. Excess: "+t.head); 1215 } 1216 private String arg(List<? extends JCTree> l, int index) throws ArgError { 1217 while(index>0) { 1218 if(l==null || l.isEmpty()) throw new ArgError("Missing argument"); 1219 l = l.tail; 1220 index--; 1221 } 1222 if(l==null || l.isEmpty()) throw new ArgError("Missing argument"); 1223 return arg(l.head); 1224 } 1225 private String arg(JCTree t) throws ArgError { 1226 if(t==null) return "null"; 1227 switch(t.tag) { 1228 case JCTree.IDENT: { 1229 Name idname = ((JCIdent)t).name; 1230 for(int i = metaslot; --i>=0; ) 1231 if(idname==metakeys[i]) { 1232 String ret = metavalues[i]; 1233 if(isList[i]>0) 1234 ret = "firstN("+ret+",len_"+i+")"; 1235 return ret; 1236 } 1237 return idname.toString(); 1238 } 1239 case JCTree.SELECT: { 1240 JCFieldAccess sel = (JCFieldAccess) t; 1241 Name idname = sel.name; 1242 String base = arg(sel.selected); 1243 if(idname==parentName) { 1244 int ix = base.lastIndexOf('.'); 1245 logger.fine("SEL "+t+" "+base+" ix="+ix); 1246 if(ix>0) return base.substring(0,ix); 1247 } 1248 return base+"."+idname; 1249 } 1250 } 1251 throw new ArgError("Unacceptable argument: "+t); 1252 1253 } 1254 String metaValue(JCTree t) { 1255 int idx = metaValueIndex(t); 1256 if(idx == -1) { 1257 logError(t==null?0:t.pos, "metavar.expected", t); 1258 return "error"; 1259 } 1260 return metavalues[idx]; 1261 } 1262 int metaValueIndex(JCTree t) { 1263 if(t instanceof JCIdent) { 1264 Name idname = ((JCIdent)t).name; 1265 for(int i = metaslot; --i>=0; ) 1266 if(idname==metakeys[i]) 1267 return i; 1268 } 1269 return -1; 1270 } 1271 boolean isMetaValue(JCTree t) { 1272 return metaValueIndex(t) > -1; 1273 } 1274 void addGuard(String t, long v, int k) { 1275 for(Guard g = head; g!=null; g = g.ifSucceed) 1276 if(g.test.equals(t) && g.value==v && g.kind==k) 1277 return; Guard n = new Guard(t, v, k); 1279 if(head==null) head = n; 1280 else tail.ifSucceed = n; 1281 tail = n; 1282 } 1283 void addBoolean(String s) { 1284 addGuard(s, 0, Guard.BOOLEAN); 1285 } 1286 void addLoop(String val, int mv) { 1287 addGuard(val, mv, Guard.LOOP); 1288 } 1289 void addInt(String s, long v) { 1290 addGuard(s, v, Guard.INT); 1291 } 1292 static final String pfx = "com.sun.tools.javac.tree.JCTree."; 1293 static final int pfxl = pfx.length(); 1294 void addDeclaration(String type, String vname, String value) { 1295 if(type.startsWith(pfx)) type = type.substring(pfxl); 1296 addGuard(type+" "+vname+" = ("+type+") ("+value+")", 0, Guard.DECLARATION); 1297 } 1298 void addReplacement(Rule r) { 1299 Guard n = new Replacement(r, metaslot, metakeys, metavalues, isName, isList); 1300 if(head==null) head = n; 1301 else tail.ifSucceed = n; 1302 tail = n; 1303 } 1304 private <T extends JCTree> void genMatch(String prefix, List<T> t) throws IOException { 1305 genMatch(prefix, t, false); 1306 } 1307 private <T extends JCTree> void genMatch(String prefix, List<T> t, boolean mightBeNull) throws IOException { 1308 if(t==null) { 1309 addBoolean(prefix+"==null || "+prefix+".isEmpty()"); 1310 return; 1311 } 1312 if(mightBeNull) addBoolean(prefix+"!=null"); 1313 for( ; t.nonEmpty(); t = t.tail) { 1314 JCTree head = deblock(t.head); 1315 if(head.tag==JCTree.IDENT) { 1316 Name idname = ((JCIdent)head).name; 1317 MetaKind meta = metaKind(idname); 1318 if(meta == MetaKind.LIST) { 1319 for(int i = metaslot; --i>=0; ) 1320 if(idname==metakeys[i]) { 1321 if(isList[i]==0) 1322 addBoolean("matches("+metavalues[i]+","+prefix+")"); 1323 else 1324 addBoolean("matches("+metavalues[i]+","+prefix+",len_"+i+")"); 1325 return; 1326 } 1327 metakeys[metaslot]=idname; 1328 isList[metaslot]=0; 1329 metavalues[metaslot] = prefix; 1330 if(t.tail.isEmpty()) { 1331 metaslot++; 1332 return; 1333 } 1334 isList[metaslot]=1; 1335 addLoop(metavalues[metaslot],metaslot); 1336 prefix = "p_"+metaslot; 1337 metaslot++; 1338 continue; 1339 } 1340 } 1341 addBoolean(prefix+".nonEmpty()"); 1342 genMatch(prefix+".head", head); 1343 prefix = prefix+".tail"; 1344 } 1345 addBoolean(prefix+".isEmpty()"); 1346 } 1347 private void genMatch(String prefix, Name n) throws IOException { 1348 if(n==null) addBoolean(prefix+"==null"); 1349 else addBoolean(prefix+"=="+nameConst(n)); 1350 } 1351 private void genMatch(String prefix, long v) { 1352 addInt(prefix,v); 1353 } 1354 private void genMatch(String prefix, JCTree t) throws IOException { 1355 genMatch(prefix, t, false); 1356 } 1357 enum MetaKind { 1358 NONE, 1360 VARIABLE, 1362 LIST 1364 }; 1365 private static MetaKind metaKind(Name n) { 1366 if (n != null && n.len > 1) { 1367 byte[] names = n.table.names; 1368 if (names[n.index] == '$') 1369 return (n.len > 2 && names[n.index+n.len-1] == '$') ? 1370 MetaKind.LIST : MetaKind.VARIABLE; 1371 } 1372 return MetaKind.NONE; 1373 } 1374 private boolean metavar(Name idname,String prefix, boolean nameContext) { 1375 if(metaKind(idname) != MetaKind.NONE) { 1376 for(int i = metaslot; --i>=0; ) 1377 if(idname==metakeys[i]) { 1378 addBoolean("matches("+metavalues[i]+","+prefix+")"); 1379 return true; 1380 } 1381 metakeys[metaslot]=idname; 1382 isName[metaslot]=nameContext; 1383 isList[metaslot]=-1; 1384 metavalues[metaslot++] = prefix; 1385 return true; 1386 } 1387 return false; 1388 } 1389 private boolean containsMeta(JCTree t) { 1390 while(t!=null) 1391 switch(t.tag) { 1392 default: return false; 1393 case JCTree.IDENT: return metaKind(((JCIdent)t).name) != MetaKind.NONE; 1394 case JCTree.SELECT: t = ((JCFieldAccess)t).selected; continue; 1395 case JCTree.TYPEAPPLY: return containsMeta(((JCTypeApply)t).clazz); 1396 case JCTree.APPLY: t = ((JCMethodInvocation)t).meth; continue; 1397 } 1398 return false; 1399 } 1400 private void genMatch(String prefix, JCTree t, boolean couldBeNull) throws IOException { 1401 t = deblock(t); 1402 if(t==null) { 1403 addBoolean("isEmpty("+prefix+")"); 1404 return; 1405 } 1406 switch(t.tag) { 1407 case JCTree.IDENT: 1408 Name idname = ((JCIdent)t).name; 1409 if(idname==trueName) { 1410 addBoolean("isTrue("+prefix+")"); 1411 return; 1412 } 1413 if(idname==falseName) { 1414 addBoolean("isFalse("+prefix+")"); 1415 return; 1416 } 1417 if(idname==nullName) { 1418 addBoolean("isNull("+prefix+")"); 1419 return; 1420 } 1421 if(metavar(idname, prefix, false)) { 1422 if (couldBeNull) addBoolean("!isEmpty("+prefix+")"); 1424 return; 1425 } 1426 break; 1427 case JCTree.SKIP: 1428 addBoolean("isEmpty("+prefix+")"); 1429 return; 1430 } 1431 String tname0 = "T"+ ++tempslot; 1432 addDeclaration("JCTree", tname0, "deblock("+prefix+")"); 1433 prefix = tname0; 1434 if(couldBeNull) addBoolean(prefix+"!=null"); 1435 addInt(prefix+".tag", t.tag); 1436 String cname = t.getClass().getName().replace('$','.'); 1437 String tname = "T"+ ++tempslot; 1438 addDeclaration(cname,tname,prefix); 1439 int tag = t.tag; 1440 switch(tag) { 1441 default: 1442 if(tag>=JCTree.BITOR_ASG) { 1443 genMatch(tname+".lhs", ((JCAssignOp)t).lhs); 1444 genMatch(tname+".rhs", ((JCAssignOp)t).rhs); 1445 } else if(tag>=JCTree.OR) { 1446 genMatch(tname+".lhs", ((JCBinary)t).lhs); 1447 genMatch(tname+".rhs", ((JCBinary)t).rhs); 1448 } else if(tag>=JCTree.POS) 1449 genMatch(tname+".arg", ((JCUnary)t).arg); 1450 else logError(t.pos, "no.matcher", t.getClass(), t); 1451 break; 1452 case JCTree.BLOCK: 1453 genMatch(tname+".stats", ((JCBlock)t).stats); 1454 break; 1455 case JCTree.ASSIGN: 1456 genMatch(tname+".lhs", ((JCAssign)t).lhs); 1457 genMatch(tname+".rhs", ((JCAssign)t).rhs); 1458 break; 1459 case JCTree.NEWCLASS: { 1460 JCNewClass nc = (JCNewClass) t; 1461 JCTree clazz = nc.clazz; 1462 if(containsMeta(clazz)) genMatch(tname+".clazz", clazz); 1463 else addBoolean("isInstance("+tname+".clazz, " 1464 + classSymConst(TreeInfo.fullName(clazz))+")"); 1465 genMatch(tname+".args", nc.args); 1466 } 1467 break; 1468 case JCTree.NEWARRAY: { 1469 JCNewArray na = (JCNewArray) t; 1470 JCTree clazz = na.elemtype; 1471 if(containsMeta(clazz)) genMatch(tname+".elemtype", clazz); 1472 else if (na.elemtype instanceof JCPrimitiveTypeTree) 1473 addBoolean("(" + tname + ".elemtype instanceof JCPrimitiveTypeTree) && ((JCPrimitiveTypeTree)" + 1474 tname + ".elemtype).typetag == " + ((JCPrimitiveTypeTree)na.elemtype).typetag); 1475 else addBoolean("isInstance("+tname+".elemtype, " 1476 + classSymConst(TreeInfo.fullName(clazz))+")"); 1477 genMatch(tname+".dims", na.dims); 1478 genMatch(tname+".elems", na.elems, true); 1479 } 1480 break; 1481 case JCTree.TYPECAST: 1482 genMatch(tname+".clazz", ((JCTypeCast)t).clazz); 1483 genMatch(tname+".expr", ((JCTypeCast)t).expr); 1484 break; 1485 case JCTree.VARDEF: 1486 { JCVariableDecl vd = (JCVariableDecl) t; 1487 metavar(vd.name, tname+".name", true); 1489 if(containsMeta(vd.vartype)) genMatch(tname+".vartype", vd.vartype); 1490 else if (vd.vartype instanceof JCPrimitiveTypeTree) 1491 addBoolean("(" + tname + ".vartype instanceof JCPrimitiveTypeTree) && ((JCPrimitiveTypeTree)" + 1492 tname + ".vartype).typetag == " + ((JCPrimitiveTypeTree)vd.vartype).typetag); 1493 else addBoolean("isInstance("+tname+".vartype, " 1494 + classSymConst(TreeInfo.fullName(vd.vartype))+")"); 1495 genMatch(tname+".init", vd.init, true); 1496 } 1497 break; 1498 case JCTree.INDEXED: 1499 genMatch(tname+".indexed", ((JCArrayAccess)t).indexed); 1500 genMatch(tname+".index", ((JCArrayAccess)t).index); 1501 break; 1502 case JCTree.SELECT: 1503 { 1504 JCFieldAccess sel = (JCFieldAccess) t; 1505 String selid = tname+".name"; 1506 if (containsMeta(sel)){ 1507 genMatch(tname+".selected", sel.selected); 1508 if(!metavar(sel.name, selid, true)) 1509 genMatch(selid, sel.name); 1510 } 1511 else 1512 addBoolean("idMatches(" + tname + ", " + nameConst(TreeInfo.fullName(sel)) + ")"); 1513 } 1514 break; 1515 case JCTree.TYPETEST: 1516 genMatch(tname+".clazz", ((JCInstanceOf)t).clazz); 1517 genMatch(tname+".expr", ((JCInstanceOf)t).expr); 1518 break; 1519 case JCTree.RETURN: 1520 genMatch(tname+".expr", ((JCReturn)t).expr, true); 1521 break; 1522 case JCTree.CONDEXPR: 1523 genMatch(tname+".cond", ((JCConditional)t).cond); 1524 genMatch(tname+".truepart", ((JCConditional)t).truepart); 1525 genMatch(tname+".falsepart", ((JCConditional)t).falsepart); 1526 break; 1527 case JCTree.IF: 1528 genMatch(tname+".cond", ((JCIf)t).cond); 1529 genMatch(tname+".thenpart", ((JCIf)t).thenpart, true); 1530 genMatch(tname+".elsepart", ((JCIf)t).elsepart, true); 1531 break; 1532 case JCTree.DOLOOP: 1533 genMatch(tname+".cond", ((JCDoWhileLoop)t).cond); 1534 genMatch(tname+".body", ((JCDoWhileLoop)t).body, true); 1535 break; 1536 case JCTree.WHILELOOP: 1537 genMatch(tname+".cond", ((JCWhileLoop)t).cond); 1538 genMatch(tname+".body", ((JCWhileLoop)t).body, true); 1539 break; 1540 case JCTree.FORLOOP: 1541 genMatch(tname+".init", ((JCForLoop)t).init); 1542 genMatch(tname+".cond", ((JCForLoop)t).cond, true); 1543 genMatch(tname+".step", ((JCForLoop)t).step); 1544 genMatch(tname+".body", ((JCForLoop)t).body, true); 1545 break; 1546 case JCTree.LABELLED: 1547 genMatch(tname+".label", ((JCLabeledStatement)t).label); 1548 genMatch(tname+".body", ((JCLabeledStatement)t).body, true); 1549 break; 1550 case JCTree.SWITCH: 1551 genMatch(tname+".selector", ((JCSwitch)t).selector); 1552 genMatch(tname+".cases", ((JCSwitch)t).cases); 1553 break; 1554 case JCTree.CASE: 1555 genMatch(tname+".pat", ((JCCase)t).pat); 1556 genMatch(tname+".stats", ((JCCase)t).stats); 1557 break; 1558 case JCTree.SYNCHRONIZED: 1559 genMatch(tname+".lock", ((JCSynchronized)t).lock); 1560 genMatch(tname+".body", ((JCSynchronized)t).body, true); 1561 break; 1562 case JCTree.TRY: 1563 genMatch(tname+".body", ((JCTry)t).body, true); 1564 genMatch(tname+".catchers", ((JCTry)t).catchers); 1565 genMatch(tname+".finalizer", ((JCTry)t).finalizer, true); 1566 break; 1567 case JCTree.CATCH: 1568 genMatch(tname+".param", ((JCCatch)t).param); 1569 genMatch(tname+".body", ((JCCatch)t).body, true); 1570 break; 1571 case JCTree.APPLY: 1572 genMatch(tname+".meth", ((JCMethodInvocation)t).meth); 1573 genMatch(tname+".args", ((JCMethodInvocation)t).args); 1574 break; 1575 case JCTree.BREAK: 1576 genMatch(tname+".label", ((JCBreak)t).label); 1577 break; 1578 case JCTree.CONTINUE: 1579 genMatch(tname+".label", ((JCContinue)t).label); 1580 break; 1581 case JCTree.THROW: 1582 genMatch(tname+".expr", ((JCThrow)t).expr, true); 1583 break; 1584 case JCTree.ASSERT: 1585 genMatch(tname+".cond", ((JCAssert)t).cond, true); 1586 genMatch(tname+".detail", ((JCAssert)t).detail, true); 1587 break; 1588 case JCTree.TYPEAPPLY: 1589 genMatch(tname+".clazz", ((JCTypeApply)t).clazz, false); 1590 genMatch(tname+".arguments", ((JCTypeApply)t).arguments); 1591 break; 1592 case JCTree.IDENT: 1593 addBoolean(tname+".name=="+nameConst(((JCIdent)t).name)); 1594 break; 1595 case JCTree.LITERAL: 1596 JCLiteral lit = (JCLiteral)t; 1597 Object v = lit.value; 1598 Kind kind = lit.getKind(); 1599 if (kind == Kind.NULL_LITERAL) { addBoolean(tname + ".value==null"); 1601 } else { 1602 addBoolean(tname + ".getKind() == Kind." + kind); 1603 String subname = "O"+tname; 1604 String subtype = v.getClass().getName(); 1605 if(subtype.startsWith("java.lang.")) subtype = subtype.substring(10); 1606 addDeclaration("Object", subname, tname+".value"); 1607 if(kind == Kind.INT_LITERAL) 1608 addInt("(("+subtype+")"+subname+").intValue()",((Integer )v).intValue()); 1609 else { 1610 String test; 1611 if(lit.getKind() == Kind.STRING_LITERAL) 1612 test = "equals(\""+quoteString(v.toString())+"\")"; 1613 else if (lit.getKind() == Kind.BOOLEAN_LITERAL) { 1614 if (v instanceof Integer ) test = "intValue() == " + ((Integer )v).intValue(); 1616 else 1617 test = "booleanValue() == " + ((Boolean )v).booleanValue(); 1618 } 1619 else test = "Missing("+v.getClass().getName()+")"; 1620 addBoolean("(("+subtype+")"+subname+")."+test); 1621 } 1622 } 1623 break; 1624 } 1625 } 1626 public static String quoteString(String s) { 1627 if(s.indexOf('"')<0 && s.indexOf('\\')<0 && s.indexOf('\n')<0) return s; 1628 StringBuffer sb = new StringBuffer (); 1629 int limit = s.length(); 1630 for(int i = 0; i<limit; i++) { 1631 char c = s.charAt(i); 1632 switch(c) { 1633 case '"': 1634 case '\\': 1635 sb.append('\\'); 1636 break; 1637 case '\n': 1638 sb.append("\\n"); 1639 continue; 1640 } 1641 sb.append(c); 1642 } 1643 return sb.toString(); 1644 } 1645 private static class Factory extends Parser.Factory { 1646 public static Factory instance(Context context) { 1647 Factory instance = (Factory)context.get(parserFactoryKey); 1648 if (instance == null) 1649 instance = new Factory(context); 1650 return instance; 1651 } 1652 protected Factory(Context context) { 1653 super(context); 1654 } 1655 public Parser newParser(final Scanner S, final TransformParser tp) { 1656 return new Parser(this, S, false) { 1657 protected JCExpression checkExprStat(JCExpression t) { return t; 1659 } 1660 public void accept(Token token) { if(token!=SEMI || (!tp.isToken(tp.impliesToken) && !tp.isToken(tp.suchthatToken) && !tp.isToken(tp.doSomethingToken))) 1662 super.accept(token); 1663 } 1664 public Name ident() { if (S.token() == IDENTIFIER || S.token() == ASSERT) { 1666 Name name = S.name(); 1667 S.nextToken(); 1668 return name; 1669 } else { 1670 accept(IDENTIFIER); 1671 return tp.names.error; 1672 } 1673 } 1674 }; 1675 } 1676 } 1677 public Parser makeParser() { 1678 return Factory.instance(context).newParser(scanner, this); 1679 } 1680 Guard optimize(Guard g) { 1681 if(g==null || g.kind==Guard.REPLACEMENT) return g; 1682 Guard f0 = g.ifFail; 1683 Guard f = optimize(f0); 1684 if(f!=null && g.sameTest(f) && g.ifSucceed.ifFail==null) { 1685 1686 g.ifSucceed.ifFail = f.ifSucceed; 1687 g.ifSucceed = optimize(g.ifSucceed); 1688 g.ifFail = f = f.ifFail; 1689 } else g.ifFail = f; 1690 if(f!=null && g.kind==Guard.INT && f.kind==Guard.INT && g.test.equals(f.test) && g.value>f.value) { 1691 1694 g.ifFail = f.ifFail; 1695 f.ifFail = g; 1696 return optimize(f); 1697 } else if(f != f0) return optimize(g); 1698 else return g; 1699 } 1700 public String stringIfy(List<? extends JCTree> t) { 1701 if(t==null||t.isEmpty()) return ""; 1702 return t.tail.isEmpty() ? stringIfy(t.head) : stringIfy(t.head)+stringIfy(t.tail); 1703 } 1704 public String stringIfy(JCTree t) { 1705 if(t==null) return ""; 1706 else if(t instanceof JCLiteral) return String.valueOf(((JCLiteral)t).value); 1707 else if(t instanceof JCIdent) return ((JCIdent)t).name.toString(); 1708 else return t.toString(); 1709 } 1710 private class Guard { 1711 static final int INT = 0; 1712 static final int BOOLEAN = 1; 1713 static final int LOOP = 2; 1714 static final int DECLARATION = 3; 1715 static final int REPLACEMENT = 4; 1716 Guard ifSucceed; 1717 Guard ifFail; 1718 final String test; 1719 final long value; 1720 final int kind; 1721 Guard(String t, long v, int k) { 1722 test = t; 1723 value = v; 1724 kind = k; 1725 } 1726 boolean sameTest(Guard g) { 1727 return g.kind==kind && (test==null ? g.test==null : test.equals(g.test)) && value==g.value; 1728 } 1729 boolean canFlowOut() { 1730 return kind<=LOOP || 1731 kind==DECLARATION && ifSucceed!=null && ifSucceed.canFlowOut(); 1732 } 1733 void writeAll(PluginCompiler pc, int gdepth) throws IOException { 1734 if(ifFail==null) { 1735 writeWrapped(pc,gdepth); 1736 } else if(kind==INT && ifFail!=null && ifFail.kind==INT && test.equals(ifFail.test)) { 1739 pc.write("\tswitch("); 1741 pc.write(test); 1742 pc.write(") {\n"); 1743 long lastsw = value-1; 1744 Guard c = this; 1745 boolean reachable = false; 1746 while(c!=null && c.kind==INT && test.equals(c.test)) { 1747 if(c.value != lastsw) { 1748 if(reachable) pc.write("\t\tbreak;\n"); 1749 pc.write("\t case "); 1750 pc.write(lastsw = c.value); 1751 pc.write(":\n"); 1752 } 1753 c.ifSucceed.writeWrapped(pc, gdepth+1); 1754 reachable = c.ifSucceed.canFlowOut() || c.ifSucceed.kind==LOOP; 1755 c = c.ifFail; 1756 } 1757 pc.write("\t} //end switch\n"); 1758 if(c!=null) c.writeAll(pc, gdepth); 1759 } else writeWrapped(pc, gdepth); 1760 } 1761 void writeWrapped(PluginCompiler pc, int gdepth) throws IOException { 1762 if(kind==LOOP) { 1763 pc.write("\t\t{ int len_"+value+"=0;\n\t\tfor(List<JCStatement> p_"+value+" = "+test+"; p_" 1764 +value+".nonEmpty(); p_"+value+" = p_"+value+".tail, len_"+value+"++) {\n"); 1765 ifSucceed.writeWrapped(pc, gdepth+1); 1766 pc.write("\t\t} }\n"); 1770 } else { 1771 pc.write("\t test"); 1772 pc.write(gdepth+1); 1773 pc.write(": {\n"); 1774 write(pc, gdepth+1); 1775 if(ifSucceed!=null) ifSucceed.writeAll(pc,gdepth+1); 1776 pc.write("\t }\n"); 1777 } 1778 if(ifFail!=null) ifFail.writeAll(pc,gdepth); 1779 } 1780 void write(PluginCompiler pc,int gdepth) throws IOException { 1781 switch(kind) { 1782 default: 1783 pc.write("BOGUS "+kind+": "+test); 1784 break; 1785 case DECLARATION: 1786 if(test==null || test.length()<=0) return; 1787 pc.write("\t\t"); 1788 pc.write(test); 1789 break; 1790 case BOOLEAN: 1791 if(gdepth>debugDepth) { 1792 pc.write("\t\tif(!("); 1793 pc.write(test); 1794 pc.write(")) System.err.println(\""+ debugTag++ +": Failed: \"+"); 1795 pc.writeQuoted(test); 1796 if(test.startsWith("isFalse")) 1797 pc.write("+\": \"+"+test.substring(7)+"+\" @\"+"+test.substring(7)+".tag"); 1798 pc.write(");\n"); 1799 } 1800 pc.write("\t\tif(!("); 1801 pc.write(test); 1802 pc.write(")) break test"); 1803 pc.write(gdepth); 1804 break; 1805 case INT: 1806 if(gdepth>debugDepth) { 1807 pc.write("\t\tif("); 1808 pc.write(test); 1809 pc.write("!="); 1810 pc.write(value); 1811 pc.write(") System.err.println(\""+ debugTag++ +": Failed: \"+"); 1812 pc.writeQuoted(test); 1813 pc.write("+\" Wanted: "+value+" Got: \"+"+test); 1814 pc.write(");\n"); 1815 } 1816 pc.write("\t\tif("); 1817 pc.write(test); 1818 pc.write("!="); 1819 pc.write(value); 1820 pc.write(") break test"); 1821 pc.write(gdepth); 1822 break; 1823 } 1824 pc.write(";\n"); 1825 } 1826 } 1827 final int debugDepth = 999; 1828 final Name parentName = names.fromString("parent"); 1829 final Name assignedInName = names.fromString("assignedIn"); 1830 final Name declaredInName = names.fromString("declaredIn"); 1831 final Name noteName = names.fromString("note"); 1832 final Name commentName = names.fromString("comment"); 1833 final Name inlineName = names.fromString("inline"); 1834 final Name mapclassName = names.fromString("mapclass"); 1835 final Name statementcontextName = names.fromString("statementcontext"); 1836 final Name translationFailureName = names.fromString("translationFailure"); 1837 class Replacement extends Guard { 1838 final Rule rule; 1839 final Name[] metavars; 1840 final String [] metavals; 1841 final boolean[] isName; 1842 final int[] isList; 1843 Replacement(Rule r, int nmeta, Name[] vars, String [] vals, boolean isn[], int[] isl) { 1844 super(null, 0, DECLARATION); 1845 rule = r; 1846 metavars = new Name[nmeta]; 1847 metavals = new String [nmeta]; 1848 isName = new boolean[nmeta]; 1849 isList = new int[nmeta]; 1850 System.arraycopy(vars,0,metavars,0,nmeta); 1851 System.arraycopy(vals,0,metavals,0,nmeta); 1852 System.arraycopy(isn,0,isName,0,nmeta); 1853 System.arraycopy(isl,0,isList,0,nmeta); 1854 } 1855 boolean sameTest(Guard g) { 1856 return false; 1857 } 1858 void writeAll(PluginCompiler pc, int gdepth) throws IOException { 1859 write(pc, gdepth); 1860 if(ifFail!=null) 1861 logError(rule.pattern.pos, "pattern.hides.followers", rule.pattern); 1862 } 1863 void write(PluginCompiler pc, int gdepth) throws IOException { 1864 pc.write("\t\tcomment = "); 1865 String rString = rule.toString(); 1866 pc.writeQuoted(rString); 1867 pc.write(";\n\t\tcurrentLine = " + rule.startLine); 1868 pc.write(";\n\t\t"); 1869 JCTree replacement = rule.replacement; 1870 if(replacement!=null) { 1871 JCMethodInvocation a = null; 1872 if(replacement.tag==JCTree.APPLY) 1873 a = (JCMethodInvocation) replacement; 1874 else if(replacement.tag==JCTree.EXEC) { 1875 JCTree t = deblock(replacement); 1876 if (t.tag == JCTree.APPLY) 1877 a = (JCMethodInvocation) t; 1878 } 1879 if (a != null) { 1880 if(a.meth.tag==JCTree.IDENT) { 1881 Name nm = ((JCIdent)a.meth).name; 1882 if(nm==noteName) { 1883 pc.write("addResult(rewriter.currentSym, t, "); 1884 pc.writeQuoted(stringIfy(a.args)); 1885 pc.write(");\n\t\treturn t;\n"); 1886 return; 1887 } else if(nm==commentName) { 1888 String comment = stringIfy(a.args); 1889 pc.write("addResult(rewriter.currentSym, t, "); 1890 pc.writeQuoted(comment); 1891 pc.write(");\n\t\tattach(containingStatement(), "); 1892 pc.writeQuoted(comment); 1893 pc.write(");\n\t\treturn t;\n"); 1894 return; 1895 } else if(nm==translationFailureName) { 1896 pc.write("translationFailure("); 1897 pc.writeQuoted(stringIfy(a.args)); 1898 pc.write(");\n"); 1899 return; 1900 } 1901 } 1902 } 1903 } 1904 pc.write("{ " + returnType() + " result = "); 1905 if(replacement!=null) { 1906 constructor.metavars = metavars; 1907 constructor.metavals = metavals; 1908 constructor.isName = isName; 1909 constructor.isList = isList; 1910 constructor.pc = pc; 1911 constructor.generate(replacement); 1912 } else pc.write("t"); 1913 pc.write(";\n"); 1914 if(rule.code!=null) { 1915 coder.metavars = metavars; 1916 coder.metavals = metavals; 1917 coder.isList = isList; 1918 coder.pc = pc; 1919 coder.generate(rule.code); 1920 } 1921 pc.write("\t\treturn result; }\n"); 1922 } 1923 } 1924 private int debugTag = 0; 1925 final private HashMap <String ,String > classMap = new HashMap <String ,String >(); 1926 public String classRef(String jar, String clazz) { 1927 if(jar==null) jar = ""; 1928 if("org.netbeans.api.java.source.query.Query".equals(clazz)) return "this"; 1929 if("org.netbeans.api.java.source.transform.Transformer".equals(clazz)) return "this"; 1930 String key = jar+':'+clazz; 1931 String v = classMap.get(key); 1932 if(v == null) { 1933 v = "preloadedClass_"+classMap.size(); 1934 classMap.put(key,v); 1935 } 1936 return v; 1937 } 1938 private static final HashMap <String ,Method> methodRegistry = new HashMap <String ,Method>(); 1939 1940 public static synchronized void registerBoolean(String jar, String clazz, String method) { 1941 methodRegistry.put(method, new BooleanMethod(jar,clazz,method)); 1942 } 1943 public static synchronized void registerBSym(String jar, String clazz, String method) { 1944 methodRegistry.put(method, new BSymMethod(jar,clazz,method)); 1945 } 1946 static { 1947 registerBoolean("", "org.netbeans.api.java.source.query.Query", "hasComment"); 1948 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isConstant"); 1949 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isClassIdentifier"); 1950 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isEmpty"); 1951 registerBoolean("", "org.netbeans.api.java.source.query.Query", "sideEffectFree"); 1952 registerBoolean("", "org.netbeans.api.java.source.query.Query", "hasVariableDeclarations"); 1953 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isStatement"); 1954 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isTrue"); 1955 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isFalse"); 1956 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isNull"); 1957 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isNullTree"); 1958 registerBoolean("", "org.netbeans.api.java.source.query.Query", "isStatic"); 1959 registerBoolean("", "org.netbeans.api.java.source.query.Query", "couldThrow"); 1960 registerBoolean("", "org.netbeans.api.java.source.query.Query", "sourceLevel"); 1961 registerBSym("", "org.netbeans.api.java.source.query.Query", "referenced"); 1962 registerBSym("", "org.netbeans.api.java.source.query.Query", "assigned"); 1963 registerBSym("", "org.netbeans.api.java.source.query.Query", "parameter"); 1964 registerBSym("", "org.netbeans.api.java.source.query.Query", "local"); 1965 } 1966 1967 abstract static class Method { 1968 String jar; 1969 String clazz; 1970 String method; 1971 Method(String j, String c, String m) { 1972 jar = j; clazz = c; method = m; 1973 } 1974 abstract String genInvoke(TransformParser tp, String arg); 1975 } 1976 static class BooleanMethod extends Method { 1977 BooleanMethod(String j, String c, String m) { super(j,c,m); } 1978 String genInvoke(TransformParser tp, String arg) { 1979 return tp.classRef(jar,clazz)+"."+method+"("+arg+")"; 1980 } 1981 } 1982 static class BSymMethod extends BooleanMethod { 1983 BSymMethod(String j, String c, String m) { super(j,c,m); } 1984 String genInvoke(TransformParser tp, String arg) { 1985 return super.genInvoke(tp, arg.endsWith(".name") 1986 ? arg.substring(0,arg.length()-5)+".sym" : arg); 1987 } 1988 } 1989} 1990 | Popular Tags |