LCOV - code coverage report
Current view: top level - string_scanner-1.1.0/lib/src - span_scanner.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 16 37 43.2 %
Date: 2021-11-28 14:37:50 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import 'package:source_span/source_span.dart';
       6             : 
       7             : import 'eager_span_scanner.dart';
       8             : import 'exception.dart';
       9             : import 'line_scanner.dart';
      10             : import 'relative_span_scanner.dart';
      11             : import 'string_scanner.dart';
      12             : import 'utils.dart';
      13             : 
      14             : /// A subclass of [LineScanner] that exposes matched ranges as source map
      15             : /// [FileSpan]s.
      16             : class SpanScanner extends StringScanner implements LineScanner {
      17             :   /// The source of the scanner.
      18             :   ///
      19             :   /// This caches line break information and is used to generate [FileSpan]s.
      20             :   final SourceFile _sourceFile;
      21             : 
      22           0 :   @override
      23           0 :   int get line => _sourceFile.getLine(position);
      24           0 :   @override
      25           0 :   int get column => _sourceFile.getColumn(position);
      26             : 
      27           5 :   @override
      28          10 :   LineScannerState get state => _SpanScannerState(this, position);
      29             : 
      30           0 :   @override
      31             :   set state(LineScannerState state) {
      32           0 :     if (state is! _SpanScannerState || !identical(state._scanner, this)) {
      33           0 :       throw ArgumentError('The given LineScannerState was not returned by '
      34             :           'this LineScanner.');
      35             :     }
      36             : 
      37           0 :     position = state.position;
      38             :   }
      39             : 
      40             :   /// The [FileSpan] for [lastMatch].
      41             :   ///
      42             :   /// This is the span for the entire match. There's no way to get spans for
      43             :   /// subgroups since [Match] exposes no information about their positions.
      44           5 :   FileSpan? get lastSpan {
      45           5 :     if (lastMatch == null) _lastSpan = null;
      46           5 :     return _lastSpan;
      47             :   }
      48             : 
      49             :   FileSpan? _lastSpan;
      50             : 
      51             :   /// The current location of the scanner.
      52           0 :   FileLocation get location => _sourceFile.location(position);
      53             : 
      54             :   /// Returns an empty span at the current location.
      55           0 :   FileSpan get emptySpan => location.pointSpan();
      56             : 
      57             :   /// Creates a new [SpanScanner] that starts scanning from [position].
      58             :   ///
      59             :   /// [sourceUrl] is used as [SourceLocation.sourceUrl] for the returned
      60             :   /// [FileSpan]s as well as for error reporting. It can be a [String], a
      61             :   /// [Uri], or `null`.
      62           5 :   SpanScanner(String string, {sourceUrl, int? position})
      63           5 :       : _sourceFile = SourceFile.fromString(string, url: sourceUrl),
      64           5 :         super(string, sourceUrl: sourceUrl, position: position);
      65             : 
      66             :   /// Creates a new [SpanScanner] that eagerly computes line and column numbers.
      67             :   ///
      68             :   /// In general [new SpanScanner] will be more efficient, since it avoids extra
      69             :   /// computation on every scan. However, eager scanning can be useful for
      70             :   /// situations where the normal course of parsing frequently involves
      71             :   /// accessing the current line and column numbers.
      72             :   ///
      73             :   /// Note that *only* the `line` and `column` fields on the `SpanScanner`
      74             :   /// itself and its `LineScannerState` are eagerly computed. To limit their
      75             :   /// memory footprint, returned spans and locations will still lazily compute
      76             :   /// their line and column numbers.
      77             :   factory SpanScanner.eager(String string, {sourceUrl, int? position}) =
      78             :       EagerSpanScanner;
      79             : 
      80             :   /// Creates a new [SpanScanner] that scans within [span].
      81             :   ///
      82             :   /// This scans through [span]`.text, but emits new spans from [span]`.file` in
      83             :   /// their appropriate relative positions. The [string] field contains only
      84             :   /// [span]`.text`, and [position], [line], and [column] are all relative to
      85             :   /// the span.
      86             :   factory SpanScanner.within(FileSpan span) = RelativeSpanScanner;
      87             : 
      88             :   /// Creates a [FileSpan] representing the source range between [startState]
      89             :   /// and the current position.
      90           5 :   FileSpan spanFrom(LineScannerState startState, [LineScannerState? endState]) {
      91           5 :     final endPosition = endState == null ? position : endState.position;
      92          15 :     return _sourceFile.span(startState.position, endPosition);
      93             :   }
      94             : 
      95           5 :   @override
      96             :   bool matches(Pattern pattern) {
      97           5 :     if (!super.matches(pattern)) {
      98           5 :       _lastSpan = null;
      99             :       return false;
     100             :     }
     101             : 
     102          30 :     _lastSpan = _sourceFile.span(position, lastMatch!.end);
     103             :     return true;
     104             :   }
     105             : 
     106           0 :   @override
     107             :   Never error(String message, {Match? match, int? position, int? length}) {
     108           0 :     validateErrorArgs(string, match, position, length);
     109             : 
     110           0 :     if (match == null && position == null && length == null) match = lastMatch;
     111           0 :     position ??= match == null ? this.position : match.start;
     112           0 :     length ??= match == null ? 0 : match.end - match.start;
     113             : 
     114           0 :     final span = _sourceFile.span(position, position + length);
     115           0 :     throw StringScannerException(message, span, string);
     116             :   }
     117             : }
     118             : 
     119             : /// A class representing the state of a [SpanScanner].
     120             : class _SpanScannerState implements LineScannerState {
     121             :   /// The [SpanScanner] that created this.
     122             :   final SpanScanner _scanner;
     123             : 
     124             :   @override
     125             :   final int position;
     126           0 :   @override
     127           0 :   int get line => _scanner._sourceFile.getLine(position);
     128           0 :   @override
     129           0 :   int get column => _scanner._sourceFile.getColumn(position);
     130             : 
     131           5 :   _SpanScannerState(this._scanner, this.position);
     132             : }

Generated by: LCOV version 1.14