aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayCreationNode.java
blob: 4af69077d3d67254bdfc20f9570a8752dc3dfb97 (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
129
130
131
132
133
134
135
package org.checkerframework.dataflow.cfg.node;

/*>>>
import org.checkerframework.checker.nullness.qual.Nullable;
*/

import org.checkerframework.dataflow.util.HashCodeUtils;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.lang.model.type.TypeMirror;

import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.Tree;

/**
 * A node for new array creation
 *
 * <pre>
 *   <em>new type [1][2]</em>
 *   <em>new type [] = { expr1, expr2, ... }</em>
 * </pre>
 *
 * @author Stefan Heule
 * @author Charlie Garrett
 *
 */
public class ArrayCreationNode extends Node {

    // The tree is null when an array is created for
    // variable arity method calls.
    protected /*@Nullable*/ NewArrayTree tree;
    protected List<Node> dimensions;
    protected List<Node> initializers;

    public ArrayCreationNode(/*@Nullable*/ NewArrayTree tree,
            TypeMirror type,
            List<Node> dimensions,
            List<Node> initializers) {
        super(type);
        this.tree = tree;
        this.dimensions = dimensions;
        this.initializers = initializers;
    }

    public List<Node> getDimensions() {
        return dimensions;
    }

    public Node getDimension(int i) {
        return dimensions.get(i);
    }

    public List<Node> getInitializers() {
        return initializers;
    }

    public Node getInitializer(int i) {
        return initializers.get(i);
    }

    @Override
    public Tree getTree() {
        return tree;
    }

    @Override
    public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
        return visitor.visitArrayCreation(this, p);
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("new " + type);
        if (!dimensions.isEmpty()) {
            boolean needComma = false;
            sb.append(" (");
            for (Node dim : dimensions) {
                if (needComma) {
                    sb.append(", ");
                }
                sb.append(dim);
                needComma = true;
            }
            sb.append(")");
        }
        if (!initializers.isEmpty()) {
            boolean needComma = false;
            sb.append(" = {");
            for (Node init : initializers) {
                if (needComma) {
                    sb.append(", ");
                }
                sb.append(init);
                needComma = true;
            }
            sb.append("}");
        }
        return sb.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof ArrayCreationNode)) {
            return false;
        }
        ArrayCreationNode other = (ArrayCreationNode) obj;

        return getDimensions().equals(other.getDimensions())
                && getInitializers().equals(other.getInitializers());
    }

    @Override
    public int hashCode() {
        int hash = 0;
        for (Node dim : dimensions) {
            hash = HashCodeUtils.hash(hash, dim.hashCode());
        }
        for (Node init : initializers) {
            hash = HashCodeUtils.hash(hash, init.hashCode());
        }
        return hash;
    }

    @Override
    public Collection<Node> getOperands() {
        LinkedList<Node> list = new LinkedList<Node>();
        list.addAll(dimensions);
        list.addAll(initializers);
        return list;
    }
}