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