| // Copyright (c) 2018, 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. |
| |
| /// Utility functions to make it easier to work with source-map files. |
| import 'package:source_span/source_span.dart'; |
| import 'package:source_maps/source_maps.dart'; |
| import 'package:source_maps/src/utils.dart'; |
| import 'util.dart' show FileProvider; |
| |
| /// Search backwards in [sources] for a function declaration that includes the |
| /// [start] offset. |
| TargetEntry findEnclosingFunction(FileProvider provider, Uri uri, int start) { |
| String sources = provider.sourcesFor(uri); |
| if (sources == null) return null; |
| SourceFile file = provider.fileFor(uri); |
| SingleMapping mapping = provider.mappingFor(uri).sourceMap; |
| int index = start; |
| while (true) { |
| index = sources.lastIndexOf('function', index); |
| if (index < 0) return null; |
| var line = file.getLine(index); |
| var lineEntry = findLine(mapping, line); |
| var column = file.getColumn(index); |
| TargetEntry result = findColumn(line, column, lineEntry); |
| // If the name entry doesn't start exactly at the column corresponding to |
| // `index`, we must be in the middle of a string or code that uses the word |
| // "function", but that doesn't have a corresponding mapping. In those |
| // cases, we keep searching backwards until we find the actual definition of |
| // a function. |
| if (result?.column == column) return result; |
| index--; |
| } |
| } |
| |
| /// Returns [TargetLineEntry] which includes the location in the target [line] |
| /// number. In particular, the resulting entry is the last entry whose line |
| /// number is lower or equal to [line]. |
| /// |
| /// Copied from [SingleMapping._findLine]. |
| TargetLineEntry findLine(SingleMapping sourceMap, int line) { |
| int index = binarySearch(sourceMap.lines, (e) => e.line > line); |
| return (index <= 0) ? null : sourceMap.lines[index - 1]; |
| } |
| |
| /// Returns [TargetEntry] which includes the location denoted by |
| /// [line], [column]. If [lineEntry] corresponds to [line], then this will be |
| /// the last entry whose column is lower or equal than [column]. If |
| /// [lineEntry] corresponds to a line prior to [line], then the result will be |
| /// the very last entry on that line. |
| /// |
| /// Copied from [SingleMapping._findColumn]. |
| TargetEntry findColumn(int line, int column, TargetLineEntry lineEntry) { |
| if (lineEntry == null || lineEntry.entries.length == 0) return null; |
| if (lineEntry.line != line) return lineEntry.entries.last; |
| var entries = lineEntry.entries; |
| int index = binarySearch(entries, (e) => e.column > column); |
| return (index <= 0) ? null : entries[index - 1]; |
| } |