/** * 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.ScriptObject; 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.1 Map Objects</h2> * <ul> * <li>23.1.1 The Map Constructor * <li>23.1.2 Properties of the Map Constructor * </ul> */ public final class MapConstructor extends BuiltinConstructor implements Initializable { /** * Constructs a new Map constructor function. * * @param realm * the realm object */ public MapConstructor(Realm realm) { super(realm, "Map", 0); } @Override public void initialize(Realm realm) { createProperties(realm, this, Properties.class); } @Override public MapConstructor clone() { return new MapConstructor(getRealm()); } /** * 23.1.1.1 Map ([ iterable ]) */ @Override public Object call(ExecutionContext callerContext, Object thisValue, Object... args) { /* step 1 */ throw newTypeError(calleeContext(), Messages.Key.InvalidCall, "Map"); } /** * 23.1.1.1 Map ([ iterable ]) */ @Override public MapObject construct(ExecutionContext callerContext, Constructor newTarget, Object... args) { ExecutionContext calleeContext = calleeContext(); Object iterable = argument(args, 0); /* step 1 (not applicable) */ /* steps 2-4 */ MapObject map = OrdinaryCreateFromConstructor(calleeContext, newTarget, Intrinsics.MapPrototype, MapObject::new); /* steps 5-6, 8 */ if (Type.isUndefinedOrNull(iterable)) { return map; } /* step 7 */ Object _adder = Get(calleeContext, map, "set"); if (!IsCallable(_adder)) { throw newTypeError(calleeContext, Messages.Key.PropertyNotCallable, "set"); } Callable adder = (Callable) _adder; boolean isBuiltin = MapPrototype.isBuiltinSet(_adder); if (isBuiltin && iterable instanceof MapObject) { MapObject other = (MapObject) iterable; if (ScriptIterators.isBuiltinIterator(calleeContext, other)) { map.getMapData().setAll(other.getMapData()); return map; } } ScriptIterator<?> iter = GetScriptIterator(calleeContext, iterable); /* step 9 */ try { while (iter.hasNext()) { Object nextItem = iter.next(); if (!Type.isObject(nextItem)) { throw newTypeError(calleeContext, Messages.Key.MapPairNotObject); } ScriptObject item = Type.objectValue(nextItem); Object k = Get(calleeContext, item, 0); Object v = Get(calleeContext, item, 1); if (isBuiltin) { map.getMapData().set(k, v); } else { adder.call(calleeContext, map, k, v); } } return map; } catch (ScriptException e) { iter.close(e); throw e; } } /** * 23.1.2 Properties of the Map 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 = "Map"; /** * 23.1.2.1 Map.prototype */ @Value(name = "prototype", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Intrinsics prototype = Intrinsics.MapPrototype; /** * 23.1.2.2 get Map [ @@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; } } }