/**
* 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.objects.collection;
import static com.github.anba.es6draft.runtime.AbstractOperations.Get;
import static com.github.anba.es6draft.runtime.AbstractOperations.GetScriptIterator;
import static com.github.anba.es6draft.runtime.AbstractOperations.IsCallable;
import static com.github.anba.es6draft.runtime.internal.Errors.newTypeError;
import static com.github.anba.es6draft.runtime.internal.Properties.createProperties;
import com.github.anba.es6draft.runtime.ExecutionContext;
import com.github.anba.es6draft.runtime.Realm;
import com.github.anba.es6draft.runtime.internal.Initializable;
import com.github.anba.es6draft.runtime.internal.Messages;
import com.github.anba.es6draft.runtime.internal.Properties.Accessor;
import com.github.anba.es6draft.runtime.internal.Properties.Attributes;
import com.github.anba.es6draft.runtime.internal.Properties.Prototype;
import com.github.anba.es6draft.runtime.internal.Properties.Value;
import com.github.anba.es6draft.runtime.internal.ScriptException;
import com.github.anba.es6draft.runtime.internal.ScriptIterator;
import com.github.anba.es6draft.runtime.internal.ScriptIterators;
import com.github.anba.es6draft.runtime.types.BuiltinSymbol;
import com.github.anba.es6draft.runtime.types.Callable;
import com.github.anba.es6draft.runtime.types.Constructor;
import com.github.anba.es6draft.runtime.types.Intrinsics;
import com.github.anba.es6draft.runtime.types.Type;
import com.github.anba.es6draft.runtime.types.builtins.BuiltinConstructor;
/**
* <h1>23 Keyed Collection</h1><br>
* <h2>23.2 Set Objects</h2>
* <ul>
* <li>23.2.1 The Set Constructor
* <li>23.2.2 Properties of the Set Constructor
* </ul>
*/
public final class SetConstructor extends BuiltinConstructor implements Initializable {
/**
* Constructs a new Set constructor function.
*
* @param realm
* the realm object
*/
public SetConstructor(Realm realm) {
super(realm, "Set", 0);
}
@Override
public void initialize(Realm realm) {
createProperties(realm, this, Properties.class);
}
@Override
public SetConstructor clone() {
return new SetConstructor(getRealm());
}
/**
* 23.2.1.1 Set ([ iterable ])
*/
@Override
public Object call(ExecutionContext callerContext, Object thisValue, Object... args) {
/* step 1 */
throw newTypeError(calleeContext(), Messages.Key.InvalidCall, "Set");
}
/**
* 23.2.1.1 Set ([ iterable ])
*/
@Override
public SetObject construct(ExecutionContext callerContext, Constructor newTarget,
Object... args) {
ExecutionContext calleeContext = calleeContext();
Object iterable = argument(args, 0);
/* step 1 (not applicable) */
/* steps 2-4 */
SetObject set = OrdinaryCreateFromConstructor(calleeContext, newTarget, Intrinsics.SetPrototype,
SetObject::new);
/* steps 5-6, 8 */
if (Type.isUndefinedOrNull(iterable)) {
return set;
}
/* step 7 */
Object _adder = Get(calleeContext, set, "add");
if (!IsCallable(_adder)) {
throw newTypeError(calleeContext, Messages.Key.PropertyNotCallable, "add");
}
Callable adder = (Callable) _adder;
boolean isBuiltin = SetPrototype.isBuiltinAdd(_adder);
if (isBuiltin && iterable instanceof SetObject) {
SetObject other = (SetObject) iterable;
if (ScriptIterators.isBuiltinIterator(calleeContext, other)) {
set.getSetData().setAll(other.getSetData());
return set;
}
}
ScriptIterator<?> iter = GetScriptIterator(calleeContext, iterable);
/* step 9 */
try {
while (iter.hasNext()) {
Object nextValue = iter.next();
if (isBuiltin) {
set.getSetData().set(nextValue, null);
} else {
adder.call(calleeContext, set, nextValue);
}
}
return set;
} catch (ScriptException e) {
iter.close(e);
throw e;
}
}
/**
* 23.2.2 Properties of the Set Constructor
*/
public enum Properties {
;
@Prototype
public static final Intrinsics __proto__ = Intrinsics.FunctionPrototype;
@Value(name = "length", attributes = @Attributes(writable = false, enumerable = false,
configurable = true))
public static final int length = 0;
@Value(name = "name", attributes = @Attributes(writable = false, enumerable = false,
configurable = true))
public static final String name = "Set";
/**
* 23.2.2.1 Set.prototype
*/
@Value(name = "prototype", attributes = @Attributes(writable = false, enumerable = false,
configurable = false))
public static final Intrinsics prototype = Intrinsics.SetPrototype;
/**
* 23.2.2.2 get Set [ @@species ]
*
* @param cx
* the execution context
* @param thisValue
* the function this-value
* @return the species object
*/
@Accessor(name = "get [Symbol.species]", symbol = BuiltinSymbol.species,
type = Accessor.Type.Getter)
public static Object species(ExecutionContext cx, Object thisValue) {
/* step 1 */
return thisValue;
}
}
}