/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.runtime.types; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.github.anba.es6draft.runtime.ExecutionContext; import com.github.anba.es6draft.runtime.internal.ScriptIterator; /** * <h1>6 ECMAScript Data Types and Values</h1><br> * <h2>6.1 ECMAScript Language Types</h2><br> * <h3>6.1.7 The Object Type</h3> * <ul> * <li>6.1.7.2 Object Internal Methods and Internal Slots * </ul> */ public interface ScriptObject { /** * [[GetPrototypeOf]] ( ) * * @param cx * the execution context * @return the prototype object or {@code null} */ ScriptObject getPrototypeOf(ExecutionContext cx); /** * [[SetPrototypeOf]] (V) * * @param cx * the execution context * @param prototype * the new prototype object * @return {@code true} if the prototype was successfully updated */ boolean setPrototypeOf(ExecutionContext cx, ScriptObject prototype); /** * [[IsExtensible]] () * * @param cx * the execution context * @return {@code true} if the object is extensible */ boolean isExtensible(ExecutionContext cx); /** * [[PreventExtensions]] () * * @param cx * the execution context * @return {@code true} on success */ boolean preventExtensions(ExecutionContext cx); /** * [[GetOwnProperty]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return the property or {@code null} if none found */ Property getOwnProperty(ExecutionContext cx, long propertyKey); /** * [[GetOwnProperty]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return the property or {@code null} if none found */ Property getOwnProperty(ExecutionContext cx, String propertyKey); /** * [[GetOwnProperty]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return the property or {@code null} if none found */ Property getOwnProperty(ExecutionContext cx, Symbol propertyKey); /** * [[GetOwnProperty]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return the property or {@code null} if none found */ default Property getOwnProperty(ExecutionContext cx, Object propertyKey) { if (propertyKey instanceof String) { return getOwnProperty(cx, (String) propertyKey); } return getOwnProperty(cx, (Symbol) propertyKey); } /** * [[HasProperty]](P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was found */ boolean hasProperty(ExecutionContext cx, long propertyKey); /** * [[HasProperty]](P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was found */ boolean hasProperty(ExecutionContext cx, String propertyKey); /** * [[HasProperty]](P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was found */ boolean hasProperty(ExecutionContext cx, Symbol propertyKey); /** * [[HasProperty]](P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was found */ default boolean hasProperty(ExecutionContext cx, Object propertyKey) { if (propertyKey instanceof String) { return hasProperty(cx, (String) propertyKey); } return hasProperty(cx, (Symbol) propertyKey); } /** * [[Get]] (P, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param receiver * the receiver object * @return the property value */ Object get(ExecutionContext cx, long propertyKey, Object receiver); /** * [[Get]] (P, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param receiver * the receiver object * @return the property value */ Object get(ExecutionContext cx, String propertyKey, Object receiver); /** * [[Get]] (P, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param receiver * the receiver object * @return the property value */ Object get(ExecutionContext cx, Symbol propertyKey, Object receiver); /** * [[Get]] (P, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param receiver * the receiver object * @return the property value */ default Object get(ExecutionContext cx, Object propertyKey, Object receiver) { if (propertyKey instanceof String) { return get(cx, (String) propertyKey, receiver); } return get(cx, (Symbol) propertyKey, receiver); } /** * [[Set] (P, V, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param value * the new property value * @param receiver * the receiver object * @return {@code true} on success */ boolean set(ExecutionContext cx, long propertyKey, Object value, Object receiver); /** * [[Set] (P, V, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param value * the new property value * @param receiver * the receiver object * @return {@code true} on success */ boolean set(ExecutionContext cx, String propertyKey, Object value, Object receiver); /** * [[Set] (P, V, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param value * the new property value * @param receiver * the receiver object * @return {@code true} on success */ boolean set(ExecutionContext cx, Symbol propertyKey, Object value, Object receiver); /** * [[Set] (P, V, Receiver) * * @param cx * the execution context * @param propertyKey * the property key * @param value * the new property value * @param receiver * the receiver object * @return {@code true} on success */ default boolean set(ExecutionContext cx, Object propertyKey, Object value, Object receiver) { if (propertyKey instanceof String) { return set(cx, (String) propertyKey, value, receiver); } return set(cx, (Symbol) propertyKey, value, receiver); } /** * [[Delete]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was successfully deleted */ boolean delete(ExecutionContext cx, long propertyKey); /** * [[Delete]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was successfully deleted */ boolean delete(ExecutionContext cx, String propertyKey); /** * [[Delete]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was successfully deleted */ boolean delete(ExecutionContext cx, Symbol propertyKey); /** * [[Delete]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return {@code true} if the property was successfully deleted */ default boolean delete(ExecutionContext cx, Object propertyKey) { if (propertyKey instanceof String) { return delete(cx, (String) propertyKey); } return delete(cx, (Symbol) propertyKey); } /** * [[DefineOwnProperty]] (P, Desc) * * @param cx * the execution context * @param propertyKey * the property key * @param desc * the property descriptor * @return {@code true} if the property was successfully defined */ boolean defineOwnProperty(ExecutionContext cx, long propertyKey, PropertyDescriptor desc); /** * [[DefineOwnProperty]] (P, Desc) * * @param cx * the execution context * @param propertyKey * the property key * @param desc * the property descriptor * @return {@code true} if the property was successfully defined */ boolean defineOwnProperty(ExecutionContext cx, String propertyKey, PropertyDescriptor desc); /** * [[DefineOwnProperty]] (P, Desc) * * @param cx * the execution context * @param propertyKey * the property key * @param desc * the property descriptor * @return {@code true} if the property was successfully defined */ boolean defineOwnProperty(ExecutionContext cx, Symbol propertyKey, PropertyDescriptor desc); /** * [[DefineOwnProperty]] (P, Desc) * * @param cx * the execution context * @param propertyKey * the property key * @param desc * the property descriptor * @return {@code true} if the property was successfully defined */ default boolean defineOwnProperty(ExecutionContext cx, Object propertyKey, PropertyDescriptor desc) { if (propertyKey instanceof String) { return defineOwnProperty(cx, (String) propertyKey, desc); } return defineOwnProperty(cx, (Symbol) propertyKey, desc); } /** * [[Enumerate]] () * * @param cx * the execution context * @return the enumeration iterator object */ ScriptObject enumerate(ExecutionContext cx); /** * [[Enumerate]] () * * @param cx * the execution context * @return the enumeration iterator object */ ScriptIterator<?> enumerateKeys(ExecutionContext cx); /** * [[OwnPropertyKeys]] ( ) * * @param cx * the execution context * @return the properties array object */ List<?> ownPropertyKeys(ExecutionContext cx); /** * [[OwnPropertyKeys]] ( ) * * @param cx * the execution context * @return the properties iterator object */ Iterator<?> ownKeys(ExecutionContext cx); /** * [[OwnPropertyKeys]] ( ) * * @param cx * the execution context * @return the enumerable keys iterator * @see ScriptObject#isEnumerableOwnProperty(ExecutionContext, String) */ default Iterator<String> ownEnumerablePropertyKeys(ExecutionContext cx) { List<?> ownKeys = ownPropertyKeys(cx); List<String> enumerableKeys = new ArrayList<>(); for (Object key : ownKeys) { if (key instanceof String) { enumerableKeys.add((String) key); } } return enumerableKeys.iterator(); } /** * Enumerability states. */ enum Enumerability { Enumerable, NonEnumerable, Deleted; public static Enumerability isEnumerable(boolean enumerable) { return enumerable ? Enumerable : NonEnumerable; } } /** * [[GetOwnProperty]] (P) * * @param cx * the execution context * @param propertyKey * the property key * @return the enumerability kind */ default Enumerability isEnumerableOwnProperty(ExecutionContext cx, String propertyKey) { Property prop = getOwnProperty(cx, propertyKey); if (prop == null) { return Enumerability.Deleted; } return Enumerability.isEnumerable(prop.isEnumerable()); } /** * Returns the class name of this script object. (Used in {@code Object.prototype.toString}.) * * @return the class name */ default String className() { return "Object"; } }