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(
Environment env,
Environment.BindingName name,
[NotNullWhen(true)] out Environment? record)
{
record = env;
if (env._outerEnv is null)
{
return env.HasBinding(name);
}
while (record is not null)
{
if (record.HasBinding(name))
{
return true;
}
record = record._outerEnv;
}
return false;
}
internal static bool TryGetIdentifierEnvironmentWithBindingValue(
Environment env,
Environment.BindingName name,
bool strict,
[NotNullWhen(true)] out Environment? record,
[NotNullWhen(true)] out JsValue? value)
{
record = env;
value = default;
if (env._outerEnv is null)
{
return ((GlobalEnvironment) env).TryGetBinding(name, strict, out value);
}
while (record is not null)
{
if (record.TryGetBinding(name, strict, out value))
{
return true;
}
record = record._outerEnv;
}
return false;
}
///
/// https://tc39.es/ecma262/#sec-newdeclarativeenvironment
///
internal static DeclarativeEnvironment NewDeclarativeEnvironment(Engine engine, Environment? outer, bool catchEnvironment = false)
{
return new DeclarativeEnvironment(engine, catchEnvironment)
{
_outerEnv = outer
};
}
///
/// https://tc39.es/ecma262/#sec-newfunctionenvironment
///
internal static FunctionEnvironment NewFunctionEnvironment(Engine engine, Function f, JsValue newTarget)
{
return new FunctionEnvironment(engine, f, newTarget)
{
_outerEnv = f._environment
};
}
///
/// https://tc39.es/ecma262/#sec-newglobalenvironment
///
internal static GlobalEnvironment NewGlobalEnvironment(Engine engine, ObjectInstance objectInstance, JsValue thisValue)
{
return new GlobalEnvironment(engine, objectInstance)
{
_outerEnv = null
};
}
///
/// https://tc39.es/ecma262/#sec-newobjectenvironment
///
internal static ObjectEnvironment NewObjectEnvironment(Engine engine, ObjectInstance objectInstance, Environment outer, bool provideThis, bool withEnvironment = false)
{
return new ObjectEnvironment(engine, objectInstance, provideThis, withEnvironment)
{
_outerEnv = outer
};
}
///
/// https://tc39.es/ecma262/#sec-newprivateenvironment
///
internal static PrivateEnvironment NewPrivateEnvironment(Engine engine, PrivateEnvironment? outerPriv)
{
return new PrivateEnvironment(outerPriv);
}
///
/// https://tc39.es/ecma262/#sec-newmoduleenvironment
///
internal static ModuleEnvironment NewModuleEnvironment(Engine engine, Environment outer)
{
return new ModuleEnvironment(engine)
{
_outerEnv = outer
};
}
}