#nullable disable
using Jint.Native;
using Jint.Native.Object;
using Jint.Runtime.Environments;
namespace Jint.Runtime.Modules;
internal sealed record ExportResolveSetItem(
CyclicModule Module,
string ExportName
);
///
/// https://tc39.es/ecma262/#sec-abstract-module-records
///
public abstract class Module : JsValue, IScriptOrModule
{
private ObjectInstance _namespace;
protected readonly Engine _engine;
protected readonly Realm _realm;
internal ModuleEnvironment _environment;
public string Location { get; }
internal Module(Engine engine, Realm realm, string location) : base(InternalTypes.Module)
{
_engine = engine;
_realm = realm;
Location = location;
}
public abstract List GetExportedNames(List exportStarSet = null);
internal abstract ResolvedBinding ResolveExport(string exportName, List resolveSet = null);
public abstract void Link();
public abstract JsValue Evaluate();
protected internal abstract int InnerModuleLinking(Stack stack, int index);
protected internal abstract Completion InnerModuleEvaluation(Stack stack, int index, ref int asyncEvalOrder);
///
/// https://tc39.es/ecma262/#sec-getmodulenamespace
///
public static ObjectInstance GetModuleNamespace(Module module)
{
var ns = module._namespace;
if (ns is null)
{
var exportedNames = module.GetExportedNames();
var unambiguousNames = new List();
for (var i = 0; i < exportedNames.Count; i++)
{
var name = exportedNames[i];
var resolution = module.ResolveExport(name);
if (resolution is not null && resolution != ResolvedBinding.Ambiguous)
{
unambiguousNames.Add(name);
}
}
ns = CreateModuleNamespace(module, unambiguousNames);
}
return ns;
}
///
/// https://tc39.es/ecma262/#sec-modulenamespacecreate
///
private static ModuleNamespace CreateModuleNamespace(Module module, List unambiguousNames)
{
var m = new ModuleNamespace(module._engine, module, unambiguousNames);
module._namespace = m;
return m;
}
public override object ToObject()
{
Throw.NotSupportedException();
return null;
}
public override string ToString()
{
return $"{Type}: {Location}";
}
}