TreeMaker.java revision 2571:10fc81ac75b4
1/*
2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.javac.tree;
27
28import java.util.Iterator;
29
30import com.sun.tools.javac.code.*;
31import com.sun.tools.javac.code.Symbol.*;
32import com.sun.tools.javac.code.Type.*;
33import com.sun.tools.javac.util.*;
34import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
35
36import com.sun.tools.javac.tree.JCTree.*;
37
38import static com.sun.tools.javac.code.Flags.*;
39import static com.sun.tools.javac.code.Kinds.*;
40import static com.sun.tools.javac.code.TypeTag.*;
41
42/** Factory class for trees.
43 *
44 *  <p><b>This is NOT part of any supported API.
45 *  If you write code that depends on this, you do so at your own risk.
46 *  This code and its internal interfaces are subject to change or
47 *  deletion without notice.</b>
48 */
49public class TreeMaker implements JCTree.Factory {
50
51    /** The context key for the tree factory. */
52    protected static final Context.Key<TreeMaker> treeMakerKey = new Context.Key<>();
53
54    /** Get the TreeMaker instance. */
55    public static TreeMaker instance(Context context) {
56        TreeMaker instance = context.get(treeMakerKey);
57        if (instance == null)
58            instance = new TreeMaker(context);
59        return instance;
60    }
61
62    /** The position at which subsequent trees will be created.
63     */
64    public int pos = Position.NOPOS;
65
66    /** The toplevel tree to which created trees belong.
67     */
68    public JCCompilationUnit toplevel;
69
70    /** The current name table. */
71    Names names;
72
73    Types types;
74
75    /** The current symbol table. */
76    Symtab syms;
77
78    /** Create a tree maker with null toplevel and NOPOS as initial position.
79     */
80    protected TreeMaker(Context context) {
81        context.put(treeMakerKey, this);
82        this.pos = Position.NOPOS;
83        this.toplevel = null;
84        this.names = Names.instance(context);
85        this.syms = Symtab.instance(context);
86        this.types = Types.instance(context);
87    }
88
89    /** Create a tree maker with a given toplevel and FIRSTPOS as initial position.
90     */
91    protected TreeMaker(JCCompilationUnit toplevel, Names names, Types types, Symtab syms) {
92        this.pos = Position.FIRSTPOS;
93        this.toplevel = toplevel;
94        this.names = names;
95        this.types = types;
96        this.syms = syms;
97    }
98
99    /** Create a new tree maker for a given toplevel.
100     */
101    public TreeMaker forToplevel(JCCompilationUnit toplevel) {
102        return new TreeMaker(toplevel, names, types, syms);
103    }
104
105    /** Reassign current position.
106     */
107    public TreeMaker at(int pos) {
108        this.pos = pos;
109        return this;
110    }
111
112    /** Reassign current position.
113     */
114    public TreeMaker at(DiagnosticPosition pos) {
115        this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition());
116        return this;
117    }
118
119    /**
120     * Create given tree node at current position.
121     * @param defs a list of PackageDef, ClassDef, Import, and Skip
122     */
123    public JCCompilationUnit TopLevel(List<JCTree> defs) {
124        for (JCTree node : defs)
125            Assert.check(node instanceof JCClassDecl
126                || node instanceof JCPackageDecl
127                || node instanceof JCImport
128                || node instanceof JCSkip
129                || node instanceof JCErroneous
130                || (node instanceof JCExpressionStatement
131                    && ((JCExpressionStatement)node).expr instanceof JCErroneous),
132                node.getClass().getSimpleName());
133        JCCompilationUnit tree = new JCCompilationUnit(defs);
134        tree.pos = pos;
135        return tree;
136    }
137
138    public JCPackageDecl PackageDecl(List<JCAnnotation> annotations,
139                                     JCExpression pid) {
140        Assert.checkNonNull(annotations);
141        Assert.checkNonNull(pid);
142        JCPackageDecl tree = new JCPackageDecl(annotations, pid);
143        tree.pos = pos;
144        return tree;
145    }
146
147    public JCImport Import(JCTree qualid, boolean importStatic) {
148        JCImport tree = new JCImport(qualid, importStatic);
149        tree.pos = pos;
150        return tree;
151    }
152
153    public JCClassDecl ClassDef(JCModifiers mods,
154                                Name name,
155                                List<JCTypeParameter> typarams,
156                                JCExpression extending,
157                                List<JCExpression> implementing,
158                                List<JCTree> defs)
159    {
160        JCClassDecl tree = new JCClassDecl(mods,
161                                     name,
162                                     typarams,
163                                     extending,
164                                     implementing,
165                                     defs,
166                                     null);
167        tree.pos = pos;
168        return tree;
169    }
170
171    public JCMethodDecl MethodDef(JCModifiers mods,
172                               Name name,
173                               JCExpression restype,
174                               List<JCTypeParameter> typarams,
175                               List<JCVariableDecl> params,
176                               List<JCExpression> thrown,
177                               JCBlock body,
178                               JCExpression defaultValue) {
179        return MethodDef(
180                mods, name, restype, typarams, null, params,
181                thrown, body, defaultValue);
182    }
183
184    public JCMethodDecl MethodDef(JCModifiers mods,
185                               Name name,
186                               JCExpression restype,
187                               List<JCTypeParameter> typarams,
188                               JCVariableDecl recvparam,
189                               List<JCVariableDecl> params,
190                               List<JCExpression> thrown,
191                               JCBlock body,
192                               JCExpression defaultValue)
193    {
194        JCMethodDecl tree = new JCMethodDecl(mods,
195                                       name,
196                                       restype,
197                                       typarams,
198                                       recvparam,
199                                       params,
200                                       thrown,
201                                       body,
202                                       defaultValue,
203                                       null);
204        tree.pos = pos;
205        return tree;
206    }
207
208    public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) {
209        JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null);
210        tree.pos = pos;
211        return tree;
212    }
213
214    public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) {
215        JCVariableDecl tree = new JCVariableDecl(mods, name, vartype);
216        tree.pos = pos;
217        return tree;
218    }
219
220    public JCSkip Skip() {
221        JCSkip tree = new JCSkip();
222        tree.pos = pos;
223        return tree;
224    }
225
226    public JCBlock Block(long flags, List<JCStatement> stats) {
227        JCBlock tree = new JCBlock(flags, stats);
228        tree.pos = pos;
229        return tree;
230    }
231
232    public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
233        JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
234        tree.pos = pos;
235        return tree;
236    }
237
238    public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
239        JCWhileLoop tree = new JCWhileLoop(cond, body);
240        tree.pos = pos;
241        return tree;
242    }
243
244    public JCForLoop ForLoop(List<JCStatement> init,
245                           JCExpression cond,
246                           List<JCExpressionStatement> step,
247                           JCStatement body)
248    {
249        JCForLoop tree = new JCForLoop(init, cond, step, body);
250        tree.pos = pos;
251        return tree;
252    }
253
254    public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
255        JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
256        tree.pos = pos;
257        return tree;
258    }
259
260    public JCLabeledStatement Labelled(Name label, JCStatement body) {
261        JCLabeledStatement tree = new JCLabeledStatement(label, body);
262        tree.pos = pos;
263        return tree;
264    }
265
266    public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
267        JCSwitch tree = new JCSwitch(selector, cases);
268        tree.pos = pos;
269        return tree;
270    }
271
272    public JCCase Case(JCExpression pat, List<JCStatement> stats) {
273        JCCase tree = new JCCase(pat, stats);
274        tree.pos = pos;
275        return tree;
276    }
277
278    public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
279        JCSynchronized tree = new JCSynchronized(lock, body);
280        tree.pos = pos;
281        return tree;
282    }
283
284    public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
285        return Try(List.<JCTree>nil(), body, catchers, finalizer);
286    }
287
288    public JCTry Try(List<JCTree> resources,
289                     JCBlock body,
290                     List<JCCatch> catchers,
291                     JCBlock finalizer) {
292        JCTry tree = new JCTry(resources, body, catchers, finalizer);
293        tree.pos = pos;
294        return tree;
295    }
296
297    public JCCatch Catch(JCVariableDecl param, JCBlock body) {
298        JCCatch tree = new JCCatch(param, body);
299        tree.pos = pos;
300        return tree;
301    }
302
303    public JCConditional Conditional(JCExpression cond,
304                                   JCExpression thenpart,
305                                   JCExpression elsepart)
306    {
307        JCConditional tree = new JCConditional(cond, thenpart, elsepart);
308        tree.pos = pos;
309        return tree;
310    }
311
312    public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) {
313        JCIf tree = new JCIf(cond, thenpart, elsepart);
314        tree.pos = pos;
315        return tree;
316    }
317
318    public JCExpressionStatement Exec(JCExpression expr) {
319        JCExpressionStatement tree = new JCExpressionStatement(expr);
320        tree.pos = pos;
321        return tree;
322    }
323
324    public JCBreak Break(Name label) {
325        JCBreak tree = new JCBreak(label, null);
326        tree.pos = pos;
327        return tree;
328    }
329
330    public JCContinue Continue(Name label) {
331        JCContinue tree = new JCContinue(label, null);
332        tree.pos = pos;
333        return tree;
334    }
335
336    public JCReturn Return(JCExpression expr) {
337        JCReturn tree = new JCReturn(expr);
338        tree.pos = pos;
339        return tree;
340    }
341
342    public JCThrow Throw(JCExpression expr) {
343        JCThrow tree = new JCThrow(expr);
344        tree.pos = pos;
345        return tree;
346    }
347
348    public JCAssert Assert(JCExpression cond, JCExpression detail) {
349        JCAssert tree = new JCAssert(cond, detail);
350        tree.pos = pos;
351        return tree;
352    }
353
354    public JCMethodInvocation Apply(List<JCExpression> typeargs,
355                       JCExpression fn,
356                       List<JCExpression> args)
357    {
358        JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);
359        tree.pos = pos;
360        return tree;
361    }
362
363    public JCNewClass NewClass(JCExpression encl,
364                             List<JCExpression> typeargs,
365                             JCExpression clazz,
366                             List<JCExpression> args,
367                             JCClassDecl def)
368    {
369        JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
370        tree.pos = pos;
371        return tree;
372    }
373
374    public JCNewArray NewArray(JCExpression elemtype,
375                             List<JCExpression> dims,
376                             List<JCExpression> elems)
377    {
378        JCNewArray tree = new JCNewArray(elemtype, dims, elems);
379        tree.pos = pos;
380        return tree;
381    }
382
383    public JCLambda Lambda(List<JCVariableDecl> params,
384                           JCTree body)
385    {
386        JCLambda tree = new JCLambda(params, body);
387        tree.pos = pos;
388        return tree;
389    }
390
391    public JCParens Parens(JCExpression expr) {
392        JCParens tree = new JCParens(expr);
393        tree.pos = pos;
394        return tree;
395    }
396
397    public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
398        JCAssign tree = new JCAssign(lhs, rhs);
399        tree.pos = pos;
400        return tree;
401    }
402
403    public JCAssignOp Assignop(JCTree.Tag opcode, JCTree lhs, JCTree rhs) {
404        JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
405        tree.pos = pos;
406        return tree;
407    }
408
409    public JCUnary Unary(JCTree.Tag opcode, JCExpression arg) {
410        JCUnary tree = new JCUnary(opcode, arg);
411        tree.pos = pos;
412        return tree;
413    }
414
415    public JCBinary Binary(JCTree.Tag opcode, JCExpression lhs, JCExpression rhs) {
416        JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
417        tree.pos = pos;
418        return tree;
419    }
420
421    public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
422        JCTypeCast tree = new JCTypeCast(clazz, expr);
423        tree.pos = pos;
424        return tree;
425    }
426
427    public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
428        JCInstanceOf tree = new JCInstanceOf(expr, clazz);
429        tree.pos = pos;
430        return tree;
431    }
432
433    public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
434        JCArrayAccess tree = new JCArrayAccess(indexed, index);
435        tree.pos = pos;
436        return tree;
437    }
438
439    public JCFieldAccess Select(JCExpression selected, Name selector) {
440        JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
441        tree.pos = pos;
442        return tree;
443    }
444
445    public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name,
446            JCExpression expr, List<JCExpression> typeargs) {
447        JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs);
448        tree.pos = pos;
449        return tree;
450    }
451
452    public JCIdent Ident(Name name) {
453        JCIdent tree = new JCIdent(name, null);
454        tree.pos = pos;
455        return tree;
456    }
457
458    public JCLiteral Literal(TypeTag tag, Object value) {
459        JCLiteral tree = new JCLiteral(tag, value);
460        tree.pos = pos;
461        return tree;
462    }
463
464    public JCPrimitiveTypeTree TypeIdent(TypeTag typetag) {
465        JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
466        tree.pos = pos;
467        return tree;
468    }
469
470    public JCArrayTypeTree TypeArray(JCExpression elemtype) {
471        JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
472        tree.pos = pos;
473        return tree;
474    }
475
476    public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
477        JCTypeApply tree = new JCTypeApply(clazz, arguments);
478        tree.pos = pos;
479        return tree;
480    }
481
482    public JCTypeUnion TypeUnion(List<JCExpression> components) {
483        JCTypeUnion tree = new JCTypeUnion(components);
484        tree.pos = pos;
485        return tree;
486    }
487
488    public JCTypeIntersection TypeIntersection(List<JCExpression> components) {
489        JCTypeIntersection tree = new JCTypeIntersection(components);
490        tree.pos = pos;
491        return tree;
492    }
493
494    public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
495        return TypeParameter(name, bounds, List.<JCAnnotation>nil());
496    }
497
498    public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annos) {
499        JCTypeParameter tree = new JCTypeParameter(name, bounds, annos);
500        tree.pos = pos;
501        return tree;
502    }
503
504    public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
505        JCWildcard tree = new JCWildcard(kind, type);
506        tree.pos = pos;
507        return tree;
508    }
509
510    public TypeBoundKind TypeBoundKind(BoundKind kind) {
511        TypeBoundKind tree = new TypeBoundKind(kind);
512        tree.pos = pos;
513        return tree;
514    }
515
516    public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
517        JCAnnotation tree = new JCAnnotation(Tag.ANNOTATION, annotationType, args);
518        tree.pos = pos;
519        return tree;
520    }
521
522    public JCAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) {
523        JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args);
524        tree.pos = pos;
525        return tree;
526    }
527
528    public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
529        JCModifiers tree = new JCModifiers(flags, annotations);
530        boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0;
531        tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
532        return tree;
533    }
534
535    public JCModifiers Modifiers(long flags) {
536        return Modifiers(flags, List.<JCAnnotation>nil());
537    }
538
539    public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
540        JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
541        tree.pos = pos;
542        return tree;
543    }
544
545    public JCErroneous Erroneous() {
546        return Erroneous(List.<JCTree>nil());
547    }
548
549    public JCErroneous Erroneous(List<? extends JCTree> errs) {
550        JCErroneous tree = new JCErroneous(errs);
551        tree.pos = pos;
552        return tree;
553    }
554
555    public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
556        LetExpr tree = new LetExpr(defs, expr);
557        tree.pos = pos;
558        return tree;
559    }
560
561/* ***************************************************************************
562 * Derived building blocks.
563 ****************************************************************************/
564
565    public JCClassDecl AnonymousClassDef(JCModifiers mods,
566                                         List<JCTree> defs)
567    {
568        return ClassDef(mods,
569                        names.empty,
570                        List.<JCTypeParameter>nil(),
571                        null,
572                        List.<JCExpression>nil(),
573                        defs);
574    }
575
576    public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
577        LetExpr tree = new LetExpr(List.of(def), expr);
578        tree.pos = pos;
579        return tree;
580    }
581
582    /** Create an identifier from a symbol.
583     */
584    public JCIdent Ident(Symbol sym) {
585        return (JCIdent)new JCIdent((sym.name != names.empty)
586                                ? sym.name
587                                : sym.flatName(), sym)
588            .setPos(pos)
589            .setType(sym.type);
590    }
591
592    /** Create a selection node from a qualifier tree and a symbol.
593     *  @param base   The qualifier tree.
594     */
595    public JCExpression Select(JCExpression base, Symbol sym) {
596        return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
597    }
598
599    /** Create a qualified identifier from a symbol, adding enough qualifications
600     *  to make the reference unique.
601     */
602    public JCExpression QualIdent(Symbol sym) {
603        return isUnqualifiable(sym)
604            ? Ident(sym)
605            : Select(QualIdent(sym.owner), sym);
606    }
607
608    /** Create an identifier that refers to the variable declared in given variable
609     *  declaration.
610     */
611    public JCExpression Ident(JCVariableDecl param) {
612        return Ident(param.sym);
613    }
614
615    /** Create a list of identifiers referring to the variables declared
616     *  in given list of variable declarations.
617     */
618    public List<JCExpression> Idents(List<JCVariableDecl> params) {
619        ListBuffer<JCExpression> ids = new ListBuffer<>();
620        for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
621            ids.append(Ident(l.head));
622        return ids.toList();
623    }
624
625    /** Create a tree representing `this', given its type.
626     */
627    public JCExpression This(Type t) {
628        return Ident(new VarSymbol(FINAL, names._this, t, t.tsym));
629    }
630
631    /** Create a tree representing a class literal.
632     */
633    public JCExpression ClassLiteral(ClassSymbol clazz) {
634        return ClassLiteral(clazz.type);
635    }
636
637    /** Create a tree representing a class literal.
638     */
639    public JCExpression ClassLiteral(Type t) {
640        VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
641                                      names._class,
642                                      t,
643                                      t.tsym);
644        return Select(Type(t), lit);
645    }
646
647    /** Create a tree representing `super', given its type and owner.
648     */
649    public JCIdent Super(Type t, TypeSymbol owner) {
650        return Ident(new VarSymbol(FINAL, names._super, t, owner));
651    }
652
653    /**
654     * Create a method invocation from a method tree and a list of
655     * argument trees.
656     */
657    public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
658        return Apply(null, meth, args).setType(meth.type.getReturnType());
659    }
660
661    /**
662     * Create a no-arg method invocation from a method tree
663     */
664    public JCMethodInvocation App(JCExpression meth) {
665        return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType());
666    }
667
668    /** Create a method invocation from a method tree and a list of argument trees.
669     */
670    public JCExpression Create(Symbol ctor, List<JCExpression> args) {
671        Type t = ctor.owner.erasure(types);
672        JCNewClass newclass = NewClass(null, null, Type(t), args, null);
673        newclass.constructor = ctor;
674        newclass.setType(t);
675        return newclass;
676    }
677
678    /** Create a tree representing given type.
679     */
680    public JCExpression Type(Type t) {
681        if (t == null) return null;
682        JCExpression tp;
683        switch (t.getTag()) {
684        case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
685        case DOUBLE: case BOOLEAN: case VOID:
686            tp = TypeIdent(t.getTag());
687            break;
688        case TYPEVAR:
689            tp = Ident(t.tsym);
690            break;
691        case WILDCARD: {
692            WildcardType a = ((WildcardType) t);
693            tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
694            break;
695        }
696        case CLASS:
697            switch (t.getKind()) {
698            case UNION: {
699                UnionClassType tu = (UnionClassType)t;
700                ListBuffer<JCExpression> la = new ListBuffer<>();
701                for (Type ta : tu.getAlternativeTypes()) {
702                    la.add(Type(ta));
703                }
704                tp = TypeUnion(la.toList());
705                break;
706            }
707            case INTERSECTION: {
708                IntersectionClassType it = (IntersectionClassType)t;
709                ListBuffer<JCExpression> la = new ListBuffer<>();
710                for (Type ta : it.getExplicitComponents()) {
711                    la.add(Type(ta));
712                }
713                tp = TypeIntersection(la.toList());
714                break;
715            }
716            default: {
717                Type outer = t.getEnclosingType();
718                JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP
719                        ? Select(Type(outer), t.tsym)
720                        : QualIdent(t.tsym);
721                tp = t.getTypeArguments().isEmpty()
722                        ? clazz
723                        : TypeApply(clazz, Types(t.getTypeArguments()));
724                break;
725            }
726            }
727            break;
728        case ARRAY:
729            tp = TypeArray(Type(types.elemtype(t)));
730            break;
731        case ERROR:
732            tp = TypeIdent(ERROR);
733            break;
734        default:
735            throw new AssertionError("unexpected type: " + t);
736        }
737        return tp.setType(t);
738    }
739
740    /** Create a list of trees representing given list of types.
741     */
742    public List<JCExpression> Types(List<Type> ts) {
743        ListBuffer<JCExpression> lb = new ListBuffer<>();
744        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
745            lb.append(Type(l.head));
746        return lb.toList();
747    }
748
749    /** Create a variable definition from a variable symbol and an initializer
750     *  expression.
751     */
752    public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
753        return (JCVariableDecl)
754            new JCVariableDecl(
755                Modifiers(v.flags(), Annotations(v.getRawAttributes())),
756                v.name,
757                Type(v.type),
758                init,
759                v).setPos(pos).setType(v.type);
760    }
761
762    /** Create annotation trees from annotations.
763     */
764    public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
765        if (attributes == null) return List.nil();
766        ListBuffer<JCAnnotation> result = new ListBuffer<>();
767        for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) {
768            Attribute a = i.head;
769            result.append(Annotation(a));
770        }
771        return result.toList();
772    }
773
774    public JCLiteral Literal(Object value) {
775        JCLiteral result = null;
776        if (value instanceof String) {
777            result = Literal(CLASS, value).
778                setType(syms.stringType.constType(value));
779        } else if (value instanceof Integer) {
780            result = Literal(INT, value).
781                setType(syms.intType.constType(value));
782        } else if (value instanceof Long) {
783            result = Literal(LONG, value).
784                setType(syms.longType.constType(value));
785        } else if (value instanceof Byte) {
786            result = Literal(BYTE, value).
787                setType(syms.byteType.constType(value));
788        } else if (value instanceof Character) {
789            int v = (int) (((Character) value).toString().charAt(0));
790            result = Literal(CHAR, v).
791                setType(syms.charType.constType(v));
792        } else if (value instanceof Double) {
793            result = Literal(DOUBLE, value).
794                setType(syms.doubleType.constType(value));
795        } else if (value instanceof Float) {
796            result = Literal(FLOAT, value).
797                setType(syms.floatType.constType(value));
798        } else if (value instanceof Short) {
799            result = Literal(SHORT, value).
800                setType(syms.shortType.constType(value));
801        } else if (value instanceof Boolean) {
802            int v = ((Boolean) value) ? 1 : 0;
803            result = Literal(BOOLEAN, v).
804                setType(syms.booleanType.constType(v));
805        } else {
806            throw new AssertionError(value);
807        }
808        return result;
809    }
810
811    class AnnotationBuilder implements Attribute.Visitor {
812        JCExpression result = null;
813        public void visitConstant(Attribute.Constant v) {
814            result = Literal(v.type.getTag(), v.value);
815        }
816        public void visitClass(Attribute.Class clazz) {
817            result = ClassLiteral(clazz.classType).setType(syms.classType);
818        }
819        public void visitEnum(Attribute.Enum e) {
820            result = QualIdent(e.value);
821        }
822        public void visitError(Attribute.Error e) {
823            result = Erroneous();
824        }
825        public void visitCompound(Attribute.Compound compound) {
826            if (compound instanceof Attribute.TypeCompound) {
827                result = visitTypeCompoundInternal((Attribute.TypeCompound) compound);
828            } else {
829                result = visitCompoundInternal(compound);
830            }
831        }
832        public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
833            ListBuffer<JCExpression> args = new ListBuffer<>();
834            for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
835                Pair<MethodSymbol,Attribute> pair = values.head;
836                JCExpression valueTree = translate(pair.snd);
837                args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
838            }
839            return Annotation(Type(compound.type), args.toList());
840        }
841        public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) {
842            ListBuffer<JCExpression> args = new ListBuffer<>();
843            for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
844                Pair<MethodSymbol,Attribute> pair = values.head;
845                JCExpression valueTree = translate(pair.snd);
846                args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
847            }
848            return TypeAnnotation(Type(compound.type), args.toList());
849        }
850        public void visitArray(Attribute.Array array) {
851            ListBuffer<JCExpression> elems = new ListBuffer<>();
852            for (int i = 0; i < array.values.length; i++)
853                elems.append(translate(array.values[i]));
854            result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type);
855        }
856        JCExpression translate(Attribute a) {
857            a.accept(this);
858            return result;
859        }
860        JCAnnotation translate(Attribute.Compound a) {
861            return visitCompoundInternal(a);
862        }
863        JCAnnotation translate(Attribute.TypeCompound a) {
864            return visitTypeCompoundInternal(a);
865        }
866    }
867
868    AnnotationBuilder annotationBuilder = new AnnotationBuilder();
869
870    /** Create an annotation tree from an attribute.
871     */
872    public JCAnnotation Annotation(Attribute a) {
873        return annotationBuilder.translate((Attribute.Compound)a);
874    }
875
876    public JCAnnotation TypeAnnotation(Attribute a) {
877        return annotationBuilder.translate((Attribute.TypeCompound) a);
878    }
879
880    /** Create a method definition from a method symbol and a method body.
881     */
882    public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
883        return MethodDef(m, m.type, body);
884    }
885
886    /** Create a method definition from a method symbol, method type
887     *  and a method body.
888     */
889    public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
890        return (JCMethodDecl)
891            new JCMethodDecl(
892                Modifiers(m.flags(), Annotations(m.getRawAttributes())),
893                m.name,
894                Type(mtype.getReturnType()),
895                TypeParams(mtype.getTypeArguments()),
896                null, // receiver type
897                Params(mtype.getParameterTypes(), m),
898                Types(mtype.getThrownTypes()),
899                body,
900                null,
901                m).setPos(pos).setType(mtype);
902    }
903
904    /** Create a type parameter tree from its name and type.
905     */
906    public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
907        return (JCTypeParameter)
908            TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
909    }
910
911    /** Create a list of type parameter trees from a list of type variables.
912     */
913    public List<JCTypeParameter> TypeParams(List<Type> typarams) {
914        ListBuffer<JCTypeParameter> tparams = new ListBuffer<>();
915        for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
916            tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
917        return tparams.toList();
918    }
919
920    /** Create a value parameter tree from its name, type, and owner.
921     */
922    public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
923        return VarDef(new VarSymbol(PARAMETER, name, argtype, owner), null);
924    }
925
926    /** Create a a list of value parameter trees x0, ..., xn from a list of
927     *  their types and an their owner.
928     */
929    public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
930        ListBuffer<JCVariableDecl> params = new ListBuffer<>();
931        MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null;
932        if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) {
933            for (VarSymbol param : ((MethodSymbol)owner).params)
934                params.append(VarDef(param, null));
935        } else {
936            int i = 0;
937            for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
938                params.append(Param(paramName(i++), l.head, owner));
939        }
940        return params.toList();
941    }
942
943    /** Wrap a method invocation in an expression statement or return statement,
944     *  depending on whether the method invocation expression's type is void.
945     */
946    public JCStatement Call(JCExpression apply) {
947        return apply.type.hasTag(VOID) ? Exec(apply) : Return(apply);
948    }
949
950    /** Construct an assignment from a variable symbol and a right hand side.
951     */
952    public JCStatement Assignment(Symbol v, JCExpression rhs) {
953        return Exec(Assign(Ident(v), rhs).setType(v.type));
954    }
955
956    /** Construct an index expression from a variable and an expression.
957     */
958    public JCArrayAccess Indexed(Symbol v, JCExpression index) {
959        JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
960        tree.type = ((ArrayType)v.type).elemtype;
961        return tree;
962    }
963
964    /** Make an attributed type cast expression.
965     */
966    public JCTypeCast TypeCast(Type type, JCExpression expr) {
967        return (JCTypeCast)TypeCast(Type(type), expr).setType(type);
968    }
969
970/* ***************************************************************************
971 * Helper methods.
972 ****************************************************************************/
973
974    /** Can given symbol be referred to in unqualified form?
975     */
976    boolean isUnqualifiable(Symbol sym) {
977        if (sym.name == names.empty ||
978            sym.owner == null ||
979            sym.owner == syms.rootPackage ||
980            sym.owner.kind == MTH || sym.owner.kind == VAR) {
981            return true;
982        } else if (sym.kind == TYP && toplevel != null) {
983            Iterator<Symbol> it = toplevel.namedImportScope.getSymbolsByName(sym.name).iterator();
984            if (it.hasNext()) {
985                Symbol s = it.next();
986                return
987                  s == sym &&
988                  !it.hasNext();
989            }
990            it = toplevel.packge.members().getSymbolsByName(sym.name).iterator();
991            if (it.hasNext()) {
992                Symbol s = it.next();
993                return
994                  s == sym &&
995                  !it.hasNext();
996            }
997            it = toplevel.starImportScope.getSymbolsByName(sym.name).iterator();
998            if (it.hasNext()) {
999                Symbol s = it.next();
1000                return
1001                  s == sym &&
1002                  !it.hasNext();
1003            }
1004        }
1005        return false;
1006    }
1007
1008    /** The name of synthetic parameter number `i'.
1009     */
1010    public Name paramName(int i)   { return names.fromString("x" + i); }
1011
1012    /** The name of synthetic type parameter number `i'.
1013     */
1014    public Name typaramName(int i) { return names.fromString("A" + i); }
1015}
1016