| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:dwds/src/debugging/location.dart'; |
| |
| const maxValue = 2147483647; |
| |
| class SkipLists { |
| // Map of script ID to scriptList. |
| final _idToList = <String, List<Map<String, dynamic>>>{}; |
| |
| void initialize() => _idToList.clear(); |
| |
| /// Returns a skipList as defined by the Chrome DevTools Protocol. |
| /// |
| /// A `skipList` is an array of `LocationRange`s see: |
| /// https://chromedevtools.github.io/devtools-protocol/tot/Debugger/#method-stepInto |
| /// |
| /// Can return a cached value. |
| List<Map<String, dynamic>> compute( |
| String scriptId, |
| Set<Location> locations, |
| ) { |
| if (_idToList.containsKey(scriptId)) return _idToList[scriptId]!; |
| |
| final sortedLocations = locations.toList() |
| ..sort((a, b) => a.jsLocation.compareTo(b.jsLocation)); |
| |
| final ranges = <Map<String, dynamic>>[]; |
| var startLine = 0; |
| var startColumn = 0; |
| for (var location in sortedLocations) { |
| var endLine = location.jsLocation.line; |
| var endColumn = location.jsLocation.column; |
| // Stop before the known location. |
| endColumn -= 1; |
| if (endColumn < 0) { |
| endLine -= 1; |
| endColumn = maxValue; |
| } |
| if (endLine > startLine || endColumn > startColumn) { |
| if (endLine >= startLine) { |
| ranges.add( |
| _rangeFor(scriptId, startLine, startColumn, endLine, endColumn)); |
| } |
| startLine = location.jsLocation.line; |
| startColumn = location.jsLocation.column + 1; |
| } |
| } |
| ranges.add(_rangeFor(scriptId, startLine, startColumn, maxValue, maxValue)); |
| |
| _idToList[scriptId] = ranges; |
| return ranges; |
| } |
| |
| Map<String, dynamic> _rangeFor( |
| String scriptId, |
| int startLine, |
| int startColumn, |
| int endLine, |
| int endColumn, |
| ) => |
| { |
| 'scriptId': scriptId, |
| 'start': {'lineNumber': startLine, 'columnNumber': startColumn}, |
| 'end': {'lineNumber': endLine, 'columnNumber': endColumn} |
| }; |
| } |