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