ModuleLoader.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using Esprima;
  2. using Jint.Native;
  3. using Jint.Native.Json;
  4. namespace Jint.Runtime.Modules;
  5. /// <summary>
  6. /// Base template for module loaders.
  7. /// </summary>
  8. public abstract class ModuleLoader : IModuleLoader
  9. {
  10. public abstract ResolvedSpecifier Resolve(string? referencingModuleLocation, ModuleRequest moduleRequest);
  11. public Module LoadModule(Engine engine, ResolvedSpecifier resolved)
  12. {
  13. string code;
  14. try
  15. {
  16. code = LoadModuleContents(engine, resolved);
  17. }
  18. catch (Exception)
  19. {
  20. ExceptionHelper.ThrowJavaScriptException(engine, $"Could not load module {resolved.ModuleRequest.Specifier}", (Location) default);
  21. return default!;
  22. }
  23. var isJson = resolved.ModuleRequest.Attributes != null
  24. && Array.Exists(resolved.ModuleRequest.Attributes, x => string.Equals(x.Key, "type", StringComparison.Ordinal) && string.Equals(x.Value, "json", StringComparison.Ordinal));
  25. Module moduleRecord = isJson
  26. ? BuildJsonModule(engine, resolved, code)
  27. : BuildSourceTextModule(engine, resolved, code);
  28. return moduleRecord;
  29. }
  30. protected abstract string LoadModuleContents(Engine engine, ResolvedSpecifier resolved);
  31. private static SyntheticModule BuildJsonModule(Engine engine, ResolvedSpecifier resolved, string code)
  32. {
  33. var source = resolved.Uri?.LocalPath;
  34. JsValue module;
  35. try
  36. {
  37. module = new JsonParser(engine).Parse(code);
  38. }
  39. catch (Exception)
  40. {
  41. ExceptionHelper.ThrowJavaScriptException(engine, $"Could not load module {source}", (Location) default);
  42. module = null;
  43. }
  44. return new SyntheticModule(engine, engine.Realm, module, resolved.Uri?.LocalPath);
  45. }
  46. private static SourceTextModule BuildSourceTextModule(Engine engine, ResolvedSpecifier resolved, string code)
  47. {
  48. var source = resolved.Uri?.LocalPath;
  49. Esprima.Ast.Module module;
  50. try
  51. {
  52. module = new JavaScriptParser().ParseModule(code, source);
  53. }
  54. catch (ParserException ex)
  55. {
  56. ExceptionHelper.ThrowSyntaxError(engine.Realm, $"Error while loading module: error in module '{source}': {ex.Error}");
  57. module = null;
  58. }
  59. catch (Exception)
  60. {
  61. ExceptionHelper.ThrowJavaScriptException(engine, $"Could not load module {source}", (Location) default);
  62. module = null;
  63. }
  64. return new SourceTextModule(engine, engine.Realm, module, resolved.Uri?.LocalPath, async: false);
  65. }
  66. }