BreakPointCollection.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. public bool IsReadOnly => false;
  24. /// <summary>
  25. /// Sets a new breakpoint. Note that this will replace any breakpoint at the same location (source/column/line).
  26. /// </summary>
  27. public void Set(BreakPoint breakPoint)
  28. {
  29. _breakPoints[breakPoint.Location] = breakPoint;
  30. }
  31. /// <summary>
  32. /// Removes breakpoint with the given location (source/column/line).
  33. /// Note that a null source matches <i>any</i> source.
  34. /// </summary>
  35. public bool RemoveAt(BreakLocation location)
  36. {
  37. return _breakPoints.Remove(location);
  38. }
  39. /// <summary>
  40. /// Checks whether collection contains a breakpoint at the given location (source/column/line).
  41. /// Note that a null source matches <i>any</i> source.
  42. /// </summary>
  43. public bool Contains(BreakLocation location)
  44. {
  45. return _breakPoints.ContainsKey(location);
  46. }
  47. /// <summary>
  48. /// Removes all breakpoints.
  49. /// </summary>
  50. public void Clear()
  51. {
  52. _breakPoints.Clear();
  53. }
  54. internal BreakPoint? FindMatch(DebugHandler debugger, BreakLocation location)
  55. {
  56. if (!Active)
  57. {
  58. return null;
  59. }
  60. if (!_breakPoints.TryGetValue(location, out var breakPoint))
  61. {
  62. return null;
  63. }
  64. if (!string.IsNullOrEmpty(breakPoint.Condition))
  65. {
  66. try
  67. {
  68. var completionValue = debugger.Evaluate(breakPoint.Condition!);
  69. // Truthiness check:
  70. if (!TypeConverter.ToBoolean(completionValue))
  71. {
  72. return null;
  73. }
  74. }
  75. catch (Exception ex) when (ex is JavaScriptException || ex is DebugEvaluationException)
  76. {
  77. // Error in the condition means it doesn't match - shouldn't actually throw.
  78. return null;
  79. }
  80. }
  81. return breakPoint;
  82. }
  83. public IEnumerator<BreakPoint> GetEnumerator()
  84. {
  85. return _breakPoints.Values.GetEnumerator();
  86. }
  87. IEnumerator IEnumerable.GetEnumerator()
  88. {
  89. return _breakPoints.GetEnumerator();
  90. }
  91. }
  92. }