ModuleFactory.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using Jint.Native;
  2. using Jint.Native.Json;
  3. namespace Jint.Runtime.Modules;
  4. /// <summary>
  5. /// Factory which creates a single runtime <see cref="Module"/> from a given source.
  6. /// </summary>
  7. public static class ModuleFactory
  8. {
  9. /// <summary>
  10. /// Creates a <see cref="Module"/> for the usage within the given <paramref name="engine"/>
  11. /// from the provided javascript <paramref name="code"/>.
  12. /// </summary>
  13. /// <remarks>
  14. /// The returned modules location (see <see cref="Module.Location"/>) points to
  15. /// <see cref="Uri.LocalPath"/> if <see cref="ResolvedSpecifier.Uri"/> is not null. If
  16. /// <see cref="ResolvedSpecifier.Uri"/> is null, the modules location source will be null as well.
  17. /// </remarks>
  18. /// <exception cref="ParseErrorException">Is thrown if the provided <paramref name="code"/> can not be parsed.</exception>
  19. /// <exception cref="JavaScriptException">Is thrown if an error occured when parsing <paramref name="code"/>.</exception>
  20. public static Module BuildSourceTextModule(Engine engine, ResolvedSpecifier resolved, string code)
  21. {
  22. var source = resolved.Uri?.LocalPath ?? resolved.Key;
  23. Esprima.Ast.Module module;
  24. try
  25. {
  26. module = new Parser().ParseModule(code, source);
  27. }
  28. catch (ParseErrorException ex)
  29. {
  30. ExceptionHelper.ThrowSyntaxError(engine.Realm, $"Error while loading module: error in module '{source}': {ex.Error}");
  31. module = null;
  32. }
  33. catch (Exception)
  34. {
  35. ExceptionHelper.ThrowJavaScriptException(engine, $"Could not load module {source}", (SourceLocation) default);
  36. module = null;
  37. }
  38. return BuildSourceTextModule(engine, module);
  39. }
  40. /// <summary>
  41. /// Creates a <see cref="Module"/> for the usage within the given <paramref name="engine"/>
  42. /// from the parsed <paramref name="parsedModule"/>.
  43. /// </summary>
  44. /// <remarks>
  45. /// The returned modules location (see <see cref="Module.Location"/>) will be set
  46. /// to <see cref="Location.Source"/> of the <paramref name="parsedModule"/>.
  47. /// </remarks>
  48. public static Module BuildSourceTextModule(Engine engine, Esprima.Ast.Module parsedModule)
  49. {
  50. return new SourceTextModule(engine, engine.Realm, parsedModule, parsedModule.Location.Source, async: false);
  51. }
  52. /// <summary>
  53. /// Creates a <see cref="Module"/> for the usage within the given <paramref name="engine"/> for the
  54. /// provided JSON module <paramref name="jsonString"/>.
  55. /// </summary>
  56. /// <remarks>
  57. /// The returned modules location (see <see cref="Module.Location"/>) points to
  58. /// <see cref="Uri.LocalPath"/> if <see cref="ResolvedSpecifier.Uri"/> is not null. If
  59. /// <see cref="ResolvedSpecifier.Uri"/> is null, the modules location source will be null as well.
  60. /// </remarks>
  61. /// <exception cref="JavaScriptException">Is thrown if an error occured when parsing <paramref name="jsonString"/>.</exception>
  62. public static Module BuildJsonModule(Engine engine, ResolvedSpecifier resolved, string jsonString)
  63. {
  64. var source = resolved.Uri?.LocalPath;
  65. JsValue module;
  66. try
  67. {
  68. module = new JsonParser(engine).Parse(jsonString);
  69. }
  70. catch (Exception)
  71. {
  72. ExceptionHelper.ThrowJavaScriptException(engine, $"Could not load module {source}", (SourceLocation) default);
  73. module = null;
  74. }
  75. return BuildJsonModule(engine, module, resolved.Uri?.LocalPath);
  76. }
  77. /// <summary>
  78. /// Creates a <see cref="Module"/> for the usage within the given <paramref name="engine"/>
  79. /// from the parsed JSON provided in <paramref name="parsedJson"/>.
  80. /// </summary>
  81. /// <remarks>
  82. /// The returned modules location (see <see cref="Module.Location"/>) will be set
  83. /// to <paramref name="location"/>.
  84. /// </remarks>
  85. public static Module BuildJsonModule(Engine engine, JsValue parsedJson, string? location)
  86. {
  87. return new SyntheticModule(engine, engine.Realm, parsedJson, location);
  88. }
  89. }