Tue, 25 May 2010 15:54:51 -0700
6943119: Rebrand source copyright notices
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1999, 2008, 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 */
26 package com.sun.tools.javac.tree;
28 import com.sun.tools.javac.code.*;
29 import com.sun.tools.javac.code.Symbol.*;
30 import com.sun.tools.javac.code.Type.*;
31 import com.sun.tools.javac.util.*;
32 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
34 import com.sun.tools.javac.tree.JCTree.*;
36 import static com.sun.tools.javac.code.Flags.*;
37 import static com.sun.tools.javac.code.Kinds.*;
38 import static com.sun.tools.javac.code.TypeTags.*;
40 /** Factory class for trees.
41 *
42 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
43 * you write code that depends on this, you do so at your own risk.
44 * This code and its internal interfaces are subject to change or
45 * deletion without notice.</b>
46 */
47 public class TreeMaker implements JCTree.Factory {
49 /** The context key for the tree factory. */
50 protected static final Context.Key<TreeMaker> treeMakerKey =
51 new Context.Key<TreeMaker>();
53 /** Get the TreeMaker instance. */
54 public static TreeMaker instance(Context context) {
55 TreeMaker instance = context.get(treeMakerKey);
56 if (instance == null)
57 instance = new TreeMaker(context);
58 return instance;
59 }
61 /** The position at which subsequent trees will be created.
62 */
63 public int pos = Position.NOPOS;
65 /** The toplevel tree to which created trees belong.
66 */
67 public JCCompilationUnit toplevel;
69 /** The current name table. */
70 Names names;
72 Types types;
74 /** The current symbol table. */
75 Symtab syms;
77 /** Create a tree maker with null toplevel and NOPOS as initial position.
78 */
79 protected TreeMaker(Context context) {
80 context.put(treeMakerKey, this);
81 this.pos = Position.NOPOS;
82 this.toplevel = null;
83 this.names = Names.instance(context);
84 this.syms = Symtab.instance(context);
85 this.types = Types.instance(context);
86 }
88 /** Create a tree maker with a given toplevel and FIRSTPOS as initial position.
89 */
90 TreeMaker(JCCompilationUnit toplevel, Names names, Types types, Symtab syms) {
91 this.pos = Position.FIRSTPOS;
92 this.toplevel = toplevel;
93 this.names = names;
94 this.types = types;
95 this.syms = syms;
96 }
98 /** Create a new tree maker for a given toplevel.
99 */
100 public TreeMaker forToplevel(JCCompilationUnit toplevel) {
101 return new TreeMaker(toplevel, names, types, syms);
102 }
104 /** Reassign current position.
105 */
106 public TreeMaker at(int pos) {
107 this.pos = pos;
108 return this;
109 }
111 /** Reassign current position.
112 */
113 public TreeMaker at(DiagnosticPosition pos) {
114 this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition());
115 return this;
116 }
118 /**
119 * Create given tree node at current position.
120 * @param defs a list of ClassDef, Import, and Skip
121 */
122 public JCCompilationUnit TopLevel(List<JCAnnotation> packageAnnotations,
123 JCExpression pid,
124 List<JCTree> defs) {
125 assert packageAnnotations != null;
126 for (JCTree node : defs)
127 assert node instanceof JCClassDecl
128 || node instanceof JCImport
129 || node instanceof JCSkip
130 || node instanceof JCErroneous
131 || (node instanceof JCExpressionStatement
132 && ((JCExpressionStatement)node).expr instanceof JCErroneous)
133 : node.getClass().getSimpleName();
134 JCCompilationUnit tree = new JCCompilationUnit(packageAnnotations, pid, defs,
135 null, null, null, null);
136 tree.pos = pos;
137 return tree;
138 }
140 public JCImport Import(JCTree qualid, boolean importStatic) {
141 JCImport tree = new JCImport(qualid, importStatic);
142 tree.pos = pos;
143 return tree;
144 }
146 public JCClassDecl ClassDef(JCModifiers mods,
147 Name name,
148 List<JCTypeParameter> typarams,
149 JCTree extending,
150 List<JCExpression> implementing,
151 List<JCTree> defs)
152 {
153 JCClassDecl tree = new JCClassDecl(mods,
154 name,
155 typarams,
156 extending,
157 implementing,
158 defs,
159 null);
160 tree.pos = pos;
161 return tree;
162 }
164 public JCMethodDecl MethodDef(JCModifiers mods,
165 Name name,
166 JCExpression restype,
167 List<JCTypeParameter> typarams,
168 List<JCVariableDecl> params,
169 List<JCExpression> thrown,
170 JCBlock body,
171 JCExpression defaultValue) {
172 return MethodDef(
173 mods, name, restype, typarams, params,
174 null, thrown, body, defaultValue);
175 }
177 public JCMethodDecl MethodDef(JCModifiers mods,
178 Name name,
179 JCExpression restype,
180 List<JCTypeParameter> typarams,
181 List<JCVariableDecl> params,
182 List<JCTypeAnnotation> receiver,
183 List<JCExpression> thrown,
184 JCBlock body,
185 JCExpression defaultValue)
186 {
187 JCMethodDecl tree = new JCMethodDecl(mods,
188 name,
189 restype,
190 typarams,
191 params,
192 receiver,
193 thrown,
194 body,
195 defaultValue,
196 null);
197 tree.pos = pos;
198 return tree;
199 }
201 public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) {
202 JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null);
203 tree.pos = pos;
204 return tree;
205 }
207 public JCSkip Skip() {
208 JCSkip tree = new JCSkip();
209 tree.pos = pos;
210 return tree;
211 }
213 public JCBlock Block(long flags, List<JCStatement> stats) {
214 JCBlock tree = new JCBlock(flags, stats);
215 tree.pos = pos;
216 return tree;
217 }
219 public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
220 JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
221 tree.pos = pos;
222 return tree;
223 }
225 public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
226 JCWhileLoop tree = new JCWhileLoop(cond, body);
227 tree.pos = pos;
228 return tree;
229 }
231 public JCForLoop ForLoop(List<JCStatement> init,
232 JCExpression cond,
233 List<JCExpressionStatement> step,
234 JCStatement body)
235 {
236 JCForLoop tree = new JCForLoop(init, cond, step, body);
237 tree.pos = pos;
238 return tree;
239 }
241 public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
242 JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
243 tree.pos = pos;
244 return tree;
245 }
247 public JCLabeledStatement Labelled(Name label, JCStatement body) {
248 JCLabeledStatement tree = new JCLabeledStatement(label, body);
249 tree.pos = pos;
250 return tree;
251 }
253 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
254 JCSwitch tree = new JCSwitch(selector, cases);
255 tree.pos = pos;
256 return tree;
257 }
259 public JCCase Case(JCExpression pat, List<JCStatement> stats) {
260 JCCase tree = new JCCase(pat, stats);
261 tree.pos = pos;
262 return tree;
263 }
265 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
266 JCSynchronized tree = new JCSynchronized(lock, body);
267 tree.pos = pos;
268 return tree;
269 }
271 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
272 JCTry tree = new JCTry(body, catchers, finalizer);
273 tree.pos = pos;
274 return tree;
275 }
277 public JCCatch Catch(JCVariableDecl param, JCBlock body) {
278 JCCatch tree = new JCCatch(param, body);
279 tree.pos = pos;
280 return tree;
281 }
283 public JCConditional Conditional(JCExpression cond,
284 JCExpression thenpart,
285 JCExpression elsepart)
286 {
287 JCConditional tree = new JCConditional(cond, thenpart, elsepart);
288 tree.pos = pos;
289 return tree;
290 }
292 public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) {
293 JCIf tree = new JCIf(cond, thenpart, elsepart);
294 tree.pos = pos;
295 return tree;
296 }
298 public JCExpressionStatement Exec(JCExpression expr) {
299 JCExpressionStatement tree = new JCExpressionStatement(expr);
300 tree.pos = pos;
301 return tree;
302 }
304 public JCBreak Break(Name label) {
305 JCBreak tree = new JCBreak(label, null);
306 tree.pos = pos;
307 return tree;
308 }
310 public JCContinue Continue(Name label) {
311 JCContinue tree = new JCContinue(label, null);
312 tree.pos = pos;
313 return tree;
314 }
316 public JCReturn Return(JCExpression expr) {
317 JCReturn tree = new JCReturn(expr);
318 tree.pos = pos;
319 return tree;
320 }
322 public JCThrow Throw(JCTree expr) {
323 JCThrow tree = new JCThrow(expr);
324 tree.pos = pos;
325 return tree;
326 }
328 public JCAssert Assert(JCExpression cond, JCExpression detail) {
329 JCAssert tree = new JCAssert(cond, detail);
330 tree.pos = pos;
331 return tree;
332 }
334 public JCMethodInvocation Apply(List<JCExpression> typeargs,
335 JCExpression fn,
336 List<JCExpression> args)
337 {
338 JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);
339 tree.pos = pos;
340 return tree;
341 }
343 public JCNewClass NewClass(JCExpression encl,
344 List<JCExpression> typeargs,
345 JCExpression clazz,
346 List<JCExpression> args,
347 JCClassDecl def)
348 {
349 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
350 tree.pos = pos;
351 return tree;
352 }
354 public JCNewArray NewArray(JCExpression elemtype,
355 List<JCExpression> dims,
356 List<JCExpression> elems)
357 {
358 JCNewArray tree = new JCNewArray(elemtype, dims, elems);
359 tree.pos = pos;
360 return tree;
361 }
363 public JCParens Parens(JCExpression expr) {
364 JCParens tree = new JCParens(expr);
365 tree.pos = pos;
366 return tree;
367 }
369 public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
370 JCAssign tree = new JCAssign(lhs, rhs);
371 tree.pos = pos;
372 return tree;
373 }
375 public JCAssignOp Assignop(int opcode, JCTree lhs, JCTree rhs) {
376 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
377 tree.pos = pos;
378 return tree;
379 }
381 public JCUnary Unary(int opcode, JCExpression arg) {
382 JCUnary tree = new JCUnary(opcode, arg);
383 tree.pos = pos;
384 return tree;
385 }
387 public JCBinary Binary(int opcode, JCExpression lhs, JCExpression rhs) {
388 JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
389 tree.pos = pos;
390 return tree;
391 }
393 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
394 JCTypeCast tree = new JCTypeCast(clazz, expr);
395 tree.pos = pos;
396 return tree;
397 }
399 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
400 JCInstanceOf tree = new JCInstanceOf(expr, clazz);
401 tree.pos = pos;
402 return tree;
403 }
405 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
406 JCArrayAccess tree = new JCArrayAccess(indexed, index);
407 tree.pos = pos;
408 return tree;
409 }
411 public JCFieldAccess Select(JCExpression selected, Name selector) {
412 JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
413 tree.pos = pos;
414 return tree;
415 }
417 public JCIdent Ident(Name name) {
418 JCIdent tree = new JCIdent(name, null);
419 tree.pos = pos;
420 return tree;
421 }
423 public JCLiteral Literal(int tag, Object value) {
424 JCLiteral tree = new JCLiteral(tag, value);
425 tree.pos = pos;
426 return tree;
427 }
429 public JCPrimitiveTypeTree TypeIdent(int typetag) {
430 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
431 tree.pos = pos;
432 return tree;
433 }
435 public JCArrayTypeTree TypeArray(JCExpression elemtype) {
436 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
437 tree.pos = pos;
438 return tree;
439 }
441 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
442 JCTypeApply tree = new JCTypeApply(clazz, arguments);
443 tree.pos = pos;
444 return tree;
445 }
447 public JCTypeDisjoint TypeDisjoint(List<JCExpression> components) {
448 JCTypeDisjoint tree = new JCTypeDisjoint(components);
449 tree.pos = pos;
450 return tree;
451 }
453 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
454 return TypeParameter(name, bounds, List.<JCTypeAnnotation>nil());
455 }
457 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCTypeAnnotation> annos) {
458 JCTypeParameter tree = new JCTypeParameter(name, bounds, annos);
459 tree.pos = pos;
460 return tree;
461 }
463 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
464 JCWildcard tree = new JCWildcard(kind, type);
465 tree.pos = pos;
466 return tree;
467 }
469 public TypeBoundKind TypeBoundKind(BoundKind kind) {
470 TypeBoundKind tree = new TypeBoundKind(kind);
471 tree.pos = pos;
472 return tree;
473 }
475 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
476 JCAnnotation tree = new JCAnnotation(annotationType, args);
477 tree.pos = pos;
478 return tree;
479 }
481 public JCTypeAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) {
482 JCTypeAnnotation tree = new JCTypeAnnotation(annotationType, args);
483 tree.pos = pos;
484 return tree;
485 }
487 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
488 JCModifiers tree = new JCModifiers(flags, annotations);
489 boolean noFlags = (flags & Flags.ModifierFlags) == 0;
490 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
491 return tree;
492 }
494 public JCModifiers Modifiers(long flags) {
495 return Modifiers(flags, List.<JCAnnotation>nil());
496 }
498 public JCAnnotatedType AnnotatedType(List<JCTypeAnnotation> annotations, JCExpression underlyingType) {
499 JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
500 tree.pos = pos;
501 return tree;
502 }
504 public JCErroneous Erroneous() {
505 return Erroneous(List.<JCTree>nil());
506 }
508 public JCErroneous Erroneous(List<? extends JCTree> errs) {
509 JCErroneous tree = new JCErroneous(errs);
510 tree.pos = pos;
511 return tree;
512 }
514 public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
515 LetExpr tree = new LetExpr(defs, expr);
516 tree.pos = pos;
517 return tree;
518 }
520 /* ***************************************************************************
521 * Derived building blocks.
522 ****************************************************************************/
524 public JCClassDecl AnonymousClassDef(JCModifiers mods,
525 List<JCTree> defs)
526 {
527 return ClassDef(mods,
528 names.empty,
529 List.<JCTypeParameter>nil(),
530 null,
531 List.<JCExpression>nil(),
532 defs);
533 }
535 public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
536 LetExpr tree = new LetExpr(List.of(def), expr);
537 tree.pos = pos;
538 return tree;
539 }
541 /** Create an identifier from a symbol.
542 */
543 public JCIdent Ident(Symbol sym) {
544 return (JCIdent)new JCIdent((sym.name != names.empty)
545 ? sym.name
546 : sym.flatName(), sym)
547 .setPos(pos)
548 .setType(sym.type);
549 }
551 /** Create a selection node from a qualifier tree and a symbol.
552 * @param base The qualifier tree.
553 */
554 public JCExpression Select(JCExpression base, Symbol sym) {
555 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
556 }
558 /** Create a qualified identifier from a symbol, adding enough qualifications
559 * to make the reference unique.
560 */
561 public JCExpression QualIdent(Symbol sym) {
562 return isUnqualifiable(sym)
563 ? Ident(sym)
564 : Select(QualIdent(sym.owner), sym);
565 }
567 /** Create an identifier that refers to the variable declared in given variable
568 * declaration.
569 */
570 public JCExpression Ident(JCVariableDecl param) {
571 return Ident(param.sym);
572 }
574 /** Create a list of identifiers referring to the variables declared
575 * in given list of variable declarations.
576 */
577 public List<JCExpression> Idents(List<JCVariableDecl> params) {
578 ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>();
579 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
580 ids.append(Ident(l.head));
581 return ids.toList();
582 }
584 /** Create a tree representing `this', given its type.
585 */
586 public JCExpression This(Type t) {
587 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym));
588 }
590 /** Create a tree representing a class literal.
591 */
592 public JCExpression ClassLiteral(ClassSymbol clazz) {
593 return ClassLiteral(clazz.type);
594 }
596 /** Create a tree representing a class literal.
597 */
598 public JCExpression ClassLiteral(Type t) {
599 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
600 names._class,
601 t,
602 t.tsym);
603 return Select(Type(t), lit);
604 }
606 /** Create a tree representing `super', given its type and owner.
607 */
608 public JCIdent Super(Type t, TypeSymbol owner) {
609 return Ident(new VarSymbol(FINAL, names._super, t, owner));
610 }
612 /**
613 * Create a method invocation from a method tree and a list of
614 * argument trees.
615 */
616 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
617 return Apply(null, meth, args).setType(meth.type.getReturnType());
618 }
620 /**
621 * Create a no-arg method invocation from a method tree
622 */
623 public JCMethodInvocation App(JCExpression meth) {
624 return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType());
625 }
627 /** Create a method invocation from a method tree and a list of argument trees.
628 */
629 public JCExpression Create(Symbol ctor, List<JCExpression> args) {
630 Type t = ctor.owner.erasure(types);
631 JCNewClass newclass = NewClass(null, null, Type(t), args, null);
632 newclass.constructor = ctor;
633 newclass.setType(t);
634 return newclass;
635 }
637 /** Create a tree representing given type.
638 */
639 public JCExpression Type(Type t) {
640 if (t == null) return null;
641 JCExpression tp;
642 switch (t.tag) {
643 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
644 case DOUBLE: case BOOLEAN: case VOID:
645 tp = TypeIdent(t.tag);
646 break;
647 case TYPEVAR:
648 tp = Ident(t.tsym);
649 break;
650 case WILDCARD: {
651 WildcardType a = ((WildcardType) t);
652 tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
653 break;
654 }
655 case CLASS:
656 Type outer = t.getEnclosingType();
657 JCExpression clazz = outer.tag == CLASS && t.tsym.owner.kind == TYP
658 ? Select(Type(outer), t.tsym)
659 : QualIdent(t.tsym);
660 tp = t.getTypeArguments().isEmpty()
661 ? clazz
662 : TypeApply(clazz, Types(t.getTypeArguments()));
663 break;
664 case ARRAY:
665 tp = TypeArray(Type(types.elemtype(t)));
666 break;
667 case ERROR:
668 tp = TypeIdent(ERROR);
669 break;
670 default:
671 throw new AssertionError("unexpected type: " + t);
672 }
673 return tp.setType(t);
674 }
675 //where
676 private JCExpression Selectors(JCExpression base, Symbol sym, Symbol limit) {
677 if (sym == limit) return base;
678 else return Select(Selectors(base, sym.owner, limit), sym);
679 }
681 /** Create a list of trees representing given list of types.
682 */
683 public List<JCExpression> Types(List<Type> ts) {
684 ListBuffer<JCExpression> types = new ListBuffer<JCExpression>();
685 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
686 types.append(Type(l.head));
687 return types.toList();
688 }
690 /** Create a variable definition from a variable symbol and an initializer
691 * expression.
692 */
693 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
694 return (JCVariableDecl)
695 new JCVariableDecl(
696 Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())),
697 v.name,
698 Type(v.type),
699 init,
700 v).setPos(pos).setType(v.type);
701 }
703 /** Create annotation trees from annotations.
704 */
705 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
706 if (attributes == null) return List.nil();
707 ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
708 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) {
709 Attribute a = i.head;
710 result.append(Annotation(a));
711 }
712 return result.toList();
713 }
715 public JCLiteral Literal(Object value) {
716 JCLiteral result = null;
717 if (value instanceof String) {
718 result = Literal(CLASS, value).
719 setType(syms.stringType.constType(value));
720 } else if (value instanceof Integer) {
721 result = Literal(INT, value).
722 setType(syms.intType.constType(value));
723 } else if (value instanceof Long) {
724 result = Literal(LONG, value).
725 setType(syms.longType.constType(value));
726 } else if (value instanceof Byte) {
727 result = Literal(BYTE, value).
728 setType(syms.byteType.constType(value));
729 } else if (value instanceof Character) {
730 result = Literal(CHAR, value).
731 setType(syms.charType.constType(value));
732 } else if (value instanceof Double) {
733 result = Literal(DOUBLE, value).
734 setType(syms.doubleType.constType(value));
735 } else if (value instanceof Float) {
736 result = Literal(FLOAT, value).
737 setType(syms.floatType.constType(value));
738 } else if (value instanceof Short) {
739 result = Literal(SHORT, value).
740 setType(syms.shortType.constType(value));
741 } else {
742 throw new AssertionError(value);
743 }
744 return result;
745 }
747 class AnnotationBuilder implements Attribute.Visitor {
748 JCExpression result = null;
749 public void visitConstant(Attribute.Constant v) {
750 result = Literal(v.value);
751 }
752 public void visitClass(Attribute.Class clazz) {
753 result = ClassLiteral(clazz.type).setType(syms.classType);
754 }
755 public void visitEnum(Attribute.Enum e) {
756 result = QualIdent(e.value);
757 }
758 public void visitError(Attribute.Error e) {
759 result = Erroneous();
760 }
761 public void visitCompound(Attribute.Compound compound) {
762 result = visitCompoundInternal(compound);
763 }
764 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
765 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
766 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
767 Pair<MethodSymbol,Attribute> pair = values.head;
768 JCExpression valueTree = translate(pair.snd);
769 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
770 }
771 return Annotation(Type(compound.type), args.toList());
772 }
773 public void visitArray(Attribute.Array array) {
774 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
775 for (int i = 0; i < array.values.length; i++)
776 elems.append(translate(array.values[i]));
777 result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type);
778 }
779 JCExpression translate(Attribute a) {
780 a.accept(this);
781 return result;
782 }
783 JCAnnotation translate(Attribute.Compound a) {
784 return visitCompoundInternal(a);
785 }
786 }
787 AnnotationBuilder annotationBuilder = new AnnotationBuilder();
789 /** Create an annotation tree from an attribute.
790 */
791 public JCAnnotation Annotation(Attribute a) {
792 return annotationBuilder.translate((Attribute.Compound)a);
793 }
795 /** Create a method definition from a method symbol and a method body.
796 */
797 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
798 return MethodDef(m, m.type, body);
799 }
801 /** Create a method definition from a method symbol, method type
802 * and a method body.
803 */
804 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
805 return (JCMethodDecl)
806 new JCMethodDecl(
807 Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())),
808 m.name,
809 Type(mtype.getReturnType()),
810 TypeParams(mtype.getTypeArguments()),
811 Params(mtype.getParameterTypes(), m),
812 null,
813 Types(mtype.getThrownTypes()),
814 body,
815 null,
816 m).setPos(pos).setType(mtype);
817 }
819 /** Create a type parameter tree from its name and type.
820 */
821 public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
822 return (JCTypeParameter)
823 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
824 }
826 /** Create a list of type parameter trees from a list of type variables.
827 */
828 public List<JCTypeParameter> TypeParams(List<Type> typarams) {
829 ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
830 int i = 0;
831 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
832 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
833 return tparams.toList();
834 }
836 /** Create a value parameter tree from its name, type, and owner.
837 */
838 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
839 return VarDef(new VarSymbol(0, name, argtype, owner), null);
840 }
842 /** Create a a list of value parameter trees x0, ..., xn from a list of
843 * their types and an their owner.
844 */
845 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
846 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
847 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null;
848 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) {
849 for (VarSymbol param : ((MethodSymbol)owner).params)
850 params.append(VarDef(param, null));
851 } else {
852 int i = 0;
853 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
854 params.append(Param(paramName(i++), l.head, owner));
855 }
856 return params.toList();
857 }
859 /** Wrap a method invocation in an expression statement or return statement,
860 * depending on whether the method invocation expression's type is void.
861 */
862 public JCStatement Call(JCExpression apply) {
863 return apply.type.tag == VOID ? Exec(apply) : Return(apply);
864 }
866 /** Construct an assignment from a variable symbol and a right hand side.
867 */
868 public JCStatement Assignment(Symbol v, JCExpression rhs) {
869 return Exec(Assign(Ident(v), rhs).setType(v.type));
870 }
872 /** Construct an index expression from a variable and an expression.
873 */
874 public JCArrayAccess Indexed(Symbol v, JCExpression index) {
875 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
876 tree.type = ((ArrayType)v.type).elemtype;
877 return tree;
878 }
880 /** Make an attributed type cast expression.
881 */
882 public JCTypeCast TypeCast(Type type, JCExpression expr) {
883 return (JCTypeCast)TypeCast(Type(type), expr).setType(type);
884 }
886 /* ***************************************************************************
887 * Helper methods.
888 ****************************************************************************/
890 /** Can given symbol be referred to in unqualified form?
891 */
892 boolean isUnqualifiable(Symbol sym) {
893 if (sym.name == names.empty ||
894 sym.owner == null ||
895 sym.owner.kind == MTH || sym.owner.kind == VAR) {
896 return true;
897 } else if (sym.kind == TYP && toplevel != null) {
898 Scope.Entry e;
899 e = toplevel.namedImportScope.lookup(sym.name);
900 if (e.scope != null) {
901 return
902 e.sym == sym &&
903 e.next().scope == null;
904 }
905 e = toplevel.packge.members().lookup(sym.name);
906 if (e.scope != null) {
907 return
908 e.sym == sym &&
909 e.next().scope == null;
910 }
911 e = toplevel.starImportScope.lookup(sym.name);
912 if (e.scope != null) {
913 return
914 e.sym == sym &&
915 e.next().scope == null;
916 }
917 }
918 return false;
919 }
921 /** The name of synthetic parameter number `i'.
922 */
923 public Name paramName(int i) { return names.fromString("x" + i); }
925 /** The name of synthetic type parameter number `i'.
926 */
927 public Name typaramName(int i) { return names.fromString("A" + i); }
928 }