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

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

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

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

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