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