001 /*
002 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package com.sun.tools.javac.tree;
027
028 import com.sun.tools.javac.code.*;
029 import com.sun.tools.javac.code.Symbol.*;
030 import com.sun.tools.javac.code.Type.*;
031 import com.sun.tools.javac.util.*;
032 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
033
034 import com.sun.tools.javac.tree.JCTree.*;
035
036 import static com.sun.tools.javac.code.Flags.*;
037 import static com.sun.tools.javac.code.Kinds.*;
038 import static com.sun.tools.javac.code.TypeTags.*;
039
040 /** Factory class for trees.
041 *
042 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
043 * you write code that depends on this, you do so at your own risk.
044 * This code and its internal interfaces are subject to change or
045 * deletion without notice.</b>
046 */
047 public class TreeMaker implements JCTree.Factory {
048
049 /** The context key for the tree factory. */
050 protected static final Context.Key<TreeMaker> treeMakerKey =
051 new Context.Key<TreeMaker>();
052
053 /** Get the TreeMaker instance. */
054 public static TreeMaker instance(Context context) {
055 TreeMaker instance = context.get(treeMakerKey);
056 if (instance == null)
057 instance = new TreeMaker(context);
058 return instance;
059 }
060
061 /** The position at which subsequent trees will be created.
062 */
063 public int pos = Position.NOPOS;
064
065 /** The toplevel tree to which created trees belong.
066 */
067 public JCCompilationUnit toplevel;
068
069 /** The current name table. */
070 Names names;
071
072 Types types;
073
074 /** The current symbol table. */
075 Symtab syms;
076
077 /** Create a tree maker with null toplevel and NOPOS as initial position.
078 */
079 protected TreeMaker(Context context) {
080 context.put(treeMakerKey, this);
081 this.pos = Position.NOPOS;
082 this.toplevel = null;
083 this.names = Names.instance(context);
084 this.syms = Symtab.instance(context);
085 this.types = Types.instance(context);
086 }
087
088 /** Create a tree maker with a given toplevel and FIRSTPOS as initial position.
089 */
090 TreeMaker(JCCompilationUnit toplevel, Names names, Types types, Symtab syms) {
091 this.pos = Position.FIRSTPOS;
092 this.toplevel = toplevel;
093 this.names = names;
094 this.types = types;
095 this.syms = syms;
096 }
097
098 /** Create a new tree maker for a given toplevel.
099 */
100 public TreeMaker forToplevel(JCCompilationUnit toplevel) {
101 return new TreeMaker(toplevel, names, types, syms);
102 }
103
104 /** Reassign current position.
105 */
106 public TreeMaker at(int pos) {
107 this.pos = pos;
108 return this;
109 }
110
111 /** Reassign current position.
112 */
113 public TreeMaker at(DiagnosticPosition pos) {
114 this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition());
115 return this;
116 }
117
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 }
139
140 public JCImport Import(JCTree qualid, boolean importStatic) {
141 JCImport tree = new JCImport(qualid, importStatic);
142 tree.pos = pos;
143 return tree;
144 }
145
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 }
163
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 }
185
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 }
191
192 public JCSkip Skip() {
193 JCSkip tree = new JCSkip();
194 tree.pos = pos;
195 return tree;
196 }
197
198 public JCBlock Block(long flags, List<JCStatement> stats) {
199 JCBlock tree = new JCBlock(flags, stats);
200 tree.pos = pos;
201 return tree;
202 }
203
204 /* emw4: staging additions */
205 public JCExpression BracketExpr(JCExpression body) {
206 JCExpression tree = new JCBracketExpr(body);
207 tree.pos = pos;
208 return tree;
209 }
210
211 public JCExpression BracketStat(List<JCStatement> body) {
212 JCExpression tree = new JCBracketStat(body);
213 tree.pos = pos;
214 return tree;
215 }
216
217 public JCExpression EscapeExpr(JCExpression body) {
218 JCExpression tree = new JCEscapeExpr(body);
219 tree.pos = pos;
220 return tree;
221 }
222
223 public JCStatement EscapeStat(JCExpression body) {
224 JCStatement tree = new JCEscapeStat(body);
225 tree.pos = pos;
226 return tree;
227 }
228 /* emw4: end staging additions */
229
230 public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
231 JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
232 tree.pos = pos;
233 return tree;
234 }
235
236 public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
237 JCWhileLoop tree = new JCWhileLoop(cond, body);
238 tree.pos = pos;
239 return tree;
240 }
241
242 public JCForLoop ForLoop(List<JCStatement> init,
243 JCExpression cond,
244 List<JCExpressionStatement> step,
245 JCStatement body)
246 {
247 JCForLoop tree = new JCForLoop(init, cond, step, body);
248 tree.pos = pos;
249 return tree;
250 }
251
252 public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
253 JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
254 tree.pos = pos;
255 return tree;
256 }
257
258 public JCLabeledStatement Labelled(Name label, JCStatement body) {
259 JCLabeledStatement tree = new JCLabeledStatement(label, body);
260 tree.pos = pos;
261 return tree;
262 }
263
264 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
265 JCSwitch tree = new JCSwitch(selector, cases);
266 tree.pos = pos;
267 return tree;
268 }
269
270 public JCCase Case(JCExpression pat, List<JCStatement> stats) {
271 JCCase tree = new JCCase(pat, stats);
272 tree.pos = pos;
273 return tree;
274 }
275
276 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
277 JCSynchronized tree = new JCSynchronized(lock, body);
278 tree.pos = pos;
279 return tree;
280 }
281
282 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
283 JCTry tree = new JCTry(body, catchers, finalizer);
284 tree.pos = pos;
285 return tree;
286 }
287
288 public JCCatch Catch(JCVariableDecl param, JCBlock body) {
289 JCCatch tree = new JCCatch(param, body);
290 tree.pos = pos;
291 return tree;
292 }
293
294 public JCConditional Conditional(JCExpression cond,
295 JCExpression thenpart,
296 JCExpression elsepart)
297 {
298 JCConditional tree = new JCConditional(cond, thenpart, elsepart);
299 tree.pos = pos;
300 return tree;
301 }
302
303 public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) {
304 JCIf tree = new JCIf(cond, thenpart, elsepart);
305 tree.pos = pos;
306 return tree;
307 }
308
309 public JCExpressionStatement Exec(JCExpression expr) {
310 JCExpressionStatement tree = new JCExpressionStatement(expr);
311 tree.pos = pos;
312 return tree;
313 }
314
315 public JCBreak Break(Name label) {
316 JCBreak tree = new JCBreak(label, null);
317 tree.pos = pos;
318 return tree;
319 }
320
321 public JCContinue Continue(Name label) {
322 JCContinue tree = new JCContinue(label, null);
323 tree.pos = pos;
324 return tree;
325 }
326
327 public JCReturn Return(JCExpression expr) {
328 JCReturn tree = new JCReturn(expr);
329 tree.pos = pos;
330 return tree;
331 }
332
333 public JCThrow Throw(JCTree expr) {
334 JCThrow tree = new JCThrow(expr);
335 tree.pos = pos;
336 return tree;
337 }
338
339 public JCAssert Assert(JCExpression cond, JCExpression detail) {
340 JCAssert tree = new JCAssert(cond, detail);
341 tree.pos = pos;
342 return tree;
343 }
344
345 public JCMethodInvocation Apply(List<JCExpression> typeargs,
346 JCExpression fn,
347 List<JCExpression> args)
348 {
349 JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);
350 tree.pos = pos;
351 return tree;
352 }
353
354 public JCNewClass NewClass(JCExpression encl,
355 List<JCExpression> typeargs,
356 JCExpression clazz,
357 List<JCExpression> args,
358 JCClassDecl def)
359 {
360 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
361 tree.pos = pos;
362 return tree;
363 }
364
365 public JCNewArray NewArray(JCExpression elemtype,
366 List<JCExpression> dims,
367 List<JCExpression> elems)
368 {
369 JCNewArray tree = new JCNewArray(elemtype, dims, elems);
370 tree.pos = pos;
371 return tree;
372 }
373
374 public JCParens Parens(JCExpression expr) {
375 JCParens tree = new JCParens(expr);
376 tree.pos = pos;
377 return tree;
378 }
379
380 public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
381 JCAssign tree = new JCAssign(lhs, rhs);
382 tree.pos = pos;
383 return tree;
384 }
385
386 public JCAssignOp Assignop(int opcode, JCTree lhs, JCTree rhs) {
387 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
388 tree.pos = pos;
389 return tree;
390 }
391
392 public JCUnary Unary(int opcode, JCExpression arg) {
393 JCUnary tree = new JCUnary(opcode, arg);
394 tree.pos = pos;
395 return tree;
396 }
397
398 public JCBinary Binary(int opcode, JCExpression lhs, JCExpression rhs) {
399 JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
400 tree.pos = pos;
401 return tree;
402 }
403
404 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
405 JCTypeCast tree = new JCTypeCast(clazz, expr);
406 tree.pos = pos;
407 return tree;
408 }
409
410 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
411 JCInstanceOf tree = new JCInstanceOf(expr, clazz);
412 tree.pos = pos;
413 return tree;
414 }
415
416 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
417 JCArrayAccess tree = new JCArrayAccess(indexed, index);
418 tree.pos = pos;
419 return tree;
420 }
421
422 public JCFieldAccess Select(JCExpression selected, Name selector) {
423 JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
424 tree.pos = pos;
425 return tree;
426 }
427
428 public JCIdent Ident(Name name) {
429 JCIdent tree = new JCIdent(name, null);
430 tree.pos = pos;
431 return tree;
432 }
433
434 public JCLiteral Literal(int tag, Object value) {
435 JCLiteral tree = new JCLiteral(tag, value);
436 tree.pos = pos;
437 return tree;
438 }
439
440 public JCPrimitiveTypeTree TypeIdent(int typetag) {
441 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
442 tree.pos = pos;
443 return tree;
444 }
445
446 public JCArrayTypeTree TypeArray(JCExpression elemtype) {
447 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
448 tree.pos = pos;
449 return tree;
450 }
451
452 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
453 JCTypeApply tree = new JCTypeApply(clazz, arguments);
454 tree.pos = pos;
455 return tree;
456 }
457
458 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
459 JCTypeParameter tree = new JCTypeParameter(name, bounds);
460 tree.pos = pos;
461 return tree;
462 }
463
464 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
465 JCWildcard tree = new JCWildcard(kind, type);
466 tree.pos = pos;
467 return tree;
468 }
469
470 public TypeBoundKind TypeBoundKind(BoundKind kind) {
471 TypeBoundKind tree = new TypeBoundKind(kind);
472 tree.pos = pos;
473 return tree;
474 }
475
476 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
477 JCAnnotation tree = new JCAnnotation(annotationType, args);
478 tree.pos = pos;
479 return tree;
480 }
481
482 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
483 JCModifiers tree = new JCModifiers(flags, annotations);
484 boolean noFlags = (flags & Flags.StandardFlags) == 0;
485 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
486 return tree;
487 }
488
489 public JCModifiers Modifiers(long flags) {
490 return Modifiers(flags, List.<JCAnnotation>nil());
491 }
492
493 public JCErroneous Erroneous() {
494 return Erroneous(List.<JCTree>nil());
495 }
496
497 public JCErroneous Erroneous(List<? extends JCTree> errs) {
498 JCErroneous tree = new JCErroneous(errs);
499 tree.pos = pos;
500 return tree;
501 }
502
503 public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
504 LetExpr tree = new LetExpr(defs, expr);
505 tree.pos = pos;
506 return tree;
507 }
508
509 /* ***************************************************************************
510 * Derived building blocks.
511 ****************************************************************************/
512
513 public JCClassDecl AnonymousClassDef(JCModifiers mods,
514 List<JCTree> defs)
515 {
516 return ClassDef(mods,
517 names.empty,
518 List.<JCTypeParameter>nil(),
519 null,
520 List.<JCExpression>nil(),
521 defs);
522 }
523
524 public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
525 LetExpr tree = new LetExpr(List.of(def), expr);
526 tree.pos = pos;
527 return tree;
528 }
529
530 /** Create an identifier from a symbol.
531 */
532 public JCIdent Ident(Symbol sym) {
533 return (JCIdent)new JCIdent((sym.name != names.empty)
534 ? sym.name
535 : sym.flatName(), sym)
536 .setPos(pos)
537 .setType(sym.type);
538 }
539
540 /** Create a selection node from a qualifier tree and a symbol.
541 * @param base The qualifier tree.
542 */
543 public JCExpression Select(JCExpression base, Symbol sym) {
544 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
545 }
546
547 /** Create a qualified identifier from a symbol, adding enough qualifications
548 * to make the reference unique.
549 */
550 public JCExpression QualIdent(Symbol sym) {
551 return isUnqualifiable(sym)
552 ? Ident(sym)
553 : Select(QualIdent(sym.owner), sym);
554 }
555
556 /** Create an identifier that refers to the variable declared in given variable
557 * declaration.
558 */
559 public JCExpression Ident(JCVariableDecl param) {
560 return Ident(param.sym);
561 }
562
563 /** Create a list of identifiers referring to the variables declared
564 * in given list of variable declarations.
565 */
566 public List<JCExpression> Idents(List<JCVariableDecl> params) {
567 ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>();
568 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
569 ids.append(Ident(l.head));
570 return ids.toList();
571 }
572
573 /** Create a tree representing `this', given its type.
574 */
575 public JCExpression This(Type t) {
576 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym));
577 }
578
579 /** Create a tree representing a class literal.
580 */
581 public JCExpression ClassLiteral(ClassSymbol clazz) {
582 return ClassLiteral(clazz.type);
583 }
584
585 /** Create a tree representing a class literal.
586 */
587 public JCExpression ClassLiteral(Type t) {
588 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
589 names._class,
590 t,
591 t.tsym);
592 return Select(Type(t), lit);
593 }
594
595 /** Create a tree representing `super', given its type and owner.
596 */
597 public JCIdent Super(Type t, TypeSymbol owner) {
598 return Ident(new VarSymbol(FINAL, names._super, t, owner));
599 }
600
601 /**
602 * Create a method invocation from a method tree and a list of
603 * argument trees.
604 */
605 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
606 return Apply(null, meth, args).setType(meth.type.getReturnType());
607 }
608
609 /**
610 * Create a no-arg method invocation from a method tree
611 */
612 public JCMethodInvocation App(JCExpression meth) {
613 return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType());
614 }
615
616 /** Create a method invocation from a method tree and a list of argument trees.
617 */
618 public JCExpression Create(Symbol ctor, List<JCExpression> args) {
619 Type t = ctor.owner.erasure(types);
620 JCNewClass newclass = NewClass(null, null, Type(t), args, null);
621 newclass.constructor = ctor;
622 newclass.setType(t);
623 return newclass;
624 }
625
626 /** Create a tree representing given type.
627 */
628 public JCExpression Type(Type t) {
629 if (t == null) return null;
630 JCExpression tp;
631 switch (t.tag) {
632 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
633 case DOUBLE: case BOOLEAN: case VOID:
634 tp = TypeIdent(t.tag);
635 break;
636 case TYPEVAR:
637 tp = Ident(t.tsym);
638 break;
639 case WILDCARD: {
640 WildcardType a = ((WildcardType) t);
641 tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
642 break;
643 }
644 case CLASS:
645 Type outer = t.getEnclosingType();
646 JCExpression clazz = outer.tag == CLASS && t.tsym.owner.kind == TYP
647 ? Select(Type(outer), t.tsym)
648 : QualIdent(t.tsym);
649 tp = t.getTypeArguments().isEmpty()
650 ? clazz
651 : TypeApply(clazz, Types(t.getTypeArguments()));
652 break;
653 case ARRAY:
654 tp = TypeArray(Type(types.elemtype(t)));
655 break;
656 case ERROR:
657 tp = TypeIdent(ERROR);
658 break;
659 default:
660 throw new AssertionError("unexpected type: " + t);
661 }
662 return tp.setType(t);
663 }
664 //where
665 private JCExpression Selectors(JCExpression base, Symbol sym, Symbol limit) {
666 if (sym == limit) return base;
667 else return Select(Selectors(base, sym.owner, limit), sym);
668 }
669
670 /** Create a list of trees representing given list of types.
671 */
672 public List<JCExpression> Types(List<Type> ts) {
673 ListBuffer<JCExpression> types = new ListBuffer<JCExpression>();
674 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
675 types.append(Type(l.head));
676 return types.toList();
677 }
678
679 /** Create a variable definition from a variable symbol and an initializer
680 * expression.
681 */
682 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
683 return (JCVariableDecl)
684 new JCVariableDecl(
685 Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())),
686 v.name,
687 Type(v.type),
688 init,
689 v).setPos(pos).setType(v.type);
690 }
691
692 /** Create annotation trees from annotations.
693 */
694 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
695 if (attributes == null) return List.nil();
696 ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
697 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) {
698 Attribute a = i.head;
699 result.append(Annotation(a));
700 }
701 return result.toList();
702 }
703
704 public JCLiteral Literal(Object value) {
705 JCLiteral result = null;
706 if (value instanceof String) {
707 result = Literal(CLASS, value).
708 setType(syms.stringType.constType(value));
709 } else if (value instanceof Integer) {
710 result = Literal(INT, value).
711 setType(syms.intType.constType(value));
712 } else if (value instanceof Long) {
713 result = Literal(LONG, value).
714 setType(syms.longType.constType(value));
715 } else if (value instanceof Byte) {
716 result = Literal(BYTE, value).
717 setType(syms.byteType.constType(value));
718 } else if (value instanceof Character) {
719 result = Literal(CHAR, value).
720 setType(syms.charType.constType(value));
721 } else if (value instanceof Double) {
722 result = Literal(DOUBLE, value).
723 setType(syms.doubleType.constType(value));
724 } else if (value instanceof Float) {
725 result = Literal(FLOAT, value).
726 setType(syms.floatType.constType(value));
727 } else if (value instanceof Short) {
728 result = Literal(SHORT, value).
729 setType(syms.shortType.constType(value));
730 } else {
731 throw new AssertionError(value);
732 }
733 return result;
734 }
735
736 class AnnotationBuilder implements Attribute.Visitor {
737 JCExpression result = null;
738 public void visitConstant(Attribute.Constant v) {
739 result = Literal(v.value);
740 }
741 public void visitClass(Attribute.Class clazz) {
742 result = ClassLiteral(clazz.type).setType(syms.classType);
743 }
744 public void visitEnum(Attribute.Enum e) {
745 result = QualIdent(e.value);
746 }
747 public void visitError(Attribute.Error e) {
748 result = Erroneous();
749 }
750 public void visitCompound(Attribute.Compound compound) {
751 result = visitCompoundInternal(compound);
752 }
753 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
754 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
755 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
756 Pair<MethodSymbol,Attribute> pair = values.head;
757 JCExpression valueTree = translate(pair.snd);
758 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
759 }
760 return Annotation(Type(compound.type), args.toList());
761 }
762 public void visitArray(Attribute.Array array) {
763 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
764 for (int i = 0; i < array.values.length; i++)
765 elems.append(translate(array.values[i]));
766 result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type);
767 }
768 JCExpression translate(Attribute a) {
769 a.accept(this);
770 return result;
771 }
772 JCAnnotation translate(Attribute.Compound a) {
773 return visitCompoundInternal(a);
774 }
775 }
776 AnnotationBuilder annotationBuilder = new AnnotationBuilder();
777
778 /** Create an annotation tree from an attribute.
779 */
780 public JCAnnotation Annotation(Attribute a) {
781 return annotationBuilder.translate((Attribute.Compound)a);
782 }
783
784 /** Create a method definition from a method symbol and a method body.
785 */
786 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
787 return MethodDef(m, m.type, body);
788 }
789
790 /** Create a method definition from a method symbol, method type
791 * and a method body.
792 */
793 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
794 return (JCMethodDecl)
795 new JCMethodDecl(
796 Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())),
797 m.name,
798 Type(mtype.getReturnType()),
799 TypeParams(mtype.getTypeArguments()),
800 Params(mtype.getParameterTypes(), m),
801 Types(mtype.getThrownTypes()),
802 body,
803 null,
804 m).setPos(pos).setType(mtype);
805 }
806
807 /** Create a type parameter tree from its name and type.
808 */
809 public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
810 return (JCTypeParameter)
811 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
812 }
813
814 /** Create a list of type parameter trees from a list of type variables.
815 */
816 public List<JCTypeParameter> TypeParams(List<Type> typarams) {
817 ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
818 int i = 0;
819 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
820 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
821 return tparams.toList();
822 }
823
824 /** Create a value parameter tree from its name, type, and owner.
825 */
826 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
827 return VarDef(new VarSymbol(0, name, argtype, owner), null);
828 }
829
830 /** Create a a list of value parameter trees x0, ..., xn from a list of
831 * their types and an their owner.
832 */
833 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
834 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
835 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null;
836 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) {
837 for (VarSymbol param : ((MethodSymbol)owner).params)
838 params.append(VarDef(param, null));
839 } else {
840 int i = 0;
841 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
842 params.append(Param(paramName(i++), l.head, owner));
843 }
844 return params.toList();
845 }
846
847 /** Wrap a method invocation in an expression statement or return statement,
848 * depending on whether the method invocation expression's type is void.
849 */
850 public JCStatement Call(JCExpression apply) {
851 return apply.type.tag == VOID ? Exec(apply) : Return(apply);
852 }
853
854 /** Construct an assignment from a variable symbol and a right hand side.
855 */
856 public JCStatement Assignment(Symbol v, JCExpression rhs) {
857 return Exec(Assign(Ident(v), rhs).setType(v.type));
858 }
859
860 /** Construct an index expression from a variable and an expression.
861 */
862 public JCArrayAccess Indexed(Symbol v, JCExpression index) {
863 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
864 tree.type = ((ArrayType)v.type).elemtype;
865 return tree;
866 }
867
868 /** Make an attributed type cast expression.
869 */
870 public JCTypeCast TypeCast(Type type, JCExpression expr) {
871 return (JCTypeCast)TypeCast(Type(type), expr).setType(type);
872 }
873
874 /* ***************************************************************************
875 * Helper methods.
876 ****************************************************************************/
877
878 /** Can given symbol be referred to in unqualified form?
879 */
880 boolean isUnqualifiable(Symbol sym) {
881 if (sym.name == names.empty ||
882 sym.owner == null ||
883 sym.owner.kind == MTH || sym.owner.kind == VAR) {
884 return true;
885 } else if (sym.kind == TYP && toplevel != null) {
886 Scope.Entry e;
887 e = toplevel.namedImportScope.lookup(sym.name);
888 if (e.scope != null) {
889 return
890 e.sym == sym &&
891 e.next().scope == null;
892 }
893 e = toplevel.packge.members().lookup(sym.name);
894 if (e.scope != null) {
895 return
896 e.sym == sym &&
897 e.next().scope == null;
898 }
899 e = toplevel.starImportScope.lookup(sym.name);
900 if (e.scope != null) {
901 return
902 e.sym == sym &&
903 e.next().scope == null;
904 }
905 }
906 return false;
907 }
908
909 /** The name of synthetic parameter number `i'.
910 */
911 public Name paramName(int i) { return names.fromString("x" + i); }
912
913 /** The name of synthetic type parameter number `i'.
914 */
915 public Name typaramName(int i) { return names.fromString("A" + i); }
916 }