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
26 package jdk.nashorn.internal.objects;
27
28 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
29 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
30 import static jdk.nashorn.internal.runtime.ScriptRuntime.sameValue;
31
32 import java.util.Objects;
33 import jdk.nashorn.internal.objects.annotations.Property;
34 import jdk.nashorn.internal.objects.annotations.ScriptClass;
35 import jdk.nashorn.internal.runtime.JSType;
36 import jdk.nashorn.internal.runtime.PropertyDescriptor;
37 import jdk.nashorn.internal.runtime.PropertyMap;
38 import jdk.nashorn.internal.runtime.ScriptFunction;
39 import jdk.nashorn.internal.runtime.ScriptObject;
40 import jdk.nashorn.internal.runtime.ScriptRuntime;
41
42 /**
43 * Accessor Property descriptor is used to represent attributes an object property
44 * that either has a getter or a setter.
45 *
46 * See ECMA 8.10 The Property Descriptor and Property Identifier Specification Types
47 *
48 */
49 @ScriptClass("AccessorPropertyDescriptor")
50 public final class AccessorPropertyDescriptor extends ScriptObject implements PropertyDescriptor {
51 /** is this property configurable? */
52 @Property
53 public Object configurable;
54
55 /** is this property enumerable? */
56 @Property
57 public Object enumerable;
58
59 /** getter for property */
60 @Property
61 public Object get;
62
63 /** setter for property */
64 @Property
65 public Object set;
66
67 // initialized by nasgen
68 private static PropertyMap $nasgenmap$;
69
70 AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) {
71 super(global.getObjectPrototype(), $nasgenmap$);
72 this.configurable = configurable;
73 this.enumerable = enumerable;
74 this.get = get;
75 this.set = set;
76 }
77
78 @Override
79 public boolean isConfigurable() {
80 return JSType.toBoolean(configurable);
81 }
82
83 @Override
84 public boolean isEnumerable() {
85 return JSType.toBoolean(enumerable);
86 }
87
88 @Override
89 public boolean isWritable() {
90 // Not applicable for this. But simplifies flag calculations.
91 return true;
92 }
93
94 @Override
95 public Object getValue() {
96 throw new UnsupportedOperationException("value");
97 }
98
99 @Override
100 public ScriptFunction getGetter() {
101 return (get instanceof ScriptFunction) ? (ScriptFunction)get : null;
102 }
103
104 @Override
105 public ScriptFunction getSetter() {
106 return (set instanceof ScriptFunction) ? (ScriptFunction)set : null;
107 }
108
109 @Override
110 public void setConfigurable(final boolean flag) {
111 this.configurable = flag;
112 }
113
114 @Override
115 public void setEnumerable(final boolean flag) {
116 this.enumerable = flag;
117 }
118
119 @Override
120 public void setWritable(final boolean flag) {
121 throw new UnsupportedOperationException("set writable");
122 }
123
124 @Override
125 public void setValue(final Object value) {
126 throw new UnsupportedOperationException("set value");
127 }
128
129 @Override
130 public void setGetter(final Object getter) {
131 this.get = getter;
132 }
133
134 @Override
135 public void setSetter(final Object setter) {
136 this.set = setter;
137 }
138
139 @Override
140 public PropertyDescriptor fillFrom(final ScriptObject sobj) {
141 if (sobj.has(CONFIGURABLE)) {
142 this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE));
143 } else {
144 delete(CONFIGURABLE, false);
145 }
146
147 if (sobj.has(ENUMERABLE)) {
148 this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE));
149 } else {
150 delete(ENUMERABLE, false);
151 }
152
153 if (sobj.has(GET)) {
154 final Object getter = sobj.get(GET);
155 if (getter == UNDEFINED || getter instanceof ScriptFunction) {
156 this.get = getter;
157 } else {
158 throw typeError("not.a.function", ScriptRuntime.safeToString(getter));
159 }
160 } else {
161 delete(GET, false);
162 }
163
164 if (sobj.has(SET)) {
165 final Object setter = sobj.get(SET);
166 if (setter == UNDEFINED || setter instanceof ScriptFunction) {
167 this.set = setter;
168 } else {
169 throw typeError("not.a.function", ScriptRuntime.safeToString(setter));
170 }
171 } else {
172 delete(SET, false);
173 }
174
175 return this;
176 }
177
178 @Override
179 public int type() {
180 return ACCESSOR;
181 }
182
183 @Override
184 public boolean hasAndEquals(final PropertyDescriptor otherDesc) {
185 if (! (otherDesc instanceof AccessorPropertyDescriptor)) {
186 return false;
187 }
188 final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)otherDesc;
189 return (!has(CONFIGURABLE) || sameValue(configurable, other.configurable)) &&
190 (!has(ENUMERABLE) || sameValue(enumerable, other.enumerable)) &&
191 (!has(GET) || sameValue(get, other.get)) &&
192 (!has(SET) || sameValue(set, other.set));
193 }
194
195 @Override
196 public boolean equals(final Object obj) {
197 if (this == obj) {
198 return true;
199 }
200 if (! (obj instanceof AccessorPropertyDescriptor)) {
201 return false;
202 }
203
204 final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)obj;
205 return sameValue(configurable, other.configurable) &&
206 sameValue(enumerable, other.enumerable) &&
207 sameValue(get, other.get) &&
208 sameValue(set, other.set);
209 }
210
211 @Override
212 public int hashCode() {
213 int hash = 7;
214 hash = 41 * hash + Objects.hashCode(this.configurable);
215 hash = 41 * hash + Objects.hashCode(this.enumerable);
216 hash = 41 * hash + Objects.hashCode(this.get);
217 hash = 41 * hash + Objects.hashCode(this.set);
218 return hash;
219 }
220 }
--- EOF ---