DebugScope.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using Jint.Native;
  2. using Jint.Native.Object;
  3. using Jint.Runtime.Environments;
  4. using Environment = Jint.Runtime.Environments.Environment;
  5. namespace Jint.Runtime.Debugger
  6. {
  7. /// <summary>
  8. /// Scope information, bindings, and values for a single scope in the scope chain
  9. /// </summary>
  10. public sealed class DebugScope
  11. {
  12. private readonly Environment _record;
  13. private string[]? _bindingNames;
  14. internal DebugScope(DebugScopeType type, Environment record, bool isTopLevel)
  15. {
  16. ScopeType = type;
  17. _record = record;
  18. BindingObject = record is ObjectEnvironment objEnv ? objEnv._bindingObject : null;
  19. IsTopLevel = isTopLevel;
  20. }
  21. /// <summary>
  22. /// The type of scope. Scope types are the same as defined by Chrome devtools protocol.
  23. /// </summary>
  24. public DebugScopeType ScopeType { get; }
  25. /// <summary>
  26. /// For <see cref="DebugScopeType.Block">block</see> scopes, indicates whether this scope is at the top level of a containing function.
  27. /// </summary>
  28. /// <remarks>
  29. /// Block scopes at the top level of a function are combined with Local scope in Chromium.
  30. /// This property facilitates implementing the same "flattening" in e.g. a UI. Because empty scopes are excluded in the scope chain,
  31. /// top level cannot be determined from the scope chain order alone.
  32. /// </remarks>
  33. public bool IsTopLevel { get; }
  34. /// <summary>
  35. /// Names of all bindings in the scope.
  36. /// </summary>
  37. public IReadOnlyList<string> BindingNames => _bindingNames ??= _record.GetAllBindingNames();
  38. /// <summary>
  39. /// Binding object for ObjectEnvironmentRecords - that is, Global scope and With scope. Null for other scopes.
  40. /// </summary>
  41. /// <remarks>
  42. /// This is mainly useful as an optimization for devtools, allowing the BindingObject to be serialized directly rather than
  43. /// building a new transient object in response to e.g. Runtime.getProperties.
  44. /// </remarks>
  45. public ObjectInstance? BindingObject { get; }
  46. /// <summary>
  47. /// Retrieves the value of a specific binding. Note that some bindings (e.g. uninitialized let/const) may return null.
  48. /// </summary>
  49. /// <param name="name">Binding name</param>
  50. /// <returns>Value of the binding</returns>
  51. public JsValue? GetBindingValue(string name)
  52. {
  53. _record.TryGetBinding(new Environment.BindingName(name), out var result);
  54. return result;
  55. }
  56. /// <summary>
  57. /// Sets the value of an existing binding.
  58. /// </summary>
  59. /// <param name="name">Binding name</param>
  60. /// <param name="value">New value of the binding</param>
  61. public void SetBindingValue(string name, JsValue value)
  62. {
  63. _record.SetMutableBinding(name, value, strict: true);
  64. }
  65. }
  66. }