Thu, 09 Oct 2008 16:07:38 +0100
6406133: JCDiagnostic.getMessage ignores locale argument
Summary: Compiler API should take into account locale settings
Reviewed-by: jjg
1 /*
2 * Copyright 1999-2008 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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 {
173 JCMethodDecl tree = new JCMethodDecl(mods,
174 name,
175 restype,
176 typarams,
177 params,
178 thrown,
179 body,
180 defaultValue,
181 null);
182 tree.pos = pos;
183 return tree;
184 }
186 public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) {
187 JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null);
188 tree.pos = pos;
189 return tree;
190 }
192 public JCSkip Skip() {
193 JCSkip tree = new JCSkip();
194 tree.pos = pos;
195 return tree;
196 }
198 public JCBlock Block(long flags, List<JCStatement> stats) {
199 JCBlock tree = new JCBlock(flags, stats);
200 tree.pos = pos;
201 return tree;
202 }
204 public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
205 JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
206 tree.pos = pos;
207 return tree;
208 }
210 public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
211 JCWhileLoop tree = new JCWhileLoop(cond, body);
212 tree.pos = pos;
213 return tree;
214 }
216 public JCForLoop ForLoop(List<JCStatement> init,
217 JCExpression cond,
218 List<JCExpressionStatement> step,
219 JCStatement body)
220 {
221 JCForLoop tree = new JCForLoop(init, cond, step, body);
222 tree.pos = pos;
223 return tree;
224 }
226 public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
227 JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
228 tree.pos = pos;
229 return tree;
230 }
232 public JCLabeledStatement Labelled(Name label, JCStatement body) {
233 JCLabeledStatement tree = new JCLabeledStatement(label, body);
234 tree.pos = pos;
235 return tree;
236 }
238 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
239 JCSwitch tree = new JCSwitch(selector, cases);
240 tree.pos = pos;
241 return tree;
242 }
244 public JCCase Case(JCExpression pat, List<JCStatement> stats) {
245 JCCase tree = new JCCase(pat, stats);
246 tree.pos = pos;
247 return tree;
248 }
250 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
251 JCSynchronized tree = new JCSynchronized(lock, body);
252 tree.pos = pos;
253 return tree;
254 }
256 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
257 JCTry tree = new JCTry(body, catchers, finalizer);
258 tree.pos = pos;
259 return tree;
260 }
262 public JCCatch Catch(JCVariableDecl param, JCBlock body) {
263 JCCatch tree = new JCCatch(param, body);
264 tree.pos = pos;
265 return tree;
266 }
268 public JCConditional Conditional(JCExpression cond,
269 JCExpression thenpart,
270 JCExpression elsepart)
271 {
272 JCConditional tree = new JCConditional(cond, thenpart, elsepart);
273 tree.pos = pos;
274 return tree;
275 }
277 public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) {
278 JCIf tree = new JCIf(cond, thenpart, elsepart);
279 tree.pos = pos;
280 return tree;
281 }
283 public JCExpressionStatement Exec(JCExpression expr) {
284 JCExpressionStatement tree = new JCExpressionStatement(expr);
285 tree.pos = pos;
286 return tree;
287 }
289 public JCBreak Break(Name label) {
290 JCBreak tree = new JCBreak(label, null);
291 tree.pos = pos;
292 return tree;
293 }
295 public JCContinue Continue(Name label) {
296 JCContinue tree = new JCContinue(label, null);
297 tree.pos = pos;
298 return tree;
299 }
301 public JCReturn Return(JCExpression expr) {
302 JCReturn tree = new JCReturn(expr);
303 tree.pos = pos;
304 return tree;
305 }
307 public JCThrow Throw(JCTree expr) {
308 JCThrow tree = new JCThrow(expr);
309 tree.pos = pos;
310 return tree;
311 }
313 public JCAssert Assert(JCExpression cond, JCExpression detail) {
314 JCAssert tree = new JCAssert(cond, detail);
315 tree.pos = pos;
316 return tree;
317 }
319 public JCMethodInvocation Apply(List<JCExpression> typeargs,
320 JCExpression fn,
321 List<JCExpression> args)
322 {
323 JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);
324 tree.pos = pos;
325 return tree;
326 }
328 public JCNewClass NewClass(JCExpression encl,
329 List<JCExpression> typeargs,
330 JCExpression clazz,
331 List<JCExpression> args,
332 JCClassDecl def)
333 {
334 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
335 tree.pos = pos;
336 return tree;
337 }
339 public JCNewArray NewArray(JCExpression elemtype,
340 List<JCExpression> dims,
341 List<JCExpression> elems)
342 {
343 JCNewArray tree = new JCNewArray(elemtype, dims, elems);
344 tree.pos = pos;
345 return tree;
346 }
348 public JCParens Parens(JCExpression expr) {
349 JCParens tree = new JCParens(expr);
350 tree.pos = pos;
351 return tree;
352 }
354 public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
355 JCAssign tree = new JCAssign(lhs, rhs);
356 tree.pos = pos;
357 return tree;
358 }
360 public JCAssignOp Assignop(int opcode, JCTree lhs, JCTree rhs) {
361 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
362 tree.pos = pos;
363 return tree;
364 }
366 public JCUnary Unary(int opcode, JCExpression arg) {
367 JCUnary tree = new JCUnary(opcode, arg);
368 tree.pos = pos;
369 return tree;
370 }
372 public JCBinary Binary(int opcode, JCExpression lhs, JCExpression rhs) {
373 JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
374 tree.pos = pos;
375 return tree;
376 }
378 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
379 JCTypeCast tree = new JCTypeCast(clazz, expr);
380 tree.pos = pos;
381 return tree;
382 }
384 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
385 JCInstanceOf tree = new JCInstanceOf(expr, clazz);
386 tree.pos = pos;
387 return tree;
388 }
390 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
391 JCArrayAccess tree = new JCArrayAccess(indexed, index);
392 tree.pos = pos;
393 return tree;
394 }
396 public JCFieldAccess Select(JCExpression selected, Name selector) {
397 JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
398 tree.pos = pos;
399 return tree;
400 }
402 public JCIdent Ident(Name name) {
403 JCIdent tree = new JCIdent(name, null);
404 tree.pos = pos;
405 return tree;
406 }
408 public JCLiteral Literal(int tag, Object value) {
409 JCLiteral tree = new JCLiteral(tag, value);
410 tree.pos = pos;
411 return tree;
412 }
414 public JCPrimitiveTypeTree TypeIdent(int typetag) {
415 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
416 tree.pos = pos;
417 return tree;
418 }
420 public JCArrayTypeTree TypeArray(JCExpression elemtype) {
421 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
422 tree.pos = pos;
423 return tree;
424 }
426 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
427 JCTypeApply tree = new JCTypeApply(clazz, arguments);
428 tree.pos = pos;
429 return tree;
430 }
432 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
433 JCTypeParameter tree = new JCTypeParameter(name, bounds);
434 tree.pos = pos;
435 return tree;
436 }
438 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
439 JCWildcard tree = new JCWildcard(kind, type);
440 tree.pos = pos;
441 return tree;
442 }
444 public TypeBoundKind TypeBoundKind(BoundKind kind) {
445 TypeBoundKind tree = new TypeBoundKind(kind);
446 tree.pos = pos;
447 return tree;
448 }
450 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
451 JCAnnotation tree = new JCAnnotation(annotationType, args);
452 tree.pos = pos;
453 return tree;
454 }
456 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
457 JCModifiers tree = new JCModifiers(flags, annotations);
458 boolean noFlags = (flags & Flags.StandardFlags) == 0;
459 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
460 return tree;
461 }
463 public JCModifiers Modifiers(long flags) {
464 return Modifiers(flags, List.<JCAnnotation>nil());
465 }
467 public JCErroneous Erroneous() {
468 return Erroneous(List.<JCTree>nil());
469 }
471 public JCErroneous Erroneous(List<? extends JCTree> errs) {
472 JCErroneous tree = new JCErroneous(errs);
473 tree.pos = pos;
474 return tree;
475 }
477 public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
478 LetExpr tree = new LetExpr(defs, expr);
479 tree.pos = pos;
480 return tree;
481 }
483 /* ***************************************************************************
484 * Derived building blocks.
485 ****************************************************************************/
487 public JCClassDecl AnonymousClassDef(JCModifiers mods,
488 List<JCTree> defs)
489 {
490 return ClassDef(mods,
491 names.empty,
492 List.<JCTypeParameter>nil(),
493 null,
494 List.<JCExpression>nil(),
495 defs);
496 }
498 public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
499 LetExpr tree = new LetExpr(List.of(def), expr);
500 tree.pos = pos;
501 return tree;
502 }
504 /** Create an identifier from a symbol.
505 */
506 public JCIdent Ident(Symbol sym) {
507 return (JCIdent)new JCIdent((sym.name != names.empty)
508 ? sym.name
509 : sym.flatName(), sym)
510 .setPos(pos)
511 .setType(sym.type);
512 }
514 /** Create a selection node from a qualifier tree and a symbol.
515 * @param base The qualifier tree.
516 */
517 public JCExpression Select(JCExpression base, Symbol sym) {
518 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
519 }
521 /** Create a qualified identifier from a symbol, adding enough qualifications
522 * to make the reference unique.
523 */
524 public JCExpression QualIdent(Symbol sym) {
525 return isUnqualifiable(sym)
526 ? Ident(sym)
527 : Select(QualIdent(sym.owner), sym);
528 }
530 /** Create an identifier that refers to the variable declared in given variable
531 * declaration.
532 */
533 public JCExpression Ident(JCVariableDecl param) {
534 return Ident(param.sym);
535 }
537 /** Create a list of identifiers referring to the variables declared
538 * in given list of variable declarations.
539 */
540 public List<JCExpression> Idents(List<JCVariableDecl> params) {
541 ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>();
542 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
543 ids.append(Ident(l.head));
544 return ids.toList();
545 }
547 /** Create a tree representing `this', given its type.
548 */
549 public JCExpression This(Type t) {
550 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym));
551 }
553 /** Create a tree representing a class literal.
554 */
555 public JCExpression ClassLiteral(ClassSymbol clazz) {
556 return ClassLiteral(clazz.type);
557 }
559 /** Create a tree representing a class literal.
560 */
561 public JCExpression ClassLiteral(Type t) {
562 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
563 names._class,
564 t,
565 t.tsym);
566 return Select(Type(t), lit);
567 }
569 /** Create a tree representing `super', given its type and owner.
570 */
571 public JCIdent Super(Type t, TypeSymbol owner) {
572 return Ident(new VarSymbol(FINAL, names._super, t, owner));
573 }
575 /**
576 * Create a method invocation from a method tree and a list of
577 * argument trees.
578 */
579 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
580 return Apply(null, meth, args).setType(meth.type.getReturnType());
581 }
583 /**
584 * Create a no-arg method invocation from a method tree
585 */
586 public JCMethodInvocation App(JCExpression meth) {
587 return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType());
588 }
590 /** Create a method invocation from a method tree and a list of argument trees.
591 */
592 public JCExpression Create(Symbol ctor, List<JCExpression> args) {
593 Type t = ctor.owner.erasure(types);
594 JCNewClass newclass = NewClass(null, null, Type(t), args, null);
595 newclass.constructor = ctor;
596 newclass.setType(t);
597 return newclass;
598 }
600 /** Create a tree representing given type.
601 */
602 public JCExpression Type(Type t) {
603 if (t == null) return null;
604 JCExpression tp;
605 switch (t.tag) {
606 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
607 case DOUBLE: case BOOLEAN: case VOID:
608 tp = TypeIdent(t.tag);
609 break;
610 case TYPEVAR:
611 tp = Ident(t.tsym);
612 break;
613 case WILDCARD: {
614 WildcardType a = ((WildcardType) t);
615 tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
616 break;
617 }
618 case CLASS:
619 Type outer = t.getEnclosingType();
620 JCExpression clazz = outer.tag == CLASS && t.tsym.owner.kind == TYP
621 ? Select(Type(outer), t.tsym)
622 : QualIdent(t.tsym);
623 tp = t.getTypeArguments().isEmpty()
624 ? clazz
625 : TypeApply(clazz, Types(t.getTypeArguments()));
626 break;
627 case ARRAY:
628 tp = TypeArray(Type(types.elemtype(t)));
629 break;
630 case ERROR:
631 tp = TypeIdent(ERROR);
632 break;
633 default:
634 throw new AssertionError("unexpected type: " + t);
635 }
636 return tp.setType(t);
637 }
638 //where
639 private JCExpression Selectors(JCExpression base, Symbol sym, Symbol limit) {
640 if (sym == limit) return base;
641 else return Select(Selectors(base, sym.owner, limit), sym);
642 }
644 /** Create a list of trees representing given list of types.
645 */
646 public List<JCExpression> Types(List<Type> ts) {
647 ListBuffer<JCExpression> types = new ListBuffer<JCExpression>();
648 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
649 types.append(Type(l.head));
650 return types.toList();
651 }
653 /** Create a variable definition from a variable symbol and an initializer
654 * expression.
655 */
656 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
657 return (JCVariableDecl)
658 new JCVariableDecl(
659 Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())),
660 v.name,
661 Type(v.type),
662 init,
663 v).setPos(pos).setType(v.type);
664 }
666 /** Create annotation trees from annotations.
667 */
668 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
669 if (attributes == null) return List.nil();
670 ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
671 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) {
672 Attribute a = i.head;
673 result.append(Annotation(a));
674 }
675 return result.toList();
676 }
678 public JCLiteral Literal(Object value) {
679 JCLiteral result = null;
680 if (value instanceof String) {
681 result = Literal(CLASS, value).
682 setType(syms.stringType.constType(value));
683 } else if (value instanceof Integer) {
684 result = Literal(INT, value).
685 setType(syms.intType.constType(value));
686 } else if (value instanceof Long) {
687 result = Literal(LONG, value).
688 setType(syms.longType.constType(value));
689 } else if (value instanceof Byte) {
690 result = Literal(BYTE, value).
691 setType(syms.byteType.constType(value));
692 } else if (value instanceof Character) {
693 result = Literal(CHAR, value).
694 setType(syms.charType.constType(value));
695 } else if (value instanceof Double) {
696 result = Literal(DOUBLE, value).
697 setType(syms.doubleType.constType(value));
698 } else if (value instanceof Float) {
699 result = Literal(FLOAT, value).
700 setType(syms.floatType.constType(value));
701 } else if (value instanceof Short) {
702 result = Literal(SHORT, value).
703 setType(syms.shortType.constType(value));
704 } else {
705 throw new AssertionError(value);
706 }
707 return result;
708 }
710 class AnnotationBuilder implements Attribute.Visitor {
711 JCExpression result = null;
712 public void visitConstant(Attribute.Constant v) {
713 result = Literal(v.value);
714 }
715 public void visitClass(Attribute.Class clazz) {
716 result = ClassLiteral(clazz.type).setType(syms.classType);
717 }
718 public void visitEnum(Attribute.Enum e) {
719 result = QualIdent(e.value);
720 }
721 public void visitError(Attribute.Error e) {
722 result = Erroneous();
723 }
724 public void visitCompound(Attribute.Compound compound) {
725 result = visitCompoundInternal(compound);
726 }
727 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
728 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
729 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
730 Pair<MethodSymbol,Attribute> pair = values.head;
731 JCExpression valueTree = translate(pair.snd);
732 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
733 }
734 return Annotation(Type(compound.type), args.toList());
735 }
736 public void visitArray(Attribute.Array array) {
737 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
738 for (int i = 0; i < array.values.length; i++)
739 elems.append(translate(array.values[i]));
740 result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type);
741 }
742 JCExpression translate(Attribute a) {
743 a.accept(this);
744 return result;
745 }
746 JCAnnotation translate(Attribute.Compound a) {
747 return visitCompoundInternal(a);
748 }
749 }
750 AnnotationBuilder annotationBuilder = new AnnotationBuilder();
752 /** Create an annotation tree from an attribute.
753 */
754 public JCAnnotation Annotation(Attribute a) {
755 return annotationBuilder.translate((Attribute.Compound)a);
756 }
758 /** Create a method definition from a method symbol and a method body.
759 */
760 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
761 return MethodDef(m, m.type, body);
762 }
764 /** Create a method definition from a method symbol, method type
765 * and a method body.
766 */
767 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
768 return (JCMethodDecl)
769 new JCMethodDecl(
770 Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())),
771 m.name,
772 Type(mtype.getReturnType()),
773 TypeParams(mtype.getTypeArguments()),
774 Params(mtype.getParameterTypes(), m),
775 Types(mtype.getThrownTypes()),
776 body,
777 null,
778 m).setPos(pos).setType(mtype);
779 }
781 /** Create a type parameter tree from its name and type.
782 */
783 public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
784 return (JCTypeParameter)
785 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
786 }
788 /** Create a list of type parameter trees from a list of type variables.
789 */
790 public List<JCTypeParameter> TypeParams(List<Type> typarams) {
791 ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
792 int i = 0;
793 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
794 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
795 return tparams.toList();
796 }
798 /** Create a value parameter tree from its name, type, and owner.
799 */
800 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
801 return VarDef(new VarSymbol(0, name, argtype, owner), null);
802 }
804 /** Create a a list of value parameter trees x0, ..., xn from a list of
805 * their types and an their owner.
806 */
807 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
808 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
809 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null;
810 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) {
811 for (VarSymbol param : ((MethodSymbol)owner).params)
812 params.append(VarDef(param, null));
813 } else {
814 int i = 0;
815 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
816 params.append(Param(paramName(i++), l.head, owner));
817 }
818 return params.toList();
819 }
821 /** Wrap a method invocation in an expression statement or return statement,
822 * depending on whether the method invocation expression's type is void.
823 */
824 public JCStatement Call(JCExpression apply) {
825 return apply.type.tag == VOID ? Exec(apply) : Return(apply);
826 }
828 /** Construct an assignment from a variable symbol and a right hand side.
829 */
830 public JCStatement Assignment(Symbol v, JCExpression rhs) {
831 return Exec(Assign(Ident(v), rhs).setType(v.type));
832 }
834 /** Construct an index expression from a variable and an expression.
835 */
836 public JCArrayAccess Indexed(Symbol v, JCExpression index) {
837 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
838 tree.type = ((ArrayType)v.type).elemtype;
839 return tree;
840 }
842 /** Make an attributed type cast expression.
843 */
844 public JCTypeCast TypeCast(Type type, JCExpression expr) {
845 return (JCTypeCast)TypeCast(Type(type), expr).setType(type);
846 }
848 /* ***************************************************************************
849 * Helper methods.
850 ****************************************************************************/
852 /** Can given symbol be referred to in unqualified form?
853 */
854 boolean isUnqualifiable(Symbol sym) {
855 if (sym.name == names.empty ||
856 sym.owner == null ||
857 sym.owner.kind == MTH || sym.owner.kind == VAR) {
858 return true;
859 } else if (sym.kind == TYP && toplevel != null) {
860 Scope.Entry e;
861 e = toplevel.namedImportScope.lookup(sym.name);
862 if (e.scope != null) {
863 return
864 e.sym == sym &&
865 e.next().scope == null;
866 }
867 e = toplevel.packge.members().lookup(sym.name);
868 if (e.scope != null) {
869 return
870 e.sym == sym &&
871 e.next().scope == null;
872 }
873 e = toplevel.starImportScope.lookup(sym.name);
874 if (e.scope != null) {
875 return
876 e.sym == sym &&
877 e.next().scope == null;
878 }
879 }
880 return false;
881 }
883 /** The name of synthetic parameter number `i'.
884 */
885 public Name paramName(int i) { return names.fromString("x" + i); }
887 /** The name of synthetic type parameter number `i'.
888 */
889 public Name typaramName(int i) { return names.fromString("A" + i); }
890 }