org.checkerframework.dataflow.cfg.UnderlyingAST Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dataflow-shaded Show documentation
Show all versions of dataflow-shaded Show documentation
dataflow-shaded is a dataflow framework based on the javac compiler.
It differs from the org.checkerframework:dataflow artifact in two ways.
First, the packages in this artifact have been renamed to org.checkerframework.shaded.*.
Second, unlike the dataflow artifact, this artifact contains the dependencies it requires.
package org.checkerframework.dataflow.cfg;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import java.util.concurrent.atomic.AtomicLong;
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.plumelib.util.StringsPlume;
import org.plumelib.util.UniqueId;
/**
* Represents an abstract syntax tree of type {@link Tree} that underlies a given control flow
* graph.
*/
public abstract class UnderlyingAST implements UniqueId {
/** The kinds of underlying ASTs. */
public enum Kind {
/** The underlying code is a whole method. */
METHOD,
/** The underlying code is a lambda expression. */
LAMBDA,
/** The underlying code is an arbitrary Java statement or expression. */
ARBITRARY_CODE,
}
/** The kind of the underlying AST. */
protected final Kind kind;
/** The unique ID for the next-created object. */
private static final AtomicLong nextUid = new AtomicLong(0);
/** The unique ID of this object. */
private final transient long uid = nextUid.getAndIncrement();
@Override
public long getUid(@UnknownInitialization UnderlyingAST this) {
return uid;
}
/**
* Creates an UnderlyingAST.
*
* @param kind the kind of the AST
*/
protected UnderlyingAST(Kind kind) {
this.kind = kind;
}
/**
* Returns the code that corresponds to the CFG. For a method or lamdda, this returns the body.
* For other constructs, it returns the tree itself (a statement or expression).
*
* @return the code that corresponds to the CFG
*/
public abstract Tree getCode();
public Kind getKind() {
return kind;
}
/** If the underlying AST is a method. */
public static class CFGMethod extends UnderlyingAST {
/** The method declaration. */
protected final MethodTree method;
/** The class tree this method belongs to. */
protected final ClassTree classTree;
public CFGMethod(MethodTree method, ClassTree classTree) {
super(Kind.METHOD);
this.method = method;
this.classTree = classTree;
}
@Override
public Tree getCode() {
return method.getBody();
}
public MethodTree getMethod() {
return method;
}
/**
* Returns the name of the method.
*
* @return the name of the method
*/
public String getMethodName() {
return method.getName().toString();
}
/**
* Returns the class tree this method belongs to.
*
* @return the class tree this method belongs to
*/
public ClassTree getClassTree() {
return classTree;
}
/**
* Returns the simple name of the enclosing class.
*
* @return the simple name of the enclosing class
*/
public String getSimpleClassName() {
return classTree.getSimpleName().toString();
}
@Override
public String toString() {
return StringsPlume.joinLines("CFGMethod(", method, ")");
}
}
/** If the underlying AST is a lambda. */
public static class CFGLambda extends UnderlyingAST {
/** The lambda expression. */
private final LambdaExpressionTree lambda;
/** The enclosing class of the lambda. */
private final ClassTree classTree;
/** The enclosing method of the lambda. */
private final @Nullable MethodTree enclosingMethod;
/**
* Create a new CFGLambda.
*
* @param lambda the lambda expression
* @param classTree the enclosing class of the lambda
* @param enclosingMethod the enclosing method of the lambda
*/
public CFGLambda(
LambdaExpressionTree lambda, ClassTree classTree, @Nullable MethodTree enclosingMethod) {
super(Kind.LAMBDA);
this.lambda = lambda;
this.enclosingMethod = enclosingMethod;
this.classTree = classTree;
}
@Override
public Tree getCode() {
return lambda.getBody();
}
/**
* Returns the lambda expression tree.
*
* @return the lambda expression tree
*/
public LambdaExpressionTree getLambdaTree() {
return lambda;
}
/**
* Returns the enclosing class of the lambda.
*
* @return the enclosing class of the lambda
*/
public ClassTree getClassTree() {
return classTree;
}
/**
* Returns the simple name of the enclosing class.
*
* @return the simple name of the enclosing class
*/
public String getSimpleClassName() {
return classTree.getSimpleName().toString();
}
/**
* Returns the enclosing method of the lambda.
*
* @return the enclosing method of the lambda, or {@code null} if there is no enclosing method
* @deprecated use #getEnclosingMethod()
*/
@Deprecated // 2022-01-23
public @Nullable MethodTree getMethod() {
return enclosingMethod;
}
/**
* Returns the enclosing method of the lambda.
*
* @return the enclosing method of the lambda, or {@code null} if there is no enclosing method
*/
public @Nullable MethodTree getEnclosingMethod() {
return enclosingMethod;
}
/**
* Returns the name of the enclosing method of the lambda.
*
* @return the name of the enclosing method of the lambda, or {@code null} if there is no
* enclosing method
* @deprecated use #getEnclosingMethodName()
*/
@Deprecated // 2022-01-23
public @Nullable String getMethodName() {
return enclosingMethod == null ? null : enclosingMethod.getName().toString();
}
/**
* Returns the name of the enclosing method of the lambda.
*
* @return the name of the enclosing method of the lambda, or {@code null} if there is no
* enclosing method
*/
public @Nullable String getEnclosingMethodName() {
return enclosingMethod == null ? null : enclosingMethod.getName().toString();
}
@Override
public String toString() {
return StringsPlume.joinLines("CFGLambda(", lambda, ")");
}
}
/**
* If the underlying AST is a statement or expression. This is for field definitions (with
* initializers) and initializer blocks.
*/
public static class CFGStatement extends UnderlyingAST {
protected final Tree code;
/** The class tree this method belongs to. */
protected final ClassTree classTree;
public CFGStatement(Tree code, ClassTree classTree) {
super(Kind.ARBITRARY_CODE);
this.code = code;
this.classTree = classTree;
}
@Override
public Tree getCode() {
return code;
}
public ClassTree getClassTree() {
return classTree;
}
/**
* Returns the simple name of the enclosing class.
*
* @return the simple name of the enclosing class
*/
public String getSimpleClassName() {
return classTree.getSimpleName().toString();
}
@Override
public String toString() {
return StringsPlume.joinLines("CFGStatement(", code, ")");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy