KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > source > script > TransformParser


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

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 JavaDoc;
36 import java.util.Arrays JavaDoc;
37 import java.util.Collection JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.Iterator JavaDoc;
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 JavaDoc<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 JavaDoc fileName;
54     String JavaDoc javacpath;
55     String JavaDoc queryDescription;
56     String JavaDoc transformDescription;
57     long fileLastModified;
58     protected Position.LineMap lineMap;
59     protected final ASTModel model;
60
61     public TransformParser(Reader in, String JavaDoc javacpath) {
62         this("Rules", "Rules", null, in, 0L, javacpath);
63     }
64     public TransformParser(String JavaDoc path, String JavaDoc queryName, String JavaDoc transformName,
65             Reader in, long lastModified, String JavaDoc 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 JavaDoc<Name,String JavaDoc>();
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); // register subclass in context
90
return ctx;
91     }
92
93     protected String JavaDoc returnTypeDecl() { return "JCTree"; }
94     protected String JavaDoc returnType() { return "JCTree"; }
95     protected String JavaDoc returnTypeImport() { return "\n"; }
96     protected String JavaDoc baseType() { return "GeneratedMatcher"; }
97     protected String JavaDoc failureReturn() { return "t"; }
98     protected String JavaDoc scriptTitle(String JavaDoc filename) {
99         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("{ 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             // skip to next rule on error
131
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 JavaDoc key, Object JavaDoc... args) {
223     String JavaDoc format = NbBundle.getBundle(TransformParser.class).getString("TransformParser." + key);
224     String JavaDoc 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 JavaDoc 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     /** allows subclass to shove code into the generated class */
245     protected String JavaDoc 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 JavaDoc 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 JavaDoc[] metavalues = new String JavaDoc[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 JavaDoc listType) {
354         generate(t,statements,listType);
355     }
356     public <T extends JCTree> void generate(List<T> t, boolean statements, String JavaDoc 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 JavaDoc[] 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 JavaDoc)
806             pc.writeQuoted((String JavaDoc)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 JavaDoc<JCTree,JCTree> mapClass = new HashMap JavaDoc<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 JavaDoc<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 JavaDoc<Name,String JavaDoc> nameConstMap;
902     String JavaDoc nameConst(Name n) {
903     if(n==null) return "null";
904     String JavaDoc 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 JavaDoc<Name,String JavaDoc> classSymConstMap = new HashMap JavaDoc<Name,String JavaDoc>();
913     String JavaDoc classSymConst(Name n) {
914     if(n==null) return "null";
915     String JavaDoc 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 JavaDoc<Object JavaDoc,String JavaDoc> litNameMap = new HashMap JavaDoc<Object JavaDoc,String JavaDoc>();
925     private int litIndex = 1;
926     String JavaDoc litName(Object JavaDoc o) {
927     if(o==null) return "null";
928     String JavaDoc 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 JavaDoc<Name> in = nameConstMap.keySet().iterator(); in.hasNext(); ) {
939         Name n = in.next();
940         String JavaDoc 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 JavaDoc<String JavaDoc> in = classMap.keySet().iterator(); in.hasNext(); ) {
948         pc.write(" private ");
949         String JavaDoc key = in.next();
950         String JavaDoc var = classMap.get(key);
951         int sep = key.indexOf(':');
952         assert(sep>=0);
953         String JavaDoc jar = key.substring(0,sep);
954         String JavaDoc 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 JavaDoc<Name> in = classSymConstMap.keySet().iterator(); in.hasNext(); ) {
967         Name n = in.next();
968         String JavaDoc s = classSymConstMap.get(n);
969         pc.write(" private Symbol.ClassSymbol ");
970         pc.write(s);
971         pc.write(";\n");
972     }
973     for(Iterator JavaDoc<Object JavaDoc> io = litNameMap.keySet().iterator(); io.hasNext(); ) {
974         Object JavaDoc 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 JavaDoc<Name> in = nameConstMap.keySet().iterator(); in.hasNext(); ) {
985         Name n = in.next();
986         String JavaDoc 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 JavaDoc<Name> in = classSymConstMap.keySet().iterator(); in.hasNext(); ) {
997         Name n = in.next();
998         String JavaDoc 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 JavaDoc genSuchThatTerm(JCTree t,boolean invert) {
1044    String JavaDoc 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: // instanceof
1060
{
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                    // tt.expr and tt.clazz
1067
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 JavaDoc genKnown(JCTree t, boolean invert) {
1114    return (invert ? "!(" : "(") + isKnown(t) +
1115        knownValue(t)+"==Boolean.TRUE)";
1116    }
1117    private String JavaDoc 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 JavaDoc 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 JavaDoc[] funcNames = new String JavaDoc[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 JavaDoc 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 JavaDoc o = ((JCLiteral)t).value;
1173        if(o instanceof String JavaDoc) {
1174        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1175        String JavaDoc 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 JavaDoc {
1206    public ArgError(String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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; // eliminate duplicate
1278
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 JavaDoc s) {
1284    addGuard(s, 0, Guard.BOOLEAN);
1285    }
1286    void addLoop(String JavaDoc val, int mv) {
1287    addGuard(val, mv, Guard.LOOP);
1288    }
1289    void addInt(String JavaDoc s, long v) {
1290    addGuard(s, v, Guard.INT);
1291    }
1292    static final String JavaDoc pfx = "com.sun.tools.javac.tree.JCTree.";
1293    static final int pfxl = pfx.length();
1294    void addDeclaration(String JavaDoc type, String JavaDoc vname, String JavaDoc 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 JavaDoc prefix, List<T> t) throws IOException {
1305    genMatch(prefix, t, false);
1306    }
1307    private <T extends JCTree> void genMatch(String JavaDoc 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 JavaDoc prefix, Name n) throws IOException {
1348    if(n==null) addBoolean(prefix+"==null");
1349    else addBoolean(prefix+"=="+nameConst(n));
1350    }
1351    private void genMatch(String JavaDoc prefix, long v) {
1352    addInt(prefix,v);
1353    }
1354    private void genMatch(String JavaDoc prefix, JCTree t) throws IOException {
1355    genMatch(prefix, t, false);
1356    }
1357    enum MetaKind {
1358        // Normal identifier
1359
NONE,
1360        // Metavariable, such as $n
1361
VARIABLE,
1362        // Metalist, such as $list$
1363
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 JavaDoc 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 JavaDoc 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) // it could be null but wasn't (first test), so verify it's not
1423
addBoolean("!isEmpty("+prefix+")");
1424                return;
1425            }
1426        break;
1427    case JCTree.SKIP:
1428        addBoolean("isEmpty("+prefix+")");
1429        return;
1430    }
1431    String JavaDoc 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 JavaDoc cname = t.getClass().getName().replace('$','.');
1437    String JavaDoc 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                //FIXME genMatch(tname+".mods", vd.mods);
1488
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 JavaDoc 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 JavaDoc v = lit.value;
1598            Kind kind = lit.getKind();
1599            if (kind == Kind.NULL_LITERAL) { // true for the null keyword as of Mustang b80
1600
addBoolean(tname + ".value==null");
1601            } else {
1602                addBoolean(tname + ".getKind() == Kind." + kind);
1603                String JavaDoc subname = "O"+tname;
1604                String JavaDoc 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 JavaDoc)v).intValue());
1609                else {
1610                    String JavaDoc 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 JavaDoc) // true for b78-b85
1615
test = "intValue() == " + ((Integer JavaDoc)v).intValue();
1616                        else
1617                            test = "booleanValue() == " + ((Boolean JavaDoc)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 JavaDoc quoteString(String JavaDoc s) {
1627    if(s.indexOf('"')<0 && s.indexOf('\\')<0 && s.indexOf('\n')<0) return s;
1628    StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
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) { // be more forgiving
1658
return t;
1659        }
1660        public void accept(Token token) { //allow statements to be ended by =>
1661
if(token!=SEMI || (!tp.isToken(tp.impliesToken) && !tp.isToken(tp.suchthatToken) && !tp.isToken(tp.doSomethingToken)))
1662            super.accept(token);
1663        }
1664        public Name ident() { // allow asserts as identifiers
1665
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        /* ooooh! a redundant guard that can be eliminated! */
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        /* Interchange this guard with the fail successor if they're both integer tests on the
1692           same field but are out-of-order. This in combination with the recursive optimize calls
1693           that follow implement a bubble sort. This is for eventual generation as a switch statement. */

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 JavaDoc 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 JavaDoc 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 JavaDoc test;
1719    final long value;
1720    final int kind;
1721    Guard(String JavaDoc 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        // write(pc, gdepth);
1737
// if(ifSucceed!=null) ifSucceed.writeAll(pc,gdepth);
1738
} else if(kind==INT && ifFail!=null && ifFail.kind==INT && test.equals(ifFail.test)) {
1739        // Yahoo! Generate switch statement
1740
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\tbreak test");
1767
//pc.write(gdepth);
1768
//pc.write(";\n");
1769
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 JavaDoc[] metavals;
1841    final boolean[] isName;
1842    final int[] isList;
1843    Replacement(Rule r, int nmeta, Name[] vars, String JavaDoc[] vals, boolean isn[], int[] isl) {
1844        super(null, 0, DECLARATION);
1845        rule = r;
1846        metavars = new Name[nmeta];
1847        metavals = new String JavaDoc[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 JavaDoc 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 JavaDoc 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 JavaDoc<String JavaDoc,String JavaDoc> classMap = new HashMap JavaDoc<String JavaDoc,String JavaDoc>();
1926    public String JavaDoc classRef(String JavaDoc jar, String JavaDoc 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 JavaDoc key = jar+':'+clazz;
1931    String JavaDoc 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 JavaDoc<String JavaDoc,Method> methodRegistry = new HashMap JavaDoc<String JavaDoc,Method>();
1939    
1940    public static synchronized void registerBoolean(String JavaDoc jar, String JavaDoc clazz, String JavaDoc method) {
1941    methodRegistry.put(method, new BooleanMethod(jar,clazz,method));
1942    }
1943    public static synchronized void registerBSym(String JavaDoc jar, String JavaDoc clazz, String JavaDoc 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 JavaDoc jar;
1969    String JavaDoc clazz;
1970    String JavaDoc method;
1971    Method(String JavaDoc j, String JavaDoc c, String JavaDoc m) {
1972        jar = j; clazz = c; method = m;
1973    }
1974    abstract String JavaDoc genInvoke(TransformParser tp, String JavaDoc arg);
1975    }
1976    static class BooleanMethod extends Method {
1977    BooleanMethod(String JavaDoc j, String JavaDoc c, String JavaDoc m) { super(j,c,m); }
1978    String JavaDoc genInvoke(TransformParser tp, String JavaDoc arg) {
1979        return tp.classRef(jar,clazz)+"."+method+"("+arg+")";
1980    }
1981    }
1982    static class BSymMethod extends BooleanMethod {
1983    BSymMethod(String JavaDoc j, String JavaDoc c, String JavaDoc m) { super(j,c,m); }
1984    String JavaDoc genInvoke(TransformParser tp, String JavaDoc arg) {
1985        return super.genInvoke(tp, arg.endsWith(".name")
1986                ? arg.substring(0,arg.length()-5)+".sym" : arg);
1987    }
1988    }
1989}
1990
Popular Tags