BreakPointCollection.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System.Collections;
  2. namespace Jint.Runtime.Debugger
  3. {
  4. /// <summary>
  5. /// Collection of breakpoints.
  6. /// </summary>
  7. /// <remarks>
  8. /// Only allows a single breakpoint at the same location (source, column and line).
  9. /// Adding a new breakpoint at the same location <i>replaces</i> the old one - this allows replacing e.g. a
  10. /// conditional breakpoint with a new condition (or remove the condition).
  11. /// </remarks>
  12. public sealed class BreakPointCollection : IEnumerable<BreakPoint>
  13. {
  14. private readonly Dictionary<BreakLocation, BreakPoint> _breakPoints = new(new OptionalSourceBreakLocationEqualityComparer());
  15. public BreakPointCollection()
  16. {
  17. }
  18. /// <summary>
  19. /// Gets or sets whether breakpoints are activated. When false, all breakpoints will fail to match (and be skipped by the debugger).
  20. /// </summary>
  21. public bool Active { get; set; } = true;
  22. public int Count => _breakPoints.Count;
  23. /// <summary>
  24. /// Sets a new breakpoint. Note that this will replace any breakpoint at the same location (source/column/line).
  25. /// </summary>
  26. public void Set(BreakPoint breakPoint)
  27. {
  28. _breakPoints[breakPoint.Location] = breakPoint;
  29. }
  30. /// <summary>
  31. /// Removes breakpoint with the given location (source/column/line).
  32. /// Note that a null source matches <i>any</i> source.
  33. /// </summary>
  34. public bool RemoveAt(BreakLocation location)
  35. {
  36. return _breakPoints.Remove(location);
  37. }
  38. /// <summary>
  39. /// Checks whether collection contains a breakpoint at the given location (source/column/line).
  40. /// Note that a null source matches <i>any</i> source.
  41. /// </summary>
  42. public bool Contains(BreakLocation location)
  43. {
  44. return _breakPoints.ContainsKey(location);
  45. }
  46. /// <summary>
  47. /// Removes all breakpoints.
  48. /// </summary>
  49. public void Clear()
  50. {
  51. _breakPoints.Clear();
  52. }
  53. internal BreakPoint? FindMatch(DebugHandler debugger, BreakLocation location)
  54. {
  55. if (!Active)
  56. {
  57. return null;
  58. }
  59. if (!_breakPoints.TryGetValue(location, out var breakPoint))
  60. {
  61. return null;
  62. }
  63. if (!string.IsNullOrEmpty(breakPoint.Condition))
  64. {
  65. try
  66. {
  67. var completionValue = debugger.Evaluate(breakPoint.Condition!);
  68. // Truthiness check:
  69. if (!TypeConverter.ToBoolean(completionValue))
  70. {
  71. return null;
  72. }
  73. }
  74. catch (Exception ex) when (ex is JavaScriptException || ex is DebugEvaluationException)
  75. {
  76. // Error in the condition means it doesn't match - shouldn't actually throw.
  77. return null;
  78. }
  79. }
  80. return breakPoint;
  81. }
  82. public IEnumerator<BreakPoint> GetEnumerator()
  83. {
  84. return _breakPoints.Values.GetEnumerator();
  85. }
  86. IEnumerator IEnumerable.GetEnumerator()
  87. {
  88. return _breakPoints.GetEnumerator();
  89. }
  90. }
  91. }