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