/** * 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; import static com.github.anba.es6draft.runtime.AbstractOperations.ToFlatString; import static com.github.anba.es6draft.runtime.internal.Errors.newTypeError; import static com.github.anba.es6draft.runtime.internal.Properties.createProperties; import static com.github.anba.es6draft.runtime.types.Undefined.UNDEFINED; import com.github.anba.es6draft.runtime.ExecutionContext; import com.github.anba.es6draft.runtime.Realm; import com.github.anba.es6draft.runtime.internal.CompatibilityOption; import com.github.anba.es6draft.runtime.internal.Initializable; import com.github.anba.es6draft.runtime.internal.Messages; import com.github.anba.es6draft.runtime.internal.Properties.Attributes; import com.github.anba.es6draft.runtime.internal.Properties.CompatibilityExtension; import com.github.anba.es6draft.runtime.internal.Properties.Function; import com.github.anba.es6draft.runtime.internal.Properties.Prototype; import com.github.anba.es6draft.runtime.internal.Properties.Value; import com.github.anba.es6draft.runtime.types.BuiltinSymbol; 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.Symbol; import com.github.anba.es6draft.runtime.types.Type; import com.github.anba.es6draft.runtime.types.builtins.BuiltinConstructor; /** * <h1>19 Fundamental Objects</h1><br> * <h2>19.4 Symbol Objects</h2> * <ul> * <li>19.4.1 The Symbol Constructor * <li>19.4.2 Properties of the Symbol Constructor * </ul> */ public final class SymbolConstructor extends BuiltinConstructor implements Initializable { /** * Constructs a new Symbol constructor function. * * @param realm * the realm object */ public SymbolConstructor(Realm realm) { super(realm, "Symbol", 0); } @Override public void initialize(Realm realm) { createProperties(realm, this, Properties.class); createProperties(realm, this, ObservableProperty.class); createProperties(realm, this, AsyncIteratorProperty.class); } @Override public SymbolConstructor clone() { return new SymbolConstructor(getRealm()); } /** * 19.4.1.1 Symbol ( [ description ] ) */ @Override public Symbol call(ExecutionContext callerContext, Object thisValue, Object... args) { ExecutionContext calleeContext = calleeContext(); Object description = argument(args, 0); /* step 1 (not applicable) */ /* steps 2-4 */ String descString = Type.isUndefined(description) ? null : ToFlatString(calleeContext, description); /* step 5 */ return new Symbol(descString); } /** * 19.4.1.1 Symbol ( [ description ] ) */ @Override public ScriptObject construct(ExecutionContext callerContext, Constructor newTarget, Object... args) { /* step 1 */ throw newTypeError(calleeContext(), Messages.Key.SymbolCreate); } /** * 19.4.2 Properties of the Symbol 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 = "Symbol"; /** * 19.4.2.7 Symbol.prototype */ @Value(name = "prototype", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Intrinsics prototype = Intrinsics.SymbolPrototype; /** * 19.4.2.2 Symbol.hasInstance */ @Value(name = "hasInstance", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol hasInstance = BuiltinSymbol.hasInstance.get(); /** * 19.4.2.3 Symbol.isConcatSpreadable */ @Value(name = "isConcatSpreadable", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol isConcatSpreadable = BuiltinSymbol.isConcatSpreadable.get(); /** * 19.4.2.4 Symbol.iterator */ @Value(name = "iterator", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol iterator = BuiltinSymbol.iterator.get(); /** * 19.4.2.6 Symbol.match */ @Value(name = "match", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol match = BuiltinSymbol.match.get(); /** * 19.4.2.8 Symbol.replace */ @Value(name = "replace", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol replace = BuiltinSymbol.replace.get(); /** * 19.4.2.9 Symbol.search */ @Value(name = "search", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol search = BuiltinSymbol.search.get(); /** * 19.4.2.10 Symbol.species */ @Value(name = "species", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol species = BuiltinSymbol.species.get(); /** * 19.4.2.11 Symbol.split */ @Value(name = "split", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol split = BuiltinSymbol.split.get(); /** * 19.4.2.12 Symbol.toPrimitive */ @Value(name = "toPrimitive", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol toPrimitive = BuiltinSymbol.toPrimitive.get(); /** * 19.4.2.13 Symbol.toStringTag */ @Value(name = "toStringTag", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol toStringTag = BuiltinSymbol.toStringTag.get(); /** * 19.4.2.14 Symbol.unscopables */ @Value(name = "unscopables", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol unscopables = BuiltinSymbol.unscopables.get(); /** * 19.4.2.1 Symbol.for (key) * * @param cx * the execution context * @param thisValue * the function this-value * @param key * the symbol string key * @return the mapped symbol */ @Function(name = "for", arity = 1) public static Object _for(ExecutionContext cx, Object thisValue, Object key) { /* steps 1-2 */ String stringKey = ToFlatString(cx, key); /* steps 3-7 */ return cx.getRealm().getSymbolRegistry().getSymbol(stringKey); } /** * 19.4.2.5 Symbol.keyFor (sym) * * @param cx * the execution context * @param thisValue * the function this-value * @param sym * the global symbol * @return the symbol string key or undefined if the symbol is not in the registry */ @Function(name = "keyFor", arity = 1) public static Object keyFor(ExecutionContext cx, Object thisValue, Object sym) { /* step 1 */ if (!Type.isSymbol(sym)) { throw newTypeError(cx, Messages.Key.NotSymbol); } /* steps 2-3 */ String key = cx.getRealm().getSymbolRegistry().getKey(Type.symbolValue(sym)); /* step 4 */ return key != null ? key : UNDEFINED; } } /** * Extension: Observable */ @CompatibilityExtension(CompatibilityOption.Observable) public enum ObservableProperty { ; /** * Symbol.observable */ @Value(name = "observable", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol observable = BuiltinSymbol.observable.get(); } /** * Extension: Async Generator Functions */ @CompatibilityExtension(CompatibilityOption.AsyncGenerator) public enum AsyncIteratorProperty { ; /** * Symbol.asyncIterator */ @Value(name = "asyncIterator", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Symbol asyncIterator = BuiltinSymbol.asyncIterator.get(); } }