aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/UnderlyingAST.java
blob: 5f61468e8c901162881eba8383043368bdacc224 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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;

/**
 * Represents an abstract syntax tree of type {@link Tree} that underlies a
 * given control flow graph.
 *
 * @author Stefan Heule
 *
 */
public abstract class UnderlyingAST {
    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,
    }

    protected final Kind kind;

    public UnderlyingAST(Kind kind) {
        this.kind = kind;
    }

    /**
     * @return The code that corresponds to the CFG.
     */
    abstract public 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;
        }

        public ClassTree getClassTree() {
            return classTree;
        }

        @Override
        public String toString() {
            return "CFGMethod(\n" + method + "\n)";
        }
    }

    /**
     * If the underlying AST is a lambda.
     */
    public static class CFGLambda extends UnderlyingAST {

        private final LambdaExpressionTree lambda;

        public CFGLambda(LambdaExpressionTree lambda) {
            super(Kind.LAMBDA);
            this.lambda = lambda;
        }

        @Override
        public Tree getCode() {
            return lambda.getBody();
        }

        public LambdaExpressionTree getLambdaTree() {
            return lambda;
        }

        @Override
        public String toString() {
            return "CFGLambda(\n" + lambda + "\n)";
        }
    }

    /**
     * If the underlying AST is a statement or expression.
     */
    public static class CFGStatement extends UnderlyingAST {

        protected final Tree code;

        public CFGStatement(Tree code) {
            super(Kind.ARBITRARY_CODE);
            this.code = code;
        }

        @Override
        public Tree getCode() {
            return code;
        }

        @Override
        public String toString() {
            return "CFGStatement(\n" + code + "\n)";
        }
    }
}