ModuleLoader.cs 2.6 KB

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