PropertyNode.java revision 1668:bafd733be429
1/*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.nashorn.internal.ir;
27
28import jdk.nashorn.internal.ir.annotations.Immutable;
29import jdk.nashorn.internal.ir.visitor.NodeVisitor;
30
31/**
32 * IR representation of an object literal property.
33 */
34@Immutable
35public final class PropertyNode extends Node {
36    private static final long serialVersionUID = 1L;
37
38    /** Property key. */
39    private final Expression key;
40
41    /** Property value. */
42    private final Expression value;
43
44    /** Property getter. */
45    private final FunctionNode getter;
46
47    /** Property getter. */
48    private final FunctionNode setter;
49
50    /** static property flag */
51    private final boolean isStatic;
52
53    /** Computed property flag */
54    private final boolean computed;
55
56    /**
57     * Constructor
58     *
59     * @param token   token
60     * @param finish  finish
61     * @param key     the key of this property
62     * @param value   the value of this property
63     * @param getter  getter function body
64     * @param setter  setter function body
65     * @param isStatic is this a static property?
66     * @param computed is this a computed property?
67     */
68    public PropertyNode(final long token, final int finish, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) {
69        super(token, finish);
70        this.key    = key;
71        this.value  = value;
72        this.getter = getter;
73        this.setter = setter;
74        this.isStatic = isStatic;
75        this.computed = computed;
76    }
77
78    private PropertyNode(final PropertyNode propertyNode, final Expression key, final Expression value, final FunctionNode getter, final FunctionNode setter, final boolean isStatic, final boolean computed) {
79        super(propertyNode);
80        this.key    = key;
81        this.value  = value;
82        this.getter = getter;
83        this.setter = setter;
84        this.isStatic = isStatic;
85        this.computed = computed;
86    }
87
88    /**
89     * Get the name of the property key
90     * @return key name
91     */
92    public String getKeyName() {
93        return key instanceof PropertyKey ? ((PropertyKey) key).getPropertyName() : null;
94    }
95
96    @Override
97    public Node accept(final NodeVisitor<? extends LexicalContext> visitor) {
98        if (visitor.enterPropertyNode(this)) {
99            return visitor.leavePropertyNode(
100                setKey((Expression) key.accept(visitor)).
101                setValue(value == null ? null : (Expression)value.accept(visitor)).
102                setGetter(getter == null ? null : (FunctionNode)getter.accept(visitor)).
103                setSetter(setter == null ? null : (FunctionNode)setter.accept(visitor)));
104        }
105
106        return this;
107    }
108
109    @Override
110    public void toString(final StringBuilder sb, final boolean printType) {
111        if (value instanceof FunctionNode && ((FunctionNode)value).getIdent() != null) {
112            value.toString(sb);
113        }
114
115        if (value != null) {
116            ((Node)key).toString(sb, printType);
117            sb.append(": ");
118            value.toString(sb, printType);
119        }
120
121        if (getter != null) {
122            sb.append(' ');
123            getter.toString(sb, printType);
124        }
125
126        if (setter != null) {
127            sb.append(' ');
128            setter.toString(sb, printType);
129        }
130    }
131
132    /**
133     * Get the getter for this property
134     * @return getter or null if none exists
135     */
136    public FunctionNode getGetter() {
137        return getter;
138    }
139
140    /**
141     * Set the getter of this property, null if none
142     * @param getter getter
143     * @return same node or new node if state changed
144     */
145    public PropertyNode setGetter(final FunctionNode getter) {
146        if (this.getter == getter) {
147            return this;
148        }
149        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
150    }
151
152    /**
153     * Return the key for this property node
154     * @return the key
155     */
156    public Expression getKey() {
157        return key;
158    }
159
160    private PropertyNode setKey(final Expression key) {
161        if (this.key == key) {
162            return this;
163        }
164        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
165    }
166
167    /**
168     * Get the setter for this property
169     * @return setter or null if none exists
170     */
171    public FunctionNode getSetter() {
172        return setter;
173    }
174
175    /**
176     * Set the setter for this property, null if none
177     * @param setter setter
178     * @return same node or new node if state changed
179     */
180    public PropertyNode setSetter(final FunctionNode setter) {
181        if (this.setter == setter) {
182            return this;
183        }
184        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
185    }
186
187    /**
188     * Get the value of this property
189     * @return property value
190     */
191    public Expression getValue() {
192        return value;
193    }
194
195    /**
196     * Set the value of this property
197     * @param value new value
198     * @return same node or new node if state changed
199     */
200    public PropertyNode setValue(final Expression value) {
201        if (this.value == value) {
202            return this;
203        }
204        return new PropertyNode(this, key, value, getter, setter, isStatic, computed);
205    }
206
207    /**
208     * Returns true if this is a static property.
209     *
210     * @return true if static flag is set
211     */
212    public boolean isStatic() {
213        return isStatic;
214    }
215
216    /**
217     * Returns true if this is a computed property.
218     *
219     * @return true if the computed flag is set
220     */
221    public boolean isComputed() {
222        return computed;
223    }
224}
225