/* * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.tools.javac.tree; import java.io.IOException; import java.io.StringWriter; import java.util.*; import javax.lang.model.element.Modifier; import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; import com.sun.source.tree.*; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Directive.RequiresDirective; import com.sun.tools.javac.code.Scope.*; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.DefinedBy.Api; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import static com.sun.tools.javac.tree.JCTree.Tag.*; import javax.tools.JavaFileManager.Location; import com.sun.source.tree.CaseTree.CaseKind; import com.sun.source.tree.ModuleTree.ModuleKind; import com.sun.tools.javac.code.Directive.ExportsDirective; import com.sun.tools.javac.code.Directive.OpensDirective; import com.sun.tools.javac.code.Type.ModuleType; import com.sun.tools.javac.tree.JCTree.JCPolyExpression.PolyKind; /** * Root class for abstract syntax tree nodes. It provides definitions * for specific tree nodes as subclasses nested inside. * *

Each subclass is highly standardized. It generally contains * only tree fields for the syntactic subcomponents of the node. Some * classes that represent identifier uses or definitions also define a * Symbol field that denotes the represented identifier. Classes for * non-local jumps also carry the jump target as a field. The root * class Tree itself defines fields for the tree's type and position. * No other fields are kept in a tree node; instead parameters are * passed to methods accessing the node. * *

Except for the methods defined by com.sun.source, the only * method defined in subclasses is `visit' which applies a given * visitor to the tree. The actual tree processing is done by visitor * classes in other packages. The abstract class Visitor, as well as * an Factory interface for trees, are defined as inner classes in * Tree. * *

To avoid ambiguities with the Tree API in com.sun.source all sub * classes should, by convention, start with JC (javac). * *

This is NOT part of any supported API. * If you write code that depends on this, you do so at your own risk. * This code and its internal interfaces are subject to change or * deletion without notice. * * @see TreeMaker * @see TreeInfo * @see TreeTranslator * @see Pretty */ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { /* Tree tag values, identifying kinds of trees */ public enum Tag { /** For methods that return an invalid tag if a given condition is not met */ NO_TAG, /** Toplevel nodes, of type TopLevel, representing entire source files. */ TOPLEVEL, /** Package level definitions. */ PACKAGEDEF, /** Import clauses, of type Import. */ IMPORT, /** Class definitions, of type ClassDef. */ CLASSDEF, /** Method definitions, of type MethodDef. */ METHODDEF, /** Variable definitions, of type VarDef. */ VARDEF, /** The no-op statement ";", of type Skip */ SKIP, /** Blocks, of type Block. */ BLOCK, /** Do-while loops, of type DoLoop. */ DOLOOP, /** While-loops, of type WhileLoop. */ WHILELOOP, /** For-loops, of type ForLoop. */ FORLOOP, /** Foreach-loops, of type ForeachLoop. */ FOREACHLOOP, /** Labelled statements, of type Labelled. */ LABELLED, /** Switch statements, of type Switch. */ SWITCH, /** Case parts in switch statements/expressions, of type Case. */ CASE, /** Switch expression statements, of type Switch. */ SWITCH_EXPRESSION, /** Synchronized statements, of type Synchonized. */ SYNCHRONIZED, /** Try statements, of type Try. */ TRY, /** Catch clauses in try statements, of type Catch. */ CATCH, /** Conditional expressions, of type Conditional. */ CONDEXPR, /** Conditional statements, of type If. */ IF, /** Expression statements, of type Exec. */ EXEC, /** Break statements, of type Break. */ BREAK, /** Continue statements, of type Continue. */ CONTINUE, /** Return statements, of type Return. */ RETURN, /** Throw statements, of type Throw. */ THROW, /** Assert statements, of type Assert. */ ASSERT, /** Method invocation expressions, of type Apply. */ APPLY, /** Class instance creation expressions, of type NewClass. */ NEWCLASS, /** Array creation expressions, of type NewArray. */ NEWARRAY, /** Lambda expression, of type Lambda. */ LAMBDA, /** Parenthesized subexpressions, of type Parens. */ PARENS, /** Assignment expressions, of type Assign. */ ASSIGN, /** Type cast expressions, of type TypeCast. */ TYPECAST, /** Type test expressions, of type TypeTest. */ TYPETEST, /** Indexed array expressions, of type Indexed. */ INDEXED, /** Selections, of type Select. */ SELECT, /** Member references, of type Reference. */ REFERENCE, /** Simple identifiers, of type Ident. */ IDENT, /** Literals, of type Literal. */ LITERAL, /** Basic type identifiers, of type TypeIdent. */ TYPEIDENT, /** Array types, of type TypeArray. */ TYPEARRAY, /** Parameterized types, of type TypeApply. */ TYPEAPPLY, /** Union types, of type TypeUnion. */ TYPEUNION, /** Intersection types, of type TypeIntersection. */ TYPEINTERSECTION, /** Formal type parameters, of type TypeParameter. */ TYPEPARAMETER, /** Type argument. */ WILDCARD, /** Bound kind: extends, super, exact, or unbound */ TYPEBOUNDKIND, /** metadata: Annotation. */ ANNOTATION, /** metadata: Type annotation. */ TYPE_ANNOTATION, /** metadata: Modifiers */ MODIFIERS, /** An annotated type tree. */ ANNOTATED_TYPE, /** Error trees, of type Erroneous. */ ERRONEOUS, /** Unary operators, of type Unary. */ POS, // + NEG, // - NOT, // ! COMPL, // ~ PREINC, // ++ _ PREDEC, // -- _ POSTINC, // _ ++ POSTDEC, // _ -- /** unary operator for null reference checks, only used internally. */ NULLCHK, /** Binary operators, of type Binary. */ OR, // || AND, // && BITOR, // | BITXOR, // ^ BITAND, // & EQ, // == NE, // != LT, // < GT, // > LE, // <= GE, // >= SL, // << SR, // >> USR, // >>> PLUS, // + MINUS, // - MUL, // * DIV, // / MOD, // % /** Assignment operators, of type Assignop. */ BITOR_ASG(BITOR), // |= BITXOR_ASG(BITXOR), // ^= BITAND_ASG(BITAND), // &= SL_ASG(SL), // <<= SR_ASG(SR), // >>= USR_ASG(USR), // >>>= PLUS_ASG(PLUS), // += MINUS_ASG(MINUS), // -= MUL_ASG(MUL), // *= DIV_ASG(DIV), // /= MOD_ASG(MOD), // %= MODULEDEF, EXPORTS, OPENS, PROVIDES, REQUIRES, USES, /** A synthetic let expression, of type LetExpr. */ LETEXPR; // ala scheme private final Tag noAssignTag; private static final int numberOfOperators = MOD.ordinal() - POS.ordinal() + 1; private Tag(Tag noAssignTag) { this.noAssignTag = noAssignTag; } private Tag() { this(null); } public static int getNumberOfOperators() { return numberOfOperators; } public Tag noAssignOp() { if (noAssignTag != null) return noAssignTag; throw new AssertionError("noAssignOp() method is not available for non assignment tags"); } public boolean isPostUnaryOp() { return (this == POSTINC || this == POSTDEC); } public boolean isIncOrDecUnaryOp() { return (this == PREINC || this == PREDEC || this == POSTINC || this == POSTDEC); } public boolean isAssignop() { return noAssignTag != null; } public int operatorIndex() { return (this.ordinal() - POS.ordinal()); } } /* The (encoded) position in the source file. @see util.Position. */ public int pos; /* The type of this node. */ public Type type; /* The tag of this node -- one of the constants declared above. */ public abstract Tag getTag(); /* Returns true if the tag of this node is equals to tag. */ public boolean hasTag(Tag tag) { return tag == getTag(); } /** Convert a tree to a pretty-printed string. */ @Override public String toString() { StringWriter s = new StringWriter(); try { new Pretty(s, false).printExpr(this); } catch (IOException e) { // should never happen, because StringWriter is defined // never to throw any IOExceptions throw new AssertionError(e); } return s.toString(); } /** Set position field and return this tree. */ public JCTree setPos(int pos) { this.pos = pos; return this; } /** Set type field and return this tree. */ public JCTree setType(Type type) { this.type = type; return this; } /** Visit this tree with a given visitor. */ public abstract void accept(Visitor v); @DefinedBy(Api.COMPILER_TREE) public abstract R accept(TreeVisitor v, D d); /** Return a shallow copy of this tree. */ @Override public Object clone() { try { return super.clone(); } catch(CloneNotSupportedException e) { throw new RuntimeException(e); } } /** Get a default position for this tree node. */ public DiagnosticPosition pos() { return this; } // for default DiagnosticPosition public JCTree getTree() { return this; } // for default DiagnosticPosition public int getStartPosition() { return TreeInfo.getStartPos(this); } // for default DiagnosticPosition public int getPreferredPosition() { return pos; } // for default DiagnosticPosition public int getEndPosition(EndPosTable endPosTable) { return TreeInfo.getEndPos(this, endPosTable); } /** * Everything in one source file is kept in a {@linkplain JCCompilationUnit} structure. */ public static class JCCompilationUnit extends JCTree implements CompilationUnitTree { /** All definitions in this file (ClassDef, Import, and Skip) */ public List defs; /** The source file name. */ public JavaFileObject sourcefile; /** The module to which this compilation unit belongs. */ public ModuleSymbol modle; /** The location in which this compilation unit was found. */ public Location locn; /** The package to which this compilation unit belongs. */ public PackageSymbol packge; /** A scope containing top level classes. */ public WriteableScope toplevelScope; /** A scope for all named imports. */ public NamedImportScope namedImportScope; /** A scope for all import-on-demands. */ public StarImportScope starImportScope; /** Line starting positions, defined only if option -g is set. */ public Position.LineMap lineMap = null; /** A table that stores all documentation comments indexed by the tree * nodes they refer to. defined only if option -s is set. */ public DocCommentTable docComments = null; /* An object encapsulating ending positions of source ranges indexed by * the tree nodes they belong to. Defined only if option -Xjcov is set. */ public EndPosTable endPositions = null; protected JCCompilationUnit(List defs) { this.defs = defs; } @Override public void accept(Visitor v) { v.visitTopLevel(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.COMPILATION_UNIT; } public JCModuleDecl getModuleDecl() { for (JCTree tree : defs) { if (tree.hasTag(MODULEDEF)) { return (JCModuleDecl) tree; } } return null; } @DefinedBy(Api.COMPILER_TREE) public JCPackageDecl getPackage() { // PackageDecl must be the first entry if it exists if (!defs.isEmpty() && defs.head.hasTag(PACKAGEDEF)) return (JCPackageDecl)defs.head; return null; } @DefinedBy(Api.COMPILER_TREE) public List getPackageAnnotations() { JCPackageDecl pd = getPackage(); return pd != null ? pd.getAnnotations() : List.nil(); } @DefinedBy(Api.COMPILER_TREE) public ExpressionTree getPackageName() { JCPackageDecl pd = getPackage(); return pd != null ? pd.getPackageName() : null; } @DefinedBy(Api.COMPILER_TREE) public List getImports() { ListBuffer imports = new ListBuffer<>(); for (JCTree tree : defs) { if (tree.hasTag(IMPORT)) imports.append((JCImport)tree); else if (!tree.hasTag(PACKAGEDEF) && !tree.hasTag(SKIP)) break; } return imports.toList(); } @DefinedBy(Api.COMPILER_TREE) public JavaFileObject getSourceFile() { return sourcefile; } @DefinedBy(Api.COMPILER_TREE) public Position.LineMap getLineMap() { return lineMap; } @DefinedBy(Api.COMPILER_TREE) public List getTypeDecls() { List typeDefs; for (typeDefs = defs; !typeDefs.isEmpty(); typeDefs = typeDefs.tail) if (!typeDefs.head.hasTag(PACKAGEDEF) && !typeDefs.head.hasTag(IMPORT)) break; return typeDefs; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitCompilationUnit(this, d); } @Override public Tag getTag() { return TOPLEVEL; } } /** * Package definition. */ public static class JCPackageDecl extends JCTree implements PackageTree { public List annotations; /** The tree representing the package clause. */ public JCExpression pid; public PackageSymbol packge; public JCPackageDecl(List annotations, JCExpression pid) { this.annotations = annotations; this.pid = pid; } @Override public void accept(Visitor v) { v.visitPackageDef(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.PACKAGE; } @DefinedBy(Api.COMPILER_TREE) public List getAnnotations() { return annotations; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getPackageName() { return pid; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitPackage(this, d); } @Override public Tag getTag() { return PACKAGEDEF; } } /** * An import clause. */ public static class JCImport extends JCTree implements ImportTree { public boolean staticImport; /** The imported class(es). */ public JCTree qualid; public com.sun.tools.javac.code.Scope importScope; protected JCImport(JCTree qualid, boolean importStatic) { this.qualid = qualid; this.staticImport = importStatic; } @Override public void accept(Visitor v) { v.visitImport(this); } @DefinedBy(Api.COMPILER_TREE) public boolean isStatic() { return staticImport; } @DefinedBy(Api.COMPILER_TREE) public JCTree getQualifiedIdentifier() { return qualid; } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.IMPORT; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitImport(this, d); } @Override public Tag getTag() { return IMPORT; } } public static abstract class JCStatement extends JCTree implements StatementTree { @Override public JCStatement setType(Type type) { super.setType(type); return this; } @Override public JCStatement setPos(int pos) { super.setPos(pos); return this; } } public static abstract class JCExpression extends JCTree implements ExpressionTree { @Override public JCExpression setType(Type type) { super.setType(type); return this; } @Override public JCExpression setPos(int pos) { super.setPos(pos); return this; } public boolean isPoly() { return false; } public boolean isStandalone() { return true; } } /** * Common supertype for all poly expression trees (lambda, method references, * conditionals, method and constructor calls) */ public static abstract class JCPolyExpression extends JCExpression { /** * A poly expression can only be truly 'poly' in certain contexts */ public enum PolyKind { /** poly expression to be treated as a standalone expression */ STANDALONE, /** true poly expression */ POLY } /** is this poly expression a 'true' poly expression? */ public PolyKind polyKind; @Override public boolean isPoly() { return polyKind == PolyKind.POLY; } @Override public boolean isStandalone() { return polyKind == PolyKind.STANDALONE; } } /** * Common supertype for all functional expression trees (lambda and method references) */ public static abstract class JCFunctionalExpression extends JCPolyExpression { public JCFunctionalExpression() { //a functional expression is always a 'true' poly polyKind = PolyKind.POLY; } /** list of target types inferred for this functional expression. */ public Type target; public Type getDescriptorType(Types types) { return target != null ? types.findDescriptorType(target) : types.createErrorType(null); } } /** * A class definition. */ public static class JCClassDecl extends JCStatement implements ClassTree { /** the modifiers */ public JCModifiers mods; /** the name of the class */ public Name name; /** formal class parameters */ public List typarams; /** the classes this class extends */ public JCExpression extending; /** the interfaces implemented by this class */ public List implementing; /** all variables and methods defined in this class */ public List defs; /** the symbol */ public ClassSymbol sym; protected JCClassDecl(JCModifiers mods, Name name, List typarams, JCExpression extending, List implementing, List defs, ClassSymbol sym) { this.mods = mods; this.name = name; this.typarams = typarams; this.extending = extending; this.implementing = implementing; this.defs = defs; this.sym = sym; } @Override public void accept(Visitor v) { v.visitClassDef(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { if ((mods.flags & Flags.ANNOTATION) != 0) return Kind.ANNOTATION_TYPE; else if ((mods.flags & Flags.INTERFACE) != 0) return Kind.INTERFACE; else if ((mods.flags & Flags.ENUM) != 0) return Kind.ENUM; else return Kind.CLASS; } @DefinedBy(Api.COMPILER_TREE) public JCModifiers getModifiers() { return mods; } @DefinedBy(Api.COMPILER_TREE) public Name getSimpleName() { return name; } @DefinedBy(Api.COMPILER_TREE) public List getTypeParameters() { return typarams; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExtendsClause() { return extending; } @DefinedBy(Api.COMPILER_TREE) public List getImplementsClause() { return implementing; } @DefinedBy(Api.COMPILER_TREE) public List getMembers() { return defs; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitClass(this, d); } @Override public Tag getTag() { return CLASSDEF; } } /** * A method definition. */ public static class JCMethodDecl extends JCTree implements MethodTree { /** method modifiers */ public JCModifiers mods; /** method name */ public Name name; /** type of method return value */ public JCExpression restype; /** type parameters */ public List typarams; /** receiver parameter */ public JCVariableDecl recvparam; /** value parameters */ public List params; /** exceptions thrown by this method */ public List thrown; /** statements in the method */ public JCBlock body; /** default value, for annotation types */ public JCExpression defaultValue; /** method symbol */ public MethodSymbol sym; protected JCMethodDecl(JCModifiers mods, Name name, JCExpression restype, List typarams, JCVariableDecl recvparam, List params, List thrown, JCBlock body, JCExpression defaultValue, MethodSymbol sym) { this.mods = mods; this.name = name; this.restype = restype; this.typarams = typarams; this.params = params; this.recvparam = recvparam; // TODO: do something special if the given type is null? // receiver != null ? receiver : List.nil()); this.thrown = thrown; this.body = body; this.defaultValue = defaultValue; this.sym = sym; } @Override public void accept(Visitor v) { v.visitMethodDef(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.METHOD; } @DefinedBy(Api.COMPILER_TREE) public JCModifiers getModifiers() { return mods; } @DefinedBy(Api.COMPILER_TREE) public Name getName() { return name; } @DefinedBy(Api.COMPILER_TREE) public JCTree getReturnType() { return restype; } @DefinedBy(Api.COMPILER_TREE) public List getTypeParameters() { return typarams; } @DefinedBy(Api.COMPILER_TREE) public List getParameters() { return params; } @DefinedBy(Api.COMPILER_TREE) public JCVariableDecl getReceiverParameter() { return recvparam; } @DefinedBy(Api.COMPILER_TREE) public List getThrows() { return thrown; } @DefinedBy(Api.COMPILER_TREE) public JCBlock getBody() { return body; } @DefinedBy(Api.COMPILER_TREE) public JCTree getDefaultValue() { // for annotation types return defaultValue; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitMethod(this, d); } @Override public Tag getTag() { return METHODDEF; } } /** * A variable definition. */ public static class JCVariableDecl extends JCStatement implements VariableTree { /** variable modifiers */ public JCModifiers mods; /** variable name */ public Name name; /** variable name expression */ public JCExpression nameexpr; /** type of the variable */ public JCExpression vartype; /** variable's initial value */ public JCExpression init; /** symbol */ public VarSymbol sym; /** explicit start pos */ public int startPos = Position.NOPOS; protected JCVariableDecl(JCModifiers mods, Name name, JCExpression vartype, JCExpression init, VarSymbol sym) { this.mods = mods; this.name = name; this.vartype = vartype; this.init = init; this.sym = sym; } protected JCVariableDecl(JCModifiers mods, JCExpression nameexpr, JCExpression vartype) { this(mods, null, vartype, null, null); this.nameexpr = nameexpr; if (nameexpr.hasTag(Tag.IDENT)) { this.name = ((JCIdent)nameexpr).name; } else { // Only other option is qualified name x.y.this; this.name = ((JCFieldAccess)nameexpr).name; } } public boolean isImplicitlyTyped() { return vartype == null; } @Override public void accept(Visitor v) { v.visitVarDef(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.VARIABLE; } @DefinedBy(Api.COMPILER_TREE) public JCModifiers getModifiers() { return mods; } @DefinedBy(Api.COMPILER_TREE) public Name getName() { return name; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getNameExpression() { return nameexpr; } @DefinedBy(Api.COMPILER_TREE) public JCTree getType() { return vartype; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getInitializer() { return init; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitVariable(this, d); } @Override public Tag getTag() { return VARDEF; } } /** * A no-op statement ";". */ public static class JCSkip extends JCStatement implements EmptyStatementTree { protected JCSkip() { } @Override public void accept(Visitor v) { v.visitSkip(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.EMPTY_STATEMENT; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitEmptyStatement(this, d); } @Override public Tag getTag() { return SKIP; } } /** * A statement block. */ public static class JCBlock extends JCStatement implements BlockTree { /** flags */ public long flags; /** statements */ public List stats; /** Position of closing brace, optional. */ public int endpos = Position.NOPOS; protected JCBlock(long flags, List stats) { this.stats = stats; this.flags = flags; } @Override public void accept(Visitor v) { v.visitBlock(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.BLOCK; } @DefinedBy(Api.COMPILER_TREE) public List getStatements() { return stats; } @DefinedBy(Api.COMPILER_TREE) public boolean isStatic() { return (flags & Flags.STATIC) != 0; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitBlock(this, d); } @Override public Tag getTag() { return BLOCK; } } /** * A do loop */ public static class JCDoWhileLoop extends JCStatement implements DoWhileLoopTree { public JCStatement body; public JCExpression cond; protected JCDoWhileLoop(JCStatement body, JCExpression cond) { this.body = body; this.cond = cond; } @Override public void accept(Visitor v) { v.visitDoLoop(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.DO_WHILE_LOOP; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getCondition() { return cond; } @DefinedBy(Api.COMPILER_TREE) public JCStatement getStatement() { return body; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitDoWhileLoop(this, d); } @Override public Tag getTag() { return DOLOOP; } } /** * A while loop */ public static class JCWhileLoop extends JCStatement implements WhileLoopTree { public JCExpression cond; public JCStatement body; protected JCWhileLoop(JCExpression cond, JCStatement body) { this.cond = cond; this.body = body; } @Override public void accept(Visitor v) { v.visitWhileLoop(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.WHILE_LOOP; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getCondition() { return cond; } @DefinedBy(Api.COMPILER_TREE) public JCStatement getStatement() { return body; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitWhileLoop(this, d); } @Override public Tag getTag() { return WHILELOOP; } } /** * A for loop. */ public static class JCForLoop extends JCStatement implements ForLoopTree { public List init; public JCExpression cond; public List step; public JCStatement body; protected JCForLoop(List init, JCExpression cond, List update, JCStatement body) { this.init = init; this.cond = cond; this.step = update; this.body = body; } @Override public void accept(Visitor v) { v.visitForLoop(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.FOR_LOOP; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getCondition() { return cond; } @DefinedBy(Api.COMPILER_TREE) public JCStatement getStatement() { return body; } @DefinedBy(Api.COMPILER_TREE) public List getInitializer() { return init; } @DefinedBy(Api.COMPILER_TREE) public List getUpdate() { return step; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitForLoop(this, d); } @Override public Tag getTag() { return FORLOOP; } } /** * The enhanced for loop. */ public static class JCEnhancedForLoop extends JCStatement implements EnhancedForLoopTree { public JCVariableDecl var; public JCExpression expr; public JCStatement body; protected JCEnhancedForLoop(JCVariableDecl var, JCExpression expr, JCStatement body) { this.var = var; this.expr = expr; this.body = body; } @Override public void accept(Visitor v) { v.visitForeachLoop(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.ENHANCED_FOR_LOOP; } @DefinedBy(Api.COMPILER_TREE) public JCVariableDecl getVariable() { return var; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return expr; } @DefinedBy(Api.COMPILER_TREE) public JCStatement getStatement() { return body; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitEnhancedForLoop(this, d); } @Override public Tag getTag() { return FOREACHLOOP; } } /** * A labelled expression or statement. */ public static class JCLabeledStatement extends JCStatement implements LabeledStatementTree { public Name label; public JCStatement body; protected JCLabeledStatement(Name label, JCStatement body) { this.label = label; this.body = body; } @Override public void accept(Visitor v) { v.visitLabelled(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.LABELED_STATEMENT; } @DefinedBy(Api.COMPILER_TREE) public Name getLabel() { return label; } @DefinedBy(Api.COMPILER_TREE) public JCStatement getStatement() { return body; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitLabeledStatement(this, d); } @Override public Tag getTag() { return LABELLED; } } /** * A "switch ( ) { }" construction. */ public static class JCSwitch extends JCStatement implements SwitchTree { public JCExpression selector; public List cases; protected JCSwitch(JCExpression selector, List cases) { this.selector = selector; this.cases = cases; } @Override public void accept(Visitor v) { v.visitSwitch(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.SWITCH; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return selector; } @DefinedBy(Api.COMPILER_TREE) public List getCases() { return cases; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitSwitch(this, d); } @Override public Tag getTag() { return SWITCH; } } /** * A "case :" of a switch. */ public static class JCCase extends JCStatement implements CaseTree { //as CaseKind is deprecated for removal (as it is part of a preview feature), //using indirection through these fields to avoid unnecessary @SuppressWarnings: @SuppressWarnings("removal") public static final CaseKind STATEMENT = CaseKind.STATEMENT; @SuppressWarnings("removal") public static final CaseKind RULE = CaseKind.RULE; @SuppressWarnings("removal") public final CaseKind caseKind; public List pats; public List stats; public JCTree body; public boolean completesNormally; protected JCCase(@SuppressWarnings("removal") CaseKind caseKind, List pats, List stats, JCTree body) { Assert.checkNonNull(pats); Assert.check(pats.isEmpty() || pats.head != null); this.caseKind = caseKind; this.pats = pats; this.stats = stats; this.body = body; } @Override public void accept(Visitor v) { v.visitCase(this); } @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.CASE; } @Override @Deprecated @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return pats.head; } @Override @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("removal") public List getExpressions() { return pats; } @DefinedBy(Api.COMPILER_TREE) public List getStatements() { return stats; } @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("removal") public JCTree getBody() { return body; } @Override @SuppressWarnings("removal") public CaseKind getCaseKind() { return caseKind; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitCase(this, d); } @Override public Tag getTag() { return CASE; } } /** * A "switch ( ) { }" construction. */ @SuppressWarnings("removal") public static class JCSwitchExpression extends JCPolyExpression implements SwitchExpressionTree { public JCExpression selector; public List cases; protected JCSwitchExpression(JCExpression selector, List cases) { this.selector = selector; this.cases = cases; } @Override public void accept(Visitor v) { v.visitSwitchExpression(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.SWITCH_EXPRESSION; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return selector; } @DefinedBy(Api.COMPILER_TREE) public List getCases() { return cases; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitSwitchExpression(this, d); } @Override public Tag getTag() { return SWITCH_EXPRESSION; } } /** * A synchronized block. */ public static class JCSynchronized extends JCStatement implements SynchronizedTree { public JCExpression lock; public JCBlock body; protected JCSynchronized(JCExpression lock, JCBlock body) { this.lock = lock; this.body = body; } @Override public void accept(Visitor v) { v.visitSynchronized(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.SYNCHRONIZED; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return lock; } @DefinedBy(Api.COMPILER_TREE) public JCBlock getBlock() { return body; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitSynchronized(this, d); } @Override public Tag getTag() { return SYNCHRONIZED; } } /** * A "try { } catch ( ) { } finally { }" block. */ public static class JCTry extends JCStatement implements TryTree { public JCBlock body; public List catchers; public JCBlock finalizer; public List resources; public boolean finallyCanCompleteNormally; protected JCTry(List resources, JCBlock body, List catchers, JCBlock finalizer) { this.body = body; this.catchers = catchers; this.finalizer = finalizer; this.resources = resources; } @Override public void accept(Visitor v) { v.visitTry(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.TRY; } @DefinedBy(Api.COMPILER_TREE) public JCBlock getBlock() { return body; } @DefinedBy(Api.COMPILER_TREE) public List getCatches() { return catchers; } @DefinedBy(Api.COMPILER_TREE) public JCBlock getFinallyBlock() { return finalizer; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitTry(this, d); } @Override @DefinedBy(Api.COMPILER_TREE) public List getResources() { return resources; } @Override public Tag getTag() { return TRY; } } /** * A catch block. */ public static class JCCatch extends JCTree implements CatchTree { public JCVariableDecl param; public JCBlock body; protected JCCatch(JCVariableDecl param, JCBlock body) { this.param = param; this.body = body; } @Override public void accept(Visitor v) { v.visitCatch(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.CATCH; } @DefinedBy(Api.COMPILER_TREE) public JCVariableDecl getParameter() { return param; } @DefinedBy(Api.COMPILER_TREE) public JCBlock getBlock() { return body; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitCatch(this, d); } @Override public Tag getTag() { return CATCH; } } /** * A ( ) ? ( ) : ( ) conditional expression */ public static class JCConditional extends JCPolyExpression implements ConditionalExpressionTree { public JCExpression cond; public JCExpression truepart; public JCExpression falsepart; protected JCConditional(JCExpression cond, JCExpression truepart, JCExpression falsepart) { this.cond = cond; this.truepart = truepart; this.falsepart = falsepart; } @Override public void accept(Visitor v) { v.visitConditional(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.CONDITIONAL_EXPRESSION; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getCondition() { return cond; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getTrueExpression() { return truepart; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getFalseExpression() { return falsepart; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitConditionalExpression(this, d); } @Override public Tag getTag() { return CONDEXPR; } } /** * An "if ( ) { } else { }" block */ public static class JCIf extends JCStatement implements IfTree { public JCExpression cond; public JCStatement thenpart; public JCStatement elsepart; protected JCIf(JCExpression cond, JCStatement thenpart, JCStatement elsepart) { this.cond = cond; this.thenpart = thenpart; this.elsepart = elsepart; } @Override public void accept(Visitor v) { v.visitIf(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.IF; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getCondition() { return cond; } @DefinedBy(Api.COMPILER_TREE) public JCStatement getThenStatement() { return thenpart; } @DefinedBy(Api.COMPILER_TREE) public JCStatement getElseStatement() { return elsepart; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitIf(this, d); } @Override public Tag getTag() { return IF; } } /** * an expression statement */ public static class JCExpressionStatement extends JCStatement implements ExpressionStatementTree { /** expression structure */ public JCExpression expr; protected JCExpressionStatement(JCExpression expr) { this.expr = expr; } @Override public void accept(Visitor v) { v.visitExec(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.EXPRESSION_STATEMENT; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return expr; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitExpressionStatement(this, d); } @Override public Tag getTag() { return EXEC; } /** Convert a expression-statement tree to a pretty-printed string. */ @Override public String toString() { StringWriter s = new StringWriter(); try { new Pretty(s, false).printStat(this); } catch (IOException e) { // should never happen, because StringWriter is defined // never to throw any IOExceptions throw new AssertionError(e); } return s.toString(); } } /** * A break from a loop or switch. */ public static class JCBreak extends JCStatement implements BreakTree { public JCExpression value; public JCTree target; protected JCBreak(JCExpression value, JCTree target) { this.value = value; this.target = target; } @Override public void accept(Visitor v) { v.visitBreak(this); } public boolean isValueBreak() { return target != null && target.hasTag(SWITCH_EXPRESSION); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.BREAK; } @DefinedBy(Api.COMPILER_TREE) public Name getLabel() { return value != null && value.getKind() == Kind.IDENTIFIER ? ((JCIdent) value).getName() : null; } @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("removal") public JCExpression getValue() { return value; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitBreak(this, d); } @Override public Tag getTag() { return BREAK; } } /** * A continue of a loop. */ public static class JCContinue extends JCStatement implements ContinueTree { public Name label; public JCTree target; protected JCContinue(Name label, JCTree target) { this.label = label; this.target = target; } @Override public void accept(Visitor v) { v.visitContinue(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.CONTINUE; } @DefinedBy(Api.COMPILER_TREE) public Name getLabel() { return label; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitContinue(this, d); } @Override public Tag getTag() { return CONTINUE; } } /** * A return statement. */ public static class JCReturn extends JCStatement implements ReturnTree { public JCExpression expr; protected JCReturn(JCExpression expr) { this.expr = expr; } @Override public void accept(Visitor v) { v.visitReturn(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.RETURN; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return expr; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitReturn(this, d); } @Override public Tag getTag() { return RETURN; } } /** * A throw statement. */ public static class JCThrow extends JCStatement implements ThrowTree { public JCExpression expr; protected JCThrow(JCExpression expr) { this.expr = expr; } @Override public void accept(Visitor v) { v.visitThrow(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.THROW; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return expr; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitThrow(this, d); } @Override public Tag getTag() { return THROW; } } /** * An assert statement. */ public static class JCAssert extends JCStatement implements AssertTree { public JCExpression cond; public JCExpression detail; protected JCAssert(JCExpression cond, JCExpression detail) { this.cond = cond; this.detail = detail; } @Override public void accept(Visitor v) { v.visitAssert(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.ASSERT; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getCondition() { return cond; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getDetail() { return detail; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitAssert(this, d); } @Override public Tag getTag() { return ASSERT; } } /** * A method invocation */ public static class JCMethodInvocation extends JCPolyExpression implements MethodInvocationTree { public List typeargs; public JCExpression meth; public List args; public Type varargsElement; protected JCMethodInvocation(List typeargs, JCExpression meth, List args) { this.typeargs = (typeargs == null) ? List.nil() : typeargs; this.meth = meth; this.args = args; } @Override public void accept(Visitor v) { v.visitApply(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.METHOD_INVOCATION; } @DefinedBy(Api.COMPILER_TREE) public List getTypeArguments() { return typeargs; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getMethodSelect() { return meth; } @DefinedBy(Api.COMPILER_TREE) public List getArguments() { return args; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitMethodInvocation(this, d); } @Override public JCMethodInvocation setType(Type type) { super.setType(type); return this; } @Override public Tag getTag() { return(APPLY); } } /** * A new(...) operation. */ public static class JCNewClass extends JCPolyExpression implements NewClassTree { public JCExpression encl; public List typeargs; public JCExpression clazz; public List args; public JCClassDecl def; public Symbol constructor; public Type varargsElement; public Type constructorType; protected JCNewClass(JCExpression encl, List typeargs, JCExpression clazz, List args, JCClassDecl def) { this.encl = encl; this.typeargs = (typeargs == null) ? List.nil() : typeargs; this.clazz = clazz; this.args = args; this.def = def; } @Override public void accept(Visitor v) { v.visitNewClass(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.NEW_CLASS; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getEnclosingExpression() { // expr.new C< ... > ( ... ) return encl; } @DefinedBy(Api.COMPILER_TREE) public List getTypeArguments() { return typeargs; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getIdentifier() { return clazz; } @DefinedBy(Api.COMPILER_TREE) public List getArguments() { return args; } @DefinedBy(Api.COMPILER_TREE) public JCClassDecl getClassBody() { return def; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitNewClass(this, d); } @Override public Tag getTag() { return NEWCLASS; } } /** * A new[...] operation. */ public static class JCNewArray extends JCExpression implements NewArrayTree { public JCExpression elemtype; public List dims; // type annotations on inner-most component public List annotations; // type annotations on dimensions public List> dimAnnotations; public List elems; protected JCNewArray(JCExpression elemtype, List dims, List elems) { this.elemtype = elemtype; this.dims = dims; this.annotations = List.nil(); this.dimAnnotations = List.nil(); this.elems = elems; } @Override public void accept(Visitor v) { v.visitNewArray(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.NEW_ARRAY; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getType() { return elemtype; } @DefinedBy(Api.COMPILER_TREE) public List getDimensions() { return dims; } @DefinedBy(Api.COMPILER_TREE) public List getInitializers() { return elems; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitNewArray(this, d); } @Override public Tag getTag() { return NEWARRAY; } @Override @DefinedBy(Api.COMPILER_TREE) public List getAnnotations() { return annotations; } @Override @DefinedBy(Api.COMPILER_TREE) public List> getDimAnnotations() { return dimAnnotations; } } /** * A lambda expression. */ public static class JCLambda extends JCFunctionalExpression implements LambdaExpressionTree { public enum ParameterKind { IMPLICIT, EXPLICIT } public List params; public JCTree body; public boolean canCompleteNormally = true; public ParameterKind paramKind; public JCLambda(List params, JCTree body) { this.params = params; this.body = body; if (params.isEmpty() || params.head.vartype != null) { paramKind = ParameterKind.EXPLICIT; } else { paramKind = ParameterKind.IMPLICIT; } } @Override public Tag getTag() { return LAMBDA; } @Override public void accept(Visitor v) { v.visitLambda(this); } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitLambdaExpression(this, d); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.LAMBDA_EXPRESSION; } @DefinedBy(Api.COMPILER_TREE) public JCTree getBody() { return body; } @DefinedBy(Api.COMPILER_TREE) public java.util.List getParameters() { return params; } @Override public JCLambda setType(Type type) { super.setType(type); return this; } @Override @DefinedBy(Api.COMPILER_TREE) public BodyKind getBodyKind() { return body.hasTag(BLOCK) ? BodyKind.STATEMENT : BodyKind.EXPRESSION; } } /** * A parenthesized subexpression ( ... ) */ public static class JCParens extends JCExpression implements ParenthesizedTree { public JCExpression expr; protected JCParens(JCExpression expr) { this.expr = expr; } @Override public void accept(Visitor v) { v.visitParens(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.PARENTHESIZED; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return expr; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitParenthesized(this, d); } @Override public Tag getTag() { return PARENS; } } /** * A assignment with "=". */ public static class JCAssign extends JCExpression implements AssignmentTree { public JCExpression lhs; public JCExpression rhs; protected JCAssign(JCExpression lhs, JCExpression rhs) { this.lhs = lhs; this.rhs = rhs; } @Override public void accept(Visitor v) { v.visitAssign(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.ASSIGNMENT; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getVariable() { return lhs; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return rhs; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitAssignment(this, d); } @Override public Tag getTag() { return ASSIGN; } } public static abstract class JCOperatorExpression extends JCExpression { public enum OperandPos { LEFT, RIGHT } protected Tag opcode; public OperatorSymbol operator; public OperatorSymbol getOperator() { return operator; } @Override public Tag getTag() { return opcode; } public abstract JCExpression getOperand(OperandPos pos); } /** * An assignment with "+=", "|=" ... */ public static class JCAssignOp extends JCOperatorExpression implements CompoundAssignmentTree { public JCExpression lhs; public JCExpression rhs; protected JCAssignOp(Tag opcode, JCTree lhs, JCTree rhs, OperatorSymbol operator) { this.opcode = opcode; this.lhs = (JCExpression)lhs; this.rhs = (JCExpression)rhs; this.operator = operator; } @Override public void accept(Visitor v) { v.visitAssignop(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return TreeInfo.tagToKind(getTag()); } @DefinedBy(Api.COMPILER_TREE) public JCExpression getVariable() { return lhs; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return rhs; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitCompoundAssignment(this, d); } @Override public JCExpression getOperand(OperandPos pos) { return pos == OperandPos.LEFT ? lhs : rhs; } } /** * A unary operation. */ public static class JCUnary extends JCOperatorExpression implements UnaryTree { public JCExpression arg; protected JCUnary(Tag opcode, JCExpression arg) { this.opcode = opcode; this.arg = arg; } @Override public void accept(Visitor v) { v.visitUnary(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return TreeInfo.tagToKind(getTag()); } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return arg; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitUnary(this, d); } public void setTag(Tag tag) { opcode = tag; } @Override public JCExpression getOperand(OperandPos pos) { return arg; } } /** * A binary operation. */ public static class JCBinary extends JCOperatorExpression implements BinaryTree { public JCExpression lhs; public JCExpression rhs; protected JCBinary(Tag opcode, JCExpression lhs, JCExpression rhs, OperatorSymbol operator) { this.opcode = opcode; this.lhs = lhs; this.rhs = rhs; this.operator = operator; } @Override public void accept(Visitor v) { v.visitBinary(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return TreeInfo.tagToKind(getTag()); } @DefinedBy(Api.COMPILER_TREE) public JCExpression getLeftOperand() { return lhs; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getRightOperand() { return rhs; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitBinary(this, d); } @Override public JCExpression getOperand(OperandPos pos) { return pos == OperandPos.LEFT ? lhs : rhs; } } /** * A type cast. */ public static class JCTypeCast extends JCExpression implements TypeCastTree { public JCTree clazz; public JCExpression expr; protected JCTypeCast(JCTree clazz, JCExpression expr) { this.clazz = clazz; this.expr = expr; } @Override public void accept(Visitor v) { v.visitTypeCast(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.TYPE_CAST; } @DefinedBy(Api.COMPILER_TREE) public JCTree getType() { return clazz; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return expr; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitTypeCast(this, d); } @Override public Tag getTag() { return TYPECAST; } } /** * A type test. */ public static class JCInstanceOf extends JCExpression implements InstanceOfTree { public JCExpression expr; public JCTree clazz; protected JCInstanceOf(JCExpression expr, JCTree clazz) { this.expr = expr; this.clazz = clazz; } @Override public void accept(Visitor v) { v.visitTypeTest(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.INSTANCE_OF; } @DefinedBy(Api.COMPILER_TREE) public JCTree getType() { return clazz; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return expr; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitInstanceOf(this, d); } @Override public Tag getTag() { return TYPETEST; } } /** * An array selection */ public static class JCArrayAccess extends JCExpression implements ArrayAccessTree { public JCExpression indexed; public JCExpression index; protected JCArrayAccess(JCExpression indexed, JCExpression index) { this.indexed = indexed; this.index = index; } @Override public void accept(Visitor v) { v.visitIndexed(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.ARRAY_ACCESS; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return indexed; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getIndex() { return index; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitArrayAccess(this, d); } @Override public Tag getTag() { return INDEXED; } } /** * Selects through packages and classes */ public static class JCFieldAccess extends JCExpression implements MemberSelectTree { /** selected Tree hierarchy */ public JCExpression selected; /** name of field to select thru */ public Name name; /** symbol of the selected class */ public Symbol sym; protected JCFieldAccess(JCExpression selected, Name name, Symbol sym) { this.selected = selected; this.name = name; this.sym = sym; } @Override public void accept(Visitor v) { v.visitSelect(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.MEMBER_SELECT; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getExpression() { return selected; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitMemberSelect(this, d); } @DefinedBy(Api.COMPILER_TREE) public Name getIdentifier() { return name; } @Override public Tag getTag() { return SELECT; } } /** * Selects a member expression. */ public static class JCMemberReference extends JCFunctionalExpression implements MemberReferenceTree { public ReferenceMode mode; public ReferenceKind kind; public Name name; public JCExpression expr; public List typeargs; public Symbol sym; public Type varargsElement; public PolyKind refPolyKind; public boolean ownerAccessible; private OverloadKind overloadKind; public Type referentType; public enum OverloadKind { OVERLOADED, UNOVERLOADED } /** * Javac-dependent classification for member references, based * on relevant properties w.r.t. code-generation */ public enum ReferenceKind { /** super # instMethod */ SUPER(ReferenceMode.INVOKE, false), /** Type # instMethod */ UNBOUND(ReferenceMode.INVOKE, true), /** Type # staticMethod */ STATIC(ReferenceMode.INVOKE, false), /** Expr # instMethod */ BOUND(ReferenceMode.INVOKE, false), /** Inner # new */ IMPLICIT_INNER(ReferenceMode.NEW, false), /** Toplevel # new */ TOPLEVEL(ReferenceMode.NEW, false), /** ArrayType # new */ ARRAY_CTOR(ReferenceMode.NEW, false); final ReferenceMode mode; final boolean unbound; private ReferenceKind(ReferenceMode mode, boolean unbound) { this.mode = mode; this.unbound = unbound; } public boolean isUnbound() { return unbound; } } public JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List typeargs) { this.mode = mode; this.name = name; this.expr = expr; this.typeargs = typeargs; } @Override public void accept(Visitor v) { v.visitReference(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.MEMBER_REFERENCE; } @Override @DefinedBy(Api.COMPILER_TREE) public ReferenceMode getMode() { return mode; } @Override @DefinedBy(Api.COMPILER_TREE) public JCExpression getQualifierExpression() { return expr; } @Override @DefinedBy(Api.COMPILER_TREE) public Name getName() { return name; } @Override @DefinedBy(Api.COMPILER_TREE) public List getTypeArguments() { return typeargs; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitMemberReference(this, d); } @Override public Tag getTag() { return REFERENCE; } public boolean hasKind(ReferenceKind kind) { return this.kind == kind; } /** * @return the overloadKind */ public OverloadKind getOverloadKind() { return overloadKind; } /** * @param overloadKind the overloadKind to set */ public void setOverloadKind(OverloadKind overloadKind) { this.overloadKind = overloadKind; } } /** * An identifier */ public static class JCIdent extends JCExpression implements IdentifierTree { /** the name */ public Name name; /** the symbol */ public Symbol sym; protected JCIdent(Name name, Symbol sym) { this.name = name; this.sym = sym; } @Override public void accept(Visitor v) { v.visitIdent(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.IDENTIFIER; } @DefinedBy(Api.COMPILER_TREE) public Name getName() { return name; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitIdentifier(this, d); } @Override public Tag getTag() { return IDENT; } } /** * A constant value given literally. */ public static class JCLiteral extends JCExpression implements LiteralTree { public TypeTag typetag; /** value representation */ public Object value; protected JCLiteral(TypeTag typetag, Object value) { this.typetag = typetag; this.value = value; } @Override public void accept(Visitor v) { v.visitLiteral(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return typetag.getKindLiteral(); } @DefinedBy(Api.COMPILER_TREE) public Object getValue() { switch (typetag) { case BOOLEAN: int bi = (Integer) value; return (bi != 0); case CHAR: int ci = (Integer) value; char c = (char) ci; if (c != ci) throw new AssertionError("bad value for char literal"); return c; default: return value; } } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitLiteral(this, d); } @Override public JCLiteral setType(Type type) { super.setType(type); return this; } @Override public Tag getTag() { return LITERAL; } } /** * Identifies a basic type. * @see TypeTag */ public static class JCPrimitiveTypeTree extends JCExpression implements PrimitiveTypeTree { /** the basic type id */ public TypeTag typetag; protected JCPrimitiveTypeTree(TypeTag typetag) { this.typetag = typetag; } @Override public void accept(Visitor v) { v.visitTypeIdent(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.PRIMITIVE_TYPE; } @DefinedBy(Api.COMPILER_TREE) public TypeKind getPrimitiveTypeKind() { return typetag.getPrimitiveTypeKind(); } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitPrimitiveType(this, d); } @Override public Tag getTag() { return TYPEIDENT; } } /** * An array type, A[] */ public static class JCArrayTypeTree extends JCExpression implements ArrayTypeTree { public JCExpression elemtype; protected JCArrayTypeTree(JCExpression elemtype) { this.elemtype = elemtype; } @Override public void accept(Visitor v) { v.visitTypeArray(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.ARRAY_TYPE; } @DefinedBy(Api.COMPILER_TREE) public JCTree getType() { return elemtype; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitArrayType(this, d); } @Override public Tag getTag() { return TYPEARRAY; } } /** * A parameterized type, {@literal T<...>} */ public static class JCTypeApply extends JCExpression implements ParameterizedTypeTree { public JCExpression clazz; public List arguments; protected JCTypeApply(JCExpression clazz, List arguments) { this.clazz = clazz; this.arguments = arguments; } @Override public void accept(Visitor v) { v.visitTypeApply(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.PARAMETERIZED_TYPE; } @DefinedBy(Api.COMPILER_TREE) public JCTree getType() { return clazz; } @DefinedBy(Api.COMPILER_TREE) public List getTypeArguments() { return arguments; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitParameterizedType(this, d); } @Override public Tag getTag() { return TYPEAPPLY; } } /** * A union type, T1 | T2 | ... Tn (used in multicatch statements) */ public static class JCTypeUnion extends JCExpression implements UnionTypeTree { public List alternatives; protected JCTypeUnion(List components) { this.alternatives = components; } @Override public void accept(Visitor v) { v.visitTypeUnion(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.UNION_TYPE; } @DefinedBy(Api.COMPILER_TREE) public List getTypeAlternatives() { return alternatives; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitUnionType(this, d); } @Override public Tag getTag() { return TYPEUNION; } } /** * An intersection type, {@code T1 & T2 & ... Tn} (used in cast expressions) */ public static class JCTypeIntersection extends JCExpression implements IntersectionTypeTree { public List bounds; protected JCTypeIntersection(List bounds) { this.bounds = bounds; } @Override public void accept(Visitor v) { v.visitTypeIntersection(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.INTERSECTION_TYPE; } @DefinedBy(Api.COMPILER_TREE) public List getBounds() { return bounds; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitIntersectionType(this, d); } @Override public Tag getTag() { return TYPEINTERSECTION; } } /** * A formal class parameter. */ public static class JCTypeParameter extends JCTree implements TypeParameterTree { /** name */ public Name name; /** bounds */ public List bounds; /** type annotations on type parameter */ public List annotations; protected JCTypeParameter(Name name, List bounds, List annotations) { this.name = name; this.bounds = bounds; this.annotations = annotations; } @Override public void accept(Visitor v) { v.visitTypeParameter(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.TYPE_PARAMETER; } @DefinedBy(Api.COMPILER_TREE) public Name getName() { return name; } @DefinedBy(Api.COMPILER_TREE) public List getBounds() { return bounds; } @DefinedBy(Api.COMPILER_TREE) public List getAnnotations() { return annotations; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitTypeParameter(this, d); } @Override public Tag getTag() { return TYPEPARAMETER; } } public static class JCWildcard extends JCExpression implements WildcardTree { public TypeBoundKind kind; public JCTree inner; protected JCWildcard(TypeBoundKind kind, JCTree inner) { this.kind = Assert.checkNonNull(kind); this.inner = inner; } @Override public void accept(Visitor v) { v.visitWildcard(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { switch (kind.kind) { case UNBOUND: return Kind.UNBOUNDED_WILDCARD; case EXTENDS: return Kind.EXTENDS_WILDCARD; case SUPER: return Kind.SUPER_WILDCARD; default: throw new AssertionError("Unknown wildcard bound " + kind); } } @DefinedBy(Api.COMPILER_TREE) public JCTree getBound() { return inner; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitWildcard(this, d); } @Override public Tag getTag() { return Tag.WILDCARD; } } public static class TypeBoundKind extends JCTree { public BoundKind kind; protected TypeBoundKind(BoundKind kind) { this.kind = kind; } @Override public void accept(Visitor v) { v.visitTypeBoundKind(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { throw new AssertionError("TypeBoundKind is not part of a public API"); } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { throw new AssertionError("TypeBoundKind is not part of a public API"); } @Override public Tag getTag() { return TYPEBOUNDKIND; } } public static class JCAnnotation extends JCExpression implements AnnotationTree { // Either Tag.ANNOTATION or Tag.TYPE_ANNOTATION private Tag tag; public JCTree annotationType; public List args; public Attribute.Compound attribute; protected JCAnnotation(Tag tag, JCTree annotationType, List args) { this.tag = tag; this.annotationType = annotationType; this.args = args; } @Override public void accept(Visitor v) { v.visitAnnotation(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return TreeInfo.tagToKind(getTag()); } @DefinedBy(Api.COMPILER_TREE) public JCTree getAnnotationType() { return annotationType; } @DefinedBy(Api.COMPILER_TREE) public List getArguments() { return args; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitAnnotation(this, d); } @Override public Tag getTag() { return tag; } } public static class JCModifiers extends JCTree implements com.sun.source.tree.ModifiersTree { public long flags; public List annotations; protected JCModifiers(long flags, List annotations) { this.flags = flags; this.annotations = annotations; } @Override public void accept(Visitor v) { v.visitModifiers(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.MODIFIERS; } @DefinedBy(Api.COMPILER_TREE) public Set getFlags() { return Flags.asModifierSet(flags); } @DefinedBy(Api.COMPILER_TREE) public List getAnnotations() { return annotations; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitModifiers(this, d); } @Override public Tag getTag() { return MODIFIERS; } } public static class JCAnnotatedType extends JCExpression implements com.sun.source.tree.AnnotatedTypeTree { // type annotations public List annotations; public JCExpression underlyingType; protected JCAnnotatedType(List annotations, JCExpression underlyingType) { Assert.check(annotations != null && annotations.nonEmpty()); this.annotations = annotations; this.underlyingType = underlyingType; } @Override public void accept(Visitor v) { v.visitAnnotatedType(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.ANNOTATED_TYPE; } @DefinedBy(Api.COMPILER_TREE) public List getAnnotations() { return annotations; } @DefinedBy(Api.COMPILER_TREE) public JCExpression getUnderlyingType() { return underlyingType; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitAnnotatedType(this, d); } @Override public Tag getTag() { return ANNOTATED_TYPE; } } public static abstract class JCDirective extends JCTree implements DirectiveTree { } public static class JCModuleDecl extends JCTree implements ModuleTree { public JCModifiers mods; public ModuleType type; private final ModuleKind kind; public JCExpression qualId; public List directives; public ModuleSymbol sym; protected JCModuleDecl(JCModifiers mods, ModuleKind kind, JCExpression qualId, List directives) { this.mods = mods; this.kind = kind; this.qualId = qualId; this.directives = directives; } @Override public void accept(Visitor v) { v.visitModuleDef(this); } @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.MODULE; } @Override @DefinedBy(Api.COMPILER_TREE) public List getAnnotations() { return mods.annotations; } @Override @DefinedBy(Api.COMPILER_TREE) public ModuleKind getModuleType() { return kind; } @Override @DefinedBy(Api.COMPILER_TREE) public JCExpression getName() { return qualId; } @Override @DefinedBy(Api.COMPILER_TREE) public List getDirectives() { return directives; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitModule(this, d); } @Override public Tag getTag() { return MODULEDEF; } } public static class JCExports extends JCDirective implements ExportsTree { public JCExpression qualid; public List moduleNames; public ExportsDirective directive; protected JCExports(JCExpression qualId, List moduleNames) { this.qualid = qualId; this.moduleNames = moduleNames; } @Override public void accept(Visitor v) { v.visitExports(this); } @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.EXPORTS; } @Override @DefinedBy(Api.COMPILER_TREE) public JCExpression getPackageName() { return qualid; } @Override @DefinedBy(Api.COMPILER_TREE) public List getModuleNames() { return moduleNames; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitExports(this, d); } @Override public Tag getTag() { return Tag.EXPORTS; } } public static class JCOpens extends JCDirective implements OpensTree { public JCExpression qualid; public List moduleNames; public OpensDirective directive; protected JCOpens(JCExpression qualId, List moduleNames) { this.qualid = qualId; this.moduleNames = moduleNames; } @Override public void accept(Visitor v) { v.visitOpens(this); } @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.OPENS; } @Override @DefinedBy(Api.COMPILER_TREE) public JCExpression getPackageName() { return qualid; } @Override @DefinedBy(Api.COMPILER_TREE) public List getModuleNames() { return moduleNames; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitOpens(this, d); } @Override public Tag getTag() { return Tag.OPENS; } } public static class JCProvides extends JCDirective implements ProvidesTree { public JCExpression serviceName; public List implNames; protected JCProvides(JCExpression serviceName, List implNames) { this.serviceName = serviceName; this.implNames = implNames; } @Override public void accept(Visitor v) { v.visitProvides(this); } @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.PROVIDES; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitProvides(this, d); } @Override @DefinedBy(Api.COMPILER_TREE) public JCExpression getServiceName() { return serviceName; } @Override @DefinedBy(Api.COMPILER_TREE) public List getImplementationNames() { return implNames; } @Override public Tag getTag() { return PROVIDES; } } public static class JCRequires extends JCDirective implements RequiresTree { public boolean isTransitive; public boolean isStaticPhase; public JCExpression moduleName; public RequiresDirective directive; protected JCRequires(boolean isTransitive, boolean isStaticPhase, JCExpression moduleName) { this.isTransitive = isTransitive; this.isStaticPhase = isStaticPhase; this.moduleName = moduleName; } @Override public void accept(Visitor v) { v.visitRequires(this); } @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.REQUIRES; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitRequires(this, d); } @Override @DefinedBy(Api.COMPILER_TREE) public boolean isTransitive() { return isTransitive; } @Override @DefinedBy(Api.COMPILER_TREE) public boolean isStatic() { return isStaticPhase; } @Override @DefinedBy(Api.COMPILER_TREE) public JCExpression getModuleName() { return moduleName; } @Override public Tag getTag() { return REQUIRES; } } public static class JCUses extends JCDirective implements UsesTree { public JCExpression qualid; protected JCUses(JCExpression qualId) { this.qualid = qualId; } @Override public void accept(Visitor v) { v.visitUses(this); } @Override @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.USES; } @Override @DefinedBy(Api.COMPILER_TREE) public JCExpression getServiceName() { return qualid; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitUses(this, d); } @Override public Tag getTag() { return USES; } } public static class JCErroneous extends JCExpression implements ErroneousTree { public List errs; protected JCErroneous(List errs) { this.errs = errs; } @Override public void accept(Visitor v) { v.visitErroneous(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { return Kind.ERRONEOUS; } @DefinedBy(Api.COMPILER_TREE) public List getErrorTrees() { return errs; } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { return v.visitErroneous(this, d); } @Override public Tag getTag() { return ERRONEOUS; } } /** (let int x = 3; in x+2) */ public static class LetExpr extends JCExpression { public List defs; public JCExpression expr; protected LetExpr(List defs, JCExpression expr) { this.defs = defs; this.expr = expr; } @Override public void accept(Visitor v) { v.visitLetExpr(this); } @DefinedBy(Api.COMPILER_TREE) public Kind getKind() { throw new AssertionError("LetExpr is not part of a public API"); } @Override @DefinedBy(Api.COMPILER_TREE) public R accept(TreeVisitor v, D d) { throw new AssertionError("LetExpr is not part of a public API"); } @Override public Tag getTag() { return LETEXPR; } } /** An interface for tree factories */ public interface Factory { JCCompilationUnit TopLevel(List defs); JCPackageDecl PackageDecl(List annotations, JCExpression pid); JCImport Import(JCTree qualid, boolean staticImport); JCClassDecl ClassDef(JCModifiers mods, Name name, List typarams, JCExpression extending, List implementing, List defs); JCMethodDecl MethodDef(JCModifiers mods, Name name, JCExpression restype, List typarams, JCVariableDecl recvparam, List params, List thrown, JCBlock body, JCExpression defaultValue); JCVariableDecl VarDef(JCModifiers mods, Name name, JCExpression vartype, JCExpression init); JCSkip Skip(); JCBlock Block(long flags, List stats); JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond); JCWhileLoop WhileLoop(JCExpression cond, JCStatement body); JCForLoop ForLoop(List init, JCExpression cond, List step, JCStatement body); JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body); JCLabeledStatement Labelled(Name label, JCStatement body); JCSwitch Switch(JCExpression selector, List cases); JCSwitchExpression SwitchExpression(JCExpression selector, List cases); JCCase Case(@SuppressWarnings("removal") CaseKind caseKind, List pat, List stats, JCTree body); JCSynchronized Synchronized(JCExpression lock, JCBlock body); JCTry Try(JCBlock body, List catchers, JCBlock finalizer); JCTry Try(List resources, JCBlock body, List catchers, JCBlock finalizer); JCCatch Catch(JCVariableDecl param, JCBlock body); JCConditional Conditional(JCExpression cond, JCExpression thenpart, JCExpression elsepart); JCIf If(JCExpression cond, JCStatement thenpart, JCStatement elsepart); JCExpressionStatement Exec(JCExpression expr); JCBreak Break(JCExpression value); JCContinue Continue(Name label); JCReturn Return(JCExpression expr); JCThrow Throw(JCExpression expr); JCAssert Assert(JCExpression cond, JCExpression detail); JCMethodInvocation Apply(List typeargs, JCExpression fn, List args); JCNewClass NewClass(JCExpression encl, List typeargs, JCExpression clazz, List args, JCClassDecl def); JCNewArray NewArray(JCExpression elemtype, List dims, List elems); JCParens Parens(JCExpression expr); JCAssign Assign(JCExpression lhs, JCExpression rhs); JCAssignOp Assignop(Tag opcode, JCTree lhs, JCTree rhs); JCUnary Unary(Tag opcode, JCExpression arg); JCBinary Binary(Tag opcode, JCExpression lhs, JCExpression rhs); JCTypeCast TypeCast(JCTree expr, JCExpression type); JCInstanceOf TypeTest(JCExpression expr, JCTree clazz); JCArrayAccess Indexed(JCExpression indexed, JCExpression index); JCFieldAccess Select(JCExpression selected, Name selector); JCIdent Ident(Name idname); JCLiteral Literal(TypeTag tag, Object value); JCPrimitiveTypeTree TypeIdent(TypeTag typetag); JCArrayTypeTree TypeArray(JCExpression elemtype); JCTypeApply TypeApply(JCExpression clazz, List arguments); JCTypeParameter TypeParameter(Name name, List bounds); JCWildcard Wildcard(TypeBoundKind kind, JCTree type); TypeBoundKind TypeBoundKind(BoundKind kind); JCAnnotation Annotation(JCTree annotationType, List args); JCModifiers Modifiers(long flags, List annotations); JCErroneous Erroneous(List errs); JCModuleDecl ModuleDef(JCModifiers mods, ModuleKind kind, JCExpression qualId, List directives); JCExports Exports(JCExpression qualId, List moduleNames); JCOpens Opens(JCExpression qualId, List moduleNames); JCProvides Provides(JCExpression serviceName, List implNames); JCRequires Requires(boolean isTransitive, boolean isStaticPhase, JCExpression qualId); JCUses Uses(JCExpression qualId); LetExpr LetExpr(List defs, JCExpression expr); } /** A generic visitor class for trees. */ public static abstract class Visitor { public void visitTopLevel(JCCompilationUnit that) { visitTree(that); } public void visitPackageDef(JCPackageDecl that) { visitTree(that); } public void visitImport(JCImport that) { visitTree(that); } public void visitClassDef(JCClassDecl that) { visitTree(that); } public void visitMethodDef(JCMethodDecl that) { visitTree(that); } public void visitVarDef(JCVariableDecl that) { visitTree(that); } public void visitSkip(JCSkip that) { visitTree(that); } public void visitBlock(JCBlock that) { visitTree(that); } public void visitDoLoop(JCDoWhileLoop that) { visitTree(that); } public void visitWhileLoop(JCWhileLoop that) { visitTree(that); } public void visitForLoop(JCForLoop that) { visitTree(that); } public void visitForeachLoop(JCEnhancedForLoop that) { visitTree(that); } public void visitLabelled(JCLabeledStatement that) { visitTree(that); } public void visitSwitch(JCSwitch that) { visitTree(that); } public void visitCase(JCCase that) { visitTree(that); } public void visitSwitchExpression(JCSwitchExpression that) { visitTree(that); } public void visitSynchronized(JCSynchronized that) { visitTree(that); } public void visitTry(JCTry that) { visitTree(that); } public void visitCatch(JCCatch that) { visitTree(that); } public void visitConditional(JCConditional that) { visitTree(that); } public void visitIf(JCIf that) { visitTree(that); } public void visitExec(JCExpressionStatement that) { visitTree(that); } public void visitBreak(JCBreak that) { visitTree(that); } public void visitContinue(JCContinue that) { visitTree(that); } public void visitReturn(JCReturn that) { visitTree(that); } public void visitThrow(JCThrow that) { visitTree(that); } public void visitAssert(JCAssert that) { visitTree(that); } public void visitApply(JCMethodInvocation that) { visitTree(that); } public void visitNewClass(JCNewClass that) { visitTree(that); } public void visitNewArray(JCNewArray that) { visitTree(that); } public void visitLambda(JCLambda that) { visitTree(that); } public void visitParens(JCParens that) { visitTree(that); } public void visitAssign(JCAssign that) { visitTree(that); } public void visitAssignop(JCAssignOp that) { visitTree(that); } public void visitUnary(JCUnary that) { visitTree(that); } public void visitBinary(JCBinary that) { visitTree(that); } public void visitTypeCast(JCTypeCast that) { visitTree(that); } public void visitTypeTest(JCInstanceOf that) { visitTree(that); } public void visitIndexed(JCArrayAccess that) { visitTree(that); } public void visitSelect(JCFieldAccess that) { visitTree(that); } public void visitReference(JCMemberReference that) { visitTree(that); } public void visitIdent(JCIdent that) { visitTree(that); } public void visitLiteral(JCLiteral that) { visitTree(that); } public void visitTypeIdent(JCPrimitiveTypeTree that) { visitTree(that); } public void visitTypeArray(JCArrayTypeTree that) { visitTree(that); } public void visitTypeApply(JCTypeApply that) { visitTree(that); } public void visitTypeUnion(JCTypeUnion that) { visitTree(that); } public void visitTypeIntersection(JCTypeIntersection that) { visitTree(that); } public void visitTypeParameter(JCTypeParameter that) { visitTree(that); } public void visitWildcard(JCWildcard that) { visitTree(that); } public void visitTypeBoundKind(TypeBoundKind that) { visitTree(that); } public void visitAnnotation(JCAnnotation that) { visitTree(that); } public void visitModifiers(JCModifiers that) { visitTree(that); } public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); } public void visitErroneous(JCErroneous that) { visitTree(that); } public void visitModuleDef(JCModuleDecl that) { visitTree(that); } public void visitExports(JCExports that) { visitTree(that); } public void visitOpens(JCOpens that) { visitTree(that); } public void visitProvides(JCProvides that) { visitTree(that); } public void visitRequires(JCRequires that) { visitTree(that); } public void visitUses(JCUses that) { visitTree(that); } public void visitLetExpr(LetExpr that) { visitTree(that); } public void visitTree(JCTree that) { Assert.error(); } } }