Mon, 03 Jun 2013 17:09:26 -0700
8006615: [doclint] move remaining messages into resource bundle
Reviewed-by: mcimadamore, vromero
1 /*
2 * Copyright (c) 1999, 2013, 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.TypeTag.*;
40 /** Factory class for trees.
41 *
42 * <p><b>This is NOT part of any supported API.
43 * If 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 protected 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.checkNonNull(packageAnnotations);
126 for (JCTree node : defs)
127 Assert.check(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 JCExpression 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, null, params,
174 thrown, body, defaultValue);
175 }
177 public JCMethodDecl MethodDef(JCModifiers mods,
178 Name name,
179 JCExpression restype,
180 List<JCTypeParameter> typarams,
181 JCVariableDecl recvparam,
182 List<JCVariableDecl> params,
183 List<JCExpression> thrown,
184 JCBlock body,
185 JCExpression defaultValue)
186 {
187 JCMethodDecl tree = new JCMethodDecl(mods,
188 name,
189 restype,
190 typarams,
191 recvparam,
192 params,
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 JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) {
208 JCVariableDecl tree = new JCVariableDecl(mods, name, vartype);
209 tree.pos = pos;
210 return tree;
211 }
213 public JCSkip Skip() {
214 JCSkip tree = new JCSkip();
215 tree.pos = pos;
216 return tree;
217 }
219 public JCBlock Block(long flags, List<JCStatement> stats) {
220 JCBlock tree = new JCBlock(flags, stats);
221 tree.pos = pos;
222 return tree;
223 }
225 public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
226 JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
227 tree.pos = pos;
228 return tree;
229 }
231 public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
232 JCWhileLoop tree = new JCWhileLoop(cond, body);
233 tree.pos = pos;
234 return tree;
235 }
237 public JCForLoop ForLoop(List<JCStatement> init,
238 JCExpression cond,
239 List<JCExpressionStatement> step,
240 JCStatement body)
241 {
242 JCForLoop tree = new JCForLoop(init, cond, step, body);
243 tree.pos = pos;
244 return tree;
245 }
247 public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
248 JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
249 tree.pos = pos;
250 return tree;
251 }
253 public JCLabeledStatement Labelled(Name label, JCStatement body) {
254 JCLabeledStatement tree = new JCLabeledStatement(label, body);
255 tree.pos = pos;
256 return tree;
257 }
259 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
260 JCSwitch tree = new JCSwitch(selector, cases);
261 tree.pos = pos;
262 return tree;
263 }
265 public JCCase Case(JCExpression pat, List<JCStatement> stats) {
266 JCCase tree = new JCCase(pat, stats);
267 tree.pos = pos;
268 return tree;
269 }
271 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
272 JCSynchronized tree = new JCSynchronized(lock, body);
273 tree.pos = pos;
274 return tree;
275 }
277 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
278 return Try(List.<JCTree>nil(), body, catchers, finalizer);
279 }
281 public JCTry Try(List<JCTree> resources,
282 JCBlock body,
283 List<JCCatch> catchers,
284 JCBlock finalizer) {
285 JCTry tree = new JCTry(resources, body, catchers, finalizer);
286 tree.pos = pos;
287 return tree;
288 }
290 public JCCatch Catch(JCVariableDecl param, JCBlock body) {
291 JCCatch tree = new JCCatch(param, body);
292 tree.pos = pos;
293 return tree;
294 }
296 public JCConditional Conditional(JCExpression cond,
297 JCExpression thenpart,
298 JCExpression elsepart)
299 {
300 JCConditional tree = new JCConditional(cond, thenpart, elsepart);
301 tree.pos = pos;
302 return tree;
303 }
305 public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) {
306 JCIf tree = new JCIf(cond, thenpart, elsepart);
307 tree.pos = pos;
308 return tree;
309 }
311 public JCExpressionStatement Exec(JCExpression expr) {
312 JCExpressionStatement tree = new JCExpressionStatement(expr);
313 tree.pos = pos;
314 return tree;
315 }
317 public JCBreak Break(Name label) {
318 JCBreak tree = new JCBreak(label, null);
319 tree.pos = pos;
320 return tree;
321 }
323 public JCContinue Continue(Name label) {
324 JCContinue tree = new JCContinue(label, null);
325 tree.pos = pos;
326 return tree;
327 }
329 public JCReturn Return(JCExpression expr) {
330 JCReturn tree = new JCReturn(expr);
331 tree.pos = pos;
332 return tree;
333 }
335 public JCThrow Throw(JCExpression expr) {
336 JCThrow tree = new JCThrow(expr);
337 tree.pos = pos;
338 return tree;
339 }
341 public JCAssert Assert(JCExpression cond, JCExpression detail) {
342 JCAssert tree = new JCAssert(cond, detail);
343 tree.pos = pos;
344 return tree;
345 }
347 public JCMethodInvocation Apply(List<JCExpression> typeargs,
348 JCExpression fn,
349 List<JCExpression> args)
350 {
351 JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);
352 tree.pos = pos;
353 return tree;
354 }
356 public JCNewClass NewClass(JCExpression encl,
357 List<JCExpression> typeargs,
358 JCExpression clazz,
359 List<JCExpression> args,
360 JCClassDecl def)
361 {
362 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
363 tree.pos = pos;
364 return tree;
365 }
367 public JCNewArray NewArray(JCExpression elemtype,
368 List<JCExpression> dims,
369 List<JCExpression> elems)
370 {
371 JCNewArray tree = new JCNewArray(elemtype, dims, elems);
372 tree.pos = pos;
373 return tree;
374 }
376 public JCLambda Lambda(List<JCVariableDecl> params,
377 JCTree body)
378 {
379 JCLambda tree = new JCLambda(params, body);
380 tree.pos = pos;
381 return tree;
382 }
384 public JCParens Parens(JCExpression expr) {
385 JCParens tree = new JCParens(expr);
386 tree.pos = pos;
387 return tree;
388 }
390 public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
391 JCAssign tree = new JCAssign(lhs, rhs);
392 tree.pos = pos;
393 return tree;
394 }
396 public JCAssignOp Assignop(JCTree.Tag opcode, JCTree lhs, JCTree rhs) {
397 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
398 tree.pos = pos;
399 return tree;
400 }
402 public JCUnary Unary(JCTree.Tag opcode, JCExpression arg) {
403 JCUnary tree = new JCUnary(opcode, arg);
404 tree.pos = pos;
405 return tree;
406 }
408 public JCBinary Binary(JCTree.Tag opcode, JCExpression lhs, JCExpression rhs) {
409 JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
410 tree.pos = pos;
411 return tree;
412 }
414 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
415 JCTypeCast tree = new JCTypeCast(clazz, expr);
416 tree.pos = pos;
417 return tree;
418 }
420 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
421 JCInstanceOf tree = new JCInstanceOf(expr, clazz);
422 tree.pos = pos;
423 return tree;
424 }
426 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
427 JCArrayAccess tree = new JCArrayAccess(indexed, index);
428 tree.pos = pos;
429 return tree;
430 }
432 public JCFieldAccess Select(JCExpression selected, Name selector) {
433 JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
434 tree.pos = pos;
435 return tree;
436 }
438 public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name,
439 JCExpression expr, List<JCExpression> typeargs) {
440 JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs);
441 tree.pos = pos;
442 return tree;
443 }
445 public JCIdent Ident(Name name) {
446 JCIdent tree = new JCIdent(name, null);
447 tree.pos = pos;
448 return tree;
449 }
451 public JCLiteral Literal(TypeTag tag, Object value) {
452 JCLiteral tree = new JCLiteral(tag, value);
453 tree.pos = pos;
454 return tree;
455 }
457 public JCPrimitiveTypeTree TypeIdent(TypeTag typetag) {
458 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
459 tree.pos = pos;
460 return tree;
461 }
463 public JCArrayTypeTree TypeArray(JCExpression elemtype) {
464 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
465 tree.pos = pos;
466 return tree;
467 }
469 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
470 JCTypeApply tree = new JCTypeApply(clazz, arguments);
471 tree.pos = pos;
472 return tree;
473 }
475 public JCTypeUnion TypeUnion(List<JCExpression> components) {
476 JCTypeUnion tree = new JCTypeUnion(components);
477 tree.pos = pos;
478 return tree;
479 }
481 public JCTypeIntersection TypeIntersection(List<JCExpression> components) {
482 JCTypeIntersection tree = new JCTypeIntersection(components);
483 tree.pos = pos;
484 return tree;
485 }
487 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
488 return TypeParameter(name, bounds, List.<JCAnnotation>nil());
489 }
491 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annos) {
492 JCTypeParameter tree = new JCTypeParameter(name, bounds, annos);
493 tree.pos = pos;
494 return tree;
495 }
497 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
498 JCWildcard tree = new JCWildcard(kind, type);
499 tree.pos = pos;
500 return tree;
501 }
503 public TypeBoundKind TypeBoundKind(BoundKind kind) {
504 TypeBoundKind tree = new TypeBoundKind(kind);
505 tree.pos = pos;
506 return tree;
507 }
509 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
510 JCAnnotation tree = new JCAnnotation(Tag.ANNOTATION, annotationType, args);
511 tree.pos = pos;
512 return tree;
513 }
515 public JCAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) {
516 JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args);
517 tree.pos = pos;
518 return tree;
519 }
521 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
522 JCModifiers tree = new JCModifiers(flags, annotations);
523 boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0;
524 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
525 return tree;
526 }
528 public JCModifiers Modifiers(long flags) {
529 return Modifiers(flags, List.<JCAnnotation>nil());
530 }
532 public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
533 JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
534 tree.pos = pos;
535 return tree;
536 }
538 public JCErroneous Erroneous() {
539 return Erroneous(List.<JCTree>nil());
540 }
542 public JCErroneous Erroneous(List<? extends JCTree> errs) {
543 JCErroneous tree = new JCErroneous(errs);
544 tree.pos = pos;
545 return tree;
546 }
548 public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
549 LetExpr tree = new LetExpr(defs, expr);
550 tree.pos = pos;
551 return tree;
552 }
554 /* ***************************************************************************
555 * Derived building blocks.
556 ****************************************************************************/
558 public JCClassDecl AnonymousClassDef(JCModifiers mods,
559 List<JCTree> defs)
560 {
561 return ClassDef(mods,
562 names.empty,
563 List.<JCTypeParameter>nil(),
564 null,
565 List.<JCExpression>nil(),
566 defs);
567 }
569 public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
570 LetExpr tree = new LetExpr(List.of(def), expr);
571 tree.pos = pos;
572 return tree;
573 }
575 /** Create an identifier from a symbol.
576 */
577 public JCIdent Ident(Symbol sym) {
578 return (JCIdent)new JCIdent((sym.name != names.empty)
579 ? sym.name
580 : sym.flatName(), sym)
581 .setPos(pos)
582 .setType(sym.type);
583 }
585 /** Create a selection node from a qualifier tree and a symbol.
586 * @param base The qualifier tree.
587 */
588 public JCExpression Select(JCExpression base, Symbol sym) {
589 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
590 }
592 /** Create a qualified identifier from a symbol, adding enough qualifications
593 * to make the reference unique.
594 */
595 public JCExpression QualIdent(Symbol sym) {
596 return isUnqualifiable(sym)
597 ? Ident(sym)
598 : Select(QualIdent(sym.owner), sym);
599 }
601 /** Create an identifier that refers to the variable declared in given variable
602 * declaration.
603 */
604 public JCExpression Ident(JCVariableDecl param) {
605 return Ident(param.sym);
606 }
608 /** Create a list of identifiers referring to the variables declared
609 * in given list of variable declarations.
610 */
611 public List<JCExpression> Idents(List<JCVariableDecl> params) {
612 ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>();
613 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
614 ids.append(Ident(l.head));
615 return ids.toList();
616 }
618 /** Create a tree representing `this', given its type.
619 */
620 public JCExpression This(Type t) {
621 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym));
622 }
624 /** Create a tree representing a class literal.
625 */
626 public JCExpression ClassLiteral(ClassSymbol clazz) {
627 return ClassLiteral(clazz.type);
628 }
630 /** Create a tree representing a class literal.
631 */
632 public JCExpression ClassLiteral(Type t) {
633 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
634 names._class,
635 t,
636 t.tsym);
637 return Select(Type(t), lit);
638 }
640 /** Create a tree representing `super', given its type and owner.
641 */
642 public JCIdent Super(Type t, TypeSymbol owner) {
643 return Ident(new VarSymbol(FINAL, names._super, t, owner));
644 }
646 /**
647 * Create a method invocation from a method tree and a list of
648 * argument trees.
649 */
650 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
651 return Apply(null, meth, args).setType(meth.type.getReturnType());
652 }
654 /**
655 * Create a no-arg method invocation from a method tree
656 */
657 public JCMethodInvocation App(JCExpression meth) {
658 return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType());
659 }
661 /** Create a method invocation from a method tree and a list of argument trees.
662 */
663 public JCExpression Create(Symbol ctor, List<JCExpression> args) {
664 Type t = ctor.owner.erasure(types);
665 JCNewClass newclass = NewClass(null, null, Type(t), args, null);
666 newclass.constructor = ctor;
667 newclass.setType(t);
668 return newclass;
669 }
671 /** Create a tree representing given type.
672 */
673 public JCExpression Type(Type t) {
674 if (t == null) return null;
675 JCExpression tp;
676 switch (t.getTag()) {
677 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
678 case DOUBLE: case BOOLEAN: case VOID:
679 tp = TypeIdent(t.getTag());
680 break;
681 case TYPEVAR:
682 tp = Ident(t.tsym);
683 break;
684 case WILDCARD: {
685 WildcardType a = ((WildcardType) t);
686 tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
687 break;
688 }
689 case CLASS:
690 Type outer = t.getEnclosingType();
691 JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP
692 ? Select(Type(outer), t.tsym)
693 : QualIdent(t.tsym);
694 tp = t.getTypeArguments().isEmpty()
695 ? clazz
696 : TypeApply(clazz, Types(t.getTypeArguments()));
697 break;
698 case ARRAY:
699 tp = TypeArray(Type(types.elemtype(t)));
700 break;
701 case ERROR:
702 tp = TypeIdent(ERROR);
703 break;
704 default:
705 throw new AssertionError("unexpected type: " + t);
706 }
707 return tp.setType(t);
708 }
710 /** Create a list of trees representing given list of types.
711 */
712 public List<JCExpression> Types(List<Type> ts) {
713 ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>();
714 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
715 lb.append(Type(l.head));
716 return lb.toList();
717 }
719 /** Create a variable definition from a variable symbol and an initializer
720 * expression.
721 */
722 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
723 return (JCVariableDecl)
724 new JCVariableDecl(
725 Modifiers(v.flags(), Annotations(v.getRawAttributes())),
726 v.name,
727 Type(v.type),
728 init,
729 v).setPos(pos).setType(v.type);
730 }
732 /** Create annotation trees from annotations.
733 */
734 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
735 if (attributes == null) return List.nil();
736 ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
737 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) {
738 Attribute a = i.head;
739 result.append(Annotation(a));
740 }
741 return result.toList();
742 }
744 public JCLiteral Literal(Object value) {
745 JCLiteral result = null;
746 if (value instanceof String) {
747 result = Literal(CLASS, value).
748 setType(syms.stringType.constType(value));
749 } else if (value instanceof Integer) {
750 result = Literal(INT, value).
751 setType(syms.intType.constType(value));
752 } else if (value instanceof Long) {
753 result = Literal(LONG, value).
754 setType(syms.longType.constType(value));
755 } else if (value instanceof Byte) {
756 result = Literal(BYTE, value).
757 setType(syms.byteType.constType(value));
758 } else if (value instanceof Character) {
759 int v = (int) (((Character) value).toString().charAt(0));
760 result = Literal(CHAR, value).
761 setType(syms.charType.constType(v));
762 } else if (value instanceof Double) {
763 result = Literal(DOUBLE, value).
764 setType(syms.doubleType.constType(value));
765 } else if (value instanceof Float) {
766 result = Literal(FLOAT, value).
767 setType(syms.floatType.constType(value));
768 } else if (value instanceof Short) {
769 result = Literal(SHORT, value).
770 setType(syms.shortType.constType(value));
771 } else if (value instanceof Boolean) {
772 int v = ((Boolean) value) ? 1 : 0;
773 result = Literal(BOOLEAN, v).
774 setType(syms.booleanType.constType(v));
775 } else {
776 throw new AssertionError(value);
777 }
778 return result;
779 }
781 class AnnotationBuilder implements Attribute.Visitor {
782 JCExpression result = null;
783 public void visitConstant(Attribute.Constant v) {
784 result = Literal(v.value);
785 }
786 public void visitClass(Attribute.Class clazz) {
787 result = ClassLiteral(clazz.classType).setType(syms.classType);
788 }
789 public void visitEnum(Attribute.Enum e) {
790 result = QualIdent(e.value);
791 }
792 public void visitError(Attribute.Error e) {
793 result = Erroneous();
794 }
795 public void visitCompound(Attribute.Compound compound) {
796 if (compound instanceof Attribute.TypeCompound) {
797 result = visitTypeCompoundInternal((Attribute.TypeCompound) compound);
798 } else {
799 result = visitCompoundInternal(compound);
800 }
801 }
802 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
803 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
804 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
805 Pair<MethodSymbol,Attribute> pair = values.head;
806 JCExpression valueTree = translate(pair.snd);
807 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
808 }
809 return Annotation(Type(compound.type), args.toList());
810 }
811 public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) {
812 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
813 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
814 Pair<MethodSymbol,Attribute> pair = values.head;
815 JCExpression valueTree = translate(pair.snd);
816 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
817 }
818 return TypeAnnotation(Type(compound.type), args.toList());
819 }
820 public void visitArray(Attribute.Array array) {
821 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
822 for (int i = 0; i < array.values.length; i++)
823 elems.append(translate(array.values[i]));
824 result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type);
825 }
826 JCExpression translate(Attribute a) {
827 a.accept(this);
828 return result;
829 }
830 JCAnnotation translate(Attribute.Compound a) {
831 return visitCompoundInternal(a);
832 }
833 JCAnnotation translate(Attribute.TypeCompound a) {
834 return visitTypeCompoundInternal(a);
835 }
836 }
838 AnnotationBuilder annotationBuilder = new AnnotationBuilder();
840 /** Create an annotation tree from an attribute.
841 */
842 public JCAnnotation Annotation(Attribute a) {
843 return annotationBuilder.translate((Attribute.Compound)a);
844 }
846 public JCAnnotation TypeAnnotation(Attribute a) {
847 return annotationBuilder.translate((Attribute.TypeCompound) a);
848 }
850 /** Create a method definition from a method symbol and a method body.
851 */
852 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
853 return MethodDef(m, m.type, body);
854 }
856 /** Create a method definition from a method symbol, method type
857 * and a method body.
858 */
859 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
860 return (JCMethodDecl)
861 new JCMethodDecl(
862 Modifiers(m.flags(), Annotations(m.getRawAttributes())),
863 m.name,
864 Type(mtype.getReturnType()),
865 TypeParams(mtype.getTypeArguments()),
866 null, // receiver type
867 Params(mtype.getParameterTypes(), m),
868 Types(mtype.getThrownTypes()),
869 body,
870 null,
871 m).setPos(pos).setType(mtype);
872 }
874 /** Create a type parameter tree from its name and type.
875 */
876 public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
877 return (JCTypeParameter)
878 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
879 }
881 /** Create a list of type parameter trees from a list of type variables.
882 */
883 public List<JCTypeParameter> TypeParams(List<Type> typarams) {
884 ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
885 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
886 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
887 return tparams.toList();
888 }
890 /** Create a value parameter tree from its name, type, and owner.
891 */
892 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
893 return VarDef(new VarSymbol(0, name, argtype, owner), null);
894 }
896 /** Create a a list of value parameter trees x0, ..., xn from a list of
897 * their types and an their owner.
898 */
899 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
900 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
901 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null;
902 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) {
903 for (VarSymbol param : ((MethodSymbol)owner).params)
904 params.append(VarDef(param, null));
905 } else {
906 int i = 0;
907 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
908 params.append(Param(paramName(i++), l.head, owner));
909 }
910 return params.toList();
911 }
913 /** Wrap a method invocation in an expression statement or return statement,
914 * depending on whether the method invocation expression's type is void.
915 */
916 public JCStatement Call(JCExpression apply) {
917 return apply.type.hasTag(VOID) ? Exec(apply) : Return(apply);
918 }
920 /** Construct an assignment from a variable symbol and a right hand side.
921 */
922 public JCStatement Assignment(Symbol v, JCExpression rhs) {
923 return Exec(Assign(Ident(v), rhs).setType(v.type));
924 }
926 /** Construct an index expression from a variable and an expression.
927 */
928 public JCArrayAccess Indexed(Symbol v, JCExpression index) {
929 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
930 tree.type = ((ArrayType)v.type).elemtype;
931 return tree;
932 }
934 /** Make an attributed type cast expression.
935 */
936 public JCTypeCast TypeCast(Type type, JCExpression expr) {
937 return (JCTypeCast)TypeCast(Type(type), expr).setType(type);
938 }
940 /* ***************************************************************************
941 * Helper methods.
942 ****************************************************************************/
944 /** Can given symbol be referred to in unqualified form?
945 */
946 boolean isUnqualifiable(Symbol sym) {
947 if (sym.name == names.empty ||
948 sym.owner == null ||
949 sym.owner.kind == MTH || sym.owner.kind == VAR) {
950 return true;
951 } else if (sym.kind == TYP && toplevel != null) {
952 Scope.Entry e;
953 e = toplevel.namedImportScope.lookup(sym.name);
954 if (e.scope != null) {
955 return
956 e.sym == sym &&
957 e.next().scope == null;
958 }
959 e = toplevel.packge.members().lookup(sym.name);
960 if (e.scope != null) {
961 return
962 e.sym == sym &&
963 e.next().scope == null;
964 }
965 e = toplevel.starImportScope.lookup(sym.name);
966 if (e.scope != null) {
967 return
968 e.sym == sym &&
969 e.next().scope == null;
970 }
971 }
972 return false;
973 }
975 /** The name of synthetic parameter number `i'.
976 */
977 public Name paramName(int i) { return names.fromString("x" + i); }
979 /** The name of synthetic type parameter number `i'.
980 */
981 public Name typaramName(int i) { return names.fromString("A" + i); }
982 }