001: /*
002: * Copyright 1999-2006 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: @Version("@(#)TreeMaker.java 1.78 07/05/05")
048: public class TreeMaker implements JCTree.Factory {
049:
050: /** The context key for the tree factory. */
051: protected static final Context.Key<TreeMaker> treeMakerKey = 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: Name.Table 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 = Name.Table.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, Name.Table names,
091: Types types, Symtab syms) {
092: this .pos = Position.FIRSTPOS;
093: this .toplevel = toplevel;
094: this .names = names;
095: this .types = types;
096: this .syms = syms;
097: }
098:
099: /** Create a new tree maker for a given toplevel.
100: */
101: public TreeMaker forToplevel(JCCompilationUnit toplevel) {
102: return new TreeMaker(toplevel, names, types, syms);
103: }
104:
105: /** Reassign current position.
106: */
107: public TreeMaker at(int pos) {
108: this .pos = pos;
109: return this ;
110: }
111:
112: /** Reassign current position.
113: */
114: public TreeMaker at(DiagnosticPosition pos) {
115: this .pos = (pos == null ? Position.NOPOS : pos
116: .getStartPosition());
117: return this ;
118: }
119:
120: /**
121: * Create given tree node at current position.
122: * @param defs a list of ClassDef, Import, and Skip
123: */
124: public JCCompilationUnit TopLevel(
125: List<JCAnnotation> packageAnnotations, JCExpression pid,
126: List<JCTree> defs) {
127: assert packageAnnotations != null;
128: for (JCTree node : defs)
129: assert node instanceof JCClassDecl
130: || node instanceof JCImport
131: || node instanceof JCSkip
132: || node instanceof JCErroneous
133: || (node instanceof JCExpressionStatement && ((JCExpressionStatement) node).expr instanceof JCErroneous) : node
134: .getClass().getSimpleName();
135: JCCompilationUnit tree = new JCCompilationUnit(
136: packageAnnotations, pid, defs, null, null, null, null);
137: tree.pos = pos;
138: return tree;
139: }
140:
141: public JCImport Import(JCTree qualid, boolean importStatic) {
142: JCImport tree = new JCImport(qualid, importStatic);
143: tree.pos = pos;
144: return tree;
145: }
146:
147: public JCClassDecl ClassDef(JCModifiers mods, Name name,
148: List<JCTypeParameter> typarams, JCTree extending,
149: List<JCExpression> implementing, List<JCTree> defs) {
150: JCClassDecl tree = new JCClassDecl(mods, name, typarams,
151: extending, implementing, defs, null);
152: tree.pos = pos;
153: return tree;
154: }
155:
156: public JCMethodDecl MethodDef(JCModifiers mods, Name name,
157: JCExpression restype, List<JCTypeParameter> typarams,
158: List<JCVariableDecl> params, List<JCExpression> thrown,
159: JCBlock body, JCExpression defaultValue) {
160: JCMethodDecl tree = new JCMethodDecl(mods, name, restype,
161: typarams, params, thrown, body, defaultValue, null);
162: tree.pos = pos;
163: return tree;
164: }
165:
166: public JCVariableDecl VarDef(JCModifiers mods, Name name,
167: JCExpression vartype, JCExpression init) {
168: JCVariableDecl tree = new JCVariableDecl(mods, name, vartype,
169: init, null);
170: tree.pos = pos;
171: return tree;
172: }
173:
174: public JCSkip Skip() {
175: JCSkip tree = new JCSkip();
176: tree.pos = pos;
177: return tree;
178: }
179:
180: public JCBlock Block(long flags, List<JCStatement> stats) {
181: JCBlock tree = new JCBlock(flags, stats);
182: tree.pos = pos;
183: return tree;
184: }
185:
186: public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
187: JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
188: tree.pos = pos;
189: return tree;
190: }
191:
192: public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
193: JCWhileLoop tree = new JCWhileLoop(cond, body);
194: tree.pos = pos;
195: return tree;
196: }
197:
198: public JCForLoop ForLoop(List<JCStatement> init, JCExpression cond,
199: List<JCExpressionStatement> step, JCStatement body) {
200: JCForLoop tree = new JCForLoop(init, cond, step, body);
201: tree.pos = pos;
202: return tree;
203: }
204:
205: public JCEnhancedForLoop ForeachLoop(JCVariableDecl var,
206: JCExpression expr, JCStatement body) {
207: JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
208: tree.pos = pos;
209: return tree;
210: }
211:
212: public JCLabeledStatement Labelled(Name label, JCStatement body) {
213: JCLabeledStatement tree = new JCLabeledStatement(label, body);
214: tree.pos = pos;
215: return tree;
216: }
217:
218: public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
219: JCSwitch tree = new JCSwitch(selector, cases);
220: tree.pos = pos;
221: return tree;
222: }
223:
224: public JCCase Case(JCExpression pat, List<JCStatement> stats) {
225: JCCase tree = new JCCase(pat, stats);
226: tree.pos = pos;
227: return tree;
228: }
229:
230: public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
231: JCSynchronized tree = new JCSynchronized(lock, body);
232: tree.pos = pos;
233: return tree;
234: }
235:
236: public JCTry Try(JCBlock body, List<JCCatch> catchers,
237: JCBlock finalizer) {
238: JCTry tree = new JCTry(body, catchers, finalizer);
239: tree.pos = pos;
240: return tree;
241: }
242:
243: public JCCatch Catch(JCVariableDecl param, JCBlock body) {
244: JCCatch tree = new JCCatch(param, body);
245: tree.pos = pos;
246: return tree;
247: }
248:
249: public JCConditional Conditional(JCExpression cond,
250: JCExpression thenpart, JCExpression elsepart) {
251: JCConditional tree = new JCConditional(cond, thenpart, elsepart);
252: tree.pos = pos;
253: return tree;
254: }
255:
256: public JCIf If(JCExpression cond, JCStatement thenpart,
257: JCStatement elsepart) {
258: JCIf tree = new JCIf(cond, thenpart, elsepart);
259: tree.pos = pos;
260: return tree;
261: }
262:
263: public JCExpressionStatement Exec(JCExpression expr) {
264: JCExpressionStatement tree = new JCExpressionStatement(expr);
265: tree.pos = pos;
266: return tree;
267: }
268:
269: public JCBreak Break(Name label) {
270: JCBreak tree = new JCBreak(label, null);
271: tree.pos = pos;
272: return tree;
273: }
274:
275: public JCContinue Continue(Name label) {
276: JCContinue tree = new JCContinue(label, null);
277: tree.pos = pos;
278: return tree;
279: }
280:
281: public JCReturn Return(JCExpression expr) {
282: JCReturn tree = new JCReturn(expr);
283: tree.pos = pos;
284: return tree;
285: }
286:
287: public JCThrow Throw(JCTree expr) {
288: JCThrow tree = new JCThrow(expr);
289: tree.pos = pos;
290: return tree;
291: }
292:
293: public JCAssert Assert(JCExpression cond, JCExpression detail) {
294: JCAssert tree = new JCAssert(cond, detail);
295: tree.pos = pos;
296: return tree;
297: }
298:
299: public JCMethodInvocation Apply(List<JCExpression> typeargs,
300: JCExpression fn, List<JCExpression> args) {
301: JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn,
302: args);
303: tree.pos = pos;
304: return tree;
305: }
306:
307: public JCNewClass NewClass(JCExpression encl,
308: List<JCExpression> typeargs, JCExpression clazz,
309: List<JCExpression> args, JCClassDecl def) {
310: JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args,
311: def);
312: tree.pos = pos;
313: return tree;
314: }
315:
316: public JCNewArray NewArray(JCExpression elemtype,
317: List<JCExpression> dims, List<JCExpression> elems) {
318: JCNewArray tree = new JCNewArray(elemtype, dims, elems);
319: tree.pos = pos;
320: return tree;
321: }
322:
323: public JCParens Parens(JCExpression expr) {
324: JCParens tree = new JCParens(expr);
325: tree.pos = pos;
326: return tree;
327: }
328:
329: public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
330: JCAssign tree = new JCAssign(lhs, rhs);
331: tree.pos = pos;
332: return tree;
333: }
334:
335: public JCAssignOp Assignop(int opcode, JCTree lhs, JCTree rhs) {
336: JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
337: tree.pos = pos;
338: return tree;
339: }
340:
341: public JCUnary Unary(int opcode, JCExpression arg) {
342: JCUnary tree = new JCUnary(opcode, arg);
343: tree.pos = pos;
344: return tree;
345: }
346:
347: public JCBinary Binary(int opcode, JCExpression lhs,
348: JCExpression rhs) {
349: JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
350: tree.pos = pos;
351: return tree;
352: }
353:
354: public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
355: JCTypeCast tree = new JCTypeCast(clazz, expr);
356: tree.pos = pos;
357: return tree;
358: }
359:
360: public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
361: JCInstanceOf tree = new JCInstanceOf(expr, clazz);
362: tree.pos = pos;
363: return tree;
364: }
365:
366: public JCArrayAccess Indexed(JCExpression indexed,
367: JCExpression index) {
368: JCArrayAccess tree = new JCArrayAccess(indexed, index);
369: tree.pos = pos;
370: return tree;
371: }
372:
373: public JCFieldAccess Select(JCExpression selected, Name selector) {
374: JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
375: tree.pos = pos;
376: return tree;
377: }
378:
379: public JCIdent Ident(Name name) {
380: JCIdent tree = new JCIdent(name, null);
381: tree.pos = pos;
382: return tree;
383: }
384:
385: public JCLiteral Literal(int tag, Object value) {
386: JCLiteral tree = new JCLiteral(tag, value);
387: tree.pos = pos;
388: return tree;
389: }
390:
391: public JCPrimitiveTypeTree TypeIdent(int typetag) {
392: JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
393: tree.pos = pos;
394: return tree;
395: }
396:
397: public JCArrayTypeTree TypeArray(JCExpression elemtype) {
398: JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
399: tree.pos = pos;
400: return tree;
401: }
402:
403: public JCTypeApply TypeApply(JCExpression clazz,
404: List<JCExpression> arguments) {
405: JCTypeApply tree = new JCTypeApply(clazz, arguments);
406: tree.pos = pos;
407: return tree;
408: }
409:
410: public JCTypeParameter TypeParameter(Name name,
411: List<JCExpression> bounds) {
412: JCTypeParameter tree = new JCTypeParameter(name, bounds);
413: tree.pos = pos;
414: return tree;
415: }
416:
417: public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
418: JCWildcard tree = new JCWildcard(kind, type);
419: tree.pos = pos;
420: return tree;
421: }
422:
423: public TypeBoundKind TypeBoundKind(BoundKind kind) {
424: TypeBoundKind tree = new TypeBoundKind(kind);
425: tree.pos = pos;
426: return tree;
427: }
428:
429: public JCAnnotation Annotation(JCTree annotationType,
430: List<JCExpression> args) {
431: JCAnnotation tree = new JCAnnotation(annotationType, args);
432: tree.pos = pos;
433: return tree;
434: }
435:
436: public JCModifiers Modifiers(long flags,
437: List<JCAnnotation> annotations) {
438: JCModifiers tree = new JCModifiers(flags, annotations);
439: boolean noFlags = (flags & Flags.StandardFlags) == 0;
440: tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS
441: : pos;
442: return tree;
443: }
444:
445: public JCModifiers Modifiers(long flags) {
446: return Modifiers(flags, List.<JCAnnotation> nil());
447: }
448:
449: public JCErroneous Erroneous() {
450: return Erroneous(List.<JCTree> nil());
451: }
452:
453: public JCErroneous Erroneous(List<? extends JCTree> errs) {
454: JCErroneous tree = new JCErroneous(errs);
455: tree.pos = pos;
456: return tree;
457: }
458:
459: public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
460: LetExpr tree = new LetExpr(defs, expr);
461: tree.pos = pos;
462: return tree;
463: }
464:
465: /* ***************************************************************************
466: * Derived building blocks.
467: ****************************************************************************/
468:
469: public JCClassDecl AnonymousClassDef(JCModifiers mods,
470: List<JCTree> defs) {
471: return ClassDef(mods, names.empty,
472: List.<JCTypeParameter> nil(), null, List
473: .<JCExpression> nil(), defs);
474: }
475:
476: public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
477: LetExpr tree = new LetExpr(List.of(def), expr);
478: tree.pos = pos;
479: return tree;
480: }
481:
482: /** Create an identifier from a symbol.
483: */
484: public JCIdent Ident(Symbol sym) {
485: return (JCIdent) new JCIdent(
486: (sym.name != names.empty) ? sym.name : sym.flatName(),
487: sym).setPos(pos).setType(sym.type);
488: }
489:
490: /** Create a selection node from a qualifier tree and a symbol.
491: * @param base The qualifier tree.
492: */
493: public JCExpression Select(JCExpression base, Symbol sym) {
494: return new JCFieldAccess(base, sym.name, sym).setPos(pos)
495: .setType(sym.type);
496: }
497:
498: /** Create a qualified identifier from a symbol, adding enough qualifications
499: * to make the reference unique.
500: */
501: public JCExpression QualIdent(Symbol sym) {
502: return isUnqualifiable(sym) ? Ident(sym) : Select(
503: QualIdent(sym.owner), sym);
504: }
505:
506: /** Create an identifier that refers to the variable declared in given variable
507: * declaration.
508: */
509: public JCExpression Ident(JCVariableDecl param) {
510: return Ident(param.sym);
511: }
512:
513: /** Create a list of identifiers referring to the variables declared
514: * in given list of variable declarations.
515: */
516: public List<JCExpression> Idents(List<JCVariableDecl> params) {
517: ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>();
518: for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
519: ids.append(Ident(l.head));
520: return ids.toList();
521: }
522:
523: /** Create a tree representing `this', given its type.
524: */
525: public JCExpression This(Type t) {
526: return Ident(new VarSymbol(FINAL, names._this , t, t.tsym));
527: }
528:
529: /** Create a tree representing a class literal.
530: */
531: public JCExpression ClassLiteral(ClassSymbol clazz) {
532: return ClassLiteral(clazz.type);
533: }
534:
535: /** Create a tree representing a class literal.
536: */
537: public JCExpression ClassLiteral(Type t) {
538: VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
539: names._class, t, t.tsym);
540: return Select(Type(t), lit);
541: }
542:
543: /** Create a tree representing `super', given its type and owner.
544: */
545: public JCIdent Super(Type t, TypeSymbol owner) {
546: return Ident(new VarSymbol(FINAL, names._super , t, owner));
547: }
548:
549: /**
550: * Create a method invocation from a method tree and a list of
551: * argument trees.
552: */
553: public JCMethodInvocation App(JCExpression meth,
554: List<JCExpression> args) {
555: return Apply(null, meth, args).setType(
556: meth.type.getReturnType());
557: }
558:
559: /**
560: * Create a no-arg method invocation from a method tree
561: */
562: public JCMethodInvocation App(JCExpression meth) {
563: return Apply(null, meth, List.<JCExpression> nil()).setType(
564: meth.type.getReturnType());
565: }
566:
567: /** Create a method invocation from a method tree and a list of argument trees.
568: */
569: public JCExpression Create(Symbol ctor, List<JCExpression> args) {
570: Type t = ctor.owner.erasure(types);
571: JCNewClass newclass = NewClass(null, null, Type(t), args, null);
572: newclass.constructor = ctor;
573: newclass.setType(t);
574: return newclass;
575: }
576:
577: /** Create a tree representing given type.
578: */
579: public JCExpression Type(Type t) {
580: if (t == null)
581: return null;
582: JCExpression tp;
583: switch (t.tag) {
584: case BYTE:
585: case CHAR:
586: case SHORT:
587: case INT:
588: case LONG:
589: case FLOAT:
590: case DOUBLE:
591: case BOOLEAN:
592: case VOID:
593: tp = TypeIdent(t.tag);
594: break;
595: case TYPEVAR:
596: tp = Ident(t.tsym);
597: break;
598: case WILDCARD: {
599: WildcardType a = ((WildcardType) t);
600: tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
601: break;
602: }
603: case CLASS:
604: Type outer = t.getEnclosingType();
605: JCExpression clazz = outer.tag == CLASS
606: && t.tsym.owner.kind == TYP ? Select(Type(outer),
607: t.tsym) : QualIdent(t.tsym);
608: tp = t.getTypeArguments().isEmpty() ? clazz : TypeApply(
609: clazz, Types(t.getTypeArguments()));
610: break;
611: case ARRAY:
612: tp = TypeArray(Type(types.elemtype(t)));
613: break;
614: case ERROR:
615: tp = TypeIdent(ERROR);
616: break;
617: default:
618: throw new AssertionError("unexpected type: " + t);
619: }
620: return tp.setType(t);
621: }
622:
623: //where
624: private JCExpression Selectors(JCExpression base, Symbol sym,
625: Symbol limit) {
626: if (sym == limit)
627: return base;
628: else
629: return Select(Selectors(base, sym.owner, limit), sym);
630: }
631:
632: /** Create a list of trees representing given list of types.
633: */
634: public List<JCExpression> Types(List<Type> ts) {
635: ListBuffer<JCExpression> types = new ListBuffer<JCExpression>();
636: for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
637: types.append(Type(l.head));
638: return types.toList();
639: }
640:
641: /** Create a variable definition from a variable symbol and an initializer
642: * expression.
643: */
644: public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
645: return (JCVariableDecl) new JCVariableDecl(Modifiers(v.flags(),
646: Annotations(v.getAnnotationMirrors())), v.name,
647: Type(v.type), init, v).setPos(pos).setType(v.type);
648: }
649:
650: /** Create annotation trees from annotations.
651: */
652: public List<JCAnnotation> Annotations(
653: List<Attribute.Compound> attributes) {
654: if (attributes == null)
655: return List.nil();
656: ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
657: for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i = i.tail) {
658: Attribute a = i.head;
659: result.append(Annotation(a));
660: }
661: return result.toList();
662: }
663:
664: public JCLiteral Literal(Object value) {
665: JCLiteral result = null;
666: if (value instanceof String) {
667: result = Literal(CLASS, value).setType(
668: syms.stringType.constType(value));
669: } else if (value instanceof Integer) {
670: result = Literal(INT, value).setType(
671: syms.intType.constType(value));
672: } else if (value instanceof Long) {
673: result = Literal(LONG, value).setType(
674: syms.longType.constType(value));
675: } else if (value instanceof Byte) {
676: result = Literal(BYTE, value).setType(
677: syms.byteType.constType(value));
678: } else if (value instanceof Character) {
679: result = Literal(CHAR, value).setType(
680: syms.charType.constType(value));
681: } else if (value instanceof Double) {
682: result = Literal(DOUBLE, value).setType(
683: syms.doubleType.constType(value));
684: } else if (value instanceof Float) {
685: result = Literal(FLOAT, value).setType(
686: syms.floatType.constType(value));
687: } else if (value instanceof Short) {
688: result = Literal(SHORT, value).setType(
689: syms.shortType.constType(value));
690: } else {
691: throw new AssertionError(value);
692: }
693: return result;
694: }
695:
696: class AnnotationBuilder implements Attribute.Visitor {
697: JCExpression result = null;
698:
699: public void visitConstant(Attribute.Constant v) {
700: result = Literal(v.value);
701: }
702:
703: public void visitClass(Attribute.Class clazz) {
704: result = ClassLiteral(clazz.type).setType(syms.classType);
705: }
706:
707: public void visitEnum(Attribute.Enum e) {
708: result = QualIdent(e.value);
709: }
710:
711: public void visitError(Attribute.Error e) {
712: result = Erroneous();
713: }
714:
715: public void visitCompound(Attribute.Compound compound) {
716: result = visitCompoundInternal(compound);
717: }
718:
719: public JCAnnotation visitCompoundInternal(
720: Attribute.Compound compound) {
721: ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
722: for (List<Pair<Symbol.MethodSymbol, Attribute>> values = compound.values; values
723: .nonEmpty(); values = values.tail) {
724: Pair<MethodSymbol, Attribute> pair = values.head;
725: JCExpression valueTree = translate(pair.snd);
726: args.append(Assign(Ident(pair.fst), valueTree).setType(
727: valueTree.type));
728: }
729: return Annotation(Type(compound.type), args.toList());
730: }
731:
732: public void visitArray(Attribute.Array array) {
733: ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
734: for (int i = 0; i < array.values.length; i++)
735: elems.append(translate(array.values[i]));
736: result = NewArray(null, List.<JCExpression> nil(),
737: elems.toList()).setType(array.type);
738: }
739:
740: JCExpression translate(Attribute a) {
741: a.accept(this );
742: return result;
743: }
744:
745: JCAnnotation translate(Attribute.Compound a) {
746: return visitCompoundInternal(a);
747: }
748: }
749:
750: AnnotationBuilder annotationBuilder = new AnnotationBuilder();
751:
752: /** Create an annotation tree from an attribute.
753: */
754: public JCAnnotation Annotation(Attribute a) {
755: return annotationBuilder.translate((Attribute.Compound) a);
756: }
757:
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: }
763:
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,
768: JCBlock body) {
769: return (JCMethodDecl) new JCMethodDecl(Modifiers(m.flags(),
770: Annotations(m.getAnnotationMirrors())), m.name,
771: Type(mtype.getReturnType()), TypeParams(mtype
772: .getTypeArguments()), Params(mtype
773: .getParameterTypes(), m), Types(mtype
774: .getThrownTypes()), body, null, m).setPos(pos)
775: .setType(mtype);
776: }
777:
778: /** Create a type parameter tree from its name and type.
779: */
780: public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
781: return (JCTypeParameter) TypeParameter(name,
782: Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
783: }
784:
785: /** Create a list of type parameter trees from a list of type variables.
786: */
787: public List<JCTypeParameter> TypeParams(List<Type> typarams) {
788: ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
789: int i = 0;
790: for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
791: tparams
792: .append(TypeParam(l.head.tsym.name,
793: (TypeVar) l.head));
794: return tparams.toList();
795: }
796:
797: /** Create a value parameter tree from its name, type, and owner.
798: */
799: public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
800: return VarDef(new VarSymbol(0, name, argtype, owner), null);
801: }
802:
803: /** Create a a list of value parameter trees x0, ..., xn from a list of
804: * their types and an their owner.
805: */
806: public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
807: ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
808: MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol) owner)
809: : null;
810: if (mth != null && mth.params != null
811: && argtypes.length() == mth.params.length()) {
812: for (VarSymbol param : ((MethodSymbol) owner).params)
813: params.append(VarDef(param, null));
814: } else {
815: int i = 0;
816: for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
817: params.append(Param(paramName(i++), l.head, owner));
818: }
819: return params.toList();
820: }
821:
822: /** Wrap a method invocation in an expression statement or return statement,
823: * depending on whether the method invocation expression's type is void.
824: */
825: public JCStatement Call(JCExpression apply) {
826: return apply.type.tag == VOID ? Exec(apply) : Return(apply);
827: }
828:
829: /** Construct an assignment from a variable symbol and a right hand side.
830: */
831: public JCStatement Assignment(Symbol v, JCExpression rhs) {
832: return Exec(Assign(Ident(v), rhs).setType(v.type));
833: }
834:
835: /** Construct an index expression from a variable and an expression.
836: */
837: public JCArrayAccess Indexed(Symbol v, JCExpression index) {
838: JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
839: tree.type = ((ArrayType) v.type).elemtype;
840: return tree;
841: }
842:
843: /** Make an attributed type cast expression.
844: */
845: public JCTypeCast TypeCast(Type type, JCExpression expr) {
846: return (JCTypeCast) TypeCast(Type(type), expr).setType(type);
847: }
848:
849: /* ***************************************************************************
850: * Helper methods.
851: ****************************************************************************/
852:
853: /** Can given symbol be referred to in unqualified form?
854: */
855: boolean isUnqualifiable(Symbol sym) {
856: if (sym.name == names.empty || 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 e.sym == sym && e.next().scope == null;
864: }
865: e = toplevel.packge.members().lookup(sym.name);
866: if (e.scope != null) {
867: return e.sym == sym && e.next().scope == null;
868: }
869: e = toplevel.starImportScope.lookup(sym.name);
870: if (e.scope != null) {
871: return e.sym == sym && e.next().scope == null;
872: }
873: }
874: return false;
875: }
876:
877: /** The name of synthetic parameter number `i'.
878: */
879: public Name paramName(int i) {
880: return names.fromString("x" + i);
881: }
882:
883: /** The name of synthetic type parameter number `i'.
884: */
885: public Name typaramName(int i) {
886: return names.fromString("A" + i);
887: }
888: }
|