#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}"; } }