Merge the null_safety branch into master (#56)
diff --git a/.travis.yml b/.travis.yml
index 9738ed5..8361c62 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,24 +1,38 @@
language: dart
dart:
- - dev
- - 2.6.0
+- dev
-dart_task:
- - test: --platform vm,chrome
-
-matrix:
+jobs:
include:
- # Only validate formatting using the dev release
- - dart: dev
- dart_task: dartfmt
- - dart: dev
- dart_task:
- dartanalyzer: --fatal-warnings --fatal-infos .
+ - stage: analyze_and_format
+ name: "Analyze test/"
+ dart: dev
+ os: linux
+ script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos .
+ - stage: analyze_and_format
+ name: "Format"
+ dart: dev
+ os: linux
+ script: dartfmt -n --set-exit-if-changed .
+ - stage: test
+ name: "Vm Tests"
+ dart: dev
+ os: linux
+ script: pub run --enable-experiment=non-nullable test -p vm
+ - stage: test
+ name: "Web Tests"
+ dart: dev
+ os: linux
+ script: pub run --enable-experiment=non-nullable test -p chrome
+
+stages:
+ - analyze_and_format
+ - test
# Only building master means that we don't run two builds for each pull request.
branches:
- only: [master]
+ only: [master, null_safety]
cache:
directories:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5da330e..1723b0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+# 1.8.0-nullsafety
+
+* Migrate to null safety.
+ * Apis have been migrated to reflect the existing assumptions in the code
+ and are not expected to be breaking.
+
# 1.7.0
* Add a `SourceSpan.subspan()` extension method which returns a slice of an
diff --git a/analysis_options.yaml b/analysis_options.yaml
index ab5a4f2..ced2e21 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -2,6 +2,8 @@
analyzer:
strong-mode:
implicit-casts: false
+ enable-experiment:
+ - non-nullable
linter:
rules:
- always_declare_return_types
diff --git a/lib/src/file.dart b/lib/src/file.dart
index 9ad595c..6fbcd41 100644
--- a/lib/src/file.dart
+++ b/lib/src/file.dart
@@ -23,7 +23,7 @@
/// The URL where the source file is located.
///
/// This may be null, indicating that the URL is unknown or unavailable.
- final Uri url;
+ final Uri? url;
/// An array of offsets for each line beginning in the file.
///
@@ -47,7 +47,7 @@
/// increasing offsets. In that case, we can find the line for an offset
/// quickly by first checking to see if the offset is on the same line as the
/// previous result.
- int _cachedLine;
+ int? _cachedLine;
/// This constructor is deprecated.
///
@@ -71,7 +71,7 @@
/// forwards-compatibility, callers should only pass in characters less than
/// or equal to `0xFFFF`.
SourceFile.decoded(Iterable<int> decodedChars, {url})
- : url = url is String ? Uri.parse(url) : url as Uri,
+ : url = url is String ? Uri.parse(url) : url as Uri?,
_decodedChars = Uint32List.fromList(decodedChars.toList()) {
for (var i = 0; i < _decodedChars.length; i++) {
var c = _decodedChars[i];
@@ -87,7 +87,7 @@
/// Returns a span from [start] to [end] (exclusive).
///
/// If [end] isn't passed, it defaults to the end of the file.
- FileSpan span(int start, [int end]) {
+ FileSpan span(int start, [int? end]) {
end ??= length;
return _FileSpan(this, start, end);
}
@@ -107,10 +107,10 @@
if (offset < _lineStarts.first) return -1;
if (offset >= _lineStarts.last) return _lineStarts.length - 1;
- if (_isNearCachedLine(offset)) return _cachedLine;
+ if (_isNearCachedLine(offset)) return _cachedLine!;
_cachedLine = _binarySearch(offset) - 1;
- return _cachedLine;
+ return _cachedLine!;
}
/// Returns `true` if [offset] is near [_cachedLine].
@@ -119,20 +119,21 @@
/// updates [_cachedLine] to point to that.
bool _isNearCachedLine(int offset) {
if (_cachedLine == null) return false;
+ final cachedLine = _cachedLine!;
// See if it's before the cached line.
- if (offset < _lineStarts[_cachedLine]) return false;
+ if (offset < _lineStarts[cachedLine]) return false;
// See if it's on the cached line.
- if (_cachedLine >= _lineStarts.length - 1 ||
- offset < _lineStarts[_cachedLine + 1]) {
+ if (cachedLine >= _lineStarts.length - 1 ||
+ offset < _lineStarts[cachedLine + 1]) {
return true;
}
// See if it's on the next line.
- if (_cachedLine >= _lineStarts.length - 2 ||
- offset < _lineStarts[_cachedLine + 2]) {
- _cachedLine++;
+ if (cachedLine >= _lineStarts.length - 2 ||
+ offset < _lineStarts[cachedLine + 2]) {
+ _cachedLine = cachedLine + 1;
return true;
}
@@ -161,7 +162,7 @@
///
/// If [line] is passed, it's assumed to be the line containing [offset] and
/// is used to more efficiently compute the column.
- int getColumn(int offset, {int line}) {
+ int getColumn(int offset, {int? line}) {
if (offset < 0) {
throw RangeError('Offset may not be negative, was $offset.');
} else if (offset > length) {
@@ -189,7 +190,7 @@
/// Gets the offset for a [line] and [column].
///
/// [column] defaults to 0.
- int getOffset(int line, [int column]) {
+ int getOffset(int line, [int? column]) {
column ??= 0;
if (line < 0) {
@@ -213,7 +214,7 @@
/// Returns the text of the file from [start] to [end] (exclusive).
///
/// If [end] isn't passed, it defaults to the end of the file.
- String getText(int start, [int end]) =>
+ String getText(int start, [int? end]) =>
String.fromCharCodes(_decodedChars.sublist(start, end));
}
@@ -231,7 +232,7 @@
final int offset;
@override
- Uri get sourceUrl => file.url;
+ Uri? get sourceUrl => file.url;
@override
int get line => file.getLine(offset);
@@ -299,7 +300,7 @@
final int _end;
@override
- Uri get sourceUrl => file.url;
+ Uri? get sourceUrl => file.url;
@override
int get length => _end - _start;
@@ -318,7 +319,7 @@
final endLine = file.getLine(_end);
final endColumn = file.getColumn(_end);
- int endOffset;
+ int? endOffset;
if (endColumn == 0 && endLine != 0) {
// If [end] is at the very beginning of the line, the span covers the
// previous newline, so we only want to include the previous line in the
@@ -362,16 +363,15 @@
int compareTo(SourceSpan other) {
if (other is! _FileSpan) return super.compareTo(other);
- final otherFile = other as _FileSpan;
- final result = _start.compareTo(otherFile._start);
- return result == 0 ? _end.compareTo(otherFile._end) : result;
+ final result = _start.compareTo(other._start);
+ return result == 0 ? _end.compareTo(other._end) : result;
}
@override
SourceSpan union(SourceSpan other) {
if (other is! FileSpan) return super.union(other);
- final span = expand(other as _FileSpan);
+ final span = expand(other);
if (other is _FileSpan) {
if (_start > other._end || other._start > _end) {
@@ -425,7 +425,7 @@
}
/// See `SourceSpanExtension.subspan`.
- FileSpan subspan(int start, [int end]) {
+ FileSpan subspan(int start, [int? end]) {
RangeError.checkValidRange(start, end, length);
if (start == 0 && (end == null || end == length)) return this;
return file.span(_start + start, end == null ? _end : _start + end);
@@ -436,7 +436,7 @@
/// Extension methods on the [FileSpan] API.
extension FileSpanExtension on FileSpan {
/// See `SourceSpanExtension.subspan`.
- FileSpan subspan(int start, [int end]) {
+ FileSpan subspan(int start, [int? end]) {
RangeError.checkValidRange(start, end, length);
if (start == 0 && (end == null || end == length)) return this;
diff --git a/lib/src/highlighter.dart b/lib/src/highlighter.dart
index cef6f79..491dae5 100644
--- a/lib/src/highlighter.dart
+++ b/lib/src/highlighter.dart
@@ -6,7 +6,6 @@
import 'package:charcode/charcode.dart';
import 'package:collection/collection.dart';
-import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:term_glyph/term_glyph.dart' as glyph;
@@ -23,11 +22,11 @@
/// The color to highlight the primary [_Highlight] within its context, or
/// `null` if it should not be colored.
- final String _primaryColor;
+ final String? _primaryColor;
/// The color to highlight the secondary [_Highlight]s within their context,
/// or `null` if they should not be colored.
- final String _secondaryColor;
+ final String? _secondaryColor;
/// The number of characters before the bar in the sidebar.
final int _paddingBeforeSidebar;
@@ -63,7 +62,7 @@
: this._(_collateLines([_Highlight(span, primary: true)]), () {
if (color == true) return colors.red;
if (color == false) return null;
- return color as String;
+ return color as String?;
}(), null);
/// Creates a [Highlighter] that will return a string highlighting
@@ -83,7 +82,7 @@
/// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
Highlighter.multiple(SourceSpan primarySpan, String primaryLabel,
Map<SourceSpan, String> secondarySpans,
- {bool color = false, String primaryColor, String secondaryColor})
+ {bool color = false, String? primaryColor, String? secondaryColor})
: this._(
_collateLines([
_Highlight(primarySpan, label: primaryLabel, primary: true),
@@ -108,7 +107,8 @@
.where((highlight) => isMultiline(highlight.span))
.length)
.reduce(math.max),
- _multipleFiles = !isAllTheSame(_lines.map((line) => line.url));
+ _multipleFiles =
+ !isAllTheSame(_lines.map((line) => line.url).whereType<Uri>());
/// Returns whether [lines] contains any adjacent lines from the same source
/// file that aren't adjacent in the original file.
@@ -127,8 +127,8 @@
/// Collect all the source lines from the contexts of all spans in
/// [highlights], and associates them with the highlights that cover them.
static List<_Line> _collateLines(List<_Highlight> highlights) {
- final highlightsByUrl =
- groupBy(highlights, (highlight) => highlight.span.sourceUrl);
+ final highlightsByUrl = groupBy<_Highlight, Uri?>(
+ highlights, (highlight) => highlight.span.sourceUrl);
for (var list in highlightsByUrl.values) {
list.sort((highlight1, highlight2) =>
highlight1.span.compareTo(highlight2.span));
@@ -143,8 +143,7 @@
// If [highlight.span.context] contains lines prior to the one
// [highlight.span.text] appears on, write those first.
final lineStart = findLineStart(
- context, highlight.span.text, highlight.span.start.column);
- assert(lineStart != null); // enforced by [_normalizeContext]
+ context, highlight.span.text, highlight.span.start.column)!;
final linesBeforeSpan =
'\n'.allMatches(context.substring(0, lineStart)).length;
@@ -192,7 +191,8 @@
// Each index of this list represents a column after the sidebar that could
// contain a line indicating an active highlight. If it's `null`, that
// column is empty; if it contains a highlight, it should be drawn for that column.
- final highlightsByColumn = List<_Highlight>(_maxMultilineSpans);
+ final highlightsByColumn =
+ List<_Highlight?>.filled(_maxMultilineSpans, null);
for (var i = 0; i < _lines.length; i++) {
final line = _lines[i];
@@ -226,8 +226,10 @@
_writeMultilineHighlights(line, highlightsByColumn);
if (highlightsByColumn.isNotEmpty) _buffer.write(' ');
- final primary = line.highlights
- .firstWhere((highlight) => highlight.isPrimary, orElse: () => null);
+ final primaryIdx =
+ line.highlights.indexWhere((highlight) => highlight.isPrimary);
+ final primary = primaryIdx == -1 ? null : line.highlights[primaryIdx];
+
if (primary != null) {
_writeHighlightedText(
line.text,
@@ -258,7 +260,7 @@
/// Writes the beginning of the file highlight for the file with the given
/// [url].
- void _writeFileStart(Uri url) {
+ void _writeFileStart(Uri? url) {
if (!_multipleFiles || url == null) {
_writeSidebar(end: glyph.downEnd);
} else {
@@ -277,20 +279,20 @@
/// written. If it appears in [highlightsByColumn], a horizontal line is
/// written from its column to the rightmost column.
void _writeMultilineHighlights(
- _Line line, List<_Highlight> highlightsByColumn,
- {_Highlight current}) {
+ _Line line, List<_Highlight?> highlightsByColumn,
+ {_Highlight? current}) {
// Whether we've written a sidebar indicator for opening a new span on this
// line, and which color should be used for that indicator's rightward line.
var openedOnThisLine = false;
- String openedOnThisLineColor;
+ String? openedOnThisLineColor;
final currentColor = current == null
? null
: current.isPrimary ? _primaryColor : _secondaryColor;
var foundCurrent = false;
for (var highlight in highlightsByColumn) {
- final startLine = highlight?.span?.start?.line;
- final endLine = highlight?.span?.end?.line;
+ final startLine = highlight?.span.start.line;
+ final endLine = highlight?.span.end.line;
if (current != null && highlight == current) {
foundCurrent = true;
assert(startLine == line.number || endLine == line.number);
@@ -322,9 +324,9 @@
}, color: openedOnThisLineColor);
openedOnThisLine = true;
openedOnThisLineColor ??=
- highlight.isPrimary ? _primaryColor : _secondaryColor;
+ highlight!.isPrimary ? _primaryColor : _secondaryColor;
} else if (endLine == line.number &&
- highlight.span.end.column == line.text.length) {
+ highlight!.span.end.column == line.text.length) {
_buffer.write(highlight.label == null
? glyph.glyphOrAscii('└', '\\')
: vertical);
@@ -341,7 +343,7 @@
// Writes [text], with text between [startColumn] and [endColumn] colorized in
// the same way as [_colorize].
void _writeHighlightedText(String text, int startColumn, int endColumn,
- {@required String color}) {
+ {required String? color}) {
_writeText(text.substring(0, startColumn));
_colorize(() => _writeText(text.substring(startColumn, endColumn)),
color: color);
@@ -353,7 +355,7 @@
///
/// This may either add or remove [highlight] from [highlightsByColumn].
void _writeIndicator(
- _Line line, _Highlight highlight, List<_Highlight> highlightsByColumn) {
+ _Line line, _Highlight highlight, List<_Highlight?> highlightsByColumn) {
final color = highlight.isPrimary ? _primaryColor : _secondaryColor;
if (!isMultiline(highlight.span)) {
_writeSidebar();
@@ -436,7 +438,7 @@
}
/// Writes a space followed by [label] if [label] isn't `null`.
- void _writeLabel(String label) {
+ void _writeLabel(String? label) {
if (label != null) _buffer.write(' $label');
}
@@ -457,7 +459,7 @@
//
// If [text] is given, it's used in place of the line number. It can't be
// passed at the same time as [line].
- void _writeSidebar({int line, String text, String end}) {
+ void _writeSidebar({int? line, String? text, String? end}) {
assert(line == null || text == null);
// Add 1 to line to convert from computer-friendly 0-indexed line numbers to
@@ -489,7 +491,7 @@
/// Colors all text written to [_buffer] during [callback], if colorization is
/// enabled and [color] is not `null`.
- void _colorize(void Function() callback, {@required String color}) {
+ void _colorize(void Function() callback, {required String? color}) {
if (_primaryColor != null && color != null) _buffer.write(color);
callback();
if (_primaryColor != null && color != null) _buffer.write(colors.none);
@@ -513,7 +515,7 @@
///
/// This helps distinguish clarify what each highlight means when multiple are
/// used in the same message.
- final String label;
+ final String? label;
_Highlight(SourceSpan span, {this.label, bool primary = false})
: span = (() {
@@ -636,7 +638,7 @@
/// Returns whether [span]'s text runs all the way to the end of its context.
static bool _isTextAtEndOfContext(SourceSpanWithContext span) =>
- findLineStart(span.context, span.text, span.start.column) +
+ findLineStart(span.context, span.text, span.start.column)! +
span.start.column +
span.length ==
span.context.length;
@@ -661,7 +663,7 @@
final int number;
/// The URL of the source file in which this line appears.
- final Uri url;
+ final Uri? url;
/// All highlights that cover any portion of this line, in source span order.
///
diff --git a/lib/src/location.dart b/lib/src/location.dart
index 93942f0..0979618 100644
--- a/lib/src/location.dart
+++ b/lib/src/location.dart
@@ -16,7 +16,7 @@
///
/// This may be null, indicating that the source URL is unknown or
/// unavailable.
- final Uri sourceUrl;
+ final Uri? sourceUrl;
/// The 0-based offset of this location in the source.
final int offset;
@@ -42,9 +42,9 @@
/// means that [line] defaults to 0 and [column] defaults to [offset].
///
/// [sourceUrl] may be either a [String], a [Uri], or `null`.
- SourceLocation(this.offset, {sourceUrl, int line, int column})
+ SourceLocation(this.offset, {sourceUrl, int? line, int? column})
: sourceUrl =
- sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri,
+ sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri?,
line = line ?? 0,
column = column ?? offset {
if (offset < 0) {
@@ -89,7 +89,7 @@
offset == other.offset;
@override
- int get hashCode => sourceUrl.hashCode + offset;
+ int get hashCode => (sourceUrl?.hashCode ?? 0) + offset;
@override
String toString() => '<$runtimeType: $offset $toolString>';
@@ -98,6 +98,6 @@
/// A base class for source locations with [offset], [line], and [column] known
/// at construction time.
class SourceLocationBase extends SourceLocation {
- SourceLocationBase(int offset, {sourceUrl, int line, int column})
+ SourceLocationBase(int offset, {sourceUrl, int? line, int? column})
: super(offset, sourceUrl: sourceUrl, line: line, column: column);
}
diff --git a/lib/src/location_mixin.dart b/lib/src/location_mixin.dart
index a54e363..9a1f930 100644
--- a/lib/src/location_mixin.dart
+++ b/lib/src/location_mixin.dart
@@ -48,7 +48,7 @@
offset == other.offset;
@override
- int get hashCode => sourceUrl.hashCode + offset;
+ int get hashCode => (sourceUrl?.hashCode ?? 0) + offset;
@override
String toString() => '<$runtimeType: $offset $toolString>';
diff --git a/lib/src/span.dart b/lib/src/span.dart
index 15f0d34..94c05ba 100644
--- a/lib/src/span.dart
+++ b/lib/src/span.dart
@@ -27,7 +27,7 @@
///
/// This may be null, indicating that the source URL is unknown or
/// unavailable.
- Uri get sourceUrl;
+ Uri? get sourceUrl;
/// The length of this span, in characters.
int get length;
@@ -139,7 +139,7 @@
/// [FileSpan]s).
String messageMultiple(
String message, String label, Map<SourceSpan, String> secondarySpans,
- {bool color = false, String primaryColor, String secondaryColor}) {
+ {bool color = false, String? primaryColor, String? secondaryColor}) {
final buffer = StringBuffer()
..write('line ${start.line + 1}, column ${start.column + 1}');
if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}');
@@ -174,7 +174,7 @@
/// much more useful output with [SourceSpanWithContext]s (including
/// [FileSpan]s).
String highlightMultiple(String label, Map<SourceSpan, String> secondarySpans,
- {bool color = false, String primaryColor, String secondaryColor}) =>
+ {bool color = false, String? primaryColor, String? secondaryColor}) =>
Highlighter.multiple(this, label, secondarySpans,
color: color,
primaryColor: primaryColor,
@@ -183,7 +183,7 @@
/// Returns a span from [start] code units (inclusive) to [end] code units
/// (exclusive) after the beginning of this span.
- SourceSpan subspan(int start, [int end]) {
+ SourceSpan subspan(int start, [int? end]) {
RangeError.checkValidRange(start, end, length);
if (start == 0 && (end == null || end == length)) return this;
@@ -220,7 +220,7 @@
newEndLocation = this.end;
} else if (end == start) {
newEndLocation = newStartLocation;
- } else if (end != null && end != length) {
+ } else {
for (var i = start; i < end; i++) {
consumeCodePoint(i);
}
diff --git a/lib/src/span_exception.dart b/lib/src/span_exception.dart
index 32aaa4e..c6db03b 100644
--- a/lib/src/span_exception.dart
+++ b/lib/src/span_exception.dart
@@ -15,8 +15,8 @@
/// The span associated with this exception.
///
/// This may be `null` if the source location can't be determined.
- SourceSpan get span => _span;
- final SourceSpan _span;
+ SourceSpan? get span => _span;
+ final SourceSpan? _span;
SourceSpanException(this._message, this._span);
@@ -30,7 +30,7 @@
@override
String toString({color}) {
if (span == null) return message;
- return 'Error on ${span.message(message, color: color)}';
+ return 'Error on ${span!.message(message, color: color)}';
}
}
@@ -41,9 +41,9 @@
final dynamic source;
@override
- int get offset => span?.start?.offset;
+ int? get offset => span?.start.offset;
- SourceSpanFormatException(String message, SourceSpan span, [this.source])
+ SourceSpanFormatException(String message, SourceSpan? span, [this.source])
: super(message, span);
}
@@ -64,7 +64,7 @@
/// additional information and helps distinguish it from [secondarySpans].
final Map<SourceSpan, String> secondarySpans;
- MultiSourceSpanException(String message, SourceSpan span, this.primaryLabel,
+ MultiSourceSpanException(String message, SourceSpan? span, this.primaryLabel,
Map<SourceSpan, String> secondarySpans)
: secondarySpans = Map.unmodifiable(secondarySpans),
super(message, span);
@@ -80,11 +80,11 @@
/// If [color] is `true` or a string, [secondaryColor] is used to highlight
/// [secondarySpans].
@override
- String toString({color, String secondaryColor}) {
+ String toString({color, String? secondaryColor}) {
if (span == null) return message;
var useColor = false;
- String primaryColor;
+ String? primaryColor;
if (color is String) {
useColor = true;
primaryColor = color;
@@ -92,7 +92,7 @@
useColor = true;
}
- final formatted = span.messageMultiple(
+ final formatted = span!.messageMultiple(
message, primaryLabel, secondarySpans,
color: useColor,
primaryColor: primaryColor,
@@ -108,9 +108,9 @@
final dynamic source;
@override
- int get offset => span?.start?.offset;
+ int? get offset => span?.start.offset;
- MultiSourceSpanFormatException(String message, SourceSpan span,
+ MultiSourceSpanFormatException(String message, SourceSpan? span,
String primaryLabel, Map<SourceSpan, String> secondarySpans,
[this.source])
: super(message, span, primaryLabel, secondarySpans);
diff --git a/lib/src/span_mixin.dart b/lib/src/span_mixin.dart
index 55eae94..0f751ea 100644
--- a/lib/src/span_mixin.dart
+++ b/lib/src/span_mixin.dart
@@ -17,7 +17,7 @@
/// to the distance between [start] and [end].
abstract class SourceSpanMixin implements SourceSpan {
@override
- Uri get sourceUrl => start.sourceUrl;
+ Uri? get sourceUrl => start.sourceUrl;
@override
int get length => end.offset - start.offset;
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 5cb5e90..72c6173 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -16,10 +16,8 @@
/// Returns whether all elements of [iter] are the same value, according to
/// `==`.
-///
-/// Assumes [iter] doesn't contain any `null` values.
bool isAllTheSame(Iterable<Object> iter) {
- Object lastValue;
+ Object? lastValue;
for (var value in iter) {
if (lastValue == null) {
lastValue = value;
@@ -34,14 +32,14 @@
bool isMultiline(SourceSpan span) => span.start.line != span.end.line;
/// Sets the first `null` element of [list] to [element].
-void replaceFirstNull<E>(List<E> list, E element) {
+void replaceFirstNull<E>(List<E?> list, E element) {
final index = list.indexOf(null);
if (index < 0) throw ArgumentError('$list contains no null elements.');
list[index] = element;
}
/// Sets the element of [list] that currently contains [element] to `null`.
-void replaceWithNull<E>(List<E> list, E element) {
+void replaceWithNull<E>(List<E?> list, E element) {
final index = list.indexOf(element);
if (index < 0) {
throw ArgumentError('$list contains no elements matching $element.');
@@ -63,7 +61,7 @@
///
/// Returns the index in [context] where that line begins, or null if none
/// exists.
-int findLineStart(String context, String text, int column) {
+int? findLineStart(String context, String text, int column) {
// If the text is empty, we just want to find the first line that has at least
// [column] characters.
if (text.isEmpty) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 126d9c0..89f40c8 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,18 +1,92 @@
name: source_span
-version: 1.7.0
+version: 1.8.0-nullsafety
description: A library for identifying source spans and locations.
homepage: https://github.com/dart-lang/source_span
environment:
- sdk: '>=2.6.0 <3.0.0'
+ sdk: '>=2.9.0-18.0 <2.9.0'
dependencies:
- charcode: ^1.0.0
- collection: ^1.8.0
- meta: '>=0.9.0 <2.0.0'
- path: '>=1.2.0 <2.0.0'
- term_glyph: ^1.0.0
+ charcode: '>=1.2.0-nullsafety <1.2.0'
+ collection: '>=1.15.0-nullsafety <1.15.0'
+ path: '>=1.8.0-nullsafety <1.8.0'
+ term_glyph: '>=1.2.0-nullsafety <1.2.0'
dev_dependencies:
test: ^1.6.0
+
+dependency_overrides:
+ async:
+ git:
+ url: git://github.com/dart-lang/async.git
+ ref: null_safety
+ boolean_selector:
+ git:
+ url: git://github.com/dart-lang/boolean_selector.git
+ ref: null_safety
+ charcode:
+ git:
+ url: git://github.com/dart-lang/charcode.git
+ ref: null_safety
+ collection: 1.15.0-nullsafety
+ js:
+ git:
+ url: git://github.com/dart-lang/sdk.git
+ path: pkg/js
+ matcher:
+ git:
+ url: git://github.com/dart-lang/matcher.git
+ ref: null_safety
+ meta: 1.3.0-nullsafety
+ path:
+ git:
+ url: git://github.com/dart-lang/path.git
+ ref: null_safety
+ pedantic:
+ git:
+ url: git://github.com/dart-lang/pedantic.git
+ ref: null_safety
+ pool:
+ git:
+ url: git://github.com/dart-lang/pool.git
+ ref: null_safety
+ source_maps:
+ git:
+ url: git://github.com/dart-lang/source_maps.git
+ ref: null_safety
+ source_map_stack_trace:
+ git:
+ url: git://github.com/dart-lang/source_map_stack_trace.git
+ ref: null_safety
+ stack_trace:
+ git:
+ url: git://github.com/dart-lang/stack_trace.git
+ ref: null_safety
+ stream_channel:
+ git:
+ url: git://github.com/dart-lang/stream_channel.git
+ ref: null_safety
+ string_scanner:
+ git:
+ url: git://github.com/dart-lang/string_scanner.git
+ ref: null_safety
+ term_glyph:
+ git:
+ url: git://github.com/dart-lang/term_glyph.git
+ ref: null_safety
+ test_api:
+ git:
+ url: git://github.com/dart-lang/test.git
+ ref: null_safety
+ path: pkgs/test_api
+ test_core:
+ git:
+ url: git://github.com/dart-lang/test.git
+ ref: null_safety
+ path: pkgs/test_core
+ test:
+ git:
+ url: git://github.com/dart-lang/test.git
+ ref: null_safety
+ path: pkgs/test
diff --git a/test/file_test.dart b/test/file_test.dart
index 63b523f..581f03f 100644
--- a/test/file_test.dart
+++ b/test/file_test.dart
@@ -6,7 +6,7 @@
import 'package:source_span/source_span.dart';
void main() {
- SourceFile file;
+ late SourceFile file;
setUp(() {
file = SourceFile.fromString('''
foo bar baz
@@ -295,7 +295,7 @@
});
group('union()', () {
- FileSpan span;
+ late FileSpan span;
setUp(() {
span = file.span(5, 12);
});
@@ -358,7 +358,7 @@
});
group('expand()', () {
- FileSpan span;
+ late FileSpan span;
setUp(() {
span = file.span(5, 12);
});
@@ -407,7 +407,7 @@
});
group('subspan()', () {
- FileSpan span;
+ late FileSpan span;
setUp(() {
span = file.span(5, 11); // "ar baz"
});
diff --git a/test/highlight_test.dart b/test/highlight_test.dart
index 6313108..7754d00 100644
--- a/test/highlight_test.dart
+++ b/test/highlight_test.dart
@@ -10,7 +10,7 @@
import 'package:test/test.dart';
void main() {
- bool oldAscii;
+ late bool oldAscii;
setUpAll(() {
oldAscii = glyph.ascii;
glyph.ascii = true;
@@ -20,7 +20,7 @@
glyph.ascii = oldAscii;
});
- SourceFile file;
+ late SourceFile file;
setUp(() {
file = SourceFile.fromString('''
foo bar baz
diff --git a/test/location_test.dart b/test/location_test.dart
index c22a148..bbe259b 100644
--- a/test/location_test.dart
+++ b/test/location_test.dart
@@ -6,7 +6,7 @@
import 'package:test/test.dart';
void main() {
- SourceLocation location;
+ late SourceLocation location;
setUp(() {
location = SourceLocation(15, line: 2, column: 6, sourceUrl: 'foo.dart');
});
diff --git a/test/multiple_highlight_test.dart b/test/multiple_highlight_test.dart
index d9d1b30..6d5ec9d 100644
--- a/test/multiple_highlight_test.dart
+++ b/test/multiple_highlight_test.dart
@@ -7,7 +7,7 @@
import 'package:test/test.dart';
void main() {
- bool oldAscii;
+ late bool oldAscii;
setUpAll(() {
oldAscii = glyph.ascii;
glyph.ascii = true;
@@ -17,7 +17,7 @@
glyph.ascii = oldAscii;
});
- SourceFile file;
+ late SourceFile file;
setUp(() {
file = SourceFile.fromString('''
foo bar baz
diff --git a/test/span_test.dart b/test/span_test.dart
index 838d6b7..c27048e 100644
--- a/test/span_test.dart
+++ b/test/span_test.dart
@@ -9,7 +9,8 @@
import 'package:source_span/src/colors.dart' as colors;
void main() {
- bool oldAscii;
+ late bool oldAscii;
+
setUpAll(() {
oldAscii = glyph.ascii;
glyph.ascii = true;
@@ -19,7 +20,7 @@
glyph.ascii = oldAscii;
});
- SourceSpan span;
+ late SourceSpan span;
setUp(() {
span = SourceSpan(SourceLocation(5, sourceUrl: 'foo.dart'),
SourceLocation(12, sourceUrl: 'foo.dart'), 'foo bar');
diff --git a/test/utils_test.dart b/test/utils_test.dart
index a4a372e..02888df 100644
--- a/test/utils_test.dart
+++ b/test/utils_test.dart
@@ -9,26 +9,26 @@
group('find line start', () {
test('skip entries in wrong column', () {
final context = '0_bb\n1_bbb\n2b____\n3bbb\n';
- final index = findLineStart(context, 'b', 1);
+ final index = findLineStart(context, 'b', 1)!;
expect(index, 11);
expect(context.substring(index - 1, index + 3), '\n2b_');
});
test('end of line column for empty text', () {
final context = '0123\n56789\nabcdefgh\n';
- final index = findLineStart(context, '', 5);
+ final index = findLineStart(context, '', 5)!;
expect(index, 5);
expect(context[index], '5');
});
test('column at the end of the file for empty text', () {
var context = '0\n2\n45\n';
- var index = findLineStart(context, '', 2);
+ var index = findLineStart(context, '', 2)!;
expect(index, 4);
expect(context[index], '4');
context = '0\n2\n45';
- index = findLineStart(context, '', 2);
+ index = findLineStart(context, '', 2)!;
expect(index, 4);
});