ModuleFactory.cs 4.0 KB

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