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