DebugScope.cs 2.7 KB

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