Mon, 21 Jan 2013 20:15:16 +0000
8005851: Remove support for synchronized interface methods
Summary: Synchronized default methods are no longer supported
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1999, 2012, 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 JCMethodDecl tree = new JCMethodDecl(mods,
173 name,
174 restype,
175 typarams,
176 params,
177 thrown,
178 body,
179 defaultValue,
180 null);
181 tree.pos = pos;
182 return tree;
183 }
185 public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) {
186 JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null);
187 tree.pos = pos;
188 return tree;
189 }
191 public JCSkip Skip() {
192 JCSkip tree = new JCSkip();
193 tree.pos = pos;
194 return tree;
195 }
197 public JCBlock Block(long flags, List<JCStatement> stats) {
198 JCBlock tree = new JCBlock(flags, stats);
199 tree.pos = pos;
200 return tree;
201 }
203 public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) {
204 JCDoWhileLoop tree = new JCDoWhileLoop(body, cond);
205 tree.pos = pos;
206 return tree;
207 }
209 public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) {
210 JCWhileLoop tree = new JCWhileLoop(cond, body);
211 tree.pos = pos;
212 return tree;
213 }
215 public JCForLoop ForLoop(List<JCStatement> init,
216 JCExpression cond,
217 List<JCExpressionStatement> step,
218 JCStatement body)
219 {
220 JCForLoop tree = new JCForLoop(init, cond, step, body);
221 tree.pos = pos;
222 return tree;
223 }
225 public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
226 JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body);
227 tree.pos = pos;
228 return tree;
229 }
231 public JCLabeledStatement Labelled(Name label, JCStatement body) {
232 JCLabeledStatement tree = new JCLabeledStatement(label, body);
233 tree.pos = pos;
234 return tree;
235 }
237 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) {
238 JCSwitch tree = new JCSwitch(selector, cases);
239 tree.pos = pos;
240 return tree;
241 }
243 public JCCase Case(JCExpression pat, List<JCStatement> stats) {
244 JCCase tree = new JCCase(pat, stats);
245 tree.pos = pos;
246 return tree;
247 }
249 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) {
250 JCSynchronized tree = new JCSynchronized(lock, body);
251 tree.pos = pos;
252 return tree;
253 }
255 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) {
256 return Try(List.<JCTree>nil(), body, catchers, finalizer);
257 }
259 public JCTry Try(List<JCTree> resources,
260 JCBlock body,
261 List<JCCatch> catchers,
262 JCBlock finalizer) {
263 JCTry tree = new JCTry(resources, body, catchers, finalizer);
264 tree.pos = pos;
265 return tree;
266 }
268 public JCCatch Catch(JCVariableDecl param, JCBlock body) {
269 JCCatch tree = new JCCatch(param, body);
270 tree.pos = pos;
271 return tree;
272 }
274 public JCConditional Conditional(JCExpression cond,
275 JCExpression thenpart,
276 JCExpression elsepart)
277 {
278 JCConditional tree = new JCConditional(cond, thenpart, elsepart);
279 tree.pos = pos;
280 return tree;
281 }
283 public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) {
284 JCIf tree = new JCIf(cond, thenpart, elsepart);
285 tree.pos = pos;
286 return tree;
287 }
289 public JCExpressionStatement Exec(JCExpression expr) {
290 JCExpressionStatement tree = new JCExpressionStatement(expr);
291 tree.pos = pos;
292 return tree;
293 }
295 public JCBreak Break(Name label) {
296 JCBreak tree = new JCBreak(label, null);
297 tree.pos = pos;
298 return tree;
299 }
301 public JCContinue Continue(Name label) {
302 JCContinue tree = new JCContinue(label, null);
303 tree.pos = pos;
304 return tree;
305 }
307 public JCReturn Return(JCExpression expr) {
308 JCReturn tree = new JCReturn(expr);
309 tree.pos = pos;
310 return tree;
311 }
313 public JCThrow Throw(JCTree expr) {
314 JCThrow tree = new JCThrow(expr);
315 tree.pos = pos;
316 return tree;
317 }
319 public JCAssert Assert(JCExpression cond, JCExpression detail) {
320 JCAssert tree = new JCAssert(cond, detail);
321 tree.pos = pos;
322 return tree;
323 }
325 public JCMethodInvocation Apply(List<JCExpression> typeargs,
326 JCExpression fn,
327 List<JCExpression> args)
328 {
329 JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args);
330 tree.pos = pos;
331 return tree;
332 }
334 public JCNewClass NewClass(JCExpression encl,
335 List<JCExpression> typeargs,
336 JCExpression clazz,
337 List<JCExpression> args,
338 JCClassDecl def)
339 {
340 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def);
341 tree.pos = pos;
342 return tree;
343 }
345 public JCNewArray NewArray(JCExpression elemtype,
346 List<JCExpression> dims,
347 List<JCExpression> elems)
348 {
349 JCNewArray tree = new JCNewArray(elemtype, dims, elems);
350 tree.pos = pos;
351 return tree;
352 }
354 public JCLambda Lambda(List<JCVariableDecl> params,
355 JCTree body)
356 {
357 JCLambda tree = new JCLambda(params, body);
358 tree.pos = pos;
359 return tree;
360 }
362 public JCParens Parens(JCExpression expr) {
363 JCParens tree = new JCParens(expr);
364 tree.pos = pos;
365 return tree;
366 }
368 public JCAssign Assign(JCExpression lhs, JCExpression rhs) {
369 JCAssign tree = new JCAssign(lhs, rhs);
370 tree.pos = pos;
371 return tree;
372 }
374 public JCAssignOp Assignop(JCTree.Tag opcode, JCTree lhs, JCTree rhs) {
375 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null);
376 tree.pos = pos;
377 return tree;
378 }
380 public JCUnary Unary(JCTree.Tag opcode, JCExpression arg) {
381 JCUnary tree = new JCUnary(opcode, arg);
382 tree.pos = pos;
383 return tree;
384 }
386 public JCBinary Binary(JCTree.Tag opcode, JCExpression lhs, JCExpression rhs) {
387 JCBinary tree = new JCBinary(opcode, lhs, rhs, null);
388 tree.pos = pos;
389 return tree;
390 }
392 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) {
393 JCTypeCast tree = new JCTypeCast(clazz, expr);
394 tree.pos = pos;
395 return tree;
396 }
398 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) {
399 JCInstanceOf tree = new JCInstanceOf(expr, clazz);
400 tree.pos = pos;
401 return tree;
402 }
404 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
405 JCArrayAccess tree = new JCArrayAccess(indexed, index);
406 tree.pos = pos;
407 return tree;
408 }
410 public JCFieldAccess Select(JCExpression selected, Name selector) {
411 JCFieldAccess tree = new JCFieldAccess(selected, selector, null);
412 tree.pos = pos;
413 return tree;
414 }
416 public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name,
417 JCExpression expr, List<JCExpression> typeargs) {
418 JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs);
419 tree.pos = pos;
420 return tree;
421 }
423 public JCIdent Ident(Name name) {
424 JCIdent tree = new JCIdent(name, null);
425 tree.pos = pos;
426 return tree;
427 }
429 public JCLiteral Literal(TypeTag tag, Object value) {
430 JCLiteral tree = new JCLiteral(tag, value);
431 tree.pos = pos;
432 return tree;
433 }
435 public JCPrimitiveTypeTree TypeIdent(TypeTag typetag) {
436 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag);
437 tree.pos = pos;
438 return tree;
439 }
441 public JCArrayTypeTree TypeArray(JCExpression elemtype) {
442 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype);
443 tree.pos = pos;
444 return tree;
445 }
447 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) {
448 JCTypeApply tree = new JCTypeApply(clazz, arguments);
449 tree.pos = pos;
450 return tree;
451 }
453 public JCTypeUnion TypeUnion(List<JCExpression> components) {
454 JCTypeUnion tree = new JCTypeUnion(components);
455 tree.pos = pos;
456 return tree;
457 }
459 public JCTypeIntersection TypeIntersection(List<JCExpression> components) {
460 JCTypeIntersection tree = new JCTypeIntersection(components);
461 tree.pos = pos;
462 return tree;
463 }
465 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
466 JCTypeParameter tree = new JCTypeParameter(name, bounds);
467 tree.pos = pos;
468 return tree;
469 }
471 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) {
472 JCWildcard tree = new JCWildcard(kind, type);
473 tree.pos = pos;
474 return tree;
475 }
477 public TypeBoundKind TypeBoundKind(BoundKind kind) {
478 TypeBoundKind tree = new TypeBoundKind(kind);
479 tree.pos = pos;
480 return tree;
481 }
483 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) {
484 JCAnnotation tree = new JCAnnotation(annotationType, args);
485 tree.pos = pos;
486 return tree;
487 }
489 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
490 JCModifiers tree = new JCModifiers(flags, annotations);
491 boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0;
492 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos;
493 return tree;
494 }
496 public JCModifiers Modifiers(long flags) {
497 return Modifiers(flags, List.<JCAnnotation>nil());
498 }
500 public JCErroneous Erroneous() {
501 return Erroneous(List.<JCTree>nil());
502 }
504 public JCErroneous Erroneous(List<? extends JCTree> errs) {
505 JCErroneous tree = new JCErroneous(errs);
506 tree.pos = pos;
507 return tree;
508 }
510 public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) {
511 LetExpr tree = new LetExpr(defs, expr);
512 tree.pos = pos;
513 return tree;
514 }
516 /* ***************************************************************************
517 * Derived building blocks.
518 ****************************************************************************/
520 public JCClassDecl AnonymousClassDef(JCModifiers mods,
521 List<JCTree> defs)
522 {
523 return ClassDef(mods,
524 names.empty,
525 List.<JCTypeParameter>nil(),
526 null,
527 List.<JCExpression>nil(),
528 defs);
529 }
531 public LetExpr LetExpr(JCVariableDecl def, JCTree expr) {
532 LetExpr tree = new LetExpr(List.of(def), expr);
533 tree.pos = pos;
534 return tree;
535 }
537 /** Create an identifier from a symbol.
538 */
539 public JCIdent Ident(Symbol sym) {
540 return (JCIdent)new JCIdent((sym.name != names.empty)
541 ? sym.name
542 : sym.flatName(), sym)
543 .setPos(pos)
544 .setType(sym.type);
545 }
547 /** Create a selection node from a qualifier tree and a symbol.
548 * @param base The qualifier tree.
549 */
550 public JCExpression Select(JCExpression base, Symbol sym) {
551 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type);
552 }
554 /** Create a qualified identifier from a symbol, adding enough qualifications
555 * to make the reference unique.
556 */
557 public JCExpression QualIdent(Symbol sym) {
558 return isUnqualifiable(sym)
559 ? Ident(sym)
560 : Select(QualIdent(sym.owner), sym);
561 }
563 /** Create an identifier that refers to the variable declared in given variable
564 * declaration.
565 */
566 public JCExpression Ident(JCVariableDecl param) {
567 return Ident(param.sym);
568 }
570 /** Create a list of identifiers referring to the variables declared
571 * in given list of variable declarations.
572 */
573 public List<JCExpression> Idents(List<JCVariableDecl> params) {
574 ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>();
575 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail)
576 ids.append(Ident(l.head));
577 return ids.toList();
578 }
580 /** Create a tree representing `this', given its type.
581 */
582 public JCExpression This(Type t) {
583 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym));
584 }
586 /** Create a tree representing a class literal.
587 */
588 public JCExpression ClassLiteral(ClassSymbol clazz) {
589 return ClassLiteral(clazz.type);
590 }
592 /** Create a tree representing a class literal.
593 */
594 public JCExpression ClassLiteral(Type t) {
595 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL,
596 names._class,
597 t,
598 t.tsym);
599 return Select(Type(t), lit);
600 }
602 /** Create a tree representing `super', given its type and owner.
603 */
604 public JCIdent Super(Type t, TypeSymbol owner) {
605 return Ident(new VarSymbol(FINAL, names._super, t, owner));
606 }
608 /**
609 * Create a method invocation from a method tree and a list of
610 * argument trees.
611 */
612 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) {
613 return Apply(null, meth, args).setType(meth.type.getReturnType());
614 }
616 /**
617 * Create a no-arg method invocation from a method tree
618 */
619 public JCMethodInvocation App(JCExpression meth) {
620 return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType());
621 }
623 /** Create a method invocation from a method tree and a list of argument trees.
624 */
625 public JCExpression Create(Symbol ctor, List<JCExpression> args) {
626 Type t = ctor.owner.erasure(types);
627 JCNewClass newclass = NewClass(null, null, Type(t), args, null);
628 newclass.constructor = ctor;
629 newclass.setType(t);
630 return newclass;
631 }
633 /** Create a tree representing given type.
634 */
635 public JCExpression Type(Type t) {
636 if (t == null) return null;
637 JCExpression tp;
638 switch (t.getTag()) {
639 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
640 case DOUBLE: case BOOLEAN: case VOID:
641 tp = TypeIdent(t.getTag());
642 break;
643 case TYPEVAR:
644 tp = Ident(t.tsym);
645 break;
646 case WILDCARD: {
647 WildcardType a = ((WildcardType) t);
648 tp = Wildcard(TypeBoundKind(a.kind), Type(a.type));
649 break;
650 }
651 case CLASS:
652 Type outer = t.getEnclosingType();
653 JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP
654 ? Select(Type(outer), t.tsym)
655 : QualIdent(t.tsym);
656 tp = t.getTypeArguments().isEmpty()
657 ? clazz
658 : TypeApply(clazz, Types(t.getTypeArguments()));
659 break;
660 case ARRAY:
661 tp = TypeArray(Type(types.elemtype(t)));
662 break;
663 case ERROR:
664 tp = TypeIdent(ERROR);
665 break;
666 default:
667 throw new AssertionError("unexpected type: " + t);
668 }
669 return tp.setType(t);
670 }
672 /** Create a list of trees representing given list of types.
673 */
674 public List<JCExpression> Types(List<Type> ts) {
675 ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>();
676 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
677 lb.append(Type(l.head));
678 return lb.toList();
679 }
681 /** Create a variable definition from a variable symbol and an initializer
682 * expression.
683 */
684 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) {
685 return (JCVariableDecl)
686 new JCVariableDecl(
687 Modifiers(v.flags(), Annotations(v.getRawAttributes())),
688 v.name,
689 Type(v.type),
690 init,
691 v).setPos(pos).setType(v.type);
692 }
694 /** Create annotation trees from annotations.
695 */
696 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) {
697 if (attributes == null) return List.nil();
698 ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
699 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) {
700 Attribute a = i.head;
701 result.append(Annotation(a));
702 }
703 return result.toList();
704 }
706 public JCLiteral Literal(Object value) {
707 JCLiteral result = null;
708 if (value instanceof String) {
709 result = Literal(CLASS, value).
710 setType(syms.stringType.constType(value));
711 } else if (value instanceof Integer) {
712 result = Literal(INT, value).
713 setType(syms.intType.constType(value));
714 } else if (value instanceof Long) {
715 result = Literal(LONG, value).
716 setType(syms.longType.constType(value));
717 } else if (value instanceof Byte) {
718 result = Literal(BYTE, value).
719 setType(syms.byteType.constType(value));
720 } else if (value instanceof Character) {
721 int v = (int) (((Character) value).toString().charAt(0));
722 result = Literal(CHAR, value).
723 setType(syms.charType.constType(v));
724 } else if (value instanceof Double) {
725 result = Literal(DOUBLE, value).
726 setType(syms.doubleType.constType(value));
727 } else if (value instanceof Float) {
728 result = Literal(FLOAT, value).
729 setType(syms.floatType.constType(value));
730 } else if (value instanceof Short) {
731 result = Literal(SHORT, value).
732 setType(syms.shortType.constType(value));
733 } else if (value instanceof Boolean) {
734 int v = ((Boolean) value) ? 1 : 0;
735 result = Literal(BOOLEAN, v).
736 setType(syms.booleanType.constType(v));
737 } else {
738 throw new AssertionError(value);
739 }
740 return result;
741 }
743 class AnnotationBuilder implements Attribute.Visitor {
744 JCExpression result = null;
745 public void visitConstant(Attribute.Constant v) {
746 result = Literal(v.value);
747 }
748 public void visitClass(Attribute.Class clazz) {
749 result = ClassLiteral(clazz.classType).setType(syms.classType);
750 }
751 public void visitEnum(Attribute.Enum e) {
752 result = QualIdent(e.value);
753 }
754 public void visitError(Attribute.Error e) {
755 result = Erroneous();
756 }
757 public void visitCompound(Attribute.Compound compound) {
758 result = visitCompoundInternal(compound);
759 }
760 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) {
761 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
762 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) {
763 Pair<MethodSymbol,Attribute> pair = values.head;
764 JCExpression valueTree = translate(pair.snd);
765 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type));
766 }
767 return Annotation(Type(compound.type), args.toList());
768 }
769 public void visitArray(Attribute.Array array) {
770 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
771 for (int i = 0; i < array.values.length; i++)
772 elems.append(translate(array.values[i]));
773 result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type);
774 }
775 JCExpression translate(Attribute a) {
776 a.accept(this);
777 return result;
778 }
779 JCAnnotation translate(Attribute.Compound a) {
780 return visitCompoundInternal(a);
781 }
782 }
783 AnnotationBuilder annotationBuilder = new AnnotationBuilder();
785 /** Create an annotation tree from an attribute.
786 */
787 public JCAnnotation Annotation(Attribute a) {
788 return annotationBuilder.translate((Attribute.Compound)a);
789 }
791 /** Create a method definition from a method symbol and a method body.
792 */
793 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) {
794 return MethodDef(m, m.type, body);
795 }
797 /** Create a method definition from a method symbol, method type
798 * and a method body.
799 */
800 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) {
801 return (JCMethodDecl)
802 new JCMethodDecl(
803 Modifiers(m.flags(), Annotations(m.getRawAttributes())),
804 m.name,
805 Type(mtype.getReturnType()),
806 TypeParams(mtype.getTypeArguments()),
807 Params(mtype.getParameterTypes(), m),
808 Types(mtype.getThrownTypes()),
809 body,
810 null,
811 m).setPos(pos).setType(mtype);
812 }
814 /** Create a type parameter tree from its name and type.
815 */
816 public JCTypeParameter TypeParam(Name name, TypeVar tvar) {
817 return (JCTypeParameter)
818 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar);
819 }
821 /** Create a list of type parameter trees from a list of type variables.
822 */
823 public List<JCTypeParameter> TypeParams(List<Type> typarams) {
824 ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>();
825 int i = 0;
826 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail)
827 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head));
828 return tparams.toList();
829 }
831 /** Create a value parameter tree from its name, type, and owner.
832 */
833 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) {
834 return VarDef(new VarSymbol(0, name, argtype, owner), null);
835 }
837 /** Create a a list of value parameter trees x0, ..., xn from a list of
838 * their types and an their owner.
839 */
840 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) {
841 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
842 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null;
843 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) {
844 for (VarSymbol param : ((MethodSymbol)owner).params)
845 params.append(VarDef(param, null));
846 } else {
847 int i = 0;
848 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
849 params.append(Param(paramName(i++), l.head, owner));
850 }
851 return params.toList();
852 }
854 /** Wrap a method invocation in an expression statement or return statement,
855 * depending on whether the method invocation expression's type is void.
856 */
857 public JCStatement Call(JCExpression apply) {
858 return apply.type.hasTag(VOID) ? Exec(apply) : Return(apply);
859 }
861 /** Construct an assignment from a variable symbol and a right hand side.
862 */
863 public JCStatement Assignment(Symbol v, JCExpression rhs) {
864 return Exec(Assign(Ident(v), rhs).setType(v.type));
865 }
867 /** Construct an index expression from a variable and an expression.
868 */
869 public JCArrayAccess Indexed(Symbol v, JCExpression index) {
870 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index);
871 tree.type = ((ArrayType)v.type).elemtype;
872 return tree;
873 }
875 /** Make an attributed type cast expression.
876 */
877 public JCTypeCast TypeCast(Type type, JCExpression expr) {
878 return (JCTypeCast)TypeCast(Type(type), expr).setType(type);
879 }
881 /* ***************************************************************************
882 * Helper methods.
883 ****************************************************************************/
885 /** Can given symbol be referred to in unqualified form?
886 */
887 boolean isUnqualifiable(Symbol sym) {
888 if (sym.name == names.empty ||
889 sym.owner == null ||
890 sym.owner.kind == MTH || sym.owner.kind == VAR) {
891 return true;
892 } else if (sym.kind == TYP && toplevel != null) {
893 Scope.Entry e;
894 e = toplevel.namedImportScope.lookup(sym.name);
895 if (e.scope != null) {
896 return
897 e.sym == sym &&
898 e.next().scope == null;
899 }
900 e = toplevel.packge.members().lookup(sym.name);
901 if (e.scope != null) {
902 return
903 e.sym == sym &&
904 e.next().scope == null;
905 }
906 e = toplevel.starImportScope.lookup(sym.name);
907 if (e.scope != null) {
908 return
909 e.sym == sym &&
910 e.next().scope == null;
911 }
912 }
913 return false;
914 }
916 /** The name of synthetic parameter number `i'.
917 */
918 public Name paramName(int i) { return names.fromString("x" + i); }
920 /** The name of synthetic type parameter number `i'.
921 */
922 public Name typaramName(int i) { return names.fromString("A" + i); }
923 }