287 /**
288 * Copy all properties from the source object with their receiver bound to the source.
289 * This function was known as mergeMap
290 *
291 * @param source The source object to copy from.
292 */
293 public void addBoundProperties(final ScriptObject source) {
294 addBoundProperties(source, source.getMap().getProperties());
295 }
296
297 /**
298 * Copy all properties from the array with their receiver bound to the source.
299 *
300 * @param source The source object to copy from.
301 * @param properties The array of properties to copy.
302 */
303 public void addBoundProperties(final ScriptObject source, final Property[] properties) {
304 PropertyMap newMap = this.getMap();
305
306 for (final Property property : properties) {
307 final String key = property.getKey();
308 final Property oldProp = newMap.findProperty(key);
309 if (oldProp == null) {
310 if (property instanceof UserAccessorProperty) {
311 // Note: we copy accessor functions to this object which is semantically different from binding.
312 final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
313 newMap = newMap.addPropertyNoHistory(prop);
314 } else {
315 newMap = newMap.addPropertyBind((AccessorProperty)property, source);
316 }
317 } else {
318 // See ECMA section 10.5 Declaration Binding Instantiation
319 // step 5 processing each function declaration.
320 if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
321 if (oldProp instanceof UserAccessorProperty ||
322 !(oldProp.isWritable() && oldProp.isEnumerable())) {
323 throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
324 }
325 }
326 }
327 }
328
329 this.setMap(newMap);
330 }
331
332 /**
333 * Copy all properties from the array with their receiver bound to the source.
334 *
335 * @param source The source object to copy from.
336 * @param properties The collection of accessor properties to copy.
337 */
338 public void addBoundProperties(final Object source, final AccessorProperty[] properties) {
339 PropertyMap newMap = this.getMap();
340
341 for (final AccessorProperty property : properties) {
342 final String key = property.getKey();
343
344 if (newMap.findProperty(key) == null) {
345 newMap = newMap.addPropertyBind(property, source);
346 }
347 }
348
349 this.setMap(newMap);
493 /**
494 * ECMA 8.12.2 [[GetProperty]] (P)
495 *
496 * @param key property key
497 *
498 * @return Returns the fully populated Property Descriptor of the named property
499 * of this object, or undefined if absent.
500 */
501 public Object getPropertyDescriptor(final String key) {
502 final Object res = getOwnPropertyDescriptor(key);
503
504 if (res != UNDEFINED) {
505 return res;
506 } else if (getProto() != null) {
507 return getProto().getOwnPropertyDescriptor(key);
508 } else {
509 return UNDEFINED;
510 }
511 }
512
513 private void invalidateGlobalConstant(final String key) {
514 final GlobalConstants globalConstants = getGlobalConstants();
515 if (globalConstants != null) {
516 globalConstants.delete(key);
517 }
518 }
519
520 /**
521 * ECMA 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)
522 *
523 * @param key the property key
524 * @param propertyDesc the property descriptor
525 * @param reject is the property extensible - true means new definitions are rejected
526 *
527 * @return true if property was successfully defined
528 */
529 public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
530 final Global global = Context.getGlobal();
531 final PropertyDescriptor desc = toPropertyDescriptor(global, propertyDesc);
532 final Object current = getOwnPropertyDescriptor(key);
533 final String name = JSType.toString(key);
|
287 /**
288 * Copy all properties from the source object with their receiver bound to the source.
289 * This function was known as mergeMap
290 *
291 * @param source The source object to copy from.
292 */
293 public void addBoundProperties(final ScriptObject source) {
294 addBoundProperties(source, source.getMap().getProperties());
295 }
296
297 /**
298 * Copy all properties from the array with their receiver bound to the source.
299 *
300 * @param source The source object to copy from.
301 * @param properties The array of properties to copy.
302 */
303 public void addBoundProperties(final ScriptObject source, final Property[] properties) {
304 PropertyMap newMap = this.getMap();
305
306 for (final Property property : properties) {
307 newMap = addBoundProperty(newMap, source, property);
308 }
309
310 this.setMap(newMap);
311 }
312
313 /**
314 * Add a bound property from {@code source}, using the interim property map {@code propMap}, and return the
315 * new interim property map.
316 *
317 * @param propMap the property map
318 * @param source the source object
319 * @param property the property to be added
320 * @return the new property map
321 */
322 protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final Property property) {
323 PropertyMap newMap = propMap;
324 final String key = property.getKey();
325 final Property oldProp = newMap.findProperty(key);
326 if (oldProp == null) {
327 if (property instanceof UserAccessorProperty) {
328 // Note: we copy accessor functions to this object which is semantically different from binding.
329 final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
330 newMap = newMap.addPropertyNoHistory(prop);
331 } else {
332 newMap = newMap.addPropertyBind((AccessorProperty)property, source);
333 }
334 } else {
335 // See ECMA section 10.5 Declaration Binding Instantiation
336 // step 5 processing each function declaration.
337 if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
338 if (oldProp instanceof UserAccessorProperty ||
339 !(oldProp.isWritable() && oldProp.isEnumerable())) {
340 throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
341 }
342 }
343 }
344 return newMap;
345 }
346
347 /**
348 * Copy all properties from the array with their receiver bound to the source.
349 *
350 * @param source The source object to copy from.
351 * @param properties The collection of accessor properties to copy.
352 */
353 public void addBoundProperties(final Object source, final AccessorProperty[] properties) {
354 PropertyMap newMap = this.getMap();
355
356 for (final AccessorProperty property : properties) {
357 final String key = property.getKey();
358
359 if (newMap.findProperty(key) == null) {
360 newMap = newMap.addPropertyBind(property, source);
361 }
362 }
363
364 this.setMap(newMap);
508 /**
509 * ECMA 8.12.2 [[GetProperty]] (P)
510 *
511 * @param key property key
512 *
513 * @return Returns the fully populated Property Descriptor of the named property
514 * of this object, or undefined if absent.
515 */
516 public Object getPropertyDescriptor(final String key) {
517 final Object res = getOwnPropertyDescriptor(key);
518
519 if (res != UNDEFINED) {
520 return res;
521 } else if (getProto() != null) {
522 return getProto().getOwnPropertyDescriptor(key);
523 } else {
524 return UNDEFINED;
525 }
526 }
527
528 /**
529 * Invalidate any existing global constant method handles that may exist for {@code key}.
530 * @param key the property name
531 */
532 protected void invalidateGlobalConstant(final String key) {
533 final GlobalConstants globalConstants = getGlobalConstants();
534 if (globalConstants != null) {
535 globalConstants.delete(key);
536 }
537 }
538
539 /**
540 * ECMA 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)
541 *
542 * @param key the property key
543 * @param propertyDesc the property descriptor
544 * @param reject is the property extensible - true means new definitions are rejected
545 *
546 * @return true if property was successfully defined
547 */
548 public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
549 final Global global = Context.getGlobal();
550 final PropertyDescriptor desc = toPropertyDescriptor(global, propertyDesc);
551 final Object current = getOwnPropertyDescriptor(key);
552 final String name = JSType.toString(key);
|