2592 lines
84 KiB
Java
2592 lines
84 KiB
Java
/*
|
|
* Copyright (c) 1999, 2013, 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.source.tree.LambdaExpressionTree.BodyKind;
|
|
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
|
|
import com.sun.tools.javac.code.*;
|
|
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.JCDiagnostic.DiagnosticPosition;
|
|
import com.sun.tools.javac.util.List;
|
|
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
|
|
|
/**
|
|
* Root class for abstract syntax tree nodes. It provides definitions
|
|
* for specific tree nodes as subclasses nested inside.
|
|
*
|
|
* <p>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.
|
|
*
|
|
* <p>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.
|
|
*
|
|
* <p>To avoid ambiguities with the Tree API in com.sun.source all sub
|
|
* classes should, by convention, start with JC (javac).
|
|
*
|
|
* <p><b>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.</b>
|
|
*
|
|
* @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,
|
|
|
|
/** 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, of type Case.
|
|
*/
|
|
CASE,
|
|
|
|
/** 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), // %=
|
|
|
|
/** 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);
|
|
|
|
public abstract <R,D> R accept(TreeVisitor<R,D> 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 {
|
|
public List<JCAnnotation> packageAnnotations;
|
|
/** The tree representing the package clause. */
|
|
public JCExpression pid;
|
|
/** All definitions in this file (ClassDef, Import, and Skip) */
|
|
public List<JCTree> defs;
|
|
/* The source file name. */
|
|
public JavaFileObject sourcefile;
|
|
/** The package to which this compilation unit belongs. */
|
|
public PackageSymbol packge;
|
|
/** A scope for all named imports. */
|
|
public ImportScope 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<JCAnnotation> packageAnnotations,
|
|
JCExpression pid,
|
|
List<JCTree> defs,
|
|
JavaFileObject sourcefile,
|
|
PackageSymbol packge,
|
|
ImportScope namedImportScope,
|
|
StarImportScope starImportScope) {
|
|
this.packageAnnotations = packageAnnotations;
|
|
this.pid = pid;
|
|
this.defs = defs;
|
|
this.sourcefile = sourcefile;
|
|
this.packge = packge;
|
|
this.namedImportScope = namedImportScope;
|
|
this.starImportScope = starImportScope;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitTopLevel(this); }
|
|
|
|
public Kind getKind() { return Kind.COMPILATION_UNIT; }
|
|
public List<JCAnnotation> getPackageAnnotations() {
|
|
return packageAnnotations;
|
|
}
|
|
public List<JCImport> getImports() {
|
|
ListBuffer<JCImport> imports = new ListBuffer<JCImport>();
|
|
for (JCTree tree : defs) {
|
|
if (tree.hasTag(IMPORT))
|
|
imports.append((JCImport)tree);
|
|
else if (!tree.hasTag(SKIP))
|
|
break;
|
|
}
|
|
return imports.toList();
|
|
}
|
|
public JCExpression getPackageName() { return pid; }
|
|
public JavaFileObject getSourceFile() {
|
|
return sourcefile;
|
|
}
|
|
public Position.LineMap getLineMap() {
|
|
return lineMap;
|
|
}
|
|
public List<JCTree> getTypeDecls() {
|
|
List<JCTree> typeDefs;
|
|
for (typeDefs = defs; !typeDefs.isEmpty(); typeDefs = typeDefs.tail)
|
|
if (!typeDefs.head.hasTag(IMPORT))
|
|
break;
|
|
return typeDefs;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitCompilationUnit(this, d);
|
|
}
|
|
|
|
@Override
|
|
public Tag getTag() {
|
|
return TOPLEVEL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An import clause.
|
|
*/
|
|
public static class JCImport extends JCTree implements ImportTree {
|
|
public boolean staticImport;
|
|
/** The imported class(es). */
|
|
public JCTree qualid;
|
|
protected JCImport(JCTree qualid, boolean importStatic) {
|
|
this.qualid = qualid;
|
|
this.staticImport = importStatic;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitImport(this); }
|
|
|
|
public boolean isStatic() { return staticImport; }
|
|
public JCTree getQualifiedIdentifier() { return qualid; }
|
|
|
|
public Kind getKind() { return Kind.IMPORT; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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 List<Type> targets;
|
|
|
|
public Type getDescriptorType(Types types) {
|
|
return targets.nonEmpty() ? types.findDescriptorType(targets.head) : 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<JCTypeParameter> typarams;
|
|
/** the classes this class extends */
|
|
public JCExpression extending;
|
|
/** the interfaces implemented by this class */
|
|
public List<JCExpression> implementing;
|
|
/** all variables and methods defined in this class */
|
|
public List<JCTree> defs;
|
|
/** the symbol */
|
|
public ClassSymbol sym;
|
|
protected JCClassDecl(JCModifiers mods,
|
|
Name name,
|
|
List<JCTypeParameter> typarams,
|
|
JCExpression extending,
|
|
List<JCExpression> implementing,
|
|
List<JCTree> 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); }
|
|
|
|
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;
|
|
}
|
|
|
|
public JCModifiers getModifiers() { return mods; }
|
|
public Name getSimpleName() { return name; }
|
|
public List<JCTypeParameter> getTypeParameters() {
|
|
return typarams;
|
|
}
|
|
public JCExpression getExtendsClause() { return extending; }
|
|
public List<JCExpression> getImplementsClause() {
|
|
return implementing;
|
|
}
|
|
public List<JCTree> getMembers() {
|
|
return defs;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCTypeParameter> typarams;
|
|
/** receiver parameter */
|
|
public JCVariableDecl recvparam;
|
|
/** value parameters */
|
|
public List<JCVariableDecl> params;
|
|
/** exceptions thrown by this method */
|
|
public List<JCExpression> 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<JCTypeParameter> typarams,
|
|
JCVariableDecl recvparam,
|
|
List<JCVariableDecl> params,
|
|
List<JCExpression> 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.<JCTypeAnnotation>nil());
|
|
this.thrown = thrown;
|
|
this.body = body;
|
|
this.defaultValue = defaultValue;
|
|
this.sym = sym;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitMethodDef(this); }
|
|
|
|
public Kind getKind() { return Kind.METHOD; }
|
|
public JCModifiers getModifiers() { return mods; }
|
|
public Name getName() { return name; }
|
|
public JCTree getReturnType() { return restype; }
|
|
public List<JCTypeParameter> getTypeParameters() {
|
|
return typarams;
|
|
}
|
|
public List<JCVariableDecl> getParameters() {
|
|
return params;
|
|
}
|
|
public JCVariableDecl getReceiverParameter() { return recvparam; }
|
|
public List<JCExpression> getThrows() {
|
|
return thrown;
|
|
}
|
|
public JCBlock getBody() { return body; }
|
|
public JCTree getDefaultValue() { // for annotation types
|
|
return defaultValue;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void accept(Visitor v) { v.visitVarDef(this); }
|
|
|
|
public Kind getKind() { return Kind.VARIABLE; }
|
|
public JCModifiers getModifiers() { return mods; }
|
|
public Name getName() { return name; }
|
|
public JCExpression getNameExpression() { return nameexpr; }
|
|
public JCTree getType() { return vartype; }
|
|
public JCExpression getInitializer() {
|
|
return init;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.EMPTY_STATEMENT; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCStatement> stats;
|
|
/** Position of closing brace, optional. */
|
|
public int endpos = Position.NOPOS;
|
|
protected JCBlock(long flags, List<JCStatement> stats) {
|
|
this.stats = stats;
|
|
this.flags = flags;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitBlock(this); }
|
|
|
|
public Kind getKind() { return Kind.BLOCK; }
|
|
public List<JCStatement> getStatements() {
|
|
return stats;
|
|
}
|
|
public boolean isStatic() { return (flags & Flags.STATIC) != 0; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.DO_WHILE_LOOP; }
|
|
public JCExpression getCondition() { return cond; }
|
|
public JCStatement getStatement() { return body; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.WHILE_LOOP; }
|
|
public JCExpression getCondition() { return cond; }
|
|
public JCStatement getStatement() { return body; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCStatement> init;
|
|
public JCExpression cond;
|
|
public List<JCExpressionStatement> step;
|
|
public JCStatement body;
|
|
protected JCForLoop(List<JCStatement> init,
|
|
JCExpression cond,
|
|
List<JCExpressionStatement> update,
|
|
JCStatement body)
|
|
{
|
|
this.init = init;
|
|
this.cond = cond;
|
|
this.step = update;
|
|
this.body = body;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitForLoop(this); }
|
|
|
|
public Kind getKind() { return Kind.FOR_LOOP; }
|
|
public JCExpression getCondition() { return cond; }
|
|
public JCStatement getStatement() { return body; }
|
|
public List<JCStatement> getInitializer() {
|
|
return init;
|
|
}
|
|
public List<JCExpressionStatement> getUpdate() {
|
|
return step;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.ENHANCED_FOR_LOOP; }
|
|
public JCVariableDecl getVariable() { return var; }
|
|
public JCExpression getExpression() { return expr; }
|
|
public JCStatement getStatement() { return body; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
public Kind getKind() { return Kind.LABELED_STATEMENT; }
|
|
public Name getLabel() { return label; }
|
|
public JCStatement getStatement() { return body; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCCase> cases;
|
|
protected JCSwitch(JCExpression selector, List<JCCase> cases) {
|
|
this.selector = selector;
|
|
this.cases = cases;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitSwitch(this); }
|
|
|
|
public Kind getKind() { return Kind.SWITCH; }
|
|
public JCExpression getExpression() { return selector; }
|
|
public List<JCCase> getCases() { return cases; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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 {
|
|
public JCExpression pat;
|
|
public List<JCStatement> stats;
|
|
protected JCCase(JCExpression pat, List<JCStatement> stats) {
|
|
this.pat = pat;
|
|
this.stats = stats;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitCase(this); }
|
|
|
|
public Kind getKind() { return Kind.CASE; }
|
|
public JCExpression getExpression() { return pat; }
|
|
public List<JCStatement> getStatements() { return stats; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitCase(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return CASE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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); }
|
|
|
|
public Kind getKind() { return Kind.SYNCHRONIZED; }
|
|
public JCExpression getExpression() { return lock; }
|
|
public JCBlock getBlock() { return body; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCCatch> catchers;
|
|
public JCBlock finalizer;
|
|
public List<JCTree> resources;
|
|
public boolean finallyCanCompleteNormally;
|
|
protected JCTry(List<JCTree> resources,
|
|
JCBlock body,
|
|
List<JCCatch> catchers,
|
|
JCBlock finalizer) {
|
|
this.body = body;
|
|
this.catchers = catchers;
|
|
this.finalizer = finalizer;
|
|
this.resources = resources;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitTry(this); }
|
|
|
|
public Kind getKind() { return Kind.TRY; }
|
|
public JCBlock getBlock() { return body; }
|
|
public List<JCCatch> getCatches() {
|
|
return catchers;
|
|
}
|
|
public JCBlock getFinallyBlock() { return finalizer; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitTry(this, d);
|
|
}
|
|
@Override
|
|
public List<JCTree> 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); }
|
|
|
|
public Kind getKind() { return Kind.CATCH; }
|
|
public JCVariableDecl getParameter() { return param; }
|
|
public JCBlock getBlock() { return body; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.CONDITIONAL_EXPRESSION; }
|
|
public JCExpression getCondition() { return cond; }
|
|
public JCExpression getTrueExpression() { return truepart; }
|
|
public JCExpression getFalseExpression() { return falsepart; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.IF; }
|
|
public JCExpression getCondition() { return cond; }
|
|
public JCStatement getThenStatement() { return thenpart; }
|
|
public JCStatement getElseStatement() { return elsepart; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.EXPRESSION_STATEMENT; }
|
|
public JCExpression getExpression() { return expr; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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 Name label;
|
|
public JCTree target;
|
|
protected JCBreak(Name label, JCTree target) {
|
|
this.label = label;
|
|
this.target = target;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitBreak(this); }
|
|
|
|
public Kind getKind() { return Kind.BREAK; }
|
|
public Name getLabel() { return label; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.CONTINUE; }
|
|
public Name getLabel() { return label; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.RETURN; }
|
|
public JCExpression getExpression() { return expr; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.THROW; }
|
|
public JCExpression getExpression() { return expr; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.ASSERT; }
|
|
public JCExpression getCondition() { return cond; }
|
|
public JCExpression getDetail() { return detail; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCExpression> typeargs;
|
|
public JCExpression meth;
|
|
public List<JCExpression> args;
|
|
public Type varargsElement;
|
|
protected JCMethodInvocation(List<JCExpression> typeargs,
|
|
JCExpression meth,
|
|
List<JCExpression> args)
|
|
{
|
|
this.typeargs = (typeargs == null) ? List.<JCExpression>nil()
|
|
: typeargs;
|
|
this.meth = meth;
|
|
this.args = args;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitApply(this); }
|
|
|
|
public Kind getKind() { return Kind.METHOD_INVOCATION; }
|
|
public List<JCExpression> getTypeArguments() {
|
|
return typeargs;
|
|
}
|
|
public JCExpression getMethodSelect() { return meth; }
|
|
public List<JCExpression> getArguments() {
|
|
return args;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCExpression> typeargs;
|
|
public JCExpression clazz;
|
|
public List<JCExpression> args;
|
|
public JCClassDecl def;
|
|
public Symbol constructor;
|
|
public Type varargsElement;
|
|
public Type constructorType;
|
|
protected JCNewClass(JCExpression encl,
|
|
List<JCExpression> typeargs,
|
|
JCExpression clazz,
|
|
List<JCExpression> args,
|
|
JCClassDecl def)
|
|
{
|
|
this.encl = encl;
|
|
this.typeargs = (typeargs == null) ? List.<JCExpression>nil()
|
|
: typeargs;
|
|
this.clazz = clazz;
|
|
this.args = args;
|
|
this.def = def;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitNewClass(this); }
|
|
|
|
public Kind getKind() { return Kind.NEW_CLASS; }
|
|
public JCExpression getEnclosingExpression() { // expr.new C< ... > ( ... )
|
|
return encl;
|
|
}
|
|
public List<JCExpression> getTypeArguments() {
|
|
return typeargs;
|
|
}
|
|
public JCExpression getIdentifier() { return clazz; }
|
|
public List<JCExpression> getArguments() {
|
|
return args;
|
|
}
|
|
public JCClassDecl getClassBody() { return def; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCExpression> dims;
|
|
// type annotations on inner-most component
|
|
public List<JCAnnotation> annotations;
|
|
// type annotations on dimensions
|
|
public List<List<JCAnnotation>> dimAnnotations;
|
|
public List<JCExpression> elems;
|
|
protected JCNewArray(JCExpression elemtype,
|
|
List<JCExpression> dims,
|
|
List<JCExpression> 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); }
|
|
|
|
public Kind getKind() { return Kind.NEW_ARRAY; }
|
|
public JCExpression getType() { return elemtype; }
|
|
public List<JCExpression> getDimensions() {
|
|
return dims;
|
|
}
|
|
public List<JCExpression> getInitializers() {
|
|
return elems;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitNewArray(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return NEWARRAY;
|
|
}
|
|
|
|
@Override
|
|
public List<JCAnnotation> getAnnotations() {
|
|
return annotations;
|
|
}
|
|
|
|
@Override
|
|
public List<List<JCAnnotation>> getDimAnnotations() {
|
|
return dimAnnotations;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A lambda expression.
|
|
*/
|
|
public static class JCLambda extends JCFunctionalExpression implements LambdaExpressionTree {
|
|
|
|
public enum ParameterKind {
|
|
IMPLICIT,
|
|
EXPLICIT;
|
|
}
|
|
|
|
public List<JCVariableDecl> params;
|
|
public JCTree body;
|
|
public boolean canCompleteNormally = true;
|
|
public ParameterKind paramKind;
|
|
|
|
public JCLambda(List<JCVariableDecl> 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
|
|
public <R, D> R accept(TreeVisitor<R, D> v, D d) {
|
|
return v.visitLambdaExpression(this, d);
|
|
}
|
|
public Kind getKind() {
|
|
return Kind.LAMBDA_EXPRESSION;
|
|
}
|
|
public JCTree getBody() {
|
|
return body;
|
|
}
|
|
public java.util.List<? extends VariableTree> getParameters() {
|
|
return params;
|
|
}
|
|
@Override
|
|
public JCLambda setType(Type type) {
|
|
super.setType(type);
|
|
return this;
|
|
}
|
|
@Override
|
|
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); }
|
|
|
|
public Kind getKind() { return Kind.PARENTHESIZED; }
|
|
public JCExpression getExpression() { return expr; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.ASSIGNMENT; }
|
|
public JCExpression getVariable() { return lhs; }
|
|
public JCExpression getExpression() { return rhs; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitAssignment(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return ASSIGN;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An assignment with "+=", "|=" ...
|
|
*/
|
|
public static class JCAssignOp extends JCExpression implements CompoundAssignmentTree {
|
|
private Tag opcode;
|
|
public JCExpression lhs;
|
|
public JCExpression rhs;
|
|
public Symbol operator;
|
|
protected JCAssignOp(Tag opcode, JCTree lhs, JCTree rhs, Symbol operator) {
|
|
this.opcode = opcode;
|
|
this.lhs = (JCExpression)lhs;
|
|
this.rhs = (JCExpression)rhs;
|
|
this.operator = operator;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitAssignop(this); }
|
|
|
|
public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
|
|
public JCExpression getVariable() { return lhs; }
|
|
public JCExpression getExpression() { return rhs; }
|
|
public Symbol getOperator() {
|
|
return operator;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitCompoundAssignment(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return opcode;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A unary operation.
|
|
*/
|
|
public static class JCUnary extends JCExpression implements UnaryTree {
|
|
private Tag opcode;
|
|
public JCExpression arg;
|
|
public Symbol operator;
|
|
protected JCUnary(Tag opcode, JCExpression arg) {
|
|
this.opcode = opcode;
|
|
this.arg = arg;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitUnary(this); }
|
|
|
|
public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
|
|
public JCExpression getExpression() { return arg; }
|
|
public Symbol getOperator() {
|
|
return operator;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitUnary(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return opcode;
|
|
}
|
|
|
|
public void setTag(Tag tag) {
|
|
opcode = tag;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A binary operation.
|
|
*/
|
|
public static class JCBinary extends JCExpression implements BinaryTree {
|
|
private Tag opcode;
|
|
public JCExpression lhs;
|
|
public JCExpression rhs;
|
|
public Symbol operator;
|
|
protected JCBinary(Tag opcode,
|
|
JCExpression lhs,
|
|
JCExpression rhs,
|
|
Symbol operator) {
|
|
this.opcode = opcode;
|
|
this.lhs = lhs;
|
|
this.rhs = rhs;
|
|
this.operator = operator;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitBinary(this); }
|
|
|
|
public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
|
|
public JCExpression getLeftOperand() { return lhs; }
|
|
public JCExpression getRightOperand() { return rhs; }
|
|
public Symbol getOperator() {
|
|
return operator;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitBinary(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return opcode;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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); }
|
|
|
|
public Kind getKind() { return Kind.TYPE_CAST; }
|
|
public JCTree getType() { return clazz; }
|
|
public JCExpression getExpression() { return expr; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.INSTANCE_OF; }
|
|
public JCTree getType() { return clazz; }
|
|
public JCExpression getExpression() { return expr; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.ARRAY_ACCESS; }
|
|
public JCExpression getExpression() { return indexed; }
|
|
public JCExpression getIndex() { return index; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.MEMBER_SELECT; }
|
|
public JCExpression getExpression() { return selected; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitMemberSelect(this, d);
|
|
}
|
|
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<JCExpression> typeargs;
|
|
public Symbol sym;
|
|
public Type varargsElement;
|
|
public PolyKind refPolyKind;
|
|
public boolean ownerAccessible;
|
|
public OverloadKind overloadKind;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
protected JCMemberReference(ReferenceMode mode, Name name, JCExpression expr, List<JCExpression> typeargs) {
|
|
this.mode = mode;
|
|
this.name = name;
|
|
this.expr = expr;
|
|
this.typeargs = typeargs;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitReference(this); }
|
|
|
|
public Kind getKind() { return Kind.MEMBER_REFERENCE; }
|
|
@Override
|
|
public ReferenceMode getMode() { return mode; }
|
|
@Override
|
|
public JCExpression getQualifierExpression() { return expr; }
|
|
@Override
|
|
public Name getName() { return name; }
|
|
@Override
|
|
public List<JCExpression> getTypeArguments() { return typeargs; }
|
|
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitMemberReference(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return REFERENCE;
|
|
}
|
|
public boolean hasKind(ReferenceKind kind) {
|
|
return this.kind == kind;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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); }
|
|
|
|
public Kind getKind() { return Kind.IDENTIFIER; }
|
|
public Name getName() { return name; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() {
|
|
return typetag.getKindLiteral();
|
|
}
|
|
|
|
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
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.PRIMITIVE_TYPE; }
|
|
public TypeKind getPrimitiveTypeKind() {
|
|
return typetag.getPrimitiveTypeKind();
|
|
}
|
|
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() { return Kind.ARRAY_TYPE; }
|
|
public JCTree getType() { return elemtype; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCExpression> arguments;
|
|
protected JCTypeApply(JCExpression clazz, List<JCExpression> arguments) {
|
|
this.clazz = clazz;
|
|
this.arguments = arguments;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitTypeApply(this); }
|
|
|
|
public Kind getKind() { return Kind.PARAMETERIZED_TYPE; }
|
|
public JCTree getType() { return clazz; }
|
|
public List<JCExpression> getTypeArguments() {
|
|
return arguments;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCExpression> alternatives;
|
|
|
|
protected JCTypeUnion(List<JCExpression> components) {
|
|
this.alternatives = components;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitTypeUnion(this); }
|
|
|
|
public Kind getKind() { return Kind.UNION_TYPE; }
|
|
|
|
public List<JCExpression> getTypeAlternatives() {
|
|
return alternatives;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitUnionType(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return TYPEUNION;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An intersection type, T1 & T2 & ... Tn (used in cast expressions)
|
|
*/
|
|
public static class JCTypeIntersection extends JCExpression implements IntersectionTypeTree {
|
|
|
|
public List<JCExpression> bounds;
|
|
|
|
protected JCTypeIntersection(List<JCExpression> bounds) {
|
|
this.bounds = bounds;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitTypeIntersection(this); }
|
|
|
|
public Kind getKind() { return Kind.INTERSECTION_TYPE; }
|
|
|
|
public List<JCExpression> getBounds() {
|
|
return bounds;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCExpression> bounds;
|
|
/** type annotations on type parameter */
|
|
public List<JCAnnotation> annotations;
|
|
protected JCTypeParameter(Name name, List<JCExpression> bounds, List<JCAnnotation> annotations) {
|
|
this.name = name;
|
|
this.bounds = bounds;
|
|
this.annotations = annotations;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitTypeParameter(this); }
|
|
|
|
public Kind getKind() { return Kind.TYPE_PARAMETER; }
|
|
public Name getName() { return name; }
|
|
public List<JCExpression> getBounds() {
|
|
return bounds;
|
|
}
|
|
public List<JCAnnotation> getAnnotations() {
|
|
return annotations;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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) {
|
|
kind.getClass(); // null-check
|
|
this.kind = kind;
|
|
this.inner = inner;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitWildcard(this); }
|
|
|
|
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);
|
|
}
|
|
}
|
|
public JCTree getBound() { return inner; }
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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); }
|
|
|
|
public Kind getKind() {
|
|
throw new AssertionError("TypeBoundKind is not part of a public API");
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCExpression> args;
|
|
|
|
// Attribute.Compound if tag is ANNOTATION
|
|
// Attribute.TypeCompound if tag is TYPE_ANNOTATION
|
|
public Attribute.Compound attribute;
|
|
|
|
protected JCAnnotation(Tag tag, JCTree annotationType, List<JCExpression> args) {
|
|
this.tag = tag;
|
|
this.annotationType = annotationType;
|
|
this.args = args;
|
|
}
|
|
|
|
@Override
|
|
public void accept(Visitor v) { v.visitAnnotation(this); }
|
|
|
|
public Kind getKind() { return TreeInfo.tagToKind(getTag()); }
|
|
|
|
public JCTree getAnnotationType() { return annotationType; }
|
|
public List<JCExpression> getArguments() {
|
|
return args;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCAnnotation> annotations;
|
|
protected JCModifiers(long flags, List<JCAnnotation> annotations) {
|
|
this.flags = flags;
|
|
this.annotations = annotations;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitModifiers(this); }
|
|
|
|
public Kind getKind() { return Kind.MODIFIERS; }
|
|
public Set<Modifier> getFlags() {
|
|
return Flags.asModifierSet(flags);
|
|
}
|
|
public List<JCAnnotation> getAnnotations() {
|
|
return annotations;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCAnnotation> annotations;
|
|
public JCExpression underlyingType;
|
|
|
|
protected JCAnnotatedType(List<JCAnnotation> annotations, JCExpression underlyingType) {
|
|
Assert.check(annotations != null && annotations.nonEmpty());
|
|
this.annotations = annotations;
|
|
this.underlyingType = underlyingType;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitAnnotatedType(this); }
|
|
|
|
public Kind getKind() { return Kind.ANNOTATED_TYPE; }
|
|
public List<JCAnnotation> getAnnotations() {
|
|
return annotations;
|
|
}
|
|
public JCExpression getUnderlyingType() {
|
|
return underlyingType;
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> v, D d) {
|
|
return v.visitAnnotatedType(this, d);
|
|
}
|
|
@Override
|
|
public Tag getTag() {
|
|
return ANNOTATED_TYPE;
|
|
}
|
|
}
|
|
|
|
public static class JCErroneous extends JCExpression
|
|
implements com.sun.source.tree.ErroneousTree {
|
|
public List<? extends JCTree> errs;
|
|
protected JCErroneous(List<? extends JCTree> errs) {
|
|
this.errs = errs;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitErroneous(this); }
|
|
|
|
public Kind getKind() { return Kind.ERRONEOUS; }
|
|
|
|
public List<? extends JCTree> getErrorTrees() {
|
|
return errs;
|
|
}
|
|
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCVariableDecl> defs;
|
|
public JCTree expr;
|
|
protected LetExpr(List<JCVariableDecl> defs, JCTree expr) {
|
|
this.defs = defs;
|
|
this.expr = expr;
|
|
}
|
|
@Override
|
|
public void accept(Visitor v) { v.visitLetExpr(this); }
|
|
|
|
public Kind getKind() {
|
|
throw new AssertionError("LetExpr is not part of a public API");
|
|
}
|
|
@Override
|
|
public <R,D> R accept(TreeVisitor<R,D> 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<JCAnnotation> packageAnnotations,
|
|
JCExpression pid,
|
|
List<JCTree> defs);
|
|
JCImport Import(JCTree qualid, boolean staticImport);
|
|
JCClassDecl ClassDef(JCModifiers mods,
|
|
Name name,
|
|
List<JCTypeParameter> typarams,
|
|
JCExpression extending,
|
|
List<JCExpression> implementing,
|
|
List<JCTree> defs);
|
|
JCMethodDecl MethodDef(JCModifiers mods,
|
|
Name name,
|
|
JCExpression restype,
|
|
List<JCTypeParameter> typarams,
|
|
JCVariableDecl recvparam,
|
|
List<JCVariableDecl> params,
|
|
List<JCExpression> thrown,
|
|
JCBlock body,
|
|
JCExpression defaultValue);
|
|
JCVariableDecl VarDef(JCModifiers mods,
|
|
Name name,
|
|
JCExpression vartype,
|
|
JCExpression init);
|
|
JCSkip Skip();
|
|
JCBlock Block(long flags, List<JCStatement> stats);
|
|
JCDoWhileLoop DoLoop(JCStatement body, JCExpression cond);
|
|
JCWhileLoop WhileLoop(JCExpression cond, JCStatement body);
|
|
JCForLoop ForLoop(List<JCStatement> init,
|
|
JCExpression cond,
|
|
List<JCExpressionStatement> step,
|
|
JCStatement body);
|
|
JCEnhancedForLoop ForeachLoop(JCVariableDecl var, JCExpression expr, JCStatement body);
|
|
JCLabeledStatement Labelled(Name label, JCStatement body);
|
|
JCSwitch Switch(JCExpression selector, List<JCCase> cases);
|
|
JCCase Case(JCExpression pat, List<JCStatement> stats);
|
|
JCSynchronized Synchronized(JCExpression lock, JCBlock body);
|
|
JCTry Try(JCBlock body, List<JCCatch> catchers, JCBlock finalizer);
|
|
JCTry Try(List<JCTree> resources,
|
|
JCBlock body,
|
|
List<JCCatch> 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(Name label);
|
|
JCContinue Continue(Name label);
|
|
JCReturn Return(JCExpression expr);
|
|
JCThrow Throw(JCExpression expr);
|
|
JCAssert Assert(JCExpression cond, JCExpression detail);
|
|
JCMethodInvocation Apply(List<JCExpression> typeargs,
|
|
JCExpression fn,
|
|
List<JCExpression> args);
|
|
JCNewClass NewClass(JCExpression encl,
|
|
List<JCExpression> typeargs,
|
|
JCExpression clazz,
|
|
List<JCExpression> args,
|
|
JCClassDecl def);
|
|
JCNewArray NewArray(JCExpression elemtype,
|
|
List<JCExpression> dims,
|
|
List<JCExpression> 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<JCExpression> arguments);
|
|
JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds);
|
|
JCWildcard Wildcard(TypeBoundKind kind, JCTree type);
|
|
TypeBoundKind TypeBoundKind(BoundKind kind);
|
|
JCAnnotation Annotation(JCTree annotationType, List<JCExpression> args);
|
|
JCModifiers Modifiers(long flags, List<JCAnnotation> annotations);
|
|
JCErroneous Erroneous(List<? extends JCTree> errs);
|
|
LetExpr LetExpr(List<JCVariableDecl> defs, JCTree expr);
|
|
}
|
|
|
|
/** A generic visitor class for trees.
|
|
*/
|
|
public static abstract class Visitor {
|
|
public void visitTopLevel(JCCompilationUnit 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 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 visitLetExpr(LetExpr that) { visitTree(that); }
|
|
|
|
public void visitTree(JCTree that) { Assert.error(); }
|
|
}
|
|
|
|
}
|