ModuleEnvironment.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System.Diagnostics.CodeAnalysis;
  2. using Jint.Collections;
  3. using Jint.Native;
  4. using Module = Jint.Runtime.Modules.Module;
  5. namespace Jint.Runtime.Environments;
  6. /// <summary>
  7. /// Represents a module environment record
  8. /// https://tc39.es/ecma262/#sec-module-environment-records
  9. /// </summary>
  10. internal sealed class ModuleEnvironment : DeclarativeEnvironment
  11. {
  12. private readonly HybridDictionary<IndirectBinding> _importBindings = new();
  13. internal ModuleEnvironment(Engine engine) : base(engine, false)
  14. {
  15. }
  16. /// <summary>
  17. /// https://tc39.es/ecma262/#sec-module-environment-records-getthisbinding
  18. /// </summary>
  19. internal override JsValue GetThisBinding()
  20. {
  21. return Undefined;
  22. }
  23. /// <summary>
  24. /// https://tc39.es/ecma262/#sec-createimportbinding
  25. /// </summary>
  26. public void CreateImportBinding(string importName, Module module, string name)
  27. {
  28. _importBindings[importName] = new IndirectBinding(module, name);
  29. CreateImmutableBindingAndInitialize(importName, true, JsValue.Undefined);
  30. }
  31. /// <summary>
  32. /// https://tc39.es/ecma262/#sec-module-environment-records-getbindingvalue-n-s
  33. /// </summary>
  34. internal override JsValue GetBindingValue(Key name, bool strict)
  35. {
  36. if (_importBindings.TryGetValue(name, out var indirectBinding))
  37. {
  38. return indirectBinding.Module._environment.GetBindingValue(indirectBinding.BindingName, true);
  39. }
  40. return base.GetBindingValue(name, strict);
  41. }
  42. internal override bool TryGetBinding(BindingName name, bool strict, out Binding binding, [NotNullWhen(true)] out JsValue? value)
  43. {
  44. if (_importBindings.TryGetValue(name.Key, out var indirectBinding))
  45. {
  46. value = indirectBinding.Module._environment.GetBindingValue(indirectBinding.BindingName, strict: true);
  47. binding = new(value, canBeDeleted: false, mutable: false, strict: true);
  48. return true;
  49. }
  50. return base.TryGetBinding(name, strict, out binding, out value);
  51. }
  52. /// <summary>
  53. /// https://tc39.es/ecma262/#sec-module-environment-records-hasthisbinding
  54. /// </summary>
  55. internal override bool HasThisBinding() => true;
  56. private readonly record struct IndirectBinding(Module Module, string BindingName);
  57. }