blob: 7e01953a0e249fe663287dd90921cb1e5a5ad4e7 [file] [log] [blame]
// 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;
int index = sources.lastIndexOf(': function(', start);
if (index < 0) index = sources.lastIndexOf(':function(', start);
if (index < 0) return null;
index += 2;
SourceFile file = provider.fileFor(uri);
SingleMapping mapping = provider.mappingFor(uri).sourceMap;
var line = file.getLine(index);
var lineEntry = findLine(mapping, line);
return findColumn(line, file.getColumn(index), lineEntry);
}
/// 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];
}