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