using System.Diagnostics.CodeAnalysis; using Jint.Native; using Jint.Native.Function; using Jint.Native.Object; namespace Jint.Runtime.Environments { internal static class JintEnvironment { internal static bool TryGetIdentifierEnvironmentWithBinding( EnvironmentRecord env, in EnvironmentRecord.BindingName name, [NotNullWhen(true)] out EnvironmentRecord? record) { record = env; if (env._outerEnv is null) { return env.HasBinding(name); } while (!ReferenceEquals(record, null)) { if (record.HasBinding(name)) { return true; } record = record._outerEnv; } return false; } internal static bool TryGetIdentifierEnvironmentWithBindingValue( EnvironmentRecord env, in EnvironmentRecord.BindingName name, bool strict, [NotNullWhen(true)] out EnvironmentRecord? record, [NotNullWhen(true)] out JsValue? value) { record = env; value = default; if (env._outerEnv is null) { return env.TryGetBinding(name, strict, out _, out value); } while (!ReferenceEquals(record, null)) { if (record.TryGetBinding( name, strict, out _, out value)) { return true; } record = record._outerEnv; } return false; } /// /// https://tc39.es/ecma262/#sec-newdeclarativeenvironment /// internal static DeclarativeEnvironmentRecord NewDeclarativeEnvironment(Engine engine, EnvironmentRecord? outer, bool catchEnvironment = false) { return new DeclarativeEnvironmentRecord(engine, catchEnvironment) { _outerEnv = outer }; } /// /// https://tc39.es/ecma262/#sec-newfunctionenvironment /// internal static FunctionEnvironmentRecord NewFunctionEnvironment(Engine engine, FunctionInstance f, JsValue newTarget) { return new FunctionEnvironmentRecord(engine, f, newTarget) { _outerEnv = f._environment }; } /// /// https://tc39.es/ecma262/#sec-newglobalenvironment /// internal static GlobalEnvironmentRecord NewGlobalEnvironment(Engine engine, ObjectInstance objectInstance, JsValue thisValue) { return new GlobalEnvironmentRecord(engine, objectInstance) { _outerEnv = null }; } /// /// https://tc39.es/ecma262/#sec-newobjectenvironment /// internal static ObjectEnvironmentRecord NewObjectEnvironment(Engine engine, ObjectInstance objectInstance, EnvironmentRecord outer, bool provideThis, bool withEnvironment = false) { return new ObjectEnvironmentRecord(engine, objectInstance, provideThis, withEnvironment) { _outerEnv = outer }; } /// /// https://tc39.es/ecma262/#sec-newprivateenvironment /// internal static PrivateEnvironmentRecord NewPrivateEnvironment(Engine engine, PrivateEnvironmentRecord? outerPriv) { return new PrivateEnvironmentRecord(outerPriv); } /// /// https://tc39.es/ecma262/#sec-newmoduleenvironment /// internal static ModuleEnvironmentRecord NewModuleEnvironment(Engine engine, EnvironmentRecord outer) { return new ModuleEnvironmentRecord(engine) { _outerEnv = outer }; } } }