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