1 /* 2 * Copyright (c) 1999, 2011, 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 */ 25 26 package com.sun.tools.javac.tree; 27 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; 33 34 import com.sun.tools.javac.tree.JCTree.*; 35 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.*; 39 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 { 48 49 /** The context key for the tree factory. */ 50 protected static final Context.Key<TreeMaker> treeMakerKey = 51 new Context.Key<TreeMaker>(); 52 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 } 60 61 /** The position at which subsequent trees will be created. 62 */ 63 public int pos = Position.NOPOS; 64 65 /** The toplevel tree to which created trees belong. 66 */ 67 public JCCompilationUnit toplevel; 68 69 /** The current name table. */ 70 Names names; 71 72 Types types; 73 74 /** The current symbol table. */ 75 Symtab syms; 76 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 } 87 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 } 97 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 } 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.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 } 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 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 } 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 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 } 184 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 } 190 191 public JCSkip Skip() { 192 JCSkip tree = new JCSkip(); 193 tree.pos = pos; 194 return tree; 195 } 196 197 public JCBlock Block(long flags, List<JCStatement> stats) { 198 JCBlock tree = new JCBlock(flags, stats); 199 tree.pos = pos; 200 return tree; 201 } 202 203 public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) { 204 JCDoWhileLoop tree = new JCDoWhileLoop(body, cond); 205 tree.pos = pos; 206 return tree; 207 } 208 209 public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) { 210 JCWhileLoop tree = new JCWhileLoop(cond, body); 211 tree.pos = pos; 212 return tree; 213 } 214 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 } 224 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 } 230 231 public JCLabeledStatement Labelled(Name label, JCStatement body) { 232 JCLabeledStatement tree = new JCLabeledStatement(label, body); 233 tree.pos = pos; 234 return tree; 235 } 236 237 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) { 238 JCSwitch tree = new JCSwitch(selector, cases); 239 tree.pos = pos; 240 return tree; 241 } 242 243 public JCCase Case(JCExpression pat, List<JCStatement> stats) { 244 JCCase tree = new JCCase(pat, stats); 245 tree.pos = pos; 246 return tree; 247 } 248 249 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) { 250 JCSynchronized tree = new JCSynchronized(lock, body); 251 tree.pos = pos; 252 return tree; 253 } 254 255 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) { 256 return Try(List.<JCTree>nil(), body, catchers, finalizer); 257 } 258 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 } 267 268 public JCCatch Catch(JCVariableDecl param, JCBlock body) { 269 JCCatch tree = new JCCatch(param, body); 270 tree.pos = pos; 271 return tree; 272 } 273 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 } 282 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 } 288 289 public JCExpressionStatement Exec(JCExpression expr) { 290 JCExpressionStatement tree = new JCExpressionStatement(expr); 291 tree.pos = pos; 292 return tree; 293 } 294 295 public JCBreak Break(Name label) { 296 JCBreak tree = new JCBreak(label, null); 297 tree.pos = pos; 298 return tree; 299 } 300 301 public JCContinue Continue(Name label) { 302 JCContinue tree = new JCContinue(label, null); 303 tree.pos = pos; 304 return tree; 305 } 306 307 public JCReturn Return(JCExpression expr) { 308 JCReturn tree = new JCReturn(expr); 309 tree.pos = pos; 310 return tree; 311 } 312 313 public JCThrow Throw(JCTree expr) { 314 JCThrow tree = new JCThrow(expr); 315 tree.pos = pos; 316 return tree; 317 } 318 319 public JCAssert Assert(JCExpression cond, JCExpression detail) { 320 JCAssert tree = new JCAssert(cond, detail); 321 tree.pos = pos; 322 return tree; 323 } 324 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 } 333 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 } 344 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 } 353 354 public JCParens Parens(JCExpression expr) { 355 JCParens tree = new JCParens(expr); 356 tree.pos = pos; 357 return tree; 358 } 359 360 public JCAssign Assign(JCExpression lhs, JCExpression rhs) { 361 JCAssign tree = new JCAssign(lhs, rhs); 362 tree.pos = pos; 363 return tree; 364 } 365 366 public JCAssignOp Assignop(JCTree.Tag opcode, JCTree lhs, JCTree rhs) { 367 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null); 368 tree.pos = pos; 369 return tree; 370 } 371 372 public JCUnary Unary(JCTree.Tag opcode, JCExpression arg) { 373 JCUnary tree = new JCUnary(opcode, arg); 374 tree.pos = pos; 375 return tree; 376 } 377 378 public JCBinary Binary(JCTree.Tag opcode, JCExpression lhs, JCExpression rhs) { 379 JCBinary tree = new JCBinary(opcode, lhs, rhs, null); 380 tree.pos = pos; 381 return tree; 382 } 383 384 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) { 385 JCTypeCast tree = new JCTypeCast(clazz, expr); 386 tree.pos = pos; 387 return tree; 388 } 389 390 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) { 391 JCInstanceOf tree = new JCInstanceOf(expr, clazz); 392 tree.pos = pos; 393 return tree; 394 } 395 396 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) { 397 JCArrayAccess tree = new JCArrayAccess(indexed, index); 398 tree.pos = pos; 399 return tree; 400 } 401 402 public JCFieldAccess Select(JCExpression selected, Name selector) { 403 JCFieldAccess tree = new JCFieldAccess(selected, selector, null); 404 tree.pos = pos; 405 return tree; 406 } 407 408 public JCIdent Ident(Name name) { 409 JCIdent tree = new JCIdent(name, null); 410 tree.pos = pos; 411 return tree; 412 } 413 414 public JCLiteral Literal(int tag, Object value) { 415 JCLiteral tree = new JCLiteral(tag, value); 416 tree.pos = pos; 417 return tree; 418 } 419 420 public JCPrimitiveTypeTree TypeIdent(int typetag) { 421 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag); 422 tree.pos = pos; 423 return tree; 424 } 425 426 public JCArrayTypeTree TypeArray(JCExpression elemtype) { 427 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype); 428 tree.pos = pos; 429 return tree; 430 } 431 432 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) { 433 JCTypeApply tree = new JCTypeApply(clazz, arguments); 434 tree.pos = pos; 435 return tree; 436 } 437 438 public JCTypeUnion TypeUnion(List<JCExpression> components) { 439 JCTypeUnion tree = new JCTypeUnion(components); 440 tree.pos = pos; 441 return tree; 442 } 443 444 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) { 445 JCTypeParameter tree = new JCTypeParameter(name, bounds); 446 tree.pos = pos; 447 return tree; 448 } 449 450 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) { 451 JCWildcard tree = new JCWildcard(kind, type); 452 tree.pos = pos; 453 return tree; 454 } 455 456 public TypeBoundKind TypeBoundKind(BoundKind kind) { 457 TypeBoundKind tree = new TypeBoundKind(kind); 458 tree.pos = pos; 459 return tree; 460 } 461 462 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) { 463 JCAnnotation tree = new JCAnnotation(annotationType, args); 464 tree.pos = pos; 465 return tree; 466 } 467 468 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) { 469 JCModifiers tree = new JCModifiers(flags, annotations); 470 boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0; 471 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos; 472 return tree; 473 } 474 475 public JCModifiers Modifiers(long flags) { 476 return Modifiers(flags, List.<JCAnnotation>nil()); 477 } 478 479 public JCErroneous Erroneous() { 480 return Erroneous(List.<JCTree>nil()); 481 } 482 483 public JCErroneous Erroneous(List<? extends JCTree> errs) { 484 JCErroneous tree = new JCErroneous(errs); 485 tree.pos = pos; 486 return tree; 487 } 488 489 public LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr) { 490 LetExpr tree = new LetExpr(defs, expr); 491 tree.pos = pos; 492 return tree; 493 } 494 495 /* *************************************************************************** 496 * Derived building blocks. 497 ****************************************************************************/ 498 499 public JCClassDecl AnonymousClassDef(JCModifiers mods, 500 List<JCTree> defs) 501 { 502 return ClassDef(mods, 503 names.empty, 504 List.<JCTypeParameter>nil(), 505 null, 506 List.<JCExpression>nil(), 507 defs); 508 } 509 510 public LetExpr LetExpr(JCVariableDecl def, JCTree expr) { 511 LetExpr tree = new LetExpr(List.of(def), expr); 512 tree.pos = pos; 513 return tree; 514 } 515 516 /** Create an identifier from a symbol. 517 */ 518 public JCIdent Ident(Symbol sym) { 519 return (JCIdent)new JCIdent((sym.name != names.empty) 520 ? sym.name 521 : sym.flatName(), sym) 522 .setPos(pos) 523 .setType(sym.type); 524 } 525 526 /** Create a selection node from a qualifier tree and a symbol. 527 * @param base The qualifier tree. 528 */ 529 public JCExpression Select(JCExpression base, Symbol sym) { 530 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type); 531 } 532 533 /** Create a qualified identifier from a symbol, adding enough qualifications 534 * to make the reference unique. 535 */ 536 public JCExpression QualIdent(Symbol sym) { 537 return isUnqualifiable(sym) 538 ? Ident(sym) 539 : Select(QualIdent(sym.owner), sym); 540 } 541 542 /** Create an identifier that refers to the variable declared in given variable 543 * declaration. 544 */ 545 public JCExpression Ident(JCVariableDecl param) { 546 return Ident(param.sym); 547 } 548 549 /** Create a list of identifiers referring to the variables declared 550 * in given list of variable declarations. 551 */ 552 public List<JCExpression> Idents(List<JCVariableDecl> params) { 553 ListBuffer<JCExpression> ids = new ListBuffer<JCExpression>(); 554 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) 555 ids.append(Ident(l.head)); 556 return ids.toList(); 557 } 558 559 /** Create a tree representing `this', given its type. 560 */ 561 public JCExpression This(Type t) { 562 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym)); 563 } 564 565 /** Create a tree representing a class literal. 566 */ 567 public JCExpression ClassLiteral(ClassSymbol clazz) { 568 return ClassLiteral(clazz.type); 569 } 570 571 /** Create a tree representing a class literal. 572 */ 573 public JCExpression ClassLiteral(Type t) { 574 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL, 575 names._class, 576 t, 577 t.tsym); 578 return Select(Type(t), lit); 579 } 580 581 /** Create a tree representing `super', given its type and owner. 582 */ 583 public JCIdent Super(Type t, TypeSymbol owner) { 584 return Ident(new VarSymbol(FINAL, names._super, t, owner)); 585 } 586 587 /** 588 * Create a method invocation from a method tree and a list of 589 * argument trees. 590 */ 591 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) { 592 return Apply(null, meth, args).setType(meth.type.getReturnType()); 593 } 594 595 /** 596 * Create a no-arg method invocation from a method tree 597 */ 598 public JCMethodInvocation App(JCExpression meth) { 599 return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType()); 600 } 601 602 /** Create a method invocation from a method tree and a list of argument trees. 603 */ 604 public JCExpression Create(Symbol ctor, List<JCExpression> args) { 605 Type t = ctor.owner.erasure(types); 606 JCNewClass newclass = NewClass(null, null, Type(t), args, null); 607 newclass.constructor = ctor; 608 newclass.setType(t); 609 return newclass; 610 } 611 612 /** Create a tree representing given type. 613 */ 614 public JCExpression Type(Type t) { 615 if (t == null) return null; 616 JCExpression tp; 617 switch (t.tag) { 618 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 619 case DOUBLE: case BOOLEAN: case VOID: 620 tp = TypeIdent(t.tag); 621 break; 622 case TYPEVAR: 623 tp = Ident(t.tsym); 624 break; 625 case WILDCARD: { 626 WildcardType a = ((WildcardType) t); 627 tp = Wildcard(TypeBoundKind(a.kind), Type(a.type)); 628 break; 629 } 630 case CLASS: 631 Type outer = t.getEnclosingType(); 632 JCExpression clazz = outer.tag == CLASS && t.tsym.owner.kind == TYP 633 ? Select(Type(outer), t.tsym) 634 : QualIdent(t.tsym); 635 tp = t.getTypeArguments().isEmpty() 636 ? clazz 637 : TypeApply(clazz, Types(t.getTypeArguments())); 638 break; 639 case ARRAY: 640 tp = TypeArray(Type(types.elemtype(t))); 641 break; 642 case ERROR: 643 tp = TypeIdent(ERROR); 644 break; 645 default: 646 throw new AssertionError("unexpected type: " + t); 647 } 648 return tp.setType(t); 649 } 650 651 /** Create a list of trees representing given list of types. 652 */ 653 public List<JCExpression> Types(List<Type> ts) { 654 ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>(); 655 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 656 lb.append(Type(l.head)); 657 return lb.toList(); 658 } 659 660 /** Create a variable definition from a variable symbol and an initializer 661 * expression. 662 */ 663 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) { 664 return (JCVariableDecl) 665 new JCVariableDecl( 666 Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())), 667 v.name, 668 Type(v.type), 669 init, 670 v).setPos(pos).setType(v.type); 671 } 672 673 /** Create annotation trees from annotations. 674 */ 675 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) { 676 if (attributes == null) return List.nil(); 677 ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>(); 678 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) { 679 Attribute a = i.head; 680 result.append(Annotation(a)); 681 } 682 return result.toList(); 683 } 684 685 public JCLiteral Literal(Object value) { 686 JCLiteral result = null; 687 if (value instanceof String) { 688 result = Literal(CLASS, value). 689 setType(syms.stringType.constType(value)); 690 } else if (value instanceof Integer) { 691 result = Literal(INT, value). 692 setType(syms.intType.constType(value)); 693 } else if (value instanceof Long) { 694 result = Literal(LONG, value). 695 setType(syms.longType.constType(value)); 696 } else if (value instanceof Byte) { 697 result = Literal(BYTE, value). 698 setType(syms.byteType.constType(value)); 699 } else if (value instanceof Character) { 700 int v = (int) (((Character) value).toString().charAt(0)); 701 result = Literal(CHAR, value). 702 setType(syms.charType.constType(v)); 703 } else if (value instanceof Double) { 704 result = Literal(DOUBLE, value). 705 setType(syms.doubleType.constType(value)); 706 } else if (value instanceof Float) { 707 result = Literal(FLOAT, value). 708 setType(syms.floatType.constType(value)); 709 } else if (value instanceof Short) { 710 result = Literal(SHORT, value). 711 setType(syms.shortType.constType(value)); 712 } else if (value instanceof Boolean) { 713 int v = ((Boolean) value) ? 1 : 0; 714 result = Literal(BOOLEAN, v). 715 setType(syms.booleanType.constType(v)); 716 } else { 717 throw new AssertionError(value); 718 } 719 return result; 720 } 721 722 class AnnotationBuilder implements Attribute.Visitor { 723 JCExpression result = null; 724 public void visitConstant(Attribute.Constant v) { 725 result = Literal(v.value); 726 } 727 public void visitClass(Attribute.Class clazz) { 728 result = ClassLiteral(clazz.type).setType(syms.classType); 729 } 730 public void visitEnum(Attribute.Enum e) { 731 result = QualIdent(e.value); 732 } 733 public void visitError(Attribute.Error e) { 734 result = Erroneous(); 735 } 736 public void visitCompound(Attribute.Compound compound) { 737 result = visitCompoundInternal(compound); 738 } 739 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) { 740 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 741 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) { 742 Pair<MethodSymbol,Attribute> pair = values.head; 743 JCExpression valueTree = translate(pair.snd); 744 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type)); 745 } 746 return Annotation(Type(compound.type), args.toList()); 747 } 748 public void visitArray(Attribute.Array array) { 749 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>(); 750 for (int i = 0; i < array.values.length; i++) 751 elems.append(translate(array.values[i])); 752 result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type); 753 } 754 JCExpression translate(Attribute a) { 755 a.accept(this); 756 return result; 757 } 758 JCAnnotation translate(Attribute.Compound a) { 759 return visitCompoundInternal(a); 760 } 761 } 762 AnnotationBuilder annotationBuilder = new AnnotationBuilder(); 763 764 /** Create an annotation tree from an attribute. 765 */ 766 public JCAnnotation Annotation(Attribute a) { 767 return annotationBuilder.translate((Attribute.Compound)a); 768 } 769 770 /** Create a method definition from a method symbol and a method body. 771 */ 772 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) { 773 return MethodDef(m, m.type, body); 774 } 775 776 /** Create a method definition from a method symbol, method type 777 * and a method body. 778 */ 779 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) { 780 return (JCMethodDecl) 781 new JCMethodDecl( 782 Modifiers(m.flags(), Annotations(m.getAnnotationMirrors())), 783 m.name, 784 Type(mtype.getReturnType()), 785 TypeParams(mtype.getTypeArguments()), 786 Params(mtype.getParameterTypes(), m), 787 Types(mtype.getThrownTypes()), 788 body, 789 null, 790 m).setPos(pos).setType(mtype); 791 } 792 793 /** Create a type parameter tree from its name and type. 794 */ 795 public JCTypeParameter TypeParam(Name name, TypeVar tvar) { 796 return (JCTypeParameter) 797 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar); 798 } 799 800 /** Create a list of type parameter trees from a list of type variables. 801 */ 802 public List<JCTypeParameter> TypeParams(List<Type> typarams) { 803 ListBuffer<JCTypeParameter> tparams = new ListBuffer<JCTypeParameter>(); 804 int i = 0; 805 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail) 806 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head)); 807 return tparams.toList(); 808 } 809 810 /** Create a value parameter tree from its name, type, and owner. 811 */ 812 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) { 813 return VarDef(new VarSymbol(0, name, argtype, owner), null); 814 } 815 816 /** Create a a list of value parameter trees x0, ..., xn from a list of 817 * their types and an their owner. 818 */ 819 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) { 820 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 821 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null; 822 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) { 823 for (VarSymbol param : ((MethodSymbol)owner).params) 824 params.append(VarDef(param, null)); 825 } else { 826 int i = 0; 827 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail) 828 params.append(Param(paramName(i++), l.head, owner)); 829 } 830 return params.toList(); 831 } 832 833 /** Wrap a method invocation in an expression statement or return statement, 834 * depending on whether the method invocation expression's type is void. 835 */ 836 public JCStatement Call(JCExpression apply) { 837 return apply.type.tag == VOID ? Exec(apply) : Return(apply); 838 } 839 840 /** Construct an assignment from a variable symbol and a right hand side. 841 */ 842 public JCStatement Assignment(Symbol v, JCExpression rhs) { 843 return Exec(Assign(Ident(v), rhs).setType(v.type)); 844 } 845 846 /** Construct an index expression from a variable and an expression. 847 */ 848 public JCArrayAccess Indexed(Symbol v, JCExpression index) { 849 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index); 850 tree.type = ((ArrayType)v.type).elemtype; 851 return tree; 852 } 853 854 /** Make an attributed type cast expression. 855 */ 856 public JCTypeCast TypeCast(Type type, JCExpression expr) { 857 return (JCTypeCast)TypeCast(Type(type), expr).setType(type); 858 } 859 860 /* *************************************************************************** 861 * Helper methods. 862 ****************************************************************************/ 863 864 /** Can given symbol be referred to in unqualified form? 865 */ 866 boolean isUnqualifiable(Symbol sym) { 867 if (sym.name == names.empty || 868 sym.owner == null || 869 sym.owner.kind == MTH || sym.owner.kind == VAR) { 870 return true; 871 } else if (sym.kind == TYP && toplevel != null) { 872 Scope.Entry e; 873 e = toplevel.namedImportScope.lookup(sym.name); 874 if (e.scope != null) { 875 return 876 e.sym == sym && 877 e.next().scope == null; 878 } 879 e = toplevel.packge.members().lookup(sym.name); 880 if (e.scope != null) { 881 return 882 e.sym == sym && 883 e.next().scope == null; 884 } 885 e = toplevel.starImportScope.lookup(sym.name); 886 if (e.scope != null) { 887 return 888 e.sym == sym && 889 e.next().scope == null; 890 } 891 } 892 return false; 893 } 894 895 /** The name of synthetic parameter number `i'. 896 */ 897 public Name paramName(int i) { return names.fromString("x" + i); } 898 899 /** The name of synthetic type parameter number `i'. 900 */ 901 public Name typaramName(int i) { return names.fromString("A" + i); } 902 }