aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/zwobble/couscous/ast/FieldAccessNode.java
blob: 3b7992c8e8669b7a1667113a35199116b752a62f (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
package org.zwobble.couscous.ast;

import org.zwobble.couscous.types.ScalarType;
import org.zwobble.couscous.types.Type;
import org.zwobble.couscous.ast.visitors.AssignableExpressionNodeVisitor;
import org.zwobble.couscous.ast.visitors.ExpressionNodeMapper;
import org.zwobble.couscous.ast.visitors.NodeTransformer;
import org.zwobble.couscous.util.ExtraIterables;

import static org.zwobble.couscous.ast.InstanceReceiver.instanceReceiver;
import static org.zwobble.couscous.ast.StaticReceiver.staticReceiver;

public class FieldAccessNode implements AssignableExpressionNode {
    public static FieldAccessNode fieldAccess(
            ExpressionNode left,
            String fieldName,
            Type type)
    {
        return fieldAccess(instanceReceiver(left), fieldName, type);
    }

    public static FieldAccessNode fieldAccess(
        ScalarType left,
        String fieldName,
        Type type)
    {
        return fieldAccess(staticReceiver(left), fieldName, type);
    }

    public static FieldAccessNode fieldAccess(
        Receiver left,
        String fieldName,
        Type type)
    {
        return new FieldAccessNode(left, fieldName, type);
    }
    
    private final Receiver left;
    private final String fieldName;
    private final Type type;
    
    public FieldAccessNode(
        Receiver left,
        String fieldName,
        Type type)
    {
        this.left = left;
        this.fieldName = fieldName;
        this.type = type;
    }
    
    public Receiver getLeft() {
        return left;
    }
    
    public String getFieldName() {
        return fieldName;
    }
    
    public Type getType() {
        return type;
    }
    
    @Override
    public <T> T accept(ExpressionNodeMapper<T> visitor) {
        return visitor.visit(this);
    }

    @Override
    public Iterable<? extends Node> childNodes() {
        return ExtraIterables.of(left);
    }

    @Override
    public ExpressionNode transform(NodeTransformer transformer) {
        return new FieldAccessNode(
            transformer.transformReceiver(left),
            transformer.transformFieldName(fieldName),
            transformer.transform(type));
    }

    @Override
    public void accept(AssignableExpressionNodeVisitor mapper) {
        mapper.visit(this);
    }

    @Override
    public String toString() {
        return "FieldAccessNode(left=" + left + ", fieldName=" + fieldName
               + ", type=" + type + ")";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                 + ((fieldName == null) ? 0 : fieldName.hashCode());
        result = prime * result + ((left == null) ? 0 : left.hashCode());
        result = prime * result + ((type == null) ? 0 : type.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        FieldAccessNode other = (FieldAccessNode) obj;
        if (fieldName == null) {
            if (other.fieldName != null)
                return false;
        } else if (!fieldName.equals(other.fieldName))
            return false;
        if (left == null) {
            if (other.left != null)
                return false;
        } else if (!left.equals(other.left))
            return false;
        if (type == null) {
            if (other.type != null)
                return false;
        } else if (!type.equals(other.type))
            return false;
        return true;
    }
}