1 /* 2 * Copyright (c) 1999, 2016, 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 java.util.Iterator; 29 30 import com.sun.source.tree.ModuleTree.ModuleKind; 31 import com.sun.source.tree.NewClassTree.CreationMode; 32 import com.sun.source.tree.Tree.Kind; 33 import com.sun.tools.javac.code.*; 34 import com.sun.tools.javac.code.Symbol.*; 35 import com.sun.tools.javac.code.Type.*; 36 import com.sun.tools.javac.util.*; 37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 38 39 import com.sun.tools.javac.tree.JCTree.*; 40 41 import static com.sun.tools.javac.code.Flags.*; 42 import static com.sun.tools.javac.code.Kinds.Kind.*; 43 import static com.sun.tools.javac.code.TypeTag.*; 44 45 /** Factory class for trees. 46 * 47 * <p><b>This is NOT part of any supported API. 48 * If you write code that depends on this, you do so at your own risk. 49 * This code and its internal interfaces are subject to change or 50 * deletion without notice.</b> 51 */ 52 public class TreeMaker implements JCTree.Factory { 53 54 /** The context key for the tree factory. */ 55 protected static final Context.Key<TreeMaker> treeMakerKey = new Context.Key<>(); 56 57 /** Get the TreeMaker instance. */ 58 public static TreeMaker instance(Context context) { 59 TreeMaker instance = context.get(treeMakerKey); 60 if (instance == null) 61 instance = new TreeMaker(context); 62 return instance; 63 } 64 65 /** The position at which subsequent trees will be created. 66 */ 67 public int pos = Position.NOPOS; 68 69 /** The toplevel tree to which created trees belong. 70 */ 71 public JCCompilationUnit toplevel; 72 73 /** The current name table. */ 74 Names names; 75 76 Types types; 77 78 /** The current symbol table. */ 79 Symtab syms; 80 81 /** Create a tree maker with null toplevel and NOPOS as initial position. 82 */ 83 protected TreeMaker(Context context) { 84 context.put(treeMakerKey, this); 85 this.pos = Position.NOPOS; 86 this.toplevel = null; 87 this.names = Names.instance(context); 88 this.syms = Symtab.instance(context); 89 this.types = Types.instance(context); 90 } 91 92 /** Create a tree maker with a given toplevel and FIRSTPOS as initial position. 93 */ 94 protected TreeMaker(JCCompilationUnit toplevel, Names names, Types types, Symtab syms) { 95 this.pos = Position.FIRSTPOS; 96 this.toplevel = toplevel; 97 this.names = names; 98 this.types = types; 99 this.syms = syms; 100 } 101 102 /** Create a new tree maker for a given toplevel. 103 */ 104 public TreeMaker forToplevel(JCCompilationUnit toplevel) { 105 return new TreeMaker(toplevel, names, types, syms); 106 } 107 108 /** Reassign current position. 109 */ 110 public TreeMaker at(int pos) { 111 this.pos = pos; 112 return this; 113 } 114 115 /** Reassign current position. 116 */ 117 public TreeMaker at(DiagnosticPosition pos) { 118 this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition()); 119 return this; 120 } 121 122 /** 123 * Create given tree node at current position. 124 * @param defs a list of PackageDef, ClassDef, Import, and Skip 125 */ 126 public JCCompilationUnit TopLevel(List<JCTree> defs) { 127 for (JCTree node : defs) 128 Assert.check(node instanceof JCClassDecl 129 || node instanceof JCPackageDecl 130 || node instanceof JCImport 131 || node instanceof JCModuleDecl 132 || node instanceof JCSkip 133 || node instanceof JCErroneous 134 || (node instanceof JCExpressionStatement 135 && ((JCExpressionStatement)node).expr instanceof JCErroneous), 136 () -> node.getClass().getSimpleName()); 137 JCCompilationUnit tree = new JCCompilationUnit(defs); 138 tree.pos = pos; 139 return tree; 140 } 141 142 public JCPackageDecl PackageDecl(List<JCAnnotation> annotations, 143 JCExpression pid) { 144 Assert.checkNonNull(annotations); 145 Assert.checkNonNull(pid); 146 JCPackageDecl tree = new JCPackageDecl(annotations, pid); 147 tree.pos = pos; 148 return tree; 149 } 150 151 public JCImport Import(JCTree qualid, boolean importStatic) { 152 JCImport tree = new JCImport(qualid, importStatic); 153 tree.pos = pos; 154 return tree; 155 } 156 157 public JCClassDecl ClassDef(JCModifiers mods, 158 Name name, 159 List<JCTypeParameter> typarams, 160 JCExpression extending, 161 List<JCExpression> implementing, 162 List<JCTree> defs) 163 { 164 JCClassDecl tree = new JCClassDecl(mods, 165 name, 166 typarams, 167 extending, 168 implementing, 169 defs, 170 null); 171 tree.pos = pos; 172 return tree; 173 } 174 175 public JCMethodDecl MethodDef(JCModifiers mods, 176 Name name, 177 JCExpression restype, 178 List<JCTypeParameter> typarams, 179 List<JCVariableDecl> params, 180 List<JCExpression> thrown, 181 JCBlock body, 182 JCExpression defaultValue) { 183 return MethodDef( 184 mods, name, restype, typarams, null, params, 185 thrown, body, defaultValue); 186 } 187 188 public JCMethodDecl MethodDef(JCModifiers mods, 189 Name name, 190 JCExpression restype, 191 List<JCTypeParameter> typarams, 192 JCVariableDecl recvparam, 193 List<JCVariableDecl> params, 194 List<JCExpression> thrown, 195 JCBlock body, 196 JCExpression defaultValue) 197 { 198 JCMethodDecl tree = new JCMethodDecl(mods, 199 name, 200 restype, 201 typarams, 202 recvparam, 203 params, 204 thrown, 205 body, 206 defaultValue, 207 null); 208 tree.pos = pos; 209 return tree; 210 } 211 212 public JCMethodDecl MethodDef(JCModifiers mods, 213 Name name, 214 JCExpression restype, 215 List<JCTypeParameter> typarams, 216 JCVariableDecl recvparam, 217 List<JCVariableDecl> params, 218 List<JCExpression> thrown, 219 JCBlock body, 220 JCExpression defaultValue, 221 MethodSymbol mSymbol) 222 { 223 JCMethodDecl tree = new JCMethodDecl(mods, 224 name, 225 restype, 226 typarams, 227 recvparam, 228 params, 229 thrown, 230 body, 231 defaultValue, 232 mSymbol); 233 tree.pos = pos; 234 return tree; 235 } 236 237 public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) { 238 JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null); 239 tree.pos = pos; 240 return tree; 241 } 242 243 public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) { 244 JCVariableDecl tree = new JCVariableDecl(mods, name, vartype); 245 tree.pos = pos; 246 return tree; 247 } 248 249 public JCSkip Skip() { 250 JCSkip tree = new JCSkip(); 251 tree.pos = pos; 252 return tree; 253 } 254 255 public JCBlock Block(long flags, List<JCStatement> stats) { 256 JCBlock tree = new JCBlock(flags, stats); 257 tree.pos = pos; 258 return tree; 259 } 260 261 public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) { 262 JCDoWhileLoop tree = new JCDoWhileLoop(body, cond); 263 tree.pos = pos; 264 return tree; 265 } 266 267 public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) { 268 JCWhileLoop tree = new JCWhileLoop(cond, body); 269 tree.pos = pos; 270 return tree; 271 } 272 273 public JCWithField WithField(JCExpression field, JCExpression value) { 274 JCWithField tree = new JCWithField(field, value); 275 tree.pos = pos; 276 return tree; 277 } 278 279 public JCForLoop ForLoop(List<JCStatement> init, 280 JCExpression cond, 281 List<JCExpressionStatement> step, 282 JCStatement body) 283 { 284 JCForLoop tree = new JCForLoop(init, cond, step, body); 285 tree.pos = pos; 286 return tree; 287 } 288 289 public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) { 290 JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body); 291 tree.pos = pos; 292 return tree; 293 } 294 295 public JCLabeledStatement Labelled(Name label, JCStatement body) { 296 JCLabeledStatement tree = new JCLabeledStatement(label, body); 297 tree.pos = pos; 298 return tree; 299 } 300 301 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) { 302 JCSwitch tree = new JCSwitch(selector, cases); 303 tree.pos = pos; 304 return tree; 305 } 306 307 public JCCase Case(JCExpression pat, List<JCStatement> stats) { 308 JCCase tree = new JCCase(pat, stats); 309 tree.pos = pos; 310 return tree; 311 } 312 313 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) { 314 JCSynchronized tree = new JCSynchronized(lock, body); 315 tree.pos = pos; 316 return tree; 317 } 318 319 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) { 320 return Try(List.nil(), body, catchers, finalizer); 321 } 322 323 public JCTry Try(List<JCTree> resources, 324 JCBlock body, 325 List<JCCatch> catchers, 326 JCBlock finalizer) { 327 JCTry tree = new JCTry(resources, body, catchers, finalizer); 328 tree.pos = pos; 329 return tree; 330 } 331 332 public JCCatch Catch(JCVariableDecl param, JCBlock body) { 333 JCCatch tree = new JCCatch(param, body); 334 tree.pos = pos; 335 return tree; 336 } 337 338 public JCConditional Conditional(JCExpression cond, 339 JCExpression thenpart, 340 JCExpression elsepart) 341 { 342 JCConditional tree = new JCConditional(cond, thenpart, elsepart); 343 tree.pos = pos; 344 return tree; 345 } 346 347 public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) { 348 JCIf tree = new JCIf(cond, thenpart, elsepart); 349 tree.pos = pos; 350 return tree; 351 } 352 353 public JCExpressionStatement Exec(JCExpression expr) { 354 JCExpressionStatement tree = new JCExpressionStatement(expr); 355 tree.pos = pos; 356 return tree; 357 } 358 359 public JCBreak Break(Name label) { 360 JCBreak tree = new JCBreak(label, null); 361 tree.pos = pos; 362 return tree; 363 } 364 365 public JCContinue Continue(Name label) { 366 JCContinue tree = new JCContinue(label, null); 367 tree.pos = pos; 368 return tree; 369 } 370 371 public JCReturn Return(JCExpression expr) { 372 JCReturn tree = new JCReturn(expr); 373 tree.pos = pos; 374 return tree; 375 } 376 377 public JCThrow Throw(JCExpression expr) { 378 JCThrow tree = new JCThrow(expr); 379 tree.pos = pos; 380 return tree; 381 } 382 383 public JCAssert Assert(JCExpression cond, JCExpression detail) { 384 JCAssert tree = new JCAssert(cond, detail); 385 tree.pos = pos; 386 return tree; 387 } 388 389 public JCMethodInvocation Apply(List<JCExpression> typeargs, 390 JCExpression fn, 391 List<JCExpression> args) 392 { 393 JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args); 394 tree.pos = pos; 395 return tree; 396 } 397 398 public JCNewClass NewClass(JCExpression encl, 399 List<JCExpression> typeargs, 400 JCExpression clazz, 401 List<JCExpression> args, 402 JCClassDecl def) 403 { 404 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def, CreationMode.NEW); 405 tree.pos = pos; 406 return tree; 407 } 408 409 public JCNewClass NewClass(JCExpression encl, 410 List<JCExpression> typeargs, 411 JCExpression clazz, 412 List<JCExpression> args, 413 JCClassDecl def, 414 CreationMode creationMode) 415 { 416 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def, creationMode); 417 tree.pos = pos; 418 return tree; 419 } 420 421 public JCNewArray NewArray(JCExpression elemtype, 422 List<JCExpression> dims, 423 List<JCExpression> elems) 424 { 425 JCNewArray tree = new JCNewArray(elemtype, dims, elems); 426 tree.pos = pos; 427 return tree; 428 } 429 430 public JCLambda Lambda(List<JCVariableDecl> params, 431 JCTree body) 432 { 433 JCLambda tree = new JCLambda(params, body); 434 tree.pos = pos; 435 return tree; 436 } 437 438 public JCParens Parens(JCExpression expr) { 439 JCParens tree = new JCParens(expr); 440 tree.pos = pos; 441 return tree; 442 } 443 444 public JCAssign Assign(JCExpression lhs, JCExpression rhs) { 445 JCAssign tree = new JCAssign(lhs, rhs); 446 tree.pos = pos; 447 return tree; 448 } 449 450 public JCAssignOp Assignop(JCTree.Tag opcode, JCTree lhs, JCTree rhs) { 451 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null); 452 tree.pos = pos; 453 return tree; 454 } 455 456 public JCUnary Unary(JCTree.Tag opcode, JCExpression arg) { 457 JCUnary tree = new JCUnary(opcode, arg); 458 tree.pos = pos; 459 return tree; 460 } 461 462 public JCBinary Binary(JCTree.Tag opcode, JCExpression lhs, JCExpression rhs) { 463 JCBinary tree = new JCBinary(opcode, lhs, rhs, null); 464 tree.pos = pos; 465 return tree; 466 } 467 468 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) { 469 JCTypeCast tree = new JCTypeCast(clazz, expr); 470 tree.pos = pos; 471 return tree; 472 } 473 474 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) { 475 JCInstanceOf tree = new JCInstanceOf(expr, clazz); 476 tree.pos = pos; 477 return tree; 478 } 479 480 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) { 481 JCArrayAccess tree = new JCArrayAccess(indexed, index); 482 tree.pos = pos; 483 return tree; 484 } 485 486 public JCFieldAccess Select(JCExpression selected, Name selector) { 487 JCFieldAccess tree = new JCFieldAccess(selected, selector, null); 488 tree.pos = pos; 489 return tree; 490 } 491 492 public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name, 493 JCExpression expr, List<JCExpression> typeargs) { 494 JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs); 495 tree.pos = pos; 496 return tree; 497 } 498 499 public JCIdent Ident(Name name) { 500 JCIdent tree = new JCIdent(name, null); 501 tree.pos = pos; 502 return tree; 503 } 504 505 public JCLiteral Literal(TypeTag tag, Object value) { 506 JCLiteral tree = new JCLiteral(tag, value); 507 tree.pos = pos; 508 return tree; 509 } 510 511 public JCPrimitiveTypeTree TypeIdent(TypeTag typetag) { 512 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag); 513 tree.pos = pos; 514 return tree; 515 } 516 517 public JCArrayTypeTree TypeArray(JCExpression elemtype) { 518 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype); 519 tree.pos = pos; 520 return tree; 521 } 522 523 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) { 524 JCTypeApply tree = new JCTypeApply(clazz, arguments); 525 tree.pos = pos; 526 return tree; 527 } 528 529 public JCTypeUnion TypeUnion(List<JCExpression> components) { 530 JCTypeUnion tree = new JCTypeUnion(components); 531 tree.pos = pos; 532 return tree; 533 } 534 535 public JCTypeIntersection TypeIntersection(List<JCExpression> components) { 536 JCTypeIntersection tree = new JCTypeIntersection(components); 537 tree.pos = pos; 538 return tree; 539 } 540 541 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) { 542 return TypeParameter(name, bounds, List.nil()); 543 } 544 545 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annos) { 546 JCTypeParameter tree = new JCTypeParameter(name, bounds, annos); 547 tree.pos = pos; 548 return tree; 549 } 550 551 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) { 552 JCWildcard tree = new JCWildcard(kind, type); 553 tree.pos = pos; 554 return tree; 555 } 556 557 public TypeBoundKind TypeBoundKind(BoundKind kind) { 558 TypeBoundKind tree = new TypeBoundKind(kind); 559 tree.pos = pos; 560 return tree; 561 } 562 563 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) { 564 JCAnnotation tree = new JCAnnotation(Tag.ANNOTATION, annotationType, args); 565 tree.pos = pos; 566 return tree; 567 } 568 569 public JCAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) { 570 JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args); 571 tree.pos = pos; 572 return tree; 573 } 574 575 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) { 576 JCModifiers tree = new JCModifiers(flags, annotations); 577 boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0; 578 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos; 579 return tree; 580 } 581 582 public JCModifiers Modifiers(long flags) { 583 return Modifiers(flags, List.nil()); 584 } 585 586 @Override 587 public JCModuleDecl ModuleDef(JCModifiers mods, ModuleKind kind, 588 JCExpression qualid, List<JCDirective> directives) { 589 JCModuleDecl tree = new JCModuleDecl(mods, kind, qualid, directives); 590 tree.pos = pos; 591 return tree; 592 } 593 594 @Override 595 public JCExports Exports(JCExpression qualId, List<JCExpression> moduleNames) { 596 JCExports tree = new JCExports(qualId, moduleNames); 597 tree.pos = pos; 598 return tree; 599 } 600 601 @Override 602 public JCOpens Opens(JCExpression qualId, List<JCExpression> moduleNames) { 603 JCOpens tree = new JCOpens(qualId, moduleNames); 604 tree.pos = pos; 605 return tree; 606 } 607 608 @Override 609 public JCProvides Provides(JCExpression serviceName, List<JCExpression> implNames) { 610 JCProvides tree = new JCProvides(serviceName, implNames); 611 tree.pos = pos; 612 return tree; 613 } 614 615 @Override 616 public JCRequires Requires(boolean isTransitive, boolean isStaticPhase, JCExpression qualId) { 617 JCRequires tree = new JCRequires(isTransitive, isStaticPhase, qualId); 618 tree.pos = pos; 619 return tree; 620 } 621 622 @Override 623 public JCUses Uses(JCExpression qualId) { 624 JCUses tree = new JCUses(qualId); 625 tree.pos = pos; 626 return tree; 627 } 628 629 public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) { 630 JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType); 631 tree.pos = pos; 632 return tree; 633 } 634 635 public JCErroneous Erroneous() { 636 return Erroneous(List.nil()); 637 } 638 639 public JCErroneous Erroneous(List<? extends JCTree> errs) { 640 JCErroneous tree = new JCErroneous(errs); 641 tree.pos = pos; 642 return tree; 643 } 644 645 public LetExpr LetExpr(List<JCVariableDecl> defs, JCExpression expr) { 646 LetExpr tree = new LetExpr(defs, expr); 647 tree.pos = pos; 648 return tree; 649 } 650 651 /* *************************************************************************** 652 * Derived building blocks. 653 ****************************************************************************/ 654 655 public JCClassDecl AnonymousClassDef(JCModifiers mods, 656 List<JCTree> defs) 657 { 658 return ClassDef(mods, 659 names.empty, 660 List.nil(), 661 null, 662 List.nil(), 663 defs); 664 } 665 666 public LetExpr LetExpr(JCVariableDecl def, JCExpression expr) { 667 LetExpr tree = new LetExpr(List.of(def), expr); 668 tree.pos = pos; 669 return tree; 670 } 671 672 /** Create an identifier from a symbol. 673 */ 674 public JCIdent Ident(Symbol sym) { 675 return (JCIdent)new JCIdent((sym.name != names.empty) 676 ? sym.name 677 : sym.flatName(), sym) 678 .setPos(pos) 679 .setType(sym.type); 680 } 681 682 /** Create a selection node from a qualifier tree and a symbol. 683 * @param base The qualifier tree. 684 */ 685 public JCExpression Select(JCExpression base, Symbol sym) { 686 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type); 687 } 688 689 /** Create a qualified identifier from a symbol, adding enough qualifications 690 * to make the reference unique. 691 */ 692 public JCExpression QualIdent(Symbol sym) { 693 return isUnqualifiable(sym) 694 ? Ident(sym) 695 : Select(QualIdent(sym.owner), sym); 696 } 697 698 /** Create an identifier that refers to the variable declared in given variable 699 * declaration. 700 */ 701 public JCExpression Ident(JCVariableDecl param) { 702 return Ident(param.sym); 703 } 704 705 /** Create a list of identifiers referring to the variables declared 706 * in given list of variable declarations. 707 */ 708 public List<JCExpression> Idents(List<JCVariableDecl> params) { 709 ListBuffer<JCExpression> ids = new ListBuffer<>(); 710 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) 711 ids.append(Ident(l.head)); 712 return ids.toList(); 713 } 714 715 /** Create a tree representing `this', given its type. 716 */ 717 public JCExpression This(Type t) { 718 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym)); 719 } 720 721 /** Create a tree representing qualified `this' given its type 722 */ 723 public JCExpression QualThis(Type t) { 724 return Select(Type(t), new VarSymbol(FINAL, names._this, t, t.tsym)); 725 } 726 727 /** Create a tree representing a class literal. 728 */ 729 public JCExpression ClassLiteral(ClassSymbol clazz) { 730 return ClassLiteral(clazz.type); 731 } 732 733 /** Create a tree representing a class literal. 734 */ 735 public JCExpression ClassLiteral(Type t) { 736 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL, 737 names._class, 738 t, 739 t.tsym); 740 return Select(Type(t), lit); 741 } 742 743 /** Create a tree representing `super', given its type and owner. 744 */ 745 public JCIdent Super(Type t, TypeSymbol owner) { 746 return Ident(new VarSymbol(FINAL, names._super, t, owner)); 747 } 748 749 /** 750 * Create a method invocation from a method tree and a list of 751 * argument trees. 752 */ 753 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) { 754 return Apply(null, meth, args).setType(meth.type.getReturnType()); 755 } 756 757 /** 758 * Create a no-arg method invocation from a method tree 759 */ 760 public JCMethodInvocation App(JCExpression meth) { 761 return Apply(null, meth, List.nil()).setType(meth.type.getReturnType()); 762 } 763 764 /** Create a method invocation from a method tree and a list of argument trees. 765 */ 766 public JCExpression Create(Symbol ctor, List<JCExpression> args) { 767 return Create(ctor, args, CreationMode.NEW); 768 } 769 770 /** Create a method invocation from a method tree and a list of argument trees. 771 */ 772 public JCExpression Create(Symbol ctor, List<JCExpression> args, CreationMode creationMode) { 773 Type t = ctor.owner.erasure(types); 774 JCNewClass newclass = NewClass(null, null, Type(t), args, null, creationMode); 775 newclass.constructor = ctor; 776 newclass.setType(t); 777 return newclass; 778 } 779 780 /** Create a tree representing given type. 781 */ 782 public JCExpression Type(Type t) { 783 if (t == null) return null; 784 JCExpression tp; 785 switch (t.getTag()) { 786 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 787 case DOUBLE: case BOOLEAN: case VOID: 788 tp = TypeIdent(t.getTag()); 789 break; 790 case TYPEVAR: 791 tp = Ident(t.tsym); 792 break; 793 case WILDCARD: { 794 WildcardType a = ((WildcardType) t); 795 tp = Wildcard(TypeBoundKind(a.kind), a.kind == BoundKind.UNBOUND ? null : Type(a.type)); 796 break; 797 } 798 case CLASS: 799 switch (t.getKind()) { 800 case UNION: { 801 UnionClassType tu = (UnionClassType)t; 802 ListBuffer<JCExpression> la = new ListBuffer<>(); 803 for (Type ta : tu.getAlternativeTypes()) { 804 la.add(Type(ta)); 805 } 806 tp = TypeUnion(la.toList()); 807 break; 808 } 809 case INTERSECTION: { 810 IntersectionClassType it = (IntersectionClassType)t; 811 ListBuffer<JCExpression> la = new ListBuffer<>(); 812 for (Type ta : it.getExplicitComponents()) { 813 la.add(Type(ta)); 814 } 815 tp = TypeIntersection(la.toList()); 816 break; 817 } 818 default: { 819 Type outer = t.getEnclosingType(); 820 JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP 821 ? Select(Type(outer), t.tsym) 822 : QualIdent(t.tsym); 823 tp = t.getTypeArguments().isEmpty() 824 ? clazz 825 : TypeApply(clazz, Types(t.getTypeArguments())); 826 break; 827 } 828 } 829 break; 830 case ARRAY: 831 tp = TypeArray(Type(types.elemtype(t))); 832 break; 833 case ERROR: 834 tp = TypeIdent(ERROR); 835 break; 836 default: 837 throw new AssertionError("unexpected type: " + t); 838 } 839 return tp.setType(t); 840 } 841 842 /** Create a list of trees representing given list of types. 843 */ 844 public List<JCExpression> Types(List<Type> ts) { 845 ListBuffer<JCExpression> lb = new ListBuffer<>(); 846 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 847 lb.append(Type(l.head)); 848 return lb.toList(); 849 } 850 851 /** Create a variable definition from a variable symbol and an initializer 852 * expression. 853 */ 854 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) { 855 return (JCVariableDecl) 856 new JCVariableDecl( 857 Modifiers(v.flags(), Annotations(v.getRawAttributes())), 858 v.name, 859 Type(v.type), 860 init, 861 v).setPos(pos).setType(v.type); 862 } 863 864 /** Create annotation trees from annotations. 865 */ 866 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) { 867 if (attributes == null) return List.nil(); 868 ListBuffer<JCAnnotation> result = new ListBuffer<>(); 869 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) { 870 Attribute a = i.head; 871 result.append(Annotation(a)); 872 } 873 return result.toList(); 874 } 875 876 public JCLiteral Literal(Object value) { 877 JCLiteral result = null; 878 if (value instanceof String) { 879 result = Literal(CLASS, value). 880 setType(syms.stringType.constType(value)); 881 } else if (value instanceof Integer) { 882 result = Literal(INT, value). 883 setType(syms.intType.constType(value)); 884 } else if (value instanceof Long) { 885 result = Literal(LONG, value). 886 setType(syms.longType.constType(value)); 887 } else if (value instanceof Byte) { 888 result = Literal(BYTE, value). 889 setType(syms.byteType.constType(value)); 890 } else if (value instanceof Character) { 891 int v = (int) (((Character) value).toString().charAt(0)); 892 result = Literal(CHAR, v). 893 setType(syms.charType.constType(v)); 894 } else if (value instanceof Double) { 895 result = Literal(DOUBLE, value). 896 setType(syms.doubleType.constType(value)); 897 } else if (value instanceof Float) { 898 result = Literal(FLOAT, value). 899 setType(syms.floatType.constType(value)); 900 } else if (value instanceof Short) { 901 result = Literal(SHORT, value). 902 setType(syms.shortType.constType(value)); 903 } else if (value instanceof Boolean) { 904 int v = ((Boolean) value) ? 1 : 0; 905 result = Literal(BOOLEAN, v). 906 setType(syms.booleanType.constType(v)); 907 } else { 908 throw new AssertionError(value); 909 } 910 return result; 911 } 912 913 class AnnotationBuilder implements Attribute.Visitor { 914 JCExpression result = null; 915 public void visitConstant(Attribute.Constant v) { 916 result = Literal(v.type.getTag(), v.value); 917 } 918 public void visitClass(Attribute.Class clazz) { 919 result = ClassLiteral(clazz.classType).setType(syms.classType); 920 } 921 public void visitEnum(Attribute.Enum e) { 922 result = QualIdent(e.value); 923 } 924 public void visitError(Attribute.Error e) { 925 result = Erroneous(); 926 } 927 public void visitCompound(Attribute.Compound compound) { 928 if (compound instanceof Attribute.TypeCompound) { 929 result = visitTypeCompoundInternal((Attribute.TypeCompound) compound); 930 } else { 931 result = visitCompoundInternal(compound); 932 } 933 } 934 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) { 935 ListBuffer<JCExpression> args = new ListBuffer<>(); 936 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) { 937 Pair<MethodSymbol,Attribute> pair = values.head; 938 JCExpression valueTree = translate(pair.snd); 939 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type)); 940 } 941 return Annotation(Type(compound.type), args.toList()); 942 } 943 public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) { 944 ListBuffer<JCExpression> args = new ListBuffer<>(); 945 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) { 946 Pair<MethodSymbol,Attribute> pair = values.head; 947 JCExpression valueTree = translate(pair.snd); 948 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type)); 949 } 950 return TypeAnnotation(Type(compound.type), args.toList()); 951 } 952 public void visitArray(Attribute.Array array) { 953 ListBuffer<JCExpression> elems = new ListBuffer<>(); 954 for (int i = 0; i < array.values.length; i++) 955 elems.append(translate(array.values[i])); 956 result = NewArray(null, List.nil(), elems.toList()).setType(array.type); 957 } 958 JCExpression translate(Attribute a) { 959 a.accept(this); 960 return result; 961 } 962 JCAnnotation translate(Attribute.Compound a) { 963 return visitCompoundInternal(a); 964 } 965 JCAnnotation translate(Attribute.TypeCompound a) { 966 return visitTypeCompoundInternal(a); 967 } 968 } 969 970 AnnotationBuilder annotationBuilder = new AnnotationBuilder(); 971 972 /** Create an annotation tree from an attribute. 973 */ 974 public JCAnnotation Annotation(Attribute a) { 975 return annotationBuilder.translate((Attribute.Compound)a); 976 } 977 978 public JCAnnotation TypeAnnotation(Attribute a) { 979 return annotationBuilder.translate((Attribute.TypeCompound) a); 980 } 981 982 /** Create a method definition from a method symbol and a method body. 983 */ 984 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) { 985 return MethodDef(m, m.type, body); 986 } 987 988 /** Create a method definition from a method symbol, method type 989 * and a method body. 990 */ 991 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) { 992 return (JCMethodDecl) 993 new JCMethodDecl( 994 Modifiers(m.flags(), Annotations(m.getRawAttributes())), 995 m.name, 996 Type(mtype.getReturnType()), 997 TypeParams(mtype.getTypeArguments()), 998 null, // receiver type 999 Params(mtype.getParameterTypes(), m), 1000 Types(mtype.getThrownTypes()), 1001 body, 1002 null, 1003 m).setPos(pos).setType(mtype); 1004 } 1005 1006 /** Create a type parameter tree from its name and type. 1007 */ 1008 public JCTypeParameter TypeParam(Name name, TypeVar tvar) { 1009 return (JCTypeParameter) 1010 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar); 1011 } 1012 1013 /** Create a list of type parameter trees from a list of type variables. 1014 */ 1015 public List<JCTypeParameter> TypeParams(List<Type> typarams) { 1016 ListBuffer<JCTypeParameter> tparams = new ListBuffer<>(); 1017 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail) 1018 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head)); 1019 return tparams.toList(); 1020 } 1021 1022 /** Create a value parameter tree from its name, type, and owner. 1023 */ 1024 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) { 1025 return VarDef(new VarSymbol(PARAMETER, name, argtype, owner), null); 1026 } 1027 1028 /** Create a a list of value parameter trees x0, ..., xn from a list of 1029 * their types and an their owner. 1030 */ 1031 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) { 1032 ListBuffer<JCVariableDecl> params = new ListBuffer<>(); 1033 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null; 1034 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) { 1035 for (VarSymbol param : ((MethodSymbol)owner).params) 1036 params.append(VarDef(param, null)); 1037 } else { 1038 int i = 0; 1039 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail) 1040 params.append(Param(paramName(i++), l.head, owner)); 1041 } 1042 return params.toList(); 1043 } 1044 1045 /** Wrap a method invocation in an expression statement or return statement, 1046 * depending on whether the method invocation expression's type is void. 1047 */ 1048 public JCStatement Call(JCExpression apply) { 1049 return apply.type.hasTag(VOID) ? Exec(apply) : Return(apply); 1050 } 1051 1052 /** Construct an assignment from a variable symbol and a right hand side. 1053 */ 1054 public JCStatement Assignment(Symbol v, JCExpression rhs) { 1055 return Exec(Assign(Ident(v), rhs).setType(v.type)); 1056 } 1057 1058 /** Construct an index expression from a variable and an expression. 1059 */ 1060 public JCArrayAccess Indexed(Symbol v, JCExpression index) { 1061 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index); 1062 tree.type = ((ArrayType)v.type).elemtype; 1063 return tree; 1064 } 1065 1066 /** Make an attributed type cast expression. 1067 */ 1068 public JCTypeCast TypeCast(Type type, JCExpression expr) { 1069 return (JCTypeCast)TypeCast(Type(type), expr).setType(type); 1070 } 1071 1072 /* *************************************************************************** 1073 * Helper methods. 1074 ****************************************************************************/ 1075 1076 /** Can given symbol be referred to in unqualified form? 1077 */ 1078 boolean isUnqualifiable(Symbol sym) { 1079 if (sym.name == names.empty || 1080 sym.owner == null || 1081 sym.owner == syms.rootPackage || 1082 sym.owner.kind == MTH || sym.owner.kind == VAR) { 1083 return true; 1084 } else if (sym.kind == TYP && toplevel != null) { 1085 Iterator<Symbol> it = toplevel.namedImportScope.getSymbolsByName(sym.name).iterator(); 1086 if (it.hasNext()) { 1087 Symbol s = it.next(); 1088 return 1089 s == sym && 1090 !it.hasNext(); 1091 } 1092 it = toplevel.packge.members().getSymbolsByName(sym.name).iterator(); 1093 if (it.hasNext()) { 1094 Symbol s = it.next(); 1095 return 1096 s == sym && 1097 !it.hasNext(); 1098 } 1099 it = toplevel.starImportScope.getSymbolsByName(sym.name).iterator(); 1100 if (it.hasNext()) { 1101 Symbol s = it.next(); 1102 return 1103 s == sym && 1104 !it.hasNext(); 1105 } 1106 } 1107 return false; 1108 } 1109 1110 /** The name of synthetic parameter number `i'. 1111 */ 1112 public Name paramName(int i) { return names.fromString("x" + i); } 1113 1114 /** The name of synthetic type parameter number `i'. 1115 */ 1116 public Name typaramName(int i) { return names.fromString("A" + i); } 1117 }