1 /*
   2  * Copyright (c) 1999, 2011, 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.*;
  29 
  30 import java.io.IOException;
  31 import java.io.StringWriter;
  32 import javax.lang.model.element.Modifier;
  33 import javax.lang.model.type.TypeKind;
  34 import javax.tools.JavaFileObject;
  35 
  36 import com.sun.tools.javac.util.*;
  37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  38 import com.sun.tools.javac.util.List;
  39 import com.sun.tools.javac.code.*;
  40 import com.sun.tools.javac.code.Scope.*;
  41 import com.sun.tools.javac.code.Symbol.*;
  42 import com.sun.source.tree.*;
  43 
  44 import static com.sun.tools.javac.code.BoundKind.*;
  45 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  46 
  47 /**
  48  * Root class for abstract syntax tree nodes. It provides definitions
  49  * for specific tree nodes as subclasses nested inside.
  50  *
  51  * <p>Each subclass is highly standardized.  It generally contains
  52  * only tree fields for the syntactic subcomponents of the node.  Some
  53  * classes that represent identifier uses or definitions also define a
  54  * Symbol field that denotes the represented identifier.  Classes for
  55  * non-local jumps also carry the jump target as a field.  The root
  56  * class Tree itself defines fields for the tree's type and position.
  57  * No other fields are kept in a tree node; instead parameters are
  58  * passed to methods accessing the node.
  59  *
  60  * <p>Except for the methods defined by com.sun.source, the only
  61  * method defined in subclasses is `visit' which applies a given
  62  * visitor to the tree. The actual tree processing is done by visitor
  63  * classes in other packages. The abstract class Visitor, as well as
  64  * an Factory interface for trees, are defined as inner classes in
  65  * Tree.
  66  *
  67  * <p>To avoid ambiguities with the Tree API in com.sun.source all sub
  68  * classes should, by convention, start with JC (javac).
  69  *
  70  * <p><b>This is NOT part of any supported API.
  71  * If you write code that depends on this, you do so at your own risk.
  72  * This code and its internal interfaces are subject to change or
  73  * deletion without notice.</b>
  74  *
  75  * @see TreeMaker
  76  * @see TreeInfo
  77  * @see TreeTranslator
  78  * @see Pretty
  79  */
  80 public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
  81 
  82     /* Tree tag values, identifying kinds of trees */
  83     public enum Tag{
  84         /** For methods that return an invalid tag if a given condition is not met
  85          */
  86         NO_TAG,
  87         
  88         /** Toplevel nodes, of type TopLevel, representing entire source files.
  89         */
  90         TOPLEVEL,
  91 
  92         /** Import clauses, of type Import.
  93          */
  94         IMPORT,
  95 
  96         /** Class definitions, of type ClassDef.
  97          */
  98         CLASSDEF,
  99 
 100         /** Method definitions, of type MethodDef.
 101          */
 102         METHODDEF,
 103 
 104         /** Variable definitions, of type VarDef.
 105          */
 106         VARDEF,
 107 
 108         /** The no-op statement ";", of type Skip
 109          */
 110         SKIP,
 111 
 112         /** Blocks, of type Block.
 113          */
 114         BLOCK,
 115 
 116         /** Do-while loops, of type DoLoop.
 117          */
 118         DOLOOP,
 119 
 120         /** While-loops, of type WhileLoop.
 121          */
 122         WHILELOOP,
 123 
 124         /** For-loops, of type ForLoop.
 125          */
 126         FORLOOP,
 127 
 128         /** Foreach-loops, of type ForeachLoop.
 129          */
 130         FOREACHLOOP,
 131 
 132         /** Labelled statements, of type Labelled.
 133          */
 134         LABELLED,
 135 
 136         /** Switch statements, of type Switch.
 137          */
 138         SWITCH,
 139 
 140         /** Case parts in switch statements, of type Case.
 141          */
 142         CASE,
 143 
 144         /** Synchronized statements, of type Synchonized.
 145          */
 146         SYNCHRONIZED,
 147 
 148         /** Try statements, of type Try.
 149          */
 150         TRY,
 151 
 152         /** Catch clauses in try statements, of type Catch.
 153          */
 154         CATCH,
 155 
 156         /** Conditional expressions, of type Conditional.
 157          */
 158         CONDEXPR,
 159 
 160         /** Conditional statements, of type If.
 161          */
 162         IF,
 163 
 164         /** Expression statements, of type Exec.
 165          */
 166         EXEC,
 167 
 168         /** Break statements, of type Break.
 169          */
 170         BREAK,
 171 
 172         /** Continue statements, of type Continue.
 173          */
 174         CONTINUE,
 175 
 176         /** Return statements, of type Return.
 177          */
 178         RETURN,
 179 
 180         /** Throw statements, of type Throw.
 181          */
 182         THROW,
 183 
 184         /** Assert statements, of type Assert.
 185          */
 186         ASSERT,
 187 
 188         /** Method invocation expressions, of type Apply.
 189          */
 190         APPLY,
 191 
 192         /** Class instance creation expressions, of type NewClass.
 193          */
 194         NEWCLASS,
 195 
 196         /** Array creation expressions, of type NewArray.
 197          */
 198         NEWARRAY,
 199 
 200         /** Parenthesized subexpressions, of type Parens.
 201          */
 202         PARENS,
 203 
 204         /** Assignment expressions, of type Assign.
 205          */
 206         ASSIGN,
 207 
 208         /** Type cast expressions, of type TypeCast.
 209          */
 210         TYPECAST,
 211 
 212         /** Type test expressions, of type TypeTest.
 213          */
 214         TYPETEST,
 215 
 216         /** Indexed array expressions, of type Indexed.
 217          */
 218         INDEXED,
 219 
 220         /** Selections, of type Select.
 221          */
 222         SELECT,
 223 
 224         /** Simple identifiers, of type Ident.
 225          */
 226         IDENT,
 227 
 228         /** Literals, of type Literal.
 229          */
 230         LITERAL,
 231 
 232         /** Basic type identifiers, of type TypeIdent.
 233          */
 234         TYPEIDENT,
 235 
 236         /** Array types, of type TypeArray.
 237          */
 238         TYPEARRAY,
 239 
 240         /** Parameterized types, of type TypeApply.
 241          */
 242         TYPEAPPLY,
 243 
 244         /** Union types, of type TypeUnion
 245          */
 246         TYPEUNION,
 247 
 248         /** Formal type parameters, of type TypeParameter.
 249          */
 250         TYPEPARAMETER,
 251 
 252         /** Type argument.
 253          */
 254         WILDCARD,
 255 
 256         /** Bound kind: extends, super, exact, or unbound
 257          */
 258         TYPEBOUNDKIND,
 259 
 260         /** metadata: Annotation.
 261          */
 262         ANNOTATION,
 263 
 264         /** metadata: Modifiers
 265          */
 266         MODIFIERS,
 267 
 268         ANNOTATED_TYPE,
 269 
 270         /** Error trees, of type Erroneous.
 271          */
 272         ERRONEOUS,
 273 
 274         /** Unary operators, of type Unary.
 275          */
 276         POS,                             // +
 277         NEG,                             // -
 278         NOT,                             // !
 279         COMPL,                           // ~
 280         PREINC,                          // ++ _
 281         PREDEC,                          // -- _
 282         POSTINC,                         // _ ++
 283         POSTDEC,                         // _ --
 284 
 285         /** unary operator for null reference checks, only used internally.
 286          */
 287         NULLCHK,
 288 
 289         /** Binary operators, of type Binary.
 290          */
 291         OR,                              // ||
 292         AND,                             // &&
 293         BITOR,                           // |
 294         BITXOR,                          // ^
 295         BITAND,                          // &
 296         EQ,                              // ==
 297         NE,                              // !=
 298         LT,                              // <
 299         GT,                              // >
 300         LE,                              // <=
 301         GE,                              // >=
 302         SL,                              // <<
 303         SR,                              // >>
 304         USR,                             // >>>
 305         PLUS,                            // +
 306         MINUS,                           // -
 307         MUL,                             // *
 308         DIV,                             // /
 309         MOD,                             // %
 310 
 311         /** Assignment operators, of type Assignop.
 312          */
 313         BITOR_ASG(BITOR),                       // |=
 314         BITXOR_ASG(BITXOR),                      // ^=
 315         BITAND_ASG(BITAND),                      // &=
 316 
 317         SL_ASG(SL),                         // <<=
 318         SR_ASG(SR),                          // >>=
 319         USR_ASG(USR),                         // >>>=
 320         PLUS_ASG(PLUS),                        // +=
 321         MINUS_ASG(MINUS),                       // -=
 322         MUL_ASG(MUL),                         // *=
 323         DIV_ASG(DIV),                         // /=
 324         MOD_ASG(MOD),                         // %=
 325 
 326         /** A synthetic let expression, of type LetExpr.
 327          */
 328         LETEXPR;                          // ala scheme
 329         
 330         private Tag noAssignTag;
 331         
 332         private Tag(Tag noAssignTag)
 333         {
 334             this.noAssignTag = noAssignTag;
 335         }
 336         
 337         private Tag()
 338         {
 339         }
 340         
 341         public Tag noAssignOp()
 342         {
 343             if (this.noAssignTag != null)
 344                 return noAssignTag;
 345             throw new AssertionError("noAssignOp() method is not available for non assignment tags");
 346         }
 347     }
 348 
 349     /* The (encoded) position in the source file. @see util.Position.
 350      */
 351     public int pos;
 352 
 353     /* The type of this node.
 354      */
 355     public Type type;
 356 
 357     /* The tag of this node -- one of the constants declared above.
 358      */
 359     public abstract Tag getTag();
 360     
 361     /* Returns true if the tag of this node is equals to tag.
 362      */
 363     public abstract boolean hasTag(Tag tag);
 364 
 365     /** Convert a tree to a pretty-printed string. */
 366     @Override
 367     public String toString() {
 368         StringWriter s = new StringWriter();
 369         try {
 370             new Pretty(s, false).printExpr(this);
 371         }
 372         catch (IOException e) {
 373             // should never happen, because StringWriter is defined
 374             // never to throw any IOExceptions
 375             throw new AssertionError(e);
 376         }
 377         return s.toString();
 378     }
 379 
 380     /** Set position field and return this tree.
 381      */
 382     public JCTree setPos(int pos) {
 383         this.pos = pos;
 384         return this;
 385     }
 386 
 387     /** Set type field and return this tree.
 388      */
 389     public JCTree setType(Type type) {
 390         this.type = type;
 391         return this;
 392     }
 393 
 394     /** Visit this tree with a given visitor.
 395      */
 396     public abstract void accept(Visitor v);
 397 
 398     public abstract <R,D> R accept(TreeVisitor<R,D> v, D d);
 399 
 400     /** Return a shallow copy of this tree.
 401      */
 402     @Override
 403     public Object clone() {
 404         try {
 405             return super.clone();
 406         } catch(CloneNotSupportedException e) {
 407             throw new RuntimeException(e);
 408         }
 409     }
 410 
 411     /** Get a default position for this tree node.
 412      */
 413     public DiagnosticPosition pos() {
 414         return this;
 415     }
 416 
 417     // for default DiagnosticPosition
 418     public JCTree getTree() {
 419         return this;
 420     }
 421 
 422     // for default DiagnosticPosition
 423     public int getStartPosition() {
 424         return TreeInfo.getStartPos(this);
 425     }
 426 
 427     // for default DiagnosticPosition
 428     public int getPreferredPosition() {
 429         return pos;
 430     }
 431 
 432     // for default DiagnosticPosition
 433     public int getEndPosition(Map<JCTree, Integer> endPosTable) {
 434         return TreeInfo.getEndPos(this, endPosTable);
 435     }
 436 
 437     /**
 438      * Everything in one source file is kept in a TopLevel structure.
 439      * @param pid              The tree representing the package clause.
 440      * @param sourcefile       The source file name.
 441      * @param defs             All definitions in this file (ClassDef, Import, and Skip)
 442      * @param packge           The package it belongs to.
 443      * @param namedImportScope A scope for all named imports.
 444      * @param starImportScope  A scope for all import-on-demands.
 445      * @param lineMap          Line starting positions, defined only
 446      *                         if option -g is set.
 447      * @param docComments      A hashtable that stores all documentation comments
 448      *                         indexed by the tree nodes they refer to.
 449      *                         defined only if option -s is set.
 450      * @param endPositions     A hashtable that stores ending positions of source
 451      *                         ranges indexed by the tree nodes they belong to.
 452      *                         Defined only if option -Xjcov is set.
 453      */
 454     public static class JCCompilationUnit extends JCTree implements CompilationUnitTree {
 455         public List<JCAnnotation> packageAnnotations;
 456         public JCExpression pid;
 457         public List<JCTree> defs;
 458         public JavaFileObject sourcefile;
 459         public PackageSymbol packge;
 460         public ImportScope namedImportScope;
 461         public StarImportScope starImportScope;
 462         public Position.LineMap lineMap = null;
 463         public Map<JCTree, String> docComments = null;
 464         public Map<JCTree, Integer> endPositions = null;
 465         protected JCCompilationUnit(List<JCAnnotation> packageAnnotations,
 466                         JCExpression pid,
 467                         List<JCTree> defs,
 468                         JavaFileObject sourcefile,
 469                         PackageSymbol packge,
 470                         ImportScope namedImportScope,
 471                         StarImportScope starImportScope) {
 472             this.packageAnnotations = packageAnnotations;
 473             this.pid = pid;
 474             this.defs = defs;
 475             this.sourcefile = sourcefile;
 476             this.packge = packge;
 477             this.namedImportScope = namedImportScope;
 478             this.starImportScope = starImportScope;
 479         }
 480         @Override
 481         public void accept(Visitor v) { v.visitTopLevel(this); }
 482 
 483         public Kind getKind() { return Kind.COMPILATION_UNIT; }
 484         public List<JCAnnotation> getPackageAnnotations() {
 485             return packageAnnotations;
 486         }
 487         public List<JCImport> getImports() {
 488             ListBuffer<JCImport> imports = new ListBuffer<JCImport>();
 489             for (JCTree tree : defs) {
 490                 if (tree.hasTag(IMPORT))
 491                     imports.append((JCImport)tree);
 492                 else if (!tree.hasTag(SKIP))
 493                     break;
 494             }
 495             return imports.toList();
 496         }
 497         public JCExpression getPackageName() { return pid; }
 498         public JavaFileObject getSourceFile() {
 499             return sourcefile;
 500         }
 501         public Position.LineMap getLineMap() {
 502             return lineMap;
 503         }
 504         public List<JCTree> getTypeDecls() {
 505             List<JCTree> typeDefs;
 506             for (typeDefs = defs; !typeDefs.isEmpty(); typeDefs = typeDefs.tail)
 507                 if (!typeDefs.head.hasTag(IMPORT))
 508                     break;
 509             return typeDefs;
 510         }
 511         @Override
 512         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 513             return v.visitCompilationUnit(this, d);
 514         }
 515 
 516         @Override
 517         public Tag getTag() {
 518             return TOPLEVEL;
 519         }
 520         
 521         @Override
 522         public boolean hasTag(Tag tag){
 523             return (tag.equals(TOPLEVEL));
 524         }
 525     }
 526 
 527     /**
 528      * An import clause.
 529      * @param qualid    The imported class(es).
 530      */
 531     public static class JCImport extends JCTree implements ImportTree {
 532         public boolean staticImport;
 533         public JCTree qualid;
 534         protected JCImport(JCTree qualid, boolean importStatic) {
 535             this.qualid = qualid;
 536             this.staticImport = importStatic;
 537         }
 538         @Override
 539         public void accept(Visitor v) { v.visitImport(this); }
 540 
 541         public boolean isStatic() { return staticImport; }
 542         public JCTree getQualifiedIdentifier() { return qualid; }
 543 
 544         public Kind getKind() { return Kind.IMPORT; }
 545         @Override
 546         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 547             return v.visitImport(this, d);
 548         }
 549 
 550         @Override
 551         public Tag getTag() {
 552             return IMPORT;
 553         }
 554         
 555         @Override
 556         public boolean hasTag(Tag tag){
 557             return (tag.equals(IMPORT));
 558         }
 559     }
 560 
 561     public static abstract class JCStatement extends JCTree implements StatementTree {
 562         @Override
 563         public JCStatement setType(Type type) {
 564             super.setType(type);
 565             return this;
 566         }
 567         @Override
 568         public JCStatement setPos(int pos) {
 569             super.setPos(pos);
 570             return this;
 571         }
 572     }
 573 
 574     public static abstract class JCExpression extends JCTree implements ExpressionTree {
 575         @Override
 576         public JCExpression setType(Type type) {
 577             super.setType(type);
 578             return this;
 579         }
 580         @Override
 581         public JCExpression setPos(int pos) {
 582             super.setPos(pos);
 583             return this;
 584         }
 585     }
 586 
 587     /**
 588      * A class definition.
 589      * @param modifiers the modifiers
 590      * @param name the name of the class
 591      * @param typarams formal class parameters
 592      * @param extending the classes this class extends
 593      * @param implementing the interfaces implemented by this class
 594      * @param defs all variables and methods defined in this class
 595      * @param sym the symbol
 596      */
 597     public static class JCClassDecl extends JCStatement implements ClassTree {
 598         public JCModifiers mods;
 599         public Name name;
 600         public List<JCTypeParameter> typarams;
 601         public JCExpression extending;
 602         public List<JCExpression> implementing;
 603         public List<JCTree> defs;
 604         public ClassSymbol sym;
 605         protected JCClassDecl(JCModifiers mods,
 606                            Name name,
 607                            List<JCTypeParameter> typarams,
 608                            JCExpression extending,
 609                            List<JCExpression> implementing,
 610                            List<JCTree> defs,
 611                            ClassSymbol sym)
 612         {
 613             this.mods = mods;
 614             this.name = name;
 615             this.typarams = typarams;
 616             this.extending = extending;
 617             this.implementing = implementing;
 618             this.defs = defs;
 619             this.sym = sym;
 620         }
 621         @Override
 622         public void accept(Visitor v) { v.visitClassDef(this); }
 623 
 624         public Kind getKind() {
 625             if ((mods.flags & Flags.ANNOTATION) != 0)
 626                 return Kind.ANNOTATION_TYPE;
 627             else if ((mods.flags & Flags.INTERFACE) != 0)
 628                 return Kind.INTERFACE;
 629             else if ((mods.flags & Flags.ENUM) != 0)
 630                 return Kind.ENUM;
 631             else
 632                 return Kind.CLASS;
 633         }
 634 
 635         public JCModifiers getModifiers() { return mods; }
 636         public Name getSimpleName() { return name; }
 637         public List<JCTypeParameter> getTypeParameters() {
 638             return typarams;
 639         }
 640         public JCTree getExtendsClause() { return extending; }
 641         public List<JCExpression> getImplementsClause() {
 642             return implementing;
 643         }
 644         public List<JCTree> getMembers() {
 645             return defs;
 646         }
 647         @Override
 648         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 649             return v.visitClass(this, d);
 650         }
 651 
 652         @Override
 653         public Tag getTag() {
 654             return CLASSDEF;
 655         }
 656         
 657         @Override
 658         public boolean hasTag(Tag tag){
 659             return (tag.equals(CLASSDEF));
 660         }
 661     }
 662 
 663     /**
 664      * A method definition.
 665      * @param modifiers method modifiers
 666      * @param name method name
 667      * @param restype type of method return value
 668      * @param typarams type parameters
 669      * @param params value parameters
 670      * @param thrown exceptions thrown by this method
 671      * @param stats statements in the method
 672      * @param sym method symbol
 673      */
 674     public static class JCMethodDecl extends JCTree implements MethodTree {
 675         public JCModifiers mods;
 676         public Name name;
 677         public JCExpression restype;
 678         public List<JCTypeParameter> typarams;
 679         public List<JCVariableDecl> params;
 680         public List<JCExpression> thrown;
 681         public JCBlock body;
 682         public JCExpression defaultValue; // for annotation types
 683         public MethodSymbol sym;
 684         protected JCMethodDecl(JCModifiers mods,
 685                             Name name,
 686                             JCExpression restype,
 687                             List<JCTypeParameter> typarams,
 688                             List<JCVariableDecl> params,
 689                             List<JCExpression> thrown,
 690                             JCBlock body,
 691                             JCExpression defaultValue,
 692                             MethodSymbol sym)
 693         {
 694             this.mods = mods;
 695             this.name = name;
 696             this.restype = restype;
 697             this.typarams = typarams;
 698             this.params = params;
 699             this.thrown = thrown;
 700             this.body = body;
 701             this.defaultValue = defaultValue;
 702             this.sym = sym;
 703         }
 704         @Override
 705         public void accept(Visitor v) { v.visitMethodDef(this); }
 706 
 707         public Kind getKind() { return Kind.METHOD; }
 708         public JCModifiers getModifiers() { return mods; }
 709         public Name getName() { return name; }
 710         public JCTree getReturnType() { return restype; }
 711         public List<JCTypeParameter> getTypeParameters() {
 712             return typarams;
 713         }
 714         public List<JCVariableDecl> getParameters() {
 715             return params;
 716         }
 717         public List<JCExpression> getThrows() {
 718             return thrown;
 719         }
 720         public JCBlock getBody() { return body; }
 721         public JCTree getDefaultValue() { // for annotation types
 722             return defaultValue;
 723         }
 724         @Override
 725         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 726             return v.visitMethod(this, d);
 727         }
 728 
 729         @Override
 730         public Tag getTag() {
 731             return METHODDEF;
 732         }
 733         
 734         @Override
 735         public boolean hasTag(Tag tag){
 736             return (tag.equals(METHODDEF));
 737         }
 738   }
 739 
 740     /**
 741      * A variable definition.
 742      * @param modifiers variable modifiers
 743      * @param name variable name
 744      * @param vartype type of the variable
 745      * @param init variables initial value
 746      * @param sym symbol
 747      */
 748     public static class JCVariableDecl extends JCStatement implements VariableTree {
 749         public JCModifiers mods;
 750         public Name name;
 751         public JCExpression vartype;
 752         public JCExpression init;
 753         public VarSymbol sym;
 754         protected JCVariableDecl(JCModifiers mods,
 755                          Name name,
 756                          JCExpression vartype,
 757                          JCExpression init,
 758                          VarSymbol sym) {
 759             this.mods = mods;
 760             this.name = name;
 761             this.vartype = vartype;
 762             this.init = init;
 763             this.sym = sym;
 764         }
 765         @Override
 766         public void accept(Visitor v) { v.visitVarDef(this); }
 767 
 768         public Kind getKind() { return Kind.VARIABLE; }
 769         public JCModifiers getModifiers() { return mods; }
 770         public Name getName() { return name; }
 771         public JCTree getType() { return vartype; }
 772         public JCExpression getInitializer() {
 773             return init;
 774         }
 775         @Override
 776         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 777             return v.visitVariable(this, d);
 778         }
 779 
 780         @Override
 781         public Tag getTag() {
 782             return VARDEF;
 783         }
 784         
 785         @Override
 786         public boolean hasTag(Tag tag){
 787             return (tag.equals(VARDEF));
 788         }
 789     }
 790 
 791       /**
 792      * A no-op statement ";".
 793      */
 794     public static class JCSkip extends JCStatement implements EmptyStatementTree {
 795         protected JCSkip() {
 796         }
 797         @Override
 798         public void accept(Visitor v) { v.visitSkip(this); }
 799 
 800         public Kind getKind() { return Kind.EMPTY_STATEMENT; }
 801         @Override
 802         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 803             return v.visitEmptyStatement(this, d);
 804         }
 805 
 806         @Override
 807         public Tag getTag() {
 808             return SKIP;
 809         }
 810         
 811         @Override
 812         public boolean hasTag(Tag tag){
 813             return (tag.equals(SKIP));
 814         }
 815     }
 816 
 817     /**
 818      * A statement block.
 819      * @param stats statements
 820      * @param flags flags
 821      */
 822     public static class JCBlock extends JCStatement implements BlockTree {
 823         public long flags;
 824         public List<JCStatement> stats;
 825         /** Position of closing brace, optional. */
 826         public int endpos = Position.NOPOS;
 827         protected JCBlock(long flags, List<JCStatement> stats) {
 828             this.stats = stats;
 829             this.flags = flags;
 830         }
 831         @Override
 832         public void accept(Visitor v) { v.visitBlock(this); }
 833 
 834         public Kind getKind() { return Kind.BLOCK; }
 835         public List<JCStatement> getStatements() {
 836             return stats;
 837         }
 838         public boolean isStatic() { return (flags & Flags.STATIC) != 0; }
 839         @Override
 840         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 841             return v.visitBlock(this, d);
 842         }
 843 
 844         @Override
 845         public Tag getTag() {
 846             return BLOCK;
 847         }
 848         
 849         @Override
 850         public boolean hasTag(Tag tag){
 851             return (tag.equals(BLOCK));
 852         }
 853     }
 854 
 855     /**
 856      * A do loop
 857      */
 858     public static class JCDoWhileLoop extends JCStatement implements DoWhileLoopTree {
 859         public JCStatement body;
 860         public JCExpression cond;
 861         protected JCDoWhileLoop(JCStatement body, JCExpression cond) {
 862             this.body = body;
 863             this.cond = cond;
 864         }
 865         @Override
 866         public void accept(Visitor v) { v.visitDoLoop(this); }
 867 
 868         public Kind getKind() { return Kind.DO_WHILE_LOOP; }
 869         public JCExpression getCondition() { return cond; }
 870         public JCStatement getStatement() { return body; }
 871         @Override
 872         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 873             return v.visitDoWhileLoop(this, d);
 874         }
 875 
 876         @Override
 877         public Tag getTag() {
 878             return DOLOOP;
 879         }
 880         
 881         @Override
 882         public boolean hasTag(Tag tag){
 883             return (tag.equals(DOLOOP));
 884         }
 885     }
 886 
 887     /**
 888      * A while loop
 889      */
 890     public static class JCWhileLoop extends JCStatement implements WhileLoopTree {
 891         public JCExpression cond;
 892         public JCStatement body;
 893         protected JCWhileLoop(JCExpression cond, JCStatement body) {
 894             this.cond = cond;
 895             this.body = body;
 896         }
 897         @Override
 898         public void accept(Visitor v) { v.visitWhileLoop(this); }
 899 
 900         public Kind getKind() { return Kind.WHILE_LOOP; }
 901         public JCExpression getCondition() { return cond; }
 902         public JCStatement getStatement() { return body; }
 903         @Override
 904         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 905             return v.visitWhileLoop(this, d);
 906         }
 907 
 908         @Override
 909         public Tag getTag() {
 910             return WHILELOOP;
 911         }
 912         
 913         @Override
 914         public boolean hasTag(Tag tag){
 915             return (tag.equals(WHILELOOP));
 916         }
 917     }
 918 
 919     /**
 920      * A for loop.
 921      */
 922     public static class JCForLoop extends JCStatement implements ForLoopTree {
 923         public List<JCStatement> init;
 924         public JCExpression cond;
 925         public List<JCExpressionStatement> step;
 926         public JCStatement body;
 927         protected JCForLoop(List<JCStatement> init,
 928                           JCExpression cond,
 929                           List<JCExpressionStatement> update,
 930                           JCStatement body)
 931         {
 932             this.init = init;
 933             this.cond = cond;
 934             this.step = update;
 935             this.body = body;
 936         }
 937         @Override
 938         public void accept(Visitor v) { v.visitForLoop(this); }
 939 
 940         public Kind getKind() { return Kind.FOR_LOOP; }
 941         public JCExpression getCondition() { return cond; }
 942         public JCStatement getStatement() { return body; }
 943         public List<JCStatement> getInitializer() {
 944             return init;
 945         }
 946         public List<JCExpressionStatement> getUpdate() {
 947             return step;
 948         }
 949         @Override
 950         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 951             return v.visitForLoop(this, d);
 952         }
 953 
 954         @Override
 955         public Tag getTag() {
 956             return FORLOOP;
 957         }
 958         
 959         @Override
 960         public boolean hasTag(Tag tag){
 961             return (tag.equals(FORLOOP));
 962         }
 963     }
 964 
 965     /**
 966      * The enhanced for loop.
 967      */
 968     public static class JCEnhancedForLoop extends JCStatement implements EnhancedForLoopTree {
 969         public JCVariableDecl var;
 970         public JCExpression expr;
 971         public JCStatement body;
 972         protected JCEnhancedForLoop(JCVariableDecl var, JCExpression expr, JCStatement body) {
 973             this.var = var;
 974             this.expr = expr;
 975             this.body = body;
 976         }
 977         @Override
 978         public void accept(Visitor v) { v.visitForeachLoop(this); }
 979 
 980         public Kind getKind() { return Kind.ENHANCED_FOR_LOOP; }
 981         public JCVariableDecl getVariable() { return var; }
 982         public JCExpression getExpression() { return expr; }
 983         public JCStatement getStatement() { return body; }
 984         @Override
 985         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
 986             return v.visitEnhancedForLoop(this, d);
 987         }
 988         @Override
 989         public Tag getTag() {
 990             return FOREACHLOOP;
 991         }
 992         @Override
 993         public boolean hasTag(Tag tag){
 994             return (tag.equals(FOREACHLOOP));
 995         }
 996     }
 997 
 998     /**
 999      * A labelled expression or statement.
1000      */
1001     public static class JCLabeledStatement extends JCStatement implements LabeledStatementTree {
1002         public Name label;
1003         public JCStatement body;
1004         protected JCLabeledStatement(Name label, JCStatement body) {
1005             this.label = label;
1006             this.body = body;
1007         }
1008         @Override
1009         public void accept(Visitor v) { v.visitLabelled(this); }
1010         public Kind getKind() { return Kind.LABELED_STATEMENT; }
1011         public Name getLabel() { return label; }
1012         public JCStatement getStatement() { return body; }
1013         @Override
1014         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1015             return v.visitLabeledStatement(this, d);
1016         }
1017         @Override
1018         public Tag getTag() {
1019             return LABELLED;
1020         }
1021         @Override
1022         public boolean hasTag(Tag tag){
1023             return (tag.equals(LABELLED));
1024         }
1025     }
1026 
1027     /**
1028      * A "switch ( ) { }" construction.
1029      */
1030     public static class JCSwitch extends JCStatement implements SwitchTree {
1031         public JCExpression selector;
1032         public List<JCCase> cases;
1033         protected JCSwitch(JCExpression selector, List<JCCase> cases) {
1034             this.selector = selector;
1035             this.cases = cases;
1036         }
1037         @Override
1038         public void accept(Visitor v) { v.visitSwitch(this); }
1039 
1040         public Kind getKind() { return Kind.SWITCH; }
1041         public JCExpression getExpression() { return selector; }
1042         public List<JCCase> getCases() { return cases; }
1043         @Override
1044         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1045             return v.visitSwitch(this, d);
1046         }
1047         @Override
1048         public Tag getTag() {
1049             return SWITCH;
1050         }
1051         @Override
1052         public boolean hasTag(Tag tag){
1053             return (tag.equals(SWITCH));
1054         }
1055     }
1056 
1057     /**
1058      * A "case  :" of a switch.
1059      */
1060     public static class JCCase extends JCStatement implements CaseTree {
1061         public JCExpression pat;
1062         public List<JCStatement> stats;
1063         protected JCCase(JCExpression pat, List<JCStatement> stats) {
1064             this.pat = pat;
1065             this.stats = stats;
1066         }
1067         @Override
1068         public void accept(Visitor v) { v.visitCase(this); }
1069 
1070         public Kind getKind() { return Kind.CASE; }
1071         public JCExpression getExpression() { return pat; }
1072         public List<JCStatement> getStatements() { return stats; }
1073         @Override
1074         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1075             return v.visitCase(this, d);
1076         }
1077         @Override
1078         public Tag getTag() {
1079             return CASE;
1080         }
1081         @Override
1082         public boolean hasTag(Tag tag){
1083             return (tag.equals(CASE));
1084         }
1085     }
1086 
1087     /**
1088      * A synchronized block.
1089      */
1090     public static class JCSynchronized extends JCStatement implements SynchronizedTree {
1091         public JCExpression lock;
1092         public JCBlock body;
1093         protected JCSynchronized(JCExpression lock, JCBlock body) {
1094             this.lock = lock;
1095             this.body = body;
1096         }
1097         @Override
1098         public void accept(Visitor v) { v.visitSynchronized(this); }
1099 
1100         public Kind getKind() { return Kind.SYNCHRONIZED; }
1101         public JCExpression getExpression() { return lock; }
1102         public JCBlock getBlock() { return body; }
1103         @Override
1104         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1105             return v.visitSynchronized(this, d);
1106         }
1107         @Override
1108         public Tag getTag() {
1109             return SYNCHRONIZED;
1110         }
1111         @Override
1112         public boolean hasTag(Tag tag){
1113             return (tag.equals(SYNCHRONIZED));
1114         }
1115     }
1116 
1117     /**
1118      * A "try { } catch ( ) { } finally { }" block.
1119      */
1120     public static class JCTry extends JCStatement implements TryTree {
1121         public JCBlock body;
1122         public List<JCCatch> catchers;
1123         public JCBlock finalizer;
1124         public List<JCTree> resources;
1125         protected JCTry(List<JCTree> resources,
1126                         JCBlock body,
1127                         List<JCCatch> catchers,
1128                         JCBlock finalizer) {
1129             this.body = body;
1130             this.catchers = catchers;
1131             this.finalizer = finalizer;
1132             this.resources = resources;
1133         }
1134         @Override
1135         public void accept(Visitor v) { v.visitTry(this); }
1136 
1137         public Kind getKind() { return Kind.TRY; }
1138         public JCBlock getBlock() { return body; }
1139         public List<JCCatch> getCatches() {
1140             return catchers;
1141         }
1142         public JCBlock getFinallyBlock() { return finalizer; }
1143         @Override
1144         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1145             return v.visitTry(this, d);
1146         }
1147         @Override
1148         public List<? extends JCTree> getResources() {
1149             return resources;
1150         }
1151         @Override
1152         public Tag getTag() {
1153             return TRY;
1154         }
1155         @Override
1156         public boolean hasTag(Tag tag){
1157             return (tag.equals(TRY));
1158         }
1159     }
1160 
1161     /**
1162      * A catch block.
1163      */
1164     public static class JCCatch extends JCTree implements CatchTree {
1165         public JCVariableDecl param;
1166         public JCBlock body;
1167         protected JCCatch(JCVariableDecl param, JCBlock body) {
1168             this.param = param;
1169             this.body = body;
1170         }
1171         @Override
1172         public void accept(Visitor v) { v.visitCatch(this); }
1173 
1174         public Kind getKind() { return Kind.CATCH; }
1175         public JCVariableDecl getParameter() { return param; }
1176         public JCBlock getBlock() { return body; }
1177         @Override
1178         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1179             return v.visitCatch(this, d);
1180         }
1181         @Override
1182         public Tag getTag() {
1183             return CATCH;
1184         }
1185         @Override
1186         public boolean hasTag(Tag tag){
1187             return (tag.equals(CATCH));
1188         }
1189     }
1190 
1191     /**
1192      * A ( ) ? ( ) : ( ) conditional expression
1193      */
1194     public static class JCConditional extends JCExpression implements ConditionalExpressionTree {
1195         public JCExpression cond;
1196         public JCExpression truepart;
1197         public JCExpression falsepart;
1198         protected JCConditional(JCExpression cond,
1199                               JCExpression truepart,
1200                               JCExpression falsepart)
1201         {
1202             this.cond = cond;
1203             this.truepart = truepart;
1204             this.falsepart = falsepart;
1205         }
1206         @Override
1207         public void accept(Visitor v) { v.visitConditional(this); }
1208 
1209         public Kind getKind() { return Kind.CONDITIONAL_EXPRESSION; }
1210         public JCExpression getCondition() { return cond; }
1211         public JCExpression getTrueExpression() { return truepart; }
1212         public JCExpression getFalseExpression() { return falsepart; }
1213         @Override
1214         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1215             return v.visitConditionalExpression(this, d);
1216         }
1217         @Override
1218         public Tag getTag() {
1219             return CONDEXPR;
1220         }
1221         @Override
1222         public boolean hasTag(Tag tag){
1223             return (tag.equals(CONDEXPR));
1224         }
1225     }
1226 
1227     /**
1228      * An "if ( ) { } else { }" block
1229      */
1230     public static class JCIf extends JCStatement implements IfTree {
1231         public JCExpression cond;
1232         public JCStatement thenpart;
1233         public JCStatement elsepart;
1234         protected JCIf(JCExpression cond,
1235                      JCStatement thenpart,
1236                      JCStatement elsepart)
1237         {
1238             this.cond = cond;
1239             this.thenpart = thenpart;
1240             this.elsepart = elsepart;
1241         }
1242         @Override
1243         public void accept(Visitor v) { v.visitIf(this); }
1244 
1245         public Kind getKind() { return Kind.IF; }
1246         public JCExpression getCondition() { return cond; }
1247         public JCStatement getThenStatement() { return thenpart; }
1248         public JCStatement getElseStatement() { return elsepart; }
1249         @Override
1250         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1251             return v.visitIf(this, d);
1252         }
1253         @Override
1254         public Tag getTag() {
1255             return IF;
1256         }
1257         @Override
1258         public boolean hasTag(Tag tag){
1259             return (tag.equals(IF));
1260         }
1261     }
1262 
1263     /**
1264      * an expression statement
1265      * @param expr expression structure
1266      */
1267     public static class JCExpressionStatement extends JCStatement implements ExpressionStatementTree {
1268         public JCExpression expr;
1269         protected JCExpressionStatement(JCExpression expr)
1270         {
1271             this.expr = expr;
1272         }
1273         @Override
1274         public void accept(Visitor v) { v.visitExec(this); }
1275 
1276         public Kind getKind() { return Kind.EXPRESSION_STATEMENT; }
1277         public JCExpression getExpression() { return expr; }
1278         @Override
1279         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1280             return v.visitExpressionStatement(this, d);
1281         }
1282         @Override
1283         public Tag getTag() {
1284             return EXEC;
1285         }
1286         @Override
1287         public boolean hasTag(Tag tag){
1288             return (tag.equals(EXEC));
1289         }
1290 
1291         /** Convert a expression-statement tree to a pretty-printed string. */
1292         @Override
1293         public String toString() {
1294             StringWriter s = new StringWriter();
1295             try {
1296                 new Pretty(s, false).printStat(this);
1297             }
1298             catch (IOException e) {
1299                 // should never happen, because StringWriter is defined
1300                 // never to throw any IOExceptions
1301                 throw new AssertionError(e);
1302             }
1303             return s.toString();
1304         }
1305     }
1306 
1307     /**
1308      * A break from a loop or switch.
1309      */
1310     public static class JCBreak extends JCStatement implements BreakTree {
1311         public Name label;
1312         public JCTree target;
1313         protected JCBreak(Name label, JCTree target) {
1314             this.label = label;
1315             this.target = target;
1316         }
1317         @Override
1318         public void accept(Visitor v) { v.visitBreak(this); }
1319 
1320         public Kind getKind() { return Kind.BREAK; }
1321         public Name getLabel() { return label; }
1322         @Override
1323         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1324             return v.visitBreak(this, d);
1325         }
1326         @Override
1327         public Tag getTag() {
1328             return BREAK;
1329         }
1330         @Override
1331         public boolean hasTag(Tag tag){
1332             return (tag.equals(BREAK));
1333         }
1334     }
1335 
1336     /**
1337      * A continue of a loop.
1338      */
1339     public static class JCContinue extends JCStatement implements ContinueTree {
1340         public Name label;
1341         public JCTree target;
1342         protected JCContinue(Name label, JCTree target) {
1343             this.label = label;
1344             this.target = target;
1345         }
1346         @Override
1347         public void accept(Visitor v) { v.visitContinue(this); }
1348 
1349         public Kind getKind() { return Kind.CONTINUE; }
1350         public Name getLabel() { return label; }
1351         @Override
1352         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1353             return v.visitContinue(this, d);
1354         }
1355         @Override
1356         public Tag getTag() {
1357             return CONTINUE;
1358         }
1359         @Override
1360         public boolean hasTag(Tag tag){
1361             return (tag.equals(CONTINUE));
1362         }
1363     }
1364 
1365     /**
1366      * A return statement.
1367      */
1368     public static class JCReturn extends JCStatement implements ReturnTree {
1369         public JCExpression expr;
1370         protected JCReturn(JCExpression expr) {
1371             this.expr = expr;
1372         }
1373         @Override
1374         public void accept(Visitor v) { v.visitReturn(this); }
1375 
1376         public Kind getKind() { return Kind.RETURN; }
1377         public JCExpression getExpression() { return expr; }
1378         @Override
1379         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1380             return v.visitReturn(this, d);
1381         }
1382         @Override
1383         public Tag getTag() {
1384             return RETURN;
1385         }
1386         @Override
1387         public boolean hasTag(Tag tag){
1388             return (tag.equals(RETURN));
1389         }
1390     }
1391 
1392     /**
1393      * A throw statement.
1394      */
1395     public static class JCThrow extends JCStatement implements ThrowTree {
1396         public JCExpression expr;
1397         protected JCThrow(JCTree expr) {
1398             this.expr = (JCExpression)expr;
1399         }
1400         @Override
1401         public void accept(Visitor v) { v.visitThrow(this); }
1402 
1403         public Kind getKind() { return Kind.THROW; }
1404         public JCExpression getExpression() { return expr; }
1405         @Override
1406         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1407             return v.visitThrow(this, d);
1408         }
1409         @Override
1410         public Tag getTag() {
1411             return THROW;
1412         }
1413         @Override
1414         public boolean hasTag(Tag tag){
1415             return (tag.equals(THROW));
1416         }
1417     }
1418 
1419     /**
1420      * An assert statement.
1421      */
1422     public static class JCAssert extends JCStatement implements AssertTree {
1423         public JCExpression cond;
1424         public JCExpression detail;
1425         protected JCAssert(JCExpression cond, JCExpression detail) {
1426             this.cond = cond;
1427             this.detail = detail;
1428         }
1429         @Override
1430         public void accept(Visitor v) { v.visitAssert(this); }
1431 
1432         public Kind getKind() { return Kind.ASSERT; }
1433         public JCExpression getCondition() { return cond; }
1434         public JCExpression getDetail() { return detail; }
1435         @Override
1436         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1437             return v.visitAssert(this, d);
1438         }
1439         @Override
1440         public Tag getTag() {
1441             return ASSERT;
1442         }
1443         @Override
1444         public boolean hasTag(Tag tag){
1445             return (tag.equals(ASSERT));
1446         }
1447     }
1448 
1449     /**
1450      * A method invocation
1451      */
1452     public static class JCMethodInvocation extends JCExpression implements MethodInvocationTree {
1453         public List<JCExpression> typeargs;
1454         public JCExpression meth;
1455         public List<JCExpression> args;
1456         public Type varargsElement;
1457         protected JCMethodInvocation(List<JCExpression> typeargs,
1458                         JCExpression meth,
1459                         List<JCExpression> args)
1460         {
1461             this.typeargs = (typeargs == null) ? List.<JCExpression>nil()
1462                                                : typeargs;
1463             this.meth = meth;
1464             this.args = args;
1465         }
1466         @Override
1467         public void accept(Visitor v) { v.visitApply(this); }
1468 
1469         public Kind getKind() { return Kind.METHOD_INVOCATION; }
1470         public List<JCExpression> getTypeArguments() {
1471             return typeargs;
1472         }
1473         public JCExpression getMethodSelect() { return meth; }
1474         public List<JCExpression> getArguments() {
1475             return args;
1476         }
1477         @Override
1478         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1479             return v.visitMethodInvocation(this, d);
1480         }
1481         @Override
1482         public JCMethodInvocation setType(Type type) {
1483             super.setType(type);
1484             return this;
1485         }
1486         @Override
1487         public Tag getTag() {
1488             return(APPLY);
1489         }
1490         @Override
1491         public boolean hasTag(Tag tag){
1492             return (tag.equals(APPLY));
1493         }
1494     }
1495 
1496     /**
1497      * A new(...) operation.
1498      */
1499     public static class JCNewClass extends JCExpression implements NewClassTree {
1500         public JCExpression encl;
1501         public List<JCExpression> typeargs;
1502         public JCExpression clazz;
1503         public List<JCExpression> args;
1504         public JCClassDecl def;
1505         public Symbol constructor;
1506         public Type varargsElement;
1507         public Type constructorType;
1508         protected JCNewClass(JCExpression encl,
1509                            List<JCExpression> typeargs,
1510                            JCExpression clazz,
1511                            List<JCExpression> args,
1512                            JCClassDecl def)
1513         {
1514             this.encl = encl;
1515             this.typeargs = (typeargs == null) ? List.<JCExpression>nil()
1516                                                : typeargs;
1517             this.clazz = clazz;
1518             this.args = args;
1519             this.def = def;
1520         }
1521         @Override
1522         public void accept(Visitor v) { v.visitNewClass(this); }
1523 
1524         public Kind getKind() { return Kind.NEW_CLASS; }
1525         public JCExpression getEnclosingExpression() { // expr.new C< ... > ( ... )
1526             return encl;
1527         }
1528         public List<JCExpression> getTypeArguments() {
1529             return typeargs;
1530         }
1531         public JCExpression getIdentifier() { return clazz; }
1532         public List<JCExpression> getArguments() {
1533             return args;
1534         }
1535         public JCClassDecl getClassBody() { return def; }
1536         @Override
1537         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1538             return v.visitNewClass(this, d);
1539         }
1540         @Override
1541         public Tag getTag() {
1542             return NEWCLASS;
1543         }
1544         @Override
1545         public boolean hasTag(Tag tag){
1546             return (tag.equals(NEWCLASS));
1547         }
1548     }
1549 
1550     /**
1551      * A new[...] operation.
1552      */
1553     public static class JCNewArray extends JCExpression implements NewArrayTree {
1554         public JCExpression elemtype;
1555         public List<JCExpression> dims;
1556         public List<JCExpression> elems;
1557         protected JCNewArray(JCExpression elemtype,
1558                            List<JCExpression> dims,
1559                            List<JCExpression> elems)
1560         {
1561             this.elemtype = elemtype;
1562             this.dims = dims;
1563             this.elems = elems;
1564         }
1565         @Override
1566         public void accept(Visitor v) { v.visitNewArray(this); }
1567 
1568         public Kind getKind() { return Kind.NEW_ARRAY; }
1569         public JCExpression getType() { return elemtype; }
1570         public List<JCExpression> getDimensions() {
1571             return dims;
1572         }
1573         public List<JCExpression> getInitializers() {
1574             return elems;
1575         }
1576         @Override
1577         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1578             return v.visitNewArray(this, d);
1579         }
1580         @Override
1581         public Tag getTag() {
1582             return NEWARRAY;
1583         }
1584         @Override
1585         public boolean hasTag(Tag tag){
1586             return (tag.equals(NEWARRAY));
1587         }
1588     }
1589 
1590     /**
1591      * A parenthesized subexpression ( ... )
1592      */
1593     public static class JCParens extends JCExpression implements ParenthesizedTree {
1594         public JCExpression expr;
1595         protected JCParens(JCExpression expr) {
1596             this.expr = expr;
1597         }
1598         @Override
1599         public void accept(Visitor v) { v.visitParens(this); }
1600 
1601         public Kind getKind() { return Kind.PARENTHESIZED; }
1602         public JCExpression getExpression() { return expr; }
1603         @Override
1604         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1605             return v.visitParenthesized(this, d);
1606         }
1607         @Override
1608         public Tag getTag() {
1609             return PARENS;
1610         }
1611         @Override
1612         public boolean hasTag(Tag tag){
1613             return (tag.equals(PARENS));
1614         }
1615     }
1616 
1617     /**
1618      * A assignment with "=".
1619      */
1620     public static class JCAssign extends JCExpression implements AssignmentTree {
1621         public JCExpression lhs;
1622         public JCExpression rhs;
1623         protected JCAssign(JCExpression lhs, JCExpression rhs) {
1624             this.lhs = lhs;
1625             this.rhs = rhs;
1626         }
1627         @Override
1628         public void accept(Visitor v) { v.visitAssign(this); }
1629 
1630         public Kind getKind() { return Kind.ASSIGNMENT; }
1631         public JCExpression getVariable() { return lhs; }
1632         public JCExpression getExpression() { return rhs; }
1633         @Override
1634         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1635             return v.visitAssignment(this, d);
1636         }
1637         @Override
1638         public Tag getTag() {
1639             return ASSIGN;
1640         }
1641         @Override
1642         public boolean hasTag(Tag tag){
1643             return (tag.equals(ASSIGN));
1644         }
1645     }
1646 
1647     /**
1648      * An assignment with "+=", "|=" ...
1649      */
1650     public static class JCAssignOp extends JCExpression implements CompoundAssignmentTree {
1651         private Tag opcode;
1652         public JCExpression lhs;
1653         public JCExpression rhs;
1654         public Symbol operator;
1655         protected JCAssignOp(Tag opcode, JCTree lhs, JCTree rhs, Symbol operator) {
1656             this.opcode = opcode;
1657             this.lhs = (JCExpression)lhs;
1658             this.rhs = (JCExpression)rhs;
1659             this.operator = operator;
1660         }
1661         @Override
1662         public void accept(Visitor v) { v.visitAssignop(this); }
1663 
1664         public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
1665         public JCExpression getVariable() { return lhs; }
1666         public JCExpression getExpression() { return rhs; }
1667         public Symbol getOperator() {
1668             return operator;
1669         }
1670         @Override
1671         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1672             return v.visitCompoundAssignment(this, d);
1673         }
1674         @Override
1675         public Tag getTag() {
1676             return opcode;
1677         }
1678         @Override
1679         public boolean hasTag(Tag tag){
1680             return (tag.equals(opcode));
1681         }
1682     }
1683 
1684     /**
1685      * A unary operation.
1686      */
1687     public static class JCUnary extends JCExpression implements UnaryTree {
1688         private Tag opcode;
1689         public JCExpression arg;
1690         public Symbol operator;
1691         protected JCUnary(Tag opcode, JCExpression arg) {
1692             this.opcode = opcode;
1693             this.arg = arg;
1694         }
1695         @Override
1696         public void accept(Visitor v) { v.visitUnary(this); }
1697 
1698         public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
1699         public JCExpression getExpression() { return arg; }
1700         public Symbol getOperator() {
1701             return operator;
1702         }
1703         @Override
1704         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1705             return v.visitUnary(this, d);
1706         }
1707         @Override
1708         public Tag getTag() {
1709             return opcode;
1710         }
1711 
1712         public void setTag(Tag tag) {
1713             opcode = tag;
1714         }
1715         @Override
1716         public boolean hasTag(Tag tag){
1717             return (tag.equals(opcode));
1718         }
1719     }
1720 
1721     /**
1722      * A binary operation.
1723      */
1724     public static class JCBinary extends JCExpression implements BinaryTree {
1725         private Tag opcode;
1726         public JCExpression lhs;
1727         public JCExpression rhs;
1728         public Symbol operator;
1729         protected JCBinary(Tag opcode,
1730                          JCExpression lhs,
1731                          JCExpression rhs,
1732                          Symbol operator) {
1733             this.opcode = opcode;
1734             this.lhs = lhs;
1735             this.rhs = rhs;
1736             this.operator = operator;
1737         }
1738         @Override
1739         public void accept(Visitor v) { v.visitBinary(this); }
1740 
1741         public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
1742         public JCExpression getLeftOperand() { return lhs; }
1743         public JCExpression getRightOperand() { return rhs; }
1744         public Symbol getOperator() {
1745             return operator;
1746         }
1747         @Override
1748         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1749             return v.visitBinary(this, d);
1750         }
1751         @Override
1752         public Tag getTag() {
1753             return opcode;
1754         }
1755         @Override
1756         public boolean hasTag(Tag tag){
1757             return (tag.equals(opcode));
1758         }
1759     }
1760 
1761     /**
1762      * A type cast.
1763      */
1764     public static class JCTypeCast extends JCExpression implements TypeCastTree {
1765         public JCTree clazz;
1766         public JCExpression expr;
1767         protected JCTypeCast(JCTree clazz, JCExpression expr) {
1768             this.clazz = clazz;
1769             this.expr = expr;
1770         }
1771         @Override
1772         public void accept(Visitor v) { v.visitTypeCast(this); }
1773 
1774         public Kind getKind() { return Kind.TYPE_CAST; }
1775         public JCTree getType() { return clazz; }
1776         public JCExpression getExpression() { return expr; }
1777         @Override
1778         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1779             return v.visitTypeCast(this, d);
1780         }
1781         @Override
1782         public Tag getTag() {
1783             return TYPECAST;
1784         }
1785         @Override
1786         public boolean hasTag(Tag tag){
1787             return (tag.equals(TYPECAST));
1788         }
1789     }
1790 
1791     /**
1792      * A type test.
1793      */
1794     public static class JCInstanceOf extends JCExpression implements InstanceOfTree {
1795         public JCExpression expr;
1796         public JCTree clazz;
1797         protected JCInstanceOf(JCExpression expr, JCTree clazz) {
1798             this.expr = expr;
1799             this.clazz = clazz;
1800         }
1801         @Override
1802         public void accept(Visitor v) { v.visitTypeTest(this); }
1803 
1804         public Kind getKind() { return Kind.INSTANCE_OF; }
1805         public JCTree getType() { return clazz; }
1806         public JCExpression getExpression() { return expr; }
1807         @Override
1808         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1809             return v.visitInstanceOf(this, d);
1810         }
1811         @Override
1812         public Tag getTag() {
1813             return TYPETEST;
1814         }
1815         @Override
1816         public boolean hasTag(Tag tag){
1817             return (tag.equals(TYPETEST));
1818         }
1819     }
1820 
1821     /**
1822      * An array selection
1823      */
1824     public static class JCArrayAccess extends JCExpression implements ArrayAccessTree {
1825         public JCExpression indexed;
1826         public JCExpression index;
1827         protected JCArrayAccess(JCExpression indexed, JCExpression index) {
1828             this.indexed = indexed;
1829             this.index = index;
1830         }
1831         @Override
1832         public void accept(Visitor v) { v.visitIndexed(this); }
1833 
1834         public Kind getKind() { return Kind.ARRAY_ACCESS; }
1835         public JCExpression getExpression() { return indexed; }
1836         public JCExpression getIndex() { return index; }
1837         @Override
1838         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1839             return v.visitArrayAccess(this, d);
1840         }
1841         @Override
1842         public Tag getTag() {
1843             return INDEXED;
1844         }
1845         @Override
1846         public boolean hasTag(Tag tag){
1847             return (tag.equals(INDEXED));
1848         }
1849     }
1850 
1851     /**
1852      * Selects through packages and classes
1853      * @param selected selected Tree hierarchie
1854      * @param selector name of field to select thru
1855      * @param sym symbol of the selected class
1856      */
1857     public static class JCFieldAccess extends JCExpression implements MemberSelectTree {
1858         public JCExpression selected;
1859         public Name name;
1860         public Symbol sym;
1861         protected JCFieldAccess(JCExpression selected, Name name, Symbol sym) {
1862             this.selected = selected;
1863             this.name = name;
1864             this.sym = sym;
1865         }
1866         @Override
1867         public void accept(Visitor v) { v.visitSelect(this); }
1868 
1869         public Kind getKind() { return Kind.MEMBER_SELECT; }
1870         public JCExpression getExpression() { return selected; }
1871         @Override
1872         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1873             return v.visitMemberSelect(this, d);
1874         }
1875         public Name getIdentifier() { return name; }
1876         @Override
1877         public Tag getTag() {
1878             return SELECT;
1879         }
1880         @Override
1881         public boolean hasTag(Tag tag){
1882             return (tag.equals(SELECT));
1883         }
1884     }
1885 
1886     /**
1887      * An identifier
1888      * @param idname the name
1889      * @param sym the symbol
1890      */
1891     public static class JCIdent extends JCExpression implements IdentifierTree {
1892         public Name name;
1893         public Symbol sym;
1894         protected JCIdent(Name name, Symbol sym) {
1895             this.name = name;
1896             this.sym = sym;
1897         }
1898         @Override
1899         public void accept(Visitor v) { v.visitIdent(this); }
1900 
1901         public Kind getKind() { return Kind.IDENTIFIER; }
1902         public Name getName() { return name; }
1903         @Override
1904         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1905             return v.visitIdentifier(this, d);
1906         }
1907         @Override
1908         public Tag getTag() {
1909             return IDENT;
1910         }
1911         @Override
1912         public boolean hasTag(Tag tag){
1913             return (tag.equals(IDENT));
1914         }
1915     }
1916 
1917     /**
1918      * A constant value given literally.
1919      * @param value value representation
1920      */
1921     public static class JCLiteral extends JCExpression implements LiteralTree {
1922         public int typetag;
1923         public Object value;
1924         protected JCLiteral(int typetag, Object value) {
1925             this.typetag = typetag;
1926             this.value = value;
1927         }
1928         @Override
1929         public void accept(Visitor v) { v.visitLiteral(this); }
1930 
1931         public Kind getKind() {
1932             switch (typetag) {
1933             case TypeTags.INT:
1934                 return Kind.INT_LITERAL;
1935             case TypeTags.LONG:
1936                 return Kind.LONG_LITERAL;
1937             case TypeTags.FLOAT:
1938                 return Kind.FLOAT_LITERAL;
1939             case TypeTags.DOUBLE:
1940                 return Kind.DOUBLE_LITERAL;
1941             case TypeTags.BOOLEAN:
1942                 return Kind.BOOLEAN_LITERAL;
1943             case TypeTags.CHAR:
1944                 return Kind.CHAR_LITERAL;
1945             case TypeTags.CLASS:
1946                 return Kind.STRING_LITERAL;
1947             case TypeTags.BOT:
1948                 return Kind.NULL_LITERAL;
1949             default:
1950                 throw new AssertionError("unknown literal kind " + this);
1951             }
1952         }
1953         public Object getValue() {
1954             switch (typetag) {
1955                 case TypeTags.BOOLEAN:
1956                     int bi = (Integer) value;
1957                     return (bi != 0);
1958                 case TypeTags.CHAR:
1959                     int ci = (Integer) value;
1960                     char c = (char) ci;
1961                     if (c != ci)
1962                         throw new AssertionError("bad value for char literal");
1963                     return c;
1964                 default:
1965                     return value;
1966             }
1967         }
1968         @Override
1969         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
1970             return v.visitLiteral(this, d);
1971         }
1972         @Override
1973         public JCLiteral setType(Type type) {
1974             super.setType(type);
1975             return this;
1976         }
1977         @Override
1978         public Tag getTag() {
1979             return LITERAL;
1980         }
1981         @Override
1982         public boolean hasTag(Tag tag){
1983             return (tag.equals(LITERAL));
1984         }
1985     }
1986 
1987     /**
1988      * Identifies a basic type.
1989      * @param tag the basic type id
1990      * @see TypeTags
1991      */
1992     public static class JCPrimitiveTypeTree extends JCExpression implements PrimitiveTypeTree {
1993         public int typetag;
1994         protected JCPrimitiveTypeTree(int typetag) {
1995             this.typetag = typetag;
1996         }
1997         @Override
1998         public void accept(Visitor v) { v.visitTypeIdent(this); }
1999 
2000         public Kind getKind() { return Kind.PRIMITIVE_TYPE; }
2001         public TypeKind getPrimitiveTypeKind() {
2002             switch (typetag) {
2003             case TypeTags.BOOLEAN:
2004                 return TypeKind.BOOLEAN;
2005             case TypeTags.BYTE:
2006                 return TypeKind.BYTE;
2007             case TypeTags.SHORT:
2008                 return TypeKind.SHORT;
2009             case TypeTags.INT:
2010                 return TypeKind.INT;
2011             case TypeTags.LONG:
2012                 return TypeKind.LONG;
2013             case TypeTags.CHAR:
2014                 return TypeKind.CHAR;
2015             case TypeTags.FLOAT:
2016                 return TypeKind.FLOAT;
2017             case TypeTags.DOUBLE:
2018                 return TypeKind.DOUBLE;
2019             case TypeTags.VOID:
2020                 return TypeKind.VOID;
2021             default:
2022                 throw new AssertionError("unknown primitive type " + this);
2023             }
2024         }
2025         @Override
2026         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2027             return v.visitPrimitiveType(this, d);
2028         }
2029         @Override
2030         public Tag getTag() {
2031             return TYPEIDENT;
2032         }
2033         @Override
2034         public boolean hasTag(Tag tag){
2035             return (tag.equals(TYPEIDENT));
2036         }
2037     }
2038 
2039     /**
2040      * An array type, A[]
2041      */
2042     public static class JCArrayTypeTree extends JCExpression implements ArrayTypeTree {
2043         public JCExpression elemtype;
2044         protected JCArrayTypeTree(JCExpression elemtype) {
2045             this.elemtype = elemtype;
2046         }
2047         @Override
2048         public void accept(Visitor v) { v.visitTypeArray(this); }
2049 
2050         public Kind getKind() { return Kind.ARRAY_TYPE; }
2051         public JCTree getType() { return elemtype; }
2052         @Override
2053         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2054             return v.visitArrayType(this, d);
2055         }
2056         @Override
2057         public Tag getTag() {
2058             return TYPEARRAY;
2059         }
2060         @Override
2061         public boolean hasTag(Tag tag){
2062             return (tag.equals(TYPEARRAY));
2063         }
2064     }
2065 
2066     /**
2067      * A parameterized type, T<...>
2068      */
2069     public static class JCTypeApply extends JCExpression implements ParameterizedTypeTree {
2070         public JCExpression clazz;
2071         public List<JCExpression> arguments;
2072         protected JCTypeApply(JCExpression clazz, List<JCExpression> arguments) {
2073             this.clazz = clazz;
2074             this.arguments = arguments;
2075         }
2076         @Override
2077         public void accept(Visitor v) { v.visitTypeApply(this); }
2078 
2079         public Kind getKind() { return Kind.PARAMETERIZED_TYPE; }
2080         public JCTree getType() { return clazz; }
2081         public List<JCExpression> getTypeArguments() {
2082             return arguments;
2083         }
2084         @Override
2085         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2086             return v.visitParameterizedType(this, d);
2087         }
2088         @Override
2089         public Tag getTag() {
2090             return TYPEAPPLY;
2091         }
2092         @Override
2093         public boolean hasTag(Tag tag){
2094             return (tag.equals(TYPEAPPLY));
2095         }
2096     }
2097 
2098     /**
2099      * A union type, T1 | T2 | ... Tn (used in multicatch statements)
2100      */
2101     public static class JCTypeUnion extends JCExpression implements UnionTypeTree {
2102 
2103         public List<JCExpression> alternatives;
2104 
2105         protected JCTypeUnion(List<JCExpression> components) {
2106             this.alternatives = components;
2107         }
2108         @Override
2109         public void accept(Visitor v) { v.visitTypeUnion(this); }
2110 
2111         public Kind getKind() { return Kind.UNION_TYPE; }
2112 
2113         public List<JCExpression> getTypeAlternatives() {
2114             return alternatives;
2115         }
2116         @Override
2117         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2118             return v.visitUnionType(this, d);
2119         }
2120         @Override
2121         public Tag getTag() {
2122             return TYPEUNION;
2123         }
2124         @Override
2125         public boolean hasTag(Tag tag){
2126             return (tag.equals(TYPEUNION));
2127         }
2128     }
2129 
2130     /**
2131      * A formal class parameter.
2132      * @param name name
2133      * @param bounds bounds
2134      */
2135     public static class JCTypeParameter extends JCTree implements TypeParameterTree {
2136         public Name name;
2137         public List<JCExpression> bounds;
2138         protected JCTypeParameter(Name name, List<JCExpression> bounds) {
2139             this.name = name;
2140             this.bounds = bounds;
2141         }
2142         @Override
2143         public void accept(Visitor v) { v.visitTypeParameter(this); }
2144 
2145         public Kind getKind() { return Kind.TYPE_PARAMETER; }
2146         public Name getName() { return name; }
2147         public List<JCExpression> getBounds() {
2148             return bounds;
2149         }
2150         @Override
2151         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2152             return v.visitTypeParameter(this, d);
2153         }
2154         @Override
2155         public Tag getTag() {
2156             return TYPEPARAMETER;
2157         }
2158         @Override
2159         public boolean hasTag(Tag tag){
2160             return (tag.equals(TYPEPARAMETER));
2161         }
2162     }
2163 
2164     public static class JCWildcard extends JCExpression implements WildcardTree {
2165         public TypeBoundKind kind;
2166         public JCTree inner;
2167         protected JCWildcard(TypeBoundKind kind, JCTree inner) {
2168             kind.getClass(); // null-check
2169             this.kind = kind;
2170             this.inner = inner;
2171         }
2172         @Override
2173         public void accept(Visitor v) { v.visitWildcard(this); }
2174 
2175         public Kind getKind() {
2176             switch (kind.kind) {
2177             case UNBOUND:
2178                 return Kind.UNBOUNDED_WILDCARD;
2179             case EXTENDS:
2180                 return Kind.EXTENDS_WILDCARD;
2181             case SUPER:
2182                 return Kind.SUPER_WILDCARD;
2183             default:
2184                 throw new AssertionError("Unknown wildcard bound " + kind);
2185             }
2186         }
2187         public JCTree getBound() { return inner; }
2188         @Override
2189         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2190             return v.visitWildcard(this, d);
2191         }
2192         @Override
2193         public Tag getTag() {
2194             return WILDCARD;
2195         }
2196         @Override
2197         public boolean hasTag(Tag tag){
2198             return (tag.equals(WILDCARD));
2199         }
2200     }
2201 
2202     public static class TypeBoundKind extends JCTree {
2203         public BoundKind kind;
2204         protected TypeBoundKind(BoundKind kind) {
2205             this.kind = kind;
2206         }
2207         @Override
2208         public void accept(Visitor v) { v.visitTypeBoundKind(this); }
2209 
2210         public Kind getKind() {
2211             throw new AssertionError("TypeBoundKind is not part of a public API");
2212         }
2213         @Override
2214         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2215             throw new AssertionError("TypeBoundKind is not part of a public API");
2216         }
2217         @Override
2218         public Tag getTag() {
2219             return TYPEBOUNDKIND;
2220         }
2221         @Override
2222         public boolean hasTag(Tag tag){
2223             return (tag.equals(TYPEBOUNDKIND));
2224         }
2225     }
2226 
2227     public static class JCAnnotation extends JCExpression implements AnnotationTree {
2228         public JCTree annotationType;
2229         public List<JCExpression> args;
2230         protected JCAnnotation(JCTree annotationType, List<JCExpression> args) {
2231             this.annotationType = annotationType;
2232             this.args = args;
2233         }
2234         @Override
2235         public void accept(Visitor v) { v.visitAnnotation(this); }
2236 
2237         public Kind getKind() { return Kind.ANNOTATION; }
2238         public JCTree getAnnotationType() { return annotationType; }
2239         public List<JCExpression> getArguments() {
2240             return args;
2241         }
2242         @Override
2243         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2244             return v.visitAnnotation(this, d);
2245         }
2246         @Override
2247         public Tag getTag() {
2248             return ANNOTATION;
2249         }
2250         @Override
2251         public boolean hasTag(Tag tag){
2252             return (tag.equals(ANNOTATION));
2253         }
2254     }
2255 
2256     public static class JCModifiers extends JCTree implements com.sun.source.tree.ModifiersTree {
2257         public long flags;
2258         public List<JCAnnotation> annotations;
2259         protected JCModifiers(long flags, List<JCAnnotation> annotations) {
2260             this.flags = flags;
2261             this.annotations = annotations;
2262         }
2263         @Override
2264         public void accept(Visitor v) { v.visitModifiers(this); }
2265 
2266         public Kind getKind() { return Kind.MODIFIERS; }
2267         public Set<Modifier> getFlags() {
2268             return Flags.asModifierSet(flags);
2269         }
2270         public List<JCAnnotation> getAnnotations() {
2271             return annotations;
2272         }
2273         @Override
2274         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2275             return v.visitModifiers(this, d);
2276         }
2277         @Override
2278         public Tag getTag() {
2279             return MODIFIERS;
2280         }
2281         @Override
2282         public boolean hasTag(Tag tag){
2283             return (tag.equals(MODIFIERS));
2284         }
2285     }
2286 
2287     public static class JCErroneous extends JCExpression
2288             implements com.sun.source.tree.ErroneousTree {
2289         public List<? extends JCTree> errs;
2290         protected JCErroneous(List<? extends JCTree> errs) {
2291             this.errs = errs;
2292         }
2293         @Override
2294         public void accept(Visitor v) { v.visitErroneous(this); }
2295 
2296         public Kind getKind() { return Kind.ERRONEOUS; }
2297 
2298         public List<? extends JCTree> getErrorTrees() {
2299             return errs;
2300         }
2301 
2302         @Override
2303         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2304             return v.visitErroneous(this, d);
2305         }
2306         @Override
2307         public Tag getTag() {
2308             return ERRONEOUS;
2309         }
2310         @Override
2311         public boolean hasTag(Tag tag){
2312             return (tag.equals(ERRONEOUS));
2313         }
2314     }
2315 
2316     /** (let int x = 3; in x+2) */
2317     public static class LetExpr extends JCExpression {
2318         public List<JCVariableDecl> defs;
2319         public JCTree expr;
2320         protected LetExpr(List<JCVariableDecl> defs, JCTree expr) {
2321             this.defs = defs;
2322             this.expr = expr;
2323         }
2324         @Override
2325         public void accept(Visitor v) { v.visitLetExpr(this); }
2326 
2327         public Kind getKind() {
2328             throw new AssertionError("LetExpr is not part of a public API");
2329         }
2330         @Override
2331         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
2332             throw new AssertionError("LetExpr is not part of a public API");
2333         }
2334         @Override
2335         public Tag getTag() {
2336             return LETEXPR;
2337         }
2338         @Override
2339         public boolean hasTag(Tag tag){
2340             return (tag.equals(LETEXPR));
2341         }
2342     }
2343 
2344     /** An interface for tree factories
2345      */
2346     public interface Factory {
2347         JCCompilationUnit TopLevel(List<JCAnnotation> packageAnnotations,
2348                                    JCExpression pid,
2349                                    List<JCTree> defs);
2350         JCImport Import(JCTree qualid, boolean staticImport);
2351         JCClassDecl ClassDef(JCModifiers mods,
2352                           Name name,
2353                           List<JCTypeParameter> typarams,
2354                           JCExpression extending,
2355                           List<JCExpression> implementing,
2356                           List<JCTree> defs);
2357         JCMethodDecl MethodDef(JCModifiers mods,
2358                             Name name,
2359                             JCExpression restype,
2360                             List<JCTypeParameter> typarams,
2361                             List<JCVariableDecl> params,
2362                             List<JCExpression> thrown,
2363                             JCBlock body,
2364                             JCExpression defaultValue);
2365         JCVariableDecl VarDef(JCModifiers mods,
2366                       Name name,
2367                       JCExpression vartype,
2368                       JCExpression init);
2369         JCSkip Skip();
2370         JCBlock Block(long flags, List<JCStatement> stats);
2371         JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond);
2372         JCWhileLoop WhileLoop(JCExpression cond, JCStatement body);
2373         JCForLoop ForLoop(List<JCStatement> init,
2374                         JCExpression cond,
2375                         List<JCExpressionStatement> step,
2376                         JCStatement body);
2377         JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body);
2378         JCLabeledStatement Labelled(Name label, JCStatement body);
2379         JCSwitch Switch(JCExpression selector, List<JCCase> cases);
2380         JCCase Case(JCExpression pat, List<JCStatement> stats);
2381         JCSynchronized Synchronized(JCExpression lock, JCBlock body);
2382         JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer);
2383         JCTry Try(List<JCTree> resources,
2384                   JCBlock body,
2385                   List<JCCatch> catchers,
2386                   JCBlock finalizer);
2387         JCCatch Catch(JCVariableDecl param, JCBlock body);
2388         JCConditional Conditional(JCExpression cond,
2389                                 JCExpression thenpart,
2390                                 JCExpression elsepart);
2391         JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart);
2392         JCExpressionStatement Exec(JCExpression expr);
2393         JCBreak Break(Name label);
2394         JCContinue Continue(Name label);
2395         JCReturn Return(JCExpression expr);
2396         JCThrow Throw(JCTree expr);
2397         JCAssert Assert(JCExpression cond, JCExpression detail);
2398         JCMethodInvocation Apply(List<JCExpression> typeargs,
2399                     JCExpression fn,
2400                     List<JCExpression> args);
2401         JCNewClass NewClass(JCExpression encl,
2402                           List<JCExpression> typeargs,
2403                           JCExpression clazz,
2404                           List<JCExpression> args,
2405                           JCClassDecl def);
2406         JCNewArray NewArray(JCExpression elemtype,
2407                           List<JCExpression> dims,
2408                           List<JCExpression> elems);
2409         JCParens Parens(JCExpression expr);
2410         JCAssign Assign(JCExpression lhs, JCExpression rhs);
2411         JCAssignOp Assignop(Tag opcode, JCTree lhs, JCTree rhs);
2412         JCUnary Unary(Tag opcode, JCExpression arg);
2413         JCBinary Binary(Tag opcode, JCExpression lhs, JCExpression rhs);
2414         JCTypeCast TypeCast(JCTree expr, JCExpression type);
2415         JCInstanceOf TypeTest(JCExpression expr, JCTree clazz);
2416         JCArrayAccess Indexed(JCExpression indexed, JCExpression index);
2417         JCFieldAccess Select(JCExpression selected, Name selector);
2418         JCIdent Ident(Name idname);
2419         JCLiteral Literal(int tag, Object value);
2420         JCPrimitiveTypeTree TypeIdent(int typetag);
2421         JCArrayTypeTree TypeArray(JCExpression elemtype);
2422         JCTypeApply TypeApply(JCExpression clazz, List<JCExpression> arguments);
2423         JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds);
2424         JCWildcard Wildcard(TypeBoundKind kind, JCTree type);
2425         TypeBoundKind TypeBoundKind(BoundKind kind);
2426         JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args);
2427         JCModifiers Modifiers(long flags, List<JCAnnotation> annotations);
2428         JCErroneous Erroneous(List<? extends JCTree> errs);
2429         LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr);
2430     }
2431 
2432     /** A generic visitor class for trees.
2433      */
2434     public static abstract class Visitor {
2435         public void visitTopLevel(JCCompilationUnit that)    { visitTree(that); }
2436         public void visitImport(JCImport that)               { visitTree(that); }
2437         public void visitClassDef(JCClassDecl that)          { visitTree(that); }
2438         public void visitMethodDef(JCMethodDecl that)        { visitTree(that); }
2439         public void visitVarDef(JCVariableDecl that)         { visitTree(that); }
2440         public void visitSkip(JCSkip that)                   { visitTree(that); }
2441         public void visitBlock(JCBlock that)                 { visitTree(that); }
2442         public void visitDoLoop(JCDoWhileLoop that)          { visitTree(that); }
2443         public void visitWhileLoop(JCWhileLoop that)         { visitTree(that); }
2444         public void visitForLoop(JCForLoop that)             { visitTree(that); }
2445         public void visitForeachLoop(JCEnhancedForLoop that) { visitTree(that); }
2446         public void visitLabelled(JCLabeledStatement that)   { visitTree(that); }
2447         public void visitSwitch(JCSwitch that)               { visitTree(that); }
2448         public void visitCase(JCCase that)                   { visitTree(that); }
2449         public void visitSynchronized(JCSynchronized that)   { visitTree(that); }
2450         public void visitTry(JCTry that)                     { visitTree(that); }
2451         public void visitCatch(JCCatch that)                 { visitTree(that); }
2452         public void visitConditional(JCConditional that)     { visitTree(that); }
2453         public void visitIf(JCIf that)                       { visitTree(that); }
2454         public void visitExec(JCExpressionStatement that)    { visitTree(that); }
2455         public void visitBreak(JCBreak that)                 { visitTree(that); }
2456         public void visitContinue(JCContinue that)           { visitTree(that); }
2457         public void visitReturn(JCReturn that)               { visitTree(that); }
2458         public void visitThrow(JCThrow that)                 { visitTree(that); }
2459         public void visitAssert(JCAssert that)               { visitTree(that); }
2460         public void visitApply(JCMethodInvocation that)      { visitTree(that); }
2461         public void visitNewClass(JCNewClass that)           { visitTree(that); }
2462         public void visitNewArray(JCNewArray that)           { visitTree(that); }
2463         public void visitParens(JCParens that)               { visitTree(that); }
2464         public void visitAssign(JCAssign that)               { visitTree(that); }
2465         public void visitAssignop(JCAssignOp that)           { visitTree(that); }
2466         public void visitUnary(JCUnary that)                 { visitTree(that); }
2467         public void visitBinary(JCBinary that)               { visitTree(that); }
2468         public void visitTypeCast(JCTypeCast that)           { visitTree(that); }
2469         public void visitTypeTest(JCInstanceOf that)         { visitTree(that); }
2470         public void visitIndexed(JCArrayAccess that)         { visitTree(that); }
2471         public void visitSelect(JCFieldAccess that)          { visitTree(that); }
2472         public void visitIdent(JCIdent that)                 { visitTree(that); }
2473         public void visitLiteral(JCLiteral that)             { visitTree(that); }
2474         public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); }
2475         public void visitTypeArray(JCArrayTypeTree that)     { visitTree(that); }
2476         public void visitTypeApply(JCTypeApply that)         { visitTree(that); }
2477         public void visitTypeUnion(JCTypeUnion that)         { visitTree(that); }
2478         public void visitTypeParameter(JCTypeParameter that) { visitTree(that); }
2479         public void visitWildcard(JCWildcard that)           { visitTree(that); }
2480         public void visitTypeBoundKind(TypeBoundKind that)   { visitTree(that); }
2481         public void visitAnnotation(JCAnnotation that)       { visitTree(that); }
2482         public void visitModifiers(JCModifiers that)         { visitTree(that); }
2483         public void visitErroneous(JCErroneous that)         { visitTree(that); }
2484         public void visitLetExpr(LetExpr that)               { visitTree(that); }
2485 
2486         public void visitTree(JCTree that)                   { Assert.error(); }
2487     }
2488 
2489 }