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