TreeMaker.java revision 3294:9adfb22ff08f
1264377Sdes/* 276259Sgreen * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. 3124208Sdes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 476259Sgreen * 5124208Sdes * This code is free software; you can redistribute it and/or modify it 6124208Sdes * under the terms of the GNU General Public License version 2 only, as 7124208Sdes * published by the Free Software Foundation. Oracle designates this 876259Sgreen * particular file as subject to the "Classpath" exception as provided 9124208Sdes * by Oracle in the LICENSE file that accompanied this code. 10124208Sdes * 11124208Sdes * This code is distributed in the hope that it will be useful, but WITHOUT 12124208Sdes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13124208Sdes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14124208Sdes * version 2 for more details (a copy is included in the LICENSE file that 15124208Sdes * accompanied this code). 1676259Sgreen * 17162852Sdes * You should have received a copy of the GNU General Public License version 1876259Sgreen * 2 along with this work; if not, write to the Free Software Foundation, 1976259Sgreen * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20162852Sdes * 21162852Sdes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2276259Sgreen * or visit www.oracle.com if you need additional information or have any 2376259Sgreen * questions. 2476259Sgreen */ 25162852Sdes 26162852Sdespackage com.sun.tools.javac.tree; 27162852Sdes 2876259Sgreenimport java.util.Iterator; 2976259Sgreen 3076259Sgreenimport com.sun.tools.javac.code.*; 3176259Sgreenimport com.sun.tools.javac.code.Symbol.*; 3276259Sgreenimport com.sun.tools.javac.code.Type.*; 33215116Sdesimport com.sun.tools.javac.util.*; 3498675Sdesimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 35262566Sdes 3676259Sgreenimport com.sun.tools.javac.tree.JCTree.*; 37113908Sdes 38106121Sdesimport static com.sun.tools.javac.code.Flags.*; 3976259Sgreenimport static com.sun.tools.javac.code.Kinds.Kind.*; 4076259Sgreenimport static com.sun.tools.javac.code.TypeTag.*; 41126274Sdes 42126274Sdes/** Factory class for trees. 4376259Sgreen * 44262566Sdes * <p><b>This is NOT part of any supported API. 45262566Sdes * If you write code that depends on this, you do so at your own risk. 4676259Sgreen * This code and its internal interfaces are subject to change or 4776259Sgreen * deletion without notice.</b> 4876259Sgreen */ 4976259Sgreenpublic class TreeMaker implements JCTree.Factory { 50262566Sdes 51262566Sdes /** The context key for the tree factory. */ 52262566Sdes protected static final Context.Key<TreeMaker> treeMakerKey = new Context.Key<>(); 5376259Sgreen 5476259Sgreen /** Get the TreeMaker instance. */ 55262566Sdes public static TreeMaker instance(Context context) { 56262566Sdes TreeMaker instance = context.get(treeMakerKey); 57262566Sdes if (instance == null) 58262566Sdes instance = new TreeMaker(context); 59262566Sdes return instance; 60262566Sdes } 6176259Sgreen 6276259Sgreen /** The position at which subsequent trees will be created. 63262566Sdes */ 64262566Sdes public int pos = Position.NOPOS; 65262566Sdes 66262566Sdes /** The toplevel tree to which created trees belong. 67262566Sdes */ 6876259Sgreen public JCCompilationUnit toplevel; 6976259Sgreen 7076259Sgreen /** The current name table. */ 7176259Sgreen Names names; 7276259Sgreen 73264377Sdes Types types; 7476259Sgreen 7576259Sgreen /** The current symbol table. */ 7676259Sgreen Symtab syms; 77162852Sdes 78262566Sdes /** Create a tree maker with null toplevel and NOPOS as initial position. 7999060Sdes */ 80255767Sdes protected TreeMaker(Context context) { 8176259Sgreen context.put(treeMakerKey, this); 8276259Sgreen this.pos = Position.NOPOS; 8376259Sgreen this.toplevel = null; 84106121Sdes this.names = Names.instance(context); 8599060Sdes this.syms = Symtab.instance(context); 8676259Sgreen this.types = Types.instance(context); 87264377Sdes } 8876259Sgreen 89262566Sdes /** Create a tree maker with a given toplevel and FIRSTPOS as initial position. 90255767Sdes */ 9176259Sgreen protected TreeMaker(JCCompilationUnit toplevel, Names names, Types types, Symtab syms) { 9276259Sgreen this.pos = Position.FIRSTPOS; 9376259Sgreen this.toplevel = toplevel; 9476259Sgreen this.names = names; 9576259Sgreen this.types = types; 9676259Sgreen this.syms = syms; 9776259Sgreen } 98106121Sdes 99106121Sdes /** Create a new tree maker for a given toplevel. 100106121Sdes */ 101106121Sdes public TreeMaker forToplevel(JCCompilationUnit toplevel) { 102106121Sdes return new TreeMaker(toplevel, names, types, syms); 103106121Sdes } 10476259Sgreen 105264377Sdes /** Reassign current position. 106255767Sdes */ 10776259Sgreen public TreeMaker at(int pos) { 10876259Sgreen this.pos = pos; 10976259Sgreen return this; 11076259Sgreen } 11176259Sgreen 112126274Sdes /** Reassign current position. 113126274Sdes */ 11476259Sgreen public TreeMaker at(DiagnosticPosition pos) { 11576259Sgreen this.pos = (pos == null ? Position.NOPOS : pos.getStartPosition()); 116262566Sdes return this; 11776259Sgreen } 118262566Sdes 11998675Sdes /** 120262566Sdes * Create given tree node at current position. 12176259Sgreen * @param defs a list of PackageDef, ClassDef, Import, and Skip 122262566Sdes */ 123262566Sdes public JCCompilationUnit TopLevel(List<JCTree> defs) { 124262566Sdes for (JCTree node : defs) 12576259Sgreen Assert.check(node instanceof JCClassDecl 12676259Sgreen || node instanceof JCPackageDecl 127262566Sdes || node instanceof JCImport 12898675Sdes || node instanceof JCModuleDecl 129262566Sdes || node instanceof JCSkip 130262566Sdes || node instanceof JCErroneous 131262566Sdes || (node instanceof JCExpressionStatement 13292555Sdes && ((JCExpressionStatement)node).expr instanceof JCErroneous), 13392555Sdes () -> node.getClass().getSimpleName()); 13476259Sgreen JCCompilationUnit tree = new JCCompilationUnit(defs); 13592555Sdes tree.pos = pos; 136221420Sdes return tree; 13776259Sgreen } 138262566Sdes 13976259Sgreen public JCPackageDecl PackageDecl(List<JCAnnotation> annotations, 140255767Sdes JCExpression pid) { 14176259Sgreen Assert.checkNonNull(annotations); 14276259Sgreen Assert.checkNonNull(pid); 143255767Sdes JCPackageDecl tree = new JCPackageDecl(annotations, pid); 14492555Sdes tree.pos = pos; 14576259Sgreen return tree; 14676259Sgreen } 14792555Sdes 148262566Sdes public JCImport Import(JCTree qualid, boolean importStatic) { 149255767Sdes JCImport tree = new JCImport(qualid, importStatic); 15076259Sgreen tree.pos = pos; 15176259Sgreen return tree; 15298675Sdes } 15398675Sdes 15498675Sdes public JCClassDecl ClassDef(JCModifiers mods, 155262566Sdes Name name, 156255767Sdes List<JCTypeParameter> typarams, 15798675Sdes JCExpression extending, 15898675Sdes List<JCExpression> implementing, 159106121Sdes List<JCTree> defs) 160262566Sdes { 16198675Sdes JCClassDecl tree = new JCClassDecl(mods, 162162852Sdes name, 16398675Sdes typarams, 164264377Sdes extending, 16598675Sdes implementing, 16698675Sdes defs, 167262566Sdes null); 168262566Sdes tree.pos = pos; 169262566Sdes return tree; 170262566Sdes } 17176259Sgreen 17276259Sgreen public JCMethodDecl MethodDef(JCModifiers mods, 173262566Sdes Name name, 174262566Sdes JCExpression restype, 175262566Sdes List<JCTypeParameter> typarams, 176262566Sdes List<JCVariableDecl> params, 177262566Sdes List<JCExpression> thrown, 17876259Sgreen JCBlock body, 179262566Sdes JCExpression defaultValue) { 180262566Sdes return MethodDef( 181264377Sdes mods, name, restype, typarams, null, params, 182264377Sdes thrown, body, defaultValue); 183255767Sdes } 184262566Sdes 18576259Sgreen public JCMethodDecl MethodDef(JCModifiers mods, 18676259Sgreen Name name, 187106121Sdes JCExpression restype, 188106121Sdes List<JCTypeParameter> typarams, 189106121Sdes JCVariableDecl recvparam, 190106121Sdes List<JCVariableDecl> params, 191106121Sdes List<JCExpression> thrown, 192106121Sdes JCBlock body, 193106121Sdes JCExpression defaultValue) 194106121Sdes { 195106121Sdes JCMethodDecl tree = new JCMethodDecl(mods, 196106121Sdes name, 197106121Sdes restype, 198106121Sdes typarams, 199106121Sdes recvparam, 200106121Sdes params, 201106121Sdes thrown, 202106121Sdes body, 203106121Sdes defaultValue, 204106121Sdes null); 205106121Sdes tree.pos = pos; 206106121Sdes return tree; 207262566Sdes } 208106121Sdes 209106121Sdes public JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init) { 210106121Sdes JCVariableDecl tree = new JCVariableDecl(mods, name, vartype, init, null); 211215116Sdes tree.pos = pos; 212106121Sdes return tree; 213106121Sdes } 214106121Sdes 215106121Sdes public JCVariableDecl ReceiverVarDef(JCModifiers mods, JCExpression name, JCExpression vartype) { 216262566Sdes JCVariableDecl tree = new JCVariableDecl(mods, name, vartype); 217262566Sdes tree.pos = pos; 218106121Sdes return tree; 219106121Sdes } 220106121Sdes 221106121Sdes public JCSkip Skip() { 222106121Sdes JCSkip tree = new JCSkip(); 223106121Sdes tree.pos = pos; 224106121Sdes return tree; 225106121Sdes } 226106121Sdes 227106121Sdes public JCBlock Block(long flags, List<JCStatement> stats) { 228106121Sdes JCBlock tree = new JCBlock(flags, stats); 229106121Sdes tree.pos = pos; 230106121Sdes return tree; 231106121Sdes } 232106121Sdes 233106121Sdes public JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond) { 234106121Sdes JCDoWhileLoop tree = new JCDoWhileLoop(body, cond); 235106121Sdes tree.pos = pos; 236106121Sdes return tree; 237106121Sdes } 238106121Sdes 239106121Sdes public JCWhileLoop WhileLoop(JCExpression cond, JCStatement body) { 240106121Sdes JCWhileLoop tree = new JCWhileLoop(cond, body); 241149749Sdes tree.pos = pos; 242106121Sdes return tree; 243106121Sdes } 244106121Sdes 245215116Sdes public JCForLoop ForLoop(List<JCStatement> init, 246215116Sdes JCExpression cond, 247215116Sdes List<JCExpressionStatement> step, 248106121Sdes JCStatement body) 249106121Sdes { 250106121Sdes JCForLoop tree = new JCForLoop(init, cond, step, body); 251215116Sdes tree.pos = pos; 252106121Sdes return tree; 253106121Sdes } 254106121Sdes 255106121Sdes public JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body) { 256106121Sdes JCEnhancedForLoop tree = new JCEnhancedForLoop(var, expr, body); 257255767Sdes tree.pos = pos; 258106121Sdes return tree; 259106121Sdes } 260 261 public JCLabeledStatement Labelled(Name label, JCStatement body) { 262 JCLabeledStatement tree = new JCLabeledStatement(label, body); 263 tree.pos = pos; 264 return tree; 265 } 266 267 public JCSwitch Switch(JCExpression selector, List<JCCase> cases) { 268 JCSwitch tree = new JCSwitch(selector, cases); 269 tree.pos = pos; 270 return tree; 271 } 272 273 public JCCase Case(JCExpression pat, List<JCStatement> stats) { 274 JCCase tree = new JCCase(pat, stats); 275 tree.pos = pos; 276 return tree; 277 } 278 279 public JCSynchronized Synchronized(JCExpression lock, JCBlock body) { 280 JCSynchronized tree = new JCSynchronized(lock, body); 281 tree.pos = pos; 282 return tree; 283 } 284 285 public JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer) { 286 return Try(List.<JCTree>nil(), body, catchers, finalizer); 287 } 288 289 public JCTry Try(List<JCTree> resources, 290 JCBlock body, 291 List<JCCatch> catchers, 292 JCBlock finalizer) { 293 JCTry tree = new JCTry(resources, body, catchers, finalizer); 294 tree.pos = pos; 295 return tree; 296 } 297 298 public JCCatch Catch(JCVariableDecl param, JCBlock body) { 299 JCCatch tree = new JCCatch(param, body); 300 tree.pos = pos; 301 return tree; 302 } 303 304 public JCConditional Conditional(JCExpression cond, 305 JCExpression thenpart, 306 JCExpression elsepart) 307 { 308 JCConditional tree = new JCConditional(cond, thenpart, elsepart); 309 tree.pos = pos; 310 return tree; 311 } 312 313 public JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart) { 314 JCIf tree = new JCIf(cond, thenpart, elsepart); 315 tree.pos = pos; 316 return tree; 317 } 318 319 public JCExpressionStatement Exec(JCExpression expr) { 320 JCExpressionStatement tree = new JCExpressionStatement(expr); 321 tree.pos = pos; 322 return tree; 323 } 324 325 public JCBreak Break(Name label) { 326 JCBreak tree = new JCBreak(label, null); 327 tree.pos = pos; 328 return tree; 329 } 330 331 public JCContinue Continue(Name label) { 332 JCContinue tree = new JCContinue(label, null); 333 tree.pos = pos; 334 return tree; 335 } 336 337 public JCReturn Return(JCExpression expr) { 338 JCReturn tree = new JCReturn(expr); 339 tree.pos = pos; 340 return tree; 341 } 342 343 public JCThrow Throw(JCExpression expr) { 344 JCThrow tree = new JCThrow(expr); 345 tree.pos = pos; 346 return tree; 347 } 348 349 public JCAssert Assert(JCExpression cond, JCExpression detail) { 350 JCAssert tree = new JCAssert(cond, detail); 351 tree.pos = pos; 352 return tree; 353 } 354 355 public JCMethodInvocation Apply(List<JCExpression> typeargs, 356 JCExpression fn, 357 List<JCExpression> args) 358 { 359 JCMethodInvocation tree = new JCMethodInvocation(typeargs, fn, args); 360 tree.pos = pos; 361 return tree; 362 } 363 364 public JCNewClass NewClass(JCExpression encl, 365 List<JCExpression> typeargs, 366 JCExpression clazz, 367 List<JCExpression> args, 368 JCClassDecl def) 369 { 370 JCNewClass tree = new JCNewClass(encl, typeargs, clazz, args, def); 371 tree.pos = pos; 372 return tree; 373 } 374 375 public JCNewArray NewArray(JCExpression elemtype, 376 List<JCExpression> dims, 377 List<JCExpression> elems) 378 { 379 JCNewArray tree = new JCNewArray(elemtype, dims, elems); 380 tree.pos = pos; 381 return tree; 382 } 383 384 public JCLambda Lambda(List<JCVariableDecl> params, 385 JCTree body) 386 { 387 JCLambda tree = new JCLambda(params, body); 388 tree.pos = pos; 389 return tree; 390 } 391 392 public JCParens Parens(JCExpression expr) { 393 JCParens tree = new JCParens(expr); 394 tree.pos = pos; 395 return tree; 396 } 397 398 public JCAssign Assign(JCExpression lhs, JCExpression rhs) { 399 JCAssign tree = new JCAssign(lhs, rhs); 400 tree.pos = pos; 401 return tree; 402 } 403 404 public JCAssignOp Assignop(JCTree.Tag opcode, JCTree lhs, JCTree rhs) { 405 JCAssignOp tree = new JCAssignOp(opcode, lhs, rhs, null); 406 tree.pos = pos; 407 return tree; 408 } 409 410 public JCUnary Unary(JCTree.Tag opcode, JCExpression arg) { 411 JCUnary tree = new JCUnary(opcode, arg); 412 tree.pos = pos; 413 return tree; 414 } 415 416 public JCBinary Binary(JCTree.Tag opcode, JCExpression lhs, JCExpression rhs) { 417 JCBinary tree = new JCBinary(opcode, lhs, rhs, null); 418 tree.pos = pos; 419 return tree; 420 } 421 422 public JCTypeCast TypeCast(JCTree clazz, JCExpression expr) { 423 JCTypeCast tree = new JCTypeCast(clazz, expr); 424 tree.pos = pos; 425 return tree; 426 } 427 428 public JCInstanceOf TypeTest(JCExpression expr, JCTree clazz) { 429 JCInstanceOf tree = new JCInstanceOf(expr, clazz); 430 tree.pos = pos; 431 return tree; 432 } 433 434 public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) { 435 JCArrayAccess tree = new JCArrayAccess(indexed, index); 436 tree.pos = pos; 437 return tree; 438 } 439 440 public JCFieldAccess Select(JCExpression selected, Name selector) { 441 JCFieldAccess tree = new JCFieldAccess(selected, selector, null); 442 tree.pos = pos; 443 return tree; 444 } 445 446 public JCMemberReference Reference(JCMemberReference.ReferenceMode mode, Name name, 447 JCExpression expr, List<JCExpression> typeargs) { 448 JCMemberReference tree = new JCMemberReference(mode, name, expr, typeargs); 449 tree.pos = pos; 450 return tree; 451 } 452 453 public JCIdent Ident(Name name) { 454 JCIdent tree = new JCIdent(name, null); 455 tree.pos = pos; 456 return tree; 457 } 458 459 public JCLiteral Literal(TypeTag tag, Object value) { 460 JCLiteral tree = new JCLiteral(tag, value); 461 tree.pos = pos; 462 return tree; 463 } 464 465 public JCPrimitiveTypeTree TypeIdent(TypeTag typetag) { 466 JCPrimitiveTypeTree tree = new JCPrimitiveTypeTree(typetag); 467 tree.pos = pos; 468 return tree; 469 } 470 471 public JCArrayTypeTree TypeArray(JCExpression elemtype) { 472 JCArrayTypeTree tree = new JCArrayTypeTree(elemtype); 473 tree.pos = pos; 474 return tree; 475 } 476 477 public JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments) { 478 JCTypeApply tree = new JCTypeApply(clazz, arguments); 479 tree.pos = pos; 480 return tree; 481 } 482 483 public JCTypeUnion TypeUnion(List<JCExpression> components) { 484 JCTypeUnion tree = new JCTypeUnion(components); 485 tree.pos = pos; 486 return tree; 487 } 488 489 public JCTypeIntersection TypeIntersection(List<JCExpression> components) { 490 JCTypeIntersection tree = new JCTypeIntersection(components); 491 tree.pos = pos; 492 return tree; 493 } 494 495 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) { 496 return TypeParameter(name, bounds, List.<JCAnnotation>nil()); 497 } 498 499 public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annos) { 500 JCTypeParameter tree = new JCTypeParameter(name, bounds, annos); 501 tree.pos = pos; 502 return tree; 503 } 504 505 public JCWildcard Wildcard(TypeBoundKind kind, JCTree type) { 506 JCWildcard tree = new JCWildcard(kind, type); 507 tree.pos = pos; 508 return tree; 509 } 510 511 public TypeBoundKind TypeBoundKind(BoundKind kind) { 512 TypeBoundKind tree = new TypeBoundKind(kind); 513 tree.pos = pos; 514 return tree; 515 } 516 517 public JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args) { 518 JCAnnotation tree = new JCAnnotation(Tag.ANNOTATION, annotationType, args); 519 tree.pos = pos; 520 return tree; 521 } 522 523 public JCAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) { 524 JCAnnotation tree = new JCAnnotation(Tag.TYPE_ANNOTATION, annotationType, args); 525 tree.pos = pos; 526 return tree; 527 } 528 529 public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) { 530 JCModifiers tree = new JCModifiers(flags, annotations); 531 boolean noFlags = (flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0; 532 tree.pos = (noFlags && annotations.isEmpty()) ? Position.NOPOS : pos; 533 return tree; 534 } 535 536 public JCModifiers Modifiers(long flags) { 537 return Modifiers(flags, List.<JCAnnotation>nil()); 538 } 539 540 @Override 541 public JCModuleDecl ModuleDef(JCExpression qualid, List<JCDirective> directives) { 542 JCModuleDecl tree = new JCModuleDecl(qualid, directives); 543 tree.pos = pos; 544 return tree; 545 } 546 547 @Override 548 public JCExports Exports(JCExpression qualId, List<JCExpression> moduleNames) { 549 JCExports tree = new JCExports(qualId, moduleNames); 550 tree.pos = pos; 551 return tree; 552 } 553 554 @Override 555 public JCProvides Provides(JCExpression serviceName, JCExpression implName) { 556 JCProvides tree = new JCProvides(serviceName, implName); 557 tree.pos = pos; 558 return tree; 559 } 560 561 @Override 562 public JCRequires Requires(boolean isPublic, JCExpression qualId) { 563 JCRequires tree = new JCRequires(isPublic, qualId); 564 tree.pos = pos; 565 return tree; 566 } 567 568 @Override 569 public JCUses Uses(JCExpression qualId) { 570 JCUses tree = new JCUses(qualId); 571 tree.pos = pos; 572 return tree; 573 } 574 575 public JCAnnotatedType AnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) { 576 JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType); 577 tree.pos = pos; 578 return tree; 579 } 580 581 public JCErroneous Erroneous() { 582 return Erroneous(List.<JCTree>nil()); 583 } 584 585 public JCErroneous Erroneous(List<? extends JCTree> errs) { 586 JCErroneous tree = new JCErroneous(errs); 587 tree.pos = pos; 588 return tree; 589 } 590 591 public LetExpr LetExpr(List<JCVariableDecl> defs, JCExpression expr) { 592 LetExpr tree = new LetExpr(defs, expr); 593 tree.pos = pos; 594 return tree; 595 } 596 597/* *************************************************************************** 598 * Derived building blocks. 599 ****************************************************************************/ 600 601 public JCClassDecl AnonymousClassDef(JCModifiers mods, 602 List<JCTree> defs) 603 { 604 return ClassDef(mods, 605 names.empty, 606 List.<JCTypeParameter>nil(), 607 null, 608 List.<JCExpression>nil(), 609 defs); 610 } 611 612 public LetExpr LetExpr(JCVariableDecl def, JCExpression expr) { 613 LetExpr tree = new LetExpr(List.of(def), expr); 614 tree.pos = pos; 615 return tree; 616 } 617 618 /** Create an identifier from a symbol. 619 */ 620 public JCIdent Ident(Symbol sym) { 621 return (JCIdent)new JCIdent((sym.name != names.empty) 622 ? sym.name 623 : sym.flatName(), sym) 624 .setPos(pos) 625 .setType(sym.type); 626 } 627 628 /** Create a selection node from a qualifier tree and a symbol. 629 * @param base The qualifier tree. 630 */ 631 public JCExpression Select(JCExpression base, Symbol sym) { 632 return new JCFieldAccess(base, sym.name, sym).setPos(pos).setType(sym.type); 633 } 634 635 /** Create a qualified identifier from a symbol, adding enough qualifications 636 * to make the reference unique. 637 */ 638 public JCExpression QualIdent(Symbol sym) { 639 return isUnqualifiable(sym) 640 ? Ident(sym) 641 : Select(QualIdent(sym.owner), sym); 642 } 643 644 /** Create an identifier that refers to the variable declared in given variable 645 * declaration. 646 */ 647 public JCExpression Ident(JCVariableDecl param) { 648 return Ident(param.sym); 649 } 650 651 /** Create a list of identifiers referring to the variables declared 652 * in given list of variable declarations. 653 */ 654 public List<JCExpression> Idents(List<JCVariableDecl> params) { 655 ListBuffer<JCExpression> ids = new ListBuffer<>(); 656 for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) 657 ids.append(Ident(l.head)); 658 return ids.toList(); 659 } 660 661 /** Create a tree representing `this', given its type. 662 */ 663 public JCExpression This(Type t) { 664 return Ident(new VarSymbol(FINAL, names._this, t, t.tsym)); 665 } 666 667 /** Create a tree representing qualified `this' given its type 668 */ 669 public JCExpression QualThis(Type t) { 670 return Select(Type(t), new VarSymbol(FINAL, names._this, t, t.tsym)); 671 } 672 673 /** Create a tree representing a class literal. 674 */ 675 public JCExpression ClassLiteral(ClassSymbol clazz) { 676 return ClassLiteral(clazz.type); 677 } 678 679 /** Create a tree representing a class literal. 680 */ 681 public JCExpression ClassLiteral(Type t) { 682 VarSymbol lit = new VarSymbol(STATIC | PUBLIC | FINAL, 683 names._class, 684 t, 685 t.tsym); 686 return Select(Type(t), lit); 687 } 688 689 /** Create a tree representing `super', given its type and owner. 690 */ 691 public JCIdent Super(Type t, TypeSymbol owner) { 692 return Ident(new VarSymbol(FINAL, names._super, t, owner)); 693 } 694 695 /** 696 * Create a method invocation from a method tree and a list of 697 * argument trees. 698 */ 699 public JCMethodInvocation App(JCExpression meth, List<JCExpression> args) { 700 return Apply(null, meth, args).setType(meth.type.getReturnType()); 701 } 702 703 /** 704 * Create a no-arg method invocation from a method tree 705 */ 706 public JCMethodInvocation App(JCExpression meth) { 707 return Apply(null, meth, List.<JCExpression>nil()).setType(meth.type.getReturnType()); 708 } 709 710 /** Create a method invocation from a method tree and a list of argument trees. 711 */ 712 public JCExpression Create(Symbol ctor, List<JCExpression> args) { 713 Type t = ctor.owner.erasure(types); 714 JCNewClass newclass = NewClass(null, null, Type(t), args, null); 715 newclass.constructor = ctor; 716 newclass.setType(t); 717 return newclass; 718 } 719 720 /** Create a tree representing given type. 721 */ 722 public JCExpression Type(Type t) { 723 if (t == null) return null; 724 JCExpression tp; 725 switch (t.getTag()) { 726 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 727 case DOUBLE: case BOOLEAN: case VOID: 728 tp = TypeIdent(t.getTag()); 729 break; 730 case TYPEVAR: 731 tp = Ident(t.tsym); 732 break; 733 case WILDCARD: { 734 WildcardType a = ((WildcardType) t); 735 tp = Wildcard(TypeBoundKind(a.kind), a.kind == BoundKind.UNBOUND ? null : Type(a.type)); 736 break; 737 } 738 case CLASS: 739 switch (t.getKind()) { 740 case UNION: { 741 UnionClassType tu = (UnionClassType)t; 742 ListBuffer<JCExpression> la = new ListBuffer<>(); 743 for (Type ta : tu.getAlternativeTypes()) { 744 la.add(Type(ta)); 745 } 746 tp = TypeUnion(la.toList()); 747 break; 748 } 749 case INTERSECTION: { 750 IntersectionClassType it = (IntersectionClassType)t; 751 ListBuffer<JCExpression> la = new ListBuffer<>(); 752 for (Type ta : it.getExplicitComponents()) { 753 la.add(Type(ta)); 754 } 755 tp = TypeIntersection(la.toList()); 756 break; 757 } 758 default: { 759 Type outer = t.getEnclosingType(); 760 JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP 761 ? Select(Type(outer), t.tsym) 762 : QualIdent(t.tsym); 763 tp = t.getTypeArguments().isEmpty() 764 ? clazz 765 : TypeApply(clazz, Types(t.getTypeArguments())); 766 break; 767 } 768 } 769 break; 770 case ARRAY: 771 tp = TypeArray(Type(types.elemtype(t))); 772 break; 773 case ERROR: 774 tp = TypeIdent(ERROR); 775 break; 776 default: 777 throw new AssertionError("unexpected type: " + t); 778 } 779 return tp.setType(t); 780 } 781 782 /** Create a list of trees representing given list of types. 783 */ 784 public List<JCExpression> Types(List<Type> ts) { 785 ListBuffer<JCExpression> lb = new ListBuffer<>(); 786 for (List<Type> l = ts; l.nonEmpty(); l = l.tail) 787 lb.append(Type(l.head)); 788 return lb.toList(); 789 } 790 791 /** Create a variable definition from a variable symbol and an initializer 792 * expression. 793 */ 794 public JCVariableDecl VarDef(VarSymbol v, JCExpression init) { 795 return (JCVariableDecl) 796 new JCVariableDecl( 797 Modifiers(v.flags(), Annotations(v.getRawAttributes())), 798 v.name, 799 Type(v.type), 800 init, 801 v).setPos(pos).setType(v.type); 802 } 803 804 /** Create annotation trees from annotations. 805 */ 806 public List<JCAnnotation> Annotations(List<Attribute.Compound> attributes) { 807 if (attributes == null) return List.nil(); 808 ListBuffer<JCAnnotation> result = new ListBuffer<>(); 809 for (List<Attribute.Compound> i = attributes; i.nonEmpty(); i=i.tail) { 810 Attribute a = i.head; 811 result.append(Annotation(a)); 812 } 813 return result.toList(); 814 } 815 816 public JCLiteral Literal(Object value) { 817 JCLiteral result = null; 818 if (value instanceof String) { 819 result = Literal(CLASS, value). 820 setType(syms.stringType.constType(value)); 821 } else if (value instanceof Integer) { 822 result = Literal(INT, value). 823 setType(syms.intType.constType(value)); 824 } else if (value instanceof Long) { 825 result = Literal(LONG, value). 826 setType(syms.longType.constType(value)); 827 } else if (value instanceof Byte) { 828 result = Literal(BYTE, value). 829 setType(syms.byteType.constType(value)); 830 } else if (value instanceof Character) { 831 int v = (int) (((Character) value).toString().charAt(0)); 832 result = Literal(CHAR, v). 833 setType(syms.charType.constType(v)); 834 } else if (value instanceof Double) { 835 result = Literal(DOUBLE, value). 836 setType(syms.doubleType.constType(value)); 837 } else if (value instanceof Float) { 838 result = Literal(FLOAT, value). 839 setType(syms.floatType.constType(value)); 840 } else if (value instanceof Short) { 841 result = Literal(SHORT, value). 842 setType(syms.shortType.constType(value)); 843 } else if (value instanceof Boolean) { 844 int v = ((Boolean) value) ? 1 : 0; 845 result = Literal(BOOLEAN, v). 846 setType(syms.booleanType.constType(v)); 847 } else { 848 throw new AssertionError(value); 849 } 850 return result; 851 } 852 853 class AnnotationBuilder implements Attribute.Visitor { 854 JCExpression result = null; 855 public void visitConstant(Attribute.Constant v) { 856 result = Literal(v.type.getTag(), v.value); 857 } 858 public void visitClass(Attribute.Class clazz) { 859 result = ClassLiteral(clazz.classType).setType(syms.classType); 860 } 861 public void visitEnum(Attribute.Enum e) { 862 result = QualIdent(e.value); 863 } 864 public void visitError(Attribute.Error e) { 865 result = Erroneous(); 866 } 867 public void visitCompound(Attribute.Compound compound) { 868 if (compound instanceof Attribute.TypeCompound) { 869 result = visitTypeCompoundInternal((Attribute.TypeCompound) compound); 870 } else { 871 result = visitCompoundInternal(compound); 872 } 873 } 874 public JCAnnotation visitCompoundInternal(Attribute.Compound compound) { 875 ListBuffer<JCExpression> args = new ListBuffer<>(); 876 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) { 877 Pair<MethodSymbol,Attribute> pair = values.head; 878 JCExpression valueTree = translate(pair.snd); 879 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type)); 880 } 881 return Annotation(Type(compound.type), args.toList()); 882 } 883 public JCAnnotation visitTypeCompoundInternal(Attribute.TypeCompound compound) { 884 ListBuffer<JCExpression> args = new ListBuffer<>(); 885 for (List<Pair<Symbol.MethodSymbol,Attribute>> values = compound.values; values.nonEmpty(); values=values.tail) { 886 Pair<MethodSymbol,Attribute> pair = values.head; 887 JCExpression valueTree = translate(pair.snd); 888 args.append(Assign(Ident(pair.fst), valueTree).setType(valueTree.type)); 889 } 890 return TypeAnnotation(Type(compound.type), args.toList()); 891 } 892 public void visitArray(Attribute.Array array) { 893 ListBuffer<JCExpression> elems = new ListBuffer<>(); 894 for (int i = 0; i < array.values.length; i++) 895 elems.append(translate(array.values[i])); 896 result = NewArray(null, List.<JCExpression>nil(), elems.toList()).setType(array.type); 897 } 898 JCExpression translate(Attribute a) { 899 a.accept(this); 900 return result; 901 } 902 JCAnnotation translate(Attribute.Compound a) { 903 return visitCompoundInternal(a); 904 } 905 JCAnnotation translate(Attribute.TypeCompound a) { 906 return visitTypeCompoundInternal(a); 907 } 908 } 909 910 AnnotationBuilder annotationBuilder = new AnnotationBuilder(); 911 912 /** Create an annotation tree from an attribute. 913 */ 914 public JCAnnotation Annotation(Attribute a) { 915 return annotationBuilder.translate((Attribute.Compound)a); 916 } 917 918 public JCAnnotation TypeAnnotation(Attribute a) { 919 return annotationBuilder.translate((Attribute.TypeCompound) a); 920 } 921 922 /** Create a method definition from a method symbol and a method body. 923 */ 924 public JCMethodDecl MethodDef(MethodSymbol m, JCBlock body) { 925 return MethodDef(m, m.type, body); 926 } 927 928 /** Create a method definition from a method symbol, method type 929 * and a method body. 930 */ 931 public JCMethodDecl MethodDef(MethodSymbol m, Type mtype, JCBlock body) { 932 return (JCMethodDecl) 933 new JCMethodDecl( 934 Modifiers(m.flags(), Annotations(m.getRawAttributes())), 935 m.name, 936 Type(mtype.getReturnType()), 937 TypeParams(mtype.getTypeArguments()), 938 null, // receiver type 939 Params(mtype.getParameterTypes(), m), 940 Types(mtype.getThrownTypes()), 941 body, 942 null, 943 m).setPos(pos).setType(mtype); 944 } 945 946 /** Create a type parameter tree from its name and type. 947 */ 948 public JCTypeParameter TypeParam(Name name, TypeVar tvar) { 949 return (JCTypeParameter) 950 TypeParameter(name, Types(types.getBounds(tvar))).setPos(pos).setType(tvar); 951 } 952 953 /** Create a list of type parameter trees from a list of type variables. 954 */ 955 public List<JCTypeParameter> TypeParams(List<Type> typarams) { 956 ListBuffer<JCTypeParameter> tparams = new ListBuffer<>(); 957 for (List<Type> l = typarams; l.nonEmpty(); l = l.tail) 958 tparams.append(TypeParam(l.head.tsym.name, (TypeVar)l.head)); 959 return tparams.toList(); 960 } 961 962 /** Create a value parameter tree from its name, type, and owner. 963 */ 964 public JCVariableDecl Param(Name name, Type argtype, Symbol owner) { 965 return VarDef(new VarSymbol(PARAMETER, name, argtype, owner), null); 966 } 967 968 /** Create a a list of value parameter trees x0, ..., xn from a list of 969 * their types and an their owner. 970 */ 971 public List<JCVariableDecl> Params(List<Type> argtypes, Symbol owner) { 972 ListBuffer<JCVariableDecl> params = new ListBuffer<>(); 973 MethodSymbol mth = (owner.kind == MTH) ? ((MethodSymbol)owner) : null; 974 if (mth != null && mth.params != null && argtypes.length() == mth.params.length()) { 975 for (VarSymbol param : ((MethodSymbol)owner).params) 976 params.append(VarDef(param, null)); 977 } else { 978 int i = 0; 979 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail) 980 params.append(Param(paramName(i++), l.head, owner)); 981 } 982 return params.toList(); 983 } 984 985 /** Wrap a method invocation in an expression statement or return statement, 986 * depending on whether the method invocation expression's type is void. 987 */ 988 public JCStatement Call(JCExpression apply) { 989 return apply.type.hasTag(VOID) ? Exec(apply) : Return(apply); 990 } 991 992 /** Construct an assignment from a variable symbol and a right hand side. 993 */ 994 public JCStatement Assignment(Symbol v, JCExpression rhs) { 995 return Exec(Assign(Ident(v), rhs).setType(v.type)); 996 } 997 998 /** Construct an index expression from a variable and an expression. 999 */ 1000 public JCArrayAccess Indexed(Symbol v, JCExpression index) { 1001 JCArrayAccess tree = new JCArrayAccess(QualIdent(v), index); 1002 tree.type = ((ArrayType)v.type).elemtype; 1003 return tree; 1004 } 1005 1006 /** Make an attributed type cast expression. 1007 */ 1008 public JCTypeCast TypeCast(Type type, JCExpression expr) { 1009 return (JCTypeCast)TypeCast(Type(type), expr).setType(type); 1010 } 1011 1012/* *************************************************************************** 1013 * Helper methods. 1014 ****************************************************************************/ 1015 1016 /** Can given symbol be referred to in unqualified form? 1017 */ 1018 boolean isUnqualifiable(Symbol sym) { 1019 if (sym.name == names.empty || 1020 sym.owner == null || 1021 sym.owner == syms.rootPackage || 1022 sym.owner.kind == MTH || sym.owner.kind == VAR) { 1023 return true; 1024 } else if (sym.kind == TYP && toplevel != null) { 1025 Iterator<Symbol> it = toplevel.namedImportScope.getSymbolsByName(sym.name).iterator(); 1026 if (it.hasNext()) { 1027 Symbol s = it.next(); 1028 return 1029 s == sym && 1030 !it.hasNext(); 1031 } 1032 it = toplevel.packge.members().getSymbolsByName(sym.name).iterator(); 1033 if (it.hasNext()) { 1034 Symbol s = it.next(); 1035 return 1036 s == sym && 1037 !it.hasNext(); 1038 } 1039 it = toplevel.starImportScope.getSymbolsByName(sym.name).iterator(); 1040 if (it.hasNext()) { 1041 Symbol s = it.next(); 1042 return 1043 s == sym && 1044 !it.hasNext(); 1045 } 1046 } 1047 return false; 1048 } 1049 1050 /** The name of synthetic parameter number `i'. 1051 */ 1052 public Name paramName(int i) { return names.fromString("x" + i); } 1053 1054 /** The name of synthetic type parameter number `i'. 1055 */ 1056 public Name typaramName(int i) { return names.fromString("A" + i); } 1057} 1058