From fa5c3a7f960112eb9ae2d71766f888344e456e01 Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Wed, 20 Mar 2013 23:41:50 +0000 Subject: [PATCH 001/657] Move source maps package to the dart repo, so it can be used by other internal tools. Review URL: https://codereview.chromium.org//12207008 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@20300 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/README.md | 27 ++ pkgs/source_maps/lib/builder.dart | 146 +++++++++ pkgs/source_maps/lib/parser.dart | 391 ++++++++++++++++++++++++ pkgs/source_maps/lib/printer.dart | 89 ++++++ pkgs/source_maps/lib/source_maps.dart | 25 ++ pkgs/source_maps/lib/span.dart | 330 ++++++++++++++++++++ pkgs/source_maps/lib/src/utils.dart | 29 ++ pkgs/source_maps/lib/src/vlq.dart | 103 +++++++ pkgs/source_maps/pubspec.yaml | 6 + pkgs/source_maps/test/builder_test.dart | 32 ++ pkgs/source_maps/test/common.dart | 97 ++++++ pkgs/source_maps/test/end2end_test.dart | 106 +++++++ pkgs/source_maps/test/parser_test.dart | 36 +++ pkgs/source_maps/test/printer_test.dart | 82 +++++ pkgs/source_maps/test/run.dart | 38 +++ pkgs/source_maps/test/span_test.dart | 215 +++++++++++++ pkgs/source_maps/test/utils_test.dart | 54 ++++ pkgs/source_maps/test/vlq_test.dart | 59 ++++ 18 files changed, 1865 insertions(+) create mode 100644 pkgs/source_maps/README.md create mode 100644 pkgs/source_maps/lib/builder.dart create mode 100644 pkgs/source_maps/lib/parser.dart create mode 100644 pkgs/source_maps/lib/printer.dart create mode 100644 pkgs/source_maps/lib/source_maps.dart create mode 100644 pkgs/source_maps/lib/span.dart create mode 100644 pkgs/source_maps/lib/src/utils.dart create mode 100644 pkgs/source_maps/lib/src/vlq.dart create mode 100644 pkgs/source_maps/pubspec.yaml create mode 100644 pkgs/source_maps/test/builder_test.dart create mode 100644 pkgs/source_maps/test/common.dart create mode 100644 pkgs/source_maps/test/end2end_test.dart create mode 100644 pkgs/source_maps/test/parser_test.dart create mode 100644 pkgs/source_maps/test/printer_test.dart create mode 100755 pkgs/source_maps/test/run.dart create mode 100644 pkgs/source_maps/test/span_test.dart create mode 100644 pkgs/source_maps/test/utils_test.dart create mode 100644 pkgs/source_maps/test/vlq_test.dart diff --git a/pkgs/source_maps/README.md b/pkgs/source_maps/README.md new file mode 100644 index 000000000..df182d9ba --- /dev/null +++ b/pkgs/source_maps/README.md @@ -0,0 +1,27 @@ +Source Maps +=========== + +This project implements a Dart pub package to work with source maps. The +implementation is based on the [source map version 3 spec][spec] which was +originated from the [Closure Compiler][closure] and has been implemented in +Chrome and Firefox. + +In this package we provide: + * Data types defining file locations and spans: these are not part of the + original source map specification. These data types are great for tracking + source locations on source maps, but they can also be used by tools to + reporting useful error messages that include on source locations. + * A builder that creates a source map programatically and produces the encoded + source map format. + * A parser that reads the source map format and provides APIs to read the + mapping information. + +Some upcoming features we are planning to add to this package are: + * A printer that lets you generate code, but record source map information in + the process. + * A tool that can compose source maps together. This would be useful for + instance, if you have 2 tools that produce source maps and you call one with + the result of the other. + +[closure]: http://code.google.com/p/closure-compiler/wiki/SourceMaps +[spec]: https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart new file mode 100644 index 000000000..ad80fa000 --- /dev/null +++ b/pkgs/source_maps/lib/builder.dart @@ -0,0 +1,146 @@ +// Copyright (c) 2013, 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. + +/// Contains a builder object useful for creating source maps programatically. +library source_maps.builder; + +// TODO(sigmund): add a builder for multi-section mappings. + +import 'dart:json' as json; +import 'dart:collection'; + +import 'span.dart'; +import 'src/vlq.dart'; + +/// Builds a source map given a set of mappings. +class SourceMapBuilder { + + final List _entries = []; + + /// Indices associated with file urls that will be part of the source map. We + /// use a linked hash-map so that `_urls.keys[_urls[u]] == u` + final Map _urls = new LinkedHashMap(); + + /// Indices associated with identifiers that will be part of the source map. + /// We use a linked hash-map so that `_names.keys[_names[n]] == n` + final Map _names = new LinkedHashMap(); + + /// Adds an entry mapping the [targetOffset] to [source]. + void addFromOffset(Location source, + SourceFile targetFile, int targetOffset, String identifier) { + if (targetFile == null) { + throw new ArgumentError('targetFile cannot be null'); + } + _entries.add(new Entry(source, + new FileLocation(targetFile, targetOffset), identifier)); + } + + /// Adds an entry mapping [target] to [source]. + void addSpan(Span source, Span target) { + var name = source.isIdentifier ? source.text : null; + _entries.add(new Entry(source.start, target.start, name)); + } + + void addLocation(Location source, Location target, String identifier) { + _entries.add(new Entry(source, target, identifier)); + } + + /// Encodes all mappings added to this builder as a json map. + Map build(String fileUrl) { + var buff = new StringBuffer(); + var line = 0; + var column = 0; + var srcLine = 0; + var srcColumn = 0; + var srcUrlId = 0; + var srcNameId = 0; + var first = true; + + // The encoding needs to be sorted by the target offsets. + _entries.sort(); + for (var entry in _entries) { + int nextLine = entry.target.line; + if (nextLine > line) { + for (int i = line; i < nextLine; ++i) { + buff.write(';'); + } + line = nextLine; + column = 0; + first = true; + } + + if (!first) buff.write(','); + first = false; + column = _append(buff, column, entry.target.column); + + if (entry.source == null) continue; + + srcUrlId = _append(buff, srcUrlId, + _indexOf(_urls, entry.source.sourceUrl)); + srcLine = _append(buff, srcLine, entry.source.line); + srcColumn = _append(buff, srcColumn, entry.source.column); + + if (entry.identifierName == null) continue; + srcNameId = _append(buff, srcNameId, + _indexOf(_names, entry.identifierName)); + } + + var result = { + 'version': 3, + 'sourceRoot': '', + 'sources': _urls.keys.toList(), + 'names' : _names.keys.toList(), + 'mappings' : buff.toString() + }; + if (fileUrl != null) { + result['file'] = fileUrl; + } + return result; + } + + /// Encodes all mappings added to this builder as a json string. + String toJson(String fileUrl) => json.stringify(build(fileUrl)); + + /// Get the index of [value] in [map], or create one if it doesn't exist. + int _indexOf(Map map, String value) { + return map.putIfAbsent(value, () { + int index = map.length; + map[value] = index; + return index; + }); + } + + /// Appends to [buff] a VLQ encoding of [newValue] using the difference + /// between [oldValue] and [newValue] + static int _append(StringBuffer buff, int oldValue, int newValue) { + buff.writeAll(encodeVlq(newValue - oldValue)); + return newValue; + } +} + +/// An entry in the source map builder. +class Entry implements Comparable { + /// Span denoting the original location in the input source file + final Location source; + + /// Span indicating the corresponding location in the target file. + final Location target; + + /// An identifier name, when this location is the start of an identifier. + final String identifierName; + + Entry(this.source, this.target, this.identifierName); + + /// Implements [Comparable] to ensure that entries are ordered by their + /// location in the target file. We sort primarily by the target offset + /// because source map files are encoded by printing each mapping in order as + /// they appear in the target file. + int compareTo(Entry other) { + int res = target.compareTo(other.target); + if (res != 0) return res; + res = source.sourceUrl.compareTo(other.source.sourceUrl); + if (res != 0) return res; + return source.compareTo(other.source); + } +} diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart new file mode 100644 index 000000000..3849913a3 --- /dev/null +++ b/pkgs/source_maps/lib/parser.dart @@ -0,0 +1,391 @@ +// Copyright (c) 2013, 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. + +/// Contains the top-level function to parse source maps version 3. +library source_maps.parser; + +import 'dart:json' as json; + +import 'span.dart'; +import 'src/utils.dart'; +import 'src/vlq.dart'; + +/// Parses a source map directly from a json string. +// TODO(sigmund): evaluate whether other maps should have the json parsed, or +// the string represenation. +Mapping parse(String jsonMap, {Map otherMaps}) => + parseJson(json.parse(jsonMap), otherMaps: otherMaps); + +/// Parses a source map directly from a json map object. +Mapping parseJson(Map map, {Map otherMaps}) { + if (map['version'] != 3) { + throw new ArgumentError( + 'unexpected source map version: ${map["version"]}. ' + 'Only version 3 is supported.'); + } + + // TODO(sigmund): relax this? dart2js doesn't generate the file entry. + if (!map.containsKey('file')) { + throw new ArgumentError('missing "file" in source map'); + } + + if (map.containsKey('sections')) { + if (map.containsKey('mappings') || map.containsKey('sources') || + map.containsKey('names')) { + throw new FormatException('map containing "sections" ' + 'cannot contain "mappings", "sources", or "names".'); + } + return new MultiSectionMapping.fromJson(map['sections'], otherMaps); + } + return new SingleMapping.fromJson(map); +} + + +/// A mapping parsed our of a source map. +abstract class Mapping { + Span spanFor(int line, int column, {Map files}); + + Span spanForLocation(Location loc, {Map files}) { + return spanFor(loc.line, loc.column, files: files); + } +} + +/// A meta-level map containing sections. +class MultiSectionMapping extends Mapping { + /// For each section, the start line offset. + final List _lineStart = []; + + /// For each section, the start column offset. + final List _columnStart = []; + + /// For each section, the actual source map information, which is not adjusted + /// for offsets. + final List _maps = []; + + /// Creates a section mapping from json. + MultiSectionMapping.fromJson(List sections, Map otherMaps) { + for (var section in sections) { + var offset = section['offset']; + if (offset == null) throw new FormatException('section missing offset'); + + var line = section['offset']['line']; + if (line == null) throw new FormatException('offset missing line'); + + var column = section['offset']['column']; + if (column == null) throw new FormatException('offset missing column'); + + _lineStart.add(line); + _columnStart.add(column); + + var url = section['url']; + var map = section['map']; + + if (url != null && map != null) { + throw new FormatException("section can't use both url and map entries"); + } else if (url != null) { + if (otherMaps == null || otherMaps[url] == null) { + throw new FormatException( + 'section contains refers to $url, but no map was ' + 'given for it. Make sure a map is passed in "otherMaps"'); + } + _maps.add(parseJson(otherMaps[url], otherMaps: otherMaps)); + } else if (map != null) { + _maps.add(parseJson(map, otherMaps: otherMaps)); + } else { + throw new FormatException('section missing url or map'); + } + } + if (_lineStart.length == 0) { + throw new FormatException('expected at least one section'); + } + } + + int _indexFor(line, column) { + for(int i = 0; i < _lineStart.length; i++) { + if (line < _lineStart[i]) return i - 1; + if (line == _lineStart[i] && column < _columnStart[i]) return i - 1; + } + return _lineStart.length - 1; + } + + Span spanFor(int line, int column, {Map files}) { + int index = _indexFor(line, column); + return _maps[index].spanFor( + line - _lineStart[index], column - _columnStart[index], files: files); + } + + String toString() { + var buff = new StringBuffer("$runtimeType : ["); + for (int i = 0; i < _lineStart.length; i++) { + buff..write('(') + ..write(_lineStart[i]) + ..write(',') + ..write(_columnStart[i]) + ..write(':') + ..write(_maps[i]) + ..write(')'); + } + buff.write(']'); + return buff.toString(); + } +} + +/// A map containing direct source mappings. +// TODO(sigmund): integrate mapping and sourcemap builder? +class SingleMapping extends Mapping { + /// Url of the target file. + final String targetUrl; + + /// Source urls used in the mapping, indexed by id. + final List urls; + + /// Source names used in the mapping, indexed by id. + final List names; + + /// Entries indicating the beginning of each span. + final List lines = []; + + SingleMapping.fromJson(Map map) + : targetUrl = map['file'], + // TODO(sigmund): add support for 'sourceRoot' + urls = map['sources'], + names = map['names'] { + int line = 0; + int column = 0; + int srcUrlId = 0; + int srcLine = 0; + int srcColumn = 0; + int srcNameId = 0; + var tokenizer = new _MappingTokenizer(map['mappings']); + var entries = []; + + while (tokenizer.hasTokens) { + if (tokenizer.nextKind.isNewLine) { + if (!entries.isEmpty) { + lines.add(new TargetLineEntry(line, entries)); + entries = []; + } + line++; + column = 0; + tokenizer._consumeNewLine(); + continue; + } + + // Decode the next entry, using the previous encountered values to + // decode the relative values. + // + // We expect 1, 4, or 5 values. If present, values are expected in the + // following order: + // 0: the starting column in the current line of the generated file + // 1: the id of the original source file + // 2: the starting line in the original source + // 3: the starting column in the original source + // 4: the id of the original symbol name + // The values are relative to the previous encountered values. + if (tokenizer.nextKind.isNewSegment) throw _segmentError(0, line); + column += tokenizer._consumeValue(); + if (!tokenizer.nextKind.isValue) { + entries.add(new TargetEntry(column)); + } else { + srcUrlId += tokenizer._consumeValue(); + if (srcUrlId >= urls.length) { + throw new StateError( + 'Invalid source url id. $targetUrl, $line, $srcUrlId'); + } + if (!tokenizer.nextKind.isValue) throw _segmentError(2, line); + srcLine += tokenizer._consumeValue(); + if (!tokenizer.nextKind.isValue) throw _segmentError(3, line); + srcColumn += tokenizer._consumeValue(); + if (!tokenizer.nextKind.isValue) { + entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn)); + } else { + srcNameId += tokenizer._consumeValue(); + if (srcNameId >= names.length) { + throw new StateError( + 'Invalid name id: $targetUrl, $line, $srcNameId'); + } + entries.add( + new TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId)); + } + } + if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment(); + } + if (!entries.isEmpty) { + lines.add(new TargetLineEntry(line, entries)); + } + } + + _segmentError(int seen, int line) => new StateError( + 'Invalid entry in sourcemap, expected 1, 4, or 5' + ' values, but got $seen.\ntargeturl: $targetUrl, line: $line'); + + /// 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]. + TargetLineEntry _findLine(int line) { + int index = binarySearch(lines, (e) => e.line > line); + return (index <= 0) ? null : 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. + 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]; + } + + Span spanFor(int line, int column, {Map files}) { + var lineEntry = _findLine(line); + var entry = _findColumn(line, column, _findLine(line)); + if (entry == null) return null; + var url = urls[entry.sourceUrlId]; + if (files != null && files[url] != null) { + var file = files[url]; + var start = file.getOffset(entry.sourceLine, entry.sourceColumn); + if (entry.sourceNameId != null) { + var text = names[entry.sourceNameId]; + return new FileSpan(files[url], start, start + text.length, true); + } else { + return new FileSpan(files[url], start); + } + } else { + // Offset and other context is not available. + if (entry.sourceNameId != null) { + return new FixedSpan(url, 0, entry.sourceLine, entry.sourceColumn, + text: names[entry.sourceNameId], isIdentifier: true); + } else { + return new FixedSpan(url, 0, entry.sourceLine, entry.sourceColumn); + } + } + } + + String toString() { + return (new StringBuffer("$runtimeType : [") + ..write('targetUrl: ') + ..write(targetUrl) + ..write(', urls: ') + ..write(urls) + ..write(', names: ') + ..write(names) + ..write(', lines: ') + ..write(lines) + ..write(']')).toString(); + } + + String get debugString { + var buff = new StringBuffer(); + for (var lineEntry in lines) { + var line = lineEntry.line; + for (var entry in lineEntry.entries) { + buff..write(targetUrl) + ..write(': ') + ..write(line) + ..write(':') + ..write(entry.column) + ..write(' --> ') + ..write(urls[entry.sourceUrlId]) + ..write(': ') + ..write(entry.sourceLine) + ..write(':') + ..write(entry.sourceColumn); + if (entry.sourceNameId != null) { + buff..write(' (') + ..write(names[entry.sourceNameId]) + ..write(')'); + } + buff.write('\n'); + } + } + return buff.toString(); + } +} + +/// A line entry read from a source map. +class TargetLineEntry { + final int line; + List entries = []; + TargetLineEntry(this.line, this.entries); + + String toString() => '$runtimeType: $line $entries'; +} + +/// A target segment entry read from a source map +class TargetEntry { + final int column; + final int sourceUrlId; + final int sourceLine; + final int sourceColumn; + final int sourceNameId; + TargetEntry(this.column, [this.sourceUrlId, this.sourceLine, + this.sourceColumn, this.sourceNameId]); + + String toString() => '$runtimeType: ' + '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; +} + +/** A character iterator over a string that can peek one character ahead. */ +class _MappingTokenizer implements Iterator { + final String _internal; + final int _length; + int index = -1; + _MappingTokenizer(String internal) + : _internal = internal, + _length = internal.length; + + // Iterator API is used by decodeVlq to consume VLQ entries. + bool moveNext() => ++index < _length; + String get current => + (index >= 0 && index < _length) ? _internal[index] : null; + + bool get hasTokens => index < _length - 1 && _length > 0; + + _TokenKind get nextKind { + if (!hasTokens) return _TokenKind.EOF; + var next = _internal[index + 1]; + if (next == ';') return _TokenKind.LINE; + if (next == ',') return _TokenKind.SEGMENT; + return _TokenKind.VALUE; + } + + int _consumeValue() => decodeVlq(this); + void _consumeNewLine() { ++index; } + void _consumeNewSegment() { ++index; } + + // Print the state of the iterator, with colors indicating the current + // position. + String toString() { + var buff = new StringBuffer(); + for (int i = 0; i < index; i++) { + buff.write(_internal[i]); + } + buff.write(''); + buff.write(current == null ? '' : current); + buff.write(''); + for (int i = index + 1; i < _internal.length; i++) { + buff.write(_internal[i]); + } + buff.write(' ($index)'); + return buff.toString(); + } +} + +class _TokenKind { + static const _TokenKind LINE = const _TokenKind(isNewLine: true); + static const _TokenKind SEGMENT = const _TokenKind(isNewSegment: true); + static const _TokenKind EOF = const _TokenKind(isEof: true); + static const _TokenKind VALUE = const _TokenKind(); + final bool isNewLine; + final bool isNewSegment; + final bool isEof; + bool get isValue => !isNewLine && !isNewSegment && !isEof; + + const _TokenKind( + {this.isNewLine: false, this.isNewSegment: false, this.isEof: false}); +} diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart new file mode 100644 index 000000000..333aadcd4 --- /dev/null +++ b/pkgs/source_maps/lib/printer.dart @@ -0,0 +1,89 @@ +// Copyright (c) 2013, 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. + +/// Contains a code printer that generates code by recording the source maps. +library source_maps.printer; + +import 'dart:utf' show stringToCodepoints; +import 'builder.dart'; +import 'span.dart'; + +const int _LF = 10; +const int _CR = 13; + +/// A printer that keeps track of offset locations and records source maps +/// locations. +class Printer { + final String filename; + final StringBuffer _buff = new StringBuffer(); + final SourceMapBuilder _maps = new SourceMapBuilder(); + String get text => _buff.toString(); + String get map => _maps.toJson(filename); + + /// Current source location mapping. + Location _loc; + + /// Current line in the buffer; + int _line = 0; + + /// Current column in the buffer. + int _column = 0; + + Printer(this.filename); + + /// Add [str] contents to the output, tracking new lines to track correct + /// positions for span locations. When [projectMarks] is true, this method + /// adds a source map location on each new line, projecting that every new + /// line in the target file (printed here) corresponds to a new line in the + /// source file. + void add(String str, {projectMarks: false}) { + var chars = stringToCodepoints(str); + var length = chars.length; + for (int i = 0; i < length; i++) { + var c = chars[i]; + if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) { + // Return not followed by line-feed is treated as a new line. + _line++; + _column = 0; + if (projectMarks && _loc != null) { + if (_loc is FixedLocation) { + mark(new FixedLocation(0, _loc.sourceUrl, _loc.line + 1, 0)); + } else if (_loc is FileLocation) { + var file = (_loc as FileLocation).file; + mark(new FileLocation(file, file.getOffset(_loc.line + 1, 0))); + } + } + } else { + _column++; + } + } + _buff.write(str); + } + + + /// Append a [total] number of spaces in the target file. Typically used for + /// formatting indentation. + void addSpaces(int total) { + for (int i = 0; i < total; i++) _buff.write(' '); + _column += total; + } + + /// Marks that the current point in the target file corresponds to the [mark] + /// in the source file, which can be either a [Location] or a [Span]. When the + /// mark is an identifier's Span, this also records the name of the identifier + /// in the source map information. + void mark(mark) { + var loc; + var identifier = null; + if (mark is Location) { + loc = mark; + } else if (mark is Span) { + loc = mark.start; + if (mark.isIdentifier) identifier = mark.text; + } + _maps.addLocation(loc, + new FixedLocation(_buff.length, null, _line, _column), identifier); + _loc = loc; + } +} diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart new file mode 100644 index 000000000..4e24deab5 --- /dev/null +++ b/pkgs/source_maps/lib/source_maps.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2013, 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. + +/// Source maps library. +/// +/// Create a source map using [SourceMapBuilder]. For example: +/// var json = (new SourceMapBuilder() +/// ..add(inputSpan1, outputSpan1) +/// ..add(inputSpan2, outputSpan2) +/// ..add(inputSpan3, outputSpan3) +/// .toJson(outputFile); +/// +/// Use the [Span] and [SourceFile] classes to specify span locations. +/// +/// Parse a source map using [parse], and call `spanFor` on the returned mapping +/// object. For example: +/// var mapping = parse(json); +/// mapping.spanFor(outputSpan1.line, outputSpan1.column) +library source_maps; + +export "builder.dart"; +export "parser.dart"; +export "printer.dart"; +export "span.dart"; diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart new file mode 100644 index 000000000..19829941f --- /dev/null +++ b/pkgs/source_maps/lib/span.dart @@ -0,0 +1,330 @@ +// Copyright (c) 2013, 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. + +/// Dart classes representing the souce spans and source files. +library source_maps.span; + +import 'dart:utf' show stringToCodepoints, codepointsToString; +import 'dart:math' show min; + +import 'src/utils.dart'; + +/// A simple class that describe a segment of source text. +abstract class Span implements Comparable { + /// The start location of this span. + final Location start; + + /// The end location of this span, exclusive. + final Location end; + + /// Url of the source (typically a file) containing this span. + String get sourceUrl => start.sourceUrl; + + /// The length of this span, in characters. + int get length => end.offset - start.offset; + + /// The source text for this span, if available. + String get text; + + /// Whether [text] corresponds to an identifier symbol. + final bool isIdentifier; + + Span(this.start, this.end, bool isIdentifier) + : isIdentifier = isIdentifier != null ? isIdentifier : false { + _checkRange(); + } + + /// Creates a new span that is the union of two existing spans [start] and + /// [end]. Note that the resulting span might contain some positions that were + /// not in either of the original spans if [start] and [end] are disjoint. + Span.union(Span start, Span end) + : start = start.start, end = end.end, isIdentifier = false { + _checkRange(); + } + + void _checkRange() { + if (start.offset < 0) throw new ArgumentError('start $start must be >= 0'); + if (end.offset < start.offset) { + throw new ArgumentError('end $end must be >= start $start'); + } + } + + /// Compares two spans. If the spans are not in the same source, this method + /// generates an error. + int compareTo(Span other) { + int d = start.compareTo(other.start); + return d == 0 ? end.compareTo(other.end) : d; + } + + /// Gets the location in standard printed form `filename:line:column`, where + /// line and column are adjusted by 1 to match the convention in editors. + String get formatLocation => start.formatString; + + String getLocationMessage(String message, + {bool useColors: false, String color}) { + return '$formatLocation: $message'; + } + + bool operator ==(Span other) => + sourceUrl == other.sourceUrl && start == other.start && end == other.end; + + String toString() => '<$runtimeType: $start $end $formatLocation $text>'; +} + +/// A location in the source text +abstract class Location implements Comparable { + /// Url of the source containing this span. + String get sourceUrl; + + /// The offset of this location, 0-based. + final int offset; + + /// The 0-based line in the source of this location. + int get line; + + /// The 0-based column in the source of this location. + int get column; + + Location(this.offset); + + /// Compares two locations. If the locations are not in the same source, this + /// method generates an error. + int compareTo(Location other) { + if (sourceUrl != other.sourceUrl) { + throw new ArgumentError('can only compare locations of the same source'); + } + return offset - other.offset; + } + + String toString() => '(Location $offset)'; + String get formatString => '$sourceUrl:${line + 1}:${column + 1}'; +} + +/// Implementation of [Location] with fixed values given at allocation time. +class FixedLocation extends Location { + final String sourceUrl; + final int line; + final int column; + + FixedLocation(int offset, this.sourceUrl, this.line, this.column) + : super(offset); +} + +/// Implementation of [Span] where all the values are given at allocation time. +class FixedSpan extends Span { + /// The source text for this span, if available. + final String text; + + /// Creates a span which starts and end in the same line. + FixedSpan(String sourceUrl, int start, int line, int column, + {String text: '', bool isIdentifier: false}) + : text = text, super(new FixedLocation(start, sourceUrl, line, column), + new FixedLocation(start + text.length, sourceUrl, line, + column + text.length), + isIdentifier); +} + +/// [Location] with values computed from an underling [SourceFile]. +class FileLocation extends Location { + /// The source file containing this location. + final SourceFile file; + + String get sourceUrl => file.url; + int get line => file.getLine(offset); + int get column => file.getColumn(line, offset); + + FileLocation(this.file, int offset): super(offset); +} + +/// [Span] where values are computed from an underling [SourceFile]. +class FileSpan extends Span { + /// The source file containing this span. + final SourceFile file; + + /// The source text for this span, if available. + String get text => file.getText(start.offset, end.offset); + + factory FileSpan(SourceFile file, int start, + [int end, bool isIdentifier = false]) { + var startLoc = new FileLocation(file, start); + var endLoc = end == null ? startLoc : new FileLocation(file, end); + return new FileSpan.locations(startLoc, endLoc, isIdentifier); + } + + FileSpan.locations(FileLocation start, FileLocation end, + bool isIdentifier) + : file = start.file, super(start, end, isIdentifier); + + /// Creates a new span that is the union of two existing spans [start] and + /// [end]. Note that the resulting span might contain some positions that were + /// not in either of the original spans if [start] and [end] are disjoint. + FileSpan.union(FileSpan start, FileSpan end) + : file = start.file, super.union(start, end) { + if (start.file != end.file) { + throw new ArgumentError('start and end must be from the same file'); + } + } + + String getLocationMessage(String message, + {bool useColors: false, String color}) { + return file.getLocationMessage(message, start.offset, end.offset, + useColors: useColors, color: color); + } +} + +// Constants to determine end-of-lines. +const int _LF = 10; +const int _CR = 13; + +// Color constants used for generating messages. +const String _RED_COLOR = '\u001b[31m'; +const String _NO_COLOR = '\u001b[0m'; + +/// Stores information about a source file, to permit computation of the line +/// and column. Also contains a nice default error message highlighting the code +/// location. +class SourceFile { + /// Url where the source file is located. + final String url; + final List _lineStarts; + final List _decodedChars; + + SourceFile(this.url, this._lineStarts, this._decodedChars); + + SourceFile.text(this.url, String text) + : _lineStarts = [0], + _decodedChars = stringToCodepoints(text) { + for (int i = 0; i < _decodedChars.length; i++) { + var c = _decodedChars[i]; + if (c == _CR) { + // Return not followed by newline is treated as a newline + int j = i + 1; + if (j >= _decodedChars.length || _decodedChars[j] != _LF) { + c = _LF; + } + } + if (c == _LF) _lineStarts.add(i + 1); + } + } + + /// Returns a span in this [SourceFile] with the given offsets. + Span span(int start, [int end, bool isIdentifier = false]) => + new FileSpan(this, start, end, isIdentifier); + + /// Returns a location in this [SourceFile] with the given offset. + Location location(int offset) => new FileLocation(this, offset); + + /// Gets the 0-based line corresponding to an offset. + int getLine(int offset) { + return binarySearch(_lineStarts, (o) => o > offset) - 1; + } + + /// Gets the 0-based column corresponding to an offset. + int getColumn(int line, int offset) { + return offset - _lineStarts[line]; + } + + /// Get the offset for a given line and column + int getOffset(int line, int column) { + return _lineStarts[min(line, _lineStarts.length - 1)] + column; + } + + /// Gets the text at the given offsets. + String getText(int start, [int end]) { + return codepointsToString(_decodedChars.sublist(start, end)); + } + + /// Create a pretty string representation from a span. + String getLocationMessage(String message, int start, int end, + {bool useColors: false, String color}) { + // TODO(jmesserly): it would be more useful to pass in an object that + // controls how the errors are printed. This method is a bit too smart. + var line = getLine(start); + var column = getColumn(line, start); + + var src = url == null ? '' : url; + var msg = '$src:${line + 1}:${column + 1}: $message'; + + if (_decodedChars == null) { + // We don't have any text to include, so exit. + return msg; + } + + var buf = new StringBuffer(msg); + buf.write('\n'); + var textLine; + + // +1 for 0-indexing, +1 again to avoid the last line + if ((line + 2) < _lineStarts.length) { + textLine = getText(_lineStarts[line], _lineStarts[line + 1]); + } else { + textLine = getText(_lineStarts[line]); + textLine = '$textLine\n'; + } + + int toColumn = min(column + end - start, textLine.length); + if (useColors) { + if (color == null) { + color = _RED_COLOR; + } + buf.write(textLine.substring(0, column)); + buf.write(color); + buf.write(textLine.substring(column, toColumn)); + buf.write(_NO_COLOR); + buf.write(textLine.substring(toColumn)); + } else { + buf.write(textLine); + } + + int i = 0; + for (; i < column; i++) { + buf.write(' '); + } + + if (useColors) buf.write(color); + for (; i < toColumn; i++) { + buf.write('^'); + } + if (useColors) buf.write(_NO_COLOR); + return buf.toString(); + } +} + +/// A convenience type to treat a code segment as if it were a separate +/// [SourceFile]. A [SourceFileSegment] shifts all locations by an offset, which +/// allows you to set source-map locations based on the locations relative to +/// the start of the segment, but that get translated to absolute locations in +/// the original source file. +class SourceFileSegment extends SourceFile { + final int _baseOffset; + final int _baseLine; + final int _baseColumn; + + SourceFileSegment(String url, String textSegment, Location startOffset) + : _baseOffset = startOffset.offset, + _baseLine = startOffset.line, + _baseColumn = startOffset.column, + super.text(url, textSegment); + + Span span(int start, [int end, bool isIdentifier = false]) => + super.span(start + _baseOffset, + end == null ? null : end + _baseOffset, isIdentifier); + + Location location(int offset) => super.location(offset + _baseOffset); + + int getLine(int offset) => + super.getLine(offset - _baseOffset) + _baseLine; + + int getColumn(int line, int offset) { + var col = super.getColumn(line - _baseLine, offset - _baseOffset); + return line == _baseLine ? col + _baseColumn : col; + } + + int getOffset(int line, int column) => + super.getOffset(line - _baseLine, + line == _baseLine ? column - _baseColumn : column) + _baseOffset; + + String getText(int start, [int end]) => + super.getText(start - _baseOffset, end - _baseOffset); +} diff --git a/pkgs/source_maps/lib/src/utils.dart b/pkgs/source_maps/lib/src/utils.dart new file mode 100644 index 000000000..78f098e70 --- /dev/null +++ b/pkgs/source_maps/lib/src/utils.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2013, 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. + +/// Utilities that shouldn't be in this package. +library source_maps.utils; + +/// Find the first entry in a sorted [list] that matches a monotonic predicate. +/// Given a result `n`, that all items before `n` will not match, `n` matches, +/// and all items after `n` match too. The result is -1 when there are no +/// items, 0 when all items match, and list.length when none does. +// TODO(sigmund): remove this function after dartbug.com/5624 is fixed. +int binarySearch(List list, bool matches(item)) { + if (list.length == 0) return -1; + if (matches(list.first)) return 0; + if (!matches(list.last)) return list.length; + + int min = 0; + int max = list.length - 1; + while (min < max) { + var half = min + ((max - min) ~/ 2); + if (matches(list[half])) { + max = half; + } else { + min = half + 1; + } + } + return max; +} diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart new file mode 100644 index 000000000..e4ab4eb69 --- /dev/null +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -0,0 +1,103 @@ +// Copyright (c) 2013, 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. + + +/// Utilities to encode and decode VLQ values used in source maps. +/// +/// Sourcemaps are encoded with variable length numbers as base64 encoded +/// strings with the least significant digit coming first. Each base64 digit +/// encodes a 5-bit value (0-31) and a continuation bit. Signed values can be +/// represented by using the least significant bit of the value as the sign bit. +/// +/// For more details see the source map [version 3 documentation][spec]. +/// [spec]: https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit +library source_maps.src.vlq; + +import 'dart:math'; + +const int VLQ_BASE_SHIFT = 5; + +const int VLQ_BASE_MASK = (1 << 5) - 1; + +const int VLQ_CONTINUATION_BIT = 1 << 5; + +const int VLQ_CONTINUATION_MASK = 1 << 5; + +const String BASE64_DIGITS = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +final Map _digits = () { + var map = {}; + for (int i = 0; i < 64; i++) { + map[BASE64_DIGITS[i]] = i; + } + return map; +}(); + +final int MAX_INT32 = pow(2, 31) - 1; +final int MIN_INT32 = -pow(2, 31); + +/// Creates the VLQ encoding of [value] as a sequence of characters +Iterable encodeVlq(int value) { + if (value < MIN_INT32 || value > MAX_INT32) { + throw new ArgumentError('expected 32 bit int, got: $value'); + } + var res = []; + int signBit = 0; + if (value < 0) { + signBit = 1; + value = -value; + } + value = (value << 1) | signBit; + do { + int digit = value & VLQ_BASE_MASK; + value >>= VLQ_BASE_SHIFT; + if (value > 0) { + digit |= VLQ_CONTINUATION_BIT; + } + res.add(BASE64_DIGITS[digit]); + } while (value > 0); + return res; +} + +/// Decodes a value written as a sequence of VLQ characters. The first input +/// character will be `chars.current` after calling `chars.moveNext` once. The +/// iterator is advanced until a stop character is found (a character without +/// the [VLQ_CONTINUATION_BIT]). +int decodeVlq(Iterator chars) { + int result = 0; + bool stop = false; + int shift = 0; + while (!stop) { + if (!chars.moveNext()) throw new StateError('incomplete VLQ value'); + var char = chars.current; + if (!_digits.containsKey(char)) { + throw new FormatException('invalid character in VLQ encoding: $char'); + } + var digit = _digits[char]; + stop = (digit & VLQ_CONTINUATION_BIT) == 0; + digit &= VLQ_BASE_MASK; + result += (digit << shift); + shift += VLQ_BASE_SHIFT; + } + + // Result uses the least significant bit as a sign bit. We convert it into a + // two-complement value. For example, + // 2 (10 binary) becomes 1 + // 3 (11 binary) becomes -1 + // 4 (100 binary) becomes 2 + // 5 (101 binary) becomes -2 + // 6 (110 binary) becomes 3 + // 7 (111 binary) becomes -3 + bool negate = (result & 1) == 1; + result = result >> 1; + result = negate ? -result : result; + + // TODO(sigmund): can we detect this earlier? + if (result < MIN_INT32 || result > MAX_INT32) { + throw new FormatException( + 'expected an encoded 32 bit int, but we got: $result'); + } + return result; +} diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml new file mode 100644 index 000000000..a559b5850 --- /dev/null +++ b/pkgs/source_maps/pubspec.yaml @@ -0,0 +1,6 @@ +name: source_maps +author: "Dart Team " +homepage: https://github.com/dart-lang/source-maps +description: Library to programmatically manipulate source map files. +dev_dependencies: + unittest: any diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart new file mode 100644 index 000000000..7bf2ee424 --- /dev/null +++ b/pkgs/source_maps/test/builder_test.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2013, 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. + +library test.source_maps_test; + +import 'dart:json' as json; +import 'package:unittest/unittest.dart'; +import 'package:source_maps/source_maps.dart'; +import 'common.dart'; + +main() { + test('builder - with span', () { + var map = (new SourceMapBuilder() + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr)) + .build(output.url); + expect(map, equals(EXPECTED_MAP)); + }); + + test('builder - with location', () { + var str = (new SourceMapBuilder() + ..addLocation(inputVar1.start, outputVar1.start, 'longVar1') + ..addLocation(inputFunction.start, outputFunction.start, 'longName') + ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') + ..addLocation(inputExpr.start, outputExpr.start, null)) + .toJson(output.url); + expect(str, json.stringify(EXPECTED_MAP)); + }); +} diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart new file mode 100644 index 000000000..661979b85 --- /dev/null +++ b/pkgs/source_maps/test/common.dart @@ -0,0 +1,97 @@ +// Copyright (c) 2013, 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. + +/// Common input/output used by builder, parser and end2end tests +library test.common; + +import 'package:source_maps/source_maps.dart'; +import 'package:unittest/unittest.dart'; + +/// Content of the source file +const String INPUT = ''' +/** this is a comment. */ +int longVar1 = 3; + +// this is a comment too +int longName(int longVar2) { + return longVar1 + longVar2; +} +'''; +var input = new SourceFile.text('input.dart', INPUT); + +/// A span in the input file +Span ispan(int start, int end, [bool isIdentifier = false]) => + new FileSpan(input, start, end, isIdentifier); + +Span inputVar1 = ispan(30, 38, true); +Span inputFunction = ispan(74, 82, true); +Span inputVar2 = ispan(87, 95, true); +Span inputExpr = ispan(108, 127); + +/// Content of the target file +const String OUTPUT = ''' +var x = 3; +f(y) => x + y; +'''; +var output = new SourceFile.text('output.dart', OUTPUT); + +/// A span in the output file +Span ospan(int start, int end, [bool isIdentifier = false]) => + new FileSpan(output, start, end, isIdentifier); + +Span outputVar1 = ospan(4, 5, true); +Span outputFunction = ospan(11, 12, true); +Span outputVar2 = ospan(13, 14, true); +Span outputExpr = ospan(19, 24); + +/// Expected output mapping when recording the following four mappings: +/// inputVar1 <= outputVar1 +/// inputFunction <= outputFunction +/// inputVar2 <= outputVar2 +/// inputExpr <= outputExpr +/// +/// This mapping is stored in the tests so we can independently test the builder +/// and parser algorithms without relying entirely on end2end tests. +const Map EXPECTED_MAP = const { + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const ['longVar1','longName','longVar2'], + 'mappings': 'IACIA;AAGAC,EAAaC,MACR', + 'file': 'output.dart' +}; + +check(Span outputSpan, Mapping mapping, Span inputSpan, bool realOffsets) { + var line = outputSpan.start.line; + var column = outputSpan.start.column; + var files = realOffsets ? {'input.dart': input} : null; + var span = mapping.spanFor(line, column, files: files); + var span2 = mapping.spanForLocation(outputSpan.start, files: files); + + // Both mapping APIs are equivalent. + expect(span.start.offset, span2.start.offset); + expect(span.start.line, span2.start.line); + expect(span.start.column, span2.start.column); + expect(span.end.offset, span2.end.offset); + expect(span.end.line, span2.end.line); + expect(span.end.column, span2.end.column); + + // Mapping matches our input location (modulo using real offsets) + expect(span.start.line, inputSpan.start.line); + expect(span.start.column, inputSpan.start.column); + expect(span.sourceUrl, inputSpan.sourceUrl); + expect(span.start.offset, realOffsets ? inputSpan.start.offset : 0); + + // Mapping includes the identifier, if any + if (inputSpan.isIdentifier) { + expect(span.end.line, inputSpan.end.line); + expect(span.end.column, inputSpan.end.column); + expect(span.end.offset, span.start.offset + inputSpan.text.length); + if (realOffsets) expect(span.end.offset, inputSpan.end.offset); + } else { + expect(span.end.offset, span.start.offset); + expect(span.end.line, span.start.line); + expect(span.end.column, span.start.column); + } +} diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart new file mode 100644 index 000000000..5ea958a98 --- /dev/null +++ b/pkgs/source_maps/test/end2end_test.dart @@ -0,0 +1,106 @@ +// Copyright (c) 2013, 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. + +library test.end2end_test; + +import 'package:unittest/unittest.dart'; +import 'package:source_maps/source_maps.dart'; +import 'common.dart'; + +main() { + test('end-to-end setup', () { + expect(inputVar1.text, 'longVar1'); + expect(inputFunction.text, 'longName'); + expect(inputVar2.text, 'longVar2'); + expect(inputExpr.text, 'longVar1 + longVar2'); + + expect(outputVar1.text, 'x'); + expect(outputFunction.text, 'f'); + expect(outputVar2.text, 'y'); + expect(outputExpr.text, 'x + y'); + }); + + test('build + parse', () { + var map = (new SourceMapBuilder() + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr)) + .build(output.url); + var mapping = parseJson(map); + check(outputVar1, mapping, inputVar1, false); + check(outputVar2, mapping, inputVar2, false); + check(outputFunction, mapping, inputFunction, false); + check(outputExpr, mapping, inputExpr, false); + }); + + test('build + parse with file', () { + var json = (new SourceMapBuilder() + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr)) + .toJson(output.url); + var mapping = parse(json); + check(outputVar1, mapping, inputVar1, true); + check(outputVar2, mapping, inputVar2, true); + check(outputFunction, mapping, inputFunction, true); + check(outputExpr, mapping, inputExpr, true); + }); + + test('printer projecting marks + parse', () { + var out = INPUT.replaceAll('long', '_s'); + var file = new SourceFile.text('output2.dart', out); + var printer = new Printer('output2.dart'); + printer.mark(ispan(0, 0)); + + bool first = true; + var segments = INPUT.split('long'); + expect(segments.length, 6); + printer.add(segments[0], projectMarks: true); + printer.mark(inputVar1); + printer.add('_s'); + printer.add(segments[1], projectMarks: true); + printer.mark(inputFunction); + printer.add('_s'); + printer.add(segments[2], projectMarks: true); + printer.mark(inputVar2); + printer.add('_s'); + printer.add(segments[3], projectMarks: true); + printer.mark(inputExpr); + printer.add('_s'); + printer.add(segments[4], projectMarks: true); + printer.add('_s'); + printer.add(segments[5], projectMarks: true); + + expect(printer.text, out); + + var mapping = parse(printer.map); + checkHelper(Span inputSpan, int adjustment) { + var start = inputSpan.start.offset - adjustment; + var end = (inputSpan.end.offset - adjustment) - 2; + var span = new FileSpan(file, start, end, inputSpan.isIdentifier); + check(span, mapping, inputSpan, true); + } + + checkHelper(inputVar1, 0); + checkHelper(inputFunction, 2); + checkHelper(inputVar2, 4); + checkHelper(inputExpr, 6); + + // We projected correctly lines that have no mappings + check(new FileSpan(file, 66, 66, false), mapping, ispan(45, 45), true); + check(new FileSpan(file, 63, 64, false), mapping, ispan(45, 45), true); + check(new FileSpan(file, 68, 68, false), mapping, ispan(70, 70), true); + check(new FileSpan(file, 71, 71, false), mapping, ispan(70, 70), true); + + // Start of the last line + var oOffset = out.length - 2; + var iOffset = INPUT.length - 2; + check(new FileSpan(file, oOffset, oOffset, false), mapping, + ispan(iOffset, iOffset), true); + check(new FileSpan(file, oOffset + 1, oOffset + 1, false), mapping, + ispan(iOffset, iOffset), true); + }); +} diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart new file mode 100644 index 000000000..1c32cbd34 --- /dev/null +++ b/pkgs/source_maps/test/parser_test.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2013, 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. + +library test.parser_test; + +import 'dart:json' as json; +import 'package:unittest/unittest.dart'; +import 'package:source_maps/source_maps.dart'; +import 'common.dart'; + +main() { + test('parse', () { + var mapping = parseJson(EXPECTED_MAP); + check(outputVar1, mapping, inputVar1, false); + check(outputVar2, mapping, inputVar2, false); + check(outputFunction, mapping, inputFunction, false); + check(outputExpr, mapping, inputExpr, false); + }); + + test('parse + json', () { + var mapping = parse(json.stringify(EXPECTED_MAP)); + check(outputVar1, mapping, inputVar1, false); + check(outputVar2, mapping, inputVar2, false); + check(outputFunction, mapping, inputFunction, false); + check(outputExpr, mapping, inputExpr, false); + }); + + test('parse with file', () { + var mapping = parseJson(EXPECTED_MAP); + check(outputVar1, mapping, inputVar1, true); + check(outputVar2, mapping, inputVar2, true); + check(outputFunction, mapping, inputFunction, true); + check(outputExpr, mapping, inputExpr, true); + }); +} diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart new file mode 100644 index 000000000..d038ad51b --- /dev/null +++ b/pkgs/source_maps/test/printer_test.dart @@ -0,0 +1,82 @@ +// Copyright (c) 2013, 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. + +library test.printer_test; + +import 'dart:json' as json; +import 'package:unittest/unittest.dart'; +import 'package:source_maps/printer.dart'; +import 'package:source_maps/span.dart'; +import 'common.dart'; + +main() { + test('printer', () { + var printer = new Printer('output.dart'); + printer..add('var ') + ..mark(inputVar1) + ..add('x = 3;\n') + ..mark(inputFunction) + ..add('f(') + ..mark(inputVar2) + ..add('y) => ') + ..mark(inputExpr) + ..add('x + y;\n'); + expect(printer.text, OUTPUT); + expect(printer.map, json.stringify(EXPECTED_MAP)); + }); + + test('printer projecting marks', () { + var out = INPUT.replaceAll('long', '_s'); + var printer = new Printer('output2.dart'); + + var segments = INPUT.split('long'); + expect(segments.length, 6); + printer..mark(ispan(0, 0)) + ..add(segments[0], projectMarks: true) + ..mark(inputVar1) + ..add('_s') + ..add(segments[1], projectMarks: true) + ..mark(inputFunction) + ..add('_s') + ..add(segments[2], projectMarks: true) + ..mark(inputVar2) + ..add('_s') + ..add(segments[3], projectMarks: true) + ..mark(inputExpr) + ..add('_s') + ..add(segments[4], projectMarks: true) + ..add('_s') + ..add(segments[5], projectMarks: true); + + expect(printer.text, out); + // 8 new lines in the source map: + expect(printer.map.split(';').length, 8); + + asFixed(Span s) => new FixedSpan(s.sourceUrl, + s.start.offset, s.start.line, s.start.column, + text: s.text, isIdentifier: s.isIdentifier); + + // The result is the same if we use fixed positions + var printer2 = new Printer('output2.dart'); + printer2..mark(new FixedSpan('input.dart', 0, 0, 0)) + ..add(segments[0], projectMarks: true) + ..mark(asFixed(inputVar1)) + ..add('_s') + ..add(segments[1], projectMarks: true) + ..mark(asFixed(inputFunction)) + ..add('_s') + ..add(segments[2], projectMarks: true) + ..mark(asFixed(inputVar2)) + ..add('_s') + ..add(segments[3], projectMarks: true) + ..mark(asFixed(inputExpr)) + ..add('_s') + ..add(segments[4], projectMarks: true) + ..add('_s') + ..add(segments[5], projectMarks: true); + + expect(printer2.text, out); + expect(printer2.map, printer.map); + }); +} diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart new file mode 100755 index 000000000..9a197855f --- /dev/null +++ b/pkgs/source_maps/test/run.dart @@ -0,0 +1,38 @@ +#!/usr/bin/env dart +// Copyright (c) 2013, 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. + +library test.run; + +import 'package:unittest/compact_vm_config.dart'; +import 'package:unittest/unittest.dart'; +import 'dart:io' show Options; + +import 'builder_test.dart' as builder_test; +import 'end2end_test.dart' as end2end_test; +import 'parser_test.dart' as parser_test; +import 'printer_test.dart' as printer_test; +import 'span_test.dart' as span_test; +import 'utils_test.dart' as utils_test; +import 'vlq_test.dart' as vlq_test; + +main() { + var args = new Options().arguments; + var pattern = new RegExp(args.length > 0 ? args[0] : '.'); + useCompactVMConfiguration(); + + void addGroup(testFile, testMain) { + if (pattern.hasMatch(testFile)) { + group(testFile.replaceAll('_test.dart', ':'), testMain); + } + } + + addGroup('builder_test.dart', builder_test.main); + addGroup('end2end_test.dart', end2end_test.main); + addGroup('parser_test.dart', parser_test.main); + addGroup('printer_test.dart', printer_test.main); + addGroup('span_test.dart', span_test.main); + addGroup('utils_test.dart', utils_test.main); + addGroup('vlq_test.dart', vlq_test.main); +} diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart new file mode 100644 index 000000000..8f61b5871 --- /dev/null +++ b/pkgs/source_maps/test/span_test.dart @@ -0,0 +1,215 @@ +// Copyright (c) 2013, 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. + +library test.span_test; + +import 'package:unittest/unittest.dart'; +import 'package:source_maps/span.dart'; + +const String TEST_FILE = ''' ++23456789_ + + _123456789_123456789_123456789_123456789_123456789_123456789_123456789_ + + _123456789_1 +123+56789_123456789_1234567 +1234+6789_1234 +12345+789_123456789_12345 +123456+89_123456789_123456789_123456789_123456789_123456789_123456789_123456789 +1234567+9_123456789_123456789_123456789_123456789_123456789_123456789_123 +12345678+_123456789_123456789_123456789_123456789_1 +123456789+123456789_123456789_12345678 +123456789_+23456789_123456789_123456789_123 +123456789_1+3456789_123456789 +'''; + +List newLines = TEST_FILE.split('\n').map((s) => s.length).toList(); + +main() { + var file = new SourceFile.text('file', TEST_FILE); + span(int start, int end) => file.span(start, end); + loc(int offset) => file.location(offset); + + test('validate test input', () { + expect(newLines, + const [10, 80, 31, 27, 14, 25, 79, 73, 51, 38, 43, 29, 0]); + }); + + test('get line and column', () { + line(int n) => file.getLine(n); + col(int n) => file.getColumn(file.getLine(n), n); + + expect(line(8), 0); + expect(line(10), 0); + expect(line(11), 1); + expect(line(12), 1); + expect(line(91), 1); + expect(line(92), 2); + expect(line(93), 2); + expect(col(11), 0); + expect(col(12), 1); + expect(col(91), 80); + expect(col(92), 0); + expect(col(93), 1); + + int j = 0; + int lineOffset = 0; + for (int i = 0; i < TEST_FILE.length; i++) { + if (i > lineOffset + newLines[j]) { + lineOffset += newLines[j] + 1; + j++; + } + expect(line(i), j, reason: 'position: $i'); + expect(col(i), i - lineOffset, reason: 'position: $i'); + } + }); + + test('get text', () { + // fifth line (including 4 new lines), columns 2 .. 11 + var line = 10 + 80 + 31 + 27 + 4; + expect(file.getText(line + 2, line + 11), '34+6789_1'); + }); + + test('get location message', () { + // fifth line (including 4 new lines), columns 2 .. 11 + var line = 10 + 80 + 31 + 27 + 4; + expect(file.getLocationMessage('the message', line + 2, line + 11), + 'file:5:3: the message\n' + '1234+6789_1234\n' + ' ^^^^^^^^^'); + }); + + test('get location message - no file url', () { + var line = 10 + 80 + 31 + 27 + 4; + expect(new SourceFile.text(null, TEST_FILE).getLocationMessage( + 'the message', line + 2, line + 11), + ':5:3: the message\n' + '1234+6789_1234\n' + ' ^^^^^^^^^'); + }); + + test('location getters', () { + expect(loc(8).line, 0); + expect(loc(8).column, 8); + expect(loc(9).line, 0); + expect(loc(9).column, 9); + expect(loc(8).formatString, 'file:1:9'); + expect(loc(12).line, 1); + expect(loc(12).column, 1); + expect(loc(95).line, 2); + expect(loc(95).column, 3); + }); + + test('location compare', () { + var list = [9, 8, 11, 14, 6, 6, 1, 1].map((n) => loc(n)).toList(); + list.sort(); + var lastOffset = 0; + for (var location in list) { + expect(location.offset, greaterThanOrEqualTo(lastOffset)); + lastOffset = location.offset; + } + }); + + test('span getters', () { + expect(span(8, 9).start.line, 0); + expect(span(8, 9).start.column, 8); + expect(span(8, 9).end.line, 0); + expect(span(8, 9).end.column, 9); + expect(span(8, 9).text, '9'); + expect(span(8, 9).isIdentifier, false); + expect(span(8, 9).formatLocation, 'file:1:9'); + + var line = 10 + 80 + 31 + 27 + 4; + expect(span(line + 2, line + 11).getLocationMessage('the message'), + 'file:5:3: the message\n' + '1234+6789_1234\n' + ' ^^^^^^^^^'); + + expect(span(12, 95).start.line, 1); + expect(span(12, 95).start.column, 1); + expect(span(12, 95).end.line, 2); + expect(span(12, 95).end.column, 3); + expect(span(12, 95).text, + '+ _123456789_123456789_123456789_123456789_123456789_1234567' + '89_123456789_\n +'); + expect(span(12, 95).formatLocation, 'file:2:2'); + }); + + test('span union', () { + var union = new FileSpan.union(span(8, 9), span(12, 95)); + expect(union.start.offset, 8); + expect(union.start.line, 0); + expect(union.start.column, 8); + expect(union.end.offset, 95); + expect(union.end.line, 2); + expect(union.end.column, 3); + expect(union.text, + '9_\n' + ' + _123456789_123456789_123456789_123456789_123456789_' + '123456789_123456789_\n +'); + expect(union.formatLocation, 'file:1:9'); + }); + + test('span compare', () { + var list = [span(9, 10), span(8, 9), span(11, 12), span(14, 19), + span(6, 12), span(6, 8), span(1, 9), span(1, 2)]; + list.sort(); + var lastStart = 0; + var lastEnd = 0; + for (var span in list) { + expect(span.start.offset, greaterThanOrEqualTo(lastStart)); + if (span.start.offset == lastStart) { + expect(span.end.offset, greaterThanOrEqualTo(lastEnd)); + } + lastStart = span.start.offset; + lastEnd = span.end.offset; + } + }); + + test('file segment', () { + var segment = new SourceFileSegment('file', + TEST_FILE.substring(12), loc(12)); + sline(int n) => segment.getLine(n); + scol(int n) => segment.getColumn(segment.getLine(n), n); + + line(int n) => file.getLine(n); + col(int n) => file.getColumn(file.getLine(n), n); + + int j = 0; + int lineOffset = 0; + for (int i = 12; i < TEST_FILE.length; i++) { + if (i > lineOffset + newLines[j]) { + lineOffset += newLines[j] + 1; + j++; + } + expect(segment.location(i - 12).offset, i); + expect(segment.location(i - 12).line, line(i)); + expect(segment.location(i - 12).column, col(i)); + expect(segment.span(i - 12).start.offset, i); + expect(segment.span(i - 12).start.line, line(i)); + expect(segment.span(i - 12).start.column, col(i)); + + expect(sline(i), line(i)); + expect(scol(i), col(i)); + } + }); + + test('span isIdentifier defaults to false', () { + var start = new TestLocation(0); + var end = new TestLocation(1); + expect(new TestSpan(start, end).isIdentifier, false); + expect(file.span(8, 9, null).isIdentifier, false); + expect(new FixedSpan('', 8, 1, 8, isIdentifier: null).isIdentifier, false); + }); +} + +class TestSpan extends Span { + TestSpan(Location start, Location end) : super(start, end, null); + get text => null; +} + +class TestLocation extends Location { + String get sourceUrl => ''; + TestLocation(int offset) : super(offset); + get line => 0; + get column => 0; +} diff --git a/pkgs/source_maps/test/utils_test.dart b/pkgs/source_maps/test/utils_test.dart new file mode 100644 index 000000000..79a7de769 --- /dev/null +++ b/pkgs/source_maps/test/utils_test.dart @@ -0,0 +1,54 @@ +// Copyright (c) 2013, 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. + +/// Tests for the binary search utility algorithm. +library test.utils_test; + +import 'package:unittest/unittest.dart'; +import 'package:source_maps/src/utils.dart'; + +main() { + group('binary search', () { + test('empty', () { + expect(binarySearch([], (x) => true), -1); + }); + + test('single element', () { + expect(binarySearch([1], (x) => true), 0); + expect(binarySearch([1], (x) => false), 1); + }); + + test('no matches', () { + var list = [1, 2, 3, 4, 5, 6, 7]; + expect(binarySearch(list, (x) => false), list.length); + }); + + test('all match', () { + var list = [1, 2, 3, 4, 5, 6, 7]; + expect(binarySearch(list, (x) => true), 0); + }); + + test('compare with linear search', () { + for (int size = 0; size < 100; size++) { + var list = []; + for (int i = 0; i < size; i++) { + list.add(i); + } + for (int pos = 0; pos <= size; pos++) { + expect(binarySearch(list, (x) => x >= pos), + _linearSearch(list, (x) => x >= pos)); + } + } + }); + }); +} + +_linearSearch(list, predicate) { + if (list.length == 0) return -1; + for (int i = 0; i < list.length; i++) { + if (predicate(list[i])) return i; + } + return list.length; +} + diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart new file mode 100644 index 000000000..0abdc4795 --- /dev/null +++ b/pkgs/source_maps/test/vlq_test.dart @@ -0,0 +1,59 @@ +// Copyright (c) 2013, 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. + +library test.vlq_test; + +import 'dart:math'; +import 'package:unittest/unittest.dart'; +import 'package:source_maps/src/vlq.dart'; + +main() { + test('encode and decode - simple values', () { + expect(encodeVlq(1).join(''), 'C'); + expect(encodeVlq(2).join(''), 'E'); + expect(encodeVlq(3).join(''), 'G'); + expect(encodeVlq(100).join(''), 'oG'); + expect(decodeVlq('C'.split('').iterator), 1); + expect(decodeVlq('E'.split('').iterator), 2); + expect(decodeVlq('G'.split('').iterator), 3); + expect(decodeVlq('oG'.split('').iterator), 100); + }); + + test('encode and decode', () { + for (int i = -10000; i < 10000; i++) { + _checkEncodeDecode(i); + } + }); + + test('only 32-bit ints allowed', () { + var max_int = pow(2, 31) - 1; + var min_int = -pow(2, 31); + _checkEncodeDecode(max_int - 1); + _checkEncodeDecode(min_int + 1); + _checkEncodeDecode(max_int); + _checkEncodeDecode(min_int); + + expect(encodeVlq(min_int).join(''), 'hgggggE'); + expect(decodeVlq('hgggggE'.split('').iterator), min_int); + + expect(() => encodeVlq(max_int + 1), throws); + expect(() => encodeVlq(max_int + 2), throws); + expect(() => encodeVlq(min_int - 1), throws); + expect(() => encodeVlq(min_int - 2), throws); + + + // if we allowed more than 32 bits, these would be the expected encodings + // for the large numbers above. + expect(() => decodeVlq('ggggggE'.split('').iterator), throws); + expect(() => decodeVlq('igggggE'.split('').iterator), throws); + expect(() => decodeVlq('jgggggE'.split('').iterator), throws); + expect(() => decodeVlq('lgggggE'.split('').iterator), throws); + }); +} + +_checkEncodeDecode(int value) { + var encoded = encodeVlq(value); + expect(decodeVlq(encoded.iterator), value); + expect(decodeVlq(encoded.join('').split('').iterator), value); +} From 909880414b99eda0198faf70567ddb6ec4db90c6 Mon Sep 17 00:00:00 2001 From: "kevmoo@j832.com" Date: Tue, 9 Apr 2013 13:51:05 +0000 Subject: [PATCH 002/657] lib/utf: remove codepointsToString point folks to use String.fromCharCodes Review URL: https://codereview.chromium.org//13493020 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@21151 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/span.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 19829941f..fd302bcb6 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -5,7 +5,7 @@ /// Dart classes representing the souce spans and source files. library source_maps.span; -import 'dart:utf' show stringToCodepoints, codepointsToString; +import 'dart:utf' show stringToCodepoints; import 'dart:math' show min; import 'src/utils.dart'; @@ -232,7 +232,7 @@ class SourceFile { /// Gets the text at the given offsets. String getText(int start, [int end]) { - return codepointsToString(_decodedChars.sublist(start, end)); + return new String.fromCharCodes(_decodedChars.sublist(start, end)); } /// Create a pretty string representation from a span. From 5fd76a732b3f5c43480c0e97ce4426f8b3a21c22 Mon Sep 17 00:00:00 2001 From: "sethladd@google.com" Date: Fri, 19 Apr 2013 20:51:10 +0000 Subject: [PATCH 003/657] add installation instructions to pkg packages BUG= Review URL: https://codereview.chromium.org//14188048 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@21770 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/source_maps.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 4e24deab5..15948276f 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -4,6 +4,21 @@ /// Source maps library. /// +/// ## Installing ## +/// +/// Use [pub][] to install this package. Add the following to your +/// `pubspec.yaml` file. +/// +/// dependencies: +/// source_maps: any +/// +/// Then run `pub install`. +/// +/// For more information, see the +/// [source_maps package on pub.dartlang.org][pkg]. +/// +/// ## Using ## +/// /// Create a source map using [SourceMapBuilder]. For example: /// var json = (new SourceMapBuilder() /// ..add(inputSpan1, outputSpan1) @@ -17,6 +32,9 @@ /// object. For example: /// var mapping = parse(json); /// mapping.spanFor(outputSpan1.line, outputSpan1.column) +/// +/// [pub]: http://pub.dartlang.org +/// [pkg]: http://pub.dartlang.org/packages/source_maps library source_maps; export "builder.dart"; From 2dc1edc3352223c21a082066cadc9c3b6ab9d370 Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Wed, 3 Jul 2013 22:26:55 +0000 Subject: [PATCH 004/657] Fixes source map bug: getLocationMessage was incorrect on file segments R=jmesserly@google.com Review URL: https://codereview.chromium.org//18083030 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@24759 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/span.dart | 58 +++++++++------ pkgs/source_maps/test/span_test.dart | 104 +++++++++++++++++++++------ 2 files changed, 119 insertions(+), 43 deletions(-) diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index fd302bcb6..e7bf5bfa4 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -6,7 +6,7 @@ library source_maps.span; import 'dart:utf' show stringToCodepoints; -import 'dart:math' show min; +import 'dart:math' show min, max; import 'src/utils.dart'; @@ -216,24 +216,18 @@ class SourceFile { Location location(int offset) => new FileLocation(this, offset); /// Gets the 0-based line corresponding to an offset. - int getLine(int offset) { - return binarySearch(_lineStarts, (o) => o > offset) - 1; - } + int getLine(int offset) => binarySearch(_lineStarts, (o) => o > offset) - 1; /// Gets the 0-based column corresponding to an offset. - int getColumn(int line, int offset) { - return offset - _lineStarts[line]; - } + int getColumn(int line, int offset) => offset - _lineStarts[line]; /// Get the offset for a given line and column - int getOffset(int line, int column) { - return _lineStarts[min(line, _lineStarts.length - 1)] + column; - } + int getOffset(int line, int column) => + _lineStarts[max(min(line, _lineStarts.length - 1), 0)] + column; /// Gets the text at the given offsets. - String getText(int start, [int end]) { - return new String.fromCharCodes(_decodedChars.sublist(start, end)); - } + String getText(int start, [int end]) => + new String.fromCharCodes(_decodedChars.sublist(max(start, 0), end)); /// Create a pretty string representation from a span. String getLocationMessage(String message, int start, int end, @@ -253,16 +247,12 @@ class SourceFile { var buf = new StringBuffer(msg); buf.write('\n'); - var textLine; // +1 for 0-indexing, +1 again to avoid the last line - if ((line + 2) < _lineStarts.length) { - textLine = getText(_lineStarts[line], _lineStarts[line + 1]); - } else { - textLine = getText(_lineStarts[line]); - textLine = '$textLine\n'; - } + var textLine = getText(getOffset(line, 0), getOffset(line + 1, 0)); + + column = min(column, textLine.length - 1); int toColumn = min(column + end - start, textLine.length); if (useColors) { if (color == null) { @@ -301,30 +291,52 @@ class SourceFileSegment extends SourceFile { final int _baseLine; final int _baseColumn; + // TODO(sigmund): consider providing an end-offset to correctly truncate + // values passed the end of the segment. SourceFileSegment(String url, String textSegment, Location startOffset) : _baseOffset = startOffset.offset, _baseLine = startOffset.line, _baseColumn = startOffset.column, super.text(url, textSegment); + /// Craete a span, where [start] is relative to this segment's base offset. + /// The returned span stores the real offset on the file, so that error + /// messages are reported at the real location. Span span(int start, [int end, bool isIdentifier = false]) => super.span(start + _baseOffset, end == null ? null : end + _baseOffset, isIdentifier); + /// Create a location, where [offset] relative to this segment's base offset. + /// The returned span stores the real offset on the file, so that error + /// messages are reported at the real location. Location location(int offset) => super.location(offset + _baseOffset); + /// Return the line on the underlying file associated with the [offset] of the + /// underlying file. This method operates on the real offsets from the + /// original file, so that error messages can be reported accurately. int getLine(int offset) => - super.getLine(offset - _baseOffset) + _baseLine; + super.getLine(max(offset - _baseOffset, 0)) + _baseLine; + /// Return the column on the underlying file associated with [line] and + /// [offset], where [line] is absolute from the beginning of the underlying + /// file. This method operates on the real offsets from the original file, so + /// that error messages can be reported accurately. int getColumn(int line, int offset) { - var col = super.getColumn(line - _baseLine, offset - _baseOffset); + var col = super.getColumn(line - _baseLine, max(offset - _baseOffset, 0)); return line == _baseLine ? col + _baseColumn : col; } + /// Return the offset associated with a line and column. This method operates + /// on the real offsets from the original file, so that error messages can be + /// reported accurately. int getOffset(int line, int column) => super.getOffset(line - _baseLine, line == _baseLine ? column - _baseColumn : column) + _baseOffset; + /// Retrieve the text associated with the specified range. This method + /// operates on the real offsets from the original file, so that error + /// messages can be reported accurately. String getText(int start, [int end]) => - super.getText(start - _baseOffset, end - _baseOffset); + super.getText(start - _baseOffset, + end == null ? null : end - _baseOffset); } diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart index 8f61b5871..66bd8a8cb 100644 --- a/pkgs/source_maps/test/span_test.dart +++ b/pkgs/source_maps/test/span_test.dart @@ -165,32 +165,96 @@ main() { } }); - test('file segment', () { - var segment = new SourceFileSegment('file', - TEST_FILE.substring(12), loc(12)); + test('range check for large offsets', () { + var start = TEST_FILE.length; + expect(file.getLocationMessage('the message', start, start + 9), + 'file:13:1: the message\n'); + }); + + group('file segment', () { + var baseOffset = 123; + var segmentText = TEST_FILE.substring(baseOffset, TEST_FILE.length - 100); + var segment = new SourceFileSegment('file', segmentText, loc(baseOffset)); sline(int n) => segment.getLine(n); scol(int n) => segment.getColumn(segment.getLine(n), n); - line(int n) => file.getLine(n); col(int n) => file.getColumn(file.getLine(n), n); - int j = 0; - int lineOffset = 0; - for (int i = 12; i < TEST_FILE.length; i++) { - if (i > lineOffset + newLines[j]) { - lineOffset += newLines[j] + 1; - j++; + test('get line and column', () { + int j = 0; + int lineOffset = 0; + for (int i = baseOffset; i < segmentText.length; i++) { + if (i > lineOffset + newLines[j]) { + lineOffset += newLines[j] + 1; + j++; + } + expect(segment.location(i - baseOffset).offset, i); + expect(segment.location(i - baseOffset).line, line(i)); + expect(segment.location(i - baseOffset).column, col(i)); + expect(segment.span(i - baseOffset).start.offset, i); + expect(segment.span(i - baseOffset).start.line, line(i)); + expect(segment.span(i - baseOffset).start.column, col(i)); + + expect(sline(i), line(i)); + expect(scol(i), col(i)); } - expect(segment.location(i - 12).offset, i); - expect(segment.location(i - 12).line, line(i)); - expect(segment.location(i - 12).column, col(i)); - expect(segment.span(i - 12).start.offset, i); - expect(segment.span(i - 12).start.line, line(i)); - expect(segment.span(i - 12).start.column, col(i)); - - expect(sline(i), line(i)); - expect(scol(i), col(i)); - } + }); + + test('get text', () { + var start = 10 + 80 + 31 + 27 + 4 + 2; + expect(segment.getText(start, start + 9), file.getText(start, start + 9)); + }); + + group('location message', () { + test('first line', () { + var start = baseOffset + 7; + expect(segment.getLocationMessage('the message', start, start + 2), + file.getLocationMessage('the message', start, start + 2)); + }); + + test('in a middle line', () { + // Example from another test above: + var start = 10 + 80 + 31 + 27 + 4 + 2; + expect(segment.getLocationMessage('the message', start, start + 9), + file.getLocationMessage('the message', start, start + 9)); + }); + + test('last segment line', () { + var start = segmentText.length - 4; + expect(segment.getLocationMessage('the message', start, start + 2), + file.getLocationMessage('the message', start, start + 2)); + }); + + test('past segment, same as last segment line', () { + var start = segmentText.length; + expect(segment.getLocationMessage('the message', start, start + 2), + file.getLocationMessage('the message', start, start + 2)); + + start = segmentText.length + 20; + expect(segment.getLocationMessage('the message', start, start + 2), + file.getLocationMessage('the message', start, start + 2)); + }); + + test('past segment, past its line', () { + var start = TEST_FILE.length - 2; + expect(file.getLocationMessage('the message', start, start + 1), + 'file:12:29: the message\n' + '123456789_1+3456789_123456789\n' + ' ^'); + + // TODO(sigmund): consider also fixing this and report file:10:4 + // The answer below is different because the segment parsing only knows + // about the 10 lines it has (and nothing about the possible extra lines + // afterwards) + expect(segment.getLocationMessage('the message', start, start + 1), + 'file:10:112: the message\n'); + + // The number 112 includes the count of extra characters past the + // segment, which we verify here: + var lastSegmentLineStart = segmentText.lastIndexOf('\n'); + expect(start - baseOffset - lastSegmentLineStart, 112); + }); + }); }); test('span isIdentifier defaults to false', () { From d98bf46e00969efa5fe10d99d479bf2d006bca9e Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Wed, 10 Jul 2013 16:56:00 +0000 Subject: [PATCH 005/657] Fixes in sourcemaps discovered in csslib R=dgrove@google.com Review URL: https://codereview.chromium.org//18749005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@24881 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/span.dart | 38 +++++++---- pkgs/source_maps/test/span_test.dart | 96 +++++++++++++++++++++------- 2 files changed, 99 insertions(+), 35 deletions(-) diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index e7bf5bfa4..7ca0ca97c 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -219,11 +219,20 @@ class SourceFile { int getLine(int offset) => binarySearch(_lineStarts, (o) => o > offset) - 1; /// Gets the 0-based column corresponding to an offset. - int getColumn(int line, int offset) => offset - _lineStarts[line]; + int getColumn(int line, int offset) { + if (line < 0 || line >= _lineStarts.length) return 0; + return offset - _lineStarts[line]; + } /// Get the offset for a given line and column - int getOffset(int line, int column) => - _lineStarts[max(min(line, _lineStarts.length - 1), 0)] + column; + int getOffset(int line, int column) { + if (line < 0) return getOffset(0, 0); + if (line < _lineStarts.length) { + return _lineStarts[line] + column; + } else { + return _decodedChars.length; + } + } /// Gets the text at the given offsets. String getText(int start, [int end]) => @@ -251,7 +260,6 @@ class SourceFile { // +1 for 0-indexing, +1 again to avoid the last line var textLine = getText(getOffset(line, 0), getOffset(line + 1, 0)); - column = min(column, textLine.length - 1); int toColumn = min(column + end - start, textLine.length); if (useColors) { @@ -265,6 +273,7 @@ class SourceFile { buf.write(textLine.substring(toColumn)); } else { buf.write(textLine); + if (textLine != '' && !textLine.endsWith('\n')) buf.write('\n'); } int i = 0; @@ -290,13 +299,13 @@ class SourceFileSegment extends SourceFile { final int _baseOffset; final int _baseLine; final int _baseColumn; + final int _maxOffset; - // TODO(sigmund): consider providing an end-offset to correctly truncate - // values passed the end of the segment. SourceFileSegment(String url, String textSegment, Location startOffset) : _baseOffset = startOffset.offset, _baseLine = startOffset.line, _baseColumn = startOffset.column, + _maxOffset = startOffset.offset + textSegment.length, super.text(url, textSegment); /// Craete a span, where [start] is relative to this segment's base offset. @@ -313,9 +322,13 @@ class SourceFileSegment extends SourceFile { /// Return the line on the underlying file associated with the [offset] of the /// underlying file. This method operates on the real offsets from the - /// original file, so that error messages can be reported accurately. - int getLine(int offset) => - super.getLine(max(offset - _baseOffset, 0)) + _baseLine; + /// original file, so that error messages can be reported accurately. When the + /// requested offset is past the length of the segment, this returns the line + /// number after the end of the segment (total lines + 1). + int getLine(int offset) { + var res = super.getLine(max(offset - _baseOffset, 0)) + _baseLine; + return (offset > _maxOffset) ? res + 1 : res; + } /// Return the column on the underlying file associated with [line] and /// [offset], where [line] is absolute from the beginning of the underlying @@ -330,13 +343,12 @@ class SourceFileSegment extends SourceFile { /// on the real offsets from the original file, so that error messages can be /// reported accurately. int getOffset(int line, int column) => - super.getOffset(line - _baseLine, - line == _baseLine ? column - _baseColumn : column) + _baseOffset; + super.getOffset(line - _baseLine, + line == _baseLine ? column - _baseColumn : column) + _baseOffset; /// Retrieve the text associated with the specified range. This method /// operates on the real offsets from the original file, so that error /// messages can be reported accurately. String getText(int start, [int end]) => - super.getText(start - _baseOffset, - end == null ? null : end - _baseOffset); + super.getText(start - _baseOffset, end == null ? null : end - _baseOffset); } diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart index 66bd8a8cb..c7b9cde16 100644 --- a/pkgs/source_maps/test/span_test.dart +++ b/pkgs/source_maps/test/span_test.dart @@ -69,22 +69,80 @@ main() { expect(file.getText(line + 2, line + 11), '34+6789_1'); }); - test('get location message', () { - // fifth line (including 4 new lines), columns 2 .. 11 - var line = 10 + 80 + 31 + 27 + 4; - expect(file.getLocationMessage('the message', line + 2, line + 11), - 'file:5:3: the message\n' - '1234+6789_1234\n' - ' ^^^^^^^^^'); - }); + group('location message', () { + test('first line', () { + expect(file.getLocationMessage('the message', 1, 3), + 'file:1:2: the message\n' + '+23456789_\n' + ' ^^'); + }); - test('get location message - no file url', () { - var line = 10 + 80 + 31 + 27 + 4; - expect(new SourceFile.text(null, TEST_FILE).getLocationMessage( - 'the message', line + 2, line + 11), - ':5:3: the message\n' - '1234+6789_1234\n' - ' ^^^^^^^^^'); + test('in the middle of the file', () { + // fifth line (including 4 new lines), columns 2 .. 11 + var line = 10 + 80 + 31 + 27 + 4; + expect(file.getLocationMessage('the message', line + 2, line + 11), + 'file:5:3: the message\n' + '1234+6789_1234\n' + ' ^^^^^^^^^'); + }); + + test('no file url', () { + var line = 10 + 80 + 31 + 27 + 4; + expect(new SourceFile.text(null, TEST_FILE).getLocationMessage( + 'the message', line + 2, line + 11), + ':5:3: the message\n' + '1234+6789_1234\n' + ' ^^^^^^^^^'); + }); + + test('penultimate line', () { + // We search '\n' backwards twice because last line is \n terminated: + int index = TEST_FILE.lastIndexOf('\n'); + var start = TEST_FILE.lastIndexOf('\n', index - 1) - 3; + expect(file.getLocationMessage('the message', start, start + 2), + 'file:11:41: the message\n' + '123456789_+23456789_123456789_123456789_123\n' + ' ^^'); + }); + + test('last line', () { + var start = TEST_FILE.lastIndexOf('\n') - 2; + expect(file.getLocationMessage('the message', start, start + 1), + 'file:12:28: the message\n' + '123456789_1+3456789_123456789\n' + ' ^'); + }); + + group('no trailing empty-line at the end -', () { + var text = TEST_FILE.substring(0, TEST_FILE.length - 1); + var file2 = new SourceFile.text('file', text); + + test('penultimate line', () { + var start = text.lastIndexOf('\n') - 3; + expect(file2.getLocationMessage('the message', start, start + 2), + 'file:11:41: the message\n' + '123456789_+23456789_123456789_123456789_123\n' + ' ^^'); + }); + + test('last line', () { + var start = text.length - 2; + expect(file2.getLocationMessage('the message', start, start + 1), + 'file:12:28: the message\n' + '123456789_1+3456789_123456789\n' + ' ^'); + }); + }); + + test('single line', () { + var text = "this is a single line"; + int start = text.indexOf(' ') + 1; + var file2 = new SourceFile.text('file', text); + expect(file2.getLocationMessage('the message', start, start + 2), + 'file:1:${start + 1}: the message\n' + 'this is a single line\n' + ' ^^'); + }); }); test('location getters', () { @@ -242,17 +300,11 @@ main() { '123456789_1+3456789_123456789\n' ' ^'); - // TODO(sigmund): consider also fixing this and report file:10:4 // The answer below is different because the segment parsing only knows // about the 10 lines it has (and nothing about the possible extra lines // afterwards) expect(segment.getLocationMessage('the message', start, start + 1), - 'file:10:112: the message\n'); - - // The number 112 includes the count of extra characters past the - // segment, which we verify here: - var lastSegmentLineStart = segmentText.lastIndexOf('\n'); - expect(start - baseOffset - lastSegmentLineStart, 112); + 'file:11:1: the message\n'); }); }); }); From 920ff12d6c4a697a78929afad50744723202dbd4 Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Fri, 12 Jul 2013 23:14:38 +0000 Subject: [PATCH 006/657] Fix bug in source-maps parsing: parser failed when most information could be inferred. This fixes bug http://dartbug.com/11782 R=dgrove@google.com Review URL: https://codereview.chromium.org//19019006 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@24981 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/builder.dart | 18 +++++--- pkgs/source_maps/lib/parser.dart | 11 +++-- pkgs/source_maps/lib/source_maps.dart | 31 +++++++------- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/common.dart | 8 ++++ pkgs/source_maps/test/end2end_test.dart | 55 +++++++++++++++++++++++++ 6 files changed, 97 insertions(+), 28 deletions(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index ad80fa000..be00c9e81 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -74,12 +74,20 @@ class SourceMapBuilder { first = false; column = _append(buff, column, entry.target.column); - if (entry.source == null) continue; + // Encoding can be just the column offset if there is no source + // information, or if two consecutive mappings share exactly the same + // source information. + var source = entry.source; + if (source == null) continue; + var newUrlId = _indexOf(_urls, source.sourceUrl); + if (newUrlId == srcUrlId && source.line == srcLine + && source.column == srcColumn && entry.identifierName == null) { + continue; + } - srcUrlId = _append(buff, srcUrlId, - _indexOf(_urls, entry.source.sourceUrl)); - srcLine = _append(buff, srcLine, entry.source.line); - srcColumn = _append(buff, srcColumn, entry.source.column); + srcUrlId = _append(buff, srcUrlId, newUrlId); + srcLine = _append(buff, srcLine, source.line); + srcColumn = _append(buff, srcColumn, source.column); if (entry.identifierName == null) continue; srcNameId = _append(buff, srcNameId, diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 3849913a3..e2932634f 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -25,9 +25,8 @@ Mapping parseJson(Map map, {Map otherMaps}) { 'Only version 3 is supported.'); } - // TODO(sigmund): relax this? dart2js doesn't generate the file entry. if (!map.containsKey('file')) { - throw new ArgumentError('missing "file" in source map'); + print('warning: missing "file" entry in source map'); } if (map.containsKey('sections')) { @@ -186,7 +185,7 @@ class SingleMapping extends Mapping { if (tokenizer.nextKind.isNewSegment) throw _segmentError(0, line); column += tokenizer._consumeValue(); if (!tokenizer.nextKind.isValue) { - entries.add(new TargetEntry(column)); + entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn)); } else { srcUrlId += tokenizer._consumeValue(); if (srcUrlId >= urls.length) { @@ -242,7 +241,6 @@ class SingleMapping extends Mapping { } Span spanFor(int line, int column, {Map files}) { - var lineEntry = _findLine(line); var entry = _findColumn(line, column, _findLine(line)); if (entry == null) return null; var url = urls[entry.sourceUrlId]; @@ -323,8 +321,9 @@ class TargetEntry { final int sourceLine; final int sourceColumn; final int sourceNameId; - TargetEntry(this.column, [this.sourceUrlId, this.sourceLine, - this.sourceColumn, this.sourceNameId]); + + TargetEntry(this.column, this.sourceUrlId, this.sourceLine, + this.sourceColumn, [this.sourceNameId]); String toString() => '$runtimeType: ' '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 15948276f..8fc48c996 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -2,22 +2,7 @@ // 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. -/// Source maps library. -/// -/// ## Installing ## -/// -/// Use [pub][] to install this package. Add the following to your -/// `pubspec.yaml` file. -/// -/// dependencies: -/// source_maps: any -/// -/// Then run `pub install`. -/// -/// For more information, see the -/// [source_maps package on pub.dartlang.org][pkg]. -/// -/// ## Using ## +/// Library to create and parse source maps. /// /// Create a source map using [SourceMapBuilder]. For example: /// var json = (new SourceMapBuilder() @@ -33,6 +18,20 @@ /// var mapping = parse(json); /// mapping.spanFor(outputSpan1.line, outputSpan1.column) /// +/// ## Getting the code ## +/// +/// This library is distributed as a [pub][] package. To install this package, +/// add the following to your `pubspec.yaml` file: +/// +/// dependencies: +/// source_maps: any +/// +/// After you run `pub install`, you should be able to access this library by +/// importing `package:source_maps/source_maps.dart`. +/// +/// For more information, see the +/// [source_maps package on pub.dartlang.org][pkg]. +/// /// [pub]: http://pub.dartlang.org /// [pkg]: http://pub.dartlang.org/packages/source_maps library source_maps; diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index a559b5850..4ae180291 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,6 +1,6 @@ name: source_maps author: "Dart Team " -homepage: https://github.com/dart-lang/source-maps +homepage: http://www.dartlang.org description: Library to programmatically manipulate source map files. dev_dependencies: unittest: any diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index 661979b85..0c1f28a74 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -27,6 +27,11 @@ Span ispan(int start, int end, [bool isIdentifier = false]) => Span inputVar1 = ispan(30, 38, true); Span inputFunction = ispan(74, 82, true); Span inputVar2 = ispan(87, 95, true); + +Span inputVar1NoSymbol = ispan(30, 38); +Span inputFunctionNoSymbol = ispan(74, 82); +Span inputVar2NoSymbol = ispan(87, 95); + Span inputExpr = ispan(108, 127); /// Content of the target file @@ -43,6 +48,9 @@ Span ospan(int start, int end, [bool isIdentifier = false]) => Span outputVar1 = ospan(4, 5, true); Span outputFunction = ospan(11, 12, true); Span outputVar2 = ospan(13, 14, true); +Span outputVar1NoSymbol = ospan(4, 5); +Span outputFunctionNoSymbol = ospan(11, 12); +Span outputVar2NoSymbol = ospan(13, 14); Span outputExpr = ospan(19, 24); /// Expected output mapping when recording the following four mappings: diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 5ea958a98..99fe40d40 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -13,11 +13,17 @@ main() { expect(inputVar1.text, 'longVar1'); expect(inputFunction.text, 'longName'); expect(inputVar2.text, 'longVar2'); + expect(inputVar1NoSymbol.text, 'longVar1'); + expect(inputFunctionNoSymbol.text, 'longName'); + expect(inputVar2NoSymbol.text, 'longVar2'); expect(inputExpr.text, 'longVar1 + longVar2'); expect(outputVar1.text, 'x'); expect(outputFunction.text, 'f'); expect(outputVar2.text, 'y'); + expect(outputVar1NoSymbol.text, 'x'); + expect(outputFunctionNoSymbol.text, 'f'); + expect(outputVar2NoSymbol.text, 'y'); expect(outputExpr.text, 'x + y'); }); @@ -35,6 +41,55 @@ main() { check(outputExpr, mapping, inputExpr, false); }); + test('build + parse - no symbols', () { + var map = (new SourceMapBuilder() + ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) + ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) + ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) + ..addSpan(inputExpr, outputExpr)) + .build(output.url); + var mapping = parseJson(map); + check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false); + check(outputVar2NoSymbol, mapping, inputVar2NoSymbol, false); + check(outputFunctionNoSymbol, mapping, inputFunctionNoSymbol, false); + check(outputExpr, mapping, inputExpr, false); + }); + + test('build + parse, repeated entries', () { + var map = (new SourceMapBuilder() + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr) + ..addSpan(inputExpr, outputExpr)) + .build(output.url); + var mapping = parseJson(map); + check(outputVar1, mapping, inputVar1, false); + check(outputVar2, mapping, inputVar2, false); + check(outputFunction, mapping, inputFunction, false); + check(outputExpr, mapping, inputExpr, false); + }); + + test('build + parse - no symbols, repeated entries', () { + var map = (new SourceMapBuilder() + ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) + ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) + ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) + ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) + ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) + ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) + ..addSpan(inputExpr, outputExpr)) + .build(output.url); + var mapping = parseJson(map); + check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false); + check(outputVar2NoSymbol, mapping, inputVar2NoSymbol, false); + check(outputFunctionNoSymbol, mapping, inputFunctionNoSymbol, false); + check(outputExpr, mapping, inputExpr, false); + }); + test('build + parse with file', () { var json = (new SourceMapBuilder() ..addSpan(inputVar1, outputVar1) From f6c5549cb063f3d01ce165b10996e08f8fbf6a2c Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Tue, 16 Jul 2013 16:01:36 +0000 Subject: [PATCH 007/657] Address hint discovered by dart2js: add hashCode to source_maps.Span R=dgrove@google.com Review URL: https://codereview.chromium.org//19315003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@25050 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/span.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 7ca0ca97c..1d2152da7 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -69,6 +69,8 @@ abstract class Span implements Comparable { bool operator ==(Span other) => sourceUrl == other.sourceUrl && start == other.start && end == other.end; + int get hashCode => sourceUrl.hashCode + start + (31 * (end - start)); + String toString() => '<$runtimeType: $start $end $formatLocation $text>'; } From df5c29e07cb327774f9312aab07da86b9f37a097 Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Fri, 26 Jul 2013 00:50:29 +0000 Subject: [PATCH 008/657] Fix source spans hashcode implementation R=justinfagnani@google.com Review URL: https://codereview.chromium.org//20600002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@25514 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/span.dart | 7 ++++++- pkgs/source_maps/test/span_test.dart | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 1d2152da7..e5057fceb 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -69,7 +69,7 @@ abstract class Span implements Comparable { bool operator ==(Span other) => sourceUrl == other.sourceUrl && start == other.start && end == other.end; - int get hashCode => sourceUrl.hashCode + start + (31 * (end - start)); + int get hashCode => sourceUrl.hashCode + start.offset + (31 * length); String toString() => '<$runtimeType: $start $end $formatLocation $text>'; } @@ -99,6 +99,11 @@ abstract class Location implements Comparable { return offset - other.offset; } + bool operator ==(Location other) => + sourceUrl == other.sourceUrl && offset == other.offset; + + int get hashCode => sourceUrl.hashCode + offset; + String toString() => '(Location $offset)'; String get formatString => '$sourceUrl:${line + 1}:${column + 1}'; } diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart index c7b9cde16..da3e063ef 100644 --- a/pkgs/source_maps/test/span_test.dart +++ b/pkgs/source_maps/test/span_test.dart @@ -316,6 +316,16 @@ main() { expect(file.span(8, 9, null).isIdentifier, false); expect(new FixedSpan('', 8, 1, 8, isIdentifier: null).isIdentifier, false); }); + + test('span/location implement == and hashCode', () { + expect(identical(span(10, 14), span(10, 14)), isFalse); + expect(span(10, 14), equals(span(10, 14))); + expect(span(10, 14).hashCode, span(10, 14).hashCode); + + expect(identical(loc(13), loc(13)), isFalse); + expect(loc(13), equals(loc(13))); + expect(loc(13).hashCode, loc(13).hashCode); + }); } class TestSpan extends Span { From 889b8ab4291d2a3ac434b79dcd071d8fe798c01d Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Fri, 9 Aug 2013 22:29:38 +0000 Subject: [PATCH 009/657] Make observable transform a barback transform. R=jmesserly@google.com, nweiz@google.com, rnystrom@google.com Review URL: https://codereview.chromium.org//22396004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@25985 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/printer.dart | 160 ++++++++++++++++++++++- pkgs/source_maps/lib/refactor.dart | 131 +++++++++++++++++++ pkgs/source_maps/lib/source_maps.dart | 1 + pkgs/source_maps/test/printer_test.dart | 40 ++++++ pkgs/source_maps/test/refactor_test.dart | 96 ++++++++++++++ pkgs/source_maps/test/run.dart | 2 + 6 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 pkgs/source_maps/lib/refactor.dart create mode 100644 pkgs/source_maps/test/refactor_test.dart diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 333aadcd4..95539d2b7 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -12,8 +12,8 @@ import 'span.dart'; const int _LF = 10; const int _CR = 13; -/// A printer that keeps track of offset locations and records source maps -/// locations. +/// A simple printer that keeps track of offset locations and records source +/// maps locations. class Printer { final String filename; final StringBuffer _buff = new StringBuffer(); @@ -87,3 +87,159 @@ class Printer { _loc = loc; } } + +/// A more advanced printer that keeps track of offset locations to record +/// source maps, but additionally allows nesting of different kind of items, +/// including [NestedPrinter]s, and it let's you automatically indent text. +/// +/// This class is especially useful when doing code generation, where different +/// peices of the code are generated independently on separate printers, and are +/// finally put together in the end. +class NestedPrinter implements NestedItem { + + /// Items recoded by this printer, which can be [String] literals, + /// [NestedItem]s, and source map information like [Location] and [Span]. + List _items = []; + + /// Internal buffer to merge consecutive strings added to this printer. + StringBuffer _buff; + + /// Current indentation, which can be updated from outside this class. + int indent; + + /// Item used to indicate that the following item is copied from the original + /// source code, and hence we should preserve source-maps on every new line. + static final _ORIGINAL = new Object(); + + NestedPrinter([this.indent = 0]); + + /// Adds [object] to this printer. [object] can be a [String], + /// [NestedPrinter], or anything implementing [NestedItem]. If [object] is a + /// [String], the value is appended directly, without doing any formatting + /// changes. If you wish to add a line of code with automatic indentation, use + /// [addLine] instead. [NestedPrinter]s and [NestedItem]s are not processed + /// until [build] gets called later on. We ensure that [build] emits every + /// object in the order that they were added to this printer. + /// + /// The [location] and [span] parameters indicate the corresponding source map + /// location of [object] in the original input. Only one, [location] or + /// [span], should be provided at a time. + /// + /// Indicate [isOriginal] when [object] is copied directly from the user code. + /// Setting [isOriginal] will make this printer propagate source map locations + /// on every line-break. + void add(object, {Location location, Span span, bool isOriginal: false}) { + if (object is! String || location != null || span != null || isOriginal) { + _flush(); + assert(location == null || span == null); + if (location != null) _items.add(location); + if (span != null) _items.add(span); + if (isOriginal) _items.add(_ORIGINAL); + } + + if (object is String) { + _appendString(object); + } else { + _items.add(object); + } + } + + /// Append `2 * indent` spaces to this printer. + void insertIndent() => _indent(indent); + + /// Add a [line], autoindenting to the current value of [indent]. Note, + /// indentation is not inferred from the contents added to this printer. If a + /// line starts or ends an indentation block, you need to also update [indent] + /// accordingly. Also, indentation is not adapted for nested printers. If + /// you add a [NestedPrinter] to this printer, its indentation is set + /// separately and will not include any the indentation set here. + /// + /// The [location] and [span] parameters indicate the corresponding source map + /// location of [object] in the original input. Only one, [location] or + /// [span], should be provided at a time. + void addLine(String line, {Location location, Span span}) { + if (location != null || span != null) { + _flush(); + assert(location == null || span == null); + if (location != null) _items.add(location); + if (span != null) _items.add(span); + } + if (line == null) return; + if (line != '') { + // We don't indent empty lines. + _indent(indent); + _appendString(line); + } + _appendString('\n'); + } + + /// Appends a string merging it with any previous strings, if possible. + void _appendString(String s) { + if (_buff == null) _buff = new StringBuffer(); + _buff.write(s); + } + + /// Adds all of the current [_buff] contents as a string item. + void _flush() { + if (_buff != null) { + _items.add(_buff.toString()); + _buff = null; + } + } + + void _indent(int indent) { + for (int i = 0; i < indent; i++) _appendString(' '); + } + + /// Returns a string representation of all the contents appended to this + /// printer, including source map location tokens. + String toString() { + _flush(); + return (new StringBuffer()..writeAll(_items)).toString(); + } + + /// [Printer] used during the last call to [build], if any. + Printer printer; + + /// Returns the text produced after calling [build]. + String get text => printer.text; + + /// Returns the source-map information produced after calling [build]. + String get map => printer.map; + + /// Builds the output of this printer and source map information. After + /// calling this function, you can use [text] and [map] to retrieve the + /// geenrated code and source map information, respectively. + void build(String filename) { + writeTo(printer = new Printer(filename)); + } + + /// Implements the [NestedItem] interface. + void writeTo(Printer printer) { + _flush(); + bool propagate = false; + for (var item in _items) { + if (item is NestedItem) { + item.writeTo(printer); + } else if (item is String) { + printer.add(item, projectMarks: propagate); + propagate = false; + } else if (item is Location || item is Span) { + printer.mark(item); + } else if (item == _ORIGINAL) { + // we insert booleans when we are about to quote text that was copied + // from the original source. In such case, we will propagate marks on + // every new-line. + propagate = true; + } else { + throw new UnsupportedError('Unknown item type: $item'); + } + } + } +} + +/// An item added to a [NestedPrinter]. +abstract class NestedItem { + /// Write the contents of this item into [printer]. + void writeTo(Printer printer); +} diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart new file mode 100644 index 000000000..45fb06949 --- /dev/null +++ b/pkgs/source_maps/lib/refactor.dart @@ -0,0 +1,131 @@ +// Copyright (c) 2013, 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. + +/// Tools to help implement refactoring like transformations to Dart code. +/// +/// [TextEditTransaction] supports making a series of changes to a text buffer. +/// [guessIndent] helps to guess the appropriate indentiation for the new code. +library source_maps.refactor; + +import 'span.dart'; +import 'printer.dart'; + +/// Editable text transaction. +/// +/// Applies a series of edits using original location +/// information, and composes them into the edited string. +class TextEditTransaction { + final SourceFile file; + final String original; + final _edits = <_TextEdit>[]; + + TextEditTransaction(this.original, this.file); + + bool get hasEdits => _edits.length > 0; + + /// Edit the original text, replacing text on the range [begin] and [end] + /// with the [replacement]. [replacement] can be either a string or a + /// [NestedPrinter]. + void edit(int begin, int end, replacement) { + _edits.add(new _TextEdit(begin, end, replacement)); + } + + /// Create a source map [Location] for [offset]. + Location _loc(int offset) => + file != null ? file.location(offset) : null; + + /// Applies all pending [edit]s and returns a [NestedPrinter] containing the + /// rewritten string and source map information. [filename] is given to the + /// underlying printer to indicate the name of the generated file that will + /// contains the source map information. + /// + /// Throws [UnsupportedError] if the edits were overlapping. If no edits were + /// made, the printer simply contains the original string. + NestedPrinter commit() { + var printer = new NestedPrinter(); + if (_edits.length == 0) { + return printer..add(original, location: _loc(0), isOriginal: true); + } + + // Sort edits by start location. + _edits.sort(); + + int consumed = 0; + for (var edit in _edits) { + if (consumed > edit.begin) { + var sb = new StringBuffer(); + sb..write(file.location(edit.begin).formatString) + ..write(': overlapping edits. Insert at offset ') + ..write(edit.begin) + ..write(' but have consumed ') + ..write(consumed) + ..write(' input characters. List of edits:'); + for (var e in _edits) sb..write('\n ')..write(e); + throw new UnsupportedError(sb.toString()); + } + + // Add characters from the original string between this edit and the last + // one, if any. + var betweenEdits = original.substring(consumed, edit.begin); + printer..add(betweenEdits, location: _loc(consumed), isOriginal: true) + ..add(edit.replace, location: _loc(edit.begin)); + consumed = edit.end; + } + + // Add any text from the end of the original string that was not replaced. + printer.add(original.substring(consumed), + location: _loc(consumed), isOriginal: true); + return printer; + } +} + +class _TextEdit implements Comparable<_TextEdit> { + final int begin; + final int end; + + /// The replacement used by the edit, can be a string or a [NestedPrinter]. + final replace; + + _TextEdit(this.begin, this.end, this.replace); + + int get length => end - begin; + + String toString() => '(Edit @ $begin,$end: "$replace")'; + + int compareTo(_TextEdit other) { + int diff = begin - other.begin; + if (diff != 0) return diff; + return end - other.end; + } +} + +/// Returns all whitespace characters at the start of [charOffset]'s line. +String guessIndent(String code, int charOffset) { + // Find the beginning of the line + int lineStart = 0; + for (int i = charOffset - 1; i >= 0; i--) { + var c = code.codeUnitAt(i); + if (c == _LF || c == _CR) { + lineStart = i + 1; + break; + } + } + + // Grab all the whitespace + int whitespaceEnd = code.length; + for (int i = lineStart; i < code.length; i++) { + var c = code.codeUnitAt(i); + if (c != _SPACE && c != _TAB) { + whitespaceEnd = i; + break; + } + } + + return code.substring(lineStart, whitespaceEnd); +} + +const int _CR = 13; +const int _LF = 10; +const int _TAB = 9; +const int _SPACE = 32; diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 8fc48c996..2d4a4ccc4 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -39,4 +39,5 @@ library source_maps; export "builder.dart"; export "parser.dart"; export "printer.dart"; +export "refactor.dart"; export "span.dart"; diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index d038ad51b..06bed5768 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -79,4 +79,44 @@ main() { expect(printer2.text, out); expect(printer2.map, printer.map); }); + + group('nested printer', () { + test('simple use', () { + var printer = new NestedPrinter(); + printer..add('var ') + ..add('x = 3;\n', location: inputVar1) + ..add('f(', location: inputFunction) + ..add('y) => ', location: inputVar2) + ..add('x + y;\n', location: inputExpr) + ..build('output.dart'); + expect(printer.text, OUTPUT); + expect(printer.map, json.stringify(EXPECTED_MAP)); + }); + + test('nested use', () { + var printer = new NestedPrinter(); + printer..add('var ') + ..add(new NestedPrinter()..add('x = 3;\n', location: inputVar1)) + ..add('f(', location: inputFunction) + ..add(new NestedPrinter()..add('y) => ', location: inputVar2)) + ..add('x + y;\n', location: inputExpr) + ..build('output.dart'); + expect(printer.text, OUTPUT); + expect(printer.map, json.stringify(EXPECTED_MAP)); + }); + + test('add indentation', () { + var out = INPUT.replaceAll('long', '_s'); + var lines = INPUT.trim().split('\n'); + expect(lines.length, 7); + var printer = new NestedPrinter(); + for (int i = 0; i < lines.length; i++) { + if (i == 5) printer.indent++; + printer.addLine(lines[i].replaceAll('long', '_s').trim()); + if (i == 5) printer.indent--; + } + printer.build('output.dart'); + expect(printer.text, out); + }); + }); } diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart new file mode 100644 index 000000000..c153d9043 --- /dev/null +++ b/pkgs/source_maps/test/refactor_test.dart @@ -0,0 +1,96 @@ +// Copyright (c) 2013, 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. + +library polymer.test.refactor_test; + +import 'package:unittest/unittest.dart'; +import 'package:source_maps/refactor.dart'; +import 'package:source_maps/span.dart'; +import 'package:source_maps/parser.dart' show parse, Mapping; + +main() { + group('conflict detection', () { + var original = "0123456789abcdefghij"; + var file = new SourceFile.text('', original); + + test('no conflict, in order', () { + var txn = new TextEditTransaction(original, file); + txn.edit(2, 4, '.'); + txn.edit(5, 5, '|'); + txn.edit(6, 6, '-'); + txn.edit(6, 7, '_'); + expect((txn.commit()..build('')).text, "01.4|5-_789abcdefghij"); + }); + + test('no conflict, out of order', () { + var txn = new TextEditTransaction(original, file); + txn.edit(2, 4, '.'); + txn.edit(5, 5, '|'); + + // Regresion test for issue #404: there is no conflict/overlap for edits + // that don't remove any of the original code. + txn.edit(6, 7, '_'); + txn.edit(6, 6, '-'); + expect((txn.commit()..build('')).text, "01.4|5-_789abcdefghij"); + + }); + + test('conflict', () { + var txn = new TextEditTransaction(original, file); + txn.edit(2, 4, '.'); + txn.edit(3, 3, '-'); + expect(() => txn.commit(), throwsA(predicate( + (e) => e.toString().contains('overlapping edits')))); + }); + }); + + test('generated source maps', () { + var original = + "0123456789\n0*23456789\n01*3456789\nabcdefghij\nabcd*fghij\n"; + var file = new SourceFile.text('', original); + var txn = new TextEditTransaction(original, file); + txn.edit(27, 29, '__\n '); + txn.edit(34, 35, '___'); + var printer = (txn.commit()..build('')); + var output = printer.text; + var map = parse(printer.map); + expect(output, + "0123456789\n0*23456789\n01*34__\n 789\na___cdefghij\nabcd*fghij\n"); + + // Line 1 and 2 are unmodified: mapping any column returns the beginning + // of the corresponding line: + expect(_span(1, 1, map, file), ":1:1: \n0123456789"); + expect(_span(1, 5, map, file), ":1:1: \n0123456789"); + expect(_span(2, 1, map, file), ":2:1: \n0*23456789"); + expect(_span(2, 8, map, file), ":2:1: \n0*23456789"); + + // Line 3 is modified part way: mappings before the edits have the right + // mapping, after the edits the mapping is null. + expect(_span(3, 1, map, file), ":3:1: \n01*3456789"); + expect(_span(3, 5, map, file), ":3:1: \n01*3456789"); + + // Start of edits map to beginning of the edit secion: + expect(_span(3, 6, map, file), ":3:6: \n01*3456789"); + expect(_span(3, 7, map, file), ":3:6: \n01*3456789"); + + // Lines added have no mapping (they should inherit the last mapping), + // but the end of the edit region continues were we left off: + expect(_span(4, 1, map, file), isNull); + expect(_span(4, 5, map, file), ":3:8: \n01*3456789"); + + // Subsequent lines are still mapped correctly: + expect(_span(5, 1, map, file), ":4:1: \nabcdefghij"); // a (in a___cd...) + expect(_span(5, 2, map, file), ":4:2: \nabcdefghij"); // _ (in a___cd...) + expect(_span(5, 3, map, file), ":4:2: \nabcdefghij"); // _ (in a___cd...) + expect(_span(5, 4, map, file), ":4:2: \nabcdefghij"); // _ (in a___cd...) + expect(_span(5, 5, map, file), ":4:3: \nabcdefghij"); // c (in a___cd...) + expect(_span(6, 1, map, file), ":5:1: \nabcd*fghij"); + expect(_span(6, 8, map, file), ":5:1: \nabcd*fghij"); + }); +} + +String _span(int line, int column, Mapping map, SourceFile file) { + var span = map.spanFor(line - 1, column - 1, files: {'': file}); + return span == null ? null : span.getLocationMessage('').trim(); +} diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart index 9a197855f..876cff774 100755 --- a/pkgs/source_maps/test/run.dart +++ b/pkgs/source_maps/test/run.dart @@ -13,6 +13,7 @@ import 'builder_test.dart' as builder_test; import 'end2end_test.dart' as end2end_test; import 'parser_test.dart' as parser_test; import 'printer_test.dart' as printer_test; +import 'refactor_test.dart' as refactor_test; import 'span_test.dart' as span_test; import 'utils_test.dart' as utils_test; import 'vlq_test.dart' as vlq_test; @@ -32,6 +33,7 @@ main() { addGroup('end2end_test.dart', end2end_test.main); addGroup('parser_test.dart', parser_test.main); addGroup('printer_test.dart', printer_test.main); + addGroup('refactor_test.dart', refactor_test.main); addGroup('span_test.dart', span_test.main); addGroup('utils_test.dart', utils_test.main); addGroup('vlq_test.dart', vlq_test.main); From c9315076acda696daa795c4a9afcb90b48de92c6 Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Fri, 9 Aug 2013 22:44:51 +0000 Subject: [PATCH 010/657] Fix source maps test (failed in checked mode). R=jmesserly@google.com Review URL: https://codereview.chromium.org//22762003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@25987 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/test/printer_test.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index 06bed5768..eaeae2a12 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -84,10 +84,10 @@ main() { test('simple use', () { var printer = new NestedPrinter(); printer..add('var ') - ..add('x = 3;\n', location: inputVar1) - ..add('f(', location: inputFunction) - ..add('y) => ', location: inputVar2) - ..add('x + y;\n', location: inputExpr) + ..add('x = 3;\n', span: inputVar1) + ..add('f(', span: inputFunction) + ..add('y) => ', span: inputVar2) + ..add('x + y;\n', span: inputExpr) ..build('output.dart'); expect(printer.text, OUTPUT); expect(printer.map, json.stringify(EXPECTED_MAP)); @@ -96,10 +96,10 @@ main() { test('nested use', () { var printer = new NestedPrinter(); printer..add('var ') - ..add(new NestedPrinter()..add('x = 3;\n', location: inputVar1)) - ..add('f(', location: inputFunction) - ..add(new NestedPrinter()..add('y) => ', location: inputVar2)) - ..add('x + y;\n', location: inputExpr) + ..add(new NestedPrinter()..add('x = 3;\n', span: inputVar1)) + ..add('f(', span: inputFunction) + ..add(new NestedPrinter()..add('y) => ', span: inputVar2)) + ..add('x + y;\n', span: inputExpr) ..build('output.dart'); expect(printer.text, OUTPUT); expect(printer.map, json.stringify(EXPECTED_MAP)); From af8c728dadb4c3d6de8f58dc38fb1eeae48b7f30 Mon Sep 17 00:00:00 2001 From: "floitsch@google.com" Date: Tue, 27 Aug 2013 13:18:34 +0000 Subject: [PATCH 011/657] Some more removals of dart:utf. R=jmesserly@google.com, lrn@google.com, nweiz@google.com Review URL: https://codereview.chromium.org//22909059 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@26712 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/printer.dart | 3 +-- pkgs/source_maps/lib/span.dart | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 95539d2b7..0898017c4 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -5,7 +5,6 @@ /// Contains a code printer that generates code by recording the source maps. library source_maps.printer; -import 'dart:utf' show stringToCodepoints; import 'builder.dart'; import 'span.dart'; @@ -38,7 +37,7 @@ class Printer { /// line in the target file (printed here) corresponds to a new line in the /// source file. void add(String str, {projectMarks: false}) { - var chars = stringToCodepoints(str); + var chars = str.runes.toList(); var length = chars.length; for (int i = 0; i < length; i++) { var c = chars[i]; diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index e5057fceb..17ccd272d 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -5,7 +5,6 @@ /// Dart classes representing the souce spans and source files. library source_maps.span; -import 'dart:utf' show stringToCodepoints; import 'dart:math' show min, max; import 'src/utils.dart'; @@ -201,7 +200,7 @@ class SourceFile { SourceFile.text(this.url, String text) : _lineStarts = [0], - _decodedChars = stringToCodepoints(text) { + _decodedChars = text.runes.toList() { for (int i = 0; i < _decodedChars.length; i++) { var c = _decodedChars[i]; if (c == _CR) { From 35a756b9766e27423cc416239c61c6873db2d369 Mon Sep 17 00:00:00 2001 From: "floitsch@google.com" Date: Wed, 28 Aug 2013 14:05:11 +0000 Subject: [PATCH 012/657] Remove usage of dart:json. R=jmesserly@google.com, lrn@google.com, nweiz@google.com, rnystrom@google.com Review URL: https://codereview.chromium.org//23596007 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@26789 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/builder.dart | 4 ++-- pkgs/source_maps/lib/parser.dart | 4 ++-- pkgs/source_maps/test/builder_test.dart | 4 ++-- pkgs/source_maps/test/parser_test.dart | 4 ++-- pkgs/source_maps/test/printer_test.dart | 8 ++++---- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index be00c9e81..12587cd84 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -7,8 +7,8 @@ library source_maps.builder; // TODO(sigmund): add a builder for multi-section mappings. -import 'dart:json' as json; import 'dart:collection'; +import 'dart:convert'; import 'span.dart'; import 'src/vlq.dart'; @@ -108,7 +108,7 @@ class SourceMapBuilder { } /// Encodes all mappings added to this builder as a json string. - String toJson(String fileUrl) => json.stringify(build(fileUrl)); + String toJson(String fileUrl) => JSON.encode(build(fileUrl)); /// Get the index of [value] in [map], or create one if it doesn't exist. int _indexOf(Map map, String value) { diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index e2932634f..6b8bf3780 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -5,7 +5,7 @@ /// Contains the top-level function to parse source maps version 3. library source_maps.parser; -import 'dart:json' as json; +import 'dart:convert'; import 'span.dart'; import 'src/utils.dart'; @@ -15,7 +15,7 @@ import 'src/vlq.dart'; // TODO(sigmund): evaluate whether other maps should have the json parsed, or // the string represenation. Mapping parse(String jsonMap, {Map otherMaps}) => - parseJson(json.parse(jsonMap), otherMaps: otherMaps); + parseJson(JSON.decode(jsonMap), otherMaps: otherMaps); /// Parses a source map directly from a json map object. Mapping parseJson(Map map, {Map otherMaps}) { diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index 7bf2ee424..8842c62cb 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -4,7 +4,7 @@ library test.source_maps_test; -import 'dart:json' as json; +import 'dart:convert'; import 'package:unittest/unittest.dart'; import 'package:source_maps/source_maps.dart'; import 'common.dart'; @@ -27,6 +27,6 @@ main() { ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') ..addLocation(inputExpr.start, outputExpr.start, null)) .toJson(output.url); - expect(str, json.stringify(EXPECTED_MAP)); + expect(str, JSON.encode(EXPECTED_MAP)); }); } diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 1c32cbd34..c99acb2f1 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -4,7 +4,7 @@ library test.parser_test; -import 'dart:json' as json; +import 'dart:convert'; import 'package:unittest/unittest.dart'; import 'package:source_maps/source_maps.dart'; import 'common.dart'; @@ -19,7 +19,7 @@ main() { }); test('parse + json', () { - var mapping = parse(json.stringify(EXPECTED_MAP)); + var mapping = parse(JSON.encode(EXPECTED_MAP)); check(outputVar1, mapping, inputVar1, false); check(outputVar2, mapping, inputVar2, false); check(outputFunction, mapping, inputFunction, false); diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index eaeae2a12..fe27f76c0 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -4,7 +4,7 @@ library test.printer_test; -import 'dart:json' as json; +import 'dart:convert'; import 'package:unittest/unittest.dart'; import 'package:source_maps/printer.dart'; import 'package:source_maps/span.dart'; @@ -23,7 +23,7 @@ main() { ..mark(inputExpr) ..add('x + y;\n'); expect(printer.text, OUTPUT); - expect(printer.map, json.stringify(EXPECTED_MAP)); + expect(printer.map, JSON.encode(EXPECTED_MAP)); }); test('printer projecting marks', () { @@ -90,7 +90,7 @@ main() { ..add('x + y;\n', span: inputExpr) ..build('output.dart'); expect(printer.text, OUTPUT); - expect(printer.map, json.stringify(EXPECTED_MAP)); + expect(printer.map, JSON.encode(EXPECTED_MAP)); }); test('nested use', () { @@ -102,7 +102,7 @@ main() { ..add('x + y;\n', span: inputExpr) ..build('output.dart'); expect(printer.text, OUTPUT); - expect(printer.map, json.stringify(EXPECTED_MAP)); + expect(printer.map, JSON.encode(EXPECTED_MAP)); }); test('add indentation', () { From d3344948ebe1f7a03f19d172288309e2108505f5 Mon Sep 17 00:00:00 2001 From: "whesse@google.com" Date: Wed, 30 Oct 2013 15:17:01 +0000 Subject: [PATCH 013/657] Remove uses of Options from pkg, samples, tests, and third_party directories. BUG= R=sgjesse@google.com Review URL: https://codereview.chromium.org//52573002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@29552 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/test/run.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart index 876cff774..21d20377e 100755 --- a/pkgs/source_maps/test/run.dart +++ b/pkgs/source_maps/test/run.dart @@ -18,9 +18,8 @@ import 'span_test.dart' as span_test; import 'utils_test.dart' as utils_test; import 'vlq_test.dart' as vlq_test; -main() { - var args = new Options().arguments; - var pattern = new RegExp(args.length > 0 ? args[0] : '.'); +main(List arguments) { + var pattern = new RegExp(arguments.length > 0 ? arguments[0] : '.'); useCompactVMConfiguration(); void addGroup(testFile, testMain) { From 5edd73de8ad5f4be4d55c432cd4fd6ccdc145501 Mon Sep 17 00:00:00 2001 From: "jmesserly@google.com" Date: Wed, 6 Nov 2013 03:27:58 +0000 Subject: [PATCH 014/657] add versions and constraints for packages and samples - all packages at 0.9.0, except "analyzer" which had a version already - dependencies at ">=0.9.0 <0.10.0" except analyzer is ">=0.10.0 <0.11.0" - sdk constraint ">=1.0.0 <2.0.0" R=sigmund@google.com Review URL: https://codereview.chromium.org//59763006 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@29957 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/pubspec.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 4ae180291..a0b0dc498 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,6 +1,9 @@ name: source_maps +version: 0.9.0 author: "Dart Team " homepage: http://www.dartlang.org description: Library to programmatically manipulate source map files. dev_dependencies: - unittest: any + unittest: ">=0.9.0 <0.10.0" +environment: + sdk: ">=1.0.0 <2.0.0" From 20c0ed16de8ca5dd554c71cf2c628357b8674c74 Mon Sep 17 00:00:00 2001 From: "ajohnsen@google.com" Date: Wed, 6 Nov 2013 09:09:18 +0000 Subject: [PATCH 015/657] Revert "add versions and constraints for packages and samples" This is currently blocking us from testing samples. BUG= R=kasperl@google.com Review URL: https://codereview.chromium.org//59513007 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@29960 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/pubspec.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index a0b0dc498..4ae180291 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,9 +1,6 @@ name: source_maps -version: 0.9.0 author: "Dart Team " homepage: http://www.dartlang.org description: Library to programmatically manipulate source map files. dev_dependencies: - unittest: ">=0.9.0 <0.10.0" -environment: - sdk: ">=1.0.0 <2.0.0" + unittest: any From 7c4320ea7995e5b2fd48665b5ef2406fda089def Mon Sep 17 00:00:00 2001 From: "dgrove@google.com" Date: Wed, 6 Nov 2013 18:28:22 +0000 Subject: [PATCH 016/657] Re-land r29957 (add versions and constraints for packages and samples), with SDK constraints bumped from 1.0.0 to 0.8.10+6 . R=ricow@google.com, sigmund@google.com Review URL: https://codereview.chromium.org//62473002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@29986 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/pubspec.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 4ae180291..83c59a336 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,6 +1,9 @@ name: source_maps +version: 0.9.0 author: "Dart Team " homepage: http://www.dartlang.org description: Library to programmatically manipulate source map files. dev_dependencies: - unittest: any + unittest: ">=0.9.0 <0.10.0" +environment: + sdk: ">=0.8.10+6 <2.0.0" From 274cc23e5deea734dfc7878db24fcb470b93d829 Mon Sep 17 00:00:00 2001 From: "kevmoo@google.com" Date: Mon, 13 Jan 2014 18:07:45 +0000 Subject: [PATCH 017/657] pkg/unittest: added LICENSE R=rnystrom@google.com Review URL: https://codereview.chromium.org//135343002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@31750 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/LICENSE | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 pkgs/source_maps/LICENSE diff --git a/pkgs/source_maps/LICENSE b/pkgs/source_maps/LICENSE new file mode 100644 index 000000000..5c60afea3 --- /dev/null +++ b/pkgs/source_maps/LICENSE @@ -0,0 +1,26 @@ +Copyright 2014, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 2f2fc2051e866351cf8858ca91ac1afac595de2b Mon Sep 17 00:00:00 2001 From: "zarah@google.com" Date: Wed, 23 Apr 2014 07:57:14 +0000 Subject: [PATCH 018/657] Support unmapped areas in source maps. R=johnniwinther@google.com Review URL: https://codereview.chromium.org//237123003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@35307 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/builder.dart | 7 +-- pkgs/source_maps/lib/parser.dart | 12 ++--- pkgs/source_maps/pubspec.yaml | 12 ++--- pkgs/source_maps/test/parser_test.dart | 66 ++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 12587cd84..ef22e3123 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -75,15 +75,10 @@ class SourceMapBuilder { column = _append(buff, column, entry.target.column); // Encoding can be just the column offset if there is no source - // information, or if two consecutive mappings share exactly the same - // source information. + // information. var source = entry.source; if (source == null) continue; var newUrlId = _indexOf(_urls, source.sourceUrl); - if (newUrlId == srcUrlId && source.line == srcLine - && source.column == srcColumn && entry.identifierName == null) { - continue; - } srcUrlId = _append(buff, srcUrlId, newUrlId); srcLine = _append(buff, srcLine, source.line); diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 6b8bf3780..c92a8bba0 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -185,7 +185,7 @@ class SingleMapping extends Mapping { if (tokenizer.nextKind.isNewSegment) throw _segmentError(0, line); column += tokenizer._consumeValue(); if (!tokenizer.nextKind.isValue) { - entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn)); + entries.add(new TargetEntry(column)); } else { srcUrlId += tokenizer._consumeValue(); if (srcUrlId >= urls.length) { @@ -204,8 +204,8 @@ class SingleMapping extends Mapping { throw new StateError( 'Invalid name id: $targetUrl, $line, $srcNameId'); } - entries.add( - new TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId)); + entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn, + srcNameId)); } } if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment(); @@ -242,7 +242,7 @@ class SingleMapping extends Mapping { Span spanFor(int line, int column, {Map files}) { var entry = _findColumn(line, column, _findLine(line)); - if (entry == null) return null; + if (entry == null || entry.sourceUrlId == null) return null; var url = urls[entry.sourceUrlId]; if (files != null && files[url] != null) { var file = files[url]; @@ -322,8 +322,8 @@ class TargetEntry { final int sourceColumn; final int sourceNameId; - TargetEntry(this.column, this.sourceUrlId, this.sourceLine, - this.sourceColumn, [this.sourceNameId]); + TargetEntry(this.column, [this.sourceUrlId, this.sourceLine, + this.sourceColumn, this.sourceNameId]); String toString() => '$runtimeType: ' '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 83c59a336..71cbfb54f 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,9 +1,9 @@ name: source_maps -version: 0.9.0 -author: "Dart Team " -homepage: http://www.dartlang.org +version: 0.9.1-dev +author: Dart Team description: Library to programmatically manipulate source map files. -dev_dependencies: - unittest: ">=0.9.0 <0.10.0" +homepage: http://www.dartlang.org environment: - sdk: ">=0.8.10+6 <2.0.0" + sdk: '>=0.8.10+6 <2.0.0' +dev_dependencies: + unittest: '>=0.9.0 <0.10.0' diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index c99acb2f1..afdd7fb2c 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -9,6 +9,33 @@ import 'package:unittest/unittest.dart'; import 'package:source_maps/source_maps.dart'; import 'common.dart'; +const Map MAP_WITH_NO_SOURCE_LOCATION = const { + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const [], + 'mappings': 'A', + 'file': 'output.dart' +}; + +const Map MAP_WITH_SOURCE_LOCATION = const { + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const [], + 'mappings': 'AAAA', + 'file': 'output.dart' +}; + +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME = const { + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const ['var'], + 'mappings': 'AAAAA', + 'file': 'output.dart' +}; + main() { test('parse', () { var mapping = parseJson(EXPECTED_MAP); @@ -33,4 +60,43 @@ main() { check(outputFunction, mapping, inputFunction, true); check(outputExpr, mapping, inputExpr, true); }); + + test('parse with no source location', () { + SingleMapping map = parse(JSON.encode(MAP_WITH_NO_SOURCE_LOCATION)); + expect(map.lines.length, 1); + expect(map.lines.first.entries.length, 1); + TargetEntry entry = map.lines.first.entries.first; + + expect(entry.column, 0); + expect(entry.sourceUrlId, null); + expect(entry.sourceColumn, null); + expect(entry.sourceLine, null); + expect(entry.sourceNameId, null); + }); + + test('parse with source location and no name', () { + SingleMapping map = parse(JSON.encode(MAP_WITH_SOURCE_LOCATION)); + expect(map.lines.length, 1); + expect(map.lines.first.entries.length, 1); + TargetEntry entry = map.lines.first.entries.first; + + expect(entry.column, 0); + expect(entry.sourceUrlId, 0); + expect(entry.sourceColumn, 0); + expect(entry.sourceLine, 0); + expect(entry.sourceNameId, null); + }); + + test('parse with source location and name', () { + SingleMapping map = parse(JSON.encode(MAP_WITH_SOURCE_LOCATION_AND_NAME)); + expect(map.lines.length, 1); + expect(map.lines.first.entries.length, 1); + TargetEntry entry = map.lines.first.entries.first; + + expect(entry.sourceUrlId, 0); + expect(entry.sourceUrlId, 0); + expect(entry.sourceColumn, 0); + expect(entry.sourceLine, 0); + expect(entry.sourceNameId, 0); + }); } From 4a16d390427369bf9bf531d4d06b6f9277137026 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Sat, 24 May 2014 00:52:08 +0000 Subject: [PATCH 019/657] Make source map location information more readable. This changes "file:1:2" to "line 1, column 2 of file" and ":1:2" to "line 1, column 2" in [SourceFile.getLocationMessage]. The more machine-readable colon-separated format doesn't make sense for a message intended for humans. Since [Location.formatString] seems more likely to be consumed by machines, its format was left as-is. This also prepares version 0.9.1 for release. R=sigmund@google.com Review URL: https://codereview.chromium.org//300583002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@36603 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 5 +++++ pkgs/source_maps/lib/span.dart | 6 ++++-- pkgs/source_maps/pubspec.yaml | 4 +++- pkgs/source_maps/test/span_test.dart | 24 ++++++++++++------------ 4 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 pkgs/source_maps/CHANGELOG.md diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md new file mode 100644 index 000000000..e2784587e --- /dev/null +++ b/pkgs/source_maps/CHANGELOG.md @@ -0,0 +1,5 @@ +## 0.9.1 + +* Support unmapped areas in source maps. + +* Increase the readability of location messages. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 17ccd272d..f47e08eb6 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -7,6 +7,8 @@ library source_maps.span; import 'dart:math' show min, max; +import 'package:path/path.dart' as p; + import 'src/utils.dart'; /// A simple class that describe a segment of source text. @@ -252,8 +254,8 @@ class SourceFile { var line = getLine(start); var column = getColumn(line, start); - var src = url == null ? '' : url; - var msg = '$src:${line + 1}:${column + 1}: $message'; + var source = url == null ? '' : ' of ${p.prettyUri(url)}'; + var msg = 'line ${line + 1}, column ${column + 1}$source: $message'; if (_decodedChars == null) { // We don't have any text to include, so exit. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 71cbfb54f..3c946e006 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,8 +1,10 @@ name: source_maps -version: 0.9.1-dev +version: 0.9.1 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org +dependencies: + path: '>=1.2.0 <2.0.0' environment: sdk: '>=0.8.10+6 <2.0.0' dev_dependencies: diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart index da3e063ef..190b7a66b 100644 --- a/pkgs/source_maps/test/span_test.dart +++ b/pkgs/source_maps/test/span_test.dart @@ -72,7 +72,7 @@ main() { group('location message', () { test('first line', () { expect(file.getLocationMessage('the message', 1, 3), - 'file:1:2: the message\n' + 'line 1, column 2 of file: the message\n' '+23456789_\n' ' ^^'); }); @@ -81,7 +81,7 @@ main() { // fifth line (including 4 new lines), columns 2 .. 11 var line = 10 + 80 + 31 + 27 + 4; expect(file.getLocationMessage('the message', line + 2, line + 11), - 'file:5:3: the message\n' + 'line 5, column 3 of file: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); }); @@ -90,7 +90,7 @@ main() { var line = 10 + 80 + 31 + 27 + 4; expect(new SourceFile.text(null, TEST_FILE).getLocationMessage( 'the message', line + 2, line + 11), - ':5:3: the message\n' + 'line 5, column 3: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); }); @@ -100,7 +100,7 @@ main() { int index = TEST_FILE.lastIndexOf('\n'); var start = TEST_FILE.lastIndexOf('\n', index - 1) - 3; expect(file.getLocationMessage('the message', start, start + 2), - 'file:11:41: the message\n' + 'line 11, column 41 of file: the message\n' '123456789_+23456789_123456789_123456789_123\n' ' ^^'); }); @@ -108,7 +108,7 @@ main() { test('last line', () { var start = TEST_FILE.lastIndexOf('\n') - 2; expect(file.getLocationMessage('the message', start, start + 1), - 'file:12:28: the message\n' + 'line 12, column 28 of file: the message\n' '123456789_1+3456789_123456789\n' ' ^'); }); @@ -120,7 +120,7 @@ main() { test('penultimate line', () { var start = text.lastIndexOf('\n') - 3; expect(file2.getLocationMessage('the message', start, start + 2), - 'file:11:41: the message\n' + 'line 11, column 41 of file: the message\n' '123456789_+23456789_123456789_123456789_123\n' ' ^^'); }); @@ -128,7 +128,7 @@ main() { test('last line', () { var start = text.length - 2; expect(file2.getLocationMessage('the message', start, start + 1), - 'file:12:28: the message\n' + 'line 12, column 28 of file: the message\n' '123456789_1+3456789_123456789\n' ' ^'); }); @@ -139,7 +139,7 @@ main() { int start = text.indexOf(' ') + 1; var file2 = new SourceFile.text('file', text); expect(file2.getLocationMessage('the message', start, start + 2), - 'file:1:${start + 1}: the message\n' + 'line 1, column ${start + 1} of file: the message\n' 'this is a single line\n' ' ^^'); }); @@ -178,7 +178,7 @@ main() { var line = 10 + 80 + 31 + 27 + 4; expect(span(line + 2, line + 11).getLocationMessage('the message'), - 'file:5:3: the message\n' + 'line 5, column 3 of file: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); @@ -226,7 +226,7 @@ main() { test('range check for large offsets', () { var start = TEST_FILE.length; expect(file.getLocationMessage('the message', start, start + 9), - 'file:13:1: the message\n'); + 'line 13, column 1 of file: the message\n'); }); group('file segment', () { @@ -296,7 +296,7 @@ main() { test('past segment, past its line', () { var start = TEST_FILE.length - 2; expect(file.getLocationMessage('the message', start, start + 1), - 'file:12:29: the message\n' + 'line 12, column 29 of file: the message\n' '123456789_1+3456789_123456789\n' ' ^'); @@ -304,7 +304,7 @@ main() { // about the 10 lines it has (and nothing about the possible extra lines // afterwards) expect(segment.getLocationMessage('the message', start, start + 1), - 'file:11:1: the message\n'); + 'line 11, column 1 of file: the message\n'); }); }); }); From 5c2376945aea24d3cbe36c0bdec2e7012ba02037 Mon Sep 17 00:00:00 2001 From: "ricow@google.com" Date: Mon, 26 May 2014 05:52:05 +0000 Subject: [PATCH 020/657] Revert revision 36603 This is making 60% of the bots red Review URL: https://codereview.chromium.org//303493002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@36615 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 5 ----- pkgs/source_maps/lib/span.dart | 6 ++---- pkgs/source_maps/pubspec.yaml | 4 +--- pkgs/source_maps/test/span_test.dart | 24 ++++++++++++------------ 4 files changed, 15 insertions(+), 24 deletions(-) delete mode 100644 pkgs/source_maps/CHANGELOG.md diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md deleted file mode 100644 index e2784587e..000000000 --- a/pkgs/source_maps/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -## 0.9.1 - -* Support unmapped areas in source maps. - -* Increase the readability of location messages. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index f47e08eb6..17ccd272d 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -7,8 +7,6 @@ library source_maps.span; import 'dart:math' show min, max; -import 'package:path/path.dart' as p; - import 'src/utils.dart'; /// A simple class that describe a segment of source text. @@ -254,8 +252,8 @@ class SourceFile { var line = getLine(start); var column = getColumn(line, start); - var source = url == null ? '' : ' of ${p.prettyUri(url)}'; - var msg = 'line ${line + 1}, column ${column + 1}$source: $message'; + var src = url == null ? '' : url; + var msg = '$src:${line + 1}:${column + 1}: $message'; if (_decodedChars == null) { // We don't have any text to include, so exit. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 3c946e006..71cbfb54f 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,10 +1,8 @@ name: source_maps -version: 0.9.1 +version: 0.9.1-dev author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org -dependencies: - path: '>=1.2.0 <2.0.0' environment: sdk: '>=0.8.10+6 <2.0.0' dev_dependencies: diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart index 190b7a66b..da3e063ef 100644 --- a/pkgs/source_maps/test/span_test.dart +++ b/pkgs/source_maps/test/span_test.dart @@ -72,7 +72,7 @@ main() { group('location message', () { test('first line', () { expect(file.getLocationMessage('the message', 1, 3), - 'line 1, column 2 of file: the message\n' + 'file:1:2: the message\n' '+23456789_\n' ' ^^'); }); @@ -81,7 +81,7 @@ main() { // fifth line (including 4 new lines), columns 2 .. 11 var line = 10 + 80 + 31 + 27 + 4; expect(file.getLocationMessage('the message', line + 2, line + 11), - 'line 5, column 3 of file: the message\n' + 'file:5:3: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); }); @@ -90,7 +90,7 @@ main() { var line = 10 + 80 + 31 + 27 + 4; expect(new SourceFile.text(null, TEST_FILE).getLocationMessage( 'the message', line + 2, line + 11), - 'line 5, column 3: the message\n' + ':5:3: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); }); @@ -100,7 +100,7 @@ main() { int index = TEST_FILE.lastIndexOf('\n'); var start = TEST_FILE.lastIndexOf('\n', index - 1) - 3; expect(file.getLocationMessage('the message', start, start + 2), - 'line 11, column 41 of file: the message\n' + 'file:11:41: the message\n' '123456789_+23456789_123456789_123456789_123\n' ' ^^'); }); @@ -108,7 +108,7 @@ main() { test('last line', () { var start = TEST_FILE.lastIndexOf('\n') - 2; expect(file.getLocationMessage('the message', start, start + 1), - 'line 12, column 28 of file: the message\n' + 'file:12:28: the message\n' '123456789_1+3456789_123456789\n' ' ^'); }); @@ -120,7 +120,7 @@ main() { test('penultimate line', () { var start = text.lastIndexOf('\n') - 3; expect(file2.getLocationMessage('the message', start, start + 2), - 'line 11, column 41 of file: the message\n' + 'file:11:41: the message\n' '123456789_+23456789_123456789_123456789_123\n' ' ^^'); }); @@ -128,7 +128,7 @@ main() { test('last line', () { var start = text.length - 2; expect(file2.getLocationMessage('the message', start, start + 1), - 'line 12, column 28 of file: the message\n' + 'file:12:28: the message\n' '123456789_1+3456789_123456789\n' ' ^'); }); @@ -139,7 +139,7 @@ main() { int start = text.indexOf(' ') + 1; var file2 = new SourceFile.text('file', text); expect(file2.getLocationMessage('the message', start, start + 2), - 'line 1, column ${start + 1} of file: the message\n' + 'file:1:${start + 1}: the message\n' 'this is a single line\n' ' ^^'); }); @@ -178,7 +178,7 @@ main() { var line = 10 + 80 + 31 + 27 + 4; expect(span(line + 2, line + 11).getLocationMessage('the message'), - 'line 5, column 3 of file: the message\n' + 'file:5:3: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); @@ -226,7 +226,7 @@ main() { test('range check for large offsets', () { var start = TEST_FILE.length; expect(file.getLocationMessage('the message', start, start + 9), - 'line 13, column 1 of file: the message\n'); + 'file:13:1: the message\n'); }); group('file segment', () { @@ -296,7 +296,7 @@ main() { test('past segment, past its line', () { var start = TEST_FILE.length - 2; expect(file.getLocationMessage('the message', start, start + 1), - 'line 12, column 29 of file: the message\n' + 'file:12:29: the message\n' '123456789_1+3456789_123456789\n' ' ^'); @@ -304,7 +304,7 @@ main() { // about the 10 lines it has (and nothing about the possible extra lines // afterwards) expect(segment.getLocationMessage('the message', start, start + 1), - 'line 11, column 1 of file: the message\n'); + 'file:11:1: the message\n'); }); }); }); From 653f02456ffefc530c4ebea7a17dd6ab5e0cb1de Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Tue, 27 May 2014 23:01:24 +0000 Subject: [PATCH 021/657] Make source map location information more readable. This changes "file:1:2" to "line 1, column 2 of file" and ":1:2" to "line 1, column 2" in [SourceFile.getLocationMessage]. The more machine-readable colon-separated format doesn't make sense for a message intended for humans. Since [Location.formatString] seems more likely to be consumed by machines, its format was left as-is. This also prepares version 0.9.1 for release. This was previously submitted as r36603. That caused buildbot errors and was rolled back by r36615. This CL fixes the test errors in r36603. R=sigmund@google.com Review URL: https://codereview.chromium.org//304603003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@36717 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 5 +++++ pkgs/source_maps/lib/span.dart | 6 ++++-- pkgs/source_maps/pubspec.yaml | 4 +++- pkgs/source_maps/test/span_test.dart | 24 ++++++++++++------------ 4 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 pkgs/source_maps/CHANGELOG.md diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md new file mode 100644 index 000000000..e2784587e --- /dev/null +++ b/pkgs/source_maps/CHANGELOG.md @@ -0,0 +1,5 @@ +## 0.9.1 + +* Support unmapped areas in source maps. + +* Increase the readability of location messages. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 17ccd272d..f47e08eb6 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -7,6 +7,8 @@ library source_maps.span; import 'dart:math' show min, max; +import 'package:path/path.dart' as p; + import 'src/utils.dart'; /// A simple class that describe a segment of source text. @@ -252,8 +254,8 @@ class SourceFile { var line = getLine(start); var column = getColumn(line, start); - var src = url == null ? '' : url; - var msg = '$src:${line + 1}:${column + 1}: $message'; + var source = url == null ? '' : ' of ${p.prettyUri(url)}'; + var msg = 'line ${line + 1}, column ${column + 1}$source: $message'; if (_decodedChars == null) { // We don't have any text to include, so exit. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 71cbfb54f..3c946e006 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,8 +1,10 @@ name: source_maps -version: 0.9.1-dev +version: 0.9.1 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org +dependencies: + path: '>=1.2.0 <2.0.0' environment: sdk: '>=0.8.10+6 <2.0.0' dev_dependencies: diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart index da3e063ef..190b7a66b 100644 --- a/pkgs/source_maps/test/span_test.dart +++ b/pkgs/source_maps/test/span_test.dart @@ -72,7 +72,7 @@ main() { group('location message', () { test('first line', () { expect(file.getLocationMessage('the message', 1, 3), - 'file:1:2: the message\n' + 'line 1, column 2 of file: the message\n' '+23456789_\n' ' ^^'); }); @@ -81,7 +81,7 @@ main() { // fifth line (including 4 new lines), columns 2 .. 11 var line = 10 + 80 + 31 + 27 + 4; expect(file.getLocationMessage('the message', line + 2, line + 11), - 'file:5:3: the message\n' + 'line 5, column 3 of file: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); }); @@ -90,7 +90,7 @@ main() { var line = 10 + 80 + 31 + 27 + 4; expect(new SourceFile.text(null, TEST_FILE).getLocationMessage( 'the message', line + 2, line + 11), - ':5:3: the message\n' + 'line 5, column 3: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); }); @@ -100,7 +100,7 @@ main() { int index = TEST_FILE.lastIndexOf('\n'); var start = TEST_FILE.lastIndexOf('\n', index - 1) - 3; expect(file.getLocationMessage('the message', start, start + 2), - 'file:11:41: the message\n' + 'line 11, column 41 of file: the message\n' '123456789_+23456789_123456789_123456789_123\n' ' ^^'); }); @@ -108,7 +108,7 @@ main() { test('last line', () { var start = TEST_FILE.lastIndexOf('\n') - 2; expect(file.getLocationMessage('the message', start, start + 1), - 'file:12:28: the message\n' + 'line 12, column 28 of file: the message\n' '123456789_1+3456789_123456789\n' ' ^'); }); @@ -120,7 +120,7 @@ main() { test('penultimate line', () { var start = text.lastIndexOf('\n') - 3; expect(file2.getLocationMessage('the message', start, start + 2), - 'file:11:41: the message\n' + 'line 11, column 41 of file: the message\n' '123456789_+23456789_123456789_123456789_123\n' ' ^^'); }); @@ -128,7 +128,7 @@ main() { test('last line', () { var start = text.length - 2; expect(file2.getLocationMessage('the message', start, start + 1), - 'file:12:28: the message\n' + 'line 12, column 28 of file: the message\n' '123456789_1+3456789_123456789\n' ' ^'); }); @@ -139,7 +139,7 @@ main() { int start = text.indexOf(' ') + 1; var file2 = new SourceFile.text('file', text); expect(file2.getLocationMessage('the message', start, start + 2), - 'file:1:${start + 1}: the message\n' + 'line 1, column ${start + 1} of file: the message\n' 'this is a single line\n' ' ^^'); }); @@ -178,7 +178,7 @@ main() { var line = 10 + 80 + 31 + 27 + 4; expect(span(line + 2, line + 11).getLocationMessage('the message'), - 'file:5:3: the message\n' + 'line 5, column 3 of file: the message\n' '1234+6789_1234\n' ' ^^^^^^^^^'); @@ -226,7 +226,7 @@ main() { test('range check for large offsets', () { var start = TEST_FILE.length; expect(file.getLocationMessage('the message', start, start + 9), - 'file:13:1: the message\n'); + 'line 13, column 1 of file: the message\n'); }); group('file segment', () { @@ -296,7 +296,7 @@ main() { test('past segment, past its line', () { var start = TEST_FILE.length - 2; expect(file.getLocationMessage('the message', start, start + 1), - 'file:12:29: the message\n' + 'line 12, column 29 of file: the message\n' '123456789_1+3456789_123456789\n' ' ^'); @@ -304,7 +304,7 @@ main() { // about the 10 lines it has (and nothing about the possible extra lines // afterwards) expect(segment.getLocationMessage('the message', start, start + 1), - 'file:11:1: the message\n'); + 'line 11, column 1 of file: the message\n'); }); }); }); From eaf8323227ff98fca687de5bf3073b1593b86e2c Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 28 May 2014 00:32:00 +0000 Subject: [PATCH 022/657] Fix a couple more tests that were relying on sourcemap message format. Review URL: https://codereview.chromium.org//297203009 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@36722 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/test/refactor_test.dart | 37 ++++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index c153d9043..5d0abf1e2 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -60,33 +60,38 @@ main() { // Line 1 and 2 are unmodified: mapping any column returns the beginning // of the corresponding line: - expect(_span(1, 1, map, file), ":1:1: \n0123456789"); - expect(_span(1, 5, map, file), ":1:1: \n0123456789"); - expect(_span(2, 1, map, file), ":2:1: \n0*23456789"); - expect(_span(2, 8, map, file), ":2:1: \n0*23456789"); + expect(_span(1, 1, map, file), "line 1, column 1 of .: \n0123456789"); + expect(_span(1, 5, map, file), "line 1, column 1 of .: \n0123456789"); + expect(_span(2, 1, map, file), "line 2, column 1 of .: \n0*23456789"); + expect(_span(2, 8, map, file), "line 2, column 1 of .: \n0*23456789"); // Line 3 is modified part way: mappings before the edits have the right // mapping, after the edits the mapping is null. - expect(_span(3, 1, map, file), ":3:1: \n01*3456789"); - expect(_span(3, 5, map, file), ":3:1: \n01*3456789"); + expect(_span(3, 1, map, file), "line 3, column 1 of .: \n01*3456789"); + expect(_span(3, 5, map, file), "line 3, column 1 of .: \n01*3456789"); // Start of edits map to beginning of the edit secion: - expect(_span(3, 6, map, file), ":3:6: \n01*3456789"); - expect(_span(3, 7, map, file), ":3:6: \n01*3456789"); + expect(_span(3, 6, map, file), "line 3, column 6 of .: \n01*3456789"); + expect(_span(3, 7, map, file), "line 3, column 6 of .: \n01*3456789"); // Lines added have no mapping (they should inherit the last mapping), // but the end of the edit region continues were we left off: expect(_span(4, 1, map, file), isNull); - expect(_span(4, 5, map, file), ":3:8: \n01*3456789"); + expect(_span(4, 5, map, file), "line 3, column 8 of .: \n01*3456789"); // Subsequent lines are still mapped correctly: - expect(_span(5, 1, map, file), ":4:1: \nabcdefghij"); // a (in a___cd...) - expect(_span(5, 2, map, file), ":4:2: \nabcdefghij"); // _ (in a___cd...) - expect(_span(5, 3, map, file), ":4:2: \nabcdefghij"); // _ (in a___cd...) - expect(_span(5, 4, map, file), ":4:2: \nabcdefghij"); // _ (in a___cd...) - expect(_span(5, 5, map, file), ":4:3: \nabcdefghij"); // c (in a___cd...) - expect(_span(6, 1, map, file), ":5:1: \nabcd*fghij"); - expect(_span(6, 8, map, file), ":5:1: \nabcd*fghij"); + // a (in a___cd...) + expect(_span(5, 1, map, file), "line 4, column 1 of .: \nabcdefghij"); + // _ (in a___cd...) + expect(_span(5, 2, map, file), "line 4, column 2 of .: \nabcdefghij"); + // _ (in a___cd...) + expect(_span(5, 3, map, file), "line 4, column 2 of .: \nabcdefghij"); + // _ (in a___cd...) + expect(_span(5, 4, map, file), "line 4, column 2 of .: \nabcdefghij"); + // c (in a___cd...) + expect(_span(5, 5, map, file), "line 4, column 3 of .: \nabcdefghij"); + expect(_span(6, 1, map, file), "line 5, column 1 of .: \nabcd*fghij"); + expect(_span(6, 8, map, file), "line 5, column 1 of .: \nabcd*fghij"); }); } From b1c2cb2dd20be9579ab21038e839ec9e5e2375dd Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Thu, 19 Jun 2014 19:28:45 +0000 Subject: [PATCH 023/657] Add SpanException and SpanFormatException classes to source_maps. It's often useful to associate source range information with an exception in a way that will get printed along with that exception but can be pulled out and manipulated directly. It's especially useful if there's a common superclass/interface for doing so that can be shared across packages. This adds that superclass. R=sigmund@google.com Review URL: https://codereview.chromium.org//348493004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@37509 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/lib/span.dart | 24 ++++++++++++++++++++++++ pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index e2784587e..3730a10f5 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.2 + +* Add `SpanException` and `SpanFormatException` classes. + ## 0.9.1 * Support unmapped areas in source maps. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index f47e08eb6..cc48f190d 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -360,3 +360,27 @@ class SourceFileSegment extends SourceFile { String getText(int start, [int end]) => super.getText(start - _baseOffset, end == null ? null : end - _baseOffset); } + +/// A class for exceptions that have source span information attached. +class SpanException implements Exception { + /// A message describing the exception. + final String message; + + /// The span associated with this exception. + /// + /// This may be `null` if the source location can't be determined. + final Span span; + + SpanException(this.message, this.span); + + String toString({bool useColors: false, String color}) { + if (span == null) return message; + return span.getLocationMessage(message, useColors: useColors, color: color); + } +} + +/// A [SpanException] that's also a [FormatException]. +class SpanFormatException extends SpanException implements FormatException { + SpanFormatException(String message, Span span) + : super(message, span); +} diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 3c946e006..213587c43 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.9.1 +version: 0.9.2 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 36b7da221d34001c33f8ba4f7f1ba2f39bf859fb Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 20 Jun 2014 01:55:41 +0000 Subject: [PATCH 024/657] Improve the readability of some human-consumed strings in source_maps. R=jmesserly@google.com Review URL: https://codereview.chromium.org//346983002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@37530 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 5 +++++ pkgs/source_maps/lib/span.dart | 7 +++++-- pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 3730a10f5..55d789633 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.9.2+1 + +* Minor readability improvements to `FixedSpan.getLocationMessage` and + `SpanException.toString`. + ## 0.9.2 * Add `SpanException` and `SpanFormatException` classes. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index cc48f190d..91cfcd39c 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -64,7 +64,9 @@ abstract class Span implements Comparable { String getLocationMessage(String message, {bool useColors: false, String color}) { - return '$formatLocation: $message'; + var source = url == null ? '' : ' of ${p.prettyUri(url)}'; + return 'line ${start.line + 1}, column ${start.column + 1}$source: ' + + message; } bool operator ==(Span other) => @@ -375,7 +377,8 @@ class SpanException implements Exception { String toString({bool useColors: false, String color}) { if (span == null) return message; - return span.getLocationMessage(message, useColors: useColors, color: color); + return "Error on " + span.getLocationMessage(message, + useColors: useColors, color: color); } } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 213587c43..7fae470cb 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.9.2 +version: 0.9.2+1 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 23fa7bfaa6b9789f3cb2dbe2174966e8e572e1ee Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 20 Jun 2014 02:12:33 +0000 Subject: [PATCH 025/657] Fix a bug in FixedSpan.getLocationMessage. R=jmesserly@google.com Review URL: https://codereview.chromium.org//346993002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@37531 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/lib/span.dart | 3 ++- pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 55d789633..f40a16d80 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.2+2 + +* Fix a bug in `FixedSpan.getLocationMessage`. + ## 0.9.2+1 * Minor readability improvements to `FixedSpan.getLocationMessage` and diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 91cfcd39c..600506ee1 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -64,7 +64,8 @@ abstract class Span implements Comparable { String getLocationMessage(String message, {bool useColors: false, String color}) { - var source = url == null ? '' : ' of ${p.prettyUri(url)}'; + var source = start.sourceUrl == null ? '' : + ' of ${p.prettyUri(start.sourceUrl)}'; return 'line ${start.line + 1}, column ${start.column + 1}$source: ' + message; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 7fae470cb..80c7e7f25 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.9.2+1 +version: 0.9.2+2 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 7ea40395d0728b760f96b9c8116a1a7a142da0d8 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Thu, 26 Jun 2014 20:04:05 +0000 Subject: [PATCH 026/657] Add implicit constraints from pub onto stack_trace and source_maps. These packages are used in pub's plugin isolate, so pub needs to have a dependency on them to ensure their APIs don't change out from under it. R=rnystrom@google.com BUG=19574 Review URL: https://codereview.chromium.org//356523003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@37751 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/pubspec.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 80c7e7f25..97d6c6bdc 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,4 +1,12 @@ name: source_maps + +# Note! This version number is referenced directly in the pub source code in +# lib/src/barback.dart. Pub implicitly places a version constraint on +# source_maps to ensure users only select a version of source_maps that works +# with their current version of pub. +# +# When the minor version is upgraded, you *must* update that version constraint +# in pub to stay in sync with this. version: 0.9.2+2 author: Dart Team description: Library to programmatically manipulate source map files. From 2cf49c580b37375ba5a746e0842a47a17cf5edfc Mon Sep 17 00:00:00 2001 From: "sigmund@google.com" Date: Fri, 27 Jun 2014 19:07:20 +0000 Subject: [PATCH 027/657] Fix markdown in source_maps README.md so it renders correctly in pub site. R=nweiz@google.com Review URL: https://codereview.chromium.org//357013002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@37796 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/README.md | 2 ++ pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/README.md b/pkgs/source_maps/README.md index df182d9ba..5c7f638f4 100644 --- a/pkgs/source_maps/README.md +++ b/pkgs/source_maps/README.md @@ -7,6 +7,7 @@ originated from the [Closure Compiler][closure] and has been implemented in Chrome and Firefox. In this package we provide: + * Data types defining file locations and spans: these are not part of the original source map specification. These data types are great for tracking source locations on source maps, but they can also be used by tools to @@ -17,6 +18,7 @@ In this package we provide: mapping information. Some upcoming features we are planning to add to this package are: + * A printer that lets you generate code, but record source map information in the process. * A tool that can compose source maps together. This would be useful for diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 97d6c6bdc..9dee45f81 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -7,7 +7,7 @@ name: source_maps # # When the minor version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 0.9.2+2 +version: 0.9.2+3 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 3fdc73687f5602b708e830cf516f0d9ab533a29d Mon Sep 17 00:00:00 2001 From: "tjblasi@google.com" Date: Tue, 8 Jul 2014 22:13:43 +0000 Subject: [PATCH 028/657] Moving logic for writing source maps from SourceMapBuilder into the Mapping class. R=sigmund@google.com Review URL: https://codereview.chromium.org//372153002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38073 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/builder.dart | 80 +---------------- pkgs/source_maps/lib/parser.dart | 116 +++++++++++++++++++++++-- pkgs/source_maps/test/parser_test.dart | 11 +++ 3 files changed, 124 insertions(+), 83 deletions(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index ef22e3123..cd30ccb94 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -7,25 +7,16 @@ library source_maps.builder; // TODO(sigmund): add a builder for multi-section mappings. -import 'dart:collection'; import 'dart:convert'; +import 'parser.dart'; import 'span.dart'; -import 'src/vlq.dart'; /// Builds a source map given a set of mappings. class SourceMapBuilder { final List _entries = []; - /// Indices associated with file urls that will be part of the source map. We - /// use a linked hash-map so that `_urls.keys[_urls[u]] == u` - final Map _urls = new LinkedHashMap(); - - /// Indices associated with identifiers that will be part of the source map. - /// We use a linked hash-map so that `_names.keys[_names[n]] == n` - final Map _names = new LinkedHashMap(); - /// Adds an entry mapping the [targetOffset] to [source]. void addFromOffset(Location source, SourceFile targetFile, int targetOffset, String identifier) { @@ -48,78 +39,11 @@ class SourceMapBuilder { /// Encodes all mappings added to this builder as a json map. Map build(String fileUrl) { - var buff = new StringBuffer(); - var line = 0; - var column = 0; - var srcLine = 0; - var srcColumn = 0; - var srcUrlId = 0; - var srcNameId = 0; - var first = true; - - // The encoding needs to be sorted by the target offsets. - _entries.sort(); - for (var entry in _entries) { - int nextLine = entry.target.line; - if (nextLine > line) { - for (int i = line; i < nextLine; ++i) { - buff.write(';'); - } - line = nextLine; - column = 0; - first = true; - } - - if (!first) buff.write(','); - first = false; - column = _append(buff, column, entry.target.column); - - // Encoding can be just the column offset if there is no source - // information. - var source = entry.source; - if (source == null) continue; - var newUrlId = _indexOf(_urls, source.sourceUrl); - - srcUrlId = _append(buff, srcUrlId, newUrlId); - srcLine = _append(buff, srcLine, source.line); - srcColumn = _append(buff, srcColumn, source.column); - - if (entry.identifierName == null) continue; - srcNameId = _append(buff, srcNameId, - _indexOf(_names, entry.identifierName)); - } - - var result = { - 'version': 3, - 'sourceRoot': '', - 'sources': _urls.keys.toList(), - 'names' : _names.keys.toList(), - 'mappings' : buff.toString() - }; - if (fileUrl != null) { - result['file'] = fileUrl; - } - return result; + return new SingleMapping.fromEntries(this._entries, fileUrl).toJson(); } /// Encodes all mappings added to this builder as a json string. String toJson(String fileUrl) => JSON.encode(build(fileUrl)); - - /// Get the index of [value] in [map], or create one if it doesn't exist. - int _indexOf(Map map, String value) { - return map.putIfAbsent(value, () { - int index = map.length; - map[value] = index; - return index; - }); - } - - /// Appends to [buff] a VLQ encoding of [newValue] using the difference - /// between [oldValue] and [newValue] - static int _append(StringBuffer buff, int oldValue, int newValue) { - buff.writeAll(encodeVlq(newValue - oldValue)); - return newValue; - } } /// An entry in the source map builder. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index c92a8bba0..23835a60f 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -5,8 +5,10 @@ /// Contains the top-level function to parse source maps version 3. library source_maps.parser; +import 'dart:collection'; import 'dart:convert'; +import 'builder.dart' as builder; import 'span.dart'; import 'src/utils.dart'; import 'src/vlq.dart'; @@ -41,7 +43,7 @@ Mapping parseJson(Map map, {Map otherMaps}) { } -/// A mapping parsed our of a source map. +/// A mapping parsed out of a source map. abstract class Mapping { Span spanFor(int line, int column, {Map files}); @@ -131,7 +133,6 @@ class MultiSectionMapping extends Mapping { } /// A map containing direct source mappings. -// TODO(sigmund): integrate mapping and sourcemap builder? class SingleMapping extends Mapping { /// Url of the target file. final String targetUrl; @@ -143,13 +144,58 @@ class SingleMapping extends Mapping { final List names; /// Entries indicating the beginning of each span. - final List lines = []; + final List lines; + + SingleMapping._internal(this.targetUrl, this.urls, this.names, this.lines); + + factory SingleMapping.fromEntries( + Iterable entries, [String fileUrl]) { + // The entries needs to be sorted by the target offsets. + var sourceEntries = new List.from(entries)..sort(); + var lines = []; + + // Indices associated with file urls that will be part of the source map. We + // use a linked hash-map so that `_urls.keys[_urls[u]] == u` + var urls = new LinkedHashMap(); + + // Indices associated with identifiers that will be part of the source map. + // We use a linked hash-map so that `_names.keys[_names[n]] == n` + var names = new LinkedHashMap(); + + var lineNum; + var targetEntries; + for (var sourceEntry in sourceEntries) { + if (lineNum == null || sourceEntry.target.line > lineNum) { + lineNum = sourceEntry.target.line; + targetEntries = []; + lines.add(new TargetLineEntry(lineNum, targetEntries)); + } + + if (sourceEntry.source == null) { + targetEntries.add(new TargetEntry(sourceEntry.target.column)); + } else { + var urlId = urls.putIfAbsent( + sourceEntry.source.sourceUrl, () => urls.length); + var srcNameId = sourceEntry.identifierName == null ? null : + names.putIfAbsent(sourceEntry.identifierName, () => names.length); + targetEntries.add(new TargetEntry( + sourceEntry.target.column, + urlId, + sourceEntry.source.line, + sourceEntry.source.column, + srcNameId)); + } + } + return new SingleMapping._internal( + fileUrl, urls.keys.toList(), names.keys.toList(), lines); + } SingleMapping.fromJson(Map map) : targetUrl = map['file'], // TODO(sigmund): add support for 'sourceRoot' urls = map['sources'], - names = map['names'] { + names = map['names'], + lines = [] { int line = 0; int column = 0; int srcUrlId = 0; @@ -215,6 +261,66 @@ class SingleMapping extends Mapping { } } + /// Encodes the Mapping mappings as a json map. + Map toJson() { + var buff = new StringBuffer(); + var line = 0; + var column = 0; + var srcLine = 0; + var srcColumn = 0; + var srcUrlId = 0; + var srcNameId = 0; + var first = true; + + for (var entry in lines) { + int nextLine = entry.line; + if (nextLine > line) { + for (int i = line; i < nextLine; ++i) { + buff.write(';'); + } + line = nextLine; + column = 0; + first = true; + } + + for (var segment in entry.entries) { + if (!first) buff.write(','); + first = false; + column = _append(buff, column, segment.column); + + // Encoding can be just the column offset if there is no source + // information. + var newUrlId = segment.sourceUrlId; + if (newUrlId == null) continue; + srcUrlId = _append(buff, srcUrlId, newUrlId); + srcLine = _append(buff, srcLine, segment.sourceLine); + srcColumn = _append(buff, srcColumn, segment.sourceColumn); + + if (segment.sourceNameId == null) continue; + srcNameId = _append(buff, srcNameId, segment.sourceNameId); + } + } + + var result = { + 'version': 3, + 'sourceRoot': '', + 'sources': urls, + 'names' : names, + 'mappings' : buff.toString() + }; + if (targetUrl != null) { + result['file'] = targetUrl; + } + return result; + } + + /// Appends to [buff] a VLQ encoding of [newValue] using the difference + /// between [oldValue] and [newValue] + static int _append(StringBuffer buff, int oldValue, int newValue) { + buff.writeAll(encodeVlq(newValue - oldValue)); + return newValue; + } + _segmentError(int seen, int line) => new StateError( 'Invalid entry in sourcemap, expected 1, 4, or 5' ' values, but got $seen.\ntargeturl: $targetUrl, line: $line'); @@ -308,7 +414,7 @@ class SingleMapping extends Mapping { /// A line entry read from a source map. class TargetLineEntry { final int line; - List entries = []; + List entries; TargetLineEntry(this.line, this.entries); String toString() => '$runtimeType: $line $entries'; diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index afdd7fb2c..8f1be3dc5 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -99,4 +99,15 @@ main() { expect(entry.sourceLine, 0); expect(entry.sourceNameId, 0); }); + + test('parse and re-emit', () { + for (var expected in [ + EXPECTED_MAP, + MAP_WITH_NO_SOURCE_LOCATION, + MAP_WITH_SOURCE_LOCATION, + MAP_WITH_SOURCE_LOCATION_AND_NAME]) { + var mapping = parseJson(expected); + expect(mapping.toJson(), equals(expected)); + } + }); } From eb79592cedbff4734c3b218461b6a115d0a30fe8 Mon Sep 17 00:00:00 2001 From: "lrn@google.com" Date: Mon, 14 Jul 2014 09:24:11 +0000 Subject: [PATCH 029/657] Fix class implementing FormatException getting warnings. Update mirrors-used-test count. R=kustermann@google.com Review URL: https://codereview.chromium.org//392563003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38182 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/span.dart | 3 +++ pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 600506ee1..771e9e0ef 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -387,4 +387,7 @@ class SpanException implements Exception { class SpanFormatException extends SpanException implements FormatException { SpanFormatException(String message, Span span) : super(message, span); + + get source => null; + int get position => null; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 9dee45f81..e6e749c8a 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -7,7 +7,7 @@ name: source_maps # # When the minor version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 0.9.2+3 +version: 0.9.2+4-dev author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 74e08e7027d6d3e3dd9731f5a4a1bb88ff423aba Mon Sep 17 00:00:00 2001 From: "tjblasi@google.com" Date: Tue, 15 Jul 2014 16:47:12 +0000 Subject: [PATCH 030/657] Adding support for `sourceRoot` to the SingleMapping class. BUG= R=sigmund@google.com Review URL: https://codereview.chromium.org//383823002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38241 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/parser.dart | 31 ++++++++++++++++++-------- pkgs/source_maps/test/parser_test.dart | 14 ++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 23835a60f..f53f7edcc 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -16,6 +16,8 @@ import 'src/vlq.dart'; /// Parses a source map directly from a json string. // TODO(sigmund): evaluate whether other maps should have the json parsed, or // the string represenation. +// TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string +// `)]}'` begins the string representation of the map. Mapping parse(String jsonMap, {Map otherMaps}) => parseJson(JSON.decode(jsonMap), otherMaps: otherMaps); @@ -146,6 +148,9 @@ class SingleMapping extends Mapping { /// Entries indicating the beginning of each span. final List lines; + /// Source root appended to the start of all entries in [urls]. + String sourceRoot = null; + SingleMapping._internal(this.targetUrl, this.urls, this.names, this.lines); factory SingleMapping.fromEntries( @@ -192,9 +197,9 @@ class SingleMapping extends Mapping { SingleMapping.fromJson(Map map) : targetUrl = map['file'], - // TODO(sigmund): add support for 'sourceRoot' urls = map['sources'], names = map['names'], + sourceRoot = map['sourceRoot'], lines = [] { int line = 0; int column = 0; @@ -303,7 +308,7 @@ class SingleMapping extends Mapping { var result = { 'version': 3, - 'sourceRoot': '', + 'sourceRoot': sourceRoot == null ? '' : sourceRoot, 'sources': urls, 'names' : names, 'mappings' : buff.toString() @@ -350,6 +355,9 @@ class SingleMapping extends Mapping { var entry = _findColumn(line, column, _findLine(line)); if (entry == null || entry.sourceUrlId == null) return null; var url = urls[entry.sourceUrlId]; + if (sourceRoot != null) { + url = '${sourceRoot}${url}'; + } if (files != null && files[url] != null) { var file = files[url]; var start = file.getOffset(entry.sourceLine, entry.sourceColumn); @@ -374,6 +382,8 @@ class SingleMapping extends Mapping { return (new StringBuffer("$runtimeType : [") ..write('targetUrl: ') ..write(targetUrl) + ..write(', sourceRoot: ') + ..write(sourceRoot) ..write(', urls: ') ..write(urls) ..write(', names: ') @@ -392,13 +402,16 @@ class SingleMapping extends Mapping { ..write(': ') ..write(line) ..write(':') - ..write(entry.column) - ..write(' --> ') - ..write(urls[entry.sourceUrlId]) - ..write(': ') - ..write(entry.sourceLine) - ..write(':') - ..write(entry.sourceColumn); + ..write(entry.column); + if (entry.sourceUrlId != null) { + buff..write(' --> ') + ..write(sourceRoot) + ..write(urls[entry.sourceUrlId]) + ..write(': ') + ..write(entry.sourceLine) + ..write(':') + ..write(entry.sourceColumn); + } if (entry.sourceNameId != null) { buff..write(' (') ..write(names[entry.sourceNameId]) diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 8f1be3dc5..62cd08f1f 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -100,6 +100,20 @@ main() { expect(entry.sourceNameId, 0); }); + test('parse with source root', () { + var inputMap = new Map.from(MAP_WITH_SOURCE_LOCATION); + inputMap['sourceRoot'] = '/pkg/'; + var mapping = parseJson(inputMap); + expect(mapping.spanFor(0, 0).sourceUrl, "/pkg/input.dart"); + + var newSourceRoot = '/new/'; + + mapping.sourceRoot = newSourceRoot; + inputMap["sourceRoot"] = newSourceRoot; + + expect(mapping.toJson(), equals(inputMap)); + }); + test('parse and re-emit', () { for (var expected in [ EXPECTED_MAP, From 91ea87a9e6bebf643df99ee02063f1efe800e460 Mon Sep 17 00:00:00 2001 From: "tjblasi@google.com" Date: Tue, 15 Jul 2014 18:07:06 +0000 Subject: [PATCH 031/657] Allow updating the `targetUrl` property of SingleMapping. R=sigmund@google.com Review URL: https://codereview.chromium.org//397693002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38245 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/parser.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index f53f7edcc..3fd0d1445 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -136,9 +136,6 @@ class MultiSectionMapping extends Mapping { /// A map containing direct source mappings. class SingleMapping extends Mapping { - /// Url of the target file. - final String targetUrl; - /// Source urls used in the mapping, indexed by id. final List urls; @@ -148,10 +145,13 @@ class SingleMapping extends Mapping { /// Entries indicating the beginning of each span. final List lines; + /// Url of the target file. + String targetUrl; + /// Source root appended to the start of all entries in [urls]. - String sourceRoot = null; + String sourceRoot; - SingleMapping._internal(this.targetUrl, this.urls, this.names, this.lines); + SingleMapping._(this.targetUrl, this.urls, this.names, this.lines); factory SingleMapping.fromEntries( Iterable entries, [String fileUrl]) { @@ -191,7 +191,7 @@ class SingleMapping extends Mapping { srcNameId)); } } - return new SingleMapping._internal( + return new SingleMapping._( fileUrl, urls.keys.toList(), names.keys.toList(), lines); } From c106380a92e912d29d8705a826c73c4ac9c3490d Mon Sep 17 00:00:00 2001 From: "tjblasi@google.com" Date: Wed, 16 Jul 2014 17:49:58 +0000 Subject: [PATCH 032/657] Rev source_maps patch number, package is now 0.9.3. R=sigmund@google.com Review URL: https://codereview.chromium.org//396833003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38295 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 6 ++++++ pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index f40a16d80..7767fc145 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.9.3 + +* Support writing SingleMapping objects to source map version 3 format. +* Support the `sourceRoot` field in the SingleMapping class. +* Support updating the `targetUrl` field in the SingleMapping class. + ## 0.9.2+2 * Fix a bug in `FixedSpan.getLocationMessage`. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index e6e749c8a..ae0323d0c 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -7,7 +7,7 @@ name: source_maps # # When the minor version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 0.9.2+4-dev +version: 0.9.3 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 8105a5ee9f8c0bac2ba278c0bd25f4cea0980f9b Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 18 Jul 2014 00:51:40 +0000 Subject: [PATCH 033/657] Extract out a source_span package from source_maps. This is just the first step; future CLs will add support for the new API to various packages currently using the old one. BUG=19930 R=sigmund@google.com Review URL: https://codereview.chromium.org//381363002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_span@38360 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_span/CHANGELOG.md | 33 ++ pkgs/source_span/LICENSE | 26 ++ pkgs/source_span/README.md | 15 + pkgs/source_span/lib/source_span.dart | 11 + pkgs/source_span/lib/src/colors.dart | 13 + pkgs/source_span/lib/src/file.dart | 266 +++++++++++++ pkgs/source_span/lib/src/location.dart | 86 +++++ pkgs/source_span/lib/src/span.dart | 78 ++++ pkgs/source_span/lib/src/span_exception.dart | 43 +++ pkgs/source_span/lib/src/span_mixin.dart | 74 ++++ pkgs/source_span/lib/src/utils.dart | 39 ++ pkgs/source_span/pubspec.yaml | 12 + pkgs/source_span/test/file_message_test.dart | 100 +++++ pkgs/source_span/test/file_test.dart | 370 +++++++++++++++++++ pkgs/source_span/test/location_test.dart | 101 +++++ pkgs/source_span/test/span_test.dart | 256 +++++++++++++ pkgs/source_span/test/utils_test.dart | 51 +++ 17 files changed, 1574 insertions(+) create mode 100644 pkgs/source_span/CHANGELOG.md create mode 100644 pkgs/source_span/LICENSE create mode 100644 pkgs/source_span/README.md create mode 100644 pkgs/source_span/lib/source_span.dart create mode 100644 pkgs/source_span/lib/src/colors.dart create mode 100644 pkgs/source_span/lib/src/file.dart create mode 100644 pkgs/source_span/lib/src/location.dart create mode 100644 pkgs/source_span/lib/src/span.dart create mode 100644 pkgs/source_span/lib/src/span_exception.dart create mode 100644 pkgs/source_span/lib/src/span_mixin.dart create mode 100644 pkgs/source_span/lib/src/utils.dart create mode 100644 pkgs/source_span/pubspec.yaml create mode 100644 pkgs/source_span/test/file_message_test.dart create mode 100644 pkgs/source_span/test/file_test.dart create mode 100644 pkgs/source_span/test/location_test.dart create mode 100644 pkgs/source_span/test/span_test.dart create mode 100644 pkgs/source_span/test/utils_test.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md new file mode 100644 index 000000000..04e4be2fd --- /dev/null +++ b/pkgs/source_span/CHANGELOG.md @@ -0,0 +1,33 @@ +# 1.0.0 + +This package was extracted from the +[`source_maps`](http://pub.dartlang.org/packages/source_maps) package, but the +API has many differences. Among them: + +* `Span` has been renamed to `SourceSpan` and `Location` has been renamed to + `SourceLocation` to clarify their purpose and maintain consistency with the + package name. Likewise, `SpanException` is now `SourceSpanException` and + `SpanFormatException` is not `SourceSpanFormatException`. + +* `FixedSpan` and `FixedLocation` have been rolled into the `Span` and + `Location` classes, respectively. + +* `SourceFile` is more aggressive about validating its arguments. Out-of-bounds + lines, columns, and offsets will now throw errors rather than be silently + clamped. + +* `SourceSpan.sourceUrl`, `SourceLocation.sourceUrl`, and `SourceFile.url` now + return `Uri` objects rather than `String`s. The constructors allow either + `String`s or `Uri`s. + +* `Span.getLocationMessage` and `SourceFile.getLocationMessage` are now + `SourceSpan.message` and `SourceFile.message`, respectively. Rather than + taking both a `useColor` and a `color` parameter, they now take a single + `color` parameter that controls both whether and which color is used. + +* `Span.isIdentifier` has been removed. This property doesn't make sense outside + of a source map context. + +* `SourceFileSegment` has been removed. This class wasn't widely used and was + inconsistent in its choice of which parameters were considered relative and + which absolute. diff --git a/pkgs/source_span/LICENSE b/pkgs/source_span/LICENSE new file mode 100644 index 000000000..5c60afea3 --- /dev/null +++ b/pkgs/source_span/LICENSE @@ -0,0 +1,26 @@ +Copyright 2014, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkgs/source_span/README.md b/pkgs/source_span/README.md new file mode 100644 index 000000000..4e2547e28 --- /dev/null +++ b/pkgs/source_span/README.md @@ -0,0 +1,15 @@ +`source_span` is a library for tracking locations in source code. It's designed +to provide a standard representation for source code locations and spans so that +disparate packages can easily pass them among one another, and to make it easy +to generate human-friendly messages associated with a given piece of code. + +The most commonly-used class is the package's namesake, `SourceSpan`. It +represents a span of characters in some source file, and is often attached to an +object that has been parsed to indicate where it was parsed from. It provides +access to the text of the span via `SourceSpan.text` and can be used to produce +human-friendly messages using `SourceSpan.message()`. + +When parsing code from a file, `SourceFile` is useful. Not only does it provide +an efficient means of computing line and column numbers, `SourceFile.span()` +returns special `FileSpan`s that are able to provide more context for their +error messages. diff --git a/pkgs/source_span/lib/source_span.dart b/pkgs/source_span/lib/source_span.dart new file mode 100644 index 000000000..e9646b1fd --- /dev/null +++ b/pkgs/source_span/lib/source_span.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2014, 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. + +library source_span; + +export "src/file.dart"; +export "src/location.dart"; +export "src/span.dart"; +export "src/span_exception.dart"; +export "src/span_mixin.dart"; diff --git a/pkgs/source_span/lib/src/colors.dart b/pkgs/source_span/lib/src/colors.dart new file mode 100644 index 000000000..274fc92af --- /dev/null +++ b/pkgs/source_span/lib/src/colors.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2014, 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. + +// Color constants used for generating messages. +library source_span.colors; + +const String RED = '\u001b[31m'; + +const String YELLOW = '\u001b[33m'; + +const String NONE = '\u001b[0m'; + diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart new file mode 100644 index 000000000..0d2d6f6ca --- /dev/null +++ b/pkgs/source_span/lib/src/file.dart @@ -0,0 +1,266 @@ +// Copyright (c) 2014, 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. + +library source_span.file; + +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'package:path/path.dart' as p; + +import 'colors.dart' as colors; +import 'location.dart'; +import 'span.dart'; +import 'span_mixin.dart'; +import 'utils.dart'; + +// Constants to determine end-of-lines. +const int _LF = 10; +const int _CR = 13; + +/// A class representing a source file. +/// +/// This doesn't necessarily have to correspond to a file on disk, just a chunk +/// of text usually with a URL associated with it. +class SourceFile { + /// The URL where the source file is located. + /// + /// This may be null, indicating that the URL is unknown or unavailable. + final Uri url; + + /// An array of offsets for each line beginning in the file. + /// + /// Each offset refers to the first character *after* the newline. If the + /// source file has a trailing newline, the final offset won't actually be in + /// the file. + final _lineStarts = [0]; + + /// The code points of the characters in the file. + final Uint32List _decodedChars; + + /// The length of the file in characters. + int get length => _decodedChars.length; + + /// The number of lines in the file. + int get lines => _lineStarts.length; + + /// Creates a new source file from [text]. + /// + /// [url] may be either a [String], a [Uri], or `null`. + SourceFile(String text, {url}) + : this.decoded(text.runes, url: url); + + /// Creates a new source file from a list of decoded characters. + /// + /// [url] may be either a [String], a [Uri], or `null`. + SourceFile.decoded(Iterable decodedChars, {url}) + : url = url is String ? Uri.parse(url) : url, + _decodedChars = new Uint32List.fromList(decodedChars.toList()) { + for (var i = 0; i < _decodedChars.length; i++) { + var c = _decodedChars[i]; + if (c == _CR) { + // Return not followed by newline is treated as a newline + var j = i + 1; + if (j >= _decodedChars.length || _decodedChars[j] != _LF) c = _LF; + } + if (c == _LF) _lineStarts.add(i + 1); + } + } + + /// Returns a span in [this] from [start] to [end] (exclusive). + /// + /// If [end] isn't passed, it defaults to the end of the file. + FileSpan span(int start, [int end]) { + if (end == null) end = length - 1; + return new FileSpan._(this, location(start), location(end)); + } + + /// Returns a location in [this] at [offset]. + FileLocation location(int offset) => new FileLocation._(this, offset); + + /// Gets the 0-based line corresponding to [offset]. + int getLine(int offset) { + if (offset < 0) { + throw new RangeError("Offset may not be negative, was $offset."); + } else if (offset > length) { + throw new RangeError("Offset $offset must not be greater than the number " + "of characters in the file, $length."); + } + return binarySearch(_lineStarts, (o) => o > offset) - 1; + } + + /// Gets the 0-based column corresponding to [offset]. + /// + /// 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}) { + if (offset < 0) { + throw new RangeError("Offset may not be negative, was $offset."); + } else if (offset > length) { + throw new RangeError("Offset $offset must be not be greater than the " + "number of characters in the file, $length."); + } + + if (line == null) { + line = getLine(offset); + } else if (line < 0) { + throw new RangeError("Line may not be negative, was $line."); + } else if (line >= lines) { + throw new RangeError("Line $line must be less than the number of " + "lines in the file, $lines."); + } + + var lineStart = _lineStarts[line]; + if (lineStart > offset) { + throw new RangeError("Line $line comes after offset $offset."); + } + + return offset - lineStart; + } + + /// Gets the offset for a [line] and [column]. + /// + /// [column] defaults to 0. + int getOffset(int line, [int column]) { + if (column == null) column = 0; + + if (line < 0) { + throw new RangeError("Line may not be negative, was $line."); + } else if (line >= lines) { + throw new RangeError("Line $line must be less than the number of " + "lines in the file, $lines."); + } else if (column < 0) { + throw new RangeError("Column may not be negative, was $column."); + } + + var result = _lineStarts[line] + column; + if (result > length || + (line + 1 < lines && result >= _lineStarts[line + 1])) { + throw new RangeError("Line $line doesn't have $column columns."); + } + + return result; + } + + /// 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]) => + new String.fromCharCodes(_decodedChars.sublist(start, end)); +} + +/// A [SourceLocation] within a [SourceFile]. +/// +/// Unlike the base [SourceLocation], [FileLocation] lazily computes its line +/// and column values based on its offset and the contents of [file]. +/// +/// A [FileLocation] can be created using [SourceFile.location]. +class FileLocation extends SourceLocation { + /// The [file] that [this] belongs to. + final SourceFile file; + + Uri get sourceUrl => file.url; + int get line => file.getLine(offset); + int get column => file.getColumn(offset); + + FileLocation._(this.file, int offset) + : super(offset) { + if (offset > file.length) { + throw new RangeError("Offset $offset must not be greater than the number " + "of characters in the file, ${file.length}."); + } + } + + FileSpan pointSpan() => new FileSpan._(file, this, this); +} + +/// A [SourceSpan] within a [SourceFile]. +/// +/// Unlike the base [SourceSpan], [FileSpan] lazily computes its line and column +/// values based on its offset and the contents of [file]. [FileSpan.message] is +/// also able to provide more context then [SourceSpan.message], and +/// [FileSpan.union] will return a [FileSpan] if possible. +/// +/// A [FileSpan] can be created using [SourceFile.span]. +class FileSpan extends SourceSpanMixin { + /// The [file] that [this] belongs to. + final SourceFile file; + + final FileLocation start; + final FileLocation end; + + String get text => file.getText(start.offset, end.offset); + + FileSpan._(this.file, this.start, this.end) { + if (end.offset < start.offset) { + throw new ArgumentError('End $end must come after start $start.'); + } + } + + SourceSpan union(SourceSpan other) { + if (other is! FileSpan) return super.union(other); + + var span = expand(other); + var beginSpan = span.start == this.start ? this : other; + var endSpan = span.end == this.end ? this : other; + + if (beginSpan.end.compareTo(endSpan.start) < 0) { + throw new ArgumentError("Spans $this and $other are disjoint."); + } + + return span; + } + + /// Returns a new span that covers both [this] and [other]. + /// + /// Unlike [union], [other] may be disjoint from [this]. If it is, the text + /// between the two will be covered by the returned span. + FileSpan expand(FileSpan other) { + if (sourceUrl != other.sourceUrl) { + throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + " \"${other.sourceUrl}\" don't match."); + } + + var start = min(this.start, other.start); + var end = max(this.end, other.end); + return new FileSpan._(file, start, end); + } + + String message(String message, {color}) { + if (color == true) color = colors.RED; + if (color == false) color = null; + + var line = start.line; + var column = start.column; + + var buffer = new StringBuffer(); + buffer.write('line ${start.line + 1}, column ${start.column + 1}'); + if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); + buffer.write(': $message\n'); + + var textLine = file.getText(file.getOffset(line), + line == file.lines - 1 ? null : file.getOffset(line + 1)); + + column = math.min(column, textLine.length - 1); + var toColumn = + math.min(column + end.offset - start.offset, textLine.length); + + if (color != null) { + buffer.write(textLine.substring(0, column)); + buffer.write(color); + buffer.write(textLine.substring(column, toColumn)); + buffer.write(colors.NONE); + buffer.write(textLine.substring(toColumn)); + } else { + buffer.write(textLine); + } + if (!textLine.endsWith('\n')) buffer.write('\n'); + + buffer.write(' ' * column); + if (color != null) buffer.write(color); + buffer.write('^' * math.max(toColumn - column, 1)); + if (color != null) buffer.write(colors.NONE); + return buffer.toString(); + } +} diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart new file mode 100644 index 000000000..41f251898 --- /dev/null +++ b/pkgs/source_span/lib/src/location.dart @@ -0,0 +1,86 @@ +// Copyright (c) 2014, 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. + +library source_span.location; + +import 'span.dart'; + +// A class that describes a single location within a source file. +class SourceLocation implements Comparable { + /// URL of the source containing this location. + /// + /// This may be null, indicating that the source URL is unknown or + /// unavailable. + final Uri sourceUrl; + + /// The 0-based offset of this location in the source. + final int offset; + + /// The 0-based line of this location in the source. + final int line; + + /// The 0-based column of this location in the source + final int column; + + /// Returns a representation of this location in the `source:line:column` + /// format used by text editors. + /// + /// This prints 1-based lines and columns. + String get toolString { + var source = sourceUrl == null ? 'unknown source' : sourceUrl; + return '$source:${line + 1}:${column + 1}'; + } + + /// Creates a new location indicating [offset] within [sourceUrl]. + /// + /// [line] and [column] default to assuming the source is a single line. This + /// means that [line] defaults to 0 and [column] defaults to [offset]. + /// + /// [sourceUrl] may be either a [String], a [Uri], or `null`. + SourceLocation(int offset, {sourceUrl, int line, int column}) + : sourceUrl = sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl, + offset = offset, + line = line == null ? 0 : line, + column = column == null ? offset : column { + if (this.offset < 0) { + throw new RangeError("Offset may not be negative, was $offset."); + } else if (this.line < 0) { + throw new RangeError("Line may not be negative, was $line."); + } else if (this.column < 0) { + throw new RangeError("Column may not be negative, was $column."); + } + } + + /// Returns the distance in characters between [this] and [other]. + /// + /// This always returns a non-negative value. + int distance(SourceLocation other) { + if (sourceUrl != other.sourceUrl) { + throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + "\"${other.sourceUrl}\" don't match."); + } + return (offset - other.offset).abs(); + } + + /// Returns a span that covers only a single point: this location. + SourceSpan pointSpan() => new SourceSpan(this, this, ""); + + /// Compares two locations. + /// + /// [other] must have the same source URL as [this]. + int compareTo(SourceLocation other) { + if (sourceUrl != other.sourceUrl) { + throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + "\"${other.sourceUrl}\" don't match."); + } + return offset - other.offset; + } + + bool operator ==(SourceLocation other) => + sourceUrl == other.sourceUrl && offset == other.offset; + + int get hashCode => sourceUrl.hashCode + offset; + + String toString() => '<$runtimeType: $offset $toolString>'; +} diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart new file mode 100644 index 000000000..9f150482c --- /dev/null +++ b/pkgs/source_span/lib/src/span.dart @@ -0,0 +1,78 @@ +// Copyright (c) 2014, 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. + +library source_span.span; + +import 'location.dart'; +import 'span_mixin.dart'; + +/// A class that describes a segment of source text. +abstract class SourceSpan implements Comparable { + /// The start location of this span. + final SourceLocation start; + + /// The end location of this span, exclusive. + final SourceLocation end; + + /// The source text for this span. + final String text; + + /// The URL of the source (typically a file) of this span. + /// + /// This may be null, indicating that the source URL is unknown or + /// unavailable. + final Uri sourceUrl; + + /// The length of this span, in characters. + final int length; + + /// Creates a new span from [start] to [end] (exclusive) containing [text]. + /// + /// [start] and [end] must have the same source URL and [start] must come + /// before [end]. [text] must have a number of characters equal to the + /// distance between [start] and [end]. + factory SourceSpan(SourceLocation start, SourceLocation end, String text) => + new SourceSpanBase(start, end, text); + + /// Creates a new span that's the union of [this] and [other]. + /// + /// The two spans must have the same source URL and may not be disjoint. + /// [text] is computed by combining [this.text] and [other.text]. + SourceSpan union(SourceSpan other); + + /// Compares two spans. + /// + /// [other] must have the same source URL as [this]. This orders spans by + /// [start] then [length]. + int compareTo(SourceSpan other); + + /// Formats [message] in a human-friendly way associated with this span. + /// + /// [color] may either be a [String], a [bool], or `null`. If it's a string, + /// it indicates an ANSII terminal color escape that should be used to + /// highlight the span's text. If it's `true`, it indicates that the text + /// should be highlighted using the default color. If it's `false` or `null`, + /// it indicates that the text shouldn't be highlighted. + String message(String message, {color}); +} + +/// A base class for source spans with [start], [end], and [text] known at +/// construction time. +class SourceSpanBase extends SourceSpanMixin { + final SourceLocation start; + final SourceLocation end; + final String text; + + SourceSpanBase(this.start, this.end, this.text) { + if (end.sourceUrl != start.sourceUrl) { + throw new ArgumentError("Source URLs \"${start.sourceUrl}\" and " + " \"${end.sourceUrl}\" don't match."); + } else if (end.offset < start.offset) { + throw new ArgumentError('End $end must come after start $start.'); + } else if (text.length != start.distance(end)) { + throw new ArgumentError('Text "$text" must be ${start.distance(end)} ' + 'characters long.'); + } + } +} diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart new file mode 100644 index 000000000..af642413b --- /dev/null +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -0,0 +1,43 @@ +// Copyright (c) 2014, 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. + +library source_span.span_exception; + +import 'span.dart'; + +/// A class for exceptions that have source span information attached. +class SourceSpanException implements Exception { + /// A message describing the exception. + final String message; + + /// The span associated with this exception. + /// + /// This may be `null` if the source location can't be determined. + final SourceSpan span; + + SourceSpanException(this.message, this.span); + + /// Returns a string representation of [this]. + /// + /// [color] may either be a [String], a [bool], or `null`. If it's a string, + /// it indicates an ANSII terminal color escape that should be used to + /// highlight the span's text. If it's `true`, it indicates that the text + /// should be highlighted using the default color. If it's `false` or `null`, + /// it indicates that the text shouldn't be highlighted. + String toString({color}) { + if (span == null) return message; + return "Error on " + span.message(message, color: color); + } +} + +/// A [SourceSpanException] that's also a [FormatException]. +class SourceSpanFormatException extends SourceSpanException + implements FormatException { + final source; + + int get position => span == null ? null : span.start.offset; + + SourceSpanFormatException(String message, SourceSpan span, [this.source]) + : super(message, span); +} diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart new file mode 100644 index 000000000..95a720aae --- /dev/null +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -0,0 +1,74 @@ +// Copyright (c) 2014, 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. + +library source_span.span_mixin; + +import 'package:path/path.dart' as p; + +import 'colors.dart' as colors; +import 'span.dart'; +import 'utils.dart'; + +/// A mixin for easily implementing [SourceSpan]. +/// +/// This implements the [SourceSpan] methods in terms of [start], [end], and +/// [text]. This assumes that [start] and [end] have the same source URL, that +/// [start] comes before [end], and that [text] has a number of characters equal +/// to the distance between [start] and [end]. +abstract class SourceSpanMixin implements SourceSpan { + Uri get sourceUrl => start.sourceUrl; + int get length => end.offset - start.offset; + + int compareTo(SourceSpan other) { + int d = start.compareTo(other.start); + return d == 0 ? end.compareTo(other.end) : d; + } + + SourceSpan union(SourceSpan other) { + if (sourceUrl != other.sourceUrl) { + throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + " \"${other.sourceUrl}\" don't match."); + } + + var start = min(this.start, other.start); + var end = max(this.end, other.end); + var beginSpan = start == this.start ? this : other; + var endSpan = end == this.end ? this : other; + + if (beginSpan.end.compareTo(endSpan.start) < 0) { + throw new ArgumentError("Spans $this and $other are disjoint."); + } + + var text = beginSpan.text + + endSpan.text.substring(beginSpan.end.distance(endSpan.start)); + return new SourceSpan(start, end, text); + } + + String message(String message, {color}) { + if (color == true) color = colors.RED; + if (color == false) color = null; + + var buffer = new StringBuffer(); + buffer.write('line ${start.line + 1}, column ${start.column + 1}'); + if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); + buffer.write(': $message'); + if (length == 0) return buffer.toString(); + + buffer.write("\n"); + var textLine = text.split("\n").first; + if (color != null) buffer.write(color); + buffer.write(textLine); + buffer.write("\n"); + buffer.write('^' * textLine.length); + if (color != null) buffer.write(colors.NONE); + return buffer.toString(); + } + + bool operator ==(SourceSpan other) => + start == other.start && end == other.end; + + int get hashCode => start.hashCode + (31 * end.hashCode); + + String toString() => '<$runtimeType: from $start to $end "$text">'; +} diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart new file mode 100644 index 000000000..4a8eb551e --- /dev/null +++ b/pkgs/source_span/lib/src/utils.dart @@ -0,0 +1,39 @@ +// Copyright (c) 2014, 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. + +library source_span.utils; + +/// Returns the minimum of [obj1] and [obj2] according to +/// [Comparable.compareTo]. +Comparable min(Comparable obj1, Comparable obj2) => + obj1.compareTo(obj2) > 0 ? obj2 : obj1; + +/// Returns the maximum of [obj1] and [obj2] according to +/// [Comparable.compareTo]. +Comparable max(Comparable obj1, Comparable obj2) => + obj1.compareTo(obj2) > 0 ? obj1 : obj2; + +/// Find the first entry in a sorted [list] that matches a monotonic predicate. +/// +/// Given a result `n`, that all items before `n` will not match, `n` matches, +/// and all items after `n` match too. The result is -1 when there are no +/// items, 0 when all items match, and list.length when none does. +int binarySearch(List list, bool matches(item)) { + if (list.length == 0) return -1; + if (matches(list.first)) return 0; + if (!matches(list.last)) return list.length; + + int min = 0; + int max = list.length - 1; + while (min < max) { + var half = min + ((max - min) ~/ 2); + if (matches(list[half])) { + max = half; + } else { + min = half + 1; + } + } + return max; +} + diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml new file mode 100644 index 000000000..66e5811ac --- /dev/null +++ b/pkgs/source_span/pubspec.yaml @@ -0,0 +1,12 @@ +name: source_span + +version: 1.0.0 +author: Dart Team +description: A library for identifying source spans and locations. +homepage: http://www.dartlang.org +dependencies: + path: '>=1.2.0 <2.0.0' +environment: + sdk: '>=0.8.10+6 <2.0.0' +dev_dependencies: + unittest: '>=0.9.0 <0.10.0' diff --git a/pkgs/source_span/test/file_message_test.dart b/pkgs/source_span/test/file_message_test.dart new file mode 100644 index 000000000..18b34e71b --- /dev/null +++ b/pkgs/source_span/test/file_message_test.dart @@ -0,0 +1,100 @@ +// Copyright (c) 2014, 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:unittest/unittest.dart'; +import 'package:source_span/source_span.dart'; +import 'package:source_span/src/colors.dart' as colors; + +main() { + var file; + setUp(() { + file = new SourceFile(""" +foo bar baz +whiz bang boom +zip zap zop +""", url: "foo.dart"); + }); + + test("points to the span in the source", () { + expect(file.span(4, 7).message("oh no"), equals(""" +line 1, column 5 of foo.dart: oh no +foo bar baz + ^^^""")); + }); + + test("gracefully handles a missing source URL", () { + var span = new SourceFile("foo bar baz").span(4, 7); + expect(span.message("oh no"), equals(""" +line 1, column 5: oh no +foo bar baz + ^^^""")); + }); + + test("highlights the first line of a multiline span", () { + expect(file.span(4, 20).message("oh no"), equals(""" +line 1, column 5 of foo.dart: oh no +foo bar baz + ^^^^^^^^""")); + }); + + test("works for a point span", () { + expect(file.location(4).pointSpan().message("oh no"), equals(""" +line 1, column 5 of foo.dart: oh no +foo bar baz + ^""")); + }); + + test("works for a point span at the end of a line", () { + expect(file.location(11).pointSpan().message("oh no"), equals(""" +line 1, column 12 of foo.dart: oh no +foo bar baz + ^""")); + }); + + test("works for a point span at the end of the file", () { + expect(file.location(38).pointSpan().message("oh no"), equals(""" +line 3, column 12 of foo.dart: oh no +zip zap zop + ^""")); + }); + + test("works for a point span in an empty file", () { + expect(new SourceFile("").location(0).pointSpan().message("oh no"), + equals(""" +line 1, column 1: oh no + +^""")); + }); + + test("works for a single-line file without a newline", () { + expect(new SourceFile("foo bar").span(0, 7).message("oh no"), + equals(""" +line 1, column 1: oh no +foo bar +^^^^^^^""")); + }); + + group("colors", () { + test("doesn't colorize if color is false", () { + expect(file.span(4, 7).message("oh no", color: false), equals(""" +line 1, column 5 of foo.dart: oh no +foo bar baz + ^^^""")); + }); + + test("colorizes if color is true", () { + expect(file.span(4, 7).message("oh no", color: true), equals(""" +line 1, column 5 of foo.dart: oh no +foo ${colors.RED}bar${colors.NONE} baz + ${colors.RED}^^^${colors.NONE}""")); + }); + + test("uses the given color if it's passed", () { + expect(file.span(4, 7).message("oh no", color: colors.YELLOW), equals(""" +line 1, column 5 of foo.dart: oh no +foo ${colors.YELLOW}bar${colors.NONE} baz + ${colors.YELLOW}^^^${colors.NONE}""")); + }); + }); +} diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart new file mode 100644 index 000000000..114a17e44 --- /dev/null +++ b/pkgs/source_span/test/file_test.dart @@ -0,0 +1,370 @@ +// Copyright (c) 2014, 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:unittest/unittest.dart'; +import 'package:source_span/source_span.dart'; + +main() { + var file; + setUp(() { + file = new SourceFile(""" +foo bar baz +whiz bang boom +zip zap zop""", url: "foo.dart"); + }); + + group("errors", () { + group("for span()", () { + test("end must come after start", () { + expect(() => file.span(10, 5), throwsArgumentError); + }); + + test("start may not be negative", () { + expect(() => file.span(-1, 5), throwsRangeError); + }); + + test("end may not be outside the file", () { + expect(() => file.span(10, 100), throwsRangeError); + }); + }); + + group("for location()", () { + test("offset may not be negative", () { + expect(() => file.location(-1), throwsRangeError); + }); + + test("offset may not be outside the file", () { + expect(() => file.location(100), throwsRangeError); + }); + }); + + group("for getLine()", () { + test("offset may not be negative", () { + expect(() => file.getLine(-1), throwsRangeError); + }); + + test("offset may not be outside the file", () { + expect(() => file.getLine(100), throwsRangeError); + }); + }); + + group("for getColumn()", () { + test("offset may not be negative", () { + expect(() => file.getColumn(-1), throwsRangeError); + }); + + test("offset may not be outside the file", () { + expect(() => file.getColumn(100), throwsRangeError); + }); + + test("line may not be negative", () { + expect(() => file.getColumn(1, line: -1), throwsRangeError); + }); + + test("line may not be outside the file", () { + expect(() => file.getColumn(1, line: 100), throwsRangeError); + }); + + test("line must be accurate", () { + expect(() => file.getColumn(1, line: 1), throwsRangeError); + }); + }); + + group("getOffset()", () { + test("line may not be negative", () { + expect(() => file.getOffset(-1), throwsRangeError); + }); + + test("column may not be negative", () { + expect(() => file.getOffset(1, -1), throwsRangeError); + }); + + test("line may not be outside the file", () { + expect(() => file.getOffset(100), throwsRangeError); + }); + + test("column may not be outside the file", () { + expect(() => file.getOffset(2, 100), throwsRangeError); + }); + + test("column may not be outside the line", () { + expect(() => file.getOffset(1, 20), throwsRangeError); + }); + }); + + group("for getText()", () { + test("end must come after start", () { + expect(() => file.getText(10, 5), throwsArgumentError); + }); + + test("start may not be negative", () { + expect(() => file.getText(-1, 5), throwsRangeError); + }); + + test("end may not be outside the file", () { + expect(() => file.getText(10, 100), throwsRangeError); + }); + }); + + group("for span().union()", () { + test("source URLs must match", () { + var other = new SourceSpan( + new SourceLocation(10), new SourceLocation(11), "_"); + + expect(() => file.span(9, 10).union(other), throwsArgumentError); + }); + + test("spans may not be disjoint", () { + expect(() => file.span(9, 10).union(file.span(11, 12)), + throwsArgumentError); + }); + }); + + test("for span().expand() source URLs must match", () { + var other = new SourceFile(""" +foo bar baz +whiz bang boom +zip zap zop""", url: "bar.dart").span(10, 11); + + expect(() => file.span(9, 10).expand(other), throwsArgumentError); + }); + }); + + test('fields work correctly', () { + expect(file.url, equals(Uri.parse("foo.dart"))); + expect(file.lines, equals(3)); + expect(file.length, equals(38)); + }); + + group("new SourceFile()", () { + test("handles CRLF correctly", () { + expect(new SourceFile("foo\r\nbar").getLine(6), equals(1)); + }); + + test("handles a lone CR correctly", () { + expect(new SourceFile("foo\rbar").getLine(5), equals(1)); + }); + }); + + group("span()", () { + test("returns a span between the given offsets", () { + var span = file.span(5, 10); + expect(span.start, equals(file.location(5))); + expect(span.end, equals(file.location(10))); + }); + + test("end defaults to the end of the file", () { + var span = file.span(5); + expect(span.start, equals(file.location(5))); + expect(span.end, equals(file.location(file.length - 1))); + }); + }); + + group("getLine()", () { + test("works for a middle character on the line", () { + expect(file.getLine(15), equals(1)); + }); + + test("works for the first character of a line", () { + expect(file.getLine(12), equals(1)); + }); + + test("works for a newline character", () { + expect(file.getLine(11), equals(0)); + }); + + test("works for the last offset", () { + expect(file.getLine(file.length), equals(2)); + }); + }); + + group("getColumn()", () { + test("works for a middle character on the line", () { + expect(file.getColumn(15), equals(3)); + }); + + test("works for the first character of a line", () { + expect(file.getColumn(12), equals(0)); + }); + + test("works for a newline character", () { + expect(file.getColumn(11), equals(11)); + }); + + test("works when line is passed as well", () { + expect(file.getColumn(12, line: 1), equals(0)); + }); + + test("works for the last offset", () { + expect(file.getColumn(file.length), equals(11)); + }); + }); + + group("getOffset()", () { + test("works for a middle character on the line", () { + expect(file.getOffset(1, 3), equals(15)); + }); + + test("works for the first character of a line", () { + expect(file.getOffset(1), equals(12)); + }); + + test("works for a newline character", () { + expect(file.getOffset(0, 11), equals(11)); + }); + + test("works for the last offset", () { + expect(file.getOffset(2, 11), equals(file.length)); + }); + }); + + group("getText()", () { + test("returns a substring of the source", () { + expect(file.getText(8, 15), equals("baz\nwhi")); + }); + + test("end defaults to the end of the file", () { + expect(file.getText(20), equals("g boom\nzip zap zop")); + }); + }); + + group("FileLocation", () { + test("reports the correct line number", () { + expect(file.location(15).line, equals(1)); + }); + + test("reports the correct column number", () { + expect(file.location(15).column, equals(3)); + }); + + test("pointSpan() returns a FileSpan", () { + var location = file.location(15); + var span = location.pointSpan(); + expect(span, new isInstanceOf()); + expect(span.start, equals(location)); + expect(span.end, equals(location)); + expect(span.text, isEmpty); + }); + }); + + group("FileSpan", () { + test("text returns a substring of the source", () { + expect(file.span(8, 15).text, equals("baz\nwhi")); + }); + + group("union()", () { + var span; + setUp(() { + span = file.span(5, 12); + }); + + test("works with a preceding adjacent span", () { + var other = file.span(0, 5); + var result = span.union(other); + expect(result.start, equals(other.start)); + expect(result.end, equals(span.end)); + expect(result.text, equals("foo bar baz\n")); + }); + + test("works with a preceding overlapping span", () { + var other = file.span(0, 8); + var result = span.union(other); + expect(result.start, equals(other.start)); + expect(result.end, equals(span.end)); + expect(result.text, equals("foo bar baz\n")); + }); + + test("works with a following adjacent span", () { + var other = file.span(12, 16); + var result = span.union(other); + expect(result.start, equals(span.start)); + expect(result.end, equals(other.end)); + expect(result.text, equals("ar baz\nwhiz")); + }); + + test("works with a following overlapping span", () { + var other = file.span(9, 16); + var result = span.union(other); + expect(result.start, equals(span.start)); + expect(result.end, equals(other.end)); + expect(result.text, equals("ar baz\nwhiz")); + }); + + test("works with an internal overlapping span", () { + var other = file.span(7, 10); + expect(span.union(other), equals(span)); + }); + + test("works with an external overlapping span", () { + var other = file.span(0, 16); + expect(span.union(other), equals(other)); + }); + + test("returns a FileSpan for a FileSpan input", () { + expect(span.union(file.span(0, 5)), new isInstanceOf()); + }); + + test("returns a base SourceSpan for a SourceSpan input", () { + var other = new SourceSpan( + new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(5, sourceUrl: "foo.dart"), + "hey, "); + var result = span.union(other); + expect(result, isNot(new isInstanceOf())); + expect(result.start, equals(other.start)); + expect(result.end, equals(span.end)); + expect(result.text, equals("hey, ar baz\n")); + }); + }); + + group("expand()", () { + var span; + setUp(() { + span = file.span(5, 12); + }); + + test("works with a preceding nonadjacent span", () { + var other = file.span(0, 3); + var result = span.expand(other); + expect(result.start, equals(other.start)); + expect(result.end, equals(span.end)); + expect(result.text, equals("foo bar baz\n")); + }); + + test("works with a preceding overlapping span", () { + var other = file.span(0, 8); + var result = span.expand(other); + expect(result.start, equals(other.start)); + expect(result.end, equals(span.end)); + expect(result.text, equals("foo bar baz\n")); + }); + + test("works with a following nonadjacent span", () { + var other = file.span(14, 16); + var result = span.expand(other); + expect(result.start, equals(span.start)); + expect(result.end, equals(other.end)); + expect(result.text, equals("ar baz\nwhiz")); + }); + + test("works with a following overlapping span", () { + var other = file.span(9, 16); + var result = span.expand(other); + expect(result.start, equals(span.start)); + expect(result.end, equals(other.end)); + expect(result.text, equals("ar baz\nwhiz")); + }); + + test("works with an internal overlapping span", () { + var other = file.span(7, 10); + expect(span.expand(other), equals(span)); + }); + + test("works with an external overlapping span", () { + var other = file.span(0, 16); + expect(span.expand(other), equals(other)); + }); + }); + }); +} \ No newline at end of file diff --git a/pkgs/source_span/test/location_test.dart b/pkgs/source_span/test/location_test.dart new file mode 100644 index 000000000..1eedec43a --- /dev/null +++ b/pkgs/source_span/test/location_test.dart @@ -0,0 +1,101 @@ +// Copyright (c) 2014, 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:unittest/unittest.dart'; +import 'package:source_span/source_span.dart'; + +main() { + var location; + setUp(() { + location = new SourceLocation(15, + line: 2, column: 6, sourceUrl: "foo.dart"); + }); + + group('errors', () { + group('for new SourceLocation()', () { + test('offset may not be negative', () { + expect(() => new SourceLocation(-1), throwsRangeError); + }); + + test('line may not be negative', () { + expect(() => new SourceLocation(0, line: -1), throwsRangeError); + }); + + test('column may not be negative', () { + expect(() => new SourceLocation(0, column: -1), throwsRangeError); + }); + }); + + test('for distance() source URLs must match', () { + expect(() => location.distance(new SourceLocation(0)), + throwsArgumentError); + }); + + test('for compareTo() source URLs must match', () { + expect(() => location.compareTo(new SourceLocation(0)), + throwsArgumentError); + }); + }); + + test('fields work correctly', () { + expect(location.sourceUrl, equals(Uri.parse("foo.dart"))); + expect(location.offset, equals(15)); + expect(location.line, equals(2)); + expect(location.column, equals(6)); + }); + + group('toolString', () { + test('returns a computer-readable representation', () { + expect(location.toolString, equals('foo.dart:3:7')); + }); + + test('gracefully handles a missing source URL', () { + var location = new SourceLocation(15, line: 2, column: 6); + expect(location.toolString, equals('unknown source:3:7')); + }); + }); + + test("distance returns the absolute distance between locations", () { + var other = new SourceLocation(10, sourceUrl: "foo.dart"); + expect(location.distance(other), equals(5)); + expect(other.distance(location), equals(5)); + }); + + test("pointSpan returns an empty span at location", () { + var span = location.pointSpan(); + expect(span.start, equals(location)); + expect(span.end, equals(location)); + expect(span.text, isEmpty); + }); + + group("compareTo()", () { + test("sorts by offset", () { + var other = new SourceLocation(20, sourceUrl: "foo.dart"); + expect(location.compareTo(other), lessThan(0)); + expect(other.compareTo(location), greaterThan(0)); + }); + + test("considers equal locations equal", () { + expect(location.compareTo(location), equals(0)); + }); + }); + + + group("equality", () { + test("two locations with the same offset and source are equal", () { + var other = new SourceLocation(15, sourceUrl: "foo.dart"); + expect(location, equals(other)); + }); + + test("a different offset isn't equal", () { + var other = new SourceLocation(10, sourceUrl: "foo.dart"); + expect(location, isNot(equals(other))); + }); + + test("a different source isn't equal", () { + var other = new SourceLocation(15, sourceUrl: "bar.dart"); + expect(location, isNot(equals(other))); + }); + }); +} diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart new file mode 100644 index 000000000..c62753b1a --- /dev/null +++ b/pkgs/source_span/test/span_test.dart @@ -0,0 +1,256 @@ +// Copyright (c) 2014, 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:unittest/unittest.dart'; +import 'package:source_span/source_span.dart'; +import 'package:source_span/src/colors.dart' as colors; + +main() { + var span; + setUp(() { + span = new SourceSpan( + new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(12, sourceUrl: "foo.dart"), + "foo bar"); + }); + + group('errors', () { + group('for new SourceSpan()', () { + test('source URLs must match', () { + var start = new SourceLocation(0, sourceUrl: "foo.dart"); + var end = new SourceLocation(1, sourceUrl: "bar.dart"); + expect(() => new SourceSpan(start, end, "_"), throwsArgumentError); + }); + + test('end must come after start', () { + var start = new SourceLocation(1); + var end = new SourceLocation(0); + expect(() => new SourceSpan(start, end, "_"), throwsArgumentError); + }); + + test('text must be the right length', () { + var start = new SourceLocation(0); + var end = new SourceLocation(1); + expect(() => new SourceSpan(start, end, "abc"), throwsArgumentError); + }); + }); + + group('for union()', () { + test('source URLs must match', () { + var other = new SourceSpan( + new SourceLocation(12, sourceUrl: "bar.dart"), + new SourceLocation(13, sourceUrl: "bar.dart"), + "_"); + + expect(() => span.union(other), throwsArgumentError); + }); + + test('spans may not be disjoint', () { + var other = new SourceSpan( + new SourceLocation(13, sourceUrl: 'foo.dart'), + new SourceLocation(14, sourceUrl: 'foo.dart'), + "_"); + + expect(() => span.union(other), throwsArgumentError); + }); + }); + + test('for compareTo() source URLs must match', () { + var other = new SourceSpan( + new SourceLocation(12, sourceUrl: "bar.dart"), + new SourceLocation(13, sourceUrl: "bar.dart"), + "_"); + + expect(() => span.compareTo(other), throwsArgumentError); + }); + }); + + test('fields work correctly', () { + expect(span.start, equals(new SourceLocation(5, sourceUrl: "foo.dart"))); + expect(span.end, equals(new SourceLocation(12, sourceUrl: "foo.dart"))); + expect(span.sourceUrl, equals(Uri.parse("foo.dart"))); + expect(span.length, equals(7)); + }); + + group("union()", () { + test("works with a preceding adjacent span", () { + var other = new SourceSpan( + new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(5, sourceUrl: "foo.dart"), + "hey, "); + + var result = span.union(other); + expect(result.start, equals(other.start)); + expect(result.end, equals(span.end)); + expect(result.text, equals("hey, foo bar")); + }); + + test("works with a preceding overlapping span", () { + var other = new SourceSpan( + new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(8, sourceUrl: "foo.dart"), + "hey, foo"); + + var result = span.union(other); + expect(result.start, equals(other.start)); + expect(result.end, equals(span.end)); + expect(result.text, equals("hey, foo bar")); + }); + + test("works with a following adjacent span", () { + var other = new SourceSpan( + new SourceLocation(12, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), + " baz"); + + var result = span.union(other); + expect(result.start, equals(span.start)); + expect(result.end, equals(other.end)); + expect(result.text, equals("foo bar baz")); + }); + + test("works with a following overlapping span", () { + var other = new SourceSpan( + new SourceLocation(9, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), + "bar baz"); + + var result = span.union(other); + expect(result.start, equals(span.start)); + expect(result.end, equals(other.end)); + expect(result.text, equals("foo bar baz")); + }); + + test("works with an internal overlapping span", () { + var other = new SourceSpan( + new SourceLocation(7, sourceUrl: "foo.dart"), + new SourceLocation(10, sourceUrl: "foo.dart"), + "o b"); + + expect(span.union(other), equals(span)); + }); + + test("works with an external overlapping span", () { + var other = new SourceSpan( + new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), + "hey, foo bar baz"); + + expect(span.union(other), equals(other)); + }); + }); + + group("message()", () { + test("prints the text being described", () { + expect(span.message("oh no"), equals(""" +line 1, column 6 of foo.dart: oh no +foo bar +^^^^^^^""")); + }); + + test("gracefully handles a missing source URL", () { + var span = new SourceSpan( + new SourceLocation(5), new SourceLocation(12), "foo bar"); + + expect(span.message("oh no"), equalsIgnoringWhitespace(""" +line 1, column 6: oh no +foo bar +^^^^^^^""")); + }); + + test("gracefully handles empty text", () { + var span = new SourceSpan( + new SourceLocation(5), new SourceLocation(5), ""); + + expect(span.message("oh no"), + equals("line 1, column 6: oh no")); + }); + + test("doesn't colorize if color is false", () { + expect(span.message("oh no", color: false), equals(""" +line 1, column 6 of foo.dart: oh no +foo bar +^^^^^^^""")); + }); + + test("colorizes if color is true", () { + expect(span.message("oh no", color: true), + equals(""" +line 1, column 6 of foo.dart: oh no +${colors.RED}foo bar +^^^^^^^${colors.NONE}""")); + }); + + test("uses the given color if it's passed", () { + expect(span.message("oh no", color: colors.YELLOW), equals(""" +line 1, column 6 of foo.dart: oh no +${colors.YELLOW}foo bar +^^^^^^^${colors.NONE}""")); + }); + }); + + group("compareTo()", () { + test("sorts by start location first", () { + var other = new SourceSpan( + new SourceLocation(6, sourceUrl: "foo.dart"), + new SourceLocation(14, sourceUrl: "foo.dart"), + "oo bar b"); + + expect(span.compareTo(other), lessThan(0)); + expect(other.compareTo(span), greaterThan(0)); + }); + + test("sorts by length second", () { + var other = new SourceSpan( + new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(14, sourceUrl: "foo.dart"), + "foo bar b"); + + expect(span.compareTo(other), lessThan(0)); + expect(other.compareTo(span), greaterThan(0)); + }); + + test("considers equal spans equal", () { + expect(span.compareTo(span), equals(0)); + }); + }); + + group("equality", () { + test("two spans with the same locations are equal", () { + var other = new SourceSpan( + new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(12, sourceUrl: "foo.dart"), + "foo bar"); + + expect(span, equals(other)); + }); + + test("a different start isn't equal", () { + var other = new SourceSpan( + new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(12, sourceUrl: "foo.dart"), + "hey, foo bar"); + + expect(span, isNot(equals(other))); + }); + + test("a different end isn't equal", () { + var other = new SourceSpan( + new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), + "foo bar baz"); + + expect(span, isNot(equals(other))); + }); + + test("a different source URL isn't equal", () { + var other = new SourceSpan( + new SourceLocation(5, sourceUrl: "bar.dart"), + new SourceLocation(12, sourceUrl: "bar.dart"), + "foo bar"); + + expect(span, isNot(equals(other))); + }); + }); +} diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart new file mode 100644 index 000000000..39211111e --- /dev/null +++ b/pkgs/source_span/test/utils_test.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2013, 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:unittest/unittest.dart'; +import 'package:source_span/src/utils.dart'; + +main() { + group('binary search', () { + test('empty', () { + expect(binarySearch([], (x) => true), -1); + }); + + test('single element', () { + expect(binarySearch([1], (x) => true), 0); + expect(binarySearch([1], (x) => false), 1); + }); + + test('no matches', () { + var list = [1, 2, 3, 4, 5, 6, 7]; + expect(binarySearch(list, (x) => false), list.length); + }); + + test('all match', () { + var list = [1, 2, 3, 4, 5, 6, 7]; + expect(binarySearch(list, (x) => true), 0); + }); + + test('compare with linear search', () { + for (int size = 0; size < 100; size++) { + var list = []; + for (int i = 0; i < size; i++) { + list.add(i); + } + for (int pos = 0; pos <= size; pos++) { + expect(binarySearch(list, (x) => x >= pos), + _linearSearch(list, (x) => x >= pos)); + } + } + }); + }); +} + +_linearSearch(list, predicate) { + if (list.length == 0) return -1; + for (int i = 0; i < list.length; i++) { + if (predicate(list[i])) return i; + } + return list.length; +} + From be186a1d45c9112ab448785bb40bb909b55b9bfa Mon Sep 17 00:00:00 2001 From: "lrn@google.com" Date: Fri, 18 Jul 2014 08:22:32 +0000 Subject: [PATCH 034/657] Change "FormatException.position" to be named "offset". Address comments on SpanFormatException changes. R=nweiz@google.com Review URL: https://codereview.chromium.org//396603003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38373 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/lib/span.dart | 7 ++++--- pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 7767fc145..c52d585d4 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +* Update `SpanFormatException` with `source` and `offset`. + ## 0.9.3 * Support writing SingleMapping objects to source map version 3 format. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 771e9e0ef..7b513e6be 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -385,9 +385,10 @@ class SpanException implements Exception { /// A [SpanException] that's also a [FormatException]. class SpanFormatException extends SpanException implements FormatException { - SpanFormatException(String message, Span span) + final source; + + SpanFormatException(String message, Span span, [this.source]) : super(message, span); - get source => null; - int get position => null; + int get position => span == null ? null : span.start.offset; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index ae0323d0c..c5029e2d9 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -7,7 +7,7 @@ name: source_maps # # When the minor version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 0.9.3 +version: 0.9.4 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From af4e166a34eb68e0f7ead74803b662281ddb3b0e Mon Sep 17 00:00:00 2001 From: "lrn@google.com" Date: Fri, 18 Jul 2014 08:57:34 +0000 Subject: [PATCH 035/657] Use the new "offset" name in span.dart too. Review URL: https://codereview.chromium.org//397343005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38376 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/span.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 7b513e6be..b546a97aa 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -390,5 +390,5 @@ class SpanFormatException extends SpanException implements FormatException { SpanFormatException(String message, Span span, [this.source]) : super(message, span); - int get position => span == null ? null : span.start.offset; + int get offset => span == null ? null : span.start.offset; } From b3e5fcea34ecb57d46fd0e2467612e9d1df7550f Mon Sep 17 00:00:00 2001 From: "lrn@google.com" Date: Fri, 18 Jul 2014 09:22:58 +0000 Subject: [PATCH 036/657] Change "FormatException.position" to be named "offset". Address comments on SpanFormatException changes. R=nweiz@google.com Committed: https://code.google.com/p/dart/source/detail?r=38373 Review URL: https://codereview.chromium.org//396603003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38378 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 4 ---- pkgs/source_maps/lib/span.dart | 7 +++---- pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index c52d585d4..7767fc145 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.9.4 - -* Update `SpanFormatException` with `source` and `offset`. - ## 0.9.3 * Support writing SingleMapping objects to source map version 3 format. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index b546a97aa..771e9e0ef 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -385,10 +385,9 @@ class SpanException implements Exception { /// A [SpanException] that's also a [FormatException]. class SpanFormatException extends SpanException implements FormatException { - final source; - - SpanFormatException(String message, Span span, [this.source]) + SpanFormatException(String message, Span span) : super(message, span); - int get offset => span == null ? null : span.start.offset; + get source => null; + int get position => null; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index c5029e2d9..ae0323d0c 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -7,7 +7,7 @@ name: source_maps # # When the minor version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 0.9.4 +version: 0.9.3 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 3928ed938e6a4c4c937cb5885d39aa5d3b1078b9 Mon Sep 17 00:00:00 2001 From: "lrn@google.com" Date: Fri, 18 Jul 2014 09:25:48 +0000 Subject: [PATCH 037/657] Change "FormatException.position" to be named "offset". Address comments on SpanFormatException changes. R=nweiz@google.com Committed: https://code.google.com/p/dart/source/detail?r=38373 Committed: https://code.google.com/p/dart/source/detail?r=38378 Review URL: https://codereview.chromium.org//396603003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38379 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/lib/span.dart | 7 ++++--- pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 7767fc145..c52d585d4 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.9.4 + +* Update `SpanFormatException` with `source` and `offset`. + ## 0.9.3 * Support writing SingleMapping objects to source map version 3 format. diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index 771e9e0ef..b546a97aa 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -385,9 +385,10 @@ class SpanException implements Exception { /// A [SpanException] that's also a [FormatException]. class SpanFormatException extends SpanException implements FormatException { - SpanFormatException(String message, Span span) + final source; + + SpanFormatException(String message, Span span, [this.source]) : super(message, span); - get source => null; - int get position => null; + int get offset => span == null ? null : span.start.offset; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index ae0323d0c..c5029e2d9 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -7,7 +7,7 @@ name: source_maps # # When the minor version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 0.9.3 +version: 0.9.4 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 4990ab23d701848fae0e800399042d671307706c Mon Sep 17 00:00:00 2001 From: "lrn@google.com" Date: Fri, 18 Jul 2014 09:25:48 +0000 Subject: [PATCH 038/657] Change "FormatException.position" to be named "offset". Address comments on SpanFormatException changes. R=nweiz@google.com Committed: https://code.google.com/p/dart/source/detail?r=38373 Committed: https://code.google.com/p/dart/source/detail?r=38378 Review URL: https://codereview.chromium.org//396603003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_span@38379 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_span/lib/src/span_exception.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index af642413b..36f248832 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -36,7 +36,7 @@ class SourceSpanFormatException extends SourceSpanException implements FormatException { final source; - int get position => span == null ? null : span.start.offset; + int get offset => span == null ? null : span.start.offset; SourceSpanFormatException(String message, SourceSpan span, [this.source]) : super(message, span); From 333a0e54f9c449864fed175ecece66e075385632 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 23 Jul 2014 23:17:23 +0000 Subject: [PATCH 039/657] Deprecate the source_maps span classes. This also updates source_maps to take the new classes where possible. BUG=19930 R=sigmund@google.com Review URL: https://codereview.chromium.org//402843003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38524 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 4 + pkgs/source_maps/lib/builder.dart | 37 ++++++++-- pkgs/source_maps/lib/parser.dart | 26 +++++-- pkgs/source_maps/lib/printer.dart | 30 +++++--- pkgs/source_maps/lib/refactor.dart | 9 ++- pkgs/source_maps/lib/span.dart | 10 +++ pkgs/source_maps/lib/src/span_wrapper.dart | 85 ++++++++++++++++++++++ pkgs/source_maps/pubspec.yaml | 3 +- 8 files changed, 180 insertions(+), 24 deletions(-) create mode 100644 pkgs/source_maps/lib/src/span_wrapper.dart diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index c52d585d4..6d371c9bf 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -2,6 +2,10 @@ * Update `SpanFormatException` with `source` and `offset`. +* All methods that take `Span`s, `Location`s, and `SourceFile`s as inputs now + also accept the corresponding `source_span` classes as well. Using the old + classes is now deprecated and will be unsupported in version 0.10.0. + ## 0.9.3 * Support writing SingleMapping objects to source map version 3 format. diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index cd30ccb94..494a6b6e9 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -11,6 +11,7 @@ import 'dart:convert'; import 'parser.dart'; import 'span.dart'; +import 'src/span_wrapper.dart'; /// Builds a source map given a set of mappings. class SourceMapBuilder { @@ -18,8 +19,10 @@ class SourceMapBuilder { final List _entries = []; /// Adds an entry mapping the [targetOffset] to [source]. - void addFromOffset(Location source, - SourceFile targetFile, int targetOffset, String identifier) { + /// + /// [source] can be either a [Location] or a [SourceLocation]. Using a + /// [Location] is deprecated and will be unsupported in version 0.10.0. + void addFromOffset(source, targetFile, int targetOffset, String identifier) { if (targetFile == null) { throw new ArgumentError('targetFile cannot be null'); } @@ -28,12 +31,27 @@ class SourceMapBuilder { } /// Adds an entry mapping [target] to [source]. - void addSpan(Span source, Span target) { - var name = source.isIdentifier ? source.text : null; + /// + /// [source] and [target] can be either a [Span] or a [SourceSpan]. Using a + /// [Span] is deprecated and will be unsupported in version 0.10.0. + /// + /// If [isIdentifier] is true, this entry is considered to represent an + /// identifier whose value will be stored in the source map. + void addSpan(source, target, {bool isIdentifier}) { + source = SpanWrapper.wrap(source); + target = SpanWrapper.wrap(target); + if (isIdentifier == null) isIdentifier = source.isIdentifier; + + var name = isIdentifier ? source.text : null; _entries.add(new Entry(source.start, target.start, name)); } - void addLocation(Location source, Location target, String identifier) { + /// Adds an entry mapping [target] to [source]. + /// + /// [source] and [target] can be either a [Location] or a [SourceLocation]. + /// Using a [Location] is deprecated and will be unsupported in version + /// 0.10.0. + void addLocation(source, target, String identifier) { _entries.add(new Entry(source, target, identifier)); } @@ -57,7 +75,14 @@ class Entry implements Comparable { /// An identifier name, when this location is the start of an identifier. final String identifierName; - Entry(this.source, this.target, this.identifierName); + /// Creates a new [Entry] mapping [target] to [source]. + /// + /// [source] and [target] can be either a [Location] or a [SourceLocation]. + /// Using a [Location] is deprecated and will be unsupported in version + /// 0.10.0. + Entry(source, target, this.identifierName) + : source = LocationWrapper.wrap(source), + target = LocationWrapper.wrap(target); /// Implements [Comparable] to ensure that entries are ordered by their /// location in the target file. We sort primarily by the target offset diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 3fd0d1445..c18a1d69b 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -10,6 +10,7 @@ import 'dart:convert'; import 'builder.dart' as builder; import 'span.dart'; +import 'src/span_wrapper.dart'; import 'src/utils.dart'; import 'src/vlq.dart'; @@ -47,10 +48,21 @@ Mapping parseJson(Map map, {Map otherMaps}) { /// A mapping parsed out of a source map. abstract class Mapping { - Span spanFor(int line, int column, {Map files}); - - Span spanForLocation(Location loc, {Map files}) { - return spanFor(loc.line, loc.column, files: files); + /// Returns the span associated with [line] and [column]. + /// + /// The values of [files] can be either `source_map` [SourceFile]s or + /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is + /// deprecated and will be unsupported in version 0.10.0. + Span spanFor(int line, int column, {Map files}); + + /// Returns the span associated with [location]. + /// + /// The values of [files] may be either `source_map` [SourceFile]s or + /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is + /// deprecated and will be unsupported in version 0.10.0. + Span spanForLocation(location, {Map files}) { + location = LocationWrapper.wrap(location); + return spanFor(location.line, location.column, files: files); } } @@ -112,7 +124,7 @@ class MultiSectionMapping extends Mapping { return _lineStart.length - 1; } - Span spanFor(int line, int column, {Map files}) { + Span spanFor(int line, int column, {Map files}) { int index = _indexFor(line, column); return _maps[index].spanFor( line - _lineStart[index], column - _columnStart[index], files: files); @@ -351,7 +363,7 @@ class SingleMapping extends Mapping { return (index <= 0) ? null : entries[index - 1]; } - Span spanFor(int line, int column, {Map files}) { + Span spanFor(int line, int column, {Map files}) { var entry = _findColumn(line, column, _findLine(line)); if (entry == null || entry.sourceUrlId == null) return null; var url = urls[entry.sourceUrlId]; @@ -359,7 +371,7 @@ class SingleMapping extends Mapping { url = '${sourceRoot}${url}'; } if (files != null && files[url] != null) { - var file = files[url]; + var file = SourceFileWrapper.wrap(files[url]); var start = file.getOffset(entry.sourceLine, entry.sourceColumn); if (entry.sourceNameId != null) { var text = names[entry.sourceNameId]; diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 0898017c4..aa18bd764 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -5,8 +5,11 @@ /// Contains a code printer that generates code by recording the source maps. library source_maps.printer; +import 'package:source_span/source_span.dart' as source_span; + import 'builder.dart'; import 'span.dart'; +import 'src/span_wrapper.dart'; const int _LF = 10; const int _CR = 13; @@ -75,9 +78,10 @@ class Printer { void mark(mark) { var loc; var identifier = null; - if (mark is Location) { - loc = mark; - } else if (mark is Span) { + if (mark is Location || mark is source_span.SourceLocation) { + loc = LocationWrapper.wrap(mark); + } else if (mark is Span || mark is source_span.SourceSpan) { + mark = SpanWrapper.wrap(mark); loc = mark.start; if (mark.isIdentifier) identifier = mark.text; } @@ -124,15 +128,19 @@ class NestedPrinter implements NestedItem { /// location of [object] in the original input. Only one, [location] or /// [span], should be provided at a time. /// + /// [location] can be either a [Location] or a [SourceLocation]. [span] can be + /// either a [Span] or a [SourceSpan]. Using a [Location] or a [Span] is + /// deprecated and will be unsupported in version 0.10.0. + /// /// Indicate [isOriginal] when [object] is copied directly from the user code. /// Setting [isOriginal] will make this printer propagate source map locations /// on every line-break. - void add(object, {Location location, Span span, bool isOriginal: false}) { + void add(object, {location, span, bool isOriginal: false}) { if (object is! String || location != null || span != null || isOriginal) { _flush(); assert(location == null || span == null); - if (location != null) _items.add(location); - if (span != null) _items.add(span); + if (location != null) _items.add(LocationWrapper.wrap(location)); + if (span != null) _items.add(SpanWrapper.wrap(span)); if (isOriginal) _items.add(_ORIGINAL); } @@ -156,12 +164,16 @@ class NestedPrinter implements NestedItem { /// The [location] and [span] parameters indicate the corresponding source map /// location of [object] in the original input. Only one, [location] or /// [span], should be provided at a time. - void addLine(String line, {Location location, Span span}) { + /// + /// [location] can be either a [Location] or a [SourceLocation]. [span] can be + /// either a [Span] or a [SourceSpan]. Using a [Location] or a [Span] is + /// deprecated and will be unsupported in version 0.10.0. + void addLine(String line, {location, span}) { if (location != null || span != null) { _flush(); assert(location == null || span == null); - if (location != null) _items.add(location); - if (span != null) _items.add(span); + if (location != null) _items.add(LocationWrapper.wrap(location)); + if (span != null) _items.add(SpanWrapper.wrap(span)); } if (line == null) return; if (line != '') { diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 45fb06949..47ce2ed90 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -10,6 +10,7 @@ library source_maps.refactor; import 'span.dart'; import 'printer.dart'; +import 'src/span_wrapper.dart'; /// Editable text transaction. /// @@ -20,7 +21,13 @@ class TextEditTransaction { final String original; final _edits = <_TextEdit>[]; - TextEditTransaction(this.original, this.file); + /// Creates a new transaction. + /// + /// [file] can be either a `source_map` [SourceFile] or a `source_span` + /// `SourceFile`. Using a `source_map` [SourceFile] is deprecated and will be + /// unsupported in version 0.10.0. + TextEditTransaction(this.original, file) + : file = SourceFileWrapper.wrap(file); bool get hasEdits => _edits.length > 0; diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart index b546a97aa..a21e893b7 100644 --- a/pkgs/source_maps/lib/span.dart +++ b/pkgs/source_maps/lib/span.dart @@ -12,6 +12,7 @@ import 'package:path/path.dart' as p; import 'src/utils.dart'; /// A simple class that describe a segment of source text. +@Deprecated("Use the source_span package instead.") abstract class Span implements Comparable { /// The start location of this span. final Location start; @@ -79,6 +80,7 @@ abstract class Span implements Comparable { } /// A location in the source text +@Deprecated("Use the source_span package instead.") abstract class Location implements Comparable { /// Url of the source containing this span. String get sourceUrl; @@ -113,6 +115,7 @@ abstract class Location implements Comparable { } /// Implementation of [Location] with fixed values given at allocation time. +@Deprecated("Use the source_span package instead.") class FixedLocation extends Location { final String sourceUrl; final int line; @@ -123,6 +126,7 @@ class FixedLocation extends Location { } /// Implementation of [Span] where all the values are given at allocation time. +@Deprecated("Use the source_span package instead.") class FixedSpan extends Span { /// The source text for this span, if available. final String text; @@ -137,6 +141,7 @@ class FixedSpan extends Span { } /// [Location] with values computed from an underling [SourceFile]. +@Deprecated("Use the source_span package instead.") class FileLocation extends Location { /// The source file containing this location. final SourceFile file; @@ -149,6 +154,7 @@ class FileLocation extends Location { } /// [Span] where values are computed from an underling [SourceFile]. +@Deprecated("Use the source_span package instead.") class FileSpan extends Span { /// The source file containing this span. final SourceFile file; @@ -195,6 +201,7 @@ const String _NO_COLOR = '\u001b[0m'; /// Stores information about a source file, to permit computation of the line /// and column. Also contains a nice default error message highlighting the code /// location. +@Deprecated("Use the source_span package instead.") class SourceFile { /// Url where the source file is located. final String url; @@ -306,6 +313,7 @@ class SourceFile { /// allows you to set source-map locations based on the locations relative to /// the start of the segment, but that get translated to absolute locations in /// the original source file. +@Deprecated("Use the source_span package instead.") class SourceFileSegment extends SourceFile { final int _baseOffset; final int _baseLine; @@ -365,6 +373,7 @@ class SourceFileSegment extends SourceFile { } /// A class for exceptions that have source span information attached. +@Deprecated("Use the source_span package instead.") class SpanException implements Exception { /// A message describing the exception. final String message; @@ -384,6 +393,7 @@ class SpanException implements Exception { } /// A [SpanException] that's also a [FormatException]. +@Deprecated("Use the source_span package instead.") class SpanFormatException extends SpanException implements FormatException { final source; diff --git a/pkgs/source_maps/lib/src/span_wrapper.dart b/pkgs/source_maps/lib/src/span_wrapper.dart new file mode 100644 index 000000000..e0c107bf7 --- /dev/null +++ b/pkgs/source_maps/lib/src/span_wrapper.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2014, 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. + +library source_maps.span_wrapper; + +import 'package:source_span/source_span.dart' as source_span; + +import '../span.dart'; + +/// A wrapper that exposes a [source_span.SourceSpan] as a [Span]. +class SpanWrapper extends Span { + final source_span.SourceSpan _inner; + + String get text => _inner.text; + + SpanWrapper(source_span.SourceSpan inner, bool isIdentifier) + : _inner = inner, + super( + new LocationWrapper(inner.start), + new LocationWrapper(inner.end), + isIdentifier); + + static Span wrap(span, [bool isIdentifier = false]) { + if (span is Span) return span; + return new SpanWrapper(span, isIdentifier); + } +} + +/// A wrapper that exposes a [source_span.SourceLocation] as a [Location]. +class LocationWrapper extends Location { + final source_span.SourceLocation _inner; + + String get sourceUrl => _inner.sourceUrl.toString(); + int get line => _inner.line; + int get column => _inner.column; + + LocationWrapper(source_span.SourceLocation inner) + : _inner = inner, + super(inner.offset); + + static Location wrap(location) { + if (location is Location) return location; + return new LocationWrapper(location); + } +} + +/// A wrapper that exposes a [source_span.SourceFile] as a [SourceFile]. +class SourceFileWrapper implements SourceFile { + final source_span.SourceFile _inner; + + // These are necessary to avoid analyzer warnings; + final _lineStarts = null; + final _decodedChars = null; + + String get url => _inner.url.toString(); + + SourceFileWrapper(this._inner); + + static SourceFile wrap(sourceFile) { + if (sourceFile is SourceFile) return sourceFile; + return new SourceFileWrapper(sourceFile); + } + + Span span(int start, [int end, bool isIdentifier = false]) { + if (end == null) end = start; + return new SpanWrapper(_inner.span(start, end), isIdentifier); + } + + Location location(int offset) => new LocationWrapper(_inner.location(offset)); + + int getLine(int offset) => _inner.getLine(offset); + + int getColumn(int line, int offset) => _inner.getColumn(offset, line: line); + + int getOffset(int line, int column) => _inner.getOffset(line, column); + + String getText(int start, [int end]) => _inner.getText(start, end); + + String getLocationMessage(String message, int start, int end, + {bool useColors: false, String color}) { + return span(start, end).getLocationMessage(message, + useColors: useColors, color: color); + } +} diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index c5029e2d9..0548215b1 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -7,12 +7,13 @@ name: source_maps # # When the minor version is upgraded, you *must* update that version constraint # in pub to stay in sync with this. -version: 0.9.4 +version: 0.9.4-dev author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org dependencies: path: '>=1.2.0 <2.0.0' + source_span: '>=1.0.0 <2.0.0' environment: sdk: '>=0.8.10+6 <2.0.0' dev_dependencies: From 1a9fed77c0e29e98d8c30151bce9cb5680e8b55c Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Wed, 23 Jul 2014 23:32:06 +0000 Subject: [PATCH 040/657] Move pub/barback's Pool class into its own package. R=rnystrom@google.com Review URL: https://codereview.chromium.org//399963004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/pool@38525 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/pool/LICENSE | 26 +++++++ pkgs/pool/README.md | 53 +++++++++++++ pkgs/pool/lib/pool.dart | 139 ++++++++++++++++++++++++++++++++++ pkgs/pool/pubspec.yaml | 7 ++ pkgs/pool/test/pool_test.dart | 137 +++++++++++++++++++++++++++++++++ 5 files changed, 362 insertions(+) create mode 100644 pkgs/pool/LICENSE create mode 100644 pkgs/pool/README.md create mode 100644 pkgs/pool/lib/pool.dart create mode 100644 pkgs/pool/pubspec.yaml create mode 100644 pkgs/pool/test/pool_test.dart diff --git a/pkgs/pool/LICENSE b/pkgs/pool/LICENSE new file mode 100644 index 000000000..5c60afea3 --- /dev/null +++ b/pkgs/pool/LICENSE @@ -0,0 +1,26 @@ +Copyright 2014, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkgs/pool/README.md b/pkgs/pool/README.md new file mode 100644 index 000000000..898728867 --- /dev/null +++ b/pkgs/pool/README.md @@ -0,0 +1,53 @@ +The pool package exposes a `Pool` class which makes it easy to manage a limited +pool of resources. + +The easiest way to use a pool is by calling `withResource`. This runs a callback +and returns its result, but only once there aren't too many other callbacks +currently running. + +```dart +// Create a Pool that will only allocate 10 resources at once. After 30 seconds +// of inactivity with all resources checked out, the pool will throw an error. +final pool = new Pool(10, timeout: new Duration(seconds: 30)); + +Future readFile(String path) { + // Since the call to [File.readAsString] is within [withResource], no more + // than ten files will be open at once. + return pool.withResource(() => return new File(path).readAsString()); +} +``` + +For more fine-grained control, the user can also explicitly request generic +`PoolResource` objects that can later be released back into the pool. This is +what `withResource` does under the covers: requests a resource, then releases it +once the callback completes. + +`Pool` ensures that only a limited number of resources are allocated at once. +It's the caller's responsibility to ensure that the corresponding physical +resource is only consumed when a `PoolResource` is allocated. + +```dart +class PooledFile implements RandomAccessFile { + final RandomAccessFile _file; + final PoolResource _resource; + + static Future open(String path) { + return pool.request().then((resource) { + return new File(path).open().then((file) { + return new PooledFile._(file, resource); + }); + }); + } + + PooledFile(this._file, this._resource); + + // ... + + Future close() { + return _file.close.then((_) { + _resource.release(); + return this; + }); + } +} +``` diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart new file mode 100644 index 000000000..36a29c86d --- /dev/null +++ b/pkgs/pool/lib/pool.dart @@ -0,0 +1,139 @@ +// Copyright (c) 2014, 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. + +library pool; + +import 'dart:async'; +import 'dart:collection'; + +import 'package:stack_trace/stack_trace.dart'; + +/// Manages an abstract pool of resources with a limit on how many may be in use +/// at once. +/// +/// When a resource is needed, the user should call [request]. When the returned +/// future completes with a [PoolResource], the resource may be allocated. Once +/// the resource has been released, the user should call [PoolResource.release]. +/// The pool will ensure that only a certain number of [PoolResource]s may be +/// allocated at once. +class Pool { + /// Completers for requests beyond the first [_maxAllocatedResources]. + /// + /// When an item is released, the next element of [_requestedResources] will + /// be completed. + final _requestedResources = new Queue>(); + + /// The maximum number of resources that may be allocated at once. + final int _maxAllocatedResources; + + /// The number of resources that are currently allocated. + int _allocatedResources = 0; + + /// The timeout timer. + /// + /// If [_timeout] isn't null, this timer is set as soon as the resource limit + /// is reached and is reset every time an resource is released or a new + /// resource is requested. If it fires, that indicates that the caller became + /// deadlocked, likely due to files waiting for additional files to be read + /// before they could be closed. + Timer _timer; + + /// The amount of time to wait before timing out the pending resources. + Duration _timeout; + + /// Creates a new pool with the given limit on how many resources may be + /// allocated at once. + /// + /// If [timeout] is passed, then if that much time passes without any activity + /// all pending [request] futures will throw an exception. This is indented + /// to avoid deadlocks. + Pool(this._maxAllocatedResources, {Duration timeout}) + : _timeout = timeout; + + /// Request a [PoolResource]. + /// + /// If the maximum number of resources is already allocated, this will delay + /// until one of them is released. + Future request() { + if (_allocatedResources < _maxAllocatedResources) { + _allocatedResources++; + return new Future.value(new PoolResource._(this)); + } else { + var completer = new Completer(); + _requestedResources.add(completer); + _resetTimer(); + return completer.future; + } + } + + /// Requests a resource for the duration of [callback], which may return a + /// Future. + /// + /// The return value of [callback] is piped to the returned Future. + Future withResource(callback()) { + return request().then((resource) => + Chain.track(new Future.sync(callback)).whenComplete(resource.release)); + } + + /// If there are any pending requests, this will fire the oldest one. + void _onResourceReleased() { + if (_requestedResources.isEmpty) { + _allocatedResources--; + if (_timer != null) { + _timer.cancel(); + _timer = null; + } + return; + } + + _resetTimer(); + var pending = _requestedResources.removeFirst(); + pending.complete(new PoolResource._(this)); + } + + /// A resource has been requested, allocated, or released. + void _resetTimer() { + if (_timer != null) _timer.cancel(); + if (_timeout == null) { + _timer = null; + } else { + _timer = new Timer(_timeout, _onTimeout); + } + } + + /// Handles [_timer] timing out by causing all pending resource completers to + /// emit exceptions. + void _onTimeout() { + for (var completer in _requestedResources) { + completer.completeError("Pool deadlock: all resources have been " + "allocated for too long.", new Chain.current()); + } + _requestedResources.clear(); + _timer = null; + } +} + +/// A member of a [Pool]. +/// +/// A [PoolResource] is a token that indicates that a resource is allocated. +/// When the associated resource is released, the user should call [release]. +class PoolResource { + final Pool _pool; + + /// Whether [this] has been released yet. + bool _released = false; + + PoolResource._(this._pool); + + /// Tells the parent [Pool] that the resource associated with this resource is + /// no longer allocated, and that a new [PoolResource] may be allocated. + void release() { + if (_released) { + throw new StateError("A PoolResource may only be released once."); + } + _released = true; + _pool._onResourceReleased(); + } +} + diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml new file mode 100644 index 000000000..847a5471b --- /dev/null +++ b/pkgs/pool/pubspec.yaml @@ -0,0 +1,7 @@ +name: pool +version: 1.0.0 +description: A class for managing a finite pool of resources. +dependencies: + stack_trace: ">=0.9.2 <2.0.0" +dev_dependencies: + unittest: ">=0.11.0 <0.12.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart new file mode 100644 index 000000000..40bcf8a74 --- /dev/null +++ b/pkgs/pool/test/pool_test.dart @@ -0,0 +1,137 @@ +// Copyright (c) 2014, 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 'dart:async'; + +import 'package:pool/pool.dart'; +import 'package:stack_trace/stack_trace.dart'; +import 'package:unittest/unittest.dart'; + +void main() { + group("request()", () { + test("resources can be requested freely up to the limit", () { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + }); + + test("resources block past the limit", () { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), doesNotComplete); + }); + + test("a blocked resource is allocated when another is released", () { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + expect(pool.request(), completes); + } + + return pool.request().then((lastAllocatedResource) { + var blockedResource = pool.request(); + + return pumpEventQueue().then((_) { + lastAllocatedResource.release(); + return pumpEventQueue(); + }).then((_) { + expect(blockedResource, completes); + }); + }); + }); + }); + + group("withResource()", () { + test("can be called freely up to the limit", () { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + }); + + test("blocks the callback past the limit", () { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + pool.withResource(expectNoAsync()); + }); + + test("a blocked resource is allocated when another is released", () { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + + var completer = new Completer(); + var lastAllocatedResource = pool.withResource(() => completer.future); + var blockedResourceAllocated = false; + var blockedResource = pool.withResource(() { + blockedResourceAllocated = true; + }); + + return pumpEventQueue().then((_) { + expect(blockedResourceAllocated, isFalse); + completer.complete(); + return pumpEventQueue(); + }).then((_) { + expect(blockedResourceAllocated, isTrue); + }); + }); + }); + + // TODO(nweiz): test timeouts when seaneagan's fake_async package lands. +} + +/// Returns a [Future] that completes after pumping the event queue [times] +/// times. By default, this should pump the event queue enough times to allow +/// any code to run, as long as it's not waiting on some external event. +Future pumpEventQueue([int times = 20]) { + if (times == 0) return new Future.value(); + // We use a delayed future to allow microtask events to finish. The + // Future.value or Future() constructors use scheduleMicrotask themselves and + // would therefore not wait for microtask callbacks that are scheduled after + // invoking this method. + return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); +} + +/// Returns a function that will cause the test to fail if it's called. +/// +/// This won't let the test complete until it's confident that the function +/// won't be called. +Function expectNoAsync() { + // Make sure the test lasts long enough for the function to get called if it's + // going to get called. + expect(pumpEventQueue(), completes); + + var stack = new Trace.current(1); + return () => handleExternalError( + new TestFailure("Expected function not to be called."), "", + stack); +} + +/// A matcher for Futures that asserts that they don't complete. +/// +/// This won't let the test complete until it's confident that the function +/// won't be called. +Matcher get doesNotComplete => predicate((future) { + expect(future, new isInstanceOf('Future')); + // Make sure the test lasts long enough for the function to get called if it's + // going to get called. + expect(pumpEventQueue(), completes); + + var stack = new Trace.current(1); + future.then((_) => handleExternalError( + new TestFailure("Expected future not to complete."), "", + stack)); + return true; +}); From 1487d08098e5f456e3e323cd2bed418799d1a7bb Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Thu, 24 Jul 2014 00:26:30 +0000 Subject: [PATCH 041/657] Make the pubspec for the pool package releasable. R=alanknight@google.com Review URL: https://codereview.chromium.org//415883002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/pool@38528 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/pool/pubspec.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 847a5471b..c1d543f93 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,6 +1,8 @@ name: pool version: 1.0.0 +author: Dart Team description: A class for managing a finite pool of resources. +homepage: http://www.dartlang.org dependencies: stack_trace: ">=0.9.2 <2.0.0" dev_dependencies: From 3adf36b500f299002404d9ff1b68cb0cf9ca0ec0 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Thu, 24 Jul 2014 20:29:33 +0000 Subject: [PATCH 042/657] Add timeout tests for the pool package. R=alanknight@google.com Review URL: https://codereview.chromium.org//411263006 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/pool@38552 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/pool/CHANGELOG.md | 3 + pkgs/pool/lib/pool.dart | 13 ++- pkgs/pool/pubspec.yaml | 3 +- pkgs/pool/test/pool_test.dart | 186 ++++++++++++++++++++++------------ 4 files changed, 133 insertions(+), 72 deletions(-) create mode 100644 pkgs/pool/CHANGELOG.md diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md new file mode 100644 index 000000000..e8dee50c9 --- /dev/null +++ b/pkgs/pool/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.1 + +* A `TimeoutException` is now correctly thrown if the pool detects a deadlock. diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 36a29c86d..61482e3f2 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -40,14 +40,14 @@ class Pool { Timer _timer; /// The amount of time to wait before timing out the pending resources. - Duration _timeout; + final Duration _timeout; /// Creates a new pool with the given limit on how many resources may be /// allocated at once. /// /// If [timeout] is passed, then if that much time passes without any activity - /// all pending [request] futures will throw an exception. This is indented - /// to avoid deadlocks. + /// all pending [request] futures will throw a [TimeoutException]. This is + /// intended to avoid deadlocks. Pool(this._maxAllocatedResources, {Duration timeout}) : _timeout = timeout; @@ -106,8 +106,11 @@ class Pool { /// emit exceptions. void _onTimeout() { for (var completer in _requestedResources) { - completer.completeError("Pool deadlock: all resources have been " - "allocated for too long.", new Chain.current()); + completer.completeError( + new TimeoutException("Pool deadlock: all resources have been " + "allocated for too long.", + _timeout), + new Chain.current()); } _requestedResources.clear(); _timer = null; diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index c1d543f93..9972cbbb3 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,9 +1,10 @@ name: pool -version: 1.0.0 +version: 1.0.1 author: Dart Team description: A class for managing a finite pool of resources. homepage: http://www.dartlang.org dependencies: stack_trace: ">=0.9.2 <2.0.0" dev_dependencies: + fake_async: ">=0.1.0 <0.2.0" unittest: ">=0.11.0 <0.12.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 40bcf8a74..bb9e60768 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:fake_async/fake_async.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart'; import 'package:unittest/unittest.dart'; @@ -19,30 +20,36 @@ void main() { }); test("resources block past the limit", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 50; i++) { - expect(pool.request(), completes); - } - expect(pool.request(), doesNotComplete); + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), doesNotComplete); + + async.elapse(new Duration(seconds: 1)); + }); }); test("a blocked resource is allocated when another is released", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 49; i++) { - expect(pool.request(), completes); - } - - return pool.request().then((lastAllocatedResource) { - var blockedResource = pool.request(); - - return pumpEventQueue().then((_) { - lastAllocatedResource.release(); - return pumpEventQueue(); - }).then((_) { - expect(blockedResource, completes); + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + expect(pool.request(), completes); + } + + pool.request().then((lastAllocatedResource) { + // This will only complete once [lastAllocatedResource] is released. + expect(pool.request(), completes); + + new Future.delayed(new Duration(microseconds: 1)).then((_) { + lastAllocatedResource.release(); + }); }); + + async.elapse(new Duration(seconds: 1)); }); }); }); @@ -57,62 +64,113 @@ void main() { }); test("blocks the callback past the limit", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync(() => new Completer().future)); - } - pool.withResource(expectNoAsync()); + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + pool.withResource(expectNoAsync()); + + async.elapse(new Duration(seconds: 1)); + }); }); test("a blocked resource is allocated when another is released", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 49; i++) { - pool.withResource(expectAsync(() => new Completer().future)); - } + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + + var completer = new Completer(); + var lastAllocatedResource = pool.withResource(() => completer.future); + var blockedResourceAllocated = false; + var blockedResource = pool.withResource(() { + blockedResourceAllocated = true; + }); - var completer = new Completer(); - var lastAllocatedResource = pool.withResource(() => completer.future); - var blockedResourceAllocated = false; - var blockedResource = pool.withResource(() { - blockedResourceAllocated = true; - }); + new Future.delayed(new Duration(microseconds: 1)).then((_) { + expect(blockedResourceAllocated, isFalse); + completer.complete(); + return new Future.delayed(new Duration(microseconds: 1)); + }).then((_) { + expect(blockedResourceAllocated, isTrue); + }); - return pumpEventQueue().then((_) { - expect(blockedResourceAllocated, isFalse); - completer.complete(); - return pumpEventQueue(); - }).then((_) { - expect(blockedResourceAllocated, isTrue); + async.elapse(new Duration(seconds: 1)); }); }); }); - // TODO(nweiz): test timeouts when seaneagan's fake_async package lands. -} + group("with a timeout", () { + test("doesn't time out if there are no pending requests", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } -/// Returns a [Future] that completes after pumping the event queue [times] -/// times. By default, this should pump the event queue enough times to allow -/// any code to run, as long as it's not waiting on some external event. -Future pumpEventQueue([int times = 20]) { - if (times == 0) return new Future.value(); - // We use a delayed future to allow microtask events to finish. The - // Future.value or Future() constructors use scheduleMicrotask themselves and - // would therefore not wait for microtask callbacks that are scheduled after - // invoking this method. - return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); + async.elapse(new Duration(seconds: 6)); + }); + }); + + test("resets the timer if a resource is returned", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 49; i++) { + expect(pool.request(), completes); + } + + pool.request().then((lastAllocatedResource) { + // This will only complete once [lastAllocatedResource] is released. + expect(pool.request(), completes); + + new Future.delayed(new Duration(seconds: 3)).then((_) { + lastAllocatedResource.release(); + expect(pool.request(), doesNotComplete); + }); + }); + + async.elapse(new Duration(seconds: 6)); + }); + }); + + test("resets the timer if a resource is requested", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), doesNotComplete); + + new Future.delayed(new Duration(seconds: 3)).then((_) { + expect(pool.request(), doesNotComplete); + }); + + async.elapse(new Duration(seconds: 6)); + }); + }); + + test("times out if nothing happens", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), throwsA(new isInstanceOf())); + + async.elapse(new Duration(seconds: 6)); + }); + }); + }); } /// Returns a function that will cause the test to fail if it's called. /// -/// This won't let the test complete until it's confident that the function -/// won't be called. +/// This should only be called within a [FakeAsync.run] zone. Function expectNoAsync() { - // Make sure the test lasts long enough for the function to get called if it's - // going to get called. - expect(pumpEventQueue(), completes); - var stack = new Trace.current(1); return () => handleExternalError( new TestFailure("Expected function not to be called."), "", @@ -121,13 +179,9 @@ Function expectNoAsync() { /// A matcher for Futures that asserts that they don't complete. /// -/// This won't let the test complete until it's confident that the function -/// won't be called. +/// This should only be called within a [FakeAsync.run] zone. Matcher get doesNotComplete => predicate((future) { expect(future, new isInstanceOf('Future')); - // Make sure the test lasts long enough for the function to get called if it's - // going to get called. - expect(pumpEventQueue(), completes); var stack = new Trace.current(1); future.then((_) => handleExternalError( From 2686535940bdbe2664d4c1bd0012988038add009 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 25 Jul 2014 00:32:40 +0000 Subject: [PATCH 043/657] Revert r38549, r38552, and r38557. It's currently too difficult to include a third party package for it to be worthwhile for this use case. R=alanknight@google.com Review URL: https://codereview.chromium.org//419683002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/pool@38564 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/pool/CHANGELOG.md | 3 - pkgs/pool/lib/pool.dart | 13 +-- pkgs/pool/pubspec.yaml | 3 +- pkgs/pool/test/pool_test.dart | 187 ++++++++++++---------------------- 4 files changed, 73 insertions(+), 133 deletions(-) delete mode 100644 pkgs/pool/CHANGELOG.md diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md deleted file mode 100644 index e8dee50c9..000000000 --- a/pkgs/pool/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -## 1.0.1 - -* A `TimeoutException` is now correctly thrown if the pool detects a deadlock. diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 61482e3f2..36a29c86d 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -40,14 +40,14 @@ class Pool { Timer _timer; /// The amount of time to wait before timing out the pending resources. - final Duration _timeout; + Duration _timeout; /// Creates a new pool with the given limit on how many resources may be /// allocated at once. /// /// If [timeout] is passed, then if that much time passes without any activity - /// all pending [request] futures will throw a [TimeoutException]. This is - /// intended to avoid deadlocks. + /// all pending [request] futures will throw an exception. This is indented + /// to avoid deadlocks. Pool(this._maxAllocatedResources, {Duration timeout}) : _timeout = timeout; @@ -106,11 +106,8 @@ class Pool { /// emit exceptions. void _onTimeout() { for (var completer in _requestedResources) { - completer.completeError( - new TimeoutException("Pool deadlock: all resources have been " - "allocated for too long.", - _timeout), - new Chain.current()); + completer.completeError("Pool deadlock: all resources have been " + "allocated for too long.", new Chain.current()); } _requestedResources.clear(); _timer = null; diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 9972cbbb3..c1d543f93 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,10 +1,9 @@ name: pool -version: 1.0.1 +version: 1.0.0 author: Dart Team description: A class for managing a finite pool of resources. homepage: http://www.dartlang.org dependencies: stack_trace: ">=0.9.2 <2.0.0" dev_dependencies: - fake_async: ">=0.1.0 <0.2.0" unittest: ">=0.11.0 <0.12.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index bb9e60768..bfeb876b1 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -4,7 +4,6 @@ import 'dart:async'; -import 'package:fake_async/fake_async.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart'; import 'package:unittest/unittest.dart'; @@ -20,36 +19,30 @@ void main() { }); test("resources block past the limit", () { - new FakeAsync().run((async) { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 50; i++) { - expect(pool.request(), completes); - } - expect(pool.request(), doesNotComplete); - - async.elapse(new Duration(seconds: 1)); - }); + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), doesNotComplete); }); test("a blocked resource is allocated when another is released", () { - new FakeAsync().run((async) { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 49; i++) { - expect(pool.request(), completes); - } - - pool.request().then((lastAllocatedResource) { - // This will only complete once [lastAllocatedResource] is released. - expect(pool.request(), completes); - - new Future.delayed(new Duration(microseconds: 1)).then((_) { - lastAllocatedResource.release(); - }); - }); + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + expect(pool.request(), completes); + } + + return pool.request().then((lastAllocatedResource) { + var blockedResource = pool.request(); - async.elapse(new Duration(seconds: 1)); + return pumpEventQueue().then((_) { + lastAllocatedResource.release(); + return pumpEventQueue(); + }).then((_) { + expect(blockedResource, completes); + }); }); }); }); @@ -64,113 +57,63 @@ void main() { }); test("blocks the callback past the limit", () { - new FakeAsync().run((async) { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync(() => new Completer().future)); - } - pool.withResource(expectNoAsync()); - - async.elapse(new Duration(seconds: 1)); - }); + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + pool.withResource(expectNoAsync()); }); test("a blocked resource is allocated when another is released", () { - new FakeAsync().run((async) { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 49; i++) { - pool.withResource(expectAsync(() => new Completer().future)); - } - - var completer = new Completer(); - var lastAllocatedResource = pool.withResource(() => completer.future); - var blockedResourceAllocated = false; - var blockedResource = pool.withResource(() { - blockedResourceAllocated = true; - }); - - new Future.delayed(new Duration(microseconds: 1)).then((_) { - expect(blockedResourceAllocated, isFalse); - completer.complete(); - return new Future.delayed(new Duration(microseconds: 1)); - }).then((_) { - expect(blockedResourceAllocated, isTrue); - }); + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } - async.elapse(new Duration(seconds: 1)); + var completer = new Completer(); + var lastAllocatedResource = pool.withResource(() => completer.future); + var blockedResourceAllocated = false; + var blockedResource = pool.withResource(() { + blockedResourceAllocated = true; }); - }); - }); - - group("with a timeout", () { - test("doesn't time out if there are no pending requests", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); - for (var i = 0; i < 50; i++) { - expect(pool.request(), completes); - } - async.elapse(new Duration(seconds: 6)); + return pumpEventQueue().then((_) { + expect(blockedResourceAllocated, isFalse); + completer.complete(); + return pumpEventQueue(); + }).then((_) { + expect(blockedResourceAllocated, isTrue); }); }); + }); - test("resets the timer if a resource is returned", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); - for (var i = 0; i < 49; i++) { - expect(pool.request(), completes); - } - - pool.request().then((lastAllocatedResource) { - // This will only complete once [lastAllocatedResource] is released. - expect(pool.request(), completes); - - new Future.delayed(new Duration(seconds: 3)).then((_) { - lastAllocatedResource.release(); - expect(pool.request(), doesNotComplete); - }); - }); - - async.elapse(new Duration(seconds: 6)); - }); - }); - - test("resets the timer if a resource is requested", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); - for (var i = 0; i < 50; i++) { - expect(pool.request(), completes); - } - expect(pool.request(), doesNotComplete); - - new Future.delayed(new Duration(seconds: 3)).then((_) { - expect(pool.request(), doesNotComplete); - }); - - async.elapse(new Duration(seconds: 6)); - }); - }); - - test("times out if nothing happens", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); - for (var i = 0; i < 50; i++) { - expect(pool.request(), completes); - } - expect(pool.request(), throwsA(new isInstanceOf())); + // TODO(nweiz): Test timeouts when it's easier to use third-party packages. + // See r38552. +} - async.elapse(new Duration(seconds: 6)); - }); - }); - }); +/// Returns a [Future] that completes after pumping the event queue [times] +/// times. By default, this should pump the event queue enough times to allow +/// any code to run, as long as it's not waiting on some external event. +Future pumpEventQueue([int times = 20]) { + if (times == 0) return new Future.value(); + // We use a delayed future to allow microtask events to finish. The + // Future.value or Future() constructors use scheduleMicrotask themselves and + // would therefore not wait for microtask callbacks that are scheduled after + // invoking this method. + return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); } /// Returns a function that will cause the test to fail if it's called. /// -/// This should only be called within a [FakeAsync.run] zone. +/// This won't let the test complete until it's confident that the function +/// won't be called. Function expectNoAsync() { + // Make sure the test lasts long enough for the function to get called if it's + // going to get called. + expect(pumpEventQueue(), completes); + var stack = new Trace.current(1); return () => handleExternalError( new TestFailure("Expected function not to be called."), "", @@ -179,9 +122,13 @@ Function expectNoAsync() { /// A matcher for Futures that asserts that they don't complete. /// -/// This should only be called within a [FakeAsync.run] zone. +/// This won't let the test complete until it's confident that the function +/// won't be called. Matcher get doesNotComplete => predicate((future) { expect(future, new isInstanceOf('Future')); + // Make sure the test lasts long enough for the function to get called if it's + // going to get called. + expect(pumpEventQueue(), completes); var stack = new Trace.current(1); future.then((_) => handleExternalError( From 96b1161c2a8803c6d8eeae1797c110e2e2accb93 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Thu, 31 Jul 2014 22:04:31 +0000 Subject: [PATCH 044/657] Remove support for the old Span classes from source_maps. This releases source_maps 0.10.0, code_transformers 0.2.0+2, observe 0.11.0+3, and polymer 0.12.0+4. BUG=19930 R=sigmund@google.com Review URL: https://codereview.chromium.org//421723004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38803 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/lib/builder.dart | 54 +-- pkgs/source_maps/lib/parser.dart | 41 +- pkgs/source_maps/lib/printer.dart | 64 ++- pkgs/source_maps/lib/refactor.dart | 17 +- pkgs/source_maps/lib/source_maps.dart | 5 +- pkgs/source_maps/lib/span.dart | 404 ------------------ pkgs/source_maps/lib/src/source_map_span.dart | 59 +++ pkgs/source_maps/lib/src/span_wrapper.dart | 85 ---- pkgs/source_maps/test/builder_test.dart | 4 +- pkgs/source_maps/test/common.dart | 44 +- pkgs/source_maps/test/end2end_test.dart | 31 +- pkgs/source_maps/test/parser_test.dart | 2 +- pkgs/source_maps/test/printer_test.dart | 11 +- pkgs/source_maps/test/refactor_test.dart | 88 +++- pkgs/source_maps/test/run.dart | 2 - pkgs/source_maps/test/span_test.dart | 341 --------------- 16 files changed, 254 insertions(+), 998 deletions(-) delete mode 100644 pkgs/source_maps/lib/span.dart create mode 100644 pkgs/source_maps/lib/src/source_map_span.dart delete mode 100644 pkgs/source_maps/lib/src/span_wrapper.dart delete mode 100644 pkgs/source_maps/test/span_test.dart diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 494a6b6e9..091e220c5 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -9,9 +9,10 @@ library source_maps.builder; import 'dart:convert'; +import 'package:source_span/source_span.dart'; + import 'parser.dart'; -import 'span.dart'; -import 'src/span_wrapper.dart'; +import 'src/source_map_span.dart'; /// Builds a source map given a set of mappings. class SourceMapBuilder { @@ -19,39 +20,33 @@ class SourceMapBuilder { final List _entries = []; /// Adds an entry mapping the [targetOffset] to [source]. - /// - /// [source] can be either a [Location] or a [SourceLocation]. Using a - /// [Location] is deprecated and will be unsupported in version 0.10.0. - void addFromOffset(source, targetFile, int targetOffset, String identifier) { + void addFromOffset(SourceLocation source, SourceFile targetFile, + int targetOffset, String identifier) { if (targetFile == null) { throw new ArgumentError('targetFile cannot be null'); } - _entries.add(new Entry(source, - new FileLocation(targetFile, targetOffset), identifier)); + _entries.add( + new Entry(source, targetFile.location(targetOffset), identifier)); } /// Adds an entry mapping [target] to [source]. /// - /// [source] and [target] can be either a [Span] or a [SourceSpan]. Using a - /// [Span] is deprecated and will be unsupported in version 0.10.0. - /// - /// If [isIdentifier] is true, this entry is considered to represent an - /// identifier whose value will be stored in the source map. - void addSpan(source, target, {bool isIdentifier}) { - source = SpanWrapper.wrap(source); - target = SpanWrapper.wrap(target); - if (isIdentifier == null) isIdentifier = source.isIdentifier; + /// If [isIdentifier] is true or if [target] is a [SourceMapSpan] with + /// `isIdentifier` set to true, this entry is considered to represent an + /// identifier whose value will be stored in the source map. [isIdenfier] + /// takes precedence over [target]'s `isIdentifier` value. + void addSpan(SourceSpan source, SourceSpan target, {bool isIdentifier}) { + if (isIdentifier == null) { + isIdentifier = source is SourceMapSpan ? source.isIdentifier : false; + } var name = isIdentifier ? source.text : null; _entries.add(new Entry(source.start, target.start, name)); } /// Adds an entry mapping [target] to [source]. - /// - /// [source] and [target] can be either a [Location] or a [SourceLocation]. - /// Using a [Location] is deprecated and will be unsupported in version - /// 0.10.0. - void addLocation(source, target, String identifier) { + void addLocation(SourceLocation source, SourceLocation target, + String identifier) { _entries.add(new Entry(source, target, identifier)); } @@ -67,22 +62,16 @@ class SourceMapBuilder { /// An entry in the source map builder. class Entry implements Comparable { /// Span denoting the original location in the input source file - final Location source; + final SourceLocation source; /// Span indicating the corresponding location in the target file. - final Location target; + final SourceLocation target; /// An identifier name, when this location is the start of an identifier. final String identifierName; /// Creates a new [Entry] mapping [target] to [source]. - /// - /// [source] and [target] can be either a [Location] or a [SourceLocation]. - /// Using a [Location] is deprecated and will be unsupported in version - /// 0.10.0. - Entry(source, target, this.identifierName) - : source = LocationWrapper.wrap(source), - target = LocationWrapper.wrap(target); + Entry(this.source, this.target, this.identifierName); /// Implements [Comparable] to ensure that entries are ordered by their /// location in the target file. We sort primarily by the target offset @@ -91,7 +80,8 @@ class Entry implements Comparable { int compareTo(Entry other) { int res = target.compareTo(other.target); if (res != 0) return res; - res = source.sourceUrl.compareTo(other.source.sourceUrl); + res = source.sourceUrl.toString().compareTo( + other.source.sourceUrl.toString()); if (res != 0) return res; return source.compareTo(other.source); } diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index c18a1d69b..d67a65e58 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -8,9 +8,10 @@ library source_maps.parser; import 'dart:collection'; import 'dart:convert'; +import 'package:source_span/source_span.dart'; + import 'builder.dart' as builder; -import 'span.dart'; -import 'src/span_wrapper.dart'; +import 'src/source_map_span.dart'; import 'src/utils.dart'; import 'src/vlq.dart'; @@ -49,19 +50,11 @@ Mapping parseJson(Map map, {Map otherMaps}) { /// A mapping parsed out of a source map. abstract class Mapping { /// Returns the span associated with [line] and [column]. - /// - /// The values of [files] can be either `source_map` [SourceFile]s or - /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is - /// deprecated and will be unsupported in version 0.10.0. - Span spanFor(int line, int column, {Map files}); + SourceMapSpan spanFor(int line, int column, {Map files}); /// Returns the span associated with [location]. - /// - /// The values of [files] may be either `source_map` [SourceFile]s or - /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is - /// deprecated and will be unsupported in version 0.10.0. - Span spanForLocation(location, {Map files}) { - location = LocationWrapper.wrap(location); + SourceMapSpan spanForLocation(SourceLocation location, + {Map files}) { return spanFor(location.line, location.column, files: files); } } @@ -124,7 +117,7 @@ class MultiSectionMapping extends Mapping { return _lineStart.length - 1; } - Span spanFor(int line, int column, {Map files}) { + SourceMapSpan spanFor(int line, int column, {Map files}) { int index = _indexFor(line, column); return _maps[index].spanFor( line - _lineStart[index], column - _columnStart[index], files: files); @@ -191,8 +184,9 @@ class SingleMapping extends Mapping { if (sourceEntry.source == null) { targetEntries.add(new TargetEntry(sourceEntry.target.column)); } else { + var sourceUrl = sourceEntry.source.sourceUrl; var urlId = urls.putIfAbsent( - sourceEntry.source.sourceUrl, () => urls.length); + sourceUrl == null ? '' : sourceUrl.toString(), () => urls.length); var srcNameId = sourceEntry.identifierName == null ? null : names.putIfAbsent(sourceEntry.identifierName, () => names.length); targetEntries.add(new TargetEntry( @@ -363,7 +357,7 @@ class SingleMapping extends Mapping { return (index <= 0) ? null : entries[index - 1]; } - Span spanFor(int line, int column, {Map files}) { + SourceMapSpan spanFor(int line, int column, {Map files}) { var entry = _findColumn(line, column, _findLine(line)); if (entry == null || entry.sourceUrlId == null) return null; var url = urls[entry.sourceUrlId]; @@ -371,21 +365,24 @@ class SingleMapping extends Mapping { url = '${sourceRoot}${url}'; } if (files != null && files[url] != null) { - var file = SourceFileWrapper.wrap(files[url]); + var file = files[url]; var start = file.getOffset(entry.sourceLine, entry.sourceColumn); if (entry.sourceNameId != null) { var text = names[entry.sourceNameId]; - return new FileSpan(files[url], start, start + text.length, true); + return new SourceMapFileSpan( + files[url].span(start, start + text.length), + isIdentifier: true); } else { - return new FileSpan(files[url], start); + return new SourceMapFileSpan(files[url].location(start).pointSpan()); } } else { + var start = new SourceLocation(0, + sourceUrl: url, line: entry.sourceLine, column: entry.sourceColumn); // Offset and other context is not available. if (entry.sourceNameId != null) { - return new FixedSpan(url, 0, entry.sourceLine, entry.sourceColumn, - text: names[entry.sourceNameId], isIdentifier: true); + return new SourceMapSpan.identifier(start, names[entry.sourceNameId]); } else { - return new FixedSpan(url, 0, entry.sourceLine, entry.sourceColumn); + return new SourceMapSpan(start, start, ''); } } } diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index aa18bd764..906e260f8 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -5,11 +5,10 @@ /// Contains a code printer that generates code by recording the source maps. library source_maps.printer; -import 'package:source_span/source_span.dart' as source_span; +import 'package:source_span/source_span.dart'; import 'builder.dart'; -import 'span.dart'; -import 'src/span_wrapper.dart'; +import 'src/source_map_span.dart'; const int _LF = 10; const int _CR = 13; @@ -24,7 +23,7 @@ class Printer { String get map => _maps.toJson(filename); /// Current source location mapping. - Location _loc; + SourceLocation _loc; /// Current line in the buffer; int _line = 0; @@ -49,11 +48,12 @@ class Printer { _line++; _column = 0; if (projectMarks && _loc != null) { - if (_loc is FixedLocation) { - mark(new FixedLocation(0, _loc.sourceUrl, _loc.line + 1, 0)); - } else if (_loc is FileLocation) { + if (_loc is FileLocation) { var file = (_loc as FileLocation).file; - mark(new FileLocation(file, file.getOffset(_loc.line + 1, 0))); + mark(file.location(file.getOffset(_loc.line + 1))); + } else { + mark(new SourceLocation(0, + sourceUrl: _loc.sourceUrl, line: _loc.line + 1, column: 0)); } } } else { @@ -72,21 +72,23 @@ class Printer { } /// Marks that the current point in the target file corresponds to the [mark] - /// in the source file, which can be either a [Location] or a [Span]. When the - /// mark is an identifier's Span, this also records the name of the identifier - /// in the source map information. + /// in the source file, which can be either a [SourceLocation] or a + /// [SourceSpan]. When the mark is a [SourceMapSpan] with `isIdentifier` set, + /// this also records the name of the identifier in the source map + /// information. void mark(mark) { var loc; var identifier = null; - if (mark is Location || mark is source_span.SourceLocation) { - loc = LocationWrapper.wrap(mark); - } else if (mark is Span || mark is source_span.SourceSpan) { - mark = SpanWrapper.wrap(mark); + if (mark is SourceLocation) { + loc = mark; + } else if (mark is SourceSpan) { loc = mark.start; - if (mark.isIdentifier) identifier = mark.text; + if (mark is SourceMapSpan && mark.isIdentifier) identifier = mark.text; } - _maps.addLocation(loc, - new FixedLocation(_buff.length, null, _line, _column), identifier); + _maps.addLocation( + loc, + new SourceLocation(_buff.length, line: _line, column: _column), + identifier); _loc = loc; } } @@ -101,7 +103,8 @@ class Printer { class NestedPrinter implements NestedItem { /// Items recoded by this printer, which can be [String] literals, - /// [NestedItem]s, and source map information like [Location] and [Span]. + /// [NestedItem]s, and source map information like [SourceLocation] and + /// [SourceSpan]. List _items = []; /// Internal buffer to merge consecutive strings added to this printer. @@ -128,19 +131,16 @@ class NestedPrinter implements NestedItem { /// location of [object] in the original input. Only one, [location] or /// [span], should be provided at a time. /// - /// [location] can be either a [Location] or a [SourceLocation]. [span] can be - /// either a [Span] or a [SourceSpan]. Using a [Location] or a [Span] is - /// deprecated and will be unsupported in version 0.10.0. - /// /// Indicate [isOriginal] when [object] is copied directly from the user code. /// Setting [isOriginal] will make this printer propagate source map locations /// on every line-break. - void add(object, {location, span, bool isOriginal: false}) { + void add(object, {SourceLocation location, SourceSpan span, + bool isOriginal: false}) { if (object is! String || location != null || span != null || isOriginal) { _flush(); assert(location == null || span == null); - if (location != null) _items.add(LocationWrapper.wrap(location)); - if (span != null) _items.add(SpanWrapper.wrap(span)); + if (location != null) _items.add(location); + if (span != null) _items.add(span); if (isOriginal) _items.add(_ORIGINAL); } @@ -164,16 +164,12 @@ class NestedPrinter implements NestedItem { /// The [location] and [span] parameters indicate the corresponding source map /// location of [object] in the original input. Only one, [location] or /// [span], should be provided at a time. - /// - /// [location] can be either a [Location] or a [SourceLocation]. [span] can be - /// either a [Span] or a [SourceSpan]. Using a [Location] or a [Span] is - /// deprecated and will be unsupported in version 0.10.0. - void addLine(String line, {location, span}) { + void addLine(String line, {SourceLocation location, SourceSpan span}) { if (location != null || span != null) { _flush(); assert(location == null || span == null); - if (location != null) _items.add(LocationWrapper.wrap(location)); - if (span != null) _items.add(SpanWrapper.wrap(span)); + if (location != null) _items.add(location); + if (span != null) _items.add(span); } if (line == null) return; if (line != '') { @@ -235,7 +231,7 @@ class NestedPrinter implements NestedItem { } else if (item is String) { printer.add(item, projectMarks: propagate); propagate = false; - } else if (item is Location || item is Span) { + } else if (item is SourceLocation || item is SourceSpan) { printer.mark(item); } else if (item == _ORIGINAL) { // we insert booleans when we are about to quote text that was copied diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 47ce2ed90..a33b86bec 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -8,9 +8,9 @@ /// [guessIndent] helps to guess the appropriate indentiation for the new code. library source_maps.refactor; -import 'span.dart'; +import 'package:source_span/source_span.dart'; + import 'printer.dart'; -import 'src/span_wrapper.dart'; /// Editable text transaction. /// @@ -22,12 +22,7 @@ class TextEditTransaction { final _edits = <_TextEdit>[]; /// Creates a new transaction. - /// - /// [file] can be either a `source_map` [SourceFile] or a `source_span` - /// `SourceFile`. Using a `source_map` [SourceFile] is deprecated and will be - /// unsupported in version 0.10.0. - TextEditTransaction(this.original, file) - : file = SourceFileWrapper.wrap(file); + TextEditTransaction(this.original, this.file); bool get hasEdits => _edits.length > 0; @@ -38,8 +33,8 @@ class TextEditTransaction { _edits.add(new _TextEdit(begin, end, replacement)); } - /// Create a source map [Location] for [offset]. - Location _loc(int offset) => + /// Create a source map [SourceLocation] for [offset]. + SourceLocation _loc(int offset) => file != null ? file.location(offset) : null; /// Applies all pending [edit]s and returns a [NestedPrinter] containing the @@ -62,7 +57,7 @@ class TextEditTransaction { for (var edit in _edits) { if (consumed > edit.begin) { var sb = new StringBuffer(); - sb..write(file.location(edit.begin).formatString) + sb..write(file.location(edit.begin).toolString) ..write(': overlapping edits. Insert at offset ') ..write(edit.begin) ..write(' but have consumed ') diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 2d4a4ccc4..953190341 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -11,7 +11,8 @@ /// ..add(inputSpan3, outputSpan3) /// .toJson(outputFile); /// -/// Use the [Span] and [SourceFile] classes to specify span locations. +/// Use the source_span package's [SourceSpan] and [SourceFile] classes to +/// specify span locations. /// /// Parse a source map using [parse], and call `spanFor` on the returned mapping /// object. For example: @@ -40,4 +41,4 @@ export "builder.dart"; export "parser.dart"; export "printer.dart"; export "refactor.dart"; -export "span.dart"; +export 'src/source_map_span.dart'; diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart deleted file mode 100644 index a21e893b7..000000000 --- a/pkgs/source_maps/lib/span.dart +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright (c) 2013, 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. - -/// Dart classes representing the souce spans and source files. -library source_maps.span; - -import 'dart:math' show min, max; - -import 'package:path/path.dart' as p; - -import 'src/utils.dart'; - -/// A simple class that describe a segment of source text. -@Deprecated("Use the source_span package instead.") -abstract class Span implements Comparable { - /// The start location of this span. - final Location start; - - /// The end location of this span, exclusive. - final Location end; - - /// Url of the source (typically a file) containing this span. - String get sourceUrl => start.sourceUrl; - - /// The length of this span, in characters. - int get length => end.offset - start.offset; - - /// The source text for this span, if available. - String get text; - - /// Whether [text] corresponds to an identifier symbol. - final bool isIdentifier; - - Span(this.start, this.end, bool isIdentifier) - : isIdentifier = isIdentifier != null ? isIdentifier : false { - _checkRange(); - } - - /// Creates a new span that is the union of two existing spans [start] and - /// [end]. Note that the resulting span might contain some positions that were - /// not in either of the original spans if [start] and [end] are disjoint. - Span.union(Span start, Span end) - : start = start.start, end = end.end, isIdentifier = false { - _checkRange(); - } - - void _checkRange() { - if (start.offset < 0) throw new ArgumentError('start $start must be >= 0'); - if (end.offset < start.offset) { - throw new ArgumentError('end $end must be >= start $start'); - } - } - - /// Compares two spans. If the spans are not in the same source, this method - /// generates an error. - int compareTo(Span other) { - int d = start.compareTo(other.start); - return d == 0 ? end.compareTo(other.end) : d; - } - - /// Gets the location in standard printed form `filename:line:column`, where - /// line and column are adjusted by 1 to match the convention in editors. - String get formatLocation => start.formatString; - - String getLocationMessage(String message, - {bool useColors: false, String color}) { - var source = start.sourceUrl == null ? '' : - ' of ${p.prettyUri(start.sourceUrl)}'; - return 'line ${start.line + 1}, column ${start.column + 1}$source: ' + - message; - } - - bool operator ==(Span other) => - sourceUrl == other.sourceUrl && start == other.start && end == other.end; - - int get hashCode => sourceUrl.hashCode + start.offset + (31 * length); - - String toString() => '<$runtimeType: $start $end $formatLocation $text>'; -} - -/// A location in the source text -@Deprecated("Use the source_span package instead.") -abstract class Location implements Comparable { - /// Url of the source containing this span. - String get sourceUrl; - - /// The offset of this location, 0-based. - final int offset; - - /// The 0-based line in the source of this location. - int get line; - - /// The 0-based column in the source of this location. - int get column; - - Location(this.offset); - - /// Compares two locations. If the locations are not in the same source, this - /// method generates an error. - int compareTo(Location other) { - if (sourceUrl != other.sourceUrl) { - throw new ArgumentError('can only compare locations of the same source'); - } - return offset - other.offset; - } - - bool operator ==(Location other) => - sourceUrl == other.sourceUrl && offset == other.offset; - - int get hashCode => sourceUrl.hashCode + offset; - - String toString() => '(Location $offset)'; - String get formatString => '$sourceUrl:${line + 1}:${column + 1}'; -} - -/// Implementation of [Location] with fixed values given at allocation time. -@Deprecated("Use the source_span package instead.") -class FixedLocation extends Location { - final String sourceUrl; - final int line; - final int column; - - FixedLocation(int offset, this.sourceUrl, this.line, this.column) - : super(offset); -} - -/// Implementation of [Span] where all the values are given at allocation time. -@Deprecated("Use the source_span package instead.") -class FixedSpan extends Span { - /// The source text for this span, if available. - final String text; - - /// Creates a span which starts and end in the same line. - FixedSpan(String sourceUrl, int start, int line, int column, - {String text: '', bool isIdentifier: false}) - : text = text, super(new FixedLocation(start, sourceUrl, line, column), - new FixedLocation(start + text.length, sourceUrl, line, - column + text.length), - isIdentifier); -} - -/// [Location] with values computed from an underling [SourceFile]. -@Deprecated("Use the source_span package instead.") -class FileLocation extends Location { - /// The source file containing this location. - final SourceFile file; - - String get sourceUrl => file.url; - int get line => file.getLine(offset); - int get column => file.getColumn(line, offset); - - FileLocation(this.file, int offset): super(offset); -} - -/// [Span] where values are computed from an underling [SourceFile]. -@Deprecated("Use the source_span package instead.") -class FileSpan extends Span { - /// The source file containing this span. - final SourceFile file; - - /// The source text for this span, if available. - String get text => file.getText(start.offset, end.offset); - - factory FileSpan(SourceFile file, int start, - [int end, bool isIdentifier = false]) { - var startLoc = new FileLocation(file, start); - var endLoc = end == null ? startLoc : new FileLocation(file, end); - return new FileSpan.locations(startLoc, endLoc, isIdentifier); - } - - FileSpan.locations(FileLocation start, FileLocation end, - bool isIdentifier) - : file = start.file, super(start, end, isIdentifier); - - /// Creates a new span that is the union of two existing spans [start] and - /// [end]. Note that the resulting span might contain some positions that were - /// not in either of the original spans if [start] and [end] are disjoint. - FileSpan.union(FileSpan start, FileSpan end) - : file = start.file, super.union(start, end) { - if (start.file != end.file) { - throw new ArgumentError('start and end must be from the same file'); - } - } - - String getLocationMessage(String message, - {bool useColors: false, String color}) { - return file.getLocationMessage(message, start.offset, end.offset, - useColors: useColors, color: color); - } -} - -// Constants to determine end-of-lines. -const int _LF = 10; -const int _CR = 13; - -// Color constants used for generating messages. -const String _RED_COLOR = '\u001b[31m'; -const String _NO_COLOR = '\u001b[0m'; - -/// Stores information about a source file, to permit computation of the line -/// and column. Also contains a nice default error message highlighting the code -/// location. -@Deprecated("Use the source_span package instead.") -class SourceFile { - /// Url where the source file is located. - final String url; - final List _lineStarts; - final List _decodedChars; - - SourceFile(this.url, this._lineStarts, this._decodedChars); - - SourceFile.text(this.url, String text) - : _lineStarts = [0], - _decodedChars = text.runes.toList() { - for (int i = 0; i < _decodedChars.length; i++) { - var c = _decodedChars[i]; - if (c == _CR) { - // Return not followed by newline is treated as a newline - int j = i + 1; - if (j >= _decodedChars.length || _decodedChars[j] != _LF) { - c = _LF; - } - } - if (c == _LF) _lineStarts.add(i + 1); - } - } - - /// Returns a span in this [SourceFile] with the given offsets. - Span span(int start, [int end, bool isIdentifier = false]) => - new FileSpan(this, start, end, isIdentifier); - - /// Returns a location in this [SourceFile] with the given offset. - Location location(int offset) => new FileLocation(this, offset); - - /// Gets the 0-based line corresponding to an offset. - int getLine(int offset) => binarySearch(_lineStarts, (o) => o > offset) - 1; - - /// Gets the 0-based column corresponding to an offset. - int getColumn(int line, int offset) { - if (line < 0 || line >= _lineStarts.length) return 0; - return offset - _lineStarts[line]; - } - - /// Get the offset for a given line and column - int getOffset(int line, int column) { - if (line < 0) return getOffset(0, 0); - if (line < _lineStarts.length) { - return _lineStarts[line] + column; - } else { - return _decodedChars.length; - } - } - - /// Gets the text at the given offsets. - String getText(int start, [int end]) => - new String.fromCharCodes(_decodedChars.sublist(max(start, 0), end)); - - /// Create a pretty string representation from a span. - String getLocationMessage(String message, int start, int end, - {bool useColors: false, String color}) { - // TODO(jmesserly): it would be more useful to pass in an object that - // controls how the errors are printed. This method is a bit too smart. - var line = getLine(start); - var column = getColumn(line, start); - - var source = url == null ? '' : ' of ${p.prettyUri(url)}'; - var msg = 'line ${line + 1}, column ${column + 1}$source: $message'; - - if (_decodedChars == null) { - // We don't have any text to include, so exit. - return msg; - } - - var buf = new StringBuffer(msg); - buf.write('\n'); - - // +1 for 0-indexing, +1 again to avoid the last line - var textLine = getText(getOffset(line, 0), getOffset(line + 1, 0)); - - column = min(column, textLine.length - 1); - int toColumn = min(column + end - start, textLine.length); - if (useColors) { - if (color == null) { - color = _RED_COLOR; - } - buf.write(textLine.substring(0, column)); - buf.write(color); - buf.write(textLine.substring(column, toColumn)); - buf.write(_NO_COLOR); - buf.write(textLine.substring(toColumn)); - } else { - buf.write(textLine); - if (textLine != '' && !textLine.endsWith('\n')) buf.write('\n'); - } - - int i = 0; - for (; i < column; i++) { - buf.write(' '); - } - - if (useColors) buf.write(color); - for (; i < toColumn; i++) { - buf.write('^'); - } - if (useColors) buf.write(_NO_COLOR); - return buf.toString(); - } -} - -/// A convenience type to treat a code segment as if it were a separate -/// [SourceFile]. A [SourceFileSegment] shifts all locations by an offset, which -/// allows you to set source-map locations based on the locations relative to -/// the start of the segment, but that get translated to absolute locations in -/// the original source file. -@Deprecated("Use the source_span package instead.") -class SourceFileSegment extends SourceFile { - final int _baseOffset; - final int _baseLine; - final int _baseColumn; - final int _maxOffset; - - SourceFileSegment(String url, String textSegment, Location startOffset) - : _baseOffset = startOffset.offset, - _baseLine = startOffset.line, - _baseColumn = startOffset.column, - _maxOffset = startOffset.offset + textSegment.length, - super.text(url, textSegment); - - /// Craete a span, where [start] is relative to this segment's base offset. - /// The returned span stores the real offset on the file, so that error - /// messages are reported at the real location. - Span span(int start, [int end, bool isIdentifier = false]) => - super.span(start + _baseOffset, - end == null ? null : end + _baseOffset, isIdentifier); - - /// Create a location, where [offset] relative to this segment's base offset. - /// The returned span stores the real offset on the file, so that error - /// messages are reported at the real location. - Location location(int offset) => super.location(offset + _baseOffset); - - /// Return the line on the underlying file associated with the [offset] of the - /// underlying file. This method operates on the real offsets from the - /// original file, so that error messages can be reported accurately. When the - /// requested offset is past the length of the segment, this returns the line - /// number after the end of the segment (total lines + 1). - int getLine(int offset) { - var res = super.getLine(max(offset - _baseOffset, 0)) + _baseLine; - return (offset > _maxOffset) ? res + 1 : res; - } - - /// Return the column on the underlying file associated with [line] and - /// [offset], where [line] is absolute from the beginning of the underlying - /// file. This method operates on the real offsets from the original file, so - /// that error messages can be reported accurately. - int getColumn(int line, int offset) { - var col = super.getColumn(line - _baseLine, max(offset - _baseOffset, 0)); - return line == _baseLine ? col + _baseColumn : col; - } - - /// Return the offset associated with a line and column. This method operates - /// on the real offsets from the original file, so that error messages can be - /// reported accurately. - int getOffset(int line, int column) => - super.getOffset(line - _baseLine, - line == _baseLine ? column - _baseColumn : column) + _baseOffset; - - /// Retrieve the text associated with the specified range. This method - /// operates on the real offsets from the original file, so that error - /// messages can be reported accurately. - String getText(int start, [int end]) => - super.getText(start - _baseOffset, end == null ? null : end - _baseOffset); -} - -/// A class for exceptions that have source span information attached. -@Deprecated("Use the source_span package instead.") -class SpanException implements Exception { - /// A message describing the exception. - final String message; - - /// The span associated with this exception. - /// - /// This may be `null` if the source location can't be determined. - final Span span; - - SpanException(this.message, this.span); - - String toString({bool useColors: false, String color}) { - if (span == null) return message; - return "Error on " + span.getLocationMessage(message, - useColors: useColors, color: color); - } -} - -/// A [SpanException] that's also a [FormatException]. -@Deprecated("Use the source_span package instead.") -class SpanFormatException extends SpanException implements FormatException { - final source; - - SpanFormatException(String message, Span span, [this.source]) - : super(message, span); - - int get offset => span == null ? null : span.start.offset; -} diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart new file mode 100644 index 000000000..20eb17ad0 --- /dev/null +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -0,0 +1,59 @@ +// Copyright (c) 2014, 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. + +library source_maps.source_map_span; + +import 'package:source_span/source_span.dart'; + +/// A [SourceSpan] for spans coming from or being written to source maps. +/// +/// These spans have an extra piece of metadata: whether or not they represent +/// an identifier (see [isIdentifier]). +class SourceMapSpan extends SourceSpanBase { + /// Whether this span represents an identifier. + /// + /// If this is `true`, [text] is the value of the identifier. + final bool isIdentifier; + + SourceMapSpan(SourceLocation start, SourceLocation end, String text, + {this.isIdentifier: false}) + : super(start, end, text); + + /// Creates a [SourceMapSpan] for an identifier with value [text] starting at + /// [start]. + /// + /// The [end] location is determined by adding [text] to [start]. + SourceMapSpan.identifier(SourceLocation start, String text) + : this( + start, + new SourceLocation(start.offset + text.length, + sourceUrl: start.sourceUrl, + line: start.line, + column: start.column + text.length), + text, + isIdentifier: true); +} + +/// A wrapper aruond a [FileSpan] that implements [SourceMapSpan]. +class SourceMapFileSpan implements SourceMapSpan, FileSpan { + final FileSpan _inner; + final bool isIdentifier; + + SourceFile get file => _inner.file; + FileLocation get start => _inner.start; + FileLocation get end => _inner.end; + String get text => _inner.text; + Uri get sourceUrl => _inner.sourceUrl; + int get length => _inner.length; + + SourceMapFileSpan(this._inner, {this.isIdentifier: false}); + + int compareTo(SourceSpan other) => _inner.compareTo(other); + SourceSpan union(SourceSpan other) => _inner.union(other); + FileSpan expand(FileSpan other) => _inner.expand(other); + String message(String message, {color}) => + _inner.message(message, color: color); + String toString() => _inner.toString() + .replaceAll("FileSpan", "SourceMapFileSpan"); +} diff --git a/pkgs/source_maps/lib/src/span_wrapper.dart b/pkgs/source_maps/lib/src/span_wrapper.dart deleted file mode 100644 index e0c107bf7..000000000 --- a/pkgs/source_maps/lib/src/span_wrapper.dart +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2014, 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. - -library source_maps.span_wrapper; - -import 'package:source_span/source_span.dart' as source_span; - -import '../span.dart'; - -/// A wrapper that exposes a [source_span.SourceSpan] as a [Span]. -class SpanWrapper extends Span { - final source_span.SourceSpan _inner; - - String get text => _inner.text; - - SpanWrapper(source_span.SourceSpan inner, bool isIdentifier) - : _inner = inner, - super( - new LocationWrapper(inner.start), - new LocationWrapper(inner.end), - isIdentifier); - - static Span wrap(span, [bool isIdentifier = false]) { - if (span is Span) return span; - return new SpanWrapper(span, isIdentifier); - } -} - -/// A wrapper that exposes a [source_span.SourceLocation] as a [Location]. -class LocationWrapper extends Location { - final source_span.SourceLocation _inner; - - String get sourceUrl => _inner.sourceUrl.toString(); - int get line => _inner.line; - int get column => _inner.column; - - LocationWrapper(source_span.SourceLocation inner) - : _inner = inner, - super(inner.offset); - - static Location wrap(location) { - if (location is Location) return location; - return new LocationWrapper(location); - } -} - -/// A wrapper that exposes a [source_span.SourceFile] as a [SourceFile]. -class SourceFileWrapper implements SourceFile { - final source_span.SourceFile _inner; - - // These are necessary to avoid analyzer warnings; - final _lineStarts = null; - final _decodedChars = null; - - String get url => _inner.url.toString(); - - SourceFileWrapper(this._inner); - - static SourceFile wrap(sourceFile) { - if (sourceFile is SourceFile) return sourceFile; - return new SourceFileWrapper(sourceFile); - } - - Span span(int start, [int end, bool isIdentifier = false]) { - if (end == null) end = start; - return new SpanWrapper(_inner.span(start, end), isIdentifier); - } - - Location location(int offset) => new LocationWrapper(_inner.location(offset)); - - int getLine(int offset) => _inner.getLine(offset); - - int getColumn(int line, int offset) => _inner.getColumn(offset, line: line); - - int getOffset(int line, int column) => _inner.getOffset(line, column); - - String getText(int start, [int end]) => _inner.getText(start, end); - - String getLocationMessage(String message, int start, int end, - {bool useColors: false, String color}) { - return span(start, end).getLocationMessage(message, - useColors: useColors, color: color); - } -} diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index 8842c62cb..ca0ca8d2d 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -16,7 +16,7 @@ main() { ..addSpan(inputFunction, outputFunction) ..addSpan(inputVar2, outputVar2) ..addSpan(inputExpr, outputExpr)) - .build(output.url); + .build(output.url.toString()); expect(map, equals(EXPECTED_MAP)); }); @@ -26,7 +26,7 @@ main() { ..addLocation(inputFunction.start, outputFunction.start, 'longName') ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') ..addLocation(inputExpr.start, outputExpr.start, null)) - .toJson(output.url); + .toJson(output.url.toString()); expect(str, JSON.encode(EXPECTED_MAP)); }); } diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index 0c1f28a74..73a8d406b 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -6,6 +6,7 @@ library test.common; import 'package:source_maps/source_maps.dart'; +import 'package:source_span/source_span.dart'; import 'package:unittest/unittest.dart'; /// Content of the source file @@ -18,40 +19,40 @@ int longName(int longVar2) { return longVar1 + longVar2; } '''; -var input = new SourceFile.text('input.dart', INPUT); +var input = new SourceFile(INPUT, url: 'input.dart'); /// A span in the input file -Span ispan(int start, int end, [bool isIdentifier = false]) => - new FileSpan(input, start, end, isIdentifier); +SourceMapSpan ispan(int start, int end, [bool isIdentifier = false]) => + new SourceMapFileSpan(input.span(start, end), isIdentifier: isIdentifier); -Span inputVar1 = ispan(30, 38, true); -Span inputFunction = ispan(74, 82, true); -Span inputVar2 = ispan(87, 95, true); +SourceMapSpan inputVar1 = ispan(30, 38, true); +SourceMapSpan inputFunction = ispan(74, 82, true); +SourceMapSpan inputVar2 = ispan(87, 95, true); -Span inputVar1NoSymbol = ispan(30, 38); -Span inputFunctionNoSymbol = ispan(74, 82); -Span inputVar2NoSymbol = ispan(87, 95); +SourceMapSpan inputVar1NoSymbol = ispan(30, 38); +SourceMapSpan inputFunctionNoSymbol = ispan(74, 82); +SourceMapSpan inputVar2NoSymbol = ispan(87, 95); -Span inputExpr = ispan(108, 127); +SourceMapSpan inputExpr = ispan(108, 127); /// Content of the target file const String OUTPUT = ''' var x = 3; f(y) => x + y; '''; -var output = new SourceFile.text('output.dart', OUTPUT); +var output = new SourceFile(OUTPUT, url: 'output.dart'); /// A span in the output file -Span ospan(int start, int end, [bool isIdentifier = false]) => - new FileSpan(output, start, end, isIdentifier); +SourceMapSpan ospan(int start, int end, [bool isIdentifier = false]) => + new SourceMapFileSpan(output.span(start, end), isIdentifier: isIdentifier); -Span outputVar1 = ospan(4, 5, true); -Span outputFunction = ospan(11, 12, true); -Span outputVar2 = ospan(13, 14, true); -Span outputVar1NoSymbol = ospan(4, 5); -Span outputFunctionNoSymbol = ospan(11, 12); -Span outputVar2NoSymbol = ospan(13, 14); -Span outputExpr = ospan(19, 24); +SourceMapSpan outputVar1 = ospan(4, 5, true); +SourceMapSpan outputFunction = ospan(11, 12, true); +SourceMapSpan outputVar2 = ospan(13, 14, true); +SourceMapSpan outputVar1NoSymbol = ospan(4, 5); +SourceMapSpan outputFunctionNoSymbol = ospan(11, 12); +SourceMapSpan outputVar2NoSymbol = ospan(13, 14); +SourceMapSpan outputExpr = ospan(19, 24); /// Expected output mapping when recording the following four mappings: /// inputVar1 <= outputVar1 @@ -70,7 +71,8 @@ const Map EXPECTED_MAP = const { 'file': 'output.dart' }; -check(Span outputSpan, Mapping mapping, Span inputSpan, bool realOffsets) { +check(SourceSpan outputSpan, Mapping mapping, SourceMapSpan inputSpan, + bool realOffsets) { var line = outputSpan.start.line; var column = outputSpan.start.column; var files = realOffsets ? {'input.dart': input} : null; diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 99fe40d40..7dbc6bd9b 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -6,6 +6,7 @@ library test.end2end_test; import 'package:unittest/unittest.dart'; import 'package:source_maps/source_maps.dart'; +import 'package:source_span/source_span.dart'; import 'common.dart'; main() { @@ -33,7 +34,7 @@ main() { ..addSpan(inputFunction, outputFunction) ..addSpan(inputVar2, outputVar2) ..addSpan(inputExpr, outputExpr)) - .build(output.url); + .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1, mapping, inputVar1, false); check(outputVar2, mapping, inputVar2, false); @@ -47,7 +48,7 @@ main() { ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) ..addSpan(inputExpr, outputExpr)) - .build(output.url); + .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false); check(outputVar2NoSymbol, mapping, inputVar2NoSymbol, false); @@ -65,7 +66,7 @@ main() { ..addSpan(inputVar2, outputVar2) ..addSpan(inputExpr, outputExpr) ..addSpan(inputExpr, outputExpr)) - .build(output.url); + .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1, mapping, inputVar1, false); check(outputVar2, mapping, inputVar2, false); @@ -82,7 +83,7 @@ main() { ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) ..addSpan(inputExpr, outputExpr)) - .build(output.url); + .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false); check(outputVar2NoSymbol, mapping, inputVar2NoSymbol, false); @@ -96,7 +97,7 @@ main() { ..addSpan(inputFunction, outputFunction) ..addSpan(inputVar2, outputVar2) ..addSpan(inputExpr, outputExpr)) - .toJson(output.url); + .toJson(output.url.toString()); var mapping = parse(json); check(outputVar1, mapping, inputVar1, true); check(outputVar2, mapping, inputVar2, true); @@ -106,7 +107,7 @@ main() { test('printer projecting marks + parse', () { var out = INPUT.replaceAll('long', '_s'); - var file = new SourceFile.text('output2.dart', out); + var file = new SourceFile(out, url: 'output2.dart'); var printer = new Printer('output2.dart'); printer.mark(ispan(0, 0)); @@ -132,10 +133,11 @@ main() { expect(printer.text, out); var mapping = parse(printer.map); - checkHelper(Span inputSpan, int adjustment) { + checkHelper(SourceMapSpan inputSpan, int adjustment) { var start = inputSpan.start.offset - adjustment; var end = (inputSpan.end.offset - adjustment) - 2; - var span = new FileSpan(file, start, end, inputSpan.isIdentifier); + var span = new SourceMapFileSpan(file.span(start, end), + isIdentifier: inputSpan.isIdentifier); check(span, mapping, inputSpan, true); } @@ -145,17 +147,16 @@ main() { checkHelper(inputExpr, 6); // We projected correctly lines that have no mappings - check(new FileSpan(file, 66, 66, false), mapping, ispan(45, 45), true); - check(new FileSpan(file, 63, 64, false), mapping, ispan(45, 45), true); - check(new FileSpan(file, 68, 68, false), mapping, ispan(70, 70), true); - check(new FileSpan(file, 71, 71, false), mapping, ispan(70, 70), true); + check(file.span(66, 66), mapping, ispan(45, 45), true); + check(file.span(63, 64), mapping, ispan(45, 45), true); + check(file.span(68, 68), mapping, ispan(70, 70), true); + check(file.span(71, 71), mapping, ispan(70, 70), true); // Start of the last line var oOffset = out.length - 2; var iOffset = INPUT.length - 2; - check(new FileSpan(file, oOffset, oOffset, false), mapping, - ispan(iOffset, iOffset), true); - check(new FileSpan(file, oOffset + 1, oOffset + 1, false), mapping, + check(file.span(oOffset, oOffset), mapping, ispan(iOffset, iOffset), true); + check(file.span(oOffset + 1, oOffset + 1), mapping, ispan(iOffset, iOffset), true); }); } diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 62cd08f1f..8528683f3 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -104,7 +104,7 @@ main() { var inputMap = new Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = '/pkg/'; var mapping = parseJson(inputMap); - expect(mapping.spanFor(0, 0).sourceUrl, "/pkg/input.dart"); + expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse("/pkg/input.dart")); var newSourceRoot = '/new/'; diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index fe27f76c0..e55ca9f6e 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -6,8 +6,8 @@ library test.printer_test; import 'dart:convert'; import 'package:unittest/unittest.dart'; -import 'package:source_maps/printer.dart'; -import 'package:source_maps/span.dart'; +import 'package:source_maps/source_maps.dart'; +import 'package:source_span/source_span.dart'; import 'common.dart'; main() { @@ -53,13 +53,12 @@ main() { // 8 new lines in the source map: expect(printer.map.split(';').length, 8); - asFixed(Span s) => new FixedSpan(s.sourceUrl, - s.start.offset, s.start.line, s.start.column, - text: s.text, isIdentifier: s.isIdentifier); + asFixed(SourceMapSpan s) => new SourceMapSpan(s.start, s.end, s.text, + isIdentifier: s.isIdentifier); // The result is the same if we use fixed positions var printer2 = new Printer('output2.dart'); - printer2..mark(new FixedSpan('input.dart', 0, 0, 0)) + printer2..mark(new SourceLocation(0, sourceUrl: 'input.dart').pointSpan()) ..add(segments[0], projectMarks: true) ..mark(asFixed(inputVar1)) ..add('_s') diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 5d0abf1e2..08b896510 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -6,13 +6,13 @@ library polymer.test.refactor_test; import 'package:unittest/unittest.dart'; import 'package:source_maps/refactor.dart'; -import 'package:source_maps/span.dart'; import 'package:source_maps/parser.dart' show parse, Mapping; +import 'package:source_span/source_span.dart'; main() { group('conflict detection', () { var original = "0123456789abcdefghij"; - var file = new SourceFile.text('', original); + var file = new SourceFile(original); test('no conflict, in order', () { var txn = new TextEditTransaction(original, file); @@ -48,7 +48,7 @@ main() { test('generated source maps', () { var original = "0123456789\n0*23456789\n01*3456789\nabcdefghij\nabcd*fghij\n"; - var file = new SourceFile.text('', original); + var file = new SourceFile(original); var txn = new TextEditTransaction(original, file); txn.edit(27, 29, '__\n '); txn.edit(34, 35, '___'); @@ -60,42 +60,90 @@ main() { // Line 1 and 2 are unmodified: mapping any column returns the beginning // of the corresponding line: - expect(_span(1, 1, map, file), "line 1, column 1 of .: \n0123456789"); - expect(_span(1, 5, map, file), "line 1, column 1 of .: \n0123456789"); - expect(_span(2, 1, map, file), "line 2, column 1 of .: \n0*23456789"); - expect(_span(2, 8, map, file), "line 2, column 1 of .: \n0*23456789"); + expect(_span(1, 1, map, file), + "line 1, column 1: \n" + "0123456789\n" + "^"); + expect(_span(1, 5, map, file), + "line 1, column 1: \n" + "0123456789\n" + "^"); + expect(_span(2, 1, map, file), + "line 2, column 1: \n" + "0*23456789\n" + "^"); + expect(_span(2, 8, map, file), + "line 2, column 1: \n" + "0*23456789\n" + "^"); // Line 3 is modified part way: mappings before the edits have the right // mapping, after the edits the mapping is null. - expect(_span(3, 1, map, file), "line 3, column 1 of .: \n01*3456789"); - expect(_span(3, 5, map, file), "line 3, column 1 of .: \n01*3456789"); + expect(_span(3, 1, map, file), + "line 3, column 1: \n" + "01*3456789\n" + "^"); + expect(_span(3, 5, map, file), + "line 3, column 1: \n" + "01*3456789\n" + "^"); // Start of edits map to beginning of the edit secion: - expect(_span(3, 6, map, file), "line 3, column 6 of .: \n01*3456789"); - expect(_span(3, 7, map, file), "line 3, column 6 of .: \n01*3456789"); + expect(_span(3, 6, map, file), + "line 3, column 6: \n" + "01*3456789\n" + " ^"); + expect(_span(3, 7, map, file), + "line 3, column 6: \n" + "01*3456789\n" + " ^"); // Lines added have no mapping (they should inherit the last mapping), // but the end of the edit region continues were we left off: expect(_span(4, 1, map, file), isNull); - expect(_span(4, 5, map, file), "line 3, column 8 of .: \n01*3456789"); + expect(_span(4, 5, map, file), + "line 3, column 8: \n" + "01*3456789\n" + " ^"); // Subsequent lines are still mapped correctly: // a (in a___cd...) - expect(_span(5, 1, map, file), "line 4, column 1 of .: \nabcdefghij"); + expect(_span(5, 1, map, file), + "line 4, column 1: \n" + "abcdefghij\n" + "^"); // _ (in a___cd...) - expect(_span(5, 2, map, file), "line 4, column 2 of .: \nabcdefghij"); + expect(_span(5, 2, map, file), + "line 4, column 2: \n" + "abcdefghij\n" + " ^"); // _ (in a___cd...) - expect(_span(5, 3, map, file), "line 4, column 2 of .: \nabcdefghij"); + expect(_span(5, 3, map, file), + "line 4, column 2: \n" + "abcdefghij\n" + " ^"); // _ (in a___cd...) - expect(_span(5, 4, map, file), "line 4, column 2 of .: \nabcdefghij"); + expect(_span(5, 4, map, file), + "line 4, column 2: \n" + "abcdefghij\n" + " ^"); // c (in a___cd...) - expect(_span(5, 5, map, file), "line 4, column 3 of .: \nabcdefghij"); - expect(_span(6, 1, map, file), "line 5, column 1 of .: \nabcd*fghij"); - expect(_span(6, 8, map, file), "line 5, column 1 of .: \nabcd*fghij"); + expect(_span(5, 5, map, file), + "line 4, column 3: \n" + "abcdefghij\n" + " ^"); + expect(_span(6, 1, map, file), + "line 5, column 1: \n" + "abcd*fghij\n" + "^"); + expect(_span(6, 8, map, file), + "line 5, column 1: \n" + "abcd*fghij\n" + "^"); }); } String _span(int line, int column, Mapping map, SourceFile file) { var span = map.spanFor(line - 1, column - 1, files: {'': file}); - return span == null ? null : span.getLocationMessage('').trim(); + return span == null ? null : span.message('').trim(); } diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart index 21d20377e..ec3c3ab7f 100755 --- a/pkgs/source_maps/test/run.dart +++ b/pkgs/source_maps/test/run.dart @@ -14,7 +14,6 @@ import 'end2end_test.dart' as end2end_test; import 'parser_test.dart' as parser_test; import 'printer_test.dart' as printer_test; import 'refactor_test.dart' as refactor_test; -import 'span_test.dart' as span_test; import 'utils_test.dart' as utils_test; import 'vlq_test.dart' as vlq_test; @@ -33,7 +32,6 @@ main(List arguments) { addGroup('parser_test.dart', parser_test.main); addGroup('printer_test.dart', printer_test.main); addGroup('refactor_test.dart', refactor_test.main); - addGroup('span_test.dart', span_test.main); addGroup('utils_test.dart', utils_test.main); addGroup('vlq_test.dart', vlq_test.main); } diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart deleted file mode 100644 index 190b7a66b..000000000 --- a/pkgs/source_maps/test/span_test.dart +++ /dev/null @@ -1,341 +0,0 @@ -// Copyright (c) 2013, 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. - -library test.span_test; - -import 'package:unittest/unittest.dart'; -import 'package:source_maps/span.dart'; - -const String TEST_FILE = ''' -+23456789_ - + _123456789_123456789_123456789_123456789_123456789_123456789_123456789_ - + _123456789_1 -123+56789_123456789_1234567 -1234+6789_1234 -12345+789_123456789_12345 -123456+89_123456789_123456789_123456789_123456789_123456789_123456789_123456789 -1234567+9_123456789_123456789_123456789_123456789_123456789_123456789_123 -12345678+_123456789_123456789_123456789_123456789_1 -123456789+123456789_123456789_12345678 -123456789_+23456789_123456789_123456789_123 -123456789_1+3456789_123456789 -'''; - -List newLines = TEST_FILE.split('\n').map((s) => s.length).toList(); - -main() { - var file = new SourceFile.text('file', TEST_FILE); - span(int start, int end) => file.span(start, end); - loc(int offset) => file.location(offset); - - test('validate test input', () { - expect(newLines, - const [10, 80, 31, 27, 14, 25, 79, 73, 51, 38, 43, 29, 0]); - }); - - test('get line and column', () { - line(int n) => file.getLine(n); - col(int n) => file.getColumn(file.getLine(n), n); - - expect(line(8), 0); - expect(line(10), 0); - expect(line(11), 1); - expect(line(12), 1); - expect(line(91), 1); - expect(line(92), 2); - expect(line(93), 2); - expect(col(11), 0); - expect(col(12), 1); - expect(col(91), 80); - expect(col(92), 0); - expect(col(93), 1); - - int j = 0; - int lineOffset = 0; - for (int i = 0; i < TEST_FILE.length; i++) { - if (i > lineOffset + newLines[j]) { - lineOffset += newLines[j] + 1; - j++; - } - expect(line(i), j, reason: 'position: $i'); - expect(col(i), i - lineOffset, reason: 'position: $i'); - } - }); - - test('get text', () { - // fifth line (including 4 new lines), columns 2 .. 11 - var line = 10 + 80 + 31 + 27 + 4; - expect(file.getText(line + 2, line + 11), '34+6789_1'); - }); - - group('location message', () { - test('first line', () { - expect(file.getLocationMessage('the message', 1, 3), - 'line 1, column 2 of file: the message\n' - '+23456789_\n' - ' ^^'); - }); - - test('in the middle of the file', () { - // fifth line (including 4 new lines), columns 2 .. 11 - var line = 10 + 80 + 31 + 27 + 4; - expect(file.getLocationMessage('the message', line + 2, line + 11), - 'line 5, column 3 of file: the message\n' - '1234+6789_1234\n' - ' ^^^^^^^^^'); - }); - - test('no file url', () { - var line = 10 + 80 + 31 + 27 + 4; - expect(new SourceFile.text(null, TEST_FILE).getLocationMessage( - 'the message', line + 2, line + 11), - 'line 5, column 3: the message\n' - '1234+6789_1234\n' - ' ^^^^^^^^^'); - }); - - test('penultimate line', () { - // We search '\n' backwards twice because last line is \n terminated: - int index = TEST_FILE.lastIndexOf('\n'); - var start = TEST_FILE.lastIndexOf('\n', index - 1) - 3; - expect(file.getLocationMessage('the message', start, start + 2), - 'line 11, column 41 of file: the message\n' - '123456789_+23456789_123456789_123456789_123\n' - ' ^^'); - }); - - test('last line', () { - var start = TEST_FILE.lastIndexOf('\n') - 2; - expect(file.getLocationMessage('the message', start, start + 1), - 'line 12, column 28 of file: the message\n' - '123456789_1+3456789_123456789\n' - ' ^'); - }); - - group('no trailing empty-line at the end -', () { - var text = TEST_FILE.substring(0, TEST_FILE.length - 1); - var file2 = new SourceFile.text('file', text); - - test('penultimate line', () { - var start = text.lastIndexOf('\n') - 3; - expect(file2.getLocationMessage('the message', start, start + 2), - 'line 11, column 41 of file: the message\n' - '123456789_+23456789_123456789_123456789_123\n' - ' ^^'); - }); - - test('last line', () { - var start = text.length - 2; - expect(file2.getLocationMessage('the message', start, start + 1), - 'line 12, column 28 of file: the message\n' - '123456789_1+3456789_123456789\n' - ' ^'); - }); - }); - - test('single line', () { - var text = "this is a single line"; - int start = text.indexOf(' ') + 1; - var file2 = new SourceFile.text('file', text); - expect(file2.getLocationMessage('the message', start, start + 2), - 'line 1, column ${start + 1} of file: the message\n' - 'this is a single line\n' - ' ^^'); - }); - }); - - test('location getters', () { - expect(loc(8).line, 0); - expect(loc(8).column, 8); - expect(loc(9).line, 0); - expect(loc(9).column, 9); - expect(loc(8).formatString, 'file:1:9'); - expect(loc(12).line, 1); - expect(loc(12).column, 1); - expect(loc(95).line, 2); - expect(loc(95).column, 3); - }); - - test('location compare', () { - var list = [9, 8, 11, 14, 6, 6, 1, 1].map((n) => loc(n)).toList(); - list.sort(); - var lastOffset = 0; - for (var location in list) { - expect(location.offset, greaterThanOrEqualTo(lastOffset)); - lastOffset = location.offset; - } - }); - - test('span getters', () { - expect(span(8, 9).start.line, 0); - expect(span(8, 9).start.column, 8); - expect(span(8, 9).end.line, 0); - expect(span(8, 9).end.column, 9); - expect(span(8, 9).text, '9'); - expect(span(8, 9).isIdentifier, false); - expect(span(8, 9).formatLocation, 'file:1:9'); - - var line = 10 + 80 + 31 + 27 + 4; - expect(span(line + 2, line + 11).getLocationMessage('the message'), - 'line 5, column 3 of file: the message\n' - '1234+6789_1234\n' - ' ^^^^^^^^^'); - - expect(span(12, 95).start.line, 1); - expect(span(12, 95).start.column, 1); - expect(span(12, 95).end.line, 2); - expect(span(12, 95).end.column, 3); - expect(span(12, 95).text, - '+ _123456789_123456789_123456789_123456789_123456789_1234567' - '89_123456789_\n +'); - expect(span(12, 95).formatLocation, 'file:2:2'); - }); - - test('span union', () { - var union = new FileSpan.union(span(8, 9), span(12, 95)); - expect(union.start.offset, 8); - expect(union.start.line, 0); - expect(union.start.column, 8); - expect(union.end.offset, 95); - expect(union.end.line, 2); - expect(union.end.column, 3); - expect(union.text, - '9_\n' - ' + _123456789_123456789_123456789_123456789_123456789_' - '123456789_123456789_\n +'); - expect(union.formatLocation, 'file:1:9'); - }); - - test('span compare', () { - var list = [span(9, 10), span(8, 9), span(11, 12), span(14, 19), - span(6, 12), span(6, 8), span(1, 9), span(1, 2)]; - list.sort(); - var lastStart = 0; - var lastEnd = 0; - for (var span in list) { - expect(span.start.offset, greaterThanOrEqualTo(lastStart)); - if (span.start.offset == lastStart) { - expect(span.end.offset, greaterThanOrEqualTo(lastEnd)); - } - lastStart = span.start.offset; - lastEnd = span.end.offset; - } - }); - - test('range check for large offsets', () { - var start = TEST_FILE.length; - expect(file.getLocationMessage('the message', start, start + 9), - 'line 13, column 1 of file: the message\n'); - }); - - group('file segment', () { - var baseOffset = 123; - var segmentText = TEST_FILE.substring(baseOffset, TEST_FILE.length - 100); - var segment = new SourceFileSegment('file', segmentText, loc(baseOffset)); - sline(int n) => segment.getLine(n); - scol(int n) => segment.getColumn(segment.getLine(n), n); - line(int n) => file.getLine(n); - col(int n) => file.getColumn(file.getLine(n), n); - - test('get line and column', () { - int j = 0; - int lineOffset = 0; - for (int i = baseOffset; i < segmentText.length; i++) { - if (i > lineOffset + newLines[j]) { - lineOffset += newLines[j] + 1; - j++; - } - expect(segment.location(i - baseOffset).offset, i); - expect(segment.location(i - baseOffset).line, line(i)); - expect(segment.location(i - baseOffset).column, col(i)); - expect(segment.span(i - baseOffset).start.offset, i); - expect(segment.span(i - baseOffset).start.line, line(i)); - expect(segment.span(i - baseOffset).start.column, col(i)); - - expect(sline(i), line(i)); - expect(scol(i), col(i)); - } - }); - - test('get text', () { - var start = 10 + 80 + 31 + 27 + 4 + 2; - expect(segment.getText(start, start + 9), file.getText(start, start + 9)); - }); - - group('location message', () { - test('first line', () { - var start = baseOffset + 7; - expect(segment.getLocationMessage('the message', start, start + 2), - file.getLocationMessage('the message', start, start + 2)); - }); - - test('in a middle line', () { - // Example from another test above: - var start = 10 + 80 + 31 + 27 + 4 + 2; - expect(segment.getLocationMessage('the message', start, start + 9), - file.getLocationMessage('the message', start, start + 9)); - }); - - test('last segment line', () { - var start = segmentText.length - 4; - expect(segment.getLocationMessage('the message', start, start + 2), - file.getLocationMessage('the message', start, start + 2)); - }); - - test('past segment, same as last segment line', () { - var start = segmentText.length; - expect(segment.getLocationMessage('the message', start, start + 2), - file.getLocationMessage('the message', start, start + 2)); - - start = segmentText.length + 20; - expect(segment.getLocationMessage('the message', start, start + 2), - file.getLocationMessage('the message', start, start + 2)); - }); - - test('past segment, past its line', () { - var start = TEST_FILE.length - 2; - expect(file.getLocationMessage('the message', start, start + 1), - 'line 12, column 29 of file: the message\n' - '123456789_1+3456789_123456789\n' - ' ^'); - - // The answer below is different because the segment parsing only knows - // about the 10 lines it has (and nothing about the possible extra lines - // afterwards) - expect(segment.getLocationMessage('the message', start, start + 1), - 'line 11, column 1 of file: the message\n'); - }); - }); - }); - - test('span isIdentifier defaults to false', () { - var start = new TestLocation(0); - var end = new TestLocation(1); - expect(new TestSpan(start, end).isIdentifier, false); - expect(file.span(8, 9, null).isIdentifier, false); - expect(new FixedSpan('', 8, 1, 8, isIdentifier: null).isIdentifier, false); - }); - - test('span/location implement == and hashCode', () { - expect(identical(span(10, 14), span(10, 14)), isFalse); - expect(span(10, 14), equals(span(10, 14))); - expect(span(10, 14).hashCode, span(10, 14).hashCode); - - expect(identical(loc(13), loc(13)), isFalse); - expect(loc(13), equals(loc(13))); - expect(loc(13).hashCode, loc(13).hashCode); - }); -} - -class TestSpan extends Span { - TestSpan(Location start, Location end) : super(start, end, null); - get text => null; -} - -class TestLocation extends Location { - String get sourceUrl => ''; - TestLocation(int offset) : super(offset); - get line => 0; - get column => 0; -} From 4cb3edebe57134b861f633a4d9c79746fd0770d5 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 1 Aug 2014 00:39:29 +0000 Subject: [PATCH 045/657] Actually release source_maps 0.10.0. BUG=19930 R=sigmund@google.com Review URL: https://codereview.chromium.org//430343002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38813 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 5 +++++ pkgs/source_maps/pubspec.yaml | 10 +--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 6d371c9bf..a70bc4480 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.0 + +* Remove the `Span`, `Location` and `SourceFile` classes. Use the + corresponding `source_span` classes instead. + ## 0.9.4 * Update `SpanFormatException` with `source` and `offset`. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 0548215b1..4af996e56 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,13 +1,5 @@ name: source_maps - -# Note! This version number is referenced directly in the pub source code in -# lib/src/barback.dart. Pub implicitly places a version constraint on -# source_maps to ensure users only select a version of source_maps that works -# with their current version of pub. -# -# When the minor version is upgraded, you *must* update that version constraint -# in pub to stay in sync with this. -version: 0.9.4-dev +version: 0.10.0 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From 340c972dd0e286892210e4c84bd81c463b371f10 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Thu, 25 Sep 2014 11:28:42 -0700 Subject: [PATCH 046/657] Initial commit! --- pkgs/pub_semver/LICENSE | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 pkgs/pub_semver/LICENSE diff --git a/pkgs/pub_semver/LICENSE b/pkgs/pub_semver/LICENSE new file mode 100644 index 000000000..5c60afea3 --- /dev/null +++ b/pkgs/pub_semver/LICENSE @@ -0,0 +1,26 @@ +Copyright 2014, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 56cc24edf25aaab06df40f8bff25fb17cba5aa4f Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Fri, 26 Sep 2014 12:54:39 -0700 Subject: [PATCH 047/657] Harvest from pub. Mostly a straight copy, except: - Reorganized into smaller libraries. - Added tests for prioritize() and antiprioritize(). - Filled in a few doc comments. R=nweiz@google.com Review URL: https://chromiumcodereview.appspot.com//607663002 --- pkgs/pub_semver/.gitignore | 5 + pkgs/pub_semver/CHANGELOG.md | 3 + pkgs/pub_semver/README.md | 77 +++++ pkgs/pub_semver/lib/pub_semver.dart | 9 + pkgs/pub_semver/lib/src/patterns.dart | 19 ++ pkgs/pub_semver/lib/src/version.dart | 295 ++++++++++++++++++ .../lib/src/version_constraint.dart | 151 +++++++++ pkgs/pub_semver/lib/src/version_range.dart | 179 +++++++++++ pkgs/pub_semver/pubspec.yaml | 13 + pkgs/pub_semver/test/test_all.dart | 17 + pkgs/pub_semver/test/utils.dart | 96 ++++++ .../test/version_constraint_test.dart | 143 +++++++++ pkgs/pub_semver/test/version_range_test.dart | 202 ++++++++++++ pkgs/pub_semver/test/version_test.dart | 248 +++++++++++++++ 14 files changed, 1457 insertions(+) create mode 100644 pkgs/pub_semver/.gitignore create mode 100644 pkgs/pub_semver/CHANGELOG.md create mode 100644 pkgs/pub_semver/README.md create mode 100644 pkgs/pub_semver/lib/pub_semver.dart create mode 100644 pkgs/pub_semver/lib/src/patterns.dart create mode 100644 pkgs/pub_semver/lib/src/version.dart create mode 100644 pkgs/pub_semver/lib/src/version_constraint.dart create mode 100644 pkgs/pub_semver/lib/src/version_range.dart create mode 100644 pkgs/pub_semver/pubspec.yaml create mode 100644 pkgs/pub_semver/test/test_all.dart create mode 100644 pkgs/pub_semver/test/utils.dart create mode 100644 pkgs/pub_semver/test/version_constraint_test.dart create mode 100644 pkgs/pub_semver/test/version_range_test.dart create mode 100644 pkgs/pub_semver/test/version_test.dart diff --git a/pkgs/pub_semver/.gitignore b/pkgs/pub_semver/.gitignore new file mode 100644 index 000000000..7178642c2 --- /dev/null +++ b/pkgs/pub_semver/.gitignore @@ -0,0 +1,5 @@ +packages +pubspec.lock + +# IntelliJ project. +.idea diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md new file mode 100644 index 000000000..bf0e1f93f --- /dev/null +++ b/pkgs/pub_semver/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 + +* Initial release. diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md new file mode 100644 index 000000000..1cb152791 --- /dev/null +++ b/pkgs/pub_semver/README.md @@ -0,0 +1,77 @@ +Handles version numbers and version constraints in the same way that [pub][] +does. The semantics here very closely follow the [Semantic Versioning][semver] +spec. It differs from semver in a few corner cases: + + * **Version ordering does take build suffixes into account.** This is unlike + semver 2.0.0 but like earlier versions of semver. Version `1.2.3+1` is + considered a lower number than `1.2.3+2`. + + Since a package may have published multiple versions that differ only by + build suffix, pub still has to pick one of them *somehow*. Semver leaves + that issue unresolved, so we just say that build numbers are sorted like + pre-release suffixes. + + * **Pre-release versions are excluded from most max ranges.** Let's say a + user is depending on "foo" with constraint `>=1.0.0 <2.0.0` and that "foo" + has published these versions: + + * `1.0.0` + * `1.1.0` + * `1.2.0` + * `2.0.0-alpha` + * `2.0.0-beta` + * `2.0.0` + * `2.1.0` + + Versions `2.0.0` and `2.1.0` are excluded by the constraint since neither + matches `<2.0.0`. However, since semver specifies that pre-release versions + are lower than the non-prerelease version (i.e. `2.0.0-beta < 2.0.0`, then + the `<2.0.0` constraint does technically allow those. + + But that's almost never what the user wants. If their package doesn't work + with foo `2.0.0`, it's certainly not likely to work with experimental, + unstable versions of `2.0.0`'s API, which is what pre-release versions + represent. + + To handle that, `<` version ranges to not allow pre-release versions of the + maximum unless the max is itself a pre-release. In other words, a `<2.0.0` + constraint will prohibit not just `2.0.0` but any pre-release of `2.0.0`. + However, `<2.0.0-beta` will exclude `2.0.0-beta` but allow `2.0.0-alpha`. + + * **Pre-release versions are avoided when possible.** The above case + handles pre-release versions at the top of the range, but what about in + the middle? What if "foo" has these versions: + + * `1.0.0` + * `1.2.0-alpha` + * `1.2.0` + * `1.3.0-experimental` + + When a number of versions are valid, pub chooses the best one where "best" + usually means "highest numbered". That follows the user's intuition that, + all else being equal, they want the latest and greatest. Here, that would + mean `1.3.0-experimental`. However, most users don't want to use unstable + versions of their dependencies. + + We want pre-releases to be explicitly opt-in so that package consumers + don't get unpleasant surprises and so that package maintainers are free to + put out pre-releases and get feedback without dragging all of their users + onto the bleeding edge. + + To accommodate that, when pub is choosing a version, it uses *priority* + order which is different from strict comparison ordering. Any stable + version is considered higher priority than any unstable version. The above + versions, in priority order, are: + + * `1.2.0-alpha` + * `1.3.0-experimental` + * `1.0.0` + * `1.2.0` + + This ensures that users only end up with an unstable version when there are + no alternatives. Usually this means they've picked a constraint that + specifically selects that unstable version -- they've deliberately opted + into it. + +[pub]: http://pub.dartlang.org/ +[semver]: http://semver.org/ diff --git a/pkgs/pub_semver/lib/pub_semver.dart b/pkgs/pub_semver/lib/pub_semver.dart new file mode 100644 index 000000000..436e22600 --- /dev/null +++ b/pkgs/pub_semver/lib/pub_semver.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2014, 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. + +library pub_semver; + +export 'src/version.dart'; +export 'src/version_constraint.dart'; +export 'src/version_range.dart'; diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart new file mode 100644 index 000000000..4a2261815 --- /dev/null +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2014, 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. + +library pub_semver.src.patterns; + +/// Regex that matches a version number at the beginning of a string. +final START_VERSION = new RegExp( + r'^' // Start at beginning. + r'(\d+).(\d+).(\d+)' // Version number. + r'(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?' // Pre-release. + r'(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?'); // Build. + +/// Like [START_VERSION] but matches the entire string. +final COMPLETE_VERSION = new RegExp(START_VERSION.pattern + r'$'); + +/// Parses a comparison operator ("<", ">", "<=", or ">=") at the beginning of +/// a string. +final START_COMPARISON = new RegExp(r"^[<>]=?"); diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart new file mode 100644 index 000000000..866d89c30 --- /dev/null +++ b/pkgs/pub_semver/lib/src/version.dart @@ -0,0 +1,295 @@ +// Copyright (c) 2014, 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. + +library pub_semver.src.version; + +import 'dart:math'; + +import 'package:collection/equality.dart'; + +import 'patterns.dart'; +import 'version_constraint.dart'; +import 'version_range.dart'; + +/// The equality operator to use for comparing version components. +final _equality = const IterableEquality(); + +/// A parsed semantic version number. +class Version implements Comparable, VersionConstraint { + /// No released version: i.e. "0.0.0". + static Version get none => new Version(0, 0, 0); + + /// Compares [a] and [b] to see which takes priority over the other. + /// + /// Returns `1` if [a] takes priority over [b] and `-1` if vice versa. If + /// [a] and [b] are equivalent, returns `0`. + /// + /// Unlike [compareTo], which *orders* versions, this determines which + /// version a user is likely to prefer. In particular, it prioritizes + /// pre-release versions lower than stable versions, regardless of their + /// version numbers. Pub uses this when determining which version to prefer + /// when a number of versions are allowed. In that case, it will always + /// choose a stable version when possible. + /// + /// When used to sort a list, orders in ascending priority so that the + /// highest priority version is *last* in the result. + static int prioritize(Version a, Version b) { + // Sort all prerelease versions after all normal versions. This way + // the solver will prefer stable packages over unstable ones. + if (a.isPreRelease && !b.isPreRelease) return -1; + if (!a.isPreRelease && b.isPreRelease) return 1; + + return a.compareTo(b); + } + + /// Like [proiritize], but lower version numbers are considered greater than + /// higher version numbers. + /// + /// This still considers prerelease versions to be lower than non-prerelease + /// versions. Pub uses this when downgrading -- it chooses the lowest version + /// but still excludes pre-release versions when possible. + static int antiprioritize(Version a, Version b) { + if (a.isPreRelease && !b.isPreRelease) return -1; + if (!a.isPreRelease && b.isPreRelease) return 1; + + return b.compareTo(a); + } + + /// The major version number: "1" in "1.2.3". + final int major; + + /// The minor version number: "2" in "1.2.3". + final int minor; + + /// The patch version number: "3" in "1.2.3". + final int patch; + + /// The pre-release identifier: "foo" in "1.2.3-foo". + /// + /// This is split into a list of components, each of which may be either a + /// string or a non-negative integer. It may also be empty, indicating that + /// this version has no pre-release identifier. + final List preRelease; + + /// The build identifier: "foo" in "1.2.3+foo". + /// + /// This is split into a list of components, each of which may be either a + /// string or a non-negative integer. It may also be empty, indicating that + /// this version has no build identifier. + final List build; + + /// The original string representation of the version number. + /// + /// This preserves textual artifacts like leading zeros that may be left out + /// of the parsed version. + final String _text; + + Version._(this.major, this.minor, this.patch, String preRelease, String build, + this._text) + : preRelease = preRelease == null ? [] : _splitParts(preRelease), + build = build == null ? [] : _splitParts(build) { + if (major < 0) throw new ArgumentError( + 'Major version must be non-negative.'); + if (minor < 0) throw new ArgumentError( + 'Minor version must be non-negative.'); + if (patch < 0) throw new ArgumentError( + 'Patch version must be non-negative.'); + } + + /// Creates a new [Version] object. + factory Version(int major, int minor, int patch, {String pre, String build}) { + var text = "$major.$minor.$patch"; + if (pre != null) text += "-$pre"; + if (build != null) text += "+$build"; + + return new Version._(major, minor, patch, pre, build, text); + } + + /// Creates a new [Version] by parsing [text]. + factory Version.parse(String text) { + final match = COMPLETE_VERSION.firstMatch(text); + if (match == null) { + throw new FormatException('Could not parse "$text".'); + } + + try { + int major = int.parse(match[1]); + int minor = int.parse(match[2]); + int patch = int.parse(match[3]); + + String preRelease = match[5]; + String build = match[8]; + + return new Version._(major, minor, patch, preRelease, build, text); + } on FormatException catch (ex) { + throw new FormatException('Could not parse "$text".'); + } + } + + /// Returns the primary version out of a list of candidates. + /// + /// This is the highest-numbered stable (non-prerelease) version. If there + /// are no stable versions, it's just the highest-numbered version. + static Version primary(List versions) { + var primary; + for (var version in versions) { + if (primary == null || (!version.isPreRelease && primary.isPreRelease) || + (version.isPreRelease == primary.isPreRelease && version > primary)) { + primary = version; + } + } + return primary; + } + + /// Splits a string of dot-delimited identifiers into their component parts. + /// + /// Identifiers that are numeric are converted to numbers. + static List _splitParts(String text) { + return text.split('.').map((part) { + try { + return int.parse(part); + } on FormatException catch (ex) { + // Not a number. + return part; + } + }).toList(); + } + + bool operator ==(other) { + if (other is! Version) return false; + return major == other.major && minor == other.minor && + patch == other.patch && + _equality.equals(preRelease, other.preRelease) && + _equality.equals(build, other.build); + } + + int get hashCode => major ^ minor ^ patch ^ _equality.hash(preRelease) ^ + _equality.hash(build); + + bool operator <(Version other) => compareTo(other) < 0; + bool operator >(Version other) => compareTo(other) > 0; + bool operator <=(Version other) => compareTo(other) <= 0; + bool operator >=(Version other) => compareTo(other) >= 0; + + bool get isAny => false; + bool get isEmpty => false; + + /// Whether or not this is a pre-release version. + bool get isPreRelease => preRelease.isNotEmpty; + + /// Gets the next major version number that follows this one. + /// + /// If this version is a pre-release of a major version release (i.e. the + /// minor and patch versions are zero), then it just strips the pre-release + /// suffix. Otherwise, it increments the major version and resets the minor + /// and patch. + Version get nextMajor { + if (isPreRelease && minor == 0 && patch == 0) { + return new Version(major, minor, patch); + } + + return new Version(major + 1, 0, 0); + } + + /// Gets the next minor version number that follows this one. + /// + /// If this version is a pre-release of a minor version release (i.e. the + /// patch version is zero), then it just strips the pre-release suffix. + /// Otherwise, it increments the minor version and resets the patch. + Version get nextMinor { + if (isPreRelease && patch == 0) { + return new Version(major, minor, patch); + } + + return new Version(major, minor + 1, 0); + } + + /// Gets the next patch version number that follows this one. + /// + /// If this version is a pre-release, then it just strips the pre-release + /// suffix. Otherwise, it increments the patch version. + Version get nextPatch { + if (isPreRelease) { + return new Version(major, minor, patch); + } + + return new Version(major, minor, patch + 1); + } + + /// Tests if [other] matches this version exactly. + bool allows(Version other) => this == other; + + VersionConstraint intersect(VersionConstraint other) { + if (other.isEmpty) return other; + + // Intersect a version and a range. + if (other is VersionRange) return other.intersect(this); + + // Intersecting two versions only works if they are the same. + if (other is Version) { + return this == other ? this : VersionConstraint.empty; + } + + throw new ArgumentError( + 'Unknown VersionConstraint type $other.'); + } + + int compareTo(Version other) { + if (major != other.major) return major.compareTo(other.major); + if (minor != other.minor) return minor.compareTo(other.minor); + if (patch != other.patch) return patch.compareTo(other.patch); + + // Pre-releases always come before no pre-release string. + if (!isPreRelease && other.isPreRelease) return 1; + if (!other.isPreRelease && isPreRelease) return -1; + + var comparison = _compareLists(preRelease, other.preRelease); + if (comparison != 0) return comparison; + + // Builds always come after no build string. + if (build.isEmpty && other.build.isNotEmpty) return -1; + if (other.build.isEmpty && build.isNotEmpty) return 1; + return _compareLists(build, other.build); + } + + String toString() => _text; + + /// Compares a dot-separated component of two versions. + /// + /// This is used for the pre-release and build version parts. This follows + /// Rule 12 of the Semantic Versioning spec (v2.0.0-rc.1). + int _compareLists(List a, List b) { + for (var i = 0; i < max(a.length, b.length); i++) { + var aPart = (i < a.length) ? a[i] : null; + var bPart = (i < b.length) ? b[i] : null; + + if (aPart == bPart) continue; + + // Missing parts come before present ones. + if (aPart == null) return -1; + if (bPart == null) return 1; + + if (aPart is num) { + if (bPart is num) { + // Compare two numbers. + return aPart.compareTo(bPart); + } else { + // Numbers come before strings. + return -1; + } + } else { + if (bPart is num) { + // Strings come after numbers. + return 1; + } else { + // Compare two strings. + return aPart.compareTo(bPart); + } + } + } + + // The lists are entirely equal. + return 0; + } +} diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart new file mode 100644 index 000000000..499892ee2 --- /dev/null +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -0,0 +1,151 @@ +// Copyright (c) 2014, 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. + +library pub_semver.src.version_constraint; + +import 'patterns.dart'; +import 'version.dart'; +import 'version_range.dart'; + +/// A [VersionConstraint] is a predicate that can determine whether a given +/// version is valid or not. +/// +/// For example, a ">= 2.0.0" constraint allows any version that is "2.0.0" or +/// greater. Version objects themselves implement this to match a specific +/// version. +abstract class VersionConstraint { + /// A [VersionConstraint] that allows all versions. + static VersionConstraint any = new VersionRange(); + + /// A [VersionConstraint] that allows no versions -- the empty set. + static VersionConstraint empty = const _EmptyVersion(); + + /// Parses a version constraint. + /// + /// This string is either "any" or a series of version parts. Each part can + /// be one of: + /// + /// * A version string like `1.2.3`. In other words, anything that can be + /// parsed by [Version.parse()]. + /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version + /// string. + /// + /// Whitespace is ignored. + /// + /// Examples: + /// + /// any + /// 1.2.3-alpha + /// <=5.1.4 + /// >2.0.4 <= 2.4.6 + factory VersionConstraint.parse(String text) { + // Handle the "any" constraint. + if (text.trim() == "any") return new VersionRange(); + + var originalText = text; + var constraints = []; + + skipWhitespace() { + text = text.trim(); + } + + // Try to parse and consume a version number. + matchVersion() { + var version = START_VERSION.firstMatch(text); + if (version == null) return null; + + text = text.substring(version.end); + return new Version.parse(version[0]); + } + + // Try to parse and consume a comparison operator followed by a version. + matchComparison() { + var comparison = START_COMPARISON.firstMatch(text); + if (comparison == null) return null; + + var op = comparison[0]; + text = text.substring(comparison.end); + skipWhitespace(); + + var version = matchVersion(); + if (version == null) { + throw new FormatException('Expected version number after "$op" in ' + '"$originalText", got "$text".'); + } + + switch (op) { + case '<=': return new VersionRange(max: version, includeMax: true); + case '<': return new VersionRange(max: version, includeMax: false); + case '>=': return new VersionRange(min: version, includeMin: true); + case '>': return new VersionRange(min: version, includeMin: false); + } + throw "Unreachable."; + } + + while (true) { + skipWhitespace(); + if (text.isEmpty) break; + + var version = matchVersion(); + if (version != null) { + constraints.add(version); + continue; + } + + var comparison = matchComparison(); + if (comparison != null) { + constraints.add(comparison); + continue; + } + + // If we got here, we couldn't parse the remaining string. + throw new FormatException('Could not parse version "$originalText". ' + 'Unknown text at "$text".'); + } + + if (constraints.isEmpty) { + throw new FormatException('Cannot parse an empty string.'); + } + + return new VersionConstraint.intersection(constraints); + } + + /// Creates a new version constraint that is the intersection of + /// [constraints]. + /// + /// It only allows versions that all of those constraints allow. If + /// constraints is empty, then it returns a VersionConstraint that allows + /// all versions. + factory VersionConstraint.intersection( + Iterable constraints) { + var constraint = new VersionRange(); + for (var other in constraints) { + constraint = constraint.intersect(other); + } + return constraint; + } + + /// Returns `true` if this constraint allows no versions. + bool get isEmpty; + + /// Returns `true` if this constraint allows all versions. + bool get isAny; + + /// Returns `true` if this constraint allows [version]. + bool allows(Version version); + + /// Creates a new [VersionConstraint] that only allows [Version]s allowed by + /// both this and [other]. + VersionConstraint intersect(VersionConstraint other); +} + +class _EmptyVersion implements VersionConstraint { + const _EmptyVersion(); + + bool get isEmpty => true; + bool get isAny => false; + bool allows(Version other) => false; + VersionConstraint intersect(VersionConstraint other) => this; + String toString() => ''; +} diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart new file mode 100644 index 000000000..7020077a7 --- /dev/null +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -0,0 +1,179 @@ +// Copyright (c) 2014, 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. + +library pub_semver.src.version_range; + +import 'version.dart'; +import 'version_constraint.dart'; + +/// Constrains versions to a fall within a given range. +/// +/// If there is a minimum, then this only allows versions that are at that +/// minimum or greater. If there is a maximum, then only versions less than +/// that are allowed. In other words, this allows `>= min, < max`. +class VersionRange implements VersionConstraint { + /// The minimum end of the range. + /// + /// If [includeMin] is `true`, this will be the minimum allowed version. + /// Otherwise, it will be the highest version below the range that is not + /// allowed. + /// + /// This may be `null` in which case the range has no minimum end and allows + /// any version less than the maximum. + final Version min; + + /// The maximum end of the range. + /// + /// If [includeMax] is `true`, this will be the maximum allowed version. + /// Otherwise, it will be the lowest version above the range that is not + /// allowed. + /// + /// This may be `null` in which case the range has no maximum end and allows + /// any version greater than the minimum. + final Version max; + + /// If `true` then [min] is allowed by the range. + final bool includeMin; + + /// If `true`, then [max] is allowed by the range. + final bool includeMax; + + /// Creates a new version range from [min] to [max], either inclusive or + /// exclusive. + /// + /// If it is an error if [min] is greater than [max]. + /// + /// Either [max] or [min] may be omitted to not clamp the range at that end. + /// If both are omitted, the range allows all versions. + /// + /// If [includeMin] is `true`, then the minimum end of the range is inclusive. + /// Likewise, passing [includeMax] as `true` makes the upper end inclusive. + VersionRange({this.min, this.max, + this.includeMin: false, this.includeMax: false}) { + if (min != null && max != null && min > max) { + throw new ArgumentError( + 'Minimum version ("$min") must be less than maximum ("$max").'); + } + } + + bool operator ==(other) { + if (other is! VersionRange) return false; + + return min == other.min && + max == other.max && + includeMin == other.includeMin && + includeMax == other.includeMax; + } + + bool get isEmpty => false; + + bool get isAny => min == null && max == null; + + /// Tests if [other] falls within this version range. + bool allows(Version other) { + if (min != null) { + if (other < min) return false; + if (!includeMin && other == min) return false; + } + + if (max != null) { + if (other > max) return false; + if (!includeMax && other == max) return false; + + // If the max isn't itself a pre-release, don't allow any pre-release + // versions of the max. + // + // See: https://www.npmjs.org/doc/misc/semver.html + if (!includeMax && + !max.isPreRelease && other.isPreRelease && + other.major == max.major && other.minor == max.minor && + other.patch == max.patch) { + return false; + } + } + + return true; + } + + VersionConstraint intersect(VersionConstraint other) { + if (other.isEmpty) return other; + + // A range and a Version just yields the version if it's in the range. + if (other is Version) { + return allows(other) ? other : VersionConstraint.empty; + } + + if (other is VersionRange) { + // Intersect the two ranges. + var intersectMin = min; + var intersectIncludeMin = includeMin; + var intersectMax = max; + var intersectIncludeMax = includeMax; + + if (other.min == null) { + // Do nothing. + } else if (intersectMin == null || intersectMin < other.min) { + intersectMin = other.min; + intersectIncludeMin = other.includeMin; + } else if (intersectMin == other.min && !other.includeMin) { + // The edges are the same, but one is exclusive, make it exclusive. + intersectIncludeMin = false; + } + + if (other.max == null) { + // Do nothing. + } else if (intersectMax == null || intersectMax > other.max) { + intersectMax = other.max; + intersectIncludeMax = other.includeMax; + } else if (intersectMax == other.max && !other.includeMax) { + // The edges are the same, but one is exclusive, make it exclusive. + intersectIncludeMax = false; + } + + if (intersectMin == null && intersectMax == null) { + // Open range. + return new VersionRange(); + } + + // If the range is just a single version. + if (intersectMin == intersectMax) { + // If both ends are inclusive, allow that version. + if (intersectIncludeMin && intersectIncludeMax) return intersectMin; + + // Otherwise, no versions. + return VersionConstraint.empty; + } + + if (intersectMin != null && intersectMax != null && + intersectMin > intersectMax) { + // Non-overlapping ranges, so empty. + return VersionConstraint.empty; + } + + // If we got here, there is an actual range. + return new VersionRange(min: intersectMin, max: intersectMax, + includeMin: intersectIncludeMin, includeMax: intersectIncludeMax); + } + + throw new ArgumentError('Unknown VersionConstraint type $other.'); + } + + String toString() { + var buffer = new StringBuffer(); + + if (min != null) { + buffer.write(includeMin ? '>=' : '>'); + buffer.write(min); + } + + if (max != null) { + if (min != null) buffer.write(' '); + buffer.write(includeMax ? '<=' : '<'); + buffer.write(max); + } + + if (min == null && max == null) buffer.write('any'); + return buffer.toString(); + } +} diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml new file mode 100644 index 000000000..63b09e129 --- /dev/null +++ b/pkgs/pub_semver/pubspec.yaml @@ -0,0 +1,13 @@ +name: pub_semver +version: 1.0.0 +author: Dart Team +description: > + Versions and version constraints implementing pub's versioning policy. This + is very similar to vanilla semver, with a few corner cases. +homepage: http://github.com/dart-lang/pub_semver +dependencies: + collection: ">=0.9.0 <2.0.0" +dev_dependencies: + unittest: ">=0.9.0 <0.12.0" +environment: + sdk: ">=1.0.0 <2.0.0" diff --git a/pkgs/pub_semver/test/test_all.dart b/pkgs/pub_semver/test/test_all.dart new file mode 100644 index 000000000..533dde82e --- /dev/null +++ b/pkgs/pub_semver/test/test_all.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2014, 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. + +library pub_semver.test.test_all; + +import 'package:unittest/unittest.dart'; + +import 'version_constraint_test.dart' as version_constraint_test; +import 'version_range_test.dart' as version_range_test; +import 'version_test.dart' as version_test; + +main() { + group('Version', version_test.main); + group('VersionConstraint', version_constraint_test.main); + group('VersionRange', version_range_test.main); +} diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart new file mode 100644 index 000000000..da8968313 --- /dev/null +++ b/pkgs/pub_semver/test/utils.dart @@ -0,0 +1,96 @@ +// Copyright (c) 2014, 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. + +library pub_semver.test.utils; + +import 'package:unittest/unittest.dart'; + +import 'package:pub_semver/pub_semver.dart'; + +/// Some stock example versions to use in tests. +final v114 = new Version.parse('1.1.4'); +final v123 = new Version.parse('1.2.3'); +final v124 = new Version.parse('1.2.4'); +final v130 = new Version.parse('1.3.0'); +final v140 = new Version.parse('1.4.0'); +final v200 = new Version.parse('2.0.0'); +final v201 = new Version.parse('2.0.1'); +final v234 = new Version.parse('2.3.4'); +final v250 = new Version.parse('2.5.0'); +final v300 = new Version.parse('3.0.0'); + +/// A [Matcher] that tests if a [VersionConstraint] allows or does not allow a +/// given list of [Version]s. +class _VersionConstraintMatcher implements Matcher { + final List _expected; + final bool _allow; + + _VersionConstraintMatcher(this._expected, this._allow); + + bool matches(item, Map matchState) => (item is VersionConstraint) && + _expected.every((version) => item.allows(version) == _allow); + + Description describe(Description description) { + description.addAll(' ${_allow ? "allows" : "does not allow"} versions ', + ', ', '', _expected); + return description; + } + + Description describeMismatch(item, Description mismatchDescription, + Map matchState, bool verbose) { + if (item is! VersionConstraint) { + mismatchDescription.add('was not a VersionConstraint'); + return mismatchDescription; + } + + var first = true; + for (var version in _expected) { + if (item.allows(version) != _allow) { + if (first) { + if (_allow) { + mismatchDescription.addDescriptionOf(item).add(' did not allow '); + } else { + mismatchDescription.addDescriptionOf(item).add(' allowed '); + } + } else { + mismatchDescription.add(' and '); + } + first = false; + + mismatchDescription.add(version.toString()); + } + } + + return mismatchDescription; + } +} + +/// Gets a [Matcher] that validates that a [VersionConstraint] allows all +/// given versions. +Matcher allows(Version v1, [Version v2, Version v3, Version v4, + Version v5, Version v6, Version v7, Version v8]) { + var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); + return new _VersionConstraintMatcher(versions, true); +} + +/// Gets a [Matcher] that validates that a [VersionConstraint] allows none of +/// the given versions. +Matcher doesNotAllow(Version v1, [Version v2, Version v3, Version v4, + Version v5, Version v6, Version v7, Version v8]) { + var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); + return new _VersionConstraintMatcher(versions, false); +} + +List _makeVersionList(Version v1, [Version v2, Version v3, Version v4, + Version v5, Version v6, Version v7, Version v8]) { + var versions = [v1]; + if (v2 != null) versions.add(v2); + if (v3 != null) versions.add(v3); + if (v4 != null) versions.add(v4); + if (v5 != null) versions.add(v5); + if (v6 != null) versions.add(v6); + if (v7 != null) versions.add(v7); + if (v8 != null) versions.add(v8); + return versions; +} \ No newline at end of file diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart new file mode 100644 index 000000000..df8c09909 --- /dev/null +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -0,0 +1,143 @@ +// Copyright (c) 2014, 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. + +library pub_semver.test.version_constraint_test; + +import 'package:unittest/unittest.dart'; + +import 'package:pub_semver/pub_semver.dart'; + +import 'utils.dart'; + +main() { + test('any', () { + expect(VersionConstraint.any.isAny, isTrue); + expect(VersionConstraint.any, allows( + new Version.parse('0.0.0-blah'), + new Version.parse('1.2.3'), + new Version.parse('12345.678.90'))); + }); + + test('empty', () { + expect(VersionConstraint.empty.isEmpty, isTrue); + expect(VersionConstraint.empty.isAny, isFalse); + expect(VersionConstraint.empty, doesNotAllow( + new Version.parse('0.0.0-blah'), + new Version.parse('1.2.3'), + new Version.parse('12345.678.90'))); + }); + + group('parse()', () { + test('parses an exact version', () { + var constraint = new VersionConstraint.parse('1.2.3-alpha'); + + expect(constraint is Version, isTrue); + expect(constraint, equals(new Version(1, 2, 3, pre: 'alpha'))); + }); + + test('parses "any"', () { + var constraint = new VersionConstraint.parse('any'); + + expect(constraint is VersionConstraint, isTrue); + expect(constraint, allows( + new Version.parse('0.0.0'), + new Version.parse('1.2.3'), + new Version.parse('12345.678.90'))); + }); + + test('parses a ">" minimum version', () { + var constraint = new VersionConstraint.parse('>1.2.3'); + + expect(constraint, allows( + new Version.parse('1.2.3+foo'), + new Version.parse('1.2.4'))); + expect(constraint, doesNotAllow( + new Version.parse('1.2.1'), + new Version.parse('1.2.3-build'), + new Version.parse('1.2.3'))); + }); + + test('parses a ">=" minimum version', () { + var constraint = new VersionConstraint.parse('>=1.2.3'); + + expect(constraint, allows( + new Version.parse('1.2.3'), + new Version.parse('1.2.3+foo'), + new Version.parse('1.2.4'))); + expect(constraint, doesNotAllow( + new Version.parse('1.2.1'), + new Version.parse('1.2.3-build'))); + }); + + test('parses a "<" maximum version', () { + var constraint = new VersionConstraint.parse('<1.2.3'); + + expect(constraint, allows( + new Version.parse('1.2.1'), + new Version.parse('1.2.2+foo'))); + expect(constraint, doesNotAllow( + new Version.parse('1.2.3'), + new Version.parse('1.2.3+foo'), + new Version.parse('1.2.4'))); + }); + + test('parses a "<=" maximum version', () { + var constraint = new VersionConstraint.parse('<=1.2.3'); + + expect(constraint, allows( + new Version.parse('1.2.1'), + new Version.parse('1.2.3-build'), + new Version.parse('1.2.3'))); + expect(constraint, doesNotAllow( + new Version.parse('1.2.3+foo'), + new Version.parse('1.2.4'))); + }); + + test('parses a series of space-separated constraints', () { + var constraint = new VersionConstraint.parse('>1.0.0 >=1.2.3 <1.3.0'); + + expect(constraint, allows( + new Version.parse('1.2.3'), + new Version.parse('1.2.5'))); + expect(constraint, doesNotAllow( + new Version.parse('1.2.3-pre'), + new Version.parse('1.3.0'), + new Version.parse('3.4.5'))); + }); + + test('ignores whitespace around operators', () { + var constraint = new VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0'); + + expect(constraint, allows( + new Version.parse('1.2.3'), + new Version.parse('1.2.5'))); + expect(constraint, doesNotAllow( + new Version.parse('1.2.3-pre'), + new Version.parse('1.3.0'), + new Version.parse('3.4.5'))); + }); + + test('does not allow "any" to be mixed with other constraints', () { + expect(() => new VersionConstraint.parse('any 1.0.0'), + throwsFormatException); + }); + + test('throws FormatException on a bad string', () { + var bad = [ + "", " ", // Empty string. + "foo", // Bad text. + ">foo", // Bad text after operator. + "1.0.0 foo", "1.0.0foo", // Bad text after version. + "anything", // Bad text after "any". + "<>1.0.0", // Multiple operators. + "1.0.0<" // Trailing operator. + ]; + + for (var text in bad) { + expect(() => new VersionConstraint.parse(text), + throwsFormatException); + } + }); + }); +} diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart new file mode 100644 index 000000000..388917ff5 --- /dev/null +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -0,0 +1,202 @@ +// Copyright (c) 2014, 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. + +library pub_semver.test.version_range_test; + +import 'package:unittest/unittest.dart'; + +import 'package:pub_semver/pub_semver.dart'; + +import 'utils.dart'; + +main() { + group('constructor', () { + test('takes a min and max', () { + var range = new VersionRange(min: v123, max: v124); + expect(range.isAny, isFalse); + expect(range.min, equals(v123)); + expect(range.max, equals(v124)); + }); + + test('allows omitting max', () { + var range = new VersionRange(min: v123); + expect(range.isAny, isFalse); + expect(range.min, equals(v123)); + expect(range.max, isNull); + }); + + test('allows omitting min and max', () { + var range = new VersionRange(); + expect(range.isAny, isTrue); + expect(range.min, isNull); + expect(range.max, isNull); + }); + + test('takes includeMin', () { + var range = new VersionRange(min: v123, includeMin: true); + expect(range.includeMin, isTrue); + }); + + test('includeMin defaults to false if omitted', () { + var range = new VersionRange(min: v123); + expect(range.includeMin, isFalse); + }); + + test('takes includeMax', () { + var range = new VersionRange(max: v123, includeMax: true); + expect(range.includeMax, isTrue); + }); + + test('includeMax defaults to false if omitted', () { + var range = new VersionRange(max: v123); + expect(range.includeMax, isFalse); + }); + + test('throws if min > max', () { + expect(() => new VersionRange(min: v124, max: v123), throwsArgumentError); + }); + }); + + group('allows()', () { + test('version must be greater than min', () { + var range = new VersionRange(min: v123); + + expect(range, allows( + new Version.parse('1.3.3'), + new Version.parse('2.3.3'))); + expect(range, doesNotAllow( + new Version.parse('1.2.2'), + new Version.parse('1.2.3'))); + }); + + test('version must be min or greater if includeMin', () { + var range = new VersionRange(min: v123, includeMin: true); + + expect(range, allows( + new Version.parse('1.2.3'), + new Version.parse('1.3.3'), + new Version.parse('2.3.3'))); + expect(range, doesNotAllow(new Version.parse('1.2.2'))); + }); + + test('pre-release versions of inclusive min are excluded', () { + var range = new VersionRange(min: v123, includeMin: true); + + expect(range, allows(new Version.parse('1.2.4-dev'))); + expect(range, doesNotAllow(new Version.parse('1.2.3-dev'))); + }); + + test('version must be less than max', () { + var range = new VersionRange(max: v234); + + expect(range, allows(new Version.parse('2.3.3'))); + expect(range, doesNotAllow( + new Version.parse('2.3.4'), + new Version.parse('2.4.3'))); + }); + + test('pre-release versions of non-pre-release max are excluded', () { + var range = new VersionRange(max: v234); + + expect(range, allows(new Version.parse('2.3.3'))); + expect(range, doesNotAllow( + new Version.parse('2.3.4-dev'), + new Version.parse('2.3.4'))); + }); + + test('pre-release versions of pre-release max are included', () { + var range = new VersionRange(max: new Version.parse('2.3.4-dev.2')); + + expect(range, allows( + new Version.parse('2.3.4-dev.1'))); + expect(range, doesNotAllow( + new Version.parse('2.3.4-dev.2'), + new Version.parse('2.3.4-dev.3'))); + }); + + test('version must be max or less if includeMax', () { + var range = new VersionRange(min: v123, max: v234, includeMax: true); + + expect(range, allows( + new Version.parse('2.3.3'), + new Version.parse('2.3.4'), + // Pre-releases of the max are allowed. + new Version.parse('2.3.4-dev'))); + expect(range, doesNotAllow(new Version.parse('2.4.3'))); + }); + + test('has no min if one was not set', () { + var range = new VersionRange(max: v123); + + expect(range, allows(new Version.parse('0.0.0'))); + expect(range, doesNotAllow(new Version.parse('1.2.3'))); + }); + + test('has no max if one was not set', () { + var range = new VersionRange(min: v123); + + expect(range, allows( + new Version.parse('1.3.3'), + new Version.parse('999.3.3'))); + expect(range, doesNotAllow(new Version.parse('1.2.3'))); + }); + + test('allows any version if there is no min or max', () { + var range = new VersionRange(); + + expect(range, allows( + new Version.parse('0.0.0'), + new Version.parse('999.99.9'))); + }); + }); + + group('intersect()', () { + test('two overlapping ranges', () { + var a = new VersionRange(min: v123, max: v250); + var b = new VersionRange(min: v200, max: v300); + var intersect = a.intersect(b); + expect(intersect.min, equals(v200)); + expect(intersect.max, equals(v250)); + expect(intersect.includeMin, isFalse); + expect(intersect.includeMax, isFalse); + }); + + test('a non-overlapping range allows no versions', () { + var a = new VersionRange(min: v114, max: v124); + var b = new VersionRange(min: v200, max: v250); + expect(a.intersect(b).isEmpty, isTrue); + }); + + test('adjacent ranges allow no versions if exclusive', () { + var a = new VersionRange(min: v114, max: v124, includeMax: false); + var b = new VersionRange(min: v124, max: v200, includeMin: true); + expect(a.intersect(b).isEmpty, isTrue); + }); + + test('adjacent ranges allow version if inclusive', () { + var a = new VersionRange(min: v114, max: v124, includeMax: true); + var b = new VersionRange(min: v124, max: v200, includeMin: true); + expect(a.intersect(b), equals(v124)); + }); + + test('with an open range', () { + var open = new VersionRange(); + var a = new VersionRange(min: v114, max: v124); + expect(open.intersect(open), equals(open)); + expect(a.intersect(open), equals(a)); + }); + + test('returns the version if the range allows it', () { + expect(new VersionRange(min: v114, max: v124).intersect(v123), + equals(v123)); + expect(new VersionRange(min: v123, max: v124).intersect(v114).isEmpty, + isTrue); + }); + }); + + test('isEmpty', () { + expect(new VersionRange().isEmpty, isFalse); + expect(new VersionRange(min: v123, max: v124).isEmpty, isFalse); + }); +} diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart new file mode 100644 index 000000000..b271eccb8 --- /dev/null +++ b/pkgs/pub_semver/test/version_test.dart @@ -0,0 +1,248 @@ +// Copyright (c) 2014, 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. + +library pub_semver.test.version_test; + +import 'package:unittest/unittest.dart'; + +import 'package:pub_semver/pub_semver.dart'; + +import 'utils.dart'; + +main() { + test('none', () { + expect(Version.none.toString(), equals('0.0.0')); + }); + + test('prioritize()', () { + // A correctly sorted list of versions in order of increasing priority. + var versions = [ + '1.0.0-alpha', + '2.0.0-alpha', + '1.0.0', + '1.0.0+build', + '1.0.1', + '1.1.0', + '2.0.0' + ]; + + // Ensure that every pair of versions is prioritized in the order that it + // appears in the list. + for (var i = 0; i < versions.length; i++) { + for (var j = 0; j < versions.length; j++) { + var a = new Version.parse(versions[i]); + var b = new Version.parse(versions[j]); + expect(Version.prioritize(a, b), equals(i.compareTo(j))); + } + } + }); + + test('antiprioritize()', () { + // A correctly sorted list of versions in order of increasing antipriority. + var versions = [ + '2.0.0-alpha', + '1.0.0-alpha', + '2.0.0', + '1.1.0', + '1.0.1', + '1.0.0+build', + '1.0.0' + ]; + + // Ensure that every pair of versions is prioritized in the order that it + // appears in the list. + for (var i = 0; i < versions.length; i++) { + for (var j = 0; j < versions.length; j++) { + var a = new Version.parse(versions[i]); + var b = new Version.parse(versions[j]); + expect(Version.antiprioritize(a, b), equals(i.compareTo(j))); + } + } + }); + + group('constructor', () { + test('throws on negative numbers', () { + expect(() => new Version(-1, 1, 1), throwsArgumentError); + expect(() => new Version(1, -1, 1), throwsArgumentError); + expect(() => new Version(1, 1, -1), throwsArgumentError); + }); + }); + + group('comparison', () { + // A correctly sorted list of versions. + var versions = [ + '1.0.0-alpha', + '1.0.0-alpha.1', + '1.0.0-beta.2', + '1.0.0-beta.11', + '1.0.0-rc.1', + '1.0.0-rc.1+build.1', + '1.0.0', + '1.0.0+0.3.7', + '1.3.7+build', + '1.3.7+build.2.b8f12d7', + '1.3.7+build.11.e0f985a', + '2.0.0', + '2.1.0', + '2.2.0', + '2.11.0', + '2.11.1' + ]; + + test('compareTo()', () { + // Ensure that every pair of versions compares in the order that it + // appears in the list. + for (var i = 0; i < versions.length; i++) { + for (var j = 0; j < versions.length; j++) { + var a = new Version.parse(versions[i]); + var b = new Version.parse(versions[j]); + expect(a.compareTo(b), equals(i.compareTo(j))); + } + } + }); + + test('operators', () { + for (var i = 0; i < versions.length; i++) { + for (var j = 0; j < versions.length; j++) { + var a = new Version.parse(versions[i]); + var b = new Version.parse(versions[j]); + expect(a < b, equals(i < j)); + expect(a > b, equals(i > j)); + expect(a <= b, equals(i <= j)); + expect(a >= b, equals(i >= j)); + expect(a == b, equals(i == j)); + expect(a != b, equals(i != j)); + } + } + }); + + test('equality', () { + expect(new Version.parse('01.2.3'), equals(new Version.parse('1.2.3'))); + expect(new Version.parse('1.02.3'), equals(new Version.parse('1.2.3'))); + expect(new Version.parse('1.2.03'), equals(new Version.parse('1.2.3'))); + expect(new Version.parse('1.2.3-01'), + equals(new Version.parse('1.2.3-1'))); + expect(new Version.parse('1.2.3+01'), + equals(new Version.parse('1.2.3+1'))); + }); + }); + + test('allows()', () { + expect(v123, allows(v123)); + expect(v123, doesNotAllow( + new Version.parse('2.2.3'), + new Version.parse('1.3.3'), + new Version.parse('1.2.4'), + new Version.parse('1.2.3-dev'), + new Version.parse('1.2.3+build'))); + }); + + test('intersect()', () { + // Intersecting the same version returns the version. + expect(v123.intersect(v123), equals(v123)); + + // Intersecting a different version allows no versions. + expect(v123.intersect(v114).isEmpty, isTrue); + + // Intersecting a range returns the version if the range allows it. + expect(v123.intersect(new VersionRange(min: v114, max: v124)), + equals(v123)); + + // Intersecting a range allows no versions if the range doesn't allow it. + expect(v114.intersect(new VersionRange(min: v123, max: v124)).isEmpty, + isTrue); + }); + + test('isEmpty', () { + expect(v123.isEmpty, isFalse); + }); + + test('nextMajor', () { + expect(v123.nextMajor, equals(v200)); + expect(v114.nextMajor, equals(v200)); + expect(v200.nextMajor, equals(v300)); + + // Ignores pre-release if not on a major version. + expect(new Version.parse('1.2.3-dev').nextMajor, equals(v200)); + + // Just removes it if on a major version. + expect(new Version.parse('2.0.0-dev').nextMajor, equals(v200)); + + // Strips build suffix. + expect(new Version.parse('1.2.3+patch').nextMajor, equals(v200)); + }); + + test('nextMinor', () { + expect(v123.nextMinor, equals(v130)); + expect(v130.nextMinor, equals(v140)); + + // Ignores pre-release if not on a minor version. + expect(new Version.parse('1.2.3-dev').nextMinor, equals(v130)); + + // Just removes it if on a minor version. + expect(new Version.parse('1.3.0-dev').nextMinor, equals(v130)); + + // Strips build suffix. + expect(new Version.parse('1.2.3+patch').nextMinor, equals(v130)); + }); + + test('nextPatch', () { + expect(v123.nextPatch, equals(v124)); + expect(v200.nextPatch, equals(v201)); + + // Just removes pre-release version if present. + expect(new Version.parse('1.2.4-dev').nextPatch, equals(v124)); + + // Strips build suffix. + expect(new Version.parse('1.2.3+patch').nextPatch, equals(v124)); + }); + + test('parse()', () { + expect(new Version.parse('0.0.0'), equals(new Version(0, 0, 0))); + expect(new Version.parse('12.34.56'), equals(new Version(12, 34, 56))); + + expect(new Version.parse('1.2.3-alpha.1'), + equals(new Version(1, 2, 3, pre: 'alpha.1'))); + expect(new Version.parse('1.2.3-x.7.z-92'), + equals(new Version(1, 2, 3, pre: 'x.7.z-92'))); + + expect(new Version.parse('1.2.3+build.1'), + equals(new Version(1, 2, 3, build: 'build.1'))); + expect(new Version.parse('1.2.3+x.7.z-92'), + equals(new Version(1, 2, 3, build: 'x.7.z-92'))); + + expect(new Version.parse('1.0.0-rc-1+build-1'), + equals(new Version(1, 0, 0, pre: 'rc-1', build: 'build-1'))); + + expect(() => new Version.parse('1.0'), throwsFormatException); + expect(() => new Version.parse('1.2.3.4'), throwsFormatException); + expect(() => new Version.parse('1234'), throwsFormatException); + expect(() => new Version.parse('-2.3.4'), throwsFormatException); + expect(() => new Version.parse('1.3-pre'), throwsFormatException); + expect(() => new Version.parse('1.3+build'), throwsFormatException); + expect(() => new Version.parse('1.3+bu?!3ild'), throwsFormatException); + }); + + group('toString()', () { + test('returns the version string', () { + expect(new Version(0, 0, 0).toString(), equals('0.0.0')); + expect(new Version(12, 34, 56).toString(), equals('12.34.56')); + + expect(new Version(1, 2, 3, pre: 'alpha.1').toString(), + equals('1.2.3-alpha.1')); + expect(new Version(1, 2, 3, pre: 'x.7.z-92').toString(), + equals('1.2.3-x.7.z-92')); + + expect(new Version(1, 2, 3, build: 'build.1').toString(), + equals('1.2.3+build.1')); + expect(new Version(1, 2, 3, pre: 'pre', build: 'bui').toString(), + equals('1.2.3-pre+bui')); + }); + + test('preserves leading zeroes', () { + expect(new Version.parse('001.02.0003-01.dev+pre.002').toString(), + equals('001.02.0003-01.dev+pre.002')); + }); + }); +} From 5dd38641be46b82ad4cce561f1bb3bf13dd7a1b5 Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Thu, 23 Oct 2014 09:10:14 -0500 Subject: [PATCH 048/657] Add Version.nextBreaking and "^" operator --- pkgs/pub_semver/README.md | 18 ++++++ pkgs/pub_semver/lib/src/patterns.dart | 3 + pkgs/pub_semver/lib/src/version.dart | 28 ++++++++- .../lib/src/version_constraint.dart | 57 ++++++++++++++++--- pkgs/pub_semver/test/utils.dart | 4 ++ .../test/version_constraint_test.dart | 37 ++++++++++++ pkgs/pub_semver/test/version_test.dart | 12 ++++ 7 files changed, 148 insertions(+), 11 deletions(-) diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index 1cb152791..475c1a3ab 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -73,5 +73,23 @@ spec. It differs from semver in a few corner cases: specifically selects that unstable version -- they've deliberately opted into it. + * **There is a notion of compatibility between pre-1.0.0 versions.** Semver + deems all pre-1.0.0 versions to be incompatible. This means that the only + way to ensure compatibility when depending on a pre-1.0.0 package is to + pin the dependency to an exact version. Pinned version constraints prevent + automatic patch and pre-release updates. To avoid this situation, pub + defines the "next breaking" version to be the version with the left-most + non-zero digit in [major, minor, patch] incremented, and the subsequent + digits reset to zero. For example, here are some versions along with their + next breaking ones: + + `0.0.3` -> `0.0.4` + `0.7.2-alpha` -> `0.8.0` + `1.2.3` -> `2.0.0` + + To make use of this, pub defines a "^" operator which yields a version + constraint greater than or equal to a given version, but less than its next + breaking one. + [pub]: http://pub.dartlang.org/ [semver]: http://semver.org/ diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart index 4a2261815..59b0c091a 100644 --- a/pkgs/pub_semver/lib/src/patterns.dart +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -17,3 +17,6 @@ final COMPLETE_VERSION = new RegExp(START_VERSION.pattern + r'$'); /// Parses a comparison operator ("<", ">", "<=", or ">=") at the beginning of /// a string. final START_COMPARISON = new RegExp(r"^[<>]=?"); + +/// Parses the "compatible with" operator ("^") at the beginning of a string. +final START_COMPATIBLE_WITH = new RegExp(r"^\^"); diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 866d89c30..496178fbe 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -189,7 +189,7 @@ class Version implements Comparable, VersionConstraint { return new Version(major, minor, patch); } - return new Version(major + 1, 0, 0); + return _incrementMajor(); } /// Gets the next minor version number that follows this one. @@ -202,7 +202,7 @@ class Version implements Comparable, VersionConstraint { return new Version(major, minor, patch); } - return new Version(major, minor + 1, 0); + return _incrementMinor(); } /// Gets the next patch version number that follows this one. @@ -214,9 +214,31 @@ class Version implements Comparable, VersionConstraint { return new Version(major, minor, patch); } - return new Version(major, minor, patch + 1); + return _incrementPatch(); } + /// Gets the next breaking version number that follows this one. + /// + /// Increments the left-most non-zero digit in ([major], [minor], [patch]). + /// In other words, if [major] and [minor] are zero (e.g. 0.0.3), then it + /// increments [patch]. If [major] is zero and [minor] is not (e.g. 0.7.2), + /// then it increments [minor]. Otherwise, it increments [major]. + Version get nextBreaking { + if (major == 0) { + if (minor == 0) { + return _incrementPatch(); + } + + return _incrementMinor(); + } + + return _incrementMajor(); + } + + Version _incrementMajor() => new Version(major + 1, 0, 0); + Version _incrementMinor() => new Version(major, minor + 1, 0); + Version _incrementPatch() => new Version(major, minor, patch + 1); + /// Tests if [other] matches this version exactly. bool allows(Version other) => this == other; diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 499892ee2..29dd5742a 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -23,19 +23,26 @@ abstract class VersionConstraint { /// Parses a version constraint. /// - /// This string is either "any" or a series of version parts. Each part can - /// be one of: - /// - /// * A version string like `1.2.3`. In other words, anything that can be - /// parsed by [Version.parse()]. - /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a version - /// string. + /// This string is one of: + /// + /// * "any". See [any]. + /// * "^" followed by a version string. Versions compatible with the + /// version number. This allows versions greater than or equal to the + /// version, and less then the next breaking version (see + /// [Version.nextBreaking]). + /// * a series of version parts. Each part can be one of: + /// * A version string like `1.2.3`. In other words, anything that can be + /// parsed by [Version.parse()]. + /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a + /// version string. /// /// Whitespace is ignored. /// /// Examples: /// /// any + /// ^0.7.2 + /// ^1.0.0-alpha /// 1.2.3-alpha /// <=5.1.4 /// >2.0.4 <= 2.4.6 @@ -82,9 +89,38 @@ abstract class VersionConstraint { } throw "Unreachable."; } - + + // Try to parse the "^" operator followed by a version. + matchCompatibleWith() { + var compatibleWith = START_COMPATIBLE_WITH.firstMatch(text); + if (compatibleWith == null) return null; + + var op = compatibleWith[0]; + text = text.substring(compatibleWith.end); + skipWhitespace(); + + var version = matchVersion(); + if (version == null) { + throw new FormatException('Expected version number after "$op" in ' + '"$originalText", got "$text".'); + } + + getCurrentTextIndex() => originalText.length - text.length; + var startTextIndex = getCurrentTextIndex(); + if(constraints.isNotEmpty || text.isNotEmpty) { + var constraint = op + originalText.substring(startTextIndex, + getCurrentTextIndex()); + throw new FormatException('Cannot include other constraints with ' + '"^" constraint "$constraint" in "$originalText".'); + } + + return new VersionRange(min: version, includeMin: true, + max: version.nextBreaking); + } + while (true) { skipWhitespace(); + if (text.isEmpty) break; var version = matchVersion(); @@ -98,6 +134,11 @@ abstract class VersionConstraint { constraints.add(comparison); continue; } + + var compatibleWith = matchCompatibleWith(); + if (compatibleWith != null) { + return compatibleWith; + } // If we got here, we couldn't parse the remaining string. throw new FormatException('Could not parse version "$originalText". ' diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index da8968313..0cc0f6582 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -9,6 +9,10 @@ import 'package:unittest/unittest.dart'; import 'package:pub_semver/pub_semver.dart'; /// Some stock example versions to use in tests. +final v003 = new Version.parse('0.0.3'); +final v004 = new Version.parse('0.0.4'); +final v072 = new Version.parse('0.7.2'); +final v080 = new Version.parse('0.8.0'); final v114 = new Version.parse('1.1.4'); final v123 = new Version.parse('1.2.3'); final v124 = new Version.parse('1.2.4'); diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index df8c09909..16a3fdc24 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -123,11 +123,48 @@ main() { throwsFormatException); }); + test('parses a "^" post-1.0.0 version', () { + var constraint = new VersionConstraint.parse('^1.2.3'); + + expect(constraint, equals(new VersionRange(min: v123, includeMin: true, + max: v123.nextBreaking))); + }); + + test('parses a "^" pre-1.0.0, post-0.1.0 version', () { + var constraint = new VersionConstraint.parse('^0.7.2'); + + expect(constraint, equals(new VersionRange(min: v072, includeMin: true, + max: v072.nextBreaking))); + }); + + test('parses a "^" pre-0.1.0 version', () { + var constraint = new VersionConstraint.parse('^0.0.3'); + + expect(constraint, equals(new VersionRange(min: v003, includeMin: true, + max: v003.nextBreaking))); + }); + + test('parses a "^" pre-release version', () { + var constraint = new VersionConstraint.parse('^0.7.2-pre+1'); + + var min = new Version.parse('0.7.2-pre+1'); + expect(constraint, equals(new VersionRange(min: min, includeMin: true, + max: min.nextBreaking))); + }); + + test('does not allow "^" to be mixed with other constraints', () { + expect(() => new VersionConstraint.parse('>=1.2.3 ^1.0.0'), + throwsFormatException); + expect(() => new VersionConstraint.parse('^1.0.0 <1.2.3'), + throwsFormatException); + }); + test('throws FormatException on a bad string', () { var bad = [ "", " ", // Empty string. "foo", // Bad text. ">foo", // Bad text after operator. + "^foo", // Bad text after "^". "1.0.0 foo", "1.0.0foo", // Bad text after version. "anything", // Bad text after "any". "<>1.0.0", // Multiple operators. diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index b271eccb8..527db2942 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -198,6 +198,18 @@ main() { expect(new Version.parse('1.2.3+patch').nextPatch, equals(v124)); }); + test('nextBreaking', () { + expect(v123.nextBreaking, equals(v200)); + expect(v072.nextBreaking, equals(v080)); + expect(v003.nextBreaking, equals(v004)); + + // Removes pre-release version if present. + expect(new Version.parse('1.2.3-dev').nextBreaking, equals(v200)); + + // Strips build suffix. + expect(new Version.parse('1.2.3+patch').nextBreaking, equals(v200)); + }); + test('parse()', () { expect(new Version.parse('0.0.0'), equals(new Version(0, 0, 0))); expect(new Version.parse('12.34.56'), equals(new Version(12, 34, 56))); From 81b8e2243478dd48e85f5f1711e704cae65f6ccf Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Thu, 23 Oct 2014 12:25:11 -0500 Subject: [PATCH 049/657] Add VersionConstraint.compatibleWith constructor --- .../lib/src/version_constraint.dart | 21 +++++++++++++------ .../test/version_constraint_test.dart | 19 ++++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 29dd5742a..1b86602c4 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -25,11 +25,9 @@ abstract class VersionConstraint { /// /// This string is one of: /// - /// * "any". See [any]. - /// * "^" followed by a version string. Versions compatible with the - /// version number. This allows versions greater than or equal to the - /// version, and less then the next breaking version (see - /// [Version.nextBreaking]). + /// * "any". [any] version. + /// * "^" followed by a version string. Versions compatible with + /// ([VersionConstraint.compatibleWith]) the version. /// * a series of version parts. Each part can be one of: /// * A version string like `1.2.3`. In other words, anything that can be /// parsed by [Version.parse()]. @@ -107,7 +105,7 @@ abstract class VersionConstraint { getCurrentTextIndex() => originalText.length - text.length; var startTextIndex = getCurrentTextIndex(); - if(constraints.isNotEmpty || text.isNotEmpty) { + if (constraints.isNotEmpty || text.isNotEmpty) { var constraint = op + originalText.substring(startTextIndex, getCurrentTextIndex()); throw new FormatException('Cannot include other constraints with ' @@ -152,6 +150,17 @@ abstract class VersionConstraint { return new VersionConstraint.intersection(constraints); } + /// Creates a version constraint which allows all versions that are + /// backward compatible with [version]. + /// + /// Versions are considered backward compatible with [version] if they + /// are greater than or equal to [version], but less than the next breaking + /// version ([Version.nextBreaking]) of [version]. + factory VersionConstraint.compatibleWith(Version version) { + return new VersionRange(min: version, includeMin: true, + max: version.nextBreaking); + } + /// Creates a new version constraint that is the intersection of /// [constraints]. /// diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index 16a3fdc24..b58eab704 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -126,30 +126,26 @@ main() { test('parses a "^" post-1.0.0 version', () { var constraint = new VersionConstraint.parse('^1.2.3'); - expect(constraint, equals(new VersionRange(min: v123, includeMin: true, - max: v123.nextBreaking))); + expect(constraint, equals(new VersionConstraint.compatibleWith(v123))); }); test('parses a "^" pre-1.0.0, post-0.1.0 version', () { var constraint = new VersionConstraint.parse('^0.7.2'); - expect(constraint, equals(new VersionRange(min: v072, includeMin: true, - max: v072.nextBreaking))); + expect(constraint, equals(new VersionConstraint.compatibleWith(v072))); }); test('parses a "^" pre-0.1.0 version', () { var constraint = new VersionConstraint.parse('^0.0.3'); - expect(constraint, equals(new VersionRange(min: v003, includeMin: true, - max: v003.nextBreaking))); + expect(constraint, equals(new VersionConstraint.compatibleWith(v003))); }); test('parses a "^" pre-release version', () { var constraint = new VersionConstraint.parse('^0.7.2-pre+1'); var min = new Version.parse('0.7.2-pre+1'); - expect(constraint, equals(new VersionRange(min: min, includeMin: true, - max: min.nextBreaking))); + expect(constraint, equals(new VersionConstraint.compatibleWith(min))); }); test('does not allow "^" to be mixed with other constraints', () { @@ -177,4 +173,11 @@ main() { } }); }); + + test('compatibleWith', () { + var constraint = new VersionConstraint.compatibleWith(v072); + + expect(constraint, equals(new VersionRange(min: v072, includeMin: true, + max: v072.nextBreaking))); + }); } From 9a49be98d3f183c13a065335dc168d7f137deace Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Thu, 23 Oct 2014 14:11:19 -0500 Subject: [PATCH 050/657] Remove trailing whitespace --- pkgs/pub_semver/README.md | 30 +++++++++---------- pkgs/pub_semver/lib/src/version.dart | 8 ++--- .../lib/src/version_constraint.dart | 26 ++++++++-------- .../test/version_constraint_test.dart | 4 +-- 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index 475c1a3ab..3bc37c53e 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -73,23 +73,23 @@ spec. It differs from semver in a few corner cases: specifically selects that unstable version -- they've deliberately opted into it. - * **There is a notion of compatibility between pre-1.0.0 versions.** Semver - deems all pre-1.0.0 versions to be incompatible. This means that the only - way to ensure compatibility when depending on a pre-1.0.0 package is to - pin the dependency to an exact version. Pinned version constraints prevent - automatic patch and pre-release updates. To avoid this situation, pub - defines the "next breaking" version to be the version with the left-most - non-zero digit in [major, minor, patch] incremented, and the subsequent - digits reset to zero. For example, here are some versions along with their + * **There is a notion of compatibility between pre-1.0.0 versions.** Semver + deems all pre-1.0.0 versions to be incompatible. This means that the only + way to ensure compatibility when depending on a pre-1.0.0 package is to + pin the dependency to an exact version. Pinned version constraints prevent + automatic patch and pre-release updates. To avoid this situation, pub + defines the "next breaking" version to be the version with the left-most + non-zero digit in [major, minor, patch] incremented, and the subsequent + digits reset to zero. For example, here are some versions along with their next breaking ones: - + `0.0.3` -> `0.0.4` - `0.7.2-alpha` -> `0.8.0` - `1.2.3` -> `2.0.0` - - To make use of this, pub defines a "^" operator which yields a version - constraint greater than or equal to a given version, but less than its next + `0.7.2-alpha` -> `0.8.0` + `1.2.3` -> `2.0.0` + + To make use of this, pub defines a "^" operator which yields a version + constraint greater than or equal to a given version, but less than its next breaking one. - + [pub]: http://pub.dartlang.org/ [semver]: http://semver.org/ diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 496178fbe..d980514f4 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -220,21 +220,21 @@ class Version implements Comparable, VersionConstraint { /// Gets the next breaking version number that follows this one. /// /// Increments the left-most non-zero digit in ([major], [minor], [patch]). - /// In other words, if [major] and [minor] are zero (e.g. 0.0.3), then it - /// increments [patch]. If [major] is zero and [minor] is not (e.g. 0.7.2), + /// In other words, if [major] and [minor] are zero (e.g. 0.0.3), then it + /// increments [patch]. If [major] is zero and [minor] is not (e.g. 0.7.2), /// then it increments [minor]. Otherwise, it increments [major]. Version get nextBreaking { if (major == 0) { if (minor == 0) { return _incrementPatch(); } - + return _incrementMinor(); } return _incrementMajor(); } - + Version _incrementMajor() => new Version(major + 1, 0, 0); Version _incrementMinor() => new Version(major, minor + 1, 0); Version _incrementPatch() => new Version(major, minor, patch + 1); diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 1b86602c4..0cd45b636 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -24,14 +24,14 @@ abstract class VersionConstraint { /// Parses a version constraint. /// /// This string is one of: - /// + /// /// * "any". [any] version. - /// * "^" followed by a version string. Versions compatible with + /// * "^" followed by a version string. Versions compatible with /// ([VersionConstraint.compatibleWith]) the version. /// * a series of version parts. Each part can be one of: /// * A version string like `1.2.3`. In other words, anything that can be /// parsed by [Version.parse()]. - /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a + /// * A comparison operator (`<`, `>`, `<=`, or `>=`) followed by a /// version string. /// /// Whitespace is ignored. @@ -87,7 +87,7 @@ abstract class VersionConstraint { } throw "Unreachable."; } - + // Try to parse the "^" operator followed by a version. matchCompatibleWith() { var compatibleWith = START_COMPATIBLE_WITH.firstMatch(text); @@ -96,26 +96,26 @@ abstract class VersionConstraint { var op = compatibleWith[0]; text = text.substring(compatibleWith.end); skipWhitespace(); - + var version = matchVersion(); if (version == null) { throw new FormatException('Expected version number after "$op" in ' '"$originalText", got "$text".'); } - + getCurrentTextIndex() => originalText.length - text.length; var startTextIndex = getCurrentTextIndex(); if (constraints.isNotEmpty || text.isNotEmpty) { - var constraint = op + originalText.substring(startTextIndex, + var constraint = op + originalText.substring(startTextIndex, getCurrentTextIndex()); throw new FormatException('Cannot include other constraints with ' '"^" constraint "$constraint" in "$originalText".'); } - - return new VersionRange(min: version, includeMin: true, + + return new VersionRange(min: version, includeMin: true, max: version.nextBreaking); } - + while (true) { skipWhitespace(); @@ -132,7 +132,7 @@ abstract class VersionConstraint { constraints.add(comparison); continue; } - + var compatibleWith = matchCompatibleWith(); if (compatibleWith != null) { return compatibleWith; @@ -150,14 +150,14 @@ abstract class VersionConstraint { return new VersionConstraint.intersection(constraints); } - /// Creates a version constraint which allows all versions that are + /// Creates a version constraint which allows all versions that are /// backward compatible with [version]. /// /// Versions are considered backward compatible with [version] if they /// are greater than or equal to [version], but less than the next breaking /// version ([Version.nextBreaking]) of [version]. factory VersionConstraint.compatibleWith(Version version) { - return new VersionRange(min: version, includeMin: true, + return new VersionRange(min: version, includeMin: true, max: version.nextBreaking); } diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index b58eab704..316d57ddf 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -173,11 +173,11 @@ main() { } }); }); - + test('compatibleWith', () { var constraint = new VersionConstraint.compatibleWith(v072); - expect(constraint, equals(new VersionRange(min: v072, includeMin: true, + expect(constraint, equals(new VersionRange(min: v072, includeMin: true, max: v072.nextBreaking))); }); } From 95d0a3c74efb7ae3ff2d880b91df0cbfb90e6ed3 Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Tue, 28 Oct 2014 08:18:49 -0500 Subject: [PATCH 051/657] compatibleWith(): implement toString() and use to parse ^ --- pkgs/pub_semver/lib/src/version_constraint.dart | 17 +++++++++++------ .../test/version_constraint_test.dart | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 0cd45b636..f67375fbc 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -112,8 +112,7 @@ abstract class VersionConstraint { '"^" constraint "$constraint" in "$originalText".'); } - return new VersionRange(min: version, includeMin: true, - max: version.nextBreaking); + return new VersionConstraint.compatibleWith(version); } while (true) { @@ -156,10 +155,8 @@ abstract class VersionConstraint { /// Versions are considered backward compatible with [version] if they /// are greater than or equal to [version], but less than the next breaking /// version ([Version.nextBreaking]) of [version]. - factory VersionConstraint.compatibleWith(Version version) { - return new VersionRange(min: version, includeMin: true, - max: version.nextBreaking); - } + factory VersionConstraint.compatibleWith(Version version) => + new _CompatibleWithVersionRange(version); /// Creates a new version constraint that is the intersection of /// [constraints]. @@ -199,3 +196,11 @@ class _EmptyVersion implements VersionConstraint { VersionConstraint intersect(VersionConstraint other) => this; String toString() => ''; } + +class _CompatibleWithVersionRange extends VersionRange { + _CompatibleWithVersionRange(Version version) : super( + min: version, includeMin: true, + max: version.nextBreaking, includeMax: false); + + String toString() => '^$min'; +} diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index 316d57ddf..9ba69053f 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -174,10 +174,18 @@ main() { }); }); - test('compatibleWith', () { - var constraint = new VersionConstraint.compatibleWith(v072); + group('compatibleWith()', () { + test('returns the range of compatible versions', () { + var constraint = new VersionConstraint.compatibleWith(v072); - expect(constraint, equals(new VersionRange(min: v072, includeMin: true, - max: v072.nextBreaking))); + expect(constraint, equals(new VersionRange(min: v072, includeMin: true, + max: v072.nextBreaking))); + }); + + test('toString() uses "^"', () { + var constraint = new VersionConstraint.compatibleWith(v072); + + expect(constraint.toString(), equals('^0.7.2')); + }); }); } From a23657d5d6cd9cdd9f4eefd28d94c0bf4fa3ebb5 Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Tue, 28 Oct 2014 08:22:42 -0500 Subject: [PATCH 052/657] parse 'any' as VersionConstraint.any --- pkgs/pub_semver/lib/src/version_constraint.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index f67375fbc..ab035ff21 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -46,7 +46,7 @@ abstract class VersionConstraint { /// >2.0.4 <= 2.4.6 factory VersionConstraint.parse(String text) { // Handle the "any" constraint. - if (text.trim() == "any") return new VersionRange(); + if (text.trim() == "any") return any; var originalText = text; var constraints = []; From 97b3ab283f7bb53fe86ec4086b88dd3e57eb0925 Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Tue, 28 Oct 2014 09:02:45 -0500 Subject: [PATCH 053/657] Move matchCompatibleWith() out of while loop --- .../lib/src/version_constraint.dart | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index ab035ff21..38864aa20 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -45,16 +45,17 @@ abstract class VersionConstraint { /// <=5.1.4 /// >2.0.4 <= 2.4.6 factory VersionConstraint.parse(String text) { - // Handle the "any" constraint. - if (text.trim() == "any") return any; - var originalText = text; - var constraints = []; skipWhitespace() { text = text.trim(); } + skipWhitespace(); + + // Handle the "any" constraint. + if (text == "any") return any; + // Try to parse and consume a version number. matchVersion() { var version = START_VERSION.firstMatch(text); @@ -103,18 +104,19 @@ abstract class VersionConstraint { '"$originalText", got "$text".'); } - getCurrentTextIndex() => originalText.length - text.length; - var startTextIndex = getCurrentTextIndex(); - if (constraints.isNotEmpty || text.isNotEmpty) { - var constraint = op + originalText.substring(startTextIndex, - getCurrentTextIndex()); + if (text.isNotEmpty) { throw new FormatException('Cannot include other constraints with ' - '"^" constraint "$constraint" in "$originalText".'); + '"^" constraint in "$originalText".'); } return new VersionConstraint.compatibleWith(version); } + var compatibleWith = matchCompatibleWith(); + if (compatibleWith != null) return compatibleWith; + + var constraints = []; + while (true) { skipWhitespace(); @@ -132,11 +134,6 @@ abstract class VersionConstraint { continue; } - var compatibleWith = matchCompatibleWith(); - if (compatibleWith != null) { - return compatibleWith; - } - // If we got here, we couldn't parse the remaining string. throw new FormatException('Could not parse version "$originalText". ' 'Unknown text at "$text".'); From 02f1b5b68f52234beb823260e0faea391fbfdedd Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Tue, 28 Oct 2014 09:31:57 -0500 Subject: [PATCH 054/657] Don't use regex to parse ^ --- pkgs/pub_semver/lib/src/patterns.dart | 4 ++-- pkgs/pub_semver/lib/src/version_constraint.dart | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart index 59b0c091a..8b3290095 100644 --- a/pkgs/pub_semver/lib/src/patterns.dart +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -18,5 +18,5 @@ final COMPLETE_VERSION = new RegExp(START_VERSION.pattern + r'$'); /// a string. final START_COMPARISON = new RegExp(r"^[<>]=?"); -/// Parses the "compatible with" operator ("^") at the beginning of a string. -final START_COMPATIBLE_WITH = new RegExp(r"^\^"); +/// The "compatible with" operator. +const COMPATIBLE_WITH = "^"; diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 38864aa20..cb1c64cd4 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -91,22 +91,20 @@ abstract class VersionConstraint { // Try to parse the "^" operator followed by a version. matchCompatibleWith() { - var compatibleWith = START_COMPATIBLE_WITH.firstMatch(text); - if (compatibleWith == null) return null; + if (!text.startsWith(COMPATIBLE_WITH)) return null; - var op = compatibleWith[0]; - text = text.substring(compatibleWith.end); + text = text.substring(COMPATIBLE_WITH.length); skipWhitespace(); var version = matchVersion(); if (version == null) { - throw new FormatException('Expected version number after "$op" in ' - '"$originalText", got "$text".'); + throw new FormatException('Expected version number after ' + '"$COMPATIBLE_WITH" in "$originalText", got "$text".'); } if (text.isNotEmpty) { throw new FormatException('Cannot include other constraints with ' - '"^" constraint in "$originalText".'); + '"$COMPATIBLE_WITH" constraint in "$originalText".'); } return new VersionConstraint.compatibleWith(version); From b541708df38d6e3db26bc6c1edab192a76b1a042 Mon Sep 17 00:00:00 2001 From: Sean Eagan Date: Tue, 28 Oct 2014 10:45:52 -0500 Subject: [PATCH 055/657] Don't special case 0.0.x for ^ --- pkgs/pub_semver/README.md | 11 +++--- pkgs/pub_semver/lib/src/version.dart | 11 ++---- pkgs/pub_semver/test/utils.dart | 2 +- .../test/version_constraint_test.dart | 37 +++++++++---------- pkgs/pub_semver/test/version_test.dart | 2 +- 5 files changed, 28 insertions(+), 35 deletions(-) diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index 3bc37c53e..3f9558f42 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -78,12 +78,13 @@ spec. It differs from semver in a few corner cases: way to ensure compatibility when depending on a pre-1.0.0 package is to pin the dependency to an exact version. Pinned version constraints prevent automatic patch and pre-release updates. To avoid this situation, pub - defines the "next breaking" version to be the version with the left-most - non-zero digit in [major, minor, patch] incremented, and the subsequent - digits reset to zero. For example, here are some versions along with their - next breaking ones: + defines the "next breaking" version as the version which increments the + major version if it's greater than zero, and the minor version otherwise, + resets subsequent digits to zero, and strips any pre-release or build + suffix. For example, here are some versions along with their next breaking + ones: - `0.0.3` -> `0.0.4` + `0.0.3` -> `0.1.0` `0.7.2-alpha` -> `0.8.0` `1.2.3` -> `2.0.0` diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index d980514f4..0eb96c724 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -219,16 +219,11 @@ class Version implements Comparable, VersionConstraint { /// Gets the next breaking version number that follows this one. /// - /// Increments the left-most non-zero digit in ([major], [minor], [patch]). - /// In other words, if [major] and [minor] are zero (e.g. 0.0.3), then it - /// increments [patch]. If [major] is zero and [minor] is not (e.g. 0.7.2), - /// then it increments [minor]. Otherwise, it increments [major]. + /// Increments [major] if it's greater than zero, otherwise [minor], resets + /// subsequent digits to zero, and strips any [preRelease] or [build] + /// suffix. Version get nextBreaking { if (major == 0) { - if (minor == 0) { - return _incrementPatch(); - } - return _incrementMinor(); } diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index 0cc0f6582..d918422c6 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -10,7 +10,7 @@ import 'package:pub_semver/pub_semver.dart'; /// Some stock example versions to use in tests. final v003 = new Version.parse('0.0.3'); -final v004 = new Version.parse('0.0.4'); +final v010 = new Version.parse('0.1.0'); final v072 = new Version.parse('0.7.2'); final v080 = new Version.parse('0.8.0'); final v114 = new Version.parse('1.1.4'); diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index 9ba69053f..ee10a89d3 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -106,7 +106,7 @@ main() { new Version.parse('3.4.5'))); }); - test('ignores whitespace around operators', () { + test('ignores whitespace around comparison operators', () { var constraint = new VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0'); expect(constraint, allows( @@ -123,29 +123,19 @@ main() { throwsFormatException); }); - test('parses a "^" post-1.0.0 version', () { - var constraint = new VersionConstraint.parse('^1.2.3'); + test('parses a "^" version', () { + expect(new VersionConstraint.parse('^0.0.3'), equals( + new VersionConstraint.compatibleWith(v003))); - expect(constraint, equals(new VersionConstraint.compatibleWith(v123))); - }); - - test('parses a "^" pre-1.0.0, post-0.1.0 version', () { - var constraint = new VersionConstraint.parse('^0.7.2'); - - expect(constraint, equals(new VersionConstraint.compatibleWith(v072))); - }); - - test('parses a "^" pre-0.1.0 version', () { - var constraint = new VersionConstraint.parse('^0.0.3'); + expect(new VersionConstraint.parse('^0.7.2'), equals( + new VersionConstraint.compatibleWith(v072))); - expect(constraint, equals(new VersionConstraint.compatibleWith(v003))); - }); - - test('parses a "^" pre-release version', () { - var constraint = new VersionConstraint.parse('^0.7.2-pre+1'); + expect(new VersionConstraint.parse('^1.2.3'), equals( + new VersionConstraint.compatibleWith(v123))); var min = new Version.parse('0.7.2-pre+1'); - expect(constraint, equals(new VersionConstraint.compatibleWith(min))); + expect(new VersionConstraint.parse('^0.7.2-pre+1'), equals( + new VersionConstraint.compatibleWith(min))); }); test('does not allow "^" to be mixed with other constraints', () { @@ -155,6 +145,13 @@ main() { throwsFormatException); }); + test('ignores whitespace around "^"', () { + var constraint = new VersionConstraint.parse(' ^ 1.2.3 '); + + expect(constraint, equals( + new VersionConstraint.compatibleWith(v123))); + }); + test('throws FormatException on a bad string', () { var bad = [ "", " ", // Empty string. diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 527db2942..3c652ac2c 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -201,7 +201,7 @@ main() { test('nextBreaking', () { expect(v123.nextBreaking, equals(v200)); expect(v072.nextBreaking, equals(v080)); - expect(v003.nextBreaking, equals(v004)); + expect(v003.nextBreaking, equals(v010)); // Removes pre-release version if present. expect(new Version.parse('1.2.3-dev').nextBreaking, equals(v200)); From 0a919331dcc837c11a190e03543bc742dc9c46bd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Oct 2014 14:11:28 -0700 Subject: [PATCH 056/657] Update the pubspec and changelog. --- pkgs/pub_semver/CHANGELOG.md | 12 ++++++++++++ pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index bf0e1f93f..5a89ebd4a 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,15 @@ +# 1.1.0 + +* Add support for the `^` operator for compatible versions according to pub's + notion of compatibility. `^1.2.3` is equivalent to `>=1.2.3 <2.0.0`; `^0.1.2` + is equivalent to `>=0.1.2 <0.2.0`. + +* Add `Version.nextBreaking`, which returns the next version that introduces + breaking changes after a given version. + +* Add `new VersionConstraint.compatibleWith()`, which returns a range covering + all versions compatible with a given version. + # 1.0.0 * Initial release. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 63b09e129..b42206490 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.0.0 +version: 1.1.0-dev author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 3fa75ba02d1682bd9a13dcf132d23f5e0384cd00 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Oct 2014 15:49:54 -0700 Subject: [PATCH 057/657] Add VersionRange.hashCode. Closes dart-lang/pub_semver#4 R=rnystrom@google.com Review URL: https://codereview.chromium.org/687973004 --- pkgs/pub_semver/CHANGELOG.md | 2 ++ pkgs/pub_semver/lib/src/version_range.dart | 3 +++ pkgs/pub_semver/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 5a89ebd4a..1580867ca 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -10,6 +10,8 @@ * Add `new VersionConstraint.compatibleWith()`, which returns a range covering all versions compatible with a given version. +* Add a custom `VersionRange.hashCode` to make it properly hashable. + # 1.0.0 * Initial release. diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 7020077a7..faffb4742 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -66,6 +66,9 @@ class VersionRange implements VersionConstraint { includeMax == other.includeMax; } + int get hashCode => min.hashCode ^ (max.hashCode * 3) ^ + (includeMin.hashCode * 5) ^ (includeMax.hashCode * 7); + bool get isEmpty => false; bool get isAny => min == null && max == null; diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index b42206490..3abc401af 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.1.0-dev +version: 1.1.0 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 3db3d336c333afca2caf512d202bc9bc5fcb464f Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 7 Nov 2014 00:30:59 +0000 Subject: [PATCH 058/657] Use a more compact internal representation for FileSpan. R=rnystrom@google.com Review URL: https://codereview.chromium.org//706133002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_span@41591 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/lib/src/file.dart | 30 +++++++++++++++++++++--------- pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 04e4be2fd..e5190bcd9 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.1 + +* Use a more compact internal representation for `FileSpan`. + # 1.0.0 This package was extracted from the diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 0d2d6f6ca..5680733d4 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -73,7 +73,7 @@ class SourceFile { /// If [end] isn't passed, it defaults to the end of the file. FileSpan span(int start, [int end]) { if (end == null) end = length - 1; - return new FileSpan._(this, location(start), location(end)); + return new FileSpan._(this, start, end); } /// Returns a location in [this] at [offset]. @@ -172,7 +172,7 @@ class FileLocation extends SourceLocation { } } - FileSpan pointSpan() => new FileSpan._(file, this, this); + FileSpan pointSpan() => new FileSpan._(file, offset, offset); } /// A [SourceSpan] within a [SourceFile]. @@ -187,14 +187,26 @@ class FileSpan extends SourceSpanMixin { /// The [file] that [this] belongs to. final SourceFile file; - final FileLocation start; - final FileLocation end; + /// The offset of the beginning of the span. + /// + /// [start] is lazily generated from this to avoid allocating unnecessary + /// objects. + final int _start; + + /// The offset of the end of the span. + /// + /// [end] is lazily generated from this to avoid allocating unnecessary + /// objects. + final int _end; + + FileLocation get start => new FileLocation._(file, _start); + FileLocation get end => new FileLocation._(file, _end); String get text => file.getText(start.offset, end.offset); - FileSpan._(this.file, this.start, this.end) { - if (end.offset < start.offset) { - throw new ArgumentError('End $end must come after start $start.'); + FileSpan._(this.file, this._start, this._end) { + if (_end < _start) { + throw new ArgumentError('End $_end must come after start $_start.'); } } @@ -222,8 +234,8 @@ class FileSpan extends SourceSpanMixin { " \"${other.sourceUrl}\" don't match."); } - var start = min(this.start, other.start); - var end = max(this.end, other.end); + var start = math.min(this._start, other._start); + var end = math.max(this._end, other._end); return new FileSpan._(file, start, end); } diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 66e5811ac..ae1bfcfa3 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,6 +1,6 @@ name: source_span -version: 1.0.0 +version: 1.0.1 author: Dart Team description: A library for identifying source spans and locations. homepage: http://www.dartlang.org From 5d7bc2c0124d8d2dfdd00f25b7f880751d7a20f2 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 7 Nov 2014 20:12:46 +0000 Subject: [PATCH 059/657] Fix source_span tests. R=rnystrom@google.com Review URL: https://codereview.chromium.org//712473002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_span@41614 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_span/lib/src/file.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 5680733d4..14aa22627 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -207,6 +207,11 @@ class FileSpan extends SourceSpanMixin { FileSpan._(this.file, this._start, this._end) { if (_end < _start) { throw new ArgumentError('End $_end must come after start $_start.'); + } else if (_end > file.length) { + throw new RangeError("End $_end must not be greater than the number " + "of characters in the file, ${file.length}."); + } else if (_start < 0) { + throw new RangeError("Start may not be negative, was $_start."); } } From 9abb0961a9f1f091ad0ebe51814432922773ab14 Mon Sep 17 00:00:00 2001 From: "nweiz@google.com" Date: Fri, 21 Nov 2014 23:49:39 +0000 Subject: [PATCH 060/657] Avoid instantiating FileLocations where possible in source_span. R=rnystrom@google.com Review URL: https://codereview.chromium.org//754463002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_span@41921 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_span/CHANGELOG.md | 7 ++++++ pkgs/source_span/lib/src/file.dart | 30 +++++++++++++++++++----- pkgs/source_span/lib/src/span_mixin.dart | 6 ++--- pkgs/source_span/pubspec.yaml | 2 +- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index e5190bcd9..f057e9b5c 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.0.2 + +* Avoid unintentionally allocating extra objects for internal `FileSpan` + operations. + +* Ensure that `SourceSpan.operator==` works on arbitrary `Object`s. + # 1.0.1 * Use a more compact internal representation for `FileSpan`. diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 14aa22627..ed5f6a837 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -199,10 +199,11 @@ class FileSpan extends SourceSpanMixin { /// objects. final int _end; + Uri get sourceUrl => file.url; + int get length => _end - _start; FileLocation get start => new FileLocation._(file, _start); FileLocation get end => new FileLocation._(file, _end); - - String get text => file.getText(start.offset, end.offset); + String get text => file.getText(_start, _end); FileSpan._(this.file, this._start, this._end) { if (_end < _start) { @@ -215,20 +216,37 @@ class FileSpan extends SourceSpanMixin { } } + int compareTo(SourceSpan other) { + if (other is! FileSpan) return super.compareTo(other); + + FileSpan otherFile = other; + var result = _start.compareTo(otherFile._start); + return result == 0 ? _end.compareTo(otherFile._end) : result; + } + SourceSpan union(SourceSpan other) { if (other is! FileSpan) return super.union(other); var span = expand(other); - var beginSpan = span.start == this.start ? this : other; - var endSpan = span.end == this.end ? this : other; + var beginSpan = span._start == _start ? this : other; + var endSpan = span._end == _end ? this : other; - if (beginSpan.end.compareTo(endSpan.start) < 0) { + if (beginSpan._end < endSpan._start) { throw new ArgumentError("Spans $this and $other are disjoint."); } return span; } + bool operator ==(other) { + if (other is! FileSpan) return super == other; + return _start == other._start && _end == other._end && + sourceUrl == other.sourceUrl; + } + + int get hashCode => _start.hashCode + 5 * _end.hashCode + + 7 * sourceUrl.hashCode; + /// Returns a new span that covers both [this] and [other]. /// /// Unlike [union], [other] may be disjoint from [this]. If it is, the text @@ -241,7 +259,7 @@ class FileSpan extends SourceSpanMixin { var start = math.min(this._start, other._start); var end = math.max(this._end, other._end); - return new FileSpan._(file, start, end); + return new FileSpan._(file, start, end); } String message(String message, {color}) { diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 95a720aae..716e6e07b 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -21,8 +21,8 @@ abstract class SourceSpanMixin implements SourceSpan { int get length => end.offset - start.offset; int compareTo(SourceSpan other) { - int d = start.compareTo(other.start); - return d == 0 ? end.compareTo(other.end) : d; + var result = start.compareTo(other.start); + return result == 0 ? end.compareTo(other.end) : result; } SourceSpan union(SourceSpan other) { @@ -65,7 +65,7 @@ abstract class SourceSpanMixin implements SourceSpan { return buffer.toString(); } - bool operator ==(SourceSpan other) => + bool operator ==(other) => other is SourceSpan && start == other.start && end == other.end; int get hashCode => start.hashCode + (31 * end.hashCode); diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index ae1bfcfa3..5c166fc6f 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,6 +1,6 @@ name: source_span -version: 1.0.1 +version: 1.0.2 author: Dart Team description: A library for identifying source spans and locations. homepage: http://www.dartlang.org From 266d348e935604f43cf42f76153d27221d47336c Mon Sep 17 00:00:00 2001 From: "tjblasi@google.com" Date: Thu, 4 Dec 2014 01:16:27 +0000 Subject: [PATCH 061/657] Removing unnecessary warning when parsing Json. BUG= R=sigmund@google.com Review URL: https://codereview.chromium.org//781643002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@42098 260f80e4-7a28-3924-810f-c04153c831b5 --- pkgs/source_maps/CHANGELOG.md | 6 ++++++ pkgs/source_maps/lib/parser.dart | 4 ---- pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index a70bc4480..531a6d053 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.10.0+1 + +* Remove an unnecessary warning printed when the "file" field is missing from a + Json formatted source map. This field is optional and its absence is not + unusual. + ## 0.10.0 * Remove the `Span`, `Location` and `SourceFile` classes. Use the diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index d67a65e58..369c27d0a 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -31,10 +31,6 @@ Mapping parseJson(Map map, {Map otherMaps}) { 'Only version 3 is supported.'); } - if (!map.containsKey('file')) { - print('warning: missing "file" entry in source map'); - } - if (map.containsKey('sections')) { if (map.containsKey('mappings') || map.containsKey('sources') || map.containsKey('names')) { diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 4af996e56..275103415 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.0 +version: 0.10.0+1 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://www.dartlang.org From d2cce51db09b1d567dfd516706397ee891035ba9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 17 Dec 2014 16:23:10 -0800 Subject: [PATCH 062/657] Add gitignore, status, and codereview files. --- pkgs/pool/.gitignore | 14 ++++++++++++++ pkgs/pool/.status | 3 +++ pkgs/pool/codereview.settings | 3 +++ 3 files changed, 20 insertions(+) create mode 100644 pkgs/pool/.gitignore create mode 100644 pkgs/pool/.status create mode 100644 pkgs/pool/codereview.settings diff --git a/pkgs/pool/.gitignore b/pkgs/pool/.gitignore new file mode 100644 index 000000000..388eff0ba --- /dev/null +++ b/pkgs/pool/.gitignore @@ -0,0 +1,14 @@ +# Don’t commit the following directories created by pub. +.buildlog +.pub/ +build/ +packages + +# Or the files created by dart2js. +*.dart.js +*.js_ +*.js.deps +*.js.map + +# Include when developing application packages. +pubspec.lock \ No newline at end of file diff --git a/pkgs/pool/.status b/pkgs/pool/.status new file mode 100644 index 000000000..e9f2b0049 --- /dev/null +++ b/pkgs/pool/.status @@ -0,0 +1,3 @@ +# Copyright (c) 2014, 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. diff --git a/pkgs/pool/codereview.settings b/pkgs/pool/codereview.settings new file mode 100644 index 000000000..b474c08cb --- /dev/null +++ b/pkgs/pool/codereview.settings @@ -0,0 +1,3 @@ +CODE_REVIEW_SERVER: http://codereview.chromium.org/ +VIEW_VC: https://github.com/dart-lang/pool/commit/ +CC_LIST: reviews@dartlang.org \ No newline at end of file From ab0b997d6298e65923c45838354a5c5b9ac81d08 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 17 Dec 2014 16:23:25 -0800 Subject: [PATCH 063/657] Update the pubspec's homepage link. --- pkgs/pool/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index c1d543f93..b6a0ff299 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -2,7 +2,7 @@ name: pool version: 1.0.0 author: Dart Team description: A class for managing a finite pool of resources. -homepage: http://www.dartlang.org +homepage: http://github.com/dart-lang/pool dependencies: stack_trace: ">=0.9.2 <2.0.0" dev_dependencies: From 2b3e0406b4295c71b1213a90e14cb710f35eb82b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 17 Dec 2014 16:27:37 -0800 Subject: [PATCH 064/657] Add gitignore, status, and codereview files. --- pkgs/source_span/.gitignore | 14 ++++++++++++++ pkgs/source_span/.status | 3 +++ pkgs/source_span/codereview.settings | 3 +++ 3 files changed, 20 insertions(+) create mode 100644 pkgs/source_span/.gitignore create mode 100644 pkgs/source_span/.status create mode 100644 pkgs/source_span/codereview.settings diff --git a/pkgs/source_span/.gitignore b/pkgs/source_span/.gitignore new file mode 100644 index 000000000..388eff0ba --- /dev/null +++ b/pkgs/source_span/.gitignore @@ -0,0 +1,14 @@ +# Don’t commit the following directories created by pub. +.buildlog +.pub/ +build/ +packages + +# Or the files created by dart2js. +*.dart.js +*.js_ +*.js.deps +*.js.map + +# Include when developing application packages. +pubspec.lock \ No newline at end of file diff --git a/pkgs/source_span/.status b/pkgs/source_span/.status new file mode 100644 index 000000000..e9f2b0049 --- /dev/null +++ b/pkgs/source_span/.status @@ -0,0 +1,3 @@ +# Copyright (c) 2014, 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. diff --git a/pkgs/source_span/codereview.settings b/pkgs/source_span/codereview.settings new file mode 100644 index 000000000..6cae815a0 --- /dev/null +++ b/pkgs/source_span/codereview.settings @@ -0,0 +1,3 @@ +CODE_REVIEW_SERVER: http://codereview.chromium.org/ +VIEW_VC: https://github.com/dart-lang/source_span/commit/ +CC_LIST: reviews@dartlang.org \ No newline at end of file From 98f02e21d5243a71eab869de9582f9af5b6cbaa7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 17 Dec 2014 16:28:19 -0800 Subject: [PATCH 065/657] Update the pubspec's homepage link. --- pkgs/source_span/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 5c166fc6f..55ac89aa4 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -3,7 +3,7 @@ name: source_span version: 1.0.2 author: Dart Team description: A library for identifying source spans and locations. -homepage: http://www.dartlang.org +homepage: http://github.com/dart-lang/source_span dependencies: path: '>=1.2.0 <2.0.0' environment: From 769affb575b92c5a64f2563b5e3e62606724abc1 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 19 Dec 2014 13:58:41 -0800 Subject: [PATCH 066/657] Add gitignore, status, and codereview files. --- pkgs/source_maps/.gitignore | 14 ++++++++++++++ pkgs/source_maps/.status | 20 ++++++++++++++++++++ pkgs/source_maps/codereview.settings | 3 +++ 3 files changed, 37 insertions(+) create mode 100644 pkgs/source_maps/.gitignore create mode 100644 pkgs/source_maps/.status create mode 100644 pkgs/source_maps/codereview.settings diff --git a/pkgs/source_maps/.gitignore b/pkgs/source_maps/.gitignore new file mode 100644 index 000000000..388eff0ba --- /dev/null +++ b/pkgs/source_maps/.gitignore @@ -0,0 +1,14 @@ +# Don’t commit the following directories created by pub. +.buildlog +.pub/ +build/ +packages + +# Or the files created by dart2js. +*.dart.js +*.js_ +*.js.deps +*.js.map + +# Include when developing application packages. +pubspec.lock \ No newline at end of file diff --git a/pkgs/source_maps/.status b/pkgs/source_maps/.status new file mode 100644 index 000000000..befa7ddc7 --- /dev/null +++ b/pkgs/source_maps/.status @@ -0,0 +1,20 @@ +# Copyright (c) 2014, 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. + +# Skip non-test files ending with "_test". +packages/*: Skip +*/packages/*: Skip +*/*/packages/*: Skip +*/*/*/packages/*: Skip +*/*/*/*packages/*: Skip +*/*/*/*/*packages/*: Skip + +# Only run tests from the build directory, since we don't care about the +# difference between transformed an untransformed code. +test/*: Skip + +[ $compiler == dart2js || $compiler == dart2dart ] +build/test/vlq_test: RuntimeError # A VLQ test checks for large numbers that + # overflow in JS (numbers slightly larger than + # 32 bits where we do bitwise operations). diff --git a/pkgs/source_maps/codereview.settings b/pkgs/source_maps/codereview.settings new file mode 100644 index 000000000..313ad0a67 --- /dev/null +++ b/pkgs/source_maps/codereview.settings @@ -0,0 +1,3 @@ +CODE_REVIEW_SERVER: http://codereview.chromium.org/ +VIEW_VC: https://github.com/dart-lang/source_maps/commit/ +CC_LIST: reviews@dartlang.org \ No newline at end of file From fceb4f5fada64d1a63ca791fd3197a9962261abf Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 19 Dec 2014 13:58:59 -0800 Subject: [PATCH 067/657] Update the pubspec's homepage link. --- pkgs/source_maps/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 275103415..1d94c3280 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -2,7 +2,7 @@ name: source_maps version: 0.10.0+1 author: Dart Team description: Library to programmatically manipulate source map files. -homepage: http://www.dartlang.org +homepage: http://github.com/dart-lang/source_maps dependencies: path: '>=1.2.0 <2.0.0' source_span: '>=1.0.0 <2.0.0' From a2de959ea456fb759c139ec31ca86fe4771dc575 Mon Sep 17 00:00:00 2001 From: Kenneth Endfinger Date: Tue, 23 Dec 2014 21:51:34 -0500 Subject: [PATCH 068/657] Fix Typo in Version --- pkgs/pub_semver/lib/src/version.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 0eb96c724..2821e27e3 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -43,7 +43,7 @@ class Version implements Comparable, VersionConstraint { return a.compareTo(b); } - /// Like [proiritize], but lower version numbers are considered greater than + /// Like [prioritize], but lower version numbers are considered greater than /// higher version numbers. /// /// This still considers prerelease versions to be lower than non-prerelease From a2565ead6ffb7f93a9c2e7616479c7bfcb04ea1e Mon Sep 17 00:00:00 2001 From: Kenneth Endfinger Date: Tue, 30 Dec 2014 19:33:25 -0500 Subject: [PATCH 069/657] Bump version to 1.1.1-dev --- pkgs/pub_semver/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 3abc401af..749bc44bd 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.1.0 +version: 1.1.1-dev author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From bda022d51dbbe5a615c7f432dd208c045e8f82fb Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Tue, 27 Jan 2015 15:30:49 -0800 Subject: [PATCH 070/657] Cleanup equality operator to accept any Object rather than just a SourceLocation. BUG= R=nweiz@google.com Review URL: https://codereview.chromium.org//881673002 --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/location.dart | 5 +++-- pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index f057e9b5c..195bcf8de 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.0.3 + +* Cleanup equality operator to accept any Object rather than just a + `SourceLocation`. + # 1.0.2 * Avoid unintentionally allocating extra objects for internal `FileSpan` diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 41f251898..27057424b 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -77,8 +77,9 @@ class SourceLocation implements Comparable { return offset - other.offset; } - bool operator ==(SourceLocation other) => - sourceUrl == other.sourceUrl && offset == other.offset; + bool operator ==(other) => + other is SourceLocation && sourceUrl == other.sourceUrl && + offset == other.offset; int get hashCode => sourceUrl.hashCode + offset; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 55ac89aa4..03b290b17 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,6 +1,6 @@ name: source_span -version: 1.0.2 +version: 1.0.3 author: Dart Team description: A library for identifying source spans and locations. homepage: http://github.com/dart-lang/source_span From 13fb954988cb960dc6d1d411e1da246a5b2d5848 Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Thu, 26 Mar 2015 14:55:28 -0700 Subject: [PATCH 071/657] Introduce span with line context R=nweiz@google.com Review URL: https://codereview.chromium.org//1028813002 --- pkgs/source_span/CHANGELOG.md | 5 ++ pkgs/source_span/lib/source_span.dart | 1 + pkgs/source_span/lib/src/file.dart | 46 +++--------- pkgs/source_span/lib/src/span_mixin.dart | 45 ++++++++++-- .../lib/src/span_with_context.dart | 38 ++++++++++ pkgs/source_span/pubspec.yaml | 5 +- pkgs/source_span/test/span_test.dart | 72 +++++++++++++++++-- pkgs/source_span/test/utils_test.dart | 1 - 8 files changed, 161 insertions(+), 52 deletions(-) create mode 100644 pkgs/source_span/lib/src/span_with_context.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 195bcf8de..6ab52c8e1 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.1.0 + +* Added `SourceSpanWithContext`: a span that also includes the full line of text + that contains the span. + # 1.0.3 * Cleanup equality operator to accept any Object rather than just a diff --git a/pkgs/source_span/lib/source_span.dart b/pkgs/source_span/lib/source_span.dart index e9646b1fd..89b1650ea 100644 --- a/pkgs/source_span/lib/source_span.dart +++ b/pkgs/source_span/lib/source_span.dart @@ -9,3 +9,4 @@ export "src/location.dart"; export "src/span.dart"; export "src/span_exception.dart"; export "src/span_mixin.dart"; +export "src/span_with_context.dart"; diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index ed5f6a837..c7e58982f 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -13,6 +13,7 @@ import 'colors.dart' as colors; import 'location.dart'; import 'span.dart'; import 'span_mixin.dart'; +import 'span_with_context.dart'; import 'utils.dart'; // Constants to determine end-of-lines. @@ -183,7 +184,7 @@ class FileLocation extends SourceLocation { /// [FileSpan.union] will return a [FileSpan] if possible. /// /// A [FileSpan] can be created using [SourceFile.span]. -class FileSpan extends SourceSpanMixin { +class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { /// The [file] that [this] belongs to. final SourceFile file; @@ -205,6 +206,12 @@ class FileSpan extends SourceSpanMixin { FileLocation get end => new FileLocation._(file, _end); String get text => file.getText(_start, _end); + String get context { + var line = start.line; + return file.getText(file.getOffset(line), + line == file.lines - 1 ? null : file.getOffset(line + 1)); + } + FileSpan._(this.file, this._start, this._end) { if (_end < _start) { throw new ArgumentError('End $_end must come after start $_start.'); @@ -261,41 +268,4 @@ class FileSpan extends SourceSpanMixin { var end = math.max(this._end, other._end); return new FileSpan._(file, start, end); } - - String message(String message, {color}) { - if (color == true) color = colors.RED; - if (color == false) color = null; - - var line = start.line; - var column = start.column; - - var buffer = new StringBuffer(); - buffer.write('line ${start.line + 1}, column ${start.column + 1}'); - if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); - buffer.write(': $message\n'); - - var textLine = file.getText(file.getOffset(line), - line == file.lines - 1 ? null : file.getOffset(line + 1)); - - column = math.min(column, textLine.length - 1); - var toColumn = - math.min(column + end.offset - start.offset, textLine.length); - - if (color != null) { - buffer.write(textLine.substring(0, column)); - buffer.write(color); - buffer.write(textLine.substring(column, toColumn)); - buffer.write(colors.NONE); - buffer.write(textLine.substring(toColumn)); - } else { - buffer.write(textLine); - } - if (!textLine.endsWith('\n')) buffer.write('\n'); - - buffer.write(' ' * column); - if (color != null) buffer.write(color); - buffer.write('^' * math.max(toColumn - column, 1)); - if (color != null) buffer.write(colors.NONE); - return buffer.toString(); - } } diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 716e6e07b..a93723f10 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -4,10 +4,12 @@ library source_span.span_mixin; +import 'dart:math' as math; import 'package:path/path.dart' as p; import 'colors.dart' as colors; import 'span.dart'; +import 'span_with_context.dart'; import 'utils.dart'; /// A mixin for easily implementing [SourceSpan]. @@ -49,18 +51,49 @@ abstract class SourceSpanMixin implements SourceSpan { if (color == true) color = colors.RED; if (color == false) color = null; + var line = start.line; + var column = start.column; + var buffer = new StringBuffer(); - buffer.write('line ${start.line + 1}, column ${start.column + 1}'); + buffer.write('line ${line + 1}, column ${column + 1}'); if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); buffer.write(': $message'); - if (length == 0) return buffer.toString(); + if (length == 0 && this is! SourceSpanWithContext) return buffer.toString(); buffer.write("\n"); - var textLine = text.split("\n").first; + + var textLine; + if (this is SourceSpanWithContext) { + var context = (this as SourceSpanWithContext).context; + var textIndex = context.indexOf(text.split('\n').first); + var lineStart = context.lastIndexOf('\n', textIndex); + if (lineStart != -1) { + buffer.write(context.substring(0, lineStart + 1)); + context = context.substring(lineStart + 1); + } + var endIndex = context.indexOf('\n'); + textLine = endIndex == -1 ? context : context.substring(0, endIndex + 1); + column = math.min(column, textLine.length - 1); + } else { + textLine = text.split("\n").first; + column = 0; + } + + var toColumn = + math.min(column + end.offset - start.offset, textLine.length); + if (color != null) { + buffer.write(textLine.substring(0, column)); + buffer.write(color); + buffer.write(textLine.substring(column, toColumn)); + buffer.write(colors.NONE); + buffer.write(textLine.substring(toColumn)); + } else { + buffer.write(textLine); + } + if (!textLine.endsWith('\n')) buffer.write('\n'); + buffer.write(' ' * column); if (color != null) buffer.write(color); - buffer.write(textLine); - buffer.write("\n"); - buffer.write('^' * textLine.length); + buffer.write('^' * math.max(toColumn - column, 1)); if (color != null) buffer.write(colors.NONE); return buffer.toString(); } diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart new file mode 100644 index 000000000..4d279de38 --- /dev/null +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -0,0 +1,38 @@ +// Copyright (c) 2014, 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. + +library source_span.span; + +import 'location.dart'; +import 'span.dart'; + +/// A class that describes a segment of source text with additional context. +class SourceSpanWithContext extends SourceSpanBase { + /// Text around the span, which includes the line containing this span. + final String context; + + /// Creates a new span from [start] to [end] (exclusive) containing [text], in + /// the given [context]. + /// + /// [start] and [end] must have the same source URL and [start] must come + /// before [end]. [text] must have a number of characters equal to the + /// distance between [start] and [end]. [context] must contain [text], and + /// [text] should start at `start.column` from the beginning of a line in + /// [context]. + SourceSpanWithContext( + SourceLocation start, SourceLocation end, String text, this.context) + : super(start, end, text) { + var index = context.indexOf(text); + if (index == -1) { + throw new ArgumentError( + 'The context line "$context" must contain "$text".'); + } + + var beginningOfLine = context.lastIndexOf('\n', index) + 1; + if (start.column != index - beginningOfLine) { + throw new ArgumentError('The span text "$text" must start at ' + 'column ${start.column + 1} in a line within "$context".'); + } + } +} diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 03b290b17..887c040ca 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,6 +1,5 @@ name: source_span - -version: 1.0.3 +version: 1.1.0 author: Dart Team description: A library for identifying source spans and locations. homepage: http://github.com/dart-lang/source_span @@ -9,4 +8,4 @@ dependencies: environment: sdk: '>=0.8.10+6 <2.0.0' dev_dependencies: - unittest: '>=0.9.0 <0.10.0' + unittest: '>=0.9.0 <0.12.0' diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index c62753b1a..39b0b9433 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -36,6 +36,37 @@ main() { }); }); + group('for new SourceSpanWithContext()', () { + test('context must contain text', () { + var start = new SourceLocation(2); + var end = new SourceLocation(5); + expect(() => new SourceSpanWithContext( + start, end, "abc", "--axc--"), throwsArgumentError); + }); + + test('text starts at start.column in context', () { + var start = new SourceLocation(3); + var end = new SourceLocation(5); + expect(() => new SourceSpanWithContext( + start, end, "abc", "--abc--"), throwsArgumentError); + }); + + test('text starts at start.column of line in multi-line context', () { + var start = new SourceLocation(4, line: 55, column: 3); + var end = new SourceLocation(7, line: 55, column: 6); + expect(() => new SourceSpanWithContext( + start, end, "abc", "\n--abc--"), throwsArgumentError); + expect(() => new SourceSpanWithContext( + start, end, "abc", "\n----abc--"), throwsArgumentError); + expect(() => new SourceSpanWithContext( + start, end, "abc", "\n\n--abc--"), throwsArgumentError); + + // However, these are valid: + new SourceSpanWithContext(start, end, "abc", "\n---abc--"); + new SourceSpanWithContext(start, end, "abc", "\n\n---abc--"); + }); + }); + group('for union()', () { test('source URLs must match', () { var other = new SourceSpan( @@ -178,15 +209,48 @@ foo bar expect(span.message("oh no", color: true), equals(""" line 1, column 6 of foo.dart: oh no -${colors.RED}foo bar -^^^^^^^${colors.NONE}""")); +${colors.RED}foo bar${colors.NONE} +${colors.RED}^^^^^^^${colors.NONE}""")); }); test("uses the given color if it's passed", () { expect(span.message("oh no", color: colors.YELLOW), equals(""" line 1, column 6 of foo.dart: oh no -${colors.YELLOW}foo bar -^^^^^^^${colors.NONE}""")); +${colors.YELLOW}foo bar${colors.NONE} +${colors.YELLOW}^^^^^^^${colors.NONE}""")); + }); + }); + + group("message() with context", () { + var spanWithContext; + setUp(() { + spanWithContext = new SourceSpanWithContext( + new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(12, sourceUrl: "foo.dart"), + "foo bar", + "-----foo bar-----"); + }); + + test("underlines under the right column", () { + expect(spanWithContext.message("oh no", color: colors.YELLOW), equals(""" +line 1, column 6 of foo.dart: oh no +-----${colors.YELLOW}foo bar${colors.NONE}----- + ${colors.YELLOW}^^^^^^^${colors.NONE}""")); + }); + + test("supports lines of preceeding context", () { + var span = new SourceSpanWithContext( + new SourceLocation(5, line: 3, column: 5, sourceUrl: "foo.dart"), + new SourceLocation(12, line: 3, column: 12, sourceUrl: "foo.dart"), + "foo bar", + "previous\nlines\n-----foo bar-----\nfollowing line\n"); + + expect(span.message("oh no", color: colors.YELLOW), equals(""" +line 4, column 6 of foo.dart: oh no +previous +lines +-----${colors.YELLOW}foo bar${colors.NONE}----- + ${colors.YELLOW}^^^^^^^${colors.NONE}""")); }); }); diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index 39211111e..a99884709 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -48,4 +48,3 @@ _linearSearch(list, predicate) { } return list.length; } - From 21cddeb0ee8f54a8e29558ea46f6448f7ec2a1e5 Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Thu, 26 Mar 2015 15:06:18 -0700 Subject: [PATCH 072/657] Fix library name (dartanalyzer was complaining in the bots) R=nweiz@google.com Review URL: https://codereview.chromium.org//1033083002 --- pkgs/source_span/lib/src/span_with_context.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart index 4d279de38..edbb8b65f 100644 --- a/pkgs/source_span/lib/src/span_with_context.dart +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -2,7 +2,7 @@ // 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. -library source_span.span; +library source_span.span_with_context; import 'location.dart'; import 'span.dart'; From c7557077f5360675dff2774b4b03575dec2ba685 Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Fri, 27 Mar 2015 14:24:56 -0700 Subject: [PATCH 073/657] Fix FileSpan.context to include FileSpan.text. R=nweiz@google.com Review URL: https://codereview.chromium.org//1039603004 --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/file.dart | 8 ++------ pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/file_test.dart | 8 +++++++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 6ab52c8e1..e749513fe 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.1.1 + +* Fixed `FileSpan`'s context to include the full span text, not just the first + line of it. + # 1.1.0 * Added `SourceSpanWithContext`: a span that also includes the full line of text diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index c7e58982f..4b4e026cb 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -205,12 +205,8 @@ class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { FileLocation get start => new FileLocation._(file, _start); FileLocation get end => new FileLocation._(file, _end); String get text => file.getText(_start, _end); - - String get context { - var line = start.line; - return file.getText(file.getOffset(line), - line == file.lines - 1 ? null : file.getOffset(line + 1)); - } + String get context => file.getText(file.getOffset(start.line), + end.line == file.lines - 1 ? null : file.getOffset(end.line + 1)); FileSpan._(this.file, this._start, this._end) { if (_end < _start) { diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 887c040ca..73c266741 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.1.0 +version: 1.1.1 author: Dart Team description: A library for identifying source spans and locations. homepage: http://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 114a17e44..c27c1f64f 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -253,6 +253,12 @@ zip zap zop""", url: "bar.dart").span(10, 11); expect(file.span(8, 15).text, equals("baz\nwhi")); }); + test("context contains the span's text", () { + var span = file.span(8, 15); + expect(span.context.contains(span.text), isTrue); + expect(span.context, equals('foo bar baz\nwhiz bang boom\n')); + }); + group("union()", () { var span; setUp(() { @@ -367,4 +373,4 @@ zip zap zop""", url: "bar.dart").span(10, 11); }); }); }); -} \ No newline at end of file +} From 14112478108ebb8f60818319d22e94100f0133a2 Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Fri, 27 Mar 2015 17:39:28 -0700 Subject: [PATCH 074/657] Fix sourcemap after changes in source_span BUG= R=nweiz@google.com Review URL: https://codereview.chromium.org//1035343002 --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/lib/src/source_map_span.dart | 1 + pkgs/source_maps/pubspec.yaml | 10 +++++----- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 531a6d053..747765511 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.0+2 + +* Fix analyzer error (FileSpan has a new field since `source_span` 1.1.1) + ## 0.10.0+1 * Remove an unnecessary warning printed when the "file" field is missing from a diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index 20eb17ad0..b70bdfe98 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -44,6 +44,7 @@ class SourceMapFileSpan implements SourceMapSpan, FileSpan { FileLocation get start => _inner.start; FileLocation get end => _inner.end; String get text => _inner.text; + String get context => _inner.context; Uri get sourceUrl => _inner.sourceUrl; int get length => _inner.length; diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 1d94c3280..200f8f85b 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,12 +1,12 @@ name: source_maps -version: 0.10.0+1 +version: 0.10.0+2 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps dependencies: - path: '>=1.2.0 <2.0.0' - source_span: '>=1.0.0 <2.0.0' + path: ^1.2.0 + source_span: ^1.1.1 environment: - sdk: '>=0.8.10+6 <2.0.0' + sdk: '>=1.8.0 <2.0.0' dev_dependencies: - unittest: '>=0.9.0 <0.10.0' + unittest: '>=0.9.0 <0.12.0' From 0e4e3ffb57e7815fdd72f99ef382b2300e436f23 Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Tue, 31 Mar 2015 12:54:40 -0700 Subject: [PATCH 075/657] Support multiple occurrences of text in context R=nweiz@google.com Review URL: https://codereview.chromium.org//1041163005 --- pkgs/source_span/CHANGELOG.md | 5 +++ pkgs/source_span/lib/src/span_mixin.dart | 9 ++--- .../lib/src/span_with_context.dart | 7 ++-- pkgs/source_span/lib/src/utils.dart | 17 ++++++++ pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/span_test.dart | 27 +++++++++++++ pkgs/source_span/test/utils_test.dart | 39 +++++++++++++++++++ 7 files changed, 96 insertions(+), 10 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index e749513fe..51b0feaa0 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.1.2 + +* Fixed validation in `SourceSpanWithContext` to allow multiple occurrences of + `text` within `context`. + # 1.1.1 * Fixed `FileSpan`'s context to include the full span text, not just the first diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index a93723f10..b4503facd 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -65,11 +65,10 @@ abstract class SourceSpanMixin implements SourceSpan { var textLine; if (this is SourceSpanWithContext) { var context = (this as SourceSpanWithContext).context; - var textIndex = context.indexOf(text.split('\n').first); - var lineStart = context.lastIndexOf('\n', textIndex); - if (lineStart != -1) { - buffer.write(context.substring(0, lineStart + 1)); - context = context.substring(lineStart + 1); + var lineStart = findLineStart(context, text, column); + if (lineStart != null && lineStart > 0) { + buffer.write(context.substring(0, lineStart)); + context = context.substring(lineStart); } var endIndex = context.indexOf('\n'); textLine = endIndex == -1 ? context : context.substring(0, endIndex + 1); diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart index edbb8b65f..0012e3f3d 100644 --- a/pkgs/source_span/lib/src/span_with_context.dart +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -6,6 +6,7 @@ library source_span.span_with_context; import 'location.dart'; import 'span.dart'; +import 'utils.dart'; /// A class that describes a segment of source text with additional context. class SourceSpanWithContext extends SourceSpanBase { @@ -23,14 +24,12 @@ class SourceSpanWithContext extends SourceSpanBase { SourceSpanWithContext( SourceLocation start, SourceLocation end, String text, this.context) : super(start, end, text) { - var index = context.indexOf(text); - if (index == -1) { + if (!context.contains(text)) { throw new ArgumentError( 'The context line "$context" must contain "$text".'); } - var beginningOfLine = context.lastIndexOf('\n', index) + 1; - if (start.column != index - beginningOfLine) { + if (findLineStart(context, text, start.column) == null) { throw new ArgumentError('The span text "$text" must start at ' 'column ${start.column + 1} in a line within "$context".'); } diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 4a8eb551e..2d3386542 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -37,3 +37,20 @@ int binarySearch(List list, bool matches(item)) { return max; } +/// Finds a line in [context] containing [text] at the specified [column]. +/// +/// Returns the index in [context] where that line begins, or null if none +/// exists. +int findLineStart(String context, String text, int column) { + var isEmpty = text == ''; + var index = context.indexOf(text); + while (index != -1) { + var lineStart = context.lastIndexOf('\n', index) + 1; + var textColumn = index - lineStart; + if (column == textColumn || (isEmpty && column == textColumn + 1)) { + return lineStart; + } + index = context.indexOf(text, index + 1); + } + return null; +} diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 73c266741..16eee7cca 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.1.1 +version: 1.1.2 author: Dart Team description: A library for identifying source spans and locations. homepage: http://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 39b0b9433..2657f5ffd 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -65,6 +65,21 @@ main() { new SourceSpanWithContext(start, end, "abc", "\n---abc--"); new SourceSpanWithContext(start, end, "abc", "\n\n---abc--"); }); + + test('text can occur multiple times in context', () { + var start1 = new SourceLocation(4, line: 55, column: 2); + var end1 = new SourceLocation(7, line: 55, column: 5); + var start2 = new SourceLocation(4, line: 55, column: 8); + var end2 = new SourceLocation(7, line: 55, column: 11); + new SourceSpanWithContext(start1, end1, "abc", "--abc---abc--\n"); + new SourceSpanWithContext(start1, end1, "abc", "--abc--abc--\n"); + new SourceSpanWithContext(start2, end2, "abc", "--abc---abc--\n"); + new SourceSpanWithContext(start2, end2, "abc", "---abc--abc--\n"); + expect(() => new SourceSpanWithContext( + start1, end1, "abc", "---abc--abc--\n"), throwsArgumentError); + expect(() => new SourceSpanWithContext( + start2, end2, "abc", "--abc--abc--\n"), throwsArgumentError); + }); }); group('for union()', () { @@ -238,6 +253,18 @@ line 1, column 6 of foo.dart: oh no ${colors.YELLOW}^^^^^^^${colors.NONE}""")); }); + test("underlines correctly when text appears twice", () { + var span = new SourceSpanWithContext( + new SourceLocation(9, column: 9, sourceUrl: "foo.dart"), + new SourceLocation(12, column: 12, sourceUrl: "foo.dart"), + "foo", + "-----foo foo-----"); + expect(span.message("oh no", color: colors.YELLOW), equals(""" +line 1, column 10 of foo.dart: oh no +-----foo ${colors.YELLOW}foo${colors.NONE}----- + ${colors.YELLOW}^^^${colors.NONE}""")); + }); + test("supports lines of preceeding context", () { var span = new SourceSpanWithContext( new SourceLocation(5, line: 3, column: 5, sourceUrl: "foo.dart"), diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index a99884709..74975c35b 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -39,6 +39,45 @@ main() { } }); }); + + group('find line start', () { + test('skip entries in wrong column', () { + var context = '0_bb\n1_bbb\n2b____\n3bbb\n'; + var index = findLineStart(context, 'b', 1); + expect(index, 11); + expect(context.substring(index - 1, index + 3), '\n2b_'); + }); + + test('end of line column for empty text', () { + var context = '0123\n56789\nabcdefgh\n'; + var 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); + expect(index, 4); + expect(context[index], '4'); + + context = '0\n2\n45'; + index = findLineStart(context, '', 2); + expect(index, 4); + }); + + test('found on the first line', () { + var context = '0\n2\n45\n'; + var index = findLineStart(context, '0', 0); + expect(index, 0); + }); + + test('not found', () { + var context = '0\n2\n45\n'; + var index = findLineStart(context, '0', 1); + expect(index, isNull); + }); + }); } _linearSearch(list, predicate) { From a9328a63c118de5c460e628135e939ffdb8323b7 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Apr 2015 10:32:04 -0700 Subject: [PATCH 076/657] remove analyzer warnings add code review settings R=nweiz@google.com Review URL: https://codereview.chromium.org//1109053002 --- pkgs/pub_semver/codereview.settings | 3 +++ pkgs/pub_semver/lib/src/version.dart | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 pkgs/pub_semver/codereview.settings diff --git a/pkgs/pub_semver/codereview.settings b/pkgs/pub_semver/codereview.settings new file mode 100644 index 000000000..94ddf0ea9 --- /dev/null +++ b/pkgs/pub_semver/codereview.settings @@ -0,0 +1,3 @@ +CODE_REVIEW_SERVER: https://codereview.chromium.org/ +VIEW_VC: https://github.com/dart-lang/pub_semver/commit/ +CC_LIST: reviews@dartlang.org \ No newline at end of file diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 2821e27e3..2bf535fcc 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -122,7 +122,7 @@ class Version implements Comparable, VersionConstraint { String build = match[8]; return new Version._(major, minor, patch, preRelease, build, text); - } on FormatException catch (ex) { + } on FormatException { throw new FormatException('Could not parse "$text".'); } } @@ -149,7 +149,7 @@ class Version implements Comparable, VersionConstraint { return text.split('.').map((part) { try { return int.parse(part); - } on FormatException catch (ex) { + } on FormatException { // Not a number. return part; } From 96485a882b8df24ec7ea0a3cb34ae0ea68d45e14 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 29 Apr 2015 11:24:39 -0700 Subject: [PATCH 077/657] Add a mapUrl parameter to parse() and parseJson(). Closes dart-lang/source_maps#2 R=sigmund@google.com Review URL: https://codereview.chromium.org//1112743002 --- pkgs/source_maps/CHANGELOG.md | 5 +++ pkgs/source_maps/lib/parser.dart | 43 ++++++++++++++++++-------- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 8 +++++ 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 747765511..3066293dd 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.1 + +* Add a `mapUrl` named argument to `parse` and `parseJson`. This argument is + used to resolve source URLs for source spans. + ## 0.10.0+2 * Fix analyzer error (FileSpan has a new field since `source_span` 1.1.1) diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 369c27d0a..a9fcff578 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -16,15 +16,23 @@ import 'src/utils.dart'; import 'src/vlq.dart'; /// Parses a source map directly from a json string. +/// +/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of +/// the source map file itself. If it's passed, any URLs in the source +/// map will be interpreted as relative to this URL when generating spans. // TODO(sigmund): evaluate whether other maps should have the json parsed, or // the string represenation. // TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string // `)]}'` begins the string representation of the map. -Mapping parse(String jsonMap, {Map otherMaps}) => - parseJson(JSON.decode(jsonMap), otherMaps: otherMaps); +Mapping parse(String jsonMap, {Map otherMaps, mapUrl}) => + parseJson(JSON.decode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); /// Parses a source map directly from a json map object. -Mapping parseJson(Map map, {Map otherMaps}) { +/// +/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of +/// the source map file itself. If it's passed, any URLs in the source +/// map will be interpreted as relative to this URL when generating spans. +Mapping parseJson(Map map, {Map otherMaps, mapUrl}) { if (map['version'] != 3) { throw new ArgumentError( 'unexpected source map version: ${map["version"]}. ' @@ -37,9 +45,10 @@ Mapping parseJson(Map map, {Map otherMaps}) { throw new FormatException('map containing "sections" ' 'cannot contain "mappings", "sources", or "names".'); } - return new MultiSectionMapping.fromJson(map['sections'], otherMaps); + return new MultiSectionMapping.fromJson(map['sections'], otherMaps, + mapUrl: mapUrl); } - return new SingleMapping.fromJson(map); + return new SingleMapping.fromJson(map, mapUrl: mapUrl); } @@ -68,7 +77,8 @@ class MultiSectionMapping extends Mapping { final List _maps = []; /// Creates a section mapping from json. - MultiSectionMapping.fromJson(List sections, Map otherMaps) { + MultiSectionMapping.fromJson(List sections, Map otherMaps, + {mapUrl}) { for (var section in sections) { var offset = section['offset']; if (offset == null) throw new FormatException('section missing offset'); @@ -93,9 +103,9 @@ class MultiSectionMapping extends Mapping { 'section contains refers to $url, but no map was ' 'given for it. Make sure a map is passed in "otherMaps"'); } - _maps.add(parseJson(otherMaps[url], otherMaps: otherMaps)); + _maps.add(parseJson(otherMaps[url], otherMaps: otherMaps, mapUrl: url)); } else if (map != null) { - _maps.add(parseJson(map, otherMaps: otherMaps)); + _maps.add(parseJson(map, otherMaps: otherMaps, mapUrl: mapUrl)); } else { throw new FormatException('section missing url or map'); } @@ -149,10 +159,13 @@ class SingleMapping extends Mapping { /// Url of the target file. String targetUrl; - /// Source root appended to the start of all entries in [urls]. + /// Source root prepended to all entries in [urls]. String sourceRoot; - SingleMapping._(this.targetUrl, this.urls, this.names, this.lines); + final Uri _mapUrl; + + SingleMapping._(this.targetUrl, this.urls, this.names, this.lines) + : _mapUrl = null; factory SingleMapping.fromEntries( Iterable entries, [String fileUrl]) { @@ -197,12 +210,13 @@ class SingleMapping extends Mapping { fileUrl, urls.keys.toList(), names.keys.toList(), lines); } - SingleMapping.fromJson(Map map) + SingleMapping.fromJson(Map map, {mapUrl}) : targetUrl = map['file'], urls = map['sources'], names = map['names'], sourceRoot = map['sourceRoot'], - lines = [] { + lines = [], + _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl { int line = 0; int column = 0; int srcUrlId = 0; @@ -373,7 +387,10 @@ class SingleMapping extends Mapping { } } else { var start = new SourceLocation(0, - sourceUrl: url, line: entry.sourceLine, column: entry.sourceColumn); + sourceUrl: _mapUrl == null ? url : _mapUrl.resolve(url), + line: entry.sourceLine, + column: entry.sourceColumn); + // Offset and other context is not available. if (entry.sourceNameId != null) { return new SourceMapSpan.identifier(start, names[entry.sourceNameId]); diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 200f8f85b..fc0fe9bcc 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.0+2 +version: 0.10.1 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 8528683f3..b14fdf425 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -114,6 +114,14 @@ main() { expect(mapping.toJson(), equals(inputMap)); }); + test('parse with map URL', () { + var inputMap = new Map.from(MAP_WITH_SOURCE_LOCATION); + inputMap['sourceRoot'] = 'pkg/'; + var mapping = parseJson(inputMap, mapUrl: "file:///path/to/map"); + expect(mapping.spanFor(0, 0).sourceUrl, + Uri.parse("file:///path/to/pkg/input.dart")); + }); + test('parse and re-emit', () { for (var expected in [ EXPECTED_MAP, From 37e577006cffd28a85927cbf51abfdcd845873fd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 5 May 2015 12:00:34 -0700 Subject: [PATCH 078/657] Use the new test runner. R=rnystrom@google.com Review URL: https://codereview.chromium.org/1121233007 --- pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/test_all.dart | 17 ----------------- pkgs/pub_semver/test/utils.dart | 2 +- .../test/version_constraint_test.dart | 2 +- pkgs/pub_semver/test/version_range_test.dart | 2 +- pkgs/pub_semver/test/version_test.dart | 2 +- 6 files changed, 5 insertions(+), 22 deletions(-) delete mode 100644 pkgs/pub_semver/test/test_all.dart diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 749bc44bd..bfb104cb5 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -8,6 +8,6 @@ homepage: http://github.com/dart-lang/pub_semver dependencies: collection: ">=0.9.0 <2.0.0" dev_dependencies: - unittest: ">=0.9.0 <0.12.0" + test: ">=0.12.0 <0.13.0" environment: sdk: ">=1.0.0 <2.0.0" diff --git a/pkgs/pub_semver/test/test_all.dart b/pkgs/pub_semver/test/test_all.dart deleted file mode 100644 index 533dde82e..000000000 --- a/pkgs/pub_semver/test/test_all.dart +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2014, 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. - -library pub_semver.test.test_all; - -import 'package:unittest/unittest.dart'; - -import 'version_constraint_test.dart' as version_constraint_test; -import 'version_range_test.dart' as version_range_test; -import 'version_test.dart' as version_test; - -main() { - group('Version', version_test.main); - group('VersionConstraint', version_constraint_test.main); - group('VersionRange', version_range_test.main); -} diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index d918422c6..6fefdae76 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -4,7 +4,7 @@ library pub_semver.test.utils; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index ee10a89d3..b38305498 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -4,7 +4,7 @@ library pub_semver.test.version_constraint_test; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 388917ff5..e15539bec 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -4,7 +4,7 @@ library pub_semver.test.version_range_test; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 3c652ac2c..874500605 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -4,7 +4,7 @@ library pub_semver.test.version_test; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; From 92e6f47f6321a0c8924adaa8f809f607bbfee375 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 6 May 2015 11:19:10 -0700 Subject: [PATCH 079/657] Add more set-like version constraint operations. This adds support for union(), as well as checking if constraints are supersets of or disjoint with one another. These are necessary for some version solver work I'm doing in pub. R=rnystrom@google.com Review URL: https://codereview.chromium.org/1127783002 --- pkgs/pub_semver/CHANGELOG.md | 12 + pkgs/pub_semver/lib/src/utils.dart | 26 ++ pkgs/pub_semver/lib/src/version.dart | 41 +- .../lib/src/version_constraint.dart | 24 ++ pkgs/pub_semver/lib/src/version_range.dart | 134 +++++++ pkgs/pub_semver/lib/src/version_union.dart | 182 +++++++++ pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_range_test.dart | 236 ++++++++++++ pkgs/pub_semver/test/version_test.dart | 50 +++ pkgs/pub_semver/test/version_union_test.dart | 352 ++++++++++++++++++ 10 files changed, 1046 insertions(+), 13 deletions(-) create mode 100644 pkgs/pub_semver/lib/src/utils.dart create mode 100644 pkgs/pub_semver/lib/src/version_union.dart create mode 100644 pkgs/pub_semver/test/version_union_test.dart diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 1580867ca..32538cc9c 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,15 @@ +# 1.2.0 + +* Add a `VersionConstraint.union()` method and a `new + VersionConstraint.unionOf()` constructor. These each return a constraint that + matches multiple existing constraints. + +* Add a `VersionConstraint.allowsAll()` method, which returns whether one + constraint is a superset of another. + +* Add a `VersionConstraint.allowsAny()` method, which returns whether one + constraint overlaps another. + # 1.1.0 * Add support for the `^` operator for compatible versions according to pub's diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart new file mode 100644 index 000000000..2853e5cb4 --- /dev/null +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2015, 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. + +library pub_semver.src.utils; + +import 'version_range.dart'; + +/// Returns whether [range1] is immediately next to, but not overlapping, +/// [range2]. +bool areAdjacent(VersionRange range1, VersionRange range2) { + if (range1.max != range2.min) return false; + + return (range1.includeMax && !range2.includeMin) || + (!range1.includeMax && range2.includeMin); +} + +/// A [Comparator] that compares the maximum versions of [range1] and [range2]. +int compareMax(VersionRange range1, VersionRange range2) { + if (range1.max < range2.max) return -1; + if (range1.max > range2.max) return 1; + + if (!range1.includeMax && range2.includeMax) return -1; + if (range1.includeMax && !range2.includeMax) return 1; + return 0; +} diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 2bf535fcc..51972f7dd 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -4,7 +4,7 @@ library pub_semver.src.version; -import 'dart:math'; +import 'dart:math' as math; import 'package:collection/equality.dart'; @@ -16,7 +16,7 @@ import 'version_range.dart'; final _equality = const IterableEquality(); /// A parsed semantic version number. -class Version implements Comparable, VersionConstraint { +class Version implements Comparable, VersionConstraint, VersionRange { /// No released version: i.e. "0.0.0". static Version get none => new Version(0, 0, 0); @@ -85,6 +85,11 @@ class Version implements Comparable, VersionConstraint { /// of the parsed version. final String _text; + Version get min => this; + Version get max => this; + bool get includeMin => true; + bool get includeMax => true; + Version._(this.major, this.minor, this.patch, String preRelease, String build, this._text) : preRelease = preRelease == null ? [] : _splitParts(preRelease), @@ -237,19 +242,31 @@ class Version implements Comparable, VersionConstraint { /// Tests if [other] matches this version exactly. bool allows(Version other) => this == other; - VersionConstraint intersect(VersionConstraint other) { - if (other.isEmpty) return other; + bool allowsAll(VersionConstraint other) => other.isEmpty || other == this; + + bool allowsAny(VersionConstraint other) => other.allows(this); + + VersionConstraint intersect(VersionConstraint other) => + other.allows(this) ? this : VersionConstraint.empty; - // Intersect a version and a range. - if (other is VersionRange) return other.intersect(this); + VersionConstraint union(VersionConstraint other) { + if (other.allows(this)) return other; - // Intersecting two versions only works if they are the same. - if (other is Version) { - return this == other ? this : VersionConstraint.empty; + if (other is VersionRange) { + if (other.min == this) { + return new VersionRange( + min: other.min, max: other.max, + includeMin: true, includeMax: other.includeMax); + } + + if (other.max == this) { + return new VersionRange( + min: other.min, max: other.max, + includeMin: other.includeMin, includeMax: true); + } } - throw new ArgumentError( - 'Unknown VersionConstraint type $other.'); + return new VersionConstraint.unionOf([this, other]); } int compareTo(Version other) { @@ -277,7 +294,7 @@ class Version implements Comparable, VersionConstraint { /// This is used for the pre-release and build version parts. This follows /// Rule 12 of the Semantic Versioning spec (v2.0.0-rc.1). int _compareLists(List a, List b) { - for (var i = 0; i < max(a.length, b.length); i++) { + for (var i = 0; i < math.max(a.length, b.length); i++) { var aPart = (i < a.length) ? a[i] : null; var bPart = (i < b.length) ? b[i] : null; diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index cb1c64cd4..3f4d5b8c8 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -7,6 +7,7 @@ library pub_semver.src.version_constraint; import 'patterns.dart'; import 'version.dart'; import 'version_range.dart'; +import 'version_union.dart'; /// A [VersionConstraint] is a predicate that can determine whether a given /// version is valid or not. @@ -168,6 +169,14 @@ abstract class VersionConstraint { return constraint; } + /// Creates a new version constraint that is the union of [constraints]. + /// + /// It allows any versions that any of those constraints allows. If + /// [constraints] is empty, this returns a constraint that allows no versions. + factory VersionConstraint.unionOf( + Iterable constraints) => + VersionUnion.create(constraints); + /// Returns `true` if this constraint allows no versions. bool get isEmpty; @@ -177,9 +186,21 @@ abstract class VersionConstraint { /// Returns `true` if this constraint allows [version]. bool allows(Version version); + /// Returns `true` if this constraint allows all the versions that [other] + /// allows. + bool allowsAll(VersionConstraint other); + + /// Returns `true` if this constraint allows any of the versions that [other] + /// allows. + bool allowsAny(VersionConstraint other); + /// Creates a new [VersionConstraint] that only allows [Version]s allowed by /// both this and [other]. VersionConstraint intersect(VersionConstraint other); + + /// Creates a new [VersionConstraint] that allows [Versions]s allowed by + /// either this or [other]. + VersionConstraint union(VersionConstraint other); } class _EmptyVersion implements VersionConstraint { @@ -188,7 +209,10 @@ class _EmptyVersion implements VersionConstraint { bool get isEmpty => true; bool get isAny => false; bool allows(Version other) => false; + bool allowsAll(Version other) => other.isEmpty; + bool allowsAny(Version other) => false; VersionConstraint intersect(VersionConstraint other) => this; + VersionConstraint union(VersionConstraint other) => other; String toString() => ''; } diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index faffb4742..7a18edf0e 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -6,6 +6,7 @@ library pub_semver.src.version_range; import 'version.dart'; import 'version_constraint.dart'; +import 'version_union.dart'; /// Constrains versions to a fall within a given range. /// @@ -99,8 +100,81 @@ class VersionRange implements VersionConstraint { return true; } + bool allowsAll(VersionConstraint other) { + if (other.isEmpty) return true; + if (other is Version) return allows(other); + + if (other is VersionUnion) { + return other.constraints.every((constraint) => allowsAll(constraint)); + } + + if (other is VersionRange) { + if (min != null) { + if (other.min == null) return false; + if (min > other.min) return false; + if (min == other.min && !includeMin && other.includeMin) return false; + } + + if (max != null) { + if (other.max == null) return false; + if (max < other.max) return false; + if (max == other.max && !includeMax && other.includeMax) return false; + } + + return true; + } + + throw new ArgumentError('Unknown VersionConstraint type $other.'); + } + + bool allowsAny(VersionConstraint other) { + if (other.isEmpty) return false; + if (other is Version) return allows(other); + + if (other is VersionUnion) { + return other.constraints.any((constraint) => allowsAny(constraint)); + } + + if (other is VersionRange) { + // If neither range has a minimum, they'll overlap at some point. + // + // ... this ] + // ... other ] + if (min == null && other.min == null) return true; + + // If this range has a lower minimum than the other range, it overlaps as + // long as its maximum is higher than or the same as the other range's + // minimum. + // + // [ this ] [ this ] + // [ other ] [ other ] + if (min == null || (other.min != null && min < other.min)) { + if (max == null) return true; + if (max > other.min) return true; + if (max < other.min) return false; + assert(max == other.min); + return includeMax && other.includeMin; + } + + // If this range has a higher minimum than the other range, it overlaps as + // long as its minimum is lower than or the same as the other range's + // maximum. + // + // [ this ] [ this ] + // [ other ] [ other ] + if (other.max == null) return true; + if (min < other.max) return true; + if (min > other.max) return false; + assert(min == other.max); + return includeMin && other.includeMax; + } + + throw new ArgumentError('Unknown VersionConstraint type $other.'); + } + VersionConstraint intersect(VersionConstraint other) { if (other.isEmpty) return other; + if (other is VersionUnion) return other.intersect(this); // A range and a Version just yields the version if it's in the range. if (other is Version) { @@ -162,6 +236,66 @@ class VersionRange implements VersionConstraint { throw new ArgumentError('Unknown VersionConstraint type $other.'); } + VersionConstraint union(VersionConstraint other) { + if (other is Version) { + if (allows(other)) return this; + + if (other == min) { + return new VersionRange( + min: this.min, max: this.max, + includeMin: true, includeMax: this.includeMax); + } + + if (other == max) { + return new VersionRange( + min: this.min, max: this.max, + includeMin: this.includeMin, includeMax: true); + } + + return new VersionConstraint.unionOf([this, other]); + } + + if (other is VersionRange) { + // If the two ranges don't overlap, we won't be able to create a single + // VersionRange for both of them. + var edgesTouch = (max == other.min && (includeMax || other.includeMin)) || + (min == other.max && (includeMin || other.includeMax)); + if (!edgesTouch && !allowsAny(other)) { + return new VersionConstraint.unionOf([this, other]); + } + + var unionMin = min; + var unionIncludeMin = includeMin; + var unionMax = max; + var unionIncludeMax = includeMax; + + if (unionMin == null) { + // Do nothing. + } else if (other.min == null || other.min < min) { + unionMin = other.min; + unionIncludeMin = other.includeMin; + } else if (min == other.min && other.includeMin) { + // If the edges are the same but one is inclusive, make it inclusive. + unionIncludeMin = true; + } + + if (unionMax == null) { + // Do nothing. + } else if (other.max == null || other.max > max) { + unionMax = other.max; + unionIncludeMax = other.includeMax; + } else if (max == other.max && other.includeMax) { + // If the edges are the same but one is inclusive, make it inclusive. + unionIncludeMax = true; + } + + return new VersionRange(min: unionMin, max: unionMax, + includeMin: unionIncludeMin, includeMax: unionIncludeMax); + } + + return new VersionConstraint.unionOf([this, other]); + } + String toString() { var buffer = new StringBuffer(); diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart new file mode 100644 index 000000000..ee9f657ac --- /dev/null +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -0,0 +1,182 @@ +// Copyright (c) 2015, 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. + +library pub_semver.src.version_union; + +import 'package:collection/collection.dart'; + +import 'utils.dart'; +import 'version.dart'; +import 'version_constraint.dart'; +import 'version_range.dart'; + +/// A (package-private) version constraint representing a union of multiple +/// disjoint version constraints. +/// +/// An instance of this will only be created if the version can't be represented +/// as a non-compound value. +class VersionUnion implements VersionConstraint { + /// The constraints that compose this union. + /// + /// This list has two invariants: + /// + /// * Its contents are sorted from lowest to highest matched versions. + /// * Its contents are disjoint and non-adjacent. In other words, for any two + /// constraints next to each other in the list, there's some version between + /// those constraints that they don't match. + final List constraints; + + bool get isEmpty => false; + + bool get isAny => false; + + /// Returns the union of [constraints]. + /// + /// This ensures that an actual [VersionUnion] is only returned if necessary. + /// It also takes care of sorting and merging the constraints to ensure that + /// they're disjoint. + static VersionConstraint create(Iterable constraints) { + var flattened = constraints.expand((constraint) { + if (constraint.isEmpty) return []; + if (constraint is VersionUnion) return constraint.constraints; + return [constraint]; + }).toList(); + + if (flattened.isEmpty) return VersionConstraint.empty; + + if (flattened.any((constraint) => constraint.isAny)) { + return VersionConstraint.any; + } + + // Only allow Versions and VersionRanges here so we can more easily reason + // about everything in [flattened]. _EmptyVersions and VersionUnions are + // filtered out above. + for (var constraint in flattened) { + if (constraint is VersionRange) continue; + throw new ArgumentError('Unknown VersionConstraint type $constraint.'); + } + + (flattened as List).sort(compareMax); + + var merged = []; + for (var constraint in flattened) { + // Merge this constraint with the previous one, but only if they touch. + if (merged.isEmpty || + (!merged.last.allowsAny(constraint) && + !areAdjacent(merged.last, constraint))) { + merged.add(constraint); + } else { + merged[merged.length - 1] = merged.last.union(constraint); + } + } + + if (merged.length == 1) return merged.single; + return new VersionUnion._(merged); + } + + VersionUnion._(this.constraints); + + bool allows(Version version) => + constraints.any((constraint) => constraint.allows(version)); + + bool allowsAll(VersionConstraint other) { + var ourConstraints = constraints.iterator; + var theirConstraints = _constraintsFor(other).iterator; + + // Because both lists of constraints are ordered by minimum version, we can + // safely move through them linearly here. + ourConstraints.moveNext(); + theirConstraints.moveNext(); + while (ourConstraints.current != null && theirConstraints.current != null) { + if (ourConstraints.current.allowsAll(theirConstraints.current)) { + theirConstraints.moveNext(); + } else { + ourConstraints.moveNext(); + } + } + + // If our constraints have allowed all of their constraints, we'll have + // consumed all of them. + return theirConstraints.current == null; + } + + bool allowsAny(VersionConstraint other) { + var ourConstraints = constraints.iterator; + var theirConstraints = _constraintsFor(other).iterator; + + // Because both lists of constraints are ordered by minimum version, we can + // safely move through them linearly here. + ourConstraints.moveNext(); + theirConstraints.moveNext(); + while (ourConstraints.current != null && theirConstraints.current != null) { + if (ourConstraints.current.allowsAny(theirConstraints.current)) { + return true; + } + + // Move the constraint with the higher max value forward. This ensures + // that we keep both lists in sync as much as possible. + if (compareMax(ourConstraints.current, theirConstraints.current) < 0) { + ourConstraints.moveNext(); + } else { + theirConstraints.moveNext(); + } + } + + return false; + } + + VersionConstraint intersect(VersionConstraint other) { + var ourConstraints = constraints.iterator; + var theirConstraints = _constraintsFor(other).iterator; + + // Because both lists of constraints are ordered by minimum version, we can + // safely move through them linearly here. + var newConstraints = []; + ourConstraints.moveNext(); + theirConstraints.moveNext(); + while (ourConstraints.current != null && theirConstraints.current != null) { + var intersection = ourConstraints.current + .intersect(theirConstraints.current); + + if (!intersection.isEmpty) newConstraints.add(intersection); + + // Move the constraint with the higher max value forward. This ensures + // that we keep both lists in sync as much as possible, and that large + // constraints have a chance to match multiple small constraints that they + // contain. + if (compareMax(ourConstraints.current, theirConstraints.current) < 0) { + ourConstraints.moveNext(); + } else { + theirConstraints.moveNext(); + } + } + + if (newConstraints.isEmpty) return VersionConstraint.empty; + if (newConstraints.length == 1) return newConstraints.single; + + return new VersionUnion._(newConstraints); + } + + /// Returns [constraint] as a list of constraints. + /// + /// This is used to normalize constraints of various types. + List _constraintsFor(VersionConstraint constraint) { + if (constraint.isEmpty) return []; + if (constraint is VersionUnion) return constraint.constraints; + if (constraint is VersionRange) return [constraint]; + throw new ArgumentError('Unknown VersionConstraint type $constraint.'); + } + + VersionConstraint union(VersionConstraint other) => + new VersionConstraint.unionOf([this, other]); + + bool operator ==(other) { + if (other is! VersionUnion) return false; + return const ListEquality().equals(constraints, other.constraints); + } + + int get hashCode => const ListEquality().hash(constraints); + + String toString() => constraints.join(" or "); +} diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index bfb104cb5..26be2808b 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.1.1-dev +version: 1.2.0 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index e15539bec..ef35d8022 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -151,6 +151,167 @@ main() { }); }); + group('allowsAll()', () { + test('allows an empty constraint', () { + expect( + new VersionRange(min: v123, max: v250) + .allowsAll(VersionConstraint.empty), + isTrue); + }); + + test('allows allowed versions', () { + var range = new VersionRange(min: v123, max: v250, includeMax: true); + expect(range.allowsAll(v123), isFalse); + expect(range.allowsAll(v124), isTrue); + expect(range.allowsAll(v250), isTrue); + expect(range.allowsAll(v300), isFalse); + }); + + test('with no min', () { + var range = new VersionRange(max: v250); + expect(range.allowsAll(new VersionRange(min: v080, max: v140)), isTrue); + expect(range.allowsAll(new VersionRange(min: v080, max: v300)), isFalse); + expect(range.allowsAll(new VersionRange(max: v140)), isTrue); + expect(range.allowsAll(new VersionRange(max: v300)), isFalse); + expect(range.allowsAll(range), isTrue); + expect(range.allowsAll(VersionConstraint.any), isFalse); + }); + + test('with no max', () { + var range = new VersionRange(min: v010); + expect(range.allowsAll(new VersionRange(min: v080, max: v140)), isTrue); + expect(range.allowsAll(new VersionRange(min: v003, max: v140)), isFalse); + expect(range.allowsAll(new VersionRange(min: v080)), isTrue); + expect(range.allowsAll(new VersionRange(min: v003)), isFalse); + expect(range.allowsAll(range), isTrue); + expect(range.allowsAll(VersionConstraint.any), isFalse); + }); + + test('with a min and max', () { + var range = new VersionRange(min: v010, max: v250); + expect(range.allowsAll(new VersionRange(min: v080, max: v140)), isTrue); + expect(range.allowsAll(new VersionRange(min: v080, max: v300)), isFalse); + expect(range.allowsAll(new VersionRange(min: v003, max: v140)), isFalse); + expect(range.allowsAll(new VersionRange(min: v080)), isFalse); + expect(range.allowsAll(new VersionRange(max: v140)), isFalse); + expect(range.allowsAll(range), isTrue); + }); + + test("allows a bordering range that's not more inclusive", () { + var exclusive = new VersionRange(min: v010, max: v250); + var inclusive = new VersionRange( + min: v010, includeMin: true, max: v250, includeMax: true); + expect(inclusive.allowsAll(exclusive), isTrue); + expect(inclusive.allowsAll(inclusive), isTrue); + expect(exclusive.allowsAll(inclusive), isFalse); + expect(exclusive.allowsAll(exclusive), isTrue); + }); + + test('allows unions that are completely contained', () { + var range = new VersionRange(min: v114, max: v200); + expect( + range.allowsAll(new VersionRange(min: v123, max: v124).union(v140)), + isTrue); + expect( + range.allowsAll(new VersionRange(min: v010, max: v124).union(v140)), + isFalse); + expect( + range.allowsAll(new VersionRange(min: v123, max: v234).union(v140)), + isFalse); + }); + }); + + group('allowsAny()', () { + test('disallows an empty constraint', () { + expect( + new VersionRange(min: v123, max: v250) + .allowsAny(VersionConstraint.empty), + isFalse); + }); + + test('allows allowed versions', () { + var range = new VersionRange(min: v123, max: v250, includeMax: true); + expect(range.allowsAny(v123), isFalse); + expect(range.allowsAny(v124), isTrue); + expect(range.allowsAny(v250), isTrue); + expect(range.allowsAny(v300), isFalse); + }); + + test('with no min', () { + var range = new VersionRange(max: v200); + expect(range.allowsAny(new VersionRange(min: v140, max: v300)), isTrue); + expect(range.allowsAny(new VersionRange(min: v234, max: v300)), isFalse); + expect(range.allowsAny(new VersionRange(min: v140)), isTrue); + expect(range.allowsAny(new VersionRange(min: v234)), isFalse); + expect(range.allowsAny(range), isTrue); + }); + + test('with no max', () { + var range = new VersionRange(min: v072); + expect(range.allowsAny(new VersionRange(min: v003, max: v140)), isTrue); + expect(range.allowsAny(new VersionRange(min: v003, max: v010)), isFalse); + expect(range.allowsAny(new VersionRange(max: v080)), isTrue); + expect(range.allowsAny(new VersionRange(max: v003)), isFalse); + expect(range.allowsAny(range), isTrue); + }); + + test('with a min and max', () { + var range = new VersionRange(min: v072, max: v200); + expect(range.allowsAny(new VersionRange(min: v003, max: v140)), isTrue); + expect(range.allowsAny(new VersionRange(min: v140, max: v300)), isTrue); + expect(range.allowsAny(new VersionRange(min: v003, max: v010)), isFalse); + expect(range.allowsAny(new VersionRange(min: v234, max: v300)), isFalse); + expect(range.allowsAny(new VersionRange(max: v010)), isFalse); + expect(range.allowsAny(new VersionRange(min: v234)), isFalse); + expect(range.allowsAny(range), isTrue); + }); + + test('allows a bordering range when both are inclusive', () { + expect(new VersionRange(max: v250).allowsAny(new VersionRange(min: v250)), + isFalse); + + expect(new VersionRange(max: v250, includeMax: true) + .allowsAny(new VersionRange(min: v250)), + isFalse); + + expect(new VersionRange(max: v250) + .allowsAny(new VersionRange(min: v250, includeMin: true)), + isFalse); + + expect(new VersionRange(max: v250, includeMax: true) + .allowsAny(new VersionRange(min: v250, includeMin: true)), + isTrue); + + expect(new VersionRange(min: v250).allowsAny(new VersionRange(max: v250)), + isFalse); + + expect(new VersionRange(min: v250, includeMin: true) + .allowsAny(new VersionRange(max: v250)), + isFalse); + + expect(new VersionRange(min: v250) + .allowsAny(new VersionRange(max: v250, includeMax: true)), + isFalse); + + expect(new VersionRange(min: v250, includeMin: true) + .allowsAny(new VersionRange(max: v250, includeMax: true)), + isTrue); + }); + + test('allows unions that are partially contained', () { + var range = new VersionRange(min: v114, max: v200); + expect( + range.allowsAny(new VersionRange(min: v010, max: v080).union(v140)), + isTrue); + expect( + range.allowsAny(new VersionRange(min: v123, max: v234).union(v300)), + isTrue); + expect( + range.allowsAny(new VersionRange(min: v234, max: v300).union(v010)), + isFalse); + }); + }); + group('intersect()', () { test('two overlapping ranges', () { var a = new VersionRange(min: v123, max: v250); @@ -195,6 +356,81 @@ main() { }); }); + group('union()', () { + test("with a version returns the range if it contains the version", () { + var range = new VersionRange(min: v114, max: v124); + expect(range.union(v123), equals(range)); + }); + + test("with a version on the edge of the range, expands the range", () { + expect(new VersionRange(min: v114, max: v124).union(v124), + equals(new VersionRange(min: v114, max: v124, includeMax: true))); + expect(new VersionRange(min: v114, max: v124).union(v114), + equals(new VersionRange(min: v114, max: v124, includeMin: true))); + }); + + test("with a version allows both the range and the version if the range " + "doesn't contain the version", () { + var result = new VersionRange(min: v003, max: v114).union(v124); + expect(result, allows(v010)); + expect(result, doesNotAllow(v123)); + expect(result, allows(v124)); + }); + + test("returns a VersionUnion for a disjoint range", () { + var result = new VersionRange(min: v003, max: v114) + .union(new VersionRange(min: v130, max: v200)); + expect(result, allows(v080)); + expect(result, doesNotAllow(v123)); + expect(result, allows(v140)); + }); + + test("considers open ranges disjoint", () { + var result = new VersionRange(min: v003, max: v114) + .union(new VersionRange(min: v114, max: v200)); + expect(result, allows(v080)); + expect(result, doesNotAllow(v114)); + expect(result, allows(v140)); + + result = new VersionRange(min: v114, max: v200) + .union(new VersionRange(min: v003, max: v114)); + expect(result, allows(v080)); + expect(result, doesNotAllow(v114)); + expect(result, allows(v140)); + }); + + test("returns a merged range for an overlapping range", () { + var result = new VersionRange(min: v003, max: v114) + .union(new VersionRange(min: v080, max: v200)); + expect(result, equals(new VersionRange(min: v003, max: v200))); + }); + + test("considers closed ranges overlapping", () { + var result = new VersionRange(min: v003, max: v114, includeMax: true) + .union(new VersionRange(min: v114, max: v200)); + expect(result, equals(new VersionRange(min: v003, max: v200))); + + result = new VersionRange(min: v003, max: v114) + .union(new VersionRange(min: v114, max: v200, includeMin: true)); + expect(result, equals(new VersionRange(min: v003, max: v200))); + + result = new VersionRange(min: v114, max: v200) + .union(new VersionRange(min: v003, max: v114, includeMax: true)); + expect(result, equals(new VersionRange(min: v003, max: v200))); + + result = new VersionRange(min: v114, max: v200, includeMin: true) + .union(new VersionRange(min: v003, max: v114)); + expect(result, equals(new VersionRange(min: v003, max: v200))); + }); + + test("includes edges if either range does", () { + var result = new VersionRange(min: v003, max: v114, includeMin: true) + .union(new VersionRange(min: v003, max: v114, includeMax: true)); + expect(result, equals(new VersionRange( + min: v003, max: v114, includeMin: true, includeMax: true))); + }); + }); + test('isEmpty', () { expect(new VersionRange().isEmpty, isFalse); expect(new VersionRange(min: v123, max: v124).isEmpty, isFalse); diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 874500605..e3d1b49a9 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -138,6 +138,22 @@ main() { new Version.parse('1.2.3+build'))); }); + test('allowsAll()', () { + expect(v123.allowsAll(v123), isTrue); + expect(v123.allowsAll(v003), isFalse); + expect(v123.allowsAll(new VersionRange(min: v114, max: v124)), isFalse); + expect(v123.allowsAll(VersionConstraint.any), isFalse); + expect(v123.allowsAll(VersionConstraint.empty), isTrue); + }); + + test('allowsAny()', () { + expect(v123.allowsAny(v123), isTrue); + expect(v123.allowsAny(v003), isFalse); + expect(v123.allowsAny(new VersionRange(min: v114, max: v124)), isTrue); + expect(v123.allowsAny(VersionConstraint.any), isTrue); + expect(v123.allowsAny(VersionConstraint.empty), isFalse); + }); + test('intersect()', () { // Intersecting the same version returns the version. expect(v123.intersect(v123), equals(v123)); @@ -154,6 +170,40 @@ main() { isTrue); }); + group('union()', () { + test("with the same version returns the version", () { + expect(v123.union(v123), equals(v123)); + }); + + test("with a different version returns a version that matches both", () { + var result = v123.union(v080); + expect(result, allows(v123)); + expect(result, allows(v080)); + + // Nothing in between should match. + expect(result, doesNotAllow(v114)); + }); + + test("with a range returns the range if it contains the version", () { + var range = new VersionRange(min: v114, max: v124); + expect(v123.union(range), equals(range)); + }); + + test("with a range with the version on the edge, expands the range", () { + expect(v124.union(new VersionRange(min: v114, max: v124)), + equals(new VersionRange(min: v114, max: v124, includeMax: true))); + expect(v114.union(new VersionRange(min: v114, max: v124)), + equals(new VersionRange(min: v114, max: v124, includeMin: true))); + }); + + test("with a range allows both the range and the version if the range " + "doesn't contain the version", () { + var result = v123.union(new VersionRange(min: v003, max: v114)); + expect(result, allows(v123)); + expect(result, allows(v010)); + }); + }); + test('isEmpty', () { expect(v123.isEmpty, isFalse); }); diff --git a/pkgs/pub_semver/test/version_union_test.dart b/pkgs/pub_semver/test/version_union_test.dart new file mode 100644 index 000000000..f3518a06a --- /dev/null +++ b/pkgs/pub_semver/test/version_union_test.dart @@ -0,0 +1,352 @@ +// Copyright (c) 2015, 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:test/test.dart'; + +import 'package:pub_semver/pub_semver.dart'; + +import 'utils.dart'; + +main() { + group('factory', () { + test('ignores empty constraints', () { + expect(new VersionConstraint.unionOf([ + VersionConstraint.empty, + VersionConstraint.empty, + v123, + VersionConstraint.empty + ]), equals(v123)); + + expect(new VersionConstraint.unionOf([ + VersionConstraint.empty, + VersionConstraint.empty + ]), isEmpty); + }); + + test('returns an empty constraint for an empty list', () { + expect(new VersionConstraint.unionOf([]), isEmpty); + }); + + test('any constraints override everything', () { + expect(new VersionConstraint.unionOf([ + v123, + VersionConstraint.any, + v200, + new VersionRange(min: v234, max: v250) + ]), equals(VersionConstraint.any)); + }); + + test('flattens other unions', () { + expect(new VersionConstraint.unionOf([ + v072, + new VersionConstraint.unionOf([v123, v124]), + v250 + ]), equals(new VersionConstraint.unionOf([v072, v123, v124, v250]))); + }); + + test('returns a single merged range as-is', () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v080, max: v140), + new VersionRange(min: v123, max: v200) + ]), equals(new VersionRange(min: v080, max: v200))); + }); + }); + + group('equality', () { + test("doesn't depend on original order", () { + expect(new VersionConstraint.unionOf([ + v250, + new VersionRange(min: v201, max: v234), + v124, + v072, + new VersionRange(min: v080, max: v114), + v123 + ]), equals(new VersionConstraint.unionOf([ + v072, + new VersionRange(min: v080, max: v114), + v123, + v124, + new VersionRange(min: v201, max: v234), + v250 + ]))); + }); + + test("merges overlapping ranges", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v010, max: v080), + new VersionRange(min: v114, max: v124), + new VersionRange(min: v123, max: v130) + ]), equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v114, max: v130) + ]))); + }); + + test("merges adjacent ranges", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072, includeMax: true), + new VersionRange(min: v072, max: v080), + new VersionRange(min: v114, max: v124), + new VersionRange(min: v124, max: v130, includeMin: true) + ]), equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v114, max: v130) + ]))); + }); + + test("doesn't merge not-quite-adjacent ranges", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v072, max: v080) + ]), equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v072, max: v080) + ]))); + }); + + test("merges version numbers into ranges", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + v010, + new VersionRange(min: v114, max: v124), + v123 + ]), equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v114, max: v124) + ]))); + }); + + test("merges adjacent version numbers into ranges", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + v072, + v114, + new VersionRange(min: v114, max: v124) + ]), equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072, includeMax: true), + new VersionRange(min: v114, max: v124, includeMin: true) + ]))); + }); + }); + + test('isEmpty returns false', () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130), + ]), isNot(isEmpty)); + }); + + test('isAny returns false', () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130), + ]).isAny, isFalse); + }); + + test('allows() allows anything the components allow', () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130), + v200 + ]); + + expect(union, allows(v010)); + expect(union, doesNotAllow(v080)); + expect(union, allows(v124)); + expect(union, doesNotAllow(v140)); + expect(union, allows(v200)); + }); + + group('allowsAll()', () { + test('for a version, returns true if any component allows the version', () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130), + v200 + ]); + + expect(union.allowsAll(v010), isTrue); + expect(union.allowsAll(v080), isFalse); + expect(union.allowsAll(v124), isTrue); + expect(union.allowsAll(v140), isFalse); + expect(union.allowsAll(v200), isTrue); + }); + + test('for a version range, returns true if any component allows the whole ' + 'range', () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130) + ]); + + expect(union.allowsAll(new VersionRange(min: v003, max: v080)), isTrue); + expect(union.allowsAll(new VersionRange(min: v010, max: v072)), isTrue); + expect(union.allowsAll(new VersionRange(min: v010, max: v124)), isFalse); + }); + + group('for a union,', () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130) + ]); + + test('returns true if every constraint matches a different constraint', + () { + expect(union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v124, max: v130) + ])), isTrue); + }); + + test('returns true if every constraint matches the same constraint', () { + expect(union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v010), + new VersionRange(min: v072, max: v080) + ])), isTrue); + }); + + test("returns false if there's an unmatched constraint", () { + expect(union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v124, max: v130), + new VersionRange(min: v140, max: v200) + ])), isFalse); + }); + + test("returns false if a constraint isn't fully matched", () { + expect(union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v114), + new VersionRange(min: v124, max: v130) + ])), isFalse); + }); + }); + }); + + group('allowsAny()', () { + test('for a version, returns true if any component allows the version', () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130), + v200 + ]); + + expect(union.allowsAny(v010), isTrue); + expect(union.allowsAny(v080), isFalse); + expect(union.allowsAny(v124), isTrue); + expect(union.allowsAny(v140), isFalse); + expect(union.allowsAny(v200), isTrue); + }); + + test('for a version range, returns true if any component allows part of ' + 'the range', () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + v123 + ]); + + expect(union.allowsAny(new VersionRange(min: v010, max: v114)), isTrue); + expect(union.allowsAny(new VersionRange(min: v114, max: v124)), isTrue); + expect(union.allowsAny(new VersionRange(min: v124, max: v130)), isFalse); + }); + + group('for a union,', () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v130) + ]); + + test('returns true if any constraint matches', () { + expect(union.allowsAny(new VersionConstraint.unionOf([ + v072, + new VersionRange(min: v200, max: v300) + ])), isTrue); + + expect(union.allowsAny(new VersionConstraint.unionOf([ + v003, + new VersionRange(min: v124, max: v300) + ])), isTrue); + }); + + test("returns false if no constraint matches", () { + expect(union.allowsAny(new VersionConstraint.unionOf([ + v003, + new VersionRange(min: v130, max: v140), + new VersionRange(min: v140, max: v200) + ])), isFalse); + }); + }); + }); + + group("intersect()", () { + test("with an overlapping version, returns that version", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(v072), equals(v072)); + }); + + test("with a non-overlapping version, returns an empty constraint", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(v300), isEmpty); + }); + + test("with an overlapping range, returns that range", () { + var range = new VersionRange(min: v072, max: v080); + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(range), equals(range)); + }); + + test("with a non-overlapping range, returns an empty constraint", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(new VersionRange(min: v080, max: v123)), isEmpty); + }); + + test("with a parially-overlapping range, returns the overlapping parts", + () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(new VersionRange(min: v072, max: v130)), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v130) + ]))); + }); + + group("for a union,", () { + var union = new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130) + ]); + + test("returns the overlapping parts", () { + expect(union.intersect(new VersionConstraint.unionOf([ + v010, + new VersionRange(min: v072, max: v124), + new VersionRange(min: v124, max: v130) + ])), equals(new VersionConstraint.unionOf([ + v010, + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v124), + new VersionRange(min: v124, max: v130) + ]))); + }); + + test("drops parts that don't match", () { + expect(union.intersect(new VersionConstraint.unionOf([ + v003, + new VersionRange(min: v072, max: v080), + new VersionRange(min: v080, max: v123) + ])), equals(new VersionRange(min: v072, max: v080))); + }); + }); + }); +} \ No newline at end of file From 45c6965b7356d39ef46a473dea06db7b41b542a0 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 6 May 2015 13:24:21 -0700 Subject: [PATCH 080/657] Mention that Version implements VersionConstraint in the changelog. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1123313003 --- pkgs/pub_semver/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 32538cc9c..06f7caa40 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -10,6 +10,8 @@ * Add a `VersionConstraint.allowsAny()` method, which returns whether one constraint overlaps another. +* `Version` now implements `VersionRange`. + # 1.1.0 * Add support for the `^` operator for compatible versions according to pub's From fa368609ce721202319196d28e3b8c3d3b6daa3a Mon Sep 17 00:00:00 2001 From: pquitslund Date: Wed, 13 May 2015 13:38:29 -0700 Subject: [PATCH 081/657] Initial template commit. --- pkgs/package_config/.gitignore | 7 +++ pkgs/package_config/.travis.yml | 3 ++ pkgs/package_config/AUTHORS | 6 +++ pkgs/package_config/CHANGELOG.md | 5 ++ pkgs/package_config/CONTRIBUTING.md | 33 ++++++++++++ pkgs/package_config/LICENSE | 26 +++++++++ pkgs/package_config/README.md | 11 ++++ pkgs/package_config/pubspec.lock | 83 +++++++++++++++++++++++++++++ pkgs/package_config/pubspec.yaml | 11 ++++ pkgs/package_config/test/all.dart | 9 ++++ pkgs/package_config/tool/travis.sh | 16 ++++++ 11 files changed, 210 insertions(+) create mode 100644 pkgs/package_config/.gitignore create mode 100644 pkgs/package_config/.travis.yml create mode 100644 pkgs/package_config/AUTHORS create mode 100644 pkgs/package_config/CHANGELOG.md create mode 100644 pkgs/package_config/CONTRIBUTING.md create mode 100644 pkgs/package_config/LICENSE create mode 100644 pkgs/package_config/README.md create mode 100644 pkgs/package_config/pubspec.lock create mode 100644 pkgs/package_config/pubspec.yaml create mode 100644 pkgs/package_config/test/all.dart create mode 100755 pkgs/package_config/tool/travis.sh diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore new file mode 100644 index 000000000..f48e3c9a8 --- /dev/null +++ b/pkgs/package_config/.gitignore @@ -0,0 +1,7 @@ +.idea +.pub +packages +build +.project +.settings +pubspec.lock \ No newline at end of file diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml new file mode 100644 index 000000000..b1279b7e4 --- /dev/null +++ b/pkgs/package_config/.travis.yml @@ -0,0 +1,3 @@ +language: dart +script: ./tool/travis.sh +sudo: false diff --git a/pkgs/package_config/AUTHORS b/pkgs/package_config/AUTHORS new file mode 100644 index 000000000..e8063a8cd --- /dev/null +++ b/pkgs/package_config/AUTHORS @@ -0,0 +1,6 @@ +# Below is a list of people and organizations that have contributed +# to the project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md new file mode 100644 index 000000000..2a2d63cf8 --- /dev/null +++ b/pkgs/package_config/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 0.0.1 + +- Initial version diff --git a/pkgs/package_config/CONTRIBUTING.md b/pkgs/package_config/CONTRIBUTING.md new file mode 100644 index 000000000..6f5e0ea67 --- /dev/null +++ b/pkgs/package_config/CONTRIBUTING.md @@ -0,0 +1,33 @@ +Want to contribute? Great! First, read this page (including the small print at +the end). + +### Before you contribute +Before we can use your code, you must sign the +[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) +(CLA), which you can do online. The CLA is necessary mainly because you own the +copyright to your changes, even after your contribution becomes part of our +codebase, so we need your permission to use and distribute your code. We also +need to be sure of various other things—for instance that you'll tell us if you +know that your code infringes on other people's patents. You don't have to sign +the CLA until after you've submitted your code for review and a member has +approved it, but you must do it before we can put your code into our codebase. + +Before you start working on a larger contribution, you should get in touch with +us first through the issue tracker with your idea so that we can help out and +possibly guide you. Coordinating up front makes it much easier to avoid +frustration later on. + +### Code reviews +All submissions, including submissions by project members, require review. + +### File headers +All files in the project must start with the following header. + + // Copyright (c) 2015, 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. + +### The small print +Contributions made by corporations are covered by a different agreement than the +one above, the +[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate). diff --git a/pkgs/package_config/LICENSE b/pkgs/package_config/LICENSE new file mode 100644 index 000000000..de31e1a0a --- /dev/null +++ b/pkgs/package_config/LICENSE @@ -0,0 +1,26 @@ +Copyright 2015, the Dart project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md new file mode 100644 index 000000000..17d199b4a --- /dev/null +++ b/pkgs/package_config/README.md @@ -0,0 +1,11 @@ +# package_config + +Support for working with **Package Resolution Configuration** files as described +in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), +under review [here] (https://github.com/dart-lang/dart_enhancement_proposals/issues/5). + +## Features and bugs + +Please file feature requests and bugs at the [issue tracker][tracker]. + +[tracker]: https://github.com/dart-lang/package_config/issues diff --git a/pkgs/package_config/pubspec.lock b/pkgs/package_config/pubspec.lock new file mode 100644 index 000000000..197d32ed6 --- /dev/null +++ b/pkgs/package_config/pubspec.lock @@ -0,0 +1,83 @@ +# Generated by pub +# See http://pub.dartlang.org/doc/glossary.html#lockfile +packages: + analyzer: + description: analyzer + source: hosted + version: "0.25.0+1" + args: + description: args + source: hosted + version: "0.13.0" + barback: + description: barback + source: hosted + version: "0.15.2+4" + collection: + description: collection + source: hosted + version: "1.1.1" + crypto: + description: crypto + source: hosted + version: "0.9.0" + http_parser: + description: http_parser + source: hosted + version: "0.0.2+6" + matcher: + description: matcher + source: hosted + version: "0.12.0" + mime: + description: mime + source: hosted + version: "0.9.3" + path: + description: path + source: hosted + version: "1.3.5" + pool: + description: pool + source: hosted + version: "1.0.1" + pub_semver: + description: pub_semver + source: hosted + version: "1.2.0" + shelf: + description: shelf + source: hosted + version: "0.6.1+2" + shelf_static: + description: shelf_static + source: hosted + version: "0.2.2" + shelf_web_socket: + description: shelf_web_socket + source: hosted + version: "0.0.1+2" + source_span: + description: source_span + source: hosted + version: "1.1.2" + stack_trace: + description: stack_trace + source: hosted + version: "1.3.2" + string_scanner: + description: string_scanner + source: hosted + version: "0.1.3+1" + test: + description: test + source: hosted + version: "0.12.1" + watcher: + description: watcher + source: hosted + version: "0.9.5" + yaml: + description: yaml + source: hosted + version: "2.1.2" diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml new file mode 100644 index 000000000..b0f2d8fec --- /dev/null +++ b/pkgs/package_config/pubspec.yaml @@ -0,0 +1,11 @@ +name: package_config +version: 0.0.1 +description: Support for working with Package Resolution config files. +author: Dart Team +homepage: https://github.com/dart-lang/package_config + +environment: + sdk: '>=1.0.0 <2.0.0' + +dev_dependencies: + test: '>=0.12.0 <0.13.0' diff --git a/pkgs/package_config/test/all.dart b/pkgs/package_config/test/all.dart new file mode 100644 index 000000000..76284af2b --- /dev/null +++ b/pkgs/package_config/test/all.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, 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:test/test.dart'; + +main() { + // TODO: add tests! +} diff --git a/pkgs/package_config/tool/travis.sh b/pkgs/package_config/tool/travis.sh new file mode 100755 index 000000000..8fdabfdf6 --- /dev/null +++ b/pkgs/package_config/tool/travis.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Copyright (c) 2015, 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. + +# Fast fail the script on failures. +set -e + +# Verify that the libraries are error free. +dartanalyzer --fatal-warnings \ + test/all.dart + +# Run the tests. +dart test/all.dart + From 0ede819f2cd3d377b77cb6c0671398a474cc4a9e Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 13 May 2015 14:05:08 -0700 Subject: [PATCH 082/657] Update README.md Added build badge. --- pkgs/package_config/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 17d199b4a..140c3c4f9 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -4,6 +4,9 @@ Support for working with **Package Resolution Configuration** files as described in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), under review [here] (https://github.com/dart-lang/dart_enhancement_proposals/issues/5). +[![Build Status](https://travis-ci.org/dart-lang/package_config.svg)](https://travis-ci.org/dart-lang/linter) + + ## Features and bugs Please file feature requests and bugs at the [issue tracker][tracker]. From 8aac6f18fd215ae16a164536bf74c50fecf63f81 Mon Sep 17 00:00:00 2001 From: pquitslund Date: Wed, 13 May 2015 14:25:23 -0700 Subject: [PATCH 083/657] Initial parser port. --- pkgs/package_config/lib/packagemap.dart | 227 ++++++++++++++++++ pkgs/package_config/test/all.dart | 4 +- pkgs/package_config/test/test_packagemap.dart | 149 ++++++++++++ pkgs/package_config/tool/travis.sh | 1 + 4 files changed, 379 insertions(+), 2 deletions(-) create mode 100644 pkgs/package_config/lib/packagemap.dart create mode 100644 pkgs/package_config/test/test_packagemap.dart diff --git a/pkgs/package_config/lib/packagemap.dart b/pkgs/package_config/lib/packagemap.dart new file mode 100644 index 000000000..046aa5221 --- /dev/null +++ b/pkgs/package_config/lib/packagemap.dart @@ -0,0 +1,227 @@ +// Copyright (c) 2015, 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. + +library package_config.packagemap; + +class Packages { + static const int _EQUALS = 0x3d; + static const int _CR = 0x0d; + static const int _NL = 0x0a; + static const int _NUMBER_SIGN = 0x23; + + final Map packageMapping; + + Packages(this.packageMapping); + + /// Resolves a URI to a non-package URI. + /// + /// If [uri] is a `package:` URI, the location is resolved wrt. the + /// [packageMapping]. + /// Otherwise the original URI is returned. + Uri resolve(Uri uri) { + if (uri.scheme.toLowerCase() != "package") { + return uri; + } + if (uri.hasAuthority) { + throw new ArgumentError.value(uri, "uri", "Must not have authority"); + } + if (uri.path.startsWith("/")) { + throw new ArgumentError.value(uri, "uri", + "Path must not start with '/'."); + } + // Normalizes the path by removing '.' and '..' segments. + uri = uri.normalizePath(); + String path = uri.path; + var slashIndex = path.indexOf('/'); + String packageName; + String rest; + if (slashIndex < 0) { + packageName = path; + rest = ""; + } else { + packageName = path.substring(0, slashIndex); + rest = path.substring(slashIndex + 1); + } + Uri packageLocation = packageMapping[packageName]; + if (packageLocation == null) { + throw new ArgumentError.value(uri, "uri", + "Unknown package name: $packageName"); + } + return packageLocation.resolveUri(new Uri(path: rest)); + } + + /// Parses a `packages.cfg` file into a `Packages` object. + /// + /// The [baseLocation] is used as a base URI to resolve all relative + /// URI references against. + /// + /// The `Packages` object allows resolving package: URIs and writing + /// the mapping back to a file or string. + /// The [packageMapping] will contain a simple mapping from package name + /// to package location. + static Packages parse(String source, Uri baseLocation) { + int index = 0; + Map result = {}; + while (index < source.length) { + bool isComment = false; + int start = index; + int eqIndex = -1; + int end = source.length; + int char = source.codeUnitAt(index++); + if (char == _CR || char == _NL) { + continue; + } + if (char == _EQUALS) { + throw new FormatException("Missing package name", source, index - 1); + } + isComment = char == _NUMBER_SIGN; + while (index < source.length) { + char = source.codeUnitAt(index++); + if (char == _EQUALS && eqIndex < 0) { + eqIndex = index - 1; + } else if (char == _NL || char == _CR) { + end = index - 1; + break; + } + } + if (isComment) continue; + if (eqIndex < 0) { + throw new FormatException("No '=' on line", source, index - 1); + } + _checkIdentifier(source, start, eqIndex); + var packageName = source.substring(start, eqIndex); + + var packageLocation = Uri.parse(source, eqIndex + 1, end); + if (!packageLocation.path.endsWith('/')) { + packageLocation = packageLocation.replace( + path: packageLocation.path + "/"); + } + packageLocation = baseLocation.resolveUri(packageLocation); + if (result.containsKey(packageName)) { + throw new FormatException("Same package name occured twice.", + source, start); + } + result[packageName] = packageLocation; + } + return new Packages(result); + } + + /** + * Writes the mapping to a [StringSink]. + * + * If [comment] is provided, the output will contain this comment + * with `#` in front of each line. + * + * If [baseUri] is provided, package locations will be made relative + * to the base URI, if possible, before writing. + */ + void write(StringSink output, {Uri baseUri, String comment}) { + if (baseUri != null && !baseUri.isAbsolute) { + throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute"); + } + + if (comment != null) { + for (var commentLine in comment.split('\n')) { + output.write('#'); + output.writeln(commentLine); + } + } else { + output.write("# generated by package:packagecfg at "); + output.write(new DateTime.now()); + output.writeln(); + } + + packageMapping.forEach((String packageName, Uri uri) { + // Validate packageName. + _checkIdentifier(packageName, 0, packageName.length); + output.write(packageName); + + output.write('='); + + // If baseUri provided, make uri relative. + if (baseUri != null) { + uri = _relativizeUri(uri, baseUri); + } + output.write(uri); + if (!uri.path.endsWith('/')) { + output.write('/'); + } + output.writeln(); + }); + } + + String toString() { + StringBuffer buffer = new StringBuffer(); + write(buffer); + return buffer.toString(); + } + + static Uri relativize(Uri uri, + Uri baseUri) { + if (uri.hasQuery || uri.hasFragment) { + uri = new Uri(scheme: uri.scheme, + userInfo: uri.hasAuthority ? uri.userInfo : null, + host: uri.hasAuthority ? uri.host : null, + port: uri.hasAuthority ? uri.port : null, + path: uri.path); + } + if (!baseUri.isAbsolute) { + throw new ArgumentError("Base uri '$baseUri' must be absolute."); + } + // Already relative. + if (!uri.isAbsolute) return uri; + + if (baseUri.scheme.toLowerCase() != uri.scheme.toLowerCase()) { + return uri; + } + // If authority differs, we could remove the scheme, but it's not worth it. + if (uri.hasAuthority != baseUri.hasAuthority) return uri; + if (uri.hasAuthority) { + if (uri.userInfo != baseUri.userInfo || + uri.host.toLowerCase() != baseUri.host.toLowerCase() || + uri.port != baseUri.port) { + return uri; + } + } + + List base = baseUri.pathSegments.toList(); + base = base.normalizePath(); + if (base.isNotEmpty) { + base = new List.from(base)..removeLast(); + } + List target = uri.pathSegments.toList(); + target = target.normalizePath(); + int index = 0; + while (index < base.length && index < target.length) { + if (base[index] != target[index]) { + break; + } + index++; + } + if (index == base.length) { + return new Uri(path: target.skip(index).join('/')); + } else if (index > 0) { + return new Uri( + path: '../' * (base.length - index) + target.skip(index).join('/')); + } else { + return uri; + } + } + + static void _checkIdentifier(String string, int start, int end) { + const int a = 0x61; + const int z = 0x7a; + const int _ = 0x5f; + const int $ = 0x24; + if (start == end) return false; + for (int i = start; i < end; i++) { + var char = string.codeUnitAt(i); + if (char == _ || char == $) continue; + if ((char ^ 0x30) <= 9 && i > 0) continue; + char |= 0x20; // Lower-case letters. + if (char >= a && char <= z) continue; + throw new FormatException("Not an identifier", string, i); + } + } +} \ No newline at end of file diff --git a/pkgs/package_config/test/all.dart b/pkgs/package_config/test/all.dart index 76284af2b..795289cdf 100644 --- a/pkgs/package_config/test/all.dart +++ b/pkgs/package_config/test/all.dart @@ -2,8 +2,8 @@ // 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:test/test.dart'; +import 'test_packagemap.dart' as packagemap; main() { - // TODO: add tests! + packagemap.main(); } diff --git a/pkgs/package_config/test/test_packagemap.dart b/pkgs/package_config/test/test_packagemap.dart new file mode 100644 index 000000000..bce20d4b8 --- /dev/null +++ b/pkgs/package_config/test/test_packagemap.dart @@ -0,0 +1,149 @@ +// Copyright (c) 2015, 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. + +library test_all; + +import "package:package_config/packagemap.dart"; +import "package:test/test.dart"; + +main() { + var base = Uri.parse("file:///one/two/three/packages.map"); + test("empty", () { + var packages = Packages.parse(emptySample, base); + expect(packages.packageMapping, isEmpty); + }); + test("comment only", () { + var packages = Packages.parse(commentOnlySample, base); + expect(packages.packageMapping, isEmpty); + }); + test("empty lines only", () { + var packages = Packages.parse(emptyLinesSample, base); + expect(packages.packageMapping, isEmpty); + }); + + test("empty lines only", () { + var packages = Packages.parse(emptyLinesSample, base); + expect(packages.packageMapping, isEmpty); + }); + + test("single", () { + var packages = Packages.parse(singleRelativeSample, base); + expect(packages.packageMapping.keys.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("single no slash", () { + var packages = Packages.parse(singleRelativeSampleNoSlash, base); + expect(packages.packageMapping.keys.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("single no newline", () { + var packages = Packages.parse(singleRelativeSampleNoNewline, base); + expect(packages.packageMapping.keys.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("single absolute", () { + var packages = Packages.parse(singleAbsoluteSample, base); + expect(packages.packageMapping.keys.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(Uri.parse("http://example.com/some/where/bar/baz.dart"))); + }); + + test("multiple", () { + var packages = Packages.parse(multiRelativeSample, base); + expect( + packages.packageMapping.keys.toList()..sort(), equals(["bar", "foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + expect(packages.resolve(Uri.parse("package:bar/foo/baz.dart")), + equals(base.resolve("../test2/").resolve("foo/baz.dart"))); + }); + + test("dot-dot 1", () { + var packages = Packages.parse(singleRelativeSample, base); + expect(packages.packageMapping.keys.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/qux/../bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("dot-dot 2", () { + var packages = Packages.parse(singleRelativeSample, base); + expect(packages.packageMapping.keys.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:qux/../foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("all valid chars", () { + var packages = Packages.parse(allValidCharsSample, base); + expect(packages.packageMapping.keys.toList(), equals([allValidChars])); + expect(packages.resolve(Uri.parse("package:$allValidChars/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("no escapes", () { + expect(() => Packages.parse("x%41x=x", base), throws); + }); + + test("not identifiers", () { + expect(() => Packages.parse("1x=x", base), throws); + expect(() => Packages.parse(" x=x", base), throws); + expect(() => Packages.parse("\\x41x=x", base), throws); + expect(() => Packages.parse("x@x=x", base), throws); + expect(() => Packages.parse("x[x=x", base), throws); + expect(() => Packages.parse("x`x=x", base), throws); + expect(() => Packages.parse("x{x=x", base), throws); + expect(() => Packages.parse("x/x=x", base), throws); + expect(() => Packages.parse("x:x=x", base), throws); + }); + + test("same name twice", () { + expect(() => Packages.parse(singleRelativeSample * 2, base), throws); + }); + + for (String invalidSample in invalid) { + test("invalid '$invalidSample'", () { + var result; + try { + result = Packages.parse(invalidSample, base); + } on FormatException { + // expected + return; + } + fail("Resolved to $result"); + }); + } +} + +// Valid samples. +var emptySample = ""; +var commentOnlySample = "# comment only\n"; +var emptyLinesSample = "\n\n\r\n"; +var singleRelativeSample = "foo=../test/\n"; +var singleRelativeSampleNoSlash = "foo=../test\n"; +var singleRelativeSampleNoNewline = "foo=../test/"; +var singleAbsoluteSample = "foo=http://example.com/some/where/\n"; +var multiRelativeSample = "foo=../test/\nbar=../test2/\n"; +// All valid path segment characters in an URI. +var allValidChars = + r"$0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; +var allValidCharsSample = "${allValidChars.replaceAll('=', '%3D')}=../test/\n"; +var allUnreservedChars = + "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; + +// Invalid samples. +var invalid = [ + "foobar:baz.dart", // no equals + ".=../test/", // dot segment + "..=../test/", // dot-dot segment + "foo/bar=../test/", // + "/foo=../test/", // var multiSegmentSample + "?=../test/", // invalid characters in path segment. + "[=../test/", // invalid characters in path segment. + "x#=../test/", // invalid characters in path segment. +]; diff --git a/pkgs/package_config/tool/travis.sh b/pkgs/package_config/tool/travis.sh index 8fdabfdf6..82423816b 100755 --- a/pkgs/package_config/tool/travis.sh +++ b/pkgs/package_config/tool/travis.sh @@ -9,6 +9,7 @@ set -e # Verify that the libraries are error free. dartanalyzer --fatal-warnings \ + lib/packagemap.dart \ test/all.dart # Run the tests. From a1a4f439bd93755fa76df9eb558ba3a37099b3d8 Mon Sep 17 00:00:00 2001 From: pquitslund Date: Wed, 13 May 2015 14:44:16 -0700 Subject: [PATCH 084/657] Parser fixes. --- pkgs/package_config/lib/packagemap.dart | 47 +++++++++++++------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/pkgs/package_config/lib/packagemap.dart b/pkgs/package_config/lib/packagemap.dart index 046aa5221..25f27b9a2 100644 --- a/pkgs/package_config/lib/packagemap.dart +++ b/pkgs/package_config/lib/packagemap.dart @@ -27,8 +27,8 @@ class Packages { throw new ArgumentError.value(uri, "uri", "Must not have authority"); } if (uri.path.startsWith("/")) { - throw new ArgumentError.value(uri, "uri", - "Path must not start with '/'."); + throw new ArgumentError.value( + uri, "uri", "Path must not start with '/'."); } // Normalizes the path by removing '.' and '..' segments. uri = uri.normalizePath(); @@ -45,8 +45,8 @@ class Packages { } Uri packageLocation = packageMapping[packageName]; if (packageLocation == null) { - throw new ArgumentError.value(uri, "uri", - "Unknown package name: $packageName"); + throw new ArgumentError.value( + uri, "uri", "Unknown package name: $packageName"); } return packageLocation.resolveUri(new Uri(path: rest)); } @@ -94,13 +94,13 @@ class Packages { var packageLocation = Uri.parse(source, eqIndex + 1, end); if (!packageLocation.path.endsWith('/')) { - packageLocation = packageLocation.replace( - path: packageLocation.path + "/"); + packageLocation = + packageLocation.replace(path: packageLocation.path + "/"); } packageLocation = baseLocation.resolveUri(packageLocation); if (result.containsKey(packageName)) { - throw new FormatException("Same package name occured twice.", - source, start); + throw new FormatException( + "Same package name occured twice.", source, start); } result[packageName] = packageLocation; } @@ -141,7 +141,7 @@ class Packages { // If baseUri provided, make uri relative. if (baseUri != null) { - uri = _relativizeUri(uri, baseUri); + uri = relativize(uri, baseUri); } output.write(uri); if (!uri.path.endsWith('/')) { @@ -157,14 +157,14 @@ class Packages { return buffer.toString(); } - static Uri relativize(Uri uri, - Uri baseUri) { + static Uri relativize(Uri uri, Uri baseUri) { if (uri.hasQuery || uri.hasFragment) { - uri = new Uri(scheme: uri.scheme, - userInfo: uri.hasAuthority ? uri.userInfo : null, - host: uri.hasAuthority ? uri.host : null, - port: uri.hasAuthority ? uri.port : null, - path: uri.path); + uri = new Uri( + scheme: uri.scheme, + userInfo: uri.hasAuthority ? uri.userInfo : null, + host: uri.hasAuthority ? uri.host : null, + port: uri.hasAuthority ? uri.port : null, + path: uri.path); } if (!baseUri.isAbsolute) { throw new ArgumentError("Base uri '$baseUri' must be absolute."); @@ -179,19 +179,19 @@ class Packages { if (uri.hasAuthority != baseUri.hasAuthority) return uri; if (uri.hasAuthority) { if (uri.userInfo != baseUri.userInfo || - uri.host.toLowerCase() != baseUri.host.toLowerCase() || - uri.port != baseUri.port) { + uri.host.toLowerCase() != baseUri.host.toLowerCase() || + uri.port != baseUri.port) { return uri; } } + baseUri = baseUri.normalizePath(); List base = baseUri.pathSegments.toList(); - base = base.normalizePath(); if (base.isNotEmpty) { base = new List.from(base)..removeLast(); } + uri = uri.normalizePath(); List target = uri.pathSegments.toList(); - target = target.normalizePath(); int index = 0; while (index < base.length && index < target.length) { if (base[index] != target[index]) { @@ -209,7 +209,7 @@ class Packages { } } - static void _checkIdentifier(String string, int start, int end) { + static bool _checkIdentifier(String string, int start, int end) { const int a = 0x61; const int z = 0x7a; const int _ = 0x5f; @@ -219,9 +219,10 @@ class Packages { var char = string.codeUnitAt(i); if (char == _ || char == $) continue; if ((char ^ 0x30) <= 9 && i > 0) continue; - char |= 0x20; // Lower-case letters. + char |= 0x20; // Lower-case letters. if (char >= a && char <= z) continue; throw new FormatException("Not an identifier", string, i); } + return true; } -} \ No newline at end of file +} From 8dc4c7c292f4a81a312427700b0f429ae5f82ed8 Mon Sep 17 00:00:00 2001 From: pquitslund Date: Wed, 13 May 2015 14:57:34 -0700 Subject: [PATCH 085/657] Backed out path normalization. --- pkgs/package_config/lib/packagemap.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkgs/package_config/lib/packagemap.dart b/pkgs/package_config/lib/packagemap.dart index 25f27b9a2..e05c14d15 100644 --- a/pkgs/package_config/lib/packagemap.dart +++ b/pkgs/package_config/lib/packagemap.dart @@ -30,8 +30,9 @@ class Packages { throw new ArgumentError.value( uri, "uri", "Path must not start with '/'."); } + //TODO: re-enable // Normalizes the path by removing '.' and '..' segments. - uri = uri.normalizePath(); + // uri = uri.normalizePath(); String path = uri.path; var slashIndex = path.indexOf('/'); String packageName; @@ -185,12 +186,14 @@ class Packages { } } - baseUri = baseUri.normalizePath(); + //TODO: normalize path + // baseUri = baseUri.normalizePath(); List base = baseUri.pathSegments.toList(); if (base.isNotEmpty) { base = new List.from(base)..removeLast(); } - uri = uri.normalizePath(); + //TODO: normalize path + //uri = uri.normalizePath(); List target = uri.pathSegments.toList(); int index = 0; while (index < base.length && index < target.length) { From 4223760f55245869171c4b469ed1f1ce147b8c9f Mon Sep 17 00:00:00 2001 From: pquitslund Date: Wed, 13 May 2015 14:59:02 -0700 Subject: [PATCH 086/657] Backed out path normalization. --- pkgs/package_config/test/test_packagemap.dart | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pkgs/package_config/test/test_packagemap.dart b/pkgs/package_config/test/test_packagemap.dart index bce20d4b8..2c03dba8b 100644 --- a/pkgs/package_config/test/test_packagemap.dart +++ b/pkgs/package_config/test/test_packagemap.dart @@ -72,12 +72,14 @@ main() { equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); - test("dot-dot 2", () { - var packages = Packages.parse(singleRelativeSample, base); - expect(packages.packageMapping.keys.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:qux/../foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); + +// TODO: re-enable when path normalization is in +// test("dot-dot 2", () { +// var packages = Packages.parse(singleRelativeSample, base); +// expect(packages.packageMapping.keys.toList(), equals(["foo"])); +// expect(packages.resolve(Uri.parse("package:qux/../foo/bar/baz.dart")), +// equals(base.resolve("../test/").resolve("bar/baz.dart"))); +// }); test("all valid chars", () { var packages = Packages.parse(allValidCharsSample, base); From 9abb76046d9e8143e2268ea0b82764c82fb743ba Mon Sep 17 00:00:00 2001 From: pquitslund Date: Thu, 14 May 2015 10:26:42 -0700 Subject: [PATCH 087/657] Fixed path normalization. --- pkgs/package_config/lib/packagemap.dart | 13 +++++++------ pkgs/package_config/test/test_packagemap.dart | 14 ++++++-------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/pkgs/package_config/lib/packagemap.dart b/pkgs/package_config/lib/packagemap.dart index e05c14d15..46a17970f 100644 --- a/pkgs/package_config/lib/packagemap.dart +++ b/pkgs/package_config/lib/packagemap.dart @@ -30,9 +30,8 @@ class Packages { throw new ArgumentError.value( uri, "uri", "Path must not start with '/'."); } - //TODO: re-enable // Normalizes the path by removing '.' and '..' segments. - // uri = uri.normalizePath(); + uri = _normalizePath(uri); String path = uri.path; var slashIndex = path.indexOf('/'); String packageName; @@ -52,6 +51,10 @@ class Packages { return packageLocation.resolveUri(new Uri(path: rest)); } + /// A stand in for uri.normalizePath(), coming in 1.11 + static Uri _normalizePath(Uri existingUri) => + new Uri().resolveUri(existingUri); + /// Parses a `packages.cfg` file into a `Packages` object. /// /// The [baseLocation] is used as a base URI to resolve all relative @@ -186,14 +189,12 @@ class Packages { } } - //TODO: normalize path - // baseUri = baseUri.normalizePath(); + baseUri = _normalizePath(baseUri); List base = baseUri.pathSegments.toList(); if (base.isNotEmpty) { base = new List.from(base)..removeLast(); } - //TODO: normalize path - //uri = uri.normalizePath(); + uri = _normalizePath(uri); List target = uri.pathSegments.toList(); int index = 0; while (index < base.length && index < target.length) { diff --git a/pkgs/package_config/test/test_packagemap.dart b/pkgs/package_config/test/test_packagemap.dart index 2c03dba8b..bce20d4b8 100644 --- a/pkgs/package_config/test/test_packagemap.dart +++ b/pkgs/package_config/test/test_packagemap.dart @@ -72,14 +72,12 @@ main() { equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); - -// TODO: re-enable when path normalization is in -// test("dot-dot 2", () { -// var packages = Packages.parse(singleRelativeSample, base); -// expect(packages.packageMapping.keys.toList(), equals(["foo"])); -// expect(packages.resolve(Uri.parse("package:qux/../foo/bar/baz.dart")), -// equals(base.resolve("../test/").resolve("bar/baz.dart"))); -// }); + test("dot-dot 2", () { + var packages = Packages.parse(singleRelativeSample, base); + expect(packages.packageMapping.keys.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:qux/../foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); test("all valid chars", () { var packages = Packages.parse(allValidCharsSample, base); From fd35e58cd6133de83a64803a1300e1d4d20431a1 Mon Sep 17 00:00:00 2001 From: pquitslund Date: Thu, 14 May 2015 11:06:35 -0700 Subject: [PATCH 088/657] Fixed path normalization. --- pkgs/package_config/.travis.yml | 1 + pkgs/package_config/lib/packagemap.dart | 10 +++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml index b1279b7e4..7a20d25b2 100644 --- a/pkgs/package_config/.travis.yml +++ b/pkgs/package_config/.travis.yml @@ -1,3 +1,4 @@ language: dart +dart: dev script: ./tool/travis.sh sudo: false diff --git a/pkgs/package_config/lib/packagemap.dart b/pkgs/package_config/lib/packagemap.dart index 46a17970f..25f27b9a2 100644 --- a/pkgs/package_config/lib/packagemap.dart +++ b/pkgs/package_config/lib/packagemap.dart @@ -31,7 +31,7 @@ class Packages { uri, "uri", "Path must not start with '/'."); } // Normalizes the path by removing '.' and '..' segments. - uri = _normalizePath(uri); + uri = uri.normalizePath(); String path = uri.path; var slashIndex = path.indexOf('/'); String packageName; @@ -51,10 +51,6 @@ class Packages { return packageLocation.resolveUri(new Uri(path: rest)); } - /// A stand in for uri.normalizePath(), coming in 1.11 - static Uri _normalizePath(Uri existingUri) => - new Uri().resolveUri(existingUri); - /// Parses a `packages.cfg` file into a `Packages` object. /// /// The [baseLocation] is used as a base URI to resolve all relative @@ -189,12 +185,12 @@ class Packages { } } - baseUri = _normalizePath(baseUri); + baseUri = baseUri.normalizePath(); List base = baseUri.pathSegments.toList(); if (base.isNotEmpty) { base = new List.from(base)..removeLast(); } - uri = _normalizePath(uri); + uri = uri.normalizePath(); List target = uri.pathSegments.toList(); int index = 0; while (index < base.length && index < target.length) { From a13bf81ef7eff8a3ad9c754e3592a09a856485fc Mon Sep 17 00:00:00 2001 From: pquitslund Date: Thu, 14 May 2015 15:26:07 -0700 Subject: [PATCH 089/657] SDK constraint bump to pickup Uri.normalizePath(). --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index b0f2d8fec..7494fddb9 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -5,7 +5,7 @@ author: Dart Team homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=1.0.0 <2.0.0' + sdk: '>=1.11.0-dev.0.0 <2.0.0' dev_dependencies: test: '>=0.12.0 <0.13.0' From d56ecf203d81206f6b3cbee87a2d73dcdf8c5a21 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 20 May 2015 16:48:05 -0700 Subject: [PATCH 090/657] Change the pre-release range semantics. This allows ">=1.2.3-dev <1.2.3" to work how it looks like it should work, as opposed to matching no versions at all. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1149543002 --- pkgs/pub_semver/CHANGELOG.md | 8 +++++ pkgs/pub_semver/README.md | 10 +++--- pkgs/pub_semver/lib/src/version_range.dart | 37 +++++++++++++++----- pkgs/pub_semver/test/version_range_test.dart | 12 +++++++ 4 files changed, 55 insertions(+), 12 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 06f7caa40..58190a8a6 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,11 @@ +# 1.2.1 + +* Allow version ranges like `>=1.2.3-dev.1 <1.2.3` to match pre-release versions + of `1.2.3`. Previously, these didn't match, since the pre-release versions had + the same major, minor, and patch numbers as the max; now an exception has been + added if they also have the same major, minor, and patch numbers as the min + *and* the min is also a pre-release version. + # 1.2.0 * Add a `VersionConstraint.union()` method and a `new diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index 3f9558f42..b35975407 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -33,10 +33,12 @@ spec. It differs from semver in a few corner cases: unstable versions of `2.0.0`'s API, which is what pre-release versions represent. - To handle that, `<` version ranges to not allow pre-release versions of the - maximum unless the max is itself a pre-release. In other words, a `<2.0.0` - constraint will prohibit not just `2.0.0` but any pre-release of `2.0.0`. - However, `<2.0.0-beta` will exclude `2.0.0-beta` but allow `2.0.0-alpha`. + To handle that, `<` version ranges don't allow pre-release versions of the + maximum unless the max is itself a pre-release, or the min is a pre-release + of the same version. In other words, a `<2.0.0` constraint will prohibit not + just `2.0.0` but any pre-release of `2.0.0`. However, `<2.0.0-beta` will + exclude `2.0.0-beta` but allow `2.0.0-alpha`. Likewise, `>2.0.0-alpha + <2.0.0` will exclude `2.0.0-alpha` but allow `2.0.0-beta`. * **Pre-release versions are avoided when possible.** The above case handles pre-release versions at the top of the range, but what about in diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 7a18edf0e..5c53834c6 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -85,21 +85,42 @@ class VersionRange implements VersionConstraint { if (other > max) return false; if (!includeMax && other == max) return false; - // If the max isn't itself a pre-release, don't allow any pre-release - // versions of the max. + + // Disallow pre-release versions that have the same major, minor, and + // patch version as the max, but only if neither the max nor the min is a + // pre-release of that version. This ensures that "^1.2.3" doesn't include + // "2.0.0-pre", while also allowing both ">=2.0.0-pre.2 <2.0.0" and + // ">=1.2.3 <2.0.0-pre.7" to match "2.0.0-pre.5". + // + // It's worth noting that this is different than [NPM's semantics][]. NPM + // disallows **all** pre-release versions unless their major, minor, and + // patch numbers match those of a prerelease min or max. This ensures that + // no prerelease versions will ever be selected if the user doesn't + // explicitly allow them. + // + // [NPM's semantics]: https://www.npmjs.org/doc/misc/semver.html#prerelease-tags // - // See: https://www.npmjs.org/doc/misc/semver.html - if (!includeMax && + // Instead, we ensure that release versions will always be preferred over + // prerelease versions by ordering the release versions first in + // [Version.prioritize]. This means that constraints like "any" or + // ">1.2.3" can still match prerelease versions if they're the only things + // available. + var maxIsReleaseOfOther = !includeMax && !max.isPreRelease && other.isPreRelease && - other.major == max.major && other.minor == max.minor && - other.patch == max.patch) { - return false; - } + _equalsWithoutPreRelease(other, max); + var minIsPreReleaseOfOther = min != null && min.isPreRelease && + _equalsWithoutPreRelease(other, min); + if (maxIsReleaseOfOther && !minIsPreReleaseOfOther) return false; } return true; } + bool _equalsWithoutPreRelease(Version version1, Version version2) => + version1.major == version2.major && + version1.minor == version2.minor && + version1.patch == version2.patch; + bool allowsAll(VersionConstraint other) { if (other.isEmpty) return true; if (other is Version) return allows(other); diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index ef35d8022..6df6b310a 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -105,6 +105,18 @@ main() { new Version.parse('2.3.4'))); }); + test('pre-release versions of non-pre-release max are included if min is a ' + 'pre-release of the same version', () { + var range = new VersionRange( + min: new Version.parse('2.3.4-dev.0'), max: v234); + + expect(range, allows(new Version.parse('2.3.4-dev.1'))); + expect(range, doesNotAllow( + new Version.parse('2.3.3'), + new Version.parse('2.3.4-dev'), + new Version.parse('2.3.4'))); + }); + test('pre-release versions of pre-release max are included', () { var range = new VersionRange(max: new Version.parse('2.3.4-dev.2')); From f57d158ac181a468b3742405fb39515db0fbfb3e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 20 May 2015 17:49:03 -0700 Subject: [PATCH 091/657] Update the pubspec for 1.2.1. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1143063003 --- pkgs/pub_semver/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 26be2808b..33545a37b 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.2.0 +version: 1.2.1 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 1f27fad214f9e664b1438b3b1f555667a02edb8e Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 22 May 2015 12:43:32 +0200 Subject: [PATCH 092/657] Added .packages, packages/ discovery. Complete restructure of repository, splitting into several files. R=pquitslund@google.com Review URL: https://codereview.chromium.org//1142363005 --- pkgs/package_config/lib/discovery.dart | 160 ++++++++++++ pkgs/package_config/lib/packagemap.dart | 228 ------------------ pkgs/package_config/lib/packages.dart | 97 ++++++++ pkgs/package_config/lib/packages_file.dart | 172 +++++++++++++ .../package_config/lib/src/packages_impl.dart | 118 +++++++++ pkgs/package_config/lib/src/util.dart | 69 ++++++ pkgs/package_config/pubspec.lock | 8 + pkgs/package_config/pubspec.yaml | 5 + pkgs/package_config/test/all.dart | 4 +- .../{test_packagemap.dart => parse_test.dart} | 80 +++--- 10 files changed, 674 insertions(+), 267 deletions(-) create mode 100644 pkgs/package_config/lib/discovery.dart delete mode 100644 pkgs/package_config/lib/packagemap.dart create mode 100644 pkgs/package_config/lib/packages.dart create mode 100644 pkgs/package_config/lib/packages_file.dart create mode 100644 pkgs/package_config/lib/src/packages_impl.dart create mode 100644 pkgs/package_config/lib/src/util.dart rename pkgs/package_config/test/{test_packagemap.dart => parse_test.dart} (60%) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart new file mode 100644 index 000000000..78254eeba --- /dev/null +++ b/pkgs/package_config/lib/discovery.dart @@ -0,0 +1,160 @@ +// Copyright (c) 2015, 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. + +library package_config.discovery; + +import "dart:async"; +import "dart:io" show Directory, File, FileSystemEntity; +import "package:path/path.dart" as path; +import "package:http/http.dart" as http; +import "packages.dart"; +import "packages_file.dart" as pkgfile show parse; +import "src/packages_impl.dart"; + +/// Discover the package configuration for a Dart script. +/// +/// The [baseUri] points to either the Dart script or its directory. +/// A package resolution strategy is found by going through the following steps, +/// and stopping when something is found. +/// +/// * Check if a `.packages` file exists in the same directory. +/// * If `baseUri`'s scheme is not `file`, then assume a `packages` directory +/// in the same directory, and resolve packages relative to that. +/// * If `baseUri`'s scheme *is* `file`: +/// * Check if a `packages` directory exists. +/// * Otherwise check each successive parent directory of `baseUri` for a +/// `.packages` file. +/// +/// If any of these tests succeed, a `Packages` class is returned. +/// Returns the constant [noPackages] if no resolution strategy is found. +/// +/// This function currently only supports `file`, `http` and `https` URIs. +/// It needs to be able to load a `.packages` file from the URI, so only +/// recognized schemes are accepted. +/// +/// To support other schemes, an optional [loader] function can be supplied. +/// It's called to load the `.packages` file for any unsupported scheme. +/// It must return the *contents* of the file identified by the URI it's given, +/// which should be a UTF-8 encoded `.packages` file, and must return an +/// error future if loading fails for any reason. +Future findPackages( + Uri baseUri, + {Future> loader(Uri unsupportedUri)}) { + if (baseUri.scheme == "file") { + return new Future.sync(() => findPackagesFromFile(baseUri)); + } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { + return findPackagesFromNonFile(baseUri, _httpGet); + } else if (loader != null) { + return findPackagesFromNonFile(baseUri, loader); + } else { + return new Future.value(Packages.noPackages); + } +} + +/// Find the location of the package resolution file/directory for a Dart file. +/// +/// Checks for a `.packages` file in the [workingDirectory]. +/// If not found, checks for a `packages` directory in the same directory. +/// If still not found, starts checking parent directories for +/// `.packages` until reaching the root directory. +/// +/// Returns a [File] object of a `.packages` file if one is found, or a +/// [Directory] object for the `packages/` directory if that is found. +FileSystemEntity _findPackagesFile(String workingDirectory) { + var dir = new Directory(workingDirectory); + if (!dir.isAbsolute) dir = dir.absolute; + if (!dir.existsSync()) { + throw new ArgumentError.value( + workingDirectory, "workingDirectory", "Directory does not exist."); + } + File checkForConfigFile(Directory directory) { + assert(directory.isAbsolute); + var file = new File(path.join(directory.path, ".packages")); + if (file.existsSync()) return file; + return null; + } + // Check for $cwd/.packages + var packagesCfgFile = checkForConfigFile(dir); + if (packagesCfgFile != null) return packagesCfgFile; + // Check for $cwd/packages/ + var packagesDir = new Directory(path.join(dir.path, "packages")); + if (packagesDir.existsSync()) return packagesDir; + // Check for cwd(/..)+/.packages + var parentDir = dir.parent; + while (parentDir.path != dir.path) { + packagesCfgFile = checkForConfigFile(parentDir); + if (packagesCfgFile != null) break; + dir = parentDir; + parentDir = dir.parent; + } + return packagesCfgFile; +} + +/// Finds a package resolution strategy for a local Dart script. +/// +/// The [fileBaseUri] points to either a Dart script or the directory of the +/// script. The `fileBaseUri` must be a `file:` URI. +/// +/// This function first tries to locate a `.packages` file in the `fileBaseUri` +/// directory. If that is not found, it instead checks for the presence of +/// a `packages/` directory in the same place. +/// If that also fails, it starts checking parent directories for a `.packages` +/// file, and stops if it finds it. +/// Otherwise it gives up and returns [Pacakges.noPackages]. +Packages findPackagesFromFile(Uri fileBaseUri) { + Uri baseDirectoryUri = fileBaseUri; + if (!fileBaseUri.path.endsWith('/')) { + baseDirectoryUri = baseDirectoryUri.resolve("."); + } + String baseDirectoryPath = baseDirectoryUri.toFilePath(); + FileSystemEntity location = _findPackagesFile(baseDirectoryPath); + if (location == null) return Packages.noPackages; + if (location is File) { + List fileBytes = location.readAsBytesSync(); + Map map = pkgfile.parse(fileBytes, + new Uri.file(location.path)); + return new MapPackages(map); + } + assert(location is Directory); + return new FilePackagesDirectoryPackages(location); +} + +/// Finds a package resolution strategy for a Dart script. +/// +/// The [nonFileUri] points to either a Dart script or the directory of the +/// script. +/// The [nonFileUri] should not be a `file:` URI since the algorithm for +/// finding a package resolution strategy is more elaborate for `file:` URIs. +/// In that case, use [findPackagesFile]. +/// +/// This function first tries to locate a `.packages` file in the [nonFileUri] +/// directory. If that is not found, it instead assumes a `packages/` directory +/// in the same place. +/// +/// By default, this function only works for `http:` and `https:` URIs. +/// To support other schemes, a loader must be provided, which is used to +/// try to load the `.packages` file. The loader should return the contents +/// of the requestsed `.packages` file as bytes, which will be assumed to be +/// UTF-8 encoded. +Future findPackagesFromNonFile(Uri nonFileUri, + [Future> loader(Uri name)]) { + if (loader == null) loader = _httpGet; + Uri packagesFileUri = nonFileUri.resolve(".packages"); + return loader(packagesFileUri).then((List fileBytes) { + Map map = pkgfile.parse(fileBytes, packagesFileUri); + return new MapPackages(map); + }, onError: (_) { + // Didn't manage to load ".packages". Assume a "packages/" directory. + Uri packagesDirectoryUri = nonFileUri.resolve("packages/"); + return new NonFilePackagesDirectoryPackages(packagesDirectoryUri); + }); +} + +/// Fetches a file using the http library. +Future> _httpGet(Uri uri) { + return http.get(uri).then((http.Response response) { + if (response.statusCode == 200) return response.bodyBytes; + throw 0; // The error message isn't being used for anything. + }); +} diff --git a/pkgs/package_config/lib/packagemap.dart b/pkgs/package_config/lib/packagemap.dart deleted file mode 100644 index 25f27b9a2..000000000 --- a/pkgs/package_config/lib/packagemap.dart +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright (c) 2015, 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. - -library package_config.packagemap; - -class Packages { - static const int _EQUALS = 0x3d; - static const int _CR = 0x0d; - static const int _NL = 0x0a; - static const int _NUMBER_SIGN = 0x23; - - final Map packageMapping; - - Packages(this.packageMapping); - - /// Resolves a URI to a non-package URI. - /// - /// If [uri] is a `package:` URI, the location is resolved wrt. the - /// [packageMapping]. - /// Otherwise the original URI is returned. - Uri resolve(Uri uri) { - if (uri.scheme.toLowerCase() != "package") { - return uri; - } - if (uri.hasAuthority) { - throw new ArgumentError.value(uri, "uri", "Must not have authority"); - } - if (uri.path.startsWith("/")) { - throw new ArgumentError.value( - uri, "uri", "Path must not start with '/'."); - } - // Normalizes the path by removing '.' and '..' segments. - uri = uri.normalizePath(); - String path = uri.path; - var slashIndex = path.indexOf('/'); - String packageName; - String rest; - if (slashIndex < 0) { - packageName = path; - rest = ""; - } else { - packageName = path.substring(0, slashIndex); - rest = path.substring(slashIndex + 1); - } - Uri packageLocation = packageMapping[packageName]; - if (packageLocation == null) { - throw new ArgumentError.value( - uri, "uri", "Unknown package name: $packageName"); - } - return packageLocation.resolveUri(new Uri(path: rest)); - } - - /// Parses a `packages.cfg` file into a `Packages` object. - /// - /// The [baseLocation] is used as a base URI to resolve all relative - /// URI references against. - /// - /// The `Packages` object allows resolving package: URIs and writing - /// the mapping back to a file or string. - /// The [packageMapping] will contain a simple mapping from package name - /// to package location. - static Packages parse(String source, Uri baseLocation) { - int index = 0; - Map result = {}; - while (index < source.length) { - bool isComment = false; - int start = index; - int eqIndex = -1; - int end = source.length; - int char = source.codeUnitAt(index++); - if (char == _CR || char == _NL) { - continue; - } - if (char == _EQUALS) { - throw new FormatException("Missing package name", source, index - 1); - } - isComment = char == _NUMBER_SIGN; - while (index < source.length) { - char = source.codeUnitAt(index++); - if (char == _EQUALS && eqIndex < 0) { - eqIndex = index - 1; - } else if (char == _NL || char == _CR) { - end = index - 1; - break; - } - } - if (isComment) continue; - if (eqIndex < 0) { - throw new FormatException("No '=' on line", source, index - 1); - } - _checkIdentifier(source, start, eqIndex); - var packageName = source.substring(start, eqIndex); - - var packageLocation = Uri.parse(source, eqIndex + 1, end); - if (!packageLocation.path.endsWith('/')) { - packageLocation = - packageLocation.replace(path: packageLocation.path + "/"); - } - packageLocation = baseLocation.resolveUri(packageLocation); - if (result.containsKey(packageName)) { - throw new FormatException( - "Same package name occured twice.", source, start); - } - result[packageName] = packageLocation; - } - return new Packages(result); - } - - /** - * Writes the mapping to a [StringSink]. - * - * If [comment] is provided, the output will contain this comment - * with `#` in front of each line. - * - * If [baseUri] is provided, package locations will be made relative - * to the base URI, if possible, before writing. - */ - void write(StringSink output, {Uri baseUri, String comment}) { - if (baseUri != null && !baseUri.isAbsolute) { - throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute"); - } - - if (comment != null) { - for (var commentLine in comment.split('\n')) { - output.write('#'); - output.writeln(commentLine); - } - } else { - output.write("# generated by package:packagecfg at "); - output.write(new DateTime.now()); - output.writeln(); - } - - packageMapping.forEach((String packageName, Uri uri) { - // Validate packageName. - _checkIdentifier(packageName, 0, packageName.length); - output.write(packageName); - - output.write('='); - - // If baseUri provided, make uri relative. - if (baseUri != null) { - uri = relativize(uri, baseUri); - } - output.write(uri); - if (!uri.path.endsWith('/')) { - output.write('/'); - } - output.writeln(); - }); - } - - String toString() { - StringBuffer buffer = new StringBuffer(); - write(buffer); - return buffer.toString(); - } - - static Uri relativize(Uri uri, Uri baseUri) { - if (uri.hasQuery || uri.hasFragment) { - uri = new Uri( - scheme: uri.scheme, - userInfo: uri.hasAuthority ? uri.userInfo : null, - host: uri.hasAuthority ? uri.host : null, - port: uri.hasAuthority ? uri.port : null, - path: uri.path); - } - if (!baseUri.isAbsolute) { - throw new ArgumentError("Base uri '$baseUri' must be absolute."); - } - // Already relative. - if (!uri.isAbsolute) return uri; - - if (baseUri.scheme.toLowerCase() != uri.scheme.toLowerCase()) { - return uri; - } - // If authority differs, we could remove the scheme, but it's not worth it. - if (uri.hasAuthority != baseUri.hasAuthority) return uri; - if (uri.hasAuthority) { - if (uri.userInfo != baseUri.userInfo || - uri.host.toLowerCase() != baseUri.host.toLowerCase() || - uri.port != baseUri.port) { - return uri; - } - } - - baseUri = baseUri.normalizePath(); - List base = baseUri.pathSegments.toList(); - if (base.isNotEmpty) { - base = new List.from(base)..removeLast(); - } - uri = uri.normalizePath(); - List target = uri.pathSegments.toList(); - int index = 0; - while (index < base.length && index < target.length) { - if (base[index] != target[index]) { - break; - } - index++; - } - if (index == base.length) { - return new Uri(path: target.skip(index).join('/')); - } else if (index > 0) { - return new Uri( - path: '../' * (base.length - index) + target.skip(index).join('/')); - } else { - return uri; - } - } - - static bool _checkIdentifier(String string, int start, int end) { - const int a = 0x61; - const int z = 0x7a; - const int _ = 0x5f; - const int $ = 0x24; - if (start == end) return false; - for (int i = start; i < end; i++) { - var char = string.codeUnitAt(i); - if (char == _ || char == $) continue; - if ((char ^ 0x30) <= 9 && i > 0) continue; - char |= 0x20; // Lower-case letters. - if (char >= a && char <= z) continue; - throw new FormatException("Not an identifier", string, i); - } - return true; - } -} diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart new file mode 100644 index 000000000..8523ecc28 --- /dev/null +++ b/pkgs/package_config/lib/packages.dart @@ -0,0 +1,97 @@ +// Copyright (c) 2015, 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. + +library package_config.packages; + +import "dart:async" show Future; +import "discovery.dart" show findPackages; +import "src/packages_impl.dart"; + +/// A package resolution strategy. +/// +/// Allows converting a `package:` URI to a different kind of URI. +/// +/// May also allow listing the available packages and converting +/// to a `Map` that gives the base location of each available +/// package. In some cases there is no way to find the available packages, +/// in which case [packages] and [asMap] will throw if used. +/// One such case is if the packages are resolved relative to a +/// `packages/` directory available over HTTP. +abstract class Packages { + + /// A [Packages] resolver containing no packages. + /// + /// This constant object is returned by [find] above if no + /// package resolution strategy is found. + static const Packages noPackages = const NoPackages(); + + /// Create a `Packages` object based on a map from package name to base URI. + /// + /// The resulting `Packages` object will resolve package URIs by using this + /// map. + /// There is no validation of the map containing only valid package names, + factory Packages(Map packageMapping) => + new MapPackages(packageMapping); + + /// Attempts to find a package resolution strategy for a Dart script. + /// + /// The [baseLocation] should point to a Dart script or to its directory. + /// The function goes through the following steps in order to search for + /// a packages resolution strategy: + /// + /// * First check if a `.packages` file in the script's directory. + /// If a file is found, its content is loaded and interpreted as a map + /// from package names to package location URIs. + /// If loading or parsing of the file fails, so does this function. + /// * Then if `baseLocation` is not a `file:` URI, + /// assume that a `packages/` directory exists in the script's directory, + /// and return a `Packages` object that resolves package URIs as + /// paths into that directory. + /// * If `baseLocation` is a `file:` URI, instead *check* whether + /// a `packages/` directory exists in the script directory. + /// If it does, return a `Packages` object that resolves package URIs + /// as paths into that directory. This `Packages` object is able to + /// read the directory and see which packages are available. + /// * Otherwise, check each directory in the parent path of `baseLocation` + /// for the existence of a `.packages` file. If one is found, it is loaded + /// just as in the first step. + /// * If no file is found before reaching the file system root, + /// the constant [noPacakages] is returned. It's a `Packages` object + /// with no available packages. + /// + static Future find(Uri baseLocation) => findPackages(baseLocation); + + /// Resolve a package URI into a non-package URI. + /// + /// Translates a `package:` URI, according to the package resolution + /// strategy, into a URI that can be loaded. + /// By default, only `file`, `http` and `https` URIs are returned. + /// Custom `Packages` objects may return other URIs. + /// + /// If resolution fails because a package with the requested package name + /// is not available, the [notFound] function is called. + /// If no `notFound` function is provided, it defaults to throwing an error. + /// + /// The [packageUri] must be a valid package URI. + Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}); + + /// Return the names of the available packages. + /// + /// Returns an iterable that allows iterating the names of available packages. + /// + /// Some `Packages` objects are unable to find the package names, + /// and getting `packages` from such a `Packages` object will throw. + Iterable get packages; + + /// Return the names-to-base-URI mapping of the available packages. + /// + /// Returns a map from package name to a base URI. + /// The [resolve] method will resolve a package URI with a specific package + /// name to a path extending the base URI that this map gives for that + /// package name. + /// + /// Some `Packages` objects are unable to find the package names, + /// and calling `asMap` on such a `Packages` object will throw. + Map asMap(); +} diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart new file mode 100644 index 000000000..48c2334e0 --- /dev/null +++ b/pkgs/package_config/lib/packages_file.dart @@ -0,0 +1,172 @@ +// Copyright (c) 2015, 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. + +library package_config.packages_file; + +import "package:charcode/ascii.dart"; +import "src/util.dart" show isIdentifier; + +/// Parses a `.packages` file into a map from package name to base URI. +/// +/// The [source] is the byte content of a `.packages` file, assumed to be +/// UTF-8 encoded. In practice, all sinficant parts of the file must be ASCII, +/// so Latin-1 or Windows-1252 encoding will also work fine. +/// +/// If the file content is available as a string, its [String.codeUnits] can +/// be used as the `source` argument of this function. +/// +/// The [baseLocation] is used as a base URI to resolve all relative +/// URI references against. +/// If the content was read from a file, `baseLocation` should be the +/// location of that file. +/// +/// Returns a simple mapping from package name to package location. +Map parse(List source, Uri baseLocation) { + int index = 0; + Map result = {}; + while (index < source.length) { + bool isComment = false; + int start = index; + int eqIndex = -1; + int end = source.length; + int char = source[index++]; + if (char == $cr || char == $lf) { + continue; + } + if (char == $equal) { + throw new FormatException("Missing package name", source, index - 1); + } + isComment = char == $hash; + while (index < source.length) { + char = source[index++]; + if (char == $equal && eqIndex < 0) { + eqIndex = index - 1; + } else if (char == $cr || char == $lf) { + end = index - 1; + break; + } + } + if (isComment) continue; + if (eqIndex < 0) { + throw new FormatException("No '=' on line", source, index - 1); + } + var packageName = new String.fromCharCodes(source, start, eqIndex); + if (!isIdentifier(packageName)) { + throw new FormatException("Not a valid package name", packageName, 0); + } + var packageUri = new String.fromCharCodes(source, eqIndex + 1, end); + var packageLocation = Uri.parse(packageUri); + if (!packageLocation.path.endsWith('/')) { + packageLocation = + packageLocation.replace(path: packageLocation.path + "/"); + } + packageLocation = baseLocation.resolveUri(packageLocation); + if (result.containsKey(packageName)) { + throw new FormatException( + "Same package name occured twice.", source, start); + } + result[packageName] = packageLocation; + } + return result; +} + +/// Writes the mapping to a [StringSink]. +/// +/// If [comment] is provided, the output will contain this comment +/// with `#` in front of each line. +/// +/// If [baseUri] is provided, package locations will be made relative +/// to the base URI, if possible, before writing. +void write(StringSink output, Map packageMapping, + {Uri baseUri, String comment}) { + if (baseUri != null && !baseUri.isAbsolute) { + throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute"); + } + + if (comment != null) { + for (var commentLine in comment.split('\n')) { + output.write('#'); + output.writeln(commentLine); + } + } else { + output.write("# generated by package:package_config at "); + output.write(new DateTime.now()); + output.writeln(); + } + + packageMapping.forEach((String packageName, Uri uri) { + // Validate packageName. + if (!isIdentifier(packageName)) { + throw new ArgumentError('"$packageName" is not a valid package name'); + } + output.write(packageName); + output.write('='); + // If baseUri provided, make uri relative. + if (baseUri != null) { + uri = _relativize(uri, baseUri); + } + output.write(uri); + if (!uri.path.endsWith('/')) { + output.write('/'); + } + output.writeln(); + }); +} + +/// Attempts to return a relative URI for [uri]. +/// +/// The result URI satisfies `baseUri.resolveUri(result) == uri`, +/// but may be relative. +/// The `baseUri` must be absolute. +Uri _relativize(Uri uri, Uri baseUri) { + assert(!baseUri.isAbsolute); + if (uri.hasQuery || uri.hasFragment) { + uri = new Uri( + scheme: uri.scheme, + userInfo: uri.hasAuthority ? uri.userInfo : null, + host: uri.hasAuthority ? uri.host : null, + port: uri.hasAuthority ? uri.port : null, + path: uri.path); + } + + // Already relative. We assume the caller knows what they are doing. + if (!uri.isAbsolute) return uri; + + if (baseUri.scheme != uri.scheme) { + return uri; + } + + // If authority differs, we could remove the scheme, but it's not worth it. + if (uri.hasAuthority != baseUri.hasAuthority) return uri; + if (uri.hasAuthority) { + if (uri.userInfo != baseUri.userInfo || + uri.host.toLowerCase() != baseUri.host.toLowerCase() || + uri.port != baseUri.port) { + return uri; + } + } + + baseUri = baseUri.normalizePath(); + List base = baseUri.pathSegments.toList(); + if (base.isNotEmpty) { + base = new List.from(base)..removeLast(); + } + uri = uri.normalizePath(); + List target = uri.pathSegments.toList(); + int index = 0; + while (index < base.length && index < target.length) { + if (base[index] != target[index]) { + break; + } + index++; + } + if (index == base.length) { + return new Uri(path: target.skip(index).join('/')); + } else if (index > 0) { + return new Uri( + path: '../' * (base.length - index) + target.skip(index).join('/')); + } else { + return uri; + } +} diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart new file mode 100644 index 000000000..612dc347d --- /dev/null +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -0,0 +1,118 @@ +// Copyright (c) 2015, 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. + +library package_config.packages_impl; + +import "dart:collection" show UnmodifiableMapView; +import "dart:io" show Directory; +import "package:path/path.dart" as path; +import "../packages.dart"; +import "util.dart" show checkValidPackageUri; + +/// A [Packages] null-object. +class NoPackages implements Packages { + const NoPackages(); + + Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { + String packageName = checkValidPackageUri(packageUri); + if (notFound != null) return notFound(packageUri); + throw new ArgumentError.value(packageUri, "packageUri", + 'No package named "$packageName"'); + } + + Iterable get packages => new Iterable.empty(); + + Map asMap() => const{}; +} + + +/// Base class for [Packages] implementations. +/// +/// This class implements the [resolve] method in terms of a private +/// member +abstract class _PackagesBase implements Packages { + Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { + packageUri = packageUri.normalizePath(); + String packageName = checkValidPackageUri(packageUri); + Uri packageBase = _getBase(packageName); + if (packageBase == null) { + if (notFound != null) return notFound(packageUri); + throw new ArgumentError.value(packageUri, "packageUri", + 'No package named "$packageName"'); + } + String packagePath = packageUri.path.substring(packageName.length + 1); + return packageBase.resolve(packagePath); + } + + /// Find a base location for a package name. + /// + /// Returns `null` if no package exists with that name, and that can be + /// determined. + Uri _getBase(String packageName); +} + +/// A [Packages] implementation based on an existing map. +class MapPackages extends _PackagesBase { + final Map _mapping; + MapPackages(this._mapping); + + Uri _getBase(String packageName) => _mapping[packageName]; + + Iterable get packages => _mapping.keys; + + Map asMap() => new UnmodifiableMapView(_mapping); +} + +/// A [Packages] implementation based on a local directory. +class FilePackagesDirectoryPackages extends _PackagesBase { + final Directory _packageDir; + FilePackagesDirectoryPackages(this._packageDir); + + Uri _getBase(String packageName) => + new Uri.directory(path.join(packageName,'')); + + Iterable _listPackageNames() { + return _packageDir.listSync() + .where((e) => e is Directory) + .map((e) => path.basename(e.path)); + } + + Iterable get packages { + return _listPackageNames(); + } + + Map asMap() { + var result = {}; + for (var packageName in _listPackageNames()) { + result[packageName] = _getBase(packageName); + } + return new UnmodifiableMapView(result); + } +} + +/// A [Packages] implementation based on a remote (e.g., HTTP) directory. +/// +/// There is no way to detect which packages exist short of trying to use +/// them. You can't necessarily check whether a directory exists, +/// except by checking for a know file in the directory. +class NonFilePackagesDirectoryPackages extends _PackagesBase { + final Uri _packageBase; + NonFilePackagesDirectoryPackages(this._packageBase); + + Uri _getBase(String packageName) => _packageBase.resolve("$packageName/"); + + Error _failListingPackages() { + return new UnsupportedError( + "Cannot list packages for a ${_packageBase.scheme}: " + "based package root"); + } + + Iterable get packages { + throw _failListingPackages(); + } + + Map asMap() { + throw _failListingPackages(); + } +} diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart new file mode 100644 index 000000000..76bd1d6e5 --- /dev/null +++ b/pkgs/package_config/lib/src/util.dart @@ -0,0 +1,69 @@ +// Copyright (c) 2015, 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 methods used by more than one library in the package. +library package_config.util; + +import "package:charcode/ascii.dart"; + +/// Tests whether something is a valid Dart identifier/package name. +bool isIdentifier(String string) { + if (string.isEmpty) return false; + int firstChar = string.codeUnitAt(0); + int firstCharLower = firstChar |= 0x20; + if (firstCharLower < $a || firstCharLower > $z) { + if (firstChar != $_ && firstChar != $$) return false; + } + for (int i = 1; i < string.length; i++) { + int char = string.codeUnitAt(i); + int charLower = char | 0x20; + if (charLower < $a || charLower > $z) { // Letters. + if ((char ^ 0x30) <= 9) continue; // Digits. + if (char == $_ || char == $$) continue; // $ and _ + if (firstChar != $_ && firstChar != $$) return false; + } + } + return true; +} + + +/// Validate that a Uri is a valid package:URI. +String checkValidPackageUri(Uri packageUri) { + if (packageUri.scheme != "package") { + throw new ArgumentError.value(packageUri, "packageUri", + "Not a package: URI"); + } + if (packageUri.hasAuthority) { + throw new ArgumentError.value(packageUri, "packageUri", + "Package URIs must not have a host part"); + } + if (packageUri.hasQuery) { + // A query makes no sense if resolved to a file: URI. + throw new ArgumentError.value(packageUri, "packageUri", + "Package URIs must not have a query part"); + } + if (packageUri.hasFragment) { + // We could leave the fragment after the URL when resolving, + // but it would be odd if "package:foo/foo.dart#1" and + // "package:foo/foo.dart#2" were considered different libraries. + // Keep the syntax open in case we ever get multiple libraries in one file. + throw new ArgumentError.value(packageUri, "packageUri", + "Package URIs must not have a fragment part"); + } + if (packageUri.path.startsWith('/')) { + throw new ArgumentError.value(packageUri, "packageUri", + "Package URIs must not start with a '/'"); + } + int firstSlash = packageUri.path.indexOf('/'); + if (firstSlash == -1) { + throw new ArgumentError.value(packageUri, "packageUri", + "Package URIs must start with the package name followed by a '/'"); + } + String packageName = packageUri.path.substring(0, firstSlash); + if (!isIdentifier(packageName)) { + throw new ArgumentError.value(packageUri, "packageUri", + "Package names must be valid identifiers"); + } + return packageName; +} diff --git a/pkgs/package_config/pubspec.lock b/pkgs/package_config/pubspec.lock index 197d32ed6..708d89157 100644 --- a/pkgs/package_config/pubspec.lock +++ b/pkgs/package_config/pubspec.lock @@ -13,6 +13,10 @@ packages: description: barback source: hosted version: "0.15.2+4" + charcode: + description: charcode + source: hosted + version: "1.1.0" collection: description: collection source: hosted @@ -21,6 +25,10 @@ packages: description: crypto source: hosted version: "0.9.0" + http: + description: http + source: hosted + version: "0.11.2" http_parser: description: http_parser source: hosted diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 7494fddb9..27af78ecd 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -7,5 +7,10 @@ homepage: https://github.com/dart-lang/package_config environment: sdk: '>=1.11.0-dev.0.0 <2.0.0' +dependencies: + charcode: '^1.1.0' + path: "any" + http: "any" + dev_dependencies: test: '>=0.12.0 <0.13.0' diff --git a/pkgs/package_config/test/all.dart b/pkgs/package_config/test/all.dart index 795289cdf..310e1ee43 100644 --- a/pkgs/package_config/test/all.dart +++ b/pkgs/package_config/test/all.dart @@ -2,8 +2,8 @@ // 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 'test_packagemap.dart' as packagemap; +import 'parse_test.dart' as parse; main() { - packagemap.main(); + parse.main(); } diff --git a/pkgs/package_config/test/test_packagemap.dart b/pkgs/package_config/test/parse_test.dart similarity index 60% rename from pkgs/package_config/test/test_packagemap.dart rename to pkgs/package_config/test/parse_test.dart index bce20d4b8..f7f68f10d 100644 --- a/pkgs/package_config/test/test_packagemap.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -4,61 +4,62 @@ library test_all; -import "package:package_config/packagemap.dart"; +import "package:package_config/packages.dart"; +import "package:package_config/packages_file.dart" show parse; import "package:test/test.dart"; main() { var base = Uri.parse("file:///one/two/three/packages.map"); test("empty", () { - var packages = Packages.parse(emptySample, base); - expect(packages.packageMapping, isEmpty); + var packages = doParse(emptySample, base); + expect(packages.asMap(), isEmpty); }); test("comment only", () { - var packages = Packages.parse(commentOnlySample, base); - expect(packages.packageMapping, isEmpty); + var packages = doParse(commentOnlySample, base); + expect(packages.asMap(), isEmpty); }); test("empty lines only", () { - var packages = Packages.parse(emptyLinesSample, base); - expect(packages.packageMapping, isEmpty); + var packages = doParse(emptyLinesSample, base); + expect(packages.asMap(), isEmpty); }); test("empty lines only", () { - var packages = Packages.parse(emptyLinesSample, base); - expect(packages.packageMapping, isEmpty); + var packages = doParse(emptyLinesSample, base); + expect(packages.asMap(), isEmpty); }); test("single", () { - var packages = Packages.parse(singleRelativeSample, base); - expect(packages.packageMapping.keys.toList(), equals(["foo"])); + var packages = doParse(singleRelativeSample, base); + expect(packages.packages.toList(), equals(["foo"])); expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); test("single no slash", () { - var packages = Packages.parse(singleRelativeSampleNoSlash, base); - expect(packages.packageMapping.keys.toList(), equals(["foo"])); + var packages = doParse(singleRelativeSampleNoSlash, base); + expect(packages.packages.toList(), equals(["foo"])); expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); test("single no newline", () { - var packages = Packages.parse(singleRelativeSampleNoNewline, base); - expect(packages.packageMapping.keys.toList(), equals(["foo"])); + var packages = doParse(singleRelativeSampleNoNewline, base); + expect(packages.packages.toList(), equals(["foo"])); expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); test("single absolute", () { - var packages = Packages.parse(singleAbsoluteSample, base); - expect(packages.packageMapping.keys.toList(), equals(["foo"])); + var packages = doParse(singleAbsoluteSample, base); + expect(packages.packages.toList(), equals(["foo"])); expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), equals(Uri.parse("http://example.com/some/where/bar/baz.dart"))); }); test("multiple", () { - var packages = Packages.parse(multiRelativeSample, base); + var packages = doParse(multiRelativeSample, base); expect( - packages.packageMapping.keys.toList()..sort(), equals(["bar", "foo"])); + packages.packages.toList()..sort(), equals(["bar", "foo"])); expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); expect(packages.resolve(Uri.parse("package:bar/foo/baz.dart")), @@ -66,51 +67,51 @@ main() { }); test("dot-dot 1", () { - var packages = Packages.parse(singleRelativeSample, base); - expect(packages.packageMapping.keys.toList(), equals(["foo"])); + var packages = doParse(singleRelativeSample, base); + expect(packages.packages.toList(), equals(["foo"])); expect(packages.resolve(Uri.parse("package:foo/qux/../bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); test("dot-dot 2", () { - var packages = Packages.parse(singleRelativeSample, base); - expect(packages.packageMapping.keys.toList(), equals(["foo"])); + var packages = doParse(singleRelativeSample, base); + expect(packages.packages.toList(), equals(["foo"])); expect(packages.resolve(Uri.parse("package:qux/../foo/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); test("all valid chars", () { - var packages = Packages.parse(allValidCharsSample, base); - expect(packages.packageMapping.keys.toList(), equals([allValidChars])); + var packages = doParse(allValidCharsSample, base); + expect(packages.packages.toList(), equals([allValidChars])); expect(packages.resolve(Uri.parse("package:$allValidChars/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); test("no escapes", () { - expect(() => Packages.parse("x%41x=x", base), throws); + expect(() => doParse("x%41x=x", base), throws); }); test("not identifiers", () { - expect(() => Packages.parse("1x=x", base), throws); - expect(() => Packages.parse(" x=x", base), throws); - expect(() => Packages.parse("\\x41x=x", base), throws); - expect(() => Packages.parse("x@x=x", base), throws); - expect(() => Packages.parse("x[x=x", base), throws); - expect(() => Packages.parse("x`x=x", base), throws); - expect(() => Packages.parse("x{x=x", base), throws); - expect(() => Packages.parse("x/x=x", base), throws); - expect(() => Packages.parse("x:x=x", base), throws); + expect(() => doParse("1x=x", base), throws); + expect(() => doParse(" x=x", base), throws); + expect(() => doParse("\\x41x=x", base), throws); + expect(() => doParse("x@x=x", base), throws); + expect(() => doParse("x[x=x", base), throws); + expect(() => doParse("x`x=x", base), throws); + expect(() => doParse("x{x=x", base), throws); + expect(() => doParse("x/x=x", base), throws); + expect(() => doParse("x:x=x", base), throws); }); test("same name twice", () { - expect(() => Packages.parse(singleRelativeSample * 2, base), throws); + expect(() => doParse(singleRelativeSample * 2, base), throws); }); for (String invalidSample in invalid) { test("invalid '$invalidSample'", () { var result; try { - result = Packages.parse(invalidSample, base); + result = doParse(invalidSample, base); } on FormatException { // expected return; @@ -120,6 +121,11 @@ main() { } } +Packages doParse(String sample, Uri baseUri) { + Map map = parse(sample.codeUnits, baseUri); + return new Packages(map); +} + // Valid samples. var emptySample = ""; var commentOnlySample = "# comment only\n"; From 8f4d9fe9f19db06c91c2163f8a6df88727e509b2 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 May 2015 18:33:05 -0700 Subject: [PATCH 093/657] Revert "Revert r38549, r38552, and r38557." This reverts commit 2686535940bdbe2664d4c1bd0012988038add009. R=nweiz@google.com Review URL: https://codereview.chromium.org//1152413002 --- pkgs/pool/CHANGELOG.md | 3 + pkgs/pool/lib/pool.dart | 13 ++- pkgs/pool/pubspec.yaml | 3 +- pkgs/pool/test/pool_test.dart | 187 ++++++++++++++++++++++------------ 4 files changed, 133 insertions(+), 73 deletions(-) create mode 100644 pkgs/pool/CHANGELOG.md diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md new file mode 100644 index 000000000..e8dee50c9 --- /dev/null +++ b/pkgs/pool/CHANGELOG.md @@ -0,0 +1,3 @@ +## 1.0.1 + +* A `TimeoutException` is now correctly thrown if the pool detects a deadlock. diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 36a29c86d..61482e3f2 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -40,14 +40,14 @@ class Pool { Timer _timer; /// The amount of time to wait before timing out the pending resources. - Duration _timeout; + final Duration _timeout; /// Creates a new pool with the given limit on how many resources may be /// allocated at once. /// /// If [timeout] is passed, then if that much time passes without any activity - /// all pending [request] futures will throw an exception. This is indented - /// to avoid deadlocks. + /// all pending [request] futures will throw a [TimeoutException]. This is + /// intended to avoid deadlocks. Pool(this._maxAllocatedResources, {Duration timeout}) : _timeout = timeout; @@ -106,8 +106,11 @@ class Pool { /// emit exceptions. void _onTimeout() { for (var completer in _requestedResources) { - completer.completeError("Pool deadlock: all resources have been " - "allocated for too long.", new Chain.current()); + completer.completeError( + new TimeoutException("Pool deadlock: all resources have been " + "allocated for too long.", + _timeout), + new Chain.current()); } _requestedResources.clear(); _timer = null; diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index b6a0ff299..a7d23a52c 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,9 +1,10 @@ name: pool -version: 1.0.0 +version: 1.0.1 author: Dart Team description: A class for managing a finite pool of resources. homepage: http://github.com/dart-lang/pool dependencies: stack_trace: ">=0.9.2 <2.0.0" dev_dependencies: + fake_async: ">=0.1.0 <0.2.0" unittest: ">=0.11.0 <0.12.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index bfeb876b1..bb9e60768 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:fake_async/fake_async.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart'; import 'package:unittest/unittest.dart'; @@ -19,30 +20,36 @@ void main() { }); test("resources block past the limit", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 50; i++) { - expect(pool.request(), completes); - } - expect(pool.request(), doesNotComplete); + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), doesNotComplete); + + async.elapse(new Duration(seconds: 1)); + }); }); test("a blocked resource is allocated when another is released", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 49; i++) { - expect(pool.request(), completes); - } - - return pool.request().then((lastAllocatedResource) { - var blockedResource = pool.request(); - - return pumpEventQueue().then((_) { - lastAllocatedResource.release(); - return pumpEventQueue(); - }).then((_) { - expect(blockedResource, completes); + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + expect(pool.request(), completes); + } + + pool.request().then((lastAllocatedResource) { + // This will only complete once [lastAllocatedResource] is released. + expect(pool.request(), completes); + + new Future.delayed(new Duration(microseconds: 1)).then((_) { + lastAllocatedResource.release(); + }); }); + + async.elapse(new Duration(seconds: 1)); }); }); }); @@ -57,63 +64,113 @@ void main() { }); test("blocks the callback past the limit", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync(() => new Completer().future)); - } - pool.withResource(expectNoAsync()); + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 50; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + pool.withResource(expectNoAsync()); + + async.elapse(new Duration(seconds: 1)); + }); }); test("a blocked resource is allocated when another is released", () { - var pool = new Pool(50); - var requests = []; - for (var i = 0; i < 49; i++) { - pool.withResource(expectAsync(() => new Completer().future)); - } + new FakeAsync().run((async) { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + pool.withResource(expectAsync(() => new Completer().future)); + } + + var completer = new Completer(); + var lastAllocatedResource = pool.withResource(() => completer.future); + var blockedResourceAllocated = false; + var blockedResource = pool.withResource(() { + blockedResourceAllocated = true; + }); - var completer = new Completer(); - var lastAllocatedResource = pool.withResource(() => completer.future); - var blockedResourceAllocated = false; - var blockedResource = pool.withResource(() { - blockedResourceAllocated = true; - }); + new Future.delayed(new Duration(microseconds: 1)).then((_) { + expect(blockedResourceAllocated, isFalse); + completer.complete(); + return new Future.delayed(new Duration(microseconds: 1)); + }).then((_) { + expect(blockedResourceAllocated, isTrue); + }); - return pumpEventQueue().then((_) { - expect(blockedResourceAllocated, isFalse); - completer.complete(); - return pumpEventQueue(); - }).then((_) { - expect(blockedResourceAllocated, isTrue); + async.elapse(new Duration(seconds: 1)); }); }); }); - // TODO(nweiz): Test timeouts when it's easier to use third-party packages. - // See r38552. -} + group("with a timeout", () { + test("doesn't time out if there are no pending requests", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } -/// Returns a [Future] that completes after pumping the event queue [times] -/// times. By default, this should pump the event queue enough times to allow -/// any code to run, as long as it's not waiting on some external event. -Future pumpEventQueue([int times = 20]) { - if (times == 0) return new Future.value(); - // We use a delayed future to allow microtask events to finish. The - // Future.value or Future() constructors use scheduleMicrotask themselves and - // would therefore not wait for microtask callbacks that are scheduled after - // invoking this method. - return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1)); + async.elapse(new Duration(seconds: 6)); + }); + }); + + test("resets the timer if a resource is returned", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 49; i++) { + expect(pool.request(), completes); + } + + pool.request().then((lastAllocatedResource) { + // This will only complete once [lastAllocatedResource] is released. + expect(pool.request(), completes); + + new Future.delayed(new Duration(seconds: 3)).then((_) { + lastAllocatedResource.release(); + expect(pool.request(), doesNotComplete); + }); + }); + + async.elapse(new Duration(seconds: 6)); + }); + }); + + test("resets the timer if a resource is requested", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), doesNotComplete); + + new Future.delayed(new Duration(seconds: 3)).then((_) { + expect(pool.request(), doesNotComplete); + }); + + async.elapse(new Duration(seconds: 6)); + }); + }); + + test("times out if nothing happens", () { + new FakeAsync().run((async) { + var pool = new Pool(50, timeout: new Duration(seconds: 5)); + for (var i = 0; i < 50; i++) { + expect(pool.request(), completes); + } + expect(pool.request(), throwsA(new isInstanceOf())); + + async.elapse(new Duration(seconds: 6)); + }); + }); + }); } /// Returns a function that will cause the test to fail if it's called. /// -/// This won't let the test complete until it's confident that the function -/// won't be called. +/// This should only be called within a [FakeAsync.run] zone. Function expectNoAsync() { - // Make sure the test lasts long enough for the function to get called if it's - // going to get called. - expect(pumpEventQueue(), completes); - var stack = new Trace.current(1); return () => handleExternalError( new TestFailure("Expected function not to be called."), "", @@ -122,13 +179,9 @@ Function expectNoAsync() { /// A matcher for Futures that asserts that they don't complete. /// -/// This won't let the test complete until it's confident that the function -/// won't be called. +/// This should only be called within a [FakeAsync.run] zone. Matcher get doesNotComplete => predicate((future) { expect(future, new isInstanceOf('Future')); - // Make sure the test lasts long enough for the function to get called if it's - // going to get called. - expect(pumpEventQueue(), completes); var stack = new Trace.current(1); future.then((_) => handleExternalError( From 3fb6e29aa46a3a77c7014b8c357d3bbf462fd0fa Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 May 2015 18:42:38 -0700 Subject: [PATCH 094/657] Fixed the homepage, upgraded to pkg/test R=nweiz@google.com Review URL: https://codereview.chromium.org//1161433002 --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/pubspec.yaml | 6 +++--- pkgs/pool/test/pool_test.dart | 28 ++++++++++------------------ 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index e8dee50c9..4fa87caec 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.2 + +* Fixed the homepage. + ## 1.0.1 * A `TimeoutException` is now correctly thrown if the pool detects a deadlock. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index a7d23a52c..19aac1e54 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,10 +1,10 @@ name: pool -version: 1.0.1 +version: 1.0.2 author: Dart Team description: A class for managing a finite pool of resources. -homepage: http://github.com/dart-lang/pool +homepage: https://github.com/dart-lang/pool dependencies: stack_trace: ">=0.9.2 <2.0.0" dev_dependencies: fake_async: ">=0.1.0 <0.2.0" - unittest: ">=0.11.0 <0.12.0" + test: ">=0.12.0 <0.13.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index bb9e60768..b654801e1 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -7,13 +7,12 @@ import 'dart:async'; import 'package:fake_async/fake_async.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; void main() { group("request()", () { test("resources can be requested freely up to the limit", () { var pool = new Pool(50); - var requests = []; for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } @@ -22,7 +21,6 @@ void main() { test("resources block past the limit", () { new FakeAsync().run((async) { var pool = new Pool(50); - var requests = []; for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } @@ -35,7 +33,6 @@ void main() { test("a blocked resource is allocated when another is released", () { new FakeAsync().run((async) { var pool = new Pool(50); - var requests = []; for (var i = 0; i < 49; i++) { expect(pool.request(), completes); } @@ -57,7 +54,6 @@ void main() { group("withResource()", () { test("can be called freely up to the limit", () { var pool = new Pool(50); - var requests = []; for (var i = 0; i < 50; i++) { pool.withResource(expectAsync(() => new Completer().future)); } @@ -66,7 +62,6 @@ void main() { test("blocks the callback past the limit", () { new FakeAsync().run((async) { var pool = new Pool(50); - var requests = []; for (var i = 0; i < 50; i++) { pool.withResource(expectAsync(() => new Completer().future)); } @@ -79,15 +74,14 @@ void main() { test("a blocked resource is allocated when another is released", () { new FakeAsync().run((async) { var pool = new Pool(50); - var requests = []; for (var i = 0; i < 49; i++) { pool.withResource(expectAsync(() => new Completer().future)); } var completer = new Completer(); - var lastAllocatedResource = pool.withResource(() => completer.future); + pool.withResource(() => completer.future); var blockedResourceAllocated = false; - var blockedResource = pool.withResource(() { + pool.withResource(() { blockedResourceAllocated = true; }); @@ -151,7 +145,7 @@ void main() { async.elapse(new Duration(seconds: 6)); }); - }); + }); test("times out if nothing happens", () { new FakeAsync().run((async) { @@ -163,7 +157,7 @@ void main() { async.elapse(new Duration(seconds: 6)); }); - }); + }); }); } @@ -172,20 +166,18 @@ void main() { /// This should only be called within a [FakeAsync.run] zone. Function expectNoAsync() { var stack = new Trace.current(1); - return () => handleExternalError( - new TestFailure("Expected function not to be called."), "", - stack); + return () => registerException( + new TestFailure("Expected function not to be called."), stack); } /// A matcher for Futures that asserts that they don't complete. /// /// This should only be called within a [FakeAsync.run] zone. Matcher get doesNotComplete => predicate((future) { - expect(future, new isInstanceOf('Future')); + expect(future, new isInstanceOf()); var stack = new Trace.current(1); - future.then((_) => handleExternalError( - new TestFailure("Expected future not to complete."), "", - stack)); + future.then((_) => registerException( + new TestFailure("Expected future not to complete."), stack)); return true; }); From 86bdf0d68704a0204e29a8dcffa858529e60247c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 May 2015 19:28:28 -0700 Subject: [PATCH 095/657] fix status files TBR --- pkgs/pool/.status | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pkgs/pool/.status b/pkgs/pool/.status index e9f2b0049..ff095a2f7 100644 --- a/pkgs/pool/.status +++ b/pkgs/pool/.status @@ -1,3 +1,15 @@ # Copyright (c) 2014, 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. + +# Skip non-test files ending with "_test". +packages/*: Skip +*/packages/*: Skip +*/*/packages/*: Skip +*/*/*/packages/*: Skip +*/*/*/*packages/*: Skip +*/*/*/*/*packages/*: Skip + +# Only run tests from the build directory, since we don't care about the +# difference between transformed an untransformed code. +test/*: Skip From 2cb76b9e3c719b789acfdff9cefcea6b63425855 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Tue, 26 May 2015 11:26:32 +0200 Subject: [PATCH 096/657] Add more tests Review URL: https://codereview.chromium.org//1152173005 --- pkgs/package_config/lib/discovery.dart | 6 +- .../package_config/lib/src/packages_impl.dart | 2 +- pkgs/package_config/test/all.dart | 4 +- pkgs/package_config/test/discovery_test.dart | 281 ++++++++++++++++++ 4 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 pkgs/package_config/test/discovery_test.dart diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 78254eeba..52f208d81 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -44,9 +44,9 @@ Future findPackages( if (baseUri.scheme == "file") { return new Future.sync(() => findPackagesFromFile(baseUri)); } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { - return findPackagesFromNonFile(baseUri, _httpGet); + return findPackagesFromNonFile(baseUri, loader: _httpGet); } else if (loader != null) { - return findPackagesFromNonFile(baseUri, loader); + return findPackagesFromNonFile(baseUri, loader: loader); } else { return new Future.value(Packages.noPackages); } @@ -138,7 +138,7 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// of the requestsed `.packages` file as bytes, which will be assumed to be /// UTF-8 encoded. Future findPackagesFromNonFile(Uri nonFileUri, - [Future> loader(Uri name)]) { + {Future> loader(Uri name)}) { if (loader == null) loader = _httpGet; Uri packagesFileUri = nonFileUri.resolve(".packages"); return loader(packagesFileUri).then((List fileBytes) { diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index 612dc347d..956376275 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -70,7 +70,7 @@ class FilePackagesDirectoryPackages extends _PackagesBase { FilePackagesDirectoryPackages(this._packageDir); Uri _getBase(String packageName) => - new Uri.directory(path.join(packageName,'')); + new Uri.directory(path.join(_packageDir.path, packageName, '')); Iterable _listPackageNames() { return _packageDir.listSync() diff --git a/pkgs/package_config/test/all.dart b/pkgs/package_config/test/all.dart index 310e1ee43..79f5b3574 100644 --- a/pkgs/package_config/test/all.dart +++ b/pkgs/package_config/test/all.dart @@ -2,8 +2,10 @@ // 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 'parse_test.dart' as parse; +import "discovery_test.dart" as discovery; +import "parse_test.dart" as parse; main() { parse.main(); + discovery.main(); } diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart new file mode 100644 index 000000000..4a88928e2 --- /dev/null +++ b/pkgs/package_config/test/discovery_test.dart @@ -0,0 +1,281 @@ +// Copyright (c) 2015, 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 "dart:async"; +import "dart:io"; +import "package:test/test.dart"; +import "package:package_config/packages.dart"; +import "package:package_config/discovery.dart"; +import "package:path/path.dart" as path; + +const packagesFile = """ +# A comment +foo=file:///dart/packages/foo/ +bar=http://example.com/dart/packages/bar/ +baz=packages/baz/ +"""; + +void validatePackagesFile(Packages resolver, Uri location) { + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); +} + +void validatePackagesDir(Packages resolver, Uri location) { + // Expect three packages: foo, bar and baz + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(location.resolve("packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(location.resolve("packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + if (location.scheme == "file") { + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); + } else { + expect(() => resolver.packages, throws); + } +} + + +Uri pkg(String packageName, String packagePath) { + var path; + if (packagePath.startsWith('/')) { + path = "$packageName$packagePath"; + } else { + path = "$packageName/$packagePath"; + } + return new Uri(scheme: "package", path: path); +} + +main() { + generalTest(".packages", + {".packages": packagesFile, + "script.dart": "main(){}", + "packages": {"shouldNotBeFound": {}}}, + (Uri location) async { + Packages resolver; + resolver = await findPackages(location); + validatePackagesFile(resolver, location); + resolver = await findPackages(location.resolve("script.dart")); + validatePackagesFile(resolver, location); + var specificDiscovery = (location.scheme == "file") + ? findPackagesFromFile + : findPackagesFromNonFile; + resolver = await specificDiscovery(location); + validatePackagesFile(resolver, location); + resolver = await specificDiscovery(location.resolve("script.dart")); + validatePackagesFile(resolver, location); + }); + + generalTest("packages/", + {"packages": { "foo": {}, "bar": {}, "baz": {}}, + "script.dart": "main(){}"}, + (Uri location) async { + Packages resolver; + bool isFile = (location.scheme == "file"); + resolver = await findPackages(location); + validatePackagesDir(resolver, location); + resolver = await findPackages(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + var specificDiscovery = isFile + ? findPackagesFromFile + : findPackagesFromNonFile; + resolver = await specificDiscovery(location); + validatePackagesDir(resolver, location); + resolver = await specificDiscovery(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + }); + + fileTest(".packages recursive", + {".packages": packagesFile, "subdir": {"script.dart": "main(){}"}}, + (Uri location) async { + Packages resolver; + resolver = await findPackages(location.resolve("subdir/")); + validatePackagesFile(resolver, location); + resolver = await findPackages(location.resolve("subdir/script.dart")); + validatePackagesFile(resolver, location); + resolver = await findPackagesFromFile(location.resolve("subdir/")); + validatePackagesFile(resolver, location); + resolver = + await findPackagesFromFile(location.resolve("subdir/script.dart")); + validatePackagesFile(resolver, location); + }); + + httpTest(".packages not recursive", + {".packages": packagesFile, "subdir": {"script.dart": "main(){}"}}, + (Uri location) async { + Packages resolver; + var subdir = location.resolve("subdir/"); + resolver = await findPackages(subdir); + validatePackagesDir(resolver, subdir); + resolver = await findPackages(subdir.resolve("script.dart")); + validatePackagesDir(resolver, subdir); + resolver = await findPackagesFromNonFile(subdir); + validatePackagesDir(resolver, subdir); + resolver = await findPackagesFromNonFile(subdir.resolve("script.dart")); + validatePackagesDir(resolver, subdir); + }); + + fileTest("no packages", + {"script.dart": "main(){}"}, + (Uri location) async { + // A file: location with no .packages or packages returns + // Packages.noPackages. + Packages resolver; + resolver = await findPackages(location); + expect(resolver, same(Packages.noPackages)); + resolver = await findPackages(location.resolve("script.dart")); + expect(resolver, same(Packages.noPackages)); + resolver = findPackagesFromFile(location); + expect(resolver, same(Packages.noPackages)); + resolver = findPackagesFromFile(location.resolve("script.dart")); + expect(resolver, same(Packages.noPackages)); + }); + + httpTest("no packages", + {"script.dart": "main(){}"}, + (Uri location) async { + // A non-file: location with no .packages or packages/: + // Assumes a packages dir exists, and resolves relative to that. + Packages resolver; + resolver = await findPackages(location); + validatePackagesDir(resolver, location); + resolver = await findPackages(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + }); + + test(".packages w/ loader", () async { + Uri location = Uri.parse("krutch://example.com/path/"); + Future loader(Uri file) async { + if (file.path.endsWith(".packages")) { + return packagesFile.codeUnits; + } + throw "not found"; + } + // A non-file: location with no .packages or packages/: + // Assumes a packages dir exists, and resolves relative to that. + Packages resolver; + resolver = await findPackages(location, loader: loader); + validatePackagesFile(resolver, location); + resolver = await findPackages(location.resolve("script.dart"), + loader: loader); + validatePackagesFile(resolver, location); + resolver = await findPackagesFromNonFile(location, loader: loader); + validatePackagesFile(resolver, location); + resolver = await findPackagesFromNonFile(location.resolve("script.dart"), + loader: loader); + validatePackagesFile(resolver, location); + }); + + test("no packages w/ loader", () async { + Uri location = Uri.parse("krutch://example.com/path/"); + Future loader(Uri file) async { + throw "not found"; + } + // A non-file: location with no .packages or packages/: + // Assumes a packages dir exists, and resolves relative to that. + Packages resolver; + resolver = await findPackages(location, loader: loader); + validatePackagesDir(resolver, location); + resolver = await findPackages(location.resolve("script.dart"), + loader: loader); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location, loader: loader); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location.resolve("script.dart"), + loader:loader); + validatePackagesDir(resolver, location); + }); +} + +/// Create a directory structure from [description] and run [fileTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a sub-dir, otherwise it's a file and the value is the content +/// as a string. +void fileTest(String name, + Map description, + Future fileTest(Uri directory)) { + group("file-test", () { + Directory tempDir = Directory.systemTemp.createTempSync("file-test"); + setUp(() { + _createFiles(tempDir, description); + }); + tearDown(() { + tempDir.deleteSync(recursive: true); + }); + test(name, () => fileTest(new Uri.directory(tempDir.path))); + }); +} + +/// HTTP-server the directory structure from [description] and run [htpTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a sub-dir, otherwise it's a file and the value is the content +/// as a string. +void httpTest(String name, Map description, Future httpTest(Uri directory)) { + group("http-test", () { + var serverSub; + var uri; + setUp(() { + return HttpServer + .bind(InternetAddress.LOOPBACK_IP_V4, 0) + .then((server) { + uri = new Uri(scheme: "http", + host: "127.0.0.1", + port: server.port, + path: "/"); + serverSub = server.listen((HttpRequest request) { + // No error handling. + var path = request.uri.path; + if (path.startsWith('/')) path = path.substring(1); + if (path.endsWith('/')) path = path.substring(0, path.length - 1); + var parts = path.split('/'); + var fileOrDir = description; + for (int i = 0; i < parts.length; i++) { + fileOrDir = fileOrDir[parts[i]]; + if (fileOrDir == null) { + request.response.statusCode = 404; + request.response.close(); + } + } + request.response.write(fileOrDir); + request.response.close(); + }); + }); + }); + tearDown(() => serverSub.cancel()); + test(name, () => httpTest(uri)); + }); +} + +void generalTest(String name, Map description, Future action(Uri location)) { + fileTest(name, description, action); + httpTest(name, description, action); +} + +void _createFiles(Directory target, Map description) { + description.forEach((name, content) { + if (content is Map) { + Directory subDir = new Directory(path.join(target.path, name)); + subDir.createSync(); + _createFiles(subDir, content); + } else { + File file = new File(path.join(target.path, name)); + file.writeAsStringSync(content, flush: true); + } + }); +} + + From f3bbc021c17b6b70a2d772d5976c9a76e1be7438 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Tue, 26 May 2015 12:48:53 -0700 Subject: [PATCH 097/657] Badge update. (Fix dart-lang/package_config#7.) --- pkgs/package_config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 140c3c4f9..1437e31c1 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -4,7 +4,7 @@ Support for working with **Package Resolution Configuration** files as described in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), under review [here] (https://github.com/dart-lang/dart_enhancement_proposals/issues/5). -[![Build Status](https://travis-ci.org/dart-lang/package_config.svg)](https://travis-ci.org/dart-lang/linter) +[![Build Status](https://travis-ci.org/dart-lang/package_config.svg)](https://travis-ci.org/dart-lang/package_config) ## Features and bugs From 45aa4d5882b64c3b5b2602c50fd17eda39f25e9b Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Tue, 26 May 2015 12:50:09 -0700 Subject: [PATCH 098/657] Travis badge teak (point to master). --- pkgs/package_config/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 1437e31c1..42ae1e99b 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -4,8 +4,7 @@ Support for working with **Package Resolution Configuration** files as described in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), under review [here] (https://github.com/dart-lang/dart_enhancement_proposals/issues/5). -[![Build Status](https://travis-ci.org/dart-lang/package_config.svg)](https://travis-ci.org/dart-lang/package_config) - +[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) ## Features and bugs From 3c2c5f5434f021d98c0524eaaa2c435ba8693700 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 27 May 2015 12:46:11 -0700 Subject: [PATCH 099/657] Update travis.sh --- pkgs/package_config/tool/travis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/tool/travis.sh b/pkgs/package_config/tool/travis.sh index 82423816b..6d8cfe375 100755 --- a/pkgs/package_config/tool/travis.sh +++ b/pkgs/package_config/tool/travis.sh @@ -9,7 +9,7 @@ set -e # Verify that the libraries are error free. dartanalyzer --fatal-warnings \ - lib/packagemap.dart \ + lib/packages.dart \ test/all.dart # Run the tests. From 385d634284979e23f127b376c190fc5463cce761 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 27 May 2015 13:01:50 -0700 Subject: [PATCH 100/657] Build fix. [TBR] (Fix dart-lang/package_config#9) --- pkgs/package_config/lib/src/packages_impl.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index 956376275..6d88a65a0 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -21,7 +21,7 @@ class NoPackages implements Packages { 'No package named "$packageName"'); } - Iterable get packages => new Iterable.empty(); + Iterable get packages => new Iterable.generate(0); Map asMap() => const{}; } From fd1d37d5ba2e444804436148025fe814824f124c Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 28 May 2015 10:00:52 -0700 Subject: [PATCH 101/657] Version bump. Bump to tag package discovery logic. --- pkgs/package_config/pubspec.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 27af78ecd..36daf6f84 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.1 +version: 0.0.2 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config @@ -9,8 +9,8 @@ environment: dependencies: charcode: '^1.1.0' - path: "any" - http: "any" + path: 'any' + http: 'any' dev_dependencies: test: '>=0.12.0 <0.13.0' From 860fa65be9122e4c2e73f11437ef21968726a26a Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 28 May 2015 10:09:50 -0700 Subject: [PATCH 102/657] Constraint cleanup. --- pkgs/package_config/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 36daf6f84..0efb23f22 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -9,8 +9,8 @@ environment: dependencies: charcode: '^1.1.0' - path: 'any' - http: 'any' + http: '^0.11.2' + path: '>=1.0.0 <2.0.0' dev_dependencies: test: '>=0.12.0 <0.13.0' From 2e49f23243aba94882c4ecce75ca6aaadfe4daa8 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 28 May 2015 10:55:08 -0700 Subject: [PATCH 103/657] Package badge. --- pkgs/package_config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 42ae1e99b..9a0995d6b 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -4,7 +4,7 @@ Support for working with **Package Resolution Configuration** files as described in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), under review [here] (https://github.com/dart-lang/dart_enhancement_proposals/issues/5). -[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) +[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](http://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) ## Features and bugs From 58cc2fe7943ad73cd61d323b02e3198715dfe994 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 28 May 2015 13:06:55 -0700 Subject: [PATCH 104/657] Widen http version constraint. (Required for constraint solving in the SDK build.) --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 0efb23f22..4a3123e6d 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -9,7 +9,7 @@ environment: dependencies: charcode: '^1.1.0' - http: '^0.11.2' + http: '^0.11.0' path: '>=1.0.0 <2.0.0' dev_dependencies: From f04393798e722151745e8cf2f3126e20531f8bd4 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 28 May 2015 13:08:20 -0700 Subject: [PATCH 105/657] Update pubspec.yaml --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 4a3123e6d..5bda6ffae 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.2 +version: 0.0.2+1 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From ffabb77477e3f6cf27c8e0af354a01a7f6a3b7e0 Mon Sep 17 00:00:00 2001 From: pq Date: Thu, 28 May 2015 13:36:25 -0700 Subject: [PATCH 106/657] Inline normalizePath to make observatory happy. --- pkgs/package_config/lib/packages_file.dart | 7 +++++-- pkgs/package_config/lib/src/packages_impl.dart | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 48c2334e0..03b37b649 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -147,12 +147,12 @@ Uri _relativize(Uri uri, Uri baseUri) { } } - baseUri = baseUri.normalizePath(); + baseUri = _normalizePath(baseUri); List base = baseUri.pathSegments.toList(); if (base.isNotEmpty) { base = new List.from(base)..removeLast(); } - uri = uri.normalizePath(); + uri = _normalizePath(uri); List target = uri.pathSegments.toList(); int index = 0; while (index < base.length && index < target.length) { @@ -170,3 +170,6 @@ Uri _relativize(Uri uri, Uri baseUri) { return uri; } } + +// TODO: inline to uri.normalizePath() when we move to 1.11 +Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index 6d88a65a0..880b9db1f 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -33,7 +33,7 @@ class NoPackages implements Packages { /// member abstract class _PackagesBase implements Packages { Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { - packageUri = packageUri.normalizePath(); + packageUri = _normalizePath(packageUri); String packageName = checkValidPackageUri(packageUri); Uri packageBase = _getBase(packageName); if (packageBase == null) { @@ -50,6 +50,9 @@ abstract class _PackagesBase implements Packages { /// Returns `null` if no package exists with that name, and that can be /// determined. Uri _getBase(String packageName); + + // TODO: inline to uri.normalizePath() when we move to 1.11 + static Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); } /// A [Packages] implementation based on an existing map. From a7722c1554c8208f6896feb4046340e98d109061 Mon Sep 17 00:00:00 2001 From: pq Date: Thu, 28 May 2015 13:38:18 -0700 Subject: [PATCH 107/657] Version bump. --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 5bda6ffae..20494b9f6 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.2+1 +version: 0.0.2+2 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From de64d3dd23f9ff40b4d165d9c984ddb45dfd6ab0 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Thu, 28 May 2015 15:58:43 -0700 Subject: [PATCH 108/657] Don't use Uri.directory --- pkgs/package_config/lib/discovery.dart | 4 ++-- pkgs/package_config/lib/packages.dart | 2 +- pkgs/package_config/lib/packages_file.dart | 2 +- pkgs/package_config/lib/src/packages_impl.dart | 6 +++--- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/discovery_test.dart | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 52f208d81..f298a0afe 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -101,7 +101,7 @@ FileSystemEntity _findPackagesFile(String workingDirectory) { /// a `packages/` directory in the same place. /// If that also fails, it starts checking parent directories for a `.packages` /// file, and stops if it finds it. -/// Otherwise it gives up and returns [Pacakges.noPackages]. +/// Otherwise it gives up and returns [Packages.noPackages]. Packages findPackagesFromFile(Uri fileBaseUri) { Uri baseDirectoryUri = fileBaseUri; if (!fileBaseUri.path.endsWith('/')) { @@ -135,7 +135,7 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// By default, this function only works for `http:` and `https:` URIs. /// To support other schemes, a loader must be provided, which is used to /// try to load the `.packages` file. The loader should return the contents -/// of the requestsed `.packages` file as bytes, which will be assumed to be +/// of the requested `.packages` file as bytes, which will be assumed to be /// UTF-8 encoded. Future findPackagesFromNonFile(Uri nonFileUri, {Future> loader(Uri name)}) { diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart index 8523ecc28..3fba062f5 100644 --- a/pkgs/package_config/lib/packages.dart +++ b/pkgs/package_config/lib/packages.dart @@ -57,7 +57,7 @@ abstract class Packages { /// for the existence of a `.packages` file. If one is found, it is loaded /// just as in the first step. /// * If no file is found before reaching the file system root, - /// the constant [noPacakages] is returned. It's a `Packages` object + /// the constant [noPackages] is returned. It's a `Packages` object /// with no available packages. /// static Future find(Uri baseLocation) => findPackages(baseLocation); diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 03b37b649..2228cb3f0 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -10,7 +10,7 @@ import "src/util.dart" show isIdentifier; /// Parses a `.packages` file into a map from package name to base URI. /// /// The [source] is the byte content of a `.packages` file, assumed to be -/// UTF-8 encoded. In practice, all sinficant parts of the file must be ASCII, +/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII, /// so Latin-1 or Windows-1252 encoding will also work fine. /// /// If the file content is available as a string, its [String.codeUnits] can diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index 880b9db1f..645d76525 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -50,9 +50,9 @@ abstract class _PackagesBase implements Packages { /// Returns `null` if no package exists with that name, and that can be /// determined. Uri _getBase(String packageName); - + // TODO: inline to uri.normalizePath() when we move to 1.11 - static Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); + static Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); } /// A [Packages] implementation based on an existing map. @@ -73,7 +73,7 @@ class FilePackagesDirectoryPackages extends _PackagesBase { FilePackagesDirectoryPackages(this._packageDir); Uri _getBase(String packageName) => - new Uri.directory(path.join(_packageDir.path, packageName, '')); + new Uri.file(path.join(_packageDir.path, packageName, '.')); Iterable _listPackageNames() { return _packageDir.listSync() diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 20494b9f6..2a84d20c4 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.2+2 +version: 0.0.2+3 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 4a88928e2..16bdd267b 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -215,7 +215,7 @@ void fileTest(String name, tearDown(() { tempDir.deleteSync(recursive: true); }); - test(name, () => fileTest(new Uri.directory(tempDir.path))); + test(name, () => fileTest(new Uri.file(path.join(tempDir.path, ".")))); }); } From 95ebf31911fe8621cddbd3d504535f7c77c04eb3 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Thu, 28 May 2015 18:04:07 -0700 Subject: [PATCH 109/657] Allow "_" as the first char in a package name --- pkgs/package_config/lib/src/util.dart | 2 +- pkgs/package_config/test/discovery_test.dart | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 76bd1d6e5..abf1d52f0 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -11,7 +11,7 @@ import "package:charcode/ascii.dart"; bool isIdentifier(String string) { if (string.isEmpty) return false; int firstChar = string.codeUnitAt(0); - int firstCharLower = firstChar |= 0x20; + int firstCharLower = firstChar | 0x20; if (firstCharLower < $a || firstCharLower > $z) { if (firstChar != $_ && firstChar != $$) return false; } diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 16bdd267b..16544e43d 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -93,6 +93,14 @@ main() { validatePackagesDir(resolver, location); }); + generalTest("underscore packages", + {"packages": {"_foo": {}}}, + (Uri location) async { + Packages resolver = await findPackages(location); + expect(resolver.resolve(pkg("_foo", "foo.dart")), + equals(location.resolve("packages/_foo/foo.dart"))); + }); + fileTest(".packages recursive", {".packages": packagesFile, "subdir": {"script.dart": "main(){}"}}, (Uri location) async { From 8fee1b417ab070010ca15dd619cc462a01443f53 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Fri, 29 May 2015 09:58:04 -0700 Subject: [PATCH 110/657] Bump version to 0.0.2+4 --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 2a84d20c4..aca9c836c 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.2+3 +version: 0.0.2+4 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From 8de7c1064f9f124d520479f2a8be6b64507d399b Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Fri, 29 May 2015 09:58:04 -0700 Subject: [PATCH 111/657] Separate out VM dependencies. The Packages interface class should not depend on a platform specific library (dart:io). This removed the dependency, and also splits the implementation classes into those that are generally applicable and those that requite dart:io to operate (the "local packages directory" which allows iterating the package names by scanning the directory). Bump version to 0.0.2+4 --- pkgs/package_config/lib/discovery.dart | 1 + pkgs/package_config/lib/packages.dart | 38 --------------- .../package_config/lib/src/packages_impl.dart | 47 ++++--------------- .../lib/src/packages_io_impl.dart | 37 +++++++++++++++ pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/parse_test.dart | 3 +- 6 files changed, 51 insertions(+), 77 deletions(-) create mode 100644 pkgs/package_config/lib/src/packages_io_impl.dart diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index f298a0afe..f8e45d491 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -11,6 +11,7 @@ import "package:http/http.dart" as http; import "packages.dart"; import "packages_file.dart" as pkgfile show parse; import "src/packages_impl.dart"; +import "src/packages_io_impl.dart"; /// Discover the package configuration for a Dart script. /// diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart index 3fba062f5..dbaa06dfd 100644 --- a/pkgs/package_config/lib/packages.dart +++ b/pkgs/package_config/lib/packages.dart @@ -4,8 +4,6 @@ library package_config.packages; -import "dart:async" show Future; -import "discovery.dart" show findPackages; import "src/packages_impl.dart"; /// A package resolution strategy. @@ -26,42 +24,6 @@ abstract class Packages { /// package resolution strategy is found. static const Packages noPackages = const NoPackages(); - /// Create a `Packages` object based on a map from package name to base URI. - /// - /// The resulting `Packages` object will resolve package URIs by using this - /// map. - /// There is no validation of the map containing only valid package names, - factory Packages(Map packageMapping) => - new MapPackages(packageMapping); - - /// Attempts to find a package resolution strategy for a Dart script. - /// - /// The [baseLocation] should point to a Dart script or to its directory. - /// The function goes through the following steps in order to search for - /// a packages resolution strategy: - /// - /// * First check if a `.packages` file in the script's directory. - /// If a file is found, its content is loaded and interpreted as a map - /// from package names to package location URIs. - /// If loading or parsing of the file fails, so does this function. - /// * Then if `baseLocation` is not a `file:` URI, - /// assume that a `packages/` directory exists in the script's directory, - /// and return a `Packages` object that resolves package URIs as - /// paths into that directory. - /// * If `baseLocation` is a `file:` URI, instead *check* whether - /// a `packages/` directory exists in the script directory. - /// If it does, return a `Packages` object that resolves package URIs - /// as paths into that directory. This `Packages` object is able to - /// read the directory and see which packages are available. - /// * Otherwise, check each directory in the parent path of `baseLocation` - /// for the existence of a `.packages` file. If one is found, it is loaded - /// just as in the first step. - /// * If no file is found before reaching the file system root, - /// the constant [noPackages] is returned. It's a `Packages` object - /// with no available packages. - /// - static Future find(Uri baseLocation) => findPackages(baseLocation); - /// Resolve a package URI into a non-package URI. /// /// Translates a `package:` URI, according to the package resolution diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index 645d76525..e85f75581 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -2,11 +2,12 @@ // 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. +/// Implementations of [Packages] that may be used in either server or browser +/// based applications. For implementations that can only run in the browser, +/// see [package_config.packages_io_impl]. library package_config.packages_impl; import "dart:collection" show UnmodifiableMapView; -import "dart:io" show Directory; -import "package:path/path.dart" as path; import "../packages.dart"; import "util.dart" show checkValidPackageUri; @@ -26,16 +27,15 @@ class NoPackages implements Packages { Map asMap() => const{}; } - /// Base class for [Packages] implementations. /// /// This class implements the [resolve] method in terms of a private /// member -abstract class _PackagesBase implements Packages { +abstract class PackagesBase implements Packages { Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { packageUri = _normalizePath(packageUri); String packageName = checkValidPackageUri(packageUri); - Uri packageBase = _getBase(packageName); + Uri packageBase = getBase(packageName); if (packageBase == null) { if (notFound != null) return notFound(packageUri); throw new ArgumentError.value(packageUri, "packageUri", @@ -49,61 +49,34 @@ abstract class _PackagesBase implements Packages { /// /// Returns `null` if no package exists with that name, and that can be /// determined. - Uri _getBase(String packageName); + Uri getBase(String packageName); // TODO: inline to uri.normalizePath() when we move to 1.11 static Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); } /// A [Packages] implementation based on an existing map. -class MapPackages extends _PackagesBase { +class MapPackages extends PackagesBase { final Map _mapping; MapPackages(this._mapping); - Uri _getBase(String packageName) => _mapping[packageName]; + Uri getBase(String packageName) => _mapping[packageName]; Iterable get packages => _mapping.keys; Map asMap() => new UnmodifiableMapView(_mapping); } -/// A [Packages] implementation based on a local directory. -class FilePackagesDirectoryPackages extends _PackagesBase { - final Directory _packageDir; - FilePackagesDirectoryPackages(this._packageDir); - - Uri _getBase(String packageName) => - new Uri.file(path.join(_packageDir.path, packageName, '.')); - - Iterable _listPackageNames() { - return _packageDir.listSync() - .where((e) => e is Directory) - .map((e) => path.basename(e.path)); - } - - Iterable get packages { - return _listPackageNames(); - } - - Map asMap() { - var result = {}; - for (var packageName in _listPackageNames()) { - result[packageName] = _getBase(packageName); - } - return new UnmodifiableMapView(result); - } -} - /// A [Packages] implementation based on a remote (e.g., HTTP) directory. /// /// There is no way to detect which packages exist short of trying to use /// them. You can't necessarily check whether a directory exists, /// except by checking for a know file in the directory. -class NonFilePackagesDirectoryPackages extends _PackagesBase { +class NonFilePackagesDirectoryPackages extends PackagesBase { final Uri _packageBase; NonFilePackagesDirectoryPackages(this._packageBase); - Uri _getBase(String packageName) => _packageBase.resolve("$packageName/"); + Uri getBase(String packageName) => _packageBase.resolve("$packageName/"); Error _failListingPackages() { return new UnsupportedError( diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart new file mode 100644 index 000000000..21b61fdab --- /dev/null +++ b/pkgs/package_config/lib/src/packages_io_impl.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2015, 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. + +/// Implementations of [Packages] that can only be used in server based +/// applications. +library package_config.packages_io_impl; + +import "dart:collection" show UnmodifiableMapView; +import "dart:io" show Directory; +import "package:path/path.dart" as path; +import "packages_impl.dart"; + +/// A [Packages] implementation based on a local directory. +class FilePackagesDirectoryPackages extends PackagesBase { + final Directory _packageDir; + FilePackagesDirectoryPackages(this._packageDir); + + Uri getBase(String packageName) => + new Uri.file(path.join(_packageDir.path, packageName, '.')); + + Iterable _listPackageNames() { + return _packageDir.listSync() + .where((e) => e is Directory) + .map((e) => path.basename(e.path)); + } + + Iterable get packages => _listPackageNames(); + + Map asMap() { + var result = {}; + for (var packageName in _listPackageNames()) { + result[packageName] = getBase(packageName); + } + return new UnmodifiableMapView(result); + } +} diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index aca9c836c..338aab5bf 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.2+4 +version: 0.0.3 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index f7f68f10d..ddd8ff6ca 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -6,6 +6,7 @@ library test_all; import "package:package_config/packages.dart"; import "package:package_config/packages_file.dart" show parse; +import "package:package_config/src/packages_impl.dart"; import "package:test/test.dart"; main() { @@ -123,7 +124,7 @@ main() { Packages doParse(String sample, Uri baseUri) { Map map = parse(sample.codeUnits, baseUri); - return new Packages(map); + return new MapPackages(map); } // Valid samples. From b3a31b68e0b61e0546f2448ec34f2118305b91d8 Mon Sep 17 00:00:00 2001 From: Harry Terkelsen Date: Thu, 4 Jun 2015 13:50:22 -0700 Subject: [PATCH 112/657] Remove dependency on http package BUG= Review URL: https://codereview.appspot.com/243950044 --- pkgs/package_config/lib/discovery.dart | 42 +++++++++++++++++++------- pkgs/package_config/pubspec.lock | 4 --- pkgs/package_config/pubspec.yaml | 3 +- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index f8e45d491..0dd7f5508 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -5,9 +5,11 @@ library package_config.discovery; import "dart:async"; -import "dart:io" show Directory, File, FileSystemEntity; +import "dart:io"; +import "dart:typed_data" show Uint8List; + import "package:path/path.dart" as path; -import "package:http/http.dart" as http; + import "packages.dart"; import "packages_file.dart" as pkgfile show parse; import "src/packages_impl.dart"; @@ -39,8 +41,7 @@ import "src/packages_io_impl.dart"; /// It must return the *contents* of the file identified by the URI it's given, /// which should be a UTF-8 encoded `.packages` file, and must return an /// error future if loading fails for any reason. -Future findPackages( - Uri baseUri, +Future findPackages(Uri baseUri, {Future> loader(Uri unsupportedUri)}) { if (baseUri.scheme == "file") { return new Future.sync(() => findPackagesFromFile(baseUri)); @@ -113,8 +114,8 @@ Packages findPackagesFromFile(Uri fileBaseUri) { if (location == null) return Packages.noPackages; if (location is File) { List fileBytes = location.readAsBytesSync(); - Map map = pkgfile.parse(fileBytes, - new Uri.file(location.path)); + Map map = + pkgfile.parse(fileBytes, new Uri.file(location.path)); return new MapPackages(map); } assert(location is Directory); @@ -139,7 +140,7 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// of the requested `.packages` file as bytes, which will be assumed to be /// UTF-8 encoded. Future findPackagesFromNonFile(Uri nonFileUri, - {Future> loader(Uri name)}) { + {Future> loader(Uri name)}) { if (loader == null) loader = _httpGet; Uri packagesFileUri = nonFileUri.resolve(".packages"); return loader(packagesFileUri).then((List fileBytes) { @@ -152,10 +153,29 @@ Future findPackagesFromNonFile(Uri nonFileUri, }); } -/// Fetches a file using the http library. +/// Fetches a file over http. Future> _httpGet(Uri uri) { - return http.get(uri).then((http.Response response) { - if (response.statusCode == 200) return response.bodyBytes; - throw 0; // The error message isn't being used for anything. + HttpClient client = new HttpClient(); + return client + .getUrl(uri) + .then((HttpClientRequest request) => request.close()) + .then((HttpClientResponse response) { + if (response.statusCode != HttpStatus.OK) { + String msg = 'Failure getting $uri: ' + '${response.statusCode} ${response.reasonPhrase}'; + throw msg; + } + return response.toList(); + }).then((List> splitContent) { + int totalLength = splitContent.fold(0, (int old, List list) { + return old + list.length; + }); + Uint8List result = new Uint8List(totalLength); + int offset = 0; + for (List contentPart in splitContent) { + result.setRange(offset, offset + contentPart.length, contentPart); + offset += contentPart.length; + } + return result; }); } diff --git a/pkgs/package_config/pubspec.lock b/pkgs/package_config/pubspec.lock index 708d89157..5cae00509 100644 --- a/pkgs/package_config/pubspec.lock +++ b/pkgs/package_config/pubspec.lock @@ -25,10 +25,6 @@ packages: description: crypto source: hosted version: "0.9.0" - http: - description: http - source: hosted - version: "0.11.2" http_parser: description: http_parser source: hosted diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 338aab5bf..5eca33065 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.3 +version: 0.0.3+1 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config @@ -9,7 +9,6 @@ environment: dependencies: charcode: '^1.1.0' - http: '^0.11.0' path: '>=1.0.0 <2.0.0' dev_dependencies: From 53cf751c437cf72d51211e1a5b7a3643e86c66b2 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 10 Jun 2015 09:27:28 +0200 Subject: [PATCH 113/657] Initial approach to discovering package resolution for directory tree. R=brianwilkerson@google.com, pquitslund@google.com Review URL: https://codereview.chromium.org//1169513002. --- .../lib/discovery_analysis.dart | 167 ++++++++++++++++++ pkgs/package_config/pubspec.yaml | 2 +- .../test/discovery_analysis_test.dart | 122 +++++++++++++ 3 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 pkgs/package_config/lib/discovery_analysis.dart create mode 100644 pkgs/package_config/test/discovery_analysis_test.dart diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart new file mode 100644 index 000000000..f3bcac68e --- /dev/null +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -0,0 +1,167 @@ +// Copyright (c) 2015, 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. + +/// Analyse a directory structure and find packages resolvers for each +/// sub-directory. +/// +/// The resolvers are generally the same that would be found by using +/// the `discovery.dart` library on each sub-directory in turn, +/// but more efficiently and with some heuristics for directories that +/// wouldn't otherwise have a package resolution strategy, or that are +/// determined to be "package directories" themselves. +library package_config.discovery_analysis; + +import "dart:io" show File, Directory; +import "dart:collection" show HashMap; + +import "package:path/path.dart" as path; + +import "packages.dart"; +import "discovery.dart"; +import "packages_file.dart" as pkgfile; +import "src/packages_impl.dart"; +import "src/packages_io_impl.dart"; + +/// Associates a [Packages] package resolution strategy with a directory. +/// +/// The package resolution applies to the directory and any sub-directory +/// that doesn't have its own overriding child [PackageContext]. +abstract class PackageContext { + /// The directory that introduced the [packages] resolver. + Directory get directory; + + /// A [Packages] resolver that applies to the directory. + /// + /// Introduced either by a `.packages` file or a `packages/` directory. + Packages get packages; + + /// Child contexts that apply to sub-directories of [directory]. + List get children; + + /// Look up the [PackageContext] that applies to a specific directory. + /// + /// The directory must be inside [directory]. + PackageContext operator[](Directory directory); + + /// A map from directory to package resolver. + /// + /// Has an entry for this package context and for each child context + /// contained in this one. + Map asMap(); + + /// Analyze [directory] and sub-directories for package resolution strategies. + /// + /// Returns a mapping from sub-directories to [Packages] objects. + /// + /// The analysis assumes that there are no `.packages` files in a parent + /// directory of `directory`. If there is, its corresponding `Packages` object + /// should be provided as `root`. + static PackageContext findAll(Directory directory, + {Packages root: Packages.noPackages}) { + if (!directory.existsSync()) { + throw new ArgumentError("Directory not found: $directory"); + } + List contexts = []; + void findRoots(Directory directory) { + Packages packages; + List oldContexts; + File packagesFile = new File(path.join(directory.path, ".packages")); + if (packagesFile.existsSync()) { + packages = _loadPackagesFile(packagesFile); + oldContexts = contexts; + contexts = []; + } else { + Directory packagesDir = + new Directory(path.join(directory.path, "packages")); + if (packagesDir.existsSync()) { + packages = new FilePackagesDirectoryPackages(packagesDir); + oldContexts = contexts; + contexts = []; + } + } + for (var entry in directory.listSync()) { + if (entry is Directory) { + if (packages == null || !entry.path.endsWith("/packages")) { + findRoots(entry); + } + } + } + if (packages != null) { + oldContexts.add(new _PackageContext(directory, packages, contexts)); + contexts = oldContexts; + } + } + findRoots(directory); + // If the root is not itself context root, add a the wrapper context. + if (contexts.length == 1 && + contexts[0].directory == directory) { + return contexts[0]; + } + return new _PackageContext(directory, root, contexts); + } +} + +class _PackageContext implements PackageContext { + final Directory directory; + final Packages packages; + final List children; + _PackageContext(this.directory, this.packages, List children) + : children = new List.unmodifiable(children); + + Map asMap() { + var result = new HashMap(); + recurse(_PackageContext current) { + result[current.directory] = current.packages; + for (var child in current.children) { + recurse(child); + } + } + recurse(this); + return result; + } + + PackageContext operator[](Directory directory) { + String path = directory.path; + if (!path.startsWith(this.directory.path)) { + throw new ArgumentError("Not inside $path: $directory"); + } + _PackageContext current = this; + // The current path is know to agree with directory until deltaIndex. + int deltaIndex = current.directory.path.length; + List children = current.children; + int i = 0; + while (i < children.length) { + // TODO(lrn): Sort children and use binary search. + _PackageContext child = children[i]; + String childPath = child.directory.path; + if (_stringsAgree(path, childPath, deltaIndex, childPath.length)) { + deltaIndex = childPath.length; + if (deltaIndex == path.length) { + return child; + } + current = child; + children = current.children; + i = 0; + continue; + } + i++; + } + return current; + } + + static bool _stringsAgree(String a, String b, int start, int end) { + if (a.length < end || b.length < end) return false; + for (int i = start; i < end; i++) { + if (a.codeUnitAt(i) != b.codeUnitAt(i)) return false; + } + return true; + } +} + +Packages _loadPackagesFile(File file) { + var uri = new Uri.file(file.path); + var bytes = file.readAsBytesSync(); + var map = pkgfile.parse(bytes, uri); + return new MapPackages(map); +} diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 5eca33065..0f2735b53 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.3+1 +version: 0.0.4 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/discovery_analysis_test.dart b/pkgs/package_config/test/discovery_analysis_test.dart new file mode 100644 index 000000000..ad007c073 --- /dev/null +++ b/pkgs/package_config/test/discovery_analysis_test.dart @@ -0,0 +1,122 @@ +// Copyright (c) 2015, 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 "dart:async"; +import "dart:io"; + +import "package:package_config/discovery_analysis.dart"; +import "package:package_config/packages.dart"; +import "package:path/path.dart" as path; +import "package:test/test.dart"; + +main() { + fileTest("basic", + {".packages": packagesFile, + "foo": {".packages": packagesFile}, + "bar": {"packages": {"foo": {}, "bar":{}, "baz": {}}}, + "baz": {}}, + (Directory directory) { + var dirUri = new Uri.directory(directory.path); + PackageContext ctx = PackageContext.findAll(directory); + PackagesContext root = ctx[directory]; + expect(root, same(ctx)); + validatePackagesFile(root.packages, dirUri); + var fooDir = sub(directory, "foo"); + PackagesContext foo = ctx[fooDir]; + expect(identical(root, foo), isFalse); + validatePackagesFile(foo.packages, dirUri.resolve("foo/")); + var barDir = sub(directory, "bar"); + PackagesContext bar = ctx[sub(directory, "bar")]; + validatePackagesDir(bar.packages, dirUri.resolve("bar/")); + PackagesContext barbar = ctx[sub(barDir, "bar")]; + expect(barbar, same(bar)); // inherited. + PackagesContext baz = ctx[sub(directory, "baz")]; + expect(baz, same(root)); // inherited. + + var map = ctx.asMap(); + expect(map.keys.map((dir) => dir.path), + unorderedEquals([directory.path, fooDir.path, barDir.path])); + }); +} + +Directory sub(Directory parent, String dirName) { + return new Directory(path.join(parent.path, dirName)); +} + +const packagesFile = """ +# A comment +foo=file:///dart/packages/foo/ +bar=http://example.com/dart/packages/bar/ +baz=packages/baz/ +"""; + +void validatePackagesFile(Packages resolver, Uri location) { + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); +} + +void validatePackagesDir(Packages resolver, Uri location) { + // Expect three packages: foo, bar and baz + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(location.resolve("packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(location.resolve("packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + if (location.scheme == "file") { + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); + } else { + expect(() => resolver.packages, throws); + } +} + +Uri pkg(String packageName, String packagePath) { + var path; + if (packagePath.startsWith('/')) { + path = "$packageName$packagePath"; + } else { + path = "$packageName/$packagePath"; + } + return new Uri(scheme: "package", path: path); +} + +/// Create a directory structure from [description] and run [fileTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a sub-dir, otherwise it's a file and the value is the content +/// as a string. +void fileTest(String name, + Map description, + Future fileTest(Uri directory)) { + group("file-test", () { + Directory tempDir = Directory.systemTemp.createTempSync("file-test"); + setUp(() { + _createFiles(tempDir, description); + }); + tearDown(() { + tempDir.deleteSync(recursive: true); + }); + test(name, () => fileTest(tempDir)); + }); +} + +void _createFiles(Directory target, Map description) { + description.forEach((name, content) { + if (content is Map) { + Directory subDir = new Directory(path.join(target.path, name)); + subDir.createSync(); + _createFiles(subDir, content); + } else { + File file = new File(path.join(target.path, name)); + file.writeAsStringSync(content, flush: true); + } + }); +} From 3fcadf72678f524f6d632c80b643519e5d90cd07 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 10 Jun 2015 09:43:56 +0200 Subject: [PATCH 114/657] Add functions to help with --packages/--package-root command line parameters. R=pquitslund@google.com, sgjesse@google.com Review URL: https://codereview.chromium.org//1166443005. --- pkgs/package_config/lib/discovery.dart | 96 ++++++++++++-------- pkgs/package_config/test/discovery_test.dart | 48 +++++++++- 2 files changed, 106 insertions(+), 38 deletions(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 0dd7f5508..35c3ece7f 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -15,6 +15,55 @@ import "packages_file.dart" as pkgfile show parse; import "src/packages_impl.dart"; import "src/packages_io_impl.dart"; +/// Reads a package resolution file and creates a [Packages] object from it. +/// +/// The [packagesFile] must exist and be loadable. +/// Currently that means the URI must have a `file`, `http` or `https` scheme, +/// and that the file can be loaded and its contents parsed correctly. +/// +/// If the [loader] is provided, it is used to fetch non-`file` URIs, and +/// it can support other schemes or set up more complex HTTP requests. +/// +/// This function can be used to load an explicitly configured package +/// resolution file, for example one specified using a `--packages` +/// command-line parameter. +Future loadPackagesFile(Uri packagesFile, + {Future> loader(Uri uri)}) { + Packages parseBytes(List bytes) { + Map packageMap = pkgfile.parse(bytes, packagesFile); + return new MapPackages(packageMap); + } + if (packagesFile.scheme == "file") { + File file = new File.fromUri(packagesFile); + return file.readAsBytes().then(parseBytes); + } + if (loader == null) { + return http.readBytes(packagesFile).then(parseBytes); + } + return loader(packagesFile).then(parseBytes); +} + + +/// Create a [Packages] object for a package directory. +/// +/// The [packagesDir] URI should refer to a directory. +/// Package names are resolved as relative to sub-directories of the +/// package directory. +/// +/// This function can be used for explicitly configured package directories, +/// for example one specified using a `--package-root` comand-line parameter. +Packages getPackagesDirectory(Uri packagesDir) { + if (packagesDir.scheme == "file") { + Directory directory = new Directory.fromUri(packagesDir); + return new FilePackagesDirectoryPackages(directory); + } + if (!packagesDir.path.endsWith('/')) { + packagesDir = packagesDir.replace(path: packagesDir.path + '/'); + } + return new NonFilePackagesDirectoryPackages(packagesDir); +} + + /// Discover the package configuration for a Dart script. /// /// The [baseUri] points to either the Dart script or its directory. @@ -36,19 +85,21 @@ import "src/packages_io_impl.dart"; /// It needs to be able to load a `.packages` file from the URI, so only /// recognized schemes are accepted. /// -/// To support other schemes, an optional [loader] function can be supplied. -/// It's called to load the `.packages` file for any unsupported scheme. -/// It must return the *contents* of the file identified by the URI it's given, -/// which should be a UTF-8 encoded `.packages` file, and must return an +/// To support other schemes, or more complex HTTP requests, +/// an optional [loader] function can be supplied. +/// It's called to load the `.packages` file for a non-`file` scheme. +/// The loader function returns the *contents* of the file +/// identified by the URI it's given. +/// The content should be a UTF-8 encoded `.packages` file, and must return an /// error future if loading fails for any reason. Future findPackages(Uri baseUri, - {Future> loader(Uri unsupportedUri)}) { + {Future> loader(Uri unsupportedUri)}) { if (baseUri.scheme == "file") { return new Future.sync(() => findPackagesFromFile(baseUri)); - } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { - return findPackagesFromNonFile(baseUri, loader: _httpGet); } else if (loader != null) { return findPackagesFromNonFile(baseUri, loader: loader); + } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { + return findPackagesFromNonFile(baseUri, loader: http.readBytes); } else { return new Future.value(Packages.noPackages); } @@ -140,8 +191,8 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// of the requested `.packages` file as bytes, which will be assumed to be /// UTF-8 encoded. Future findPackagesFromNonFile(Uri nonFileUri, - {Future> loader(Uri name)}) { - if (loader == null) loader = _httpGet; + {Future> loader(Uri name)}) { + if (loader == null) loader = http.readBytes; Uri packagesFileUri = nonFileUri.resolve(".packages"); return loader(packagesFileUri).then((List fileBytes) { Map map = pkgfile.parse(fileBytes, packagesFileUri); @@ -152,30 +203,3 @@ Future findPackagesFromNonFile(Uri nonFileUri, return new NonFilePackagesDirectoryPackages(packagesDirectoryUri); }); } - -/// Fetches a file over http. -Future> _httpGet(Uri uri) { - HttpClient client = new HttpClient(); - return client - .getUrl(uri) - .then((HttpClientRequest request) => request.close()) - .then((HttpClientResponse response) { - if (response.statusCode != HttpStatus.OK) { - String msg = 'Failure getting $uri: ' - '${response.statusCode} ${response.reasonPhrase}'; - throw msg; - } - return response.toList(); - }).then((List> splitContent) { - int totalLength = splitContent.fold(0, (int old, List list) { - return old + list.length; - }); - Uint8List result = new Uint8List(totalLength); - int offset = 0; - for (List contentPart in splitContent) { - result.setRange(offset, offset + contentPart.length, contentPart); - offset += contentPart.length; - } - return result; - }); -} diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 16544e43d..d89cc2fa9 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -205,6 +205,52 @@ main() { loader:loader); validatePackagesDir(resolver, location); }); + + generalTest("loadPackagesFile", + {".packages": packagesFile}, + (Uri directory) async { + Uri file = directory.resolve(".packages"); + Packages resolver = await loadPackagesFile(file); + validatePackagesFile(resolver, file); + }); + + generalTest("loadPackagesFile non-default name", + {"pheldagriff": packagesFile}, + (Uri directory) async { + Uri file = directory.resolve("pheldagriff"); + Packages resolver = await loadPackagesFile(file); + validatePackagesFile(resolver, file); + }); + + test("loadPackagesFile w/ loader", () async { + loader(Uri uri) async => packagesFile.codeUnits; + Uri file = Uri.parse("krutz://example.com/.packages"); + Packages resolver = await loadPackagesFile(file, loader: loader); + validatePackagesFile(resolver, file); + }); + + generalTest("loadPackagesFile not found", + {}, + (Uri directory) async { + Uri file = directory.resolve(".packages"); + expect(loadPackagesFile(file), throws); + }); + + generalTest("loadPackagesFile syntax error", + {".packages": "syntax error"}, + (Uri directory) async { + Uri file = directory.resolve(".packages"); + expect(loadPackagesFile(file), throws); + }); + + generalTest("getPackagesDir", + {"packages": {"foo": {}, "bar": {}, "baz": {}}}, + (Uri directory) async { + Uri packages = directory.resolve("packages/"); + Packages resolver = getPackagesDirectory(packages); + Uri resolved = resolver.resolve(pkg("foo","flip/flop")); + expect(resolved, packages.resolve("foo/flip/flop")); + }); } /// Create a directory structure from [description] and run [fileTest]. @@ -285,5 +331,3 @@ void _createFiles(Directory target, Map description) { } }); } - - From 4eace8962445c84f69383010495a3a7b33ff37bd Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 10 Jun 2015 14:03:44 +0200 Subject: [PATCH 115/657] Tweak comments added by `write` function on packages_file.dart. Now adds "# " in front, not just "#", and doesn't treat the empty string after a final "\n" as an extra line. R=sgjesse@google.com Review URL: https://codereview.chromium.org//1167223004. --- pkgs/package_config/lib/packages_file.dart | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 2228cb3f0..a736ca0b5 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -74,7 +74,9 @@ Map parse(List source, Uri baseLocation) { /// Writes the mapping to a [StringSink]. /// /// If [comment] is provided, the output will contain this comment -/// with `#` in front of each line. +/// with `# ` in front of each line. +/// Lines are defined as ending in line feed (`'\n'`). If the final +/// line of the comment doesn't end in a line feed, one will be added. /// /// If [baseUri] is provided, package locations will be made relative /// to the base URI, if possible, before writing. @@ -85,8 +87,10 @@ void write(StringSink output, Map packageMapping, } if (comment != null) { - for (var commentLine in comment.split('\n')) { - output.write('#'); + var lines = comment.split('\n'); + if (lines.last.isEmpty) lines.removeLast(); + for (var commentLine in lines) { + output.write('# '); output.writeln(commentLine); } } else { @@ -172,4 +176,4 @@ Uri _relativize(Uri uri, Uri baseUri) { } // TODO: inline to uri.normalizePath() when we move to 1.11 -Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); +Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); From 3f171c5fee0b34fa64af46d4ab473c06821a314f Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Tue, 16 Jun 2015 09:42:56 -0700 Subject: [PATCH 116/657] Make tests pass R=het@google.com, lrn@google.com Review URL: https://codereview.chromium.org//1178673002. --- pkgs/package_config/lib/discovery.dart | 29 +++++++++++++++++-- pkgs/package_config/pubspec.yaml | 4 +-- .../test/discovery_analysis_test.dart | 12 ++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 35c3ece7f..a399395cb 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -38,7 +38,7 @@ Future loadPackagesFile(Uri packagesFile, return file.readAsBytes().then(parseBytes); } if (loader == null) { - return http.readBytes(packagesFile).then(parseBytes); + return _httpGet(packagesFile).then(parseBytes); } return loader(packagesFile).then(parseBytes); } @@ -99,7 +99,7 @@ Future findPackages(Uri baseUri, } else if (loader != null) { return findPackagesFromNonFile(baseUri, loader: loader); } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { - return findPackagesFromNonFile(baseUri, loader: http.readBytes); + return findPackagesFromNonFile(baseUri, loader: _httpGet); } else { return new Future.value(Packages.noPackages); } @@ -192,7 +192,7 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// UTF-8 encoded. Future findPackagesFromNonFile(Uri nonFileUri, {Future> loader(Uri name)}) { - if (loader == null) loader = http.readBytes; + if (loader == null) loader = _httpGet; Uri packagesFileUri = nonFileUri.resolve(".packages"); return loader(packagesFileUri).then((List fileBytes) { Map map = pkgfile.parse(fileBytes, packagesFileUri); @@ -203,3 +203,26 @@ Future findPackagesFromNonFile(Uri nonFileUri, return new NonFilePackagesDirectoryPackages(packagesDirectoryUri); }); } + +/// Fetches a file over http. +Future> _httpGet(Uri uri) async { + HttpClient client = new HttpClient(); + HttpClientRequest request = await client.getUrl(uri); + HttpClientResponse response = await request.close(); + if (response.statusCode != HttpStatus.OK) { + throw 'Failure getting $uri: ' + '${response.statusCode} ${response.reasonPhrase}'; + } + List> splitContent = await response.toList(); + int totalLength = 0; + for (var list in splitContent) { + totalLength += list.length; + } + Uint8List result = new Uint8List(totalLength); + int offset = 0; + for (List contentPart in splitContent) { + result.setRange(offset, offset + contentPart.length, contentPart); + offset += contentPart.length; + } + return result; +} diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 0f2735b53..0b780d9d7 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -8,8 +8,8 @@ environment: sdk: '>=1.11.0-dev.0.0 <2.0.0' dependencies: - charcode: '^1.1.0' - path: '>=1.0.0 <2.0.0' + charcode: ^1.1.0 + path: ^1.0.0 dev_dependencies: test: '>=0.12.0 <0.13.0' diff --git a/pkgs/package_config/test/discovery_analysis_test.dart b/pkgs/package_config/test/discovery_analysis_test.dart index ad007c073..38599f895 100644 --- a/pkgs/package_config/test/discovery_analysis_test.dart +++ b/pkgs/package_config/test/discovery_analysis_test.dart @@ -19,19 +19,19 @@ main() { (Directory directory) { var dirUri = new Uri.directory(directory.path); PackageContext ctx = PackageContext.findAll(directory); - PackagesContext root = ctx[directory]; + PackageContext root = ctx[directory]; expect(root, same(ctx)); validatePackagesFile(root.packages, dirUri); var fooDir = sub(directory, "foo"); - PackagesContext foo = ctx[fooDir]; + PackageContext foo = ctx[fooDir]; expect(identical(root, foo), isFalse); validatePackagesFile(foo.packages, dirUri.resolve("foo/")); var barDir = sub(directory, "bar"); - PackagesContext bar = ctx[sub(directory, "bar")]; + PackageContext bar = ctx[sub(directory, "bar")]; validatePackagesDir(bar.packages, dirUri.resolve("bar/")); - PackagesContext barbar = ctx[sub(barDir, "bar")]; + PackageContext barbar = ctx[sub(barDir, "bar")]; expect(barbar, same(bar)); // inherited. - PackagesContext baz = ctx[sub(directory, "baz")]; + PackageContext baz = ctx[sub(directory, "baz")]; expect(baz, same(root)); // inherited. var map = ctx.asMap(); @@ -95,7 +95,7 @@ Uri pkg(String packageName, String packagePath) { /// as a string. void fileTest(String name, Map description, - Future fileTest(Uri directory)) { + Future fileTest(Directory directory)) { group("file-test", () { Directory tempDir = Directory.systemTemp.createTempSync("file-test"); setUp(() { From ca0681f4325686bf9350e5a80e289b71f44f1b88 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 24 Jun 2015 08:00:52 +0200 Subject: [PATCH 117/657] Update to new syntax. R=het@google.com, pquitslund@google.com Review URL: https://codereview.chromium.org//1178213004. --- .../lib/discovery_analysis.dart | 1 - pkgs/package_config/lib/packages_file.dart | 30 ++++--- pkgs/package_config/lib/src/util.dart | 66 ++++++++++----- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/all.dart | 10 ++- .../test/discovery_analysis_test.dart | 8 +- pkgs/package_config/test/discovery_test.dart | 8 +- pkgs/package_config/test/parse_test.dart | 64 +++++++------- .../package_config/test/parse_write_test.dart | 84 +++++++++++++++++++ 9 files changed, 200 insertions(+), 73 deletions(-) create mode 100644 pkgs/package_config/test/parse_write_test.dart diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart index f3bcac68e..af4df070a 100644 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -18,7 +18,6 @@ import "dart:collection" show HashMap; import "package:path/path.dart" as path; import "packages.dart"; -import "discovery.dart"; import "packages_file.dart" as pkgfile; import "src/packages_impl.dart"; import "src/packages_io_impl.dart"; diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index a736ca0b5..73e6061c9 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -5,7 +5,7 @@ library package_config.packages_file; import "package:charcode/ascii.dart"; -import "src/util.dart" show isIdentifier; +import "src/util.dart" show isValidPackageName; /// Parses a `.packages` file into a map from package name to base URI. /// @@ -28,34 +28,34 @@ Map parse(List source, Uri baseLocation) { while (index < source.length) { bool isComment = false; int start = index; - int eqIndex = -1; + int separatorIndex = -1; int end = source.length; int char = source[index++]; if (char == $cr || char == $lf) { continue; } - if (char == $equal) { + if (char == $colon) { throw new FormatException("Missing package name", source, index - 1); } isComment = char == $hash; while (index < source.length) { char = source[index++]; - if (char == $equal && eqIndex < 0) { - eqIndex = index - 1; + if (char == $colon && separatorIndex < 0) { + separatorIndex = index - 1; } else if (char == $cr || char == $lf) { end = index - 1; break; } } if (isComment) continue; - if (eqIndex < 0) { - throw new FormatException("No '=' on line", source, index - 1); + if (separatorIndex < 0) { + throw new FormatException("No ':' on line", source, index - 1); } - var packageName = new String.fromCharCodes(source, start, eqIndex); - if (!isIdentifier(packageName)) { + var packageName = new String.fromCharCodes(source, start, separatorIndex); + if (!isValidPackageName(packageName)) { throw new FormatException("Not a valid package name", packageName, 0); } - var packageUri = new String.fromCharCodes(source, eqIndex + 1, end); + var packageUri = new String.fromCharCodes(source, separatorIndex + 1, end); var packageLocation = Uri.parse(packageUri); if (!packageLocation.path.endsWith('/')) { packageLocation = @@ -101,11 +101,11 @@ void write(StringSink output, Map packageMapping, packageMapping.forEach((String packageName, Uri uri) { // Validate packageName. - if (!isIdentifier(packageName)) { + if (!isValidPackageName(packageName)) { throw new ArgumentError('"$packageName" is not a valid package name'); } output.write(packageName); - output.write('='); + output.write(':'); // If baseUri provided, make uri relative. if (baseUri != null) { uri = _relativize(uri, baseUri); @@ -124,7 +124,7 @@ void write(StringSink output, Map packageMapping, /// but may be relative. /// The `baseUri` must be absolute. Uri _relativize(Uri uri, Uri baseUri) { - assert(!baseUri.isAbsolute); + assert(baseUri.isAbsolute); if (uri.hasQuery || uri.hasFragment) { uri = new Uri( scheme: uri.scheme, @@ -158,6 +158,7 @@ Uri _relativize(Uri uri, Uri baseUri) { } uri = _normalizePath(uri); List target = uri.pathSegments.toList(); + if (target.isNotEmpty && target.last.isEmpty) target.removeLast(); int index = 0; while (index < base.length && index < target.length) { if (base[index] != target[index]) { @@ -166,6 +167,9 @@ Uri _relativize(Uri uri, Uri baseUri) { index++; } if (index == base.length) { + if (index == target.length) { + return new Uri(path: "./"); + } return new Uri(path: target.skip(index).join('/')); } else if (index > 0) { return new Uri( diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index abf1d52f0..badf64086 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -7,27 +7,39 @@ library package_config.util; import "package:charcode/ascii.dart"; -/// Tests whether something is a valid Dart identifier/package name. -bool isIdentifier(String string) { - if (string.isEmpty) return false; - int firstChar = string.codeUnitAt(0); - int firstCharLower = firstChar | 0x20; - if (firstCharLower < $a || firstCharLower > $z) { - if (firstChar != $_ && firstChar != $$) return false; - } - for (int i = 1; i < string.length; i++) { - int char = string.codeUnitAt(i); - int charLower = char | 0x20; - if (charLower < $a || charLower > $z) { // Letters. - if ((char ^ 0x30) <= 9) continue; // Digits. - if (char == $_ || char == $$) continue; // $ and _ - if (firstChar != $_ && firstChar != $$) return false; +// All ASCII characters that are valid in a package name, with space +// for all the invalid ones (including space). +const String _validPackageNameCharacters = + r" ! $ &'()*+,-. 0123456789 ; = " + r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ~ "; + +/// Tests whether something is a valid Dart package name. +bool isValidPackageName(String string) { + return _findInvalidCharacter(string) < 0; +} + +/// Check if a string is a valid package name. +/// +/// Valid package names contain only characters in [_validPackageNameCharacters] +/// and must contain at least one non-'.' character. +/// +/// Returns `-1` if the string is valid. +/// Otherwise returns the index of the first invalid character, +/// or `string.length` if the string contains no non-'.' character. +int _findInvalidCharacter(String string) { + // Becomes non-zero if any non-'.' character is encountered. + int nonDot = 0; + for (int i = 0; i < string.length; i++) { + var c = string.codeUnitAt(i); + if (c > 0x7f || _validPackageNameCharacters.codeUnitAt(c) <= $space) { + return i; } + nonDot += c ^ $dot; } - return true; + if (nonDot == 0) return string.length; + return -1; } - /// Validate that a Uri is a valid package:URI. String checkValidPackageUri(Uri packageUri) { if (packageUri.scheme != "package") { @@ -61,9 +73,25 @@ String checkValidPackageUri(Uri packageUri) { "Package URIs must start with the package name followed by a '/'"); } String packageName = packageUri.path.substring(0, firstSlash); - if (!isIdentifier(packageName)) { + int badIndex = _findInvalidCharacter(packageName); + if (badIndex >= 0) { + if (packageName.isEmpty) { + throw new ArgumentError.value(packageUri, "packageUri", + "Package names mus be non-empty"); + } + if (badIndex == packageName.length) { + throw new ArgumentError.value(packageUri, "packageUri", + "Package names must contain at least one non-'.' character"); + } + assert(badIndex < packageName.length); + int badCharCode = packageName.codeUnitAt(badIndex); + var badChar = "U+" + badCharCode.toRadixString(16).padLeft(4, '0'); + if (badCharCode >= 0x20 && badCharCode <= 0x7e) { + // Printable character. + badChar = "'${packageName[badIndex]}' ($badChar)"; + } throw new ArgumentError.value(packageUri, "packageUri", - "Package names must be valid identifiers"); + "Package names must not contain $badChar"); } return packageName; } diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 0b780d9d7..2d96c9035 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.0.4 +version: 0.1.0 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/all.dart b/pkgs/package_config/test/all.dart index 79f5b3574..78e6cffd1 100644 --- a/pkgs/package_config/test/all.dart +++ b/pkgs/package_config/test/all.dart @@ -2,10 +2,16 @@ // 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:test/test.dart"; + +import "discovery_analysis_test.dart" as discovery_analysis; import "discovery_test.dart" as discovery; import "parse_test.dart" as parse; +import "parse_write_test.dart" as parse_write; main() { - parse.main(); - discovery.main(); + group("parse:", parse.main); + group("discovery:", discovery.main); + group("discovery-analysis:", discovery_analysis.main); + group("parse/write:", parse_write.main); } diff --git a/pkgs/package_config/test/discovery_analysis_test.dart b/pkgs/package_config/test/discovery_analysis_test.dart index 38599f895..f33a4a8c6 100644 --- a/pkgs/package_config/test/discovery_analysis_test.dart +++ b/pkgs/package_config/test/discovery_analysis_test.dart @@ -2,6 +2,8 @@ // 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. +library package_config.discovery_analysis_test; + import "dart:async"; import "dart:io"; @@ -46,9 +48,9 @@ Directory sub(Directory parent, String dirName) { const packagesFile = """ # A comment -foo=file:///dart/packages/foo/ -bar=http://example.com/dart/packages/bar/ -baz=packages/baz/ +foo:file:///dart/packages/foo/ +bar:http://example.com/dart/packages/bar/ +baz:packages/baz/ """; void validatePackagesFile(Packages resolver, Uri location) { diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index d89cc2fa9..4f780c2ad 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -2,6 +2,8 @@ // 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. +library package_config.discovery_test; + import "dart:async"; import "dart:io"; import "package:test/test.dart"; @@ -11,9 +13,9 @@ import "package:path/path.dart" as path; const packagesFile = """ # A comment -foo=file:///dart/packages/foo/ -bar=http://example.com/dart/packages/bar/ -baz=packages/baz/ +foo:file:///dart/packages/foo/ +bar:http://example.com/dart/packages/bar/ +baz:packages/baz/ """; void validatePackagesFile(Packages resolver, Uri location) { diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index ddd8ff6ca..902d8cea8 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -2,7 +2,7 @@ // 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. -library test_all; +library package_config.parse_test; import "package:package_config/packages.dart"; import "package:package_config/packages_file.dart" show parse; @@ -81,27 +81,27 @@ main() { equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); - test("all valid chars", () { + test("all valid chars can be used in URI segment", () { var packages = doParse(allValidCharsSample, base); expect(packages.packages.toList(), equals([allValidChars])); expect(packages.resolve(Uri.parse("package:$allValidChars/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); - test("no escapes", () { - expect(() => doParse("x%41x=x", base), throws); + test("no invalid chars accepted", () { + var map = {}; + for (int i = 0; i < allValidChars.length; i++) { + map[allValidChars.codeUnitAt(i)] = true; + } + for (int i = 0; i <= 255; i++) { + if (map[i] == true) continue; + var char = new String.fromCharCode(i); + expect(() => doParse("x${char}x:x"), throws); + } }); - test("not identifiers", () { - expect(() => doParse("1x=x", base), throws); - expect(() => doParse(" x=x", base), throws); - expect(() => doParse("\\x41x=x", base), throws); - expect(() => doParse("x@x=x", base), throws); - expect(() => doParse("x[x=x", base), throws); - expect(() => doParse("x`x=x", base), throws); - expect(() => doParse("x{x=x", base), throws); - expect(() => doParse("x/x=x", base), throws); - expect(() => doParse("x:x=x", base), throws); + test("no escapes", () { + expect(() => doParse("x%41x:x", base), throws); }); test("same name twice", () { @@ -131,26 +131,28 @@ Packages doParse(String sample, Uri baseUri) { var emptySample = ""; var commentOnlySample = "# comment only\n"; var emptyLinesSample = "\n\n\r\n"; -var singleRelativeSample = "foo=../test/\n"; -var singleRelativeSampleNoSlash = "foo=../test\n"; -var singleRelativeSampleNoNewline = "foo=../test/"; -var singleAbsoluteSample = "foo=http://example.com/some/where/\n"; -var multiRelativeSample = "foo=../test/\nbar=../test2/\n"; +var singleRelativeSample = "foo:../test/\n"; +var singleRelativeSampleNoSlash = "foo:../test\n"; +var singleRelativeSampleNoNewline = "foo:../test/"; +var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; +var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; // All valid path segment characters in an URI. var allValidChars = - r"$0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"; -var allValidCharsSample = "${allValidChars.replaceAll('=', '%3D')}=../test/\n"; -var allUnreservedChars = - "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; + r"!$&'()*+,-.0123456789;=" + r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; + +var allValidCharsSample = "${allValidChars}:../test/\n"; // Invalid samples. var invalid = [ - "foobar:baz.dart", // no equals - ".=../test/", // dot segment - "..=../test/", // dot-dot segment - "foo/bar=../test/", // - "/foo=../test/", // var multiSegmentSample - "?=../test/", // invalid characters in path segment. - "[=../test/", // invalid characters in path segment. - "x#=../test/", // invalid characters in path segment. + ":baz.dart", // empty. + "foobar=baz.dart", // no colon (but an equals, which is not the same) + ".:../test/", // dot segment + "..:../test/", // dot-dot segment + "...:../test/", // dot-dot-dot segment + "foo/bar:../test/", // slash in name + "/foo:../test/", // slash at start of name + "?:../test/", // invalid characters. + "[:../test/", // invalid characters. + "x#:../test/", // invalid characters. ]; diff --git a/pkgs/package_config/test/parse_write_test.dart b/pkgs/package_config/test/parse_write_test.dart new file mode 100644 index 000000000..fde9616ea --- /dev/null +++ b/pkgs/package_config/test/parse_write_test.dart @@ -0,0 +1,84 @@ +// Copyright (c) 2015, 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. + +library package_config.parse_write_test; + +import "package:package_config/packages.dart"; +import "package:package_config/packages_file.dart"; +import "package:test/test.dart"; + +main() { + testBase(baseDirString) { + var baseDir = Uri.parse(baseDirString); + group("${baseDir.scheme} base", () { + Uri packagesFile = baseDir.resolve(".packages"); + + roundTripTest(String name, Map map) { + group(name, () { + test("write with no baseUri", () { + var content = writeToString(map).codeUnits; + var resultMap = parse(content, packagesFile); + expect(resultMap, map); + }); + + test("write with base directory", () { + var content = writeToString(map, baseUri: baseDir).codeUnits; + var resultMap = parse(content, packagesFile); + expect(resultMap, map); + }); + + test("write with base .packages file", () { + var content = writeToString(map, baseUri: packagesFile).codeUnits; + var resultMap = parse(content, packagesFile); + expect(resultMap, map); + }); + }); + } + var lowerDir = baseDir.resolve("path3/path4/"); + var higherDir = baseDir.resolve("../"); + var parallelDir = baseDir.resolve("../path3/"); + var rootDir = baseDir.resolve("/"); + var fileDir = Uri.parse("file:///path1/part2/"); + var httpDir = Uri.parse("http://example.com/path1/path2/"); + var otherDir = Uri.parse("other:/path1/path2/"); + + roundTripTest("empty", {}); + roundTripTest("lower directory", {"foo": lowerDir}); + roundTripTest("higher directory", {"foo": higherDir}); + roundTripTest("parallel directory", {"foo": parallelDir}); + roundTripTest("same directory", {"foo": baseDir}); + roundTripTest("root directory", {"foo": rootDir}); + roundTripTest("file directory", {"foo": fileDir}); + roundTripTest("http directory", {"foo": httpDir}); + roundTripTest("other scheme directory", {"foo": otherDir}); + roundTripTest("multiple same-type directories", + {"foo": lowerDir, "bar": higherDir, "baz": parallelDir}); + roundTripTest("multiple scheme directories", + {"foo": fileDir, "bar": httpDir, "baz": otherDir}); + roundTripTest("multiple scheme directories and mutliple same type", + {"foo": fileDir, "bar": httpDir, "baz": otherDir, + "qux": lowerDir, "hip": higherDir, "dep": parallelDir}); + }); + } + + testBase("file:///base1/base2/"); + testBase("http://example.com/base1/base2/"); + testBase("other:/base1/base2/"); + + // Check that writing adds the comment. + test("write preserves comment", () { + var comment = "comment line 1\ncomment line 2\ncomment line 3"; + var result = writeToString({}, comment: comment); + // Comment with "# " before each line and "\n" after last. + var expectedComment = + "# comment line 1\n# comment line 2\n# comment line 3\n"; + expect(result, startsWith(expectedComment)); + }); +} + +String writeToString(Map map, {Uri baseUri, String comment}) { + var buffer = new StringBuffer(); + write(buffer, map, baseUri: baseUri, comment: comment); + return buffer.toString(); +} From 3b11c03435f18fab1943e94ff3d680a098a0d961 Mon Sep 17 00:00:00 2001 From: pq Date: Wed, 24 Jun 2015 09:06:02 -0700 Subject: [PATCH 118/657] Build fixes [TBR]. --- pkgs/package_config/test/parse_test.dart | 2 +- pkgs/package_config/test/parse_write_test.dart | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 902d8cea8..3c02c84b6 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -96,7 +96,7 @@ main() { for (int i = 0; i <= 255; i++) { if (map[i] == true) continue; var char = new String.fromCharCode(i); - expect(() => doParse("x${char}x:x"), throws); + expect(() => doParse("x${char}x:x", null), throws); } }); diff --git a/pkgs/package_config/test/parse_write_test.dart b/pkgs/package_config/test/parse_write_test.dart index fde9616ea..6a185db20 100644 --- a/pkgs/package_config/test/parse_write_test.dart +++ b/pkgs/package_config/test/parse_write_test.dart @@ -4,7 +4,6 @@ library package_config.parse_write_test; -import "package:package_config/packages.dart"; import "package:package_config/packages_file.dart"; import "package:test/test.dart"; From 8110c7a4a8e0119a0625d5e2caa3110a9e236de5 Mon Sep 17 00:00:00 2001 From: pq Date: Wed, 24 Jun 2015 09:13:40 -0700 Subject: [PATCH 119/657] Version bump. --- pkgs/package_config/CHANGELOG.md | 11 +++++++++-- pkgs/package_config/pubspec.yaml | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 2a2d63cf8..625f48625 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog -## 0.0.1 +## 0.1.1 + +- Syntax updates. + + +## 0.1.0 + +- Initial implementation. + -- Initial version diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 2d96c9035..72406801e 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.1.0 +version: 0.1.1 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From 150f467e4697f39cf4b52bf4cb34e305f65696ad Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 24 Jun 2015 15:04:34 -0700 Subject: [PATCH 120/657] Add Pool.allowRelease(). This allows a resource to indicate that it can be released without forcing it to deallocate immediately. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1205133002. --- pkgs/pool/CHANGELOG.md | 5 ++ pkgs/pool/lib/pool.dart | 76 +++++++++++++++++++++-- pkgs/pool/pubspec.yaml | 4 +- pkgs/pool/test/pool_test.dart | 113 ++++++++++++++++++++++++++++++++++ 4 files changed, 191 insertions(+), 7 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 4fa87caec..ec8fd79a8 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.1.0 + +* Add `PoolResource.allowRelease()`, which allows a resource to indicate that it + can be released without forcing it to deallocate immediately. + ## 1.0.2 * Fixed the homepage. diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 61482e3f2..6941229b3 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -24,6 +24,19 @@ class Pool { /// be completed. final _requestedResources = new Queue>(); + /// Callbacks that must be called before additional resources can be + /// allocated. + /// + /// See [PoolResource.allowRelease]. + final _onReleaseCallbacks = new Queue(); + + /// Completers that will be completed once `onRelease` callbacks are done + /// running. + /// + /// These are kept in a queue to ensure that the earliest request completes + /// first regardless of what order the `onRelease` callbacks complete in. + final _onReleaseCompleters = new Queue>(); + /// The maximum number of resources that may be allocated at once. final int _maxAllocatedResources; @@ -59,6 +72,8 @@ class Pool { if (_allocatedResources < _maxAllocatedResources) { _allocatedResources++; return new Future.value(new PoolResource._(this)); + } else if (_onReleaseCallbacks.isNotEmpty) { + return _runOnRelease(_onReleaseCallbacks.removeFirst()); } else { var completer = new Completer(); _requestedResources.add(completer); @@ -78,24 +93,53 @@ class Pool { /// If there are any pending requests, this will fire the oldest one. void _onResourceReleased() { + _resetTimer(); + if (_requestedResources.isEmpty) { _allocatedResources--; - if (_timer != null) { - _timer.cancel(); - _timer = null; - } return; } - _resetTimer(); var pending = _requestedResources.removeFirst(); pending.complete(new PoolResource._(this)); } + /// If there are any pending requests, this will fire the oldest one after + /// running [onRelease]. + void _onResourceReleaseAllowed(onRelease()) { + _resetTimer(); + + if (_requestedResources.isEmpty) { + _onReleaseCallbacks.add( + Zone.current.bindCallback(onRelease, runGuarded: false)); + return; + } + + var pending = _requestedResources.removeFirst(); + pending.complete(_runOnRelease(onRelease)); + } + + /// Runs [onRelease] and returns a Future that completes to a resource once an + /// [onRelease] callback completes. + /// + /// Futures returned by [_runOnRelease] always complete in the order they were + /// created, even if earlier [onRelease] callbacks take longer to run. + Future _runOnRelease(onRelease()) { + new Future.sync(onRelease).then((value) { + _onReleaseCompleters.removeFirst().complete(new PoolResource._(this)); + }).catchError((error, stackTrace) { + _onReleaseCompleters.removeFirst().completeError(error, stackTrace); + }); + + var completer = new Completer.sync(); + _onReleaseCompleters.add(completer); + return completer.future; + } + /// A resource has been requested, allocated, or released. void _resetTimer() { if (_timer != null) _timer.cancel(); - if (_timeout == null) { + if (_timeout == null || _requestedResources.isEmpty) { _timer = null; } else { _timer = new Timer(_timeout, _onTimeout); @@ -138,5 +182,25 @@ class PoolResource { _released = true; _pool._onResourceReleased(); } + + /// Tells the parent [Pool] that the resource associated with this resource is + /// no longer necessary, but should remain allocated until more resources are + /// needed. + /// + /// When [Pool.request] is called and there are no remaining available + /// resources, the [onRelease] callback is called. It should free the + /// resource, and it may return a Future or `null`. Once that completes, the + /// [Pool.request] call will complete to a new [PoolResource]. + /// + /// This is useful when a resource's main function is complete, but it may + /// produce additional information later on. For example, an isolate's task + /// may be complete, but it could still emit asynchronous errors. + void allowRelease(onRelease()) { + if (_released) { + throw new StateError("A PoolResource may only be released once."); + } + _released = true; + _pool._onResourceReleaseAllowed(onRelease); + } } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 19aac1e54..175c8dc74 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,10 +1,12 @@ name: pool -version: 1.0.2 +version: 1.1.0 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool dependencies: stack_trace: ">=0.9.2 <2.0.0" +environment: + sdk: ">=1.9.0 <2.0.0" dev_dependencies: fake_async: ">=0.1.0 <0.2.0" test: ">=0.12.0 <0.13.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index b654801e1..64bc3a6cc 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -159,6 +159,119 @@ void main() { }); }); }); + + group("allowRelease()", () { + test("runs the callback once the resource limit is exceeded", () async { + var pool = new Pool(50); + var requests = []; + for (var i = 0; i < 49; i++) { + expect(pool.request(), completes); + } + + var resource = await pool.request(); + var onReleaseCalled = false; + resource.allowRelease(() => onReleaseCalled = true); + await new Future.delayed(Duration.ZERO); + expect(onReleaseCalled, isFalse); + + expect(pool.request(), completes); + await new Future.delayed(Duration.ZERO); + expect(onReleaseCalled, isTrue); + }); + + test("runs the callback immediately if there are blocked requests", + () async { + var pool = new Pool(1); + var resource = await pool.request(); + + // This will be blocked until [resource.allowRelease] is called. + expect(pool.request(), completes); + + var onReleaseCalled = false; + resource.allowRelease(() => onReleaseCalled = true); + await new Future.delayed(Duration.ZERO); + expect(onReleaseCalled, isTrue); + }); + + test("blocks the request until the callback completes", () async { + var pool = new Pool(1); + var resource = await pool.request(); + + var requestComplete = false; + pool.request().then((_) => requestComplete = true); + + var completer = new Completer(); + resource.allowRelease(() => completer.future); + await new Future.delayed(Duration.ZERO); + expect(requestComplete, isFalse); + + completer.complete(); + await new Future.delayed(Duration.ZERO); + expect(requestComplete, isTrue); + }); + + test("completes requests in request order regardless of callback order", + () async { + var pool = new Pool(2); + var resource1 = await pool.request(); + var resource2 = await pool.request(); + + var request1Complete = false; + pool.request().then((_) => request1Complete = true); + var request2Complete = false; + pool.request().then((_) => request2Complete = true); + + var onRelease1Called = false; + var completer1 = new Completer(); + resource1.allowRelease(() { + onRelease1Called = true; + return completer1.future; + }); + await new Future.delayed(Duration.ZERO); + expect(onRelease1Called, isTrue); + + var onRelease2Called = false; + var completer2 = new Completer(); + resource2.allowRelease(() { + onRelease2Called = true; + return completer2.future; + }); + await new Future.delayed(Duration.ZERO); + expect(onRelease2Called, isTrue); + expect(request1Complete, isFalse); + expect(request2Complete, isFalse); + + // Complete the second resource's onRelease callback first. Even though it + // was triggered by the second blocking request, it should complete the + // first one to preserve ordering. + completer2.complete(); + await new Future.delayed(Duration.ZERO); + expect(request1Complete, isTrue); + expect(request2Complete, isFalse); + + completer1.complete(); + await new Future.delayed(Duration.ZERO); + expect(request1Complete, isTrue); + expect(request2Complete, isTrue); + }); + + test("runs onRequest in the zone it was created", () async { + var pool = new Pool(1); + var resource = await pool.request(); + + var outerZone = Zone.current; + runZoned(() { + var innerZone = Zone.current; + expect(innerZone, isNot(equals(outerZone))); + + resource.allowRelease(expectAsync(() { + expect(Zone.current, equals(innerZone)); + })); + }); + + pool.request(); + }); + }); } /// Returns a function that will cause the test to fail if it's called. From 05a0a88ca11541d9c51498666ba5d5893e97a94a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 30 Jun 2015 17:46:36 -0700 Subject: [PATCH 121/657] remove usage of Chain.track The min SDK is already 1.9, so we're not leaving anyone behind Also removed an unused variable in pool_test R=nweiz@google.com Review URL: https://codereview.chromium.org//1215053004. --- pkgs/pool/lib/pool.dart | 3 +-- pkgs/pool/pubspec.yaml | 2 +- pkgs/pool/test/pool_test.dart | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 6941229b3..e8ee99cab 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -87,8 +87,7 @@ class Pool { /// /// The return value of [callback] is piped to the returned Future. Future withResource(callback()) { - return request().then((resource) => - Chain.track(new Future.sync(callback)).whenComplete(resource.release)); + return request().then((resource) => new Future.sync(callback).whenComplete(resource.release)); } /// If there are any pending requests, this will fire the oldest one. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 175c8dc74..cc2d367be 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.1.0 +version: 1.1.1-dev author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 64bc3a6cc..5dfef2a24 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -163,7 +163,6 @@ void main() { group("allowRelease()", () { test("runs the callback once the resource limit is exceeded", () async { var pool = new Pool(50); - var requests = []; for (var i = 0; i < 49; i++) { expect(pool.request(), completes); } From 3351876c810771f337a05cf2950dce94ce594cde Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Mon, 13 Jul 2015 09:19:24 +0200 Subject: [PATCH 122/657] Don't allow package:-URIs as package locations when creating .packages file. R=pquitslund@google.com Review URL: https://codereview.chromium.org//1227283002 . --- pkgs/package_config/lib/discovery.dart | 2 +- pkgs/package_config/lib/packages_file.dart | 7 +++++++ pkgs/package_config/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index a399395cb..8e42af79d 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -179,7 +179,7 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// script. /// The [nonFileUri] should not be a `file:` URI since the algorithm for /// finding a package resolution strategy is more elaborate for `file:` URIs. -/// In that case, use [findPackagesFile]. +/// In that case, use [findPackagesFromFile]. /// /// This function first tries to locate a `.packages` file in the [nonFileUri] /// directory. If that is not found, it instead assumes a `packages/` directory diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 73e6061c9..25d2d6883 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -80,6 +80,9 @@ Map parse(List source, Uri baseLocation) { /// /// If [baseUri] is provided, package locations will be made relative /// to the base URI, if possible, before writing. +/// +/// All the keys of [packageMapping] must be valid package names, +/// and the values must be URIs that do not have the `package:` scheme. void write(StringSink output, Map packageMapping, {Uri baseUri, String comment}) { if (baseUri != null && !baseUri.isAbsolute) { @@ -104,6 +107,10 @@ void write(StringSink output, Map packageMapping, if (!isValidPackageName(packageName)) { throw new ArgumentError('"$packageName" is not a valid package name'); } + if (uri.scheme == "package") { + throw new ArgumentError.value( + "Package location must not be a package: URI", uri); + } output.write(packageName); output.write(':'); // If baseUri provided, make uri relative. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 72406801e..d3acb9064 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.1.1 +version: 0.1.2 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From 188ef5d26cea22fef00a6bcbef38cea16df5a092 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 16 Jul 2015 13:29:56 -0700 Subject: [PATCH 123/657] Use the new test runner on the bots. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1235143003 . --- pkgs/pool/.gitignore | 1 + pkgs/pool/.status | 15 --------------- pkgs/pool/.test_config | 3 +++ 3 files changed, 4 insertions(+), 15 deletions(-) delete mode 100644 pkgs/pool/.status create mode 100644 pkgs/pool/.test_config diff --git a/pkgs/pool/.gitignore b/pkgs/pool/.gitignore index 388eff0ba..7dbf0350d 100644 --- a/pkgs/pool/.gitignore +++ b/pkgs/pool/.gitignore @@ -3,6 +3,7 @@ .pub/ build/ packages +.packages # Or the files created by dart2js. *.dart.js diff --git a/pkgs/pool/.status b/pkgs/pool/.status deleted file mode 100644 index ff095a2f7..000000000 --- a/pkgs/pool/.status +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) 2014, 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. - -# Skip non-test files ending with "_test". -packages/*: Skip -*/packages/*: Skip -*/*/packages/*: Skip -*/*/*/packages/*: Skip -*/*/*/*packages/*: Skip -*/*/*/*/*packages/*: Skip - -# Only run tests from the build directory, since we don't care about the -# difference between transformed an untransformed code. -test/*: Skip diff --git a/pkgs/pool/.test_config b/pkgs/pool/.test_config new file mode 100644 index 000000000..412fc5c5c --- /dev/null +++ b/pkgs/pool/.test_config @@ -0,0 +1,3 @@ +{ + "test_package": true +} \ No newline at end of file From 183673110fc416d39e26d26f0058c14a29174742 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 16 Jul 2015 13:39:56 -0700 Subject: [PATCH 124/657] Upgrade to the new test runner. R=sigmund@google.com Review URL: https://codereview.chromium.org//1240033002 . --- pkgs/source_span/.gitignore | 1 + pkgs/source_span/.status | 3 --- pkgs/source_span/.test_config | 3 +++ pkgs/source_span/pubspec.yaml | 4 ++-- pkgs/source_span/test/file_message_test.dart | 2 +- pkgs/source_span/test/file_test.dart | 2 +- pkgs/source_span/test/location_test.dart | 2 +- pkgs/source_span/test/span_test.dart | 2 +- pkgs/source_span/test/utils_test.dart | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) delete mode 100644 pkgs/source_span/.status create mode 100644 pkgs/source_span/.test_config diff --git a/pkgs/source_span/.gitignore b/pkgs/source_span/.gitignore index 388eff0ba..7dbf0350d 100644 --- a/pkgs/source_span/.gitignore +++ b/pkgs/source_span/.gitignore @@ -3,6 +3,7 @@ .pub/ build/ packages +.packages # Or the files created by dart2js. *.dart.js diff --git a/pkgs/source_span/.status b/pkgs/source_span/.status deleted file mode 100644 index e9f2b0049..000000000 --- a/pkgs/source_span/.status +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2014, 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. diff --git a/pkgs/source_span/.test_config b/pkgs/source_span/.test_config new file mode 100644 index 000000000..412fc5c5c --- /dev/null +++ b/pkgs/source_span/.test_config @@ -0,0 +1,3 @@ +{ + "test_package": true +} \ No newline at end of file diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 16eee7cca..8f69deb3c 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.1.2 +version: 1.1.3-dev author: Dart Team description: A library for identifying source spans and locations. homepage: http://github.com/dart-lang/source_span @@ -8,4 +8,4 @@ dependencies: environment: sdk: '>=0.8.10+6 <2.0.0' dev_dependencies: - unittest: '>=0.9.0 <0.12.0' + test: '>=0.12.0 <0.13.0' diff --git a/pkgs/source_span/test/file_message_test.dart b/pkgs/source_span/test/file_message_test.dart index 18b34e71b..5935c5882 100644 --- a/pkgs/source_span/test/file_message_test.dart +++ b/pkgs/source_span/test/file_message_test.dart @@ -2,7 +2,7 @@ // 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:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_span/source_span.dart'; import 'package:source_span/src/colors.dart' as colors; diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index c27c1f64f..54bc3d34e 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -2,7 +2,7 @@ // 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:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_span/source_span.dart'; main() { diff --git a/pkgs/source_span/test/location_test.dart b/pkgs/source_span/test/location_test.dart index 1eedec43a..dcd497a9f 100644 --- a/pkgs/source_span/test/location_test.dart +++ b/pkgs/source_span/test/location_test.dart @@ -2,7 +2,7 @@ // 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:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_span/source_span.dart'; main() { diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 2657f5ffd..113848acf 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -2,7 +2,7 @@ // 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:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_span/source_span.dart'; import 'package:source_span/src/colors.dart' as colors; diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index 74975c35b..3b6238b55 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -2,7 +2,7 @@ // 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:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_span/src/utils.dart'; main() { From 91d98d80e0cc485672dfa5c3a66fdb15e91dc1f7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 16 Jul 2015 13:41:26 -0700 Subject: [PATCH 125/657] Upgrade to the new test runner. R=sigmund@google.com Review URL: https://codereview.chromium.org//1240863004 . --- pkgs/source_maps/.gitignore | 1 + pkgs/source_maps/.status | 20 -------------------- pkgs/source_maps/.test_config | 3 +++ pkgs/source_maps/pubspec.yaml | 4 ++-- pkgs/source_maps/test/builder_test.dart | 2 +- pkgs/source_maps/test/common.dart | 2 +- pkgs/source_maps/test/end2end_test.dart | 2 +- pkgs/source_maps/test/parser_test.dart | 2 +- pkgs/source_maps/test/printer_test.dart | 2 +- pkgs/source_maps/test/refactor_test.dart | 2 +- pkgs/source_maps/test/run.dart | 4 ++-- pkgs/source_maps/test/utils_test.dart | 2 +- pkgs/source_maps/test/vlq_test.dart | 6 ++++-- 13 files changed, 19 insertions(+), 33 deletions(-) delete mode 100644 pkgs/source_maps/.status create mode 100644 pkgs/source_maps/.test_config diff --git a/pkgs/source_maps/.gitignore b/pkgs/source_maps/.gitignore index 388eff0ba..7dbf0350d 100644 --- a/pkgs/source_maps/.gitignore +++ b/pkgs/source_maps/.gitignore @@ -3,6 +3,7 @@ .pub/ build/ packages +.packages # Or the files created by dart2js. *.dart.js diff --git a/pkgs/source_maps/.status b/pkgs/source_maps/.status deleted file mode 100644 index befa7ddc7..000000000 --- a/pkgs/source_maps/.status +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (c) 2014, 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. - -# Skip non-test files ending with "_test". -packages/*: Skip -*/packages/*: Skip -*/*/packages/*: Skip -*/*/*/packages/*: Skip -*/*/*/*packages/*: Skip -*/*/*/*/*packages/*: Skip - -# Only run tests from the build directory, since we don't care about the -# difference between transformed an untransformed code. -test/*: Skip - -[ $compiler == dart2js || $compiler == dart2dart ] -build/test/vlq_test: RuntimeError # A VLQ test checks for large numbers that - # overflow in JS (numbers slightly larger than - # 32 bits where we do bitwise operations). diff --git a/pkgs/source_maps/.test_config b/pkgs/source_maps/.test_config new file mode 100644 index 000000000..412fc5c5c --- /dev/null +++ b/pkgs/source_maps/.test_config @@ -0,0 +1,3 @@ +{ + "test_package": true +} \ No newline at end of file diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index fc0fe9bcc..86015d540 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.1 +version: 0.10.2-dev author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps @@ -9,4 +9,4 @@ dependencies: environment: sdk: '>=1.8.0 <2.0.0' dev_dependencies: - unittest: '>=0.9.0 <0.12.0' + test: '>=0.12.0 <0.13.0' diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index ca0ca8d2d..dcc583cfd 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -5,7 +5,7 @@ library test.source_maps_test; import 'dart:convert'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_maps/source_maps.dart'; import 'common.dart'; diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index 73a8d406b..3bc512cdf 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -7,7 +7,7 @@ library test.common; import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; /// Content of the source file const String INPUT = ''' diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 7dbc6bd9b..8caf2e9ea 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -4,7 +4,7 @@ library test.end2end_test; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; import 'common.dart'; diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index b14fdf425..88da8c547 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -5,7 +5,7 @@ library test.parser_test; import 'dart:convert'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_maps/source_maps.dart'; import 'common.dart'; diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index e55ca9f6e..25036eee9 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -5,7 +5,7 @@ library test.printer_test; import 'dart:convert'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; import 'common.dart'; diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 08b896510..03292d1db 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -4,7 +4,7 @@ library polymer.test.refactor_test; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_maps/refactor.dart'; import 'package:source_maps/parser.dart' show parse, Mapping; import 'package:source_span/source_span.dart'; diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart index ec3c3ab7f..b37fdcd6f 100755 --- a/pkgs/source_maps/test/run.dart +++ b/pkgs/source_maps/test/run.dart @@ -5,8 +5,8 @@ library test.run; -import 'package:unittest/compact_vm_config.dart'; -import 'package:unittest/unittest.dart'; +import 'package:test/compact_vm_config.dart'; +import 'package:test/test.dart'; import 'dart:io' show Options; import 'builder_test.dart' as builder_test; diff --git a/pkgs/source_maps/test/utils_test.dart b/pkgs/source_maps/test/utils_test.dart index 79a7de769..cbbb40ab3 100644 --- a/pkgs/source_maps/test/utils_test.dart +++ b/pkgs/source_maps/test/utils_test.dart @@ -5,7 +5,7 @@ /// Tests for the binary search utility algorithm. library test.utils_test; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_maps/src/utils.dart'; main() { diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index 0abdc4795..d1b543da0 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -5,7 +5,7 @@ library test.vlq_test; import 'dart:math'; -import 'package:unittest/unittest.dart'; +import 'package:test/test.dart'; import 'package:source_maps/src/vlq.dart'; main() { @@ -49,7 +49,9 @@ main() { expect(() => decodeVlq('igggggE'.split('').iterator), throws); expect(() => decodeVlq('jgggggE'.split('').iterator), throws); expect(() => decodeVlq('lgggggE'.split('').iterator), throws); - }); + }, + // This test uses integers so large they overflow in JS. + testOn: "dart-vm"); } _checkEncodeDecode(int value) { From 5bd94be91cae69f085ee77f0143262b01500f081 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 14 Aug 2015 16:47:02 -0700 Subject: [PATCH 126/657] remove checked-in pubspec.lock and ignore .packages --- pkgs/package_config/.gitignore | 3 +- pkgs/package_config/pubspec.lock | 87 -------------------------------- 2 files changed, 2 insertions(+), 88 deletions(-) delete mode 100644 pkgs/package_config/pubspec.lock diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore index f48e3c9a8..b46f3df8e 100644 --- a/pkgs/package_config/.gitignore +++ b/pkgs/package_config/.gitignore @@ -4,4 +4,5 @@ packages build .project .settings -pubspec.lock \ No newline at end of file +pubspec.lock +.packages diff --git a/pkgs/package_config/pubspec.lock b/pkgs/package_config/pubspec.lock deleted file mode 100644 index 5cae00509..000000000 --- a/pkgs/package_config/pubspec.lock +++ /dev/null @@ -1,87 +0,0 @@ -# Generated by pub -# See http://pub.dartlang.org/doc/glossary.html#lockfile -packages: - analyzer: - description: analyzer - source: hosted - version: "0.25.0+1" - args: - description: args - source: hosted - version: "0.13.0" - barback: - description: barback - source: hosted - version: "0.15.2+4" - charcode: - description: charcode - source: hosted - version: "1.1.0" - collection: - description: collection - source: hosted - version: "1.1.1" - crypto: - description: crypto - source: hosted - version: "0.9.0" - http_parser: - description: http_parser - source: hosted - version: "0.0.2+6" - matcher: - description: matcher - source: hosted - version: "0.12.0" - mime: - description: mime - source: hosted - version: "0.9.3" - path: - description: path - source: hosted - version: "1.3.5" - pool: - description: pool - source: hosted - version: "1.0.1" - pub_semver: - description: pub_semver - source: hosted - version: "1.2.0" - shelf: - description: shelf - source: hosted - version: "0.6.1+2" - shelf_static: - description: shelf_static - source: hosted - version: "0.2.2" - shelf_web_socket: - description: shelf_web_socket - source: hosted - version: "0.0.1+2" - source_span: - description: source_span - source: hosted - version: "1.1.2" - stack_trace: - description: stack_trace - source: hosted - version: "1.3.2" - string_scanner: - description: string_scanner - source: hosted - version: "0.1.3+1" - test: - description: test - source: hosted - version: "0.12.1" - watcher: - description: watcher - source: hosted - version: "0.9.5" - yaml: - description: yaml - source: hosted - version: "2.1.2" From 56cefdeb98f127f03e80bc29eb4caf5905f12fce Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 18 Aug 2015 08:53:55 -0700 Subject: [PATCH 127/657] Invalid test cleanup (parse_test). --- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/parse_test.dart | 7 ------- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 625f48625..f4e355e2c 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.1.3-dev + +- Invalid test cleanup (to keepup with changes in `Uri`). + ## 0.1.1 - Syntax updates. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index d3acb9064..4cc000616 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.1.2 +version: 0.1.3-dev description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 3c02c84b6..6f830a103 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -74,13 +74,6 @@ main() { equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); - test("dot-dot 2", () { - var packages = doParse(singleRelativeSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:qux/../foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - test("all valid chars can be used in URI segment", () { var packages = doParse(allValidCharsSample, base); expect(packages.packages.toList(), equals([allValidChars])); From c73974c3c5c918b9ccbde699e7c6ff81b8818e79 Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 18 Aug 2015 09:45:31 -0700 Subject: [PATCH 128/657] Static warning fix. --- pkgs/package_config/lib/packages_file.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 25d2d6883..3f432aa70 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -109,7 +109,7 @@ void write(StringSink output, Map packageMapping, } if (uri.scheme == "package") { throw new ArgumentError.value( - "Package location must not be a package: URI", uri); + "Package location must not be a package: URI", uri.toString()); } output.write(packageName); output.write(':'); From e6834f345812b5d0f2e8a4e77095cf8a73bdc96f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 18 Aug 2015 15:01:35 -0700 Subject: [PATCH 129/657] Support external implementations of FileSpan. Previously, several FileSpan methods assumed that all FileSpans were implementations of this package's FileSpan class. However, this may not always be true. It can be useful to create FileSpans without first creating a SourceFile when efficient representations of line/column information are already available, and the user doesn't want to eagerly do the parsing necessary to create a full SourceFile. This also fixes an inconsistency between FileSpan.== and FileSpan.hashCode. R=sigmund@google.com Review URL: https://codereview.chromium.org//1298093002 . --- pkgs/source_span/CHANGELOG.md | 7 ++++ pkgs/source_span/lib/src/file.dart | 51 ++++++++++++++++++++---------- pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 51b0feaa0..8ca9e5cf0 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.1.3 + +* `FileSpan.compareTo`, `FileSpan.==`, `FileSpan.union`, and `FileSpan.expand` + no longer throw exceptions for external implementations of `FileSpan`. + +* `FileSpan.hashCode` now fully agrees with `FileSpan.==`. + # 1.1.2 * Fixed validation in `SourceSpanWithContext` to allow multiple occurrences of diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 4b4e026cb..c180929f7 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -7,9 +7,6 @@ library source_span.file; import 'dart:math' as math; import 'dart:typed_data'; -import 'package:path/path.dart' as p; - -import 'colors.dart' as colors; import 'location.dart'; import 'span.dart'; import 'span_mixin.dart'; @@ -74,7 +71,7 @@ class SourceFile { /// If [end] isn't passed, it defaults to the end of the file. FileSpan span(int start, [int end]) { if (end == null) end = length - 1; - return new FileSpan._(this, start, end); + return new _FileSpan(this, start, end); } /// Returns a location in [this] at [offset]. @@ -173,7 +170,7 @@ class FileLocation extends SourceLocation { } } - FileSpan pointSpan() => new FileSpan._(file, offset, offset); + FileSpan pointSpan() => new _FileSpan(file, offset, offset); } /// A [SourceSpan] within a [SourceFile]. @@ -184,8 +181,23 @@ class FileLocation extends SourceLocation { /// [FileSpan.union] will return a [FileSpan] if possible. /// /// A [FileSpan] can be created using [SourceFile.span]. -class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { +abstract class FileSpan implements SourceSpanWithContext { /// The [file] that [this] belongs to. + SourceFile get file; + + /// Returns a new span that covers both [this] and [other]. + /// + /// Unlike [union], [other] may be disjoint from [this]. If it is, the text + /// between the two will be covered by the returned span. + FileSpan expand(FileSpan other); +} + +/// The implementation of [FileSpan]. +/// +/// This is split into a separate class so that `is _FileSpan` checks can be run +/// to make certain operations more efficient. If we used `is FileSpan`, that +/// would break if external classes implemented the interface. +class _FileSpan extends SourceSpanMixin implements FileSpan { final SourceFile file; /// The offset of the beginning of the span. @@ -208,7 +220,7 @@ class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { String get context => file.getText(file.getOffset(start.line), end.line == file.lines - 1 ? null : file.getOffset(end.line + 1)); - FileSpan._(this.file, this._start, this._end) { + _FileSpan(this.file, this._start, this._end) { if (_end < _start) { throw new ArgumentError('End $_end must come after start $_start.'); } else if (_end > file.length) { @@ -220,9 +232,9 @@ class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { } int compareTo(SourceSpan other) { - if (other is! FileSpan) return super.compareTo(other); + if (other is! _FileSpan) return super.compareTo(other); - FileSpan otherFile = other; + _FileSpan otherFile = other; var result = _start.compareTo(otherFile._start); return result == 0 ? _end.compareTo(otherFile._end) : result; } @@ -230,7 +242,7 @@ class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { SourceSpan union(SourceSpan other) { if (other is! FileSpan) return super.union(other); - var span = expand(other); + _FileSpan span = expand(other); var beginSpan = span._start == _start ? this : other; var endSpan = span._end == _end ? this : other; @@ -243,13 +255,14 @@ class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { bool operator ==(other) { if (other is! FileSpan) return super == other; + if (other is! _FileSpan) { + return super == other && sourceUrl == other.sourceUrl; + } + return _start == other._start && _end == other._end && sourceUrl == other.sourceUrl; } - int get hashCode => _start.hashCode + 5 * _end.hashCode + - 7 * sourceUrl.hashCode; - /// Returns a new span that covers both [this] and [other]. /// /// Unlike [union], [other] may be disjoint from [this]. If it is, the text @@ -260,8 +273,14 @@ class FileSpan extends SourceSpanMixin implements SourceSpanWithContext { " \"${other.sourceUrl}\" don't match."); } - var start = math.min(this._start, other._start); - var end = math.max(this._end, other._end); - return new FileSpan._(file, start, end); + if (other is _FileSpan) { + var start = math.min(this._start, other._start); + var end = math.max(this._end, other._end); + return new _FileSpan(file, start, end); + } else { + var start = math.min(this._start, other.start.offset); + var end = math.max(this._end, other.end.offset); + return new _FileSpan(file, start, end); + } } } diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 8f69deb3c..daee3f61c 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.1.3-dev +version: 1.1.3 author: Dart Team description: A library for identifying source spans and locations. homepage: http://github.com/dart-lang/source_span From 57e55d1ba4e85bb0f73b536d72174211f98d4f6a Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 20 Aug 2015 11:17:58 +0200 Subject: [PATCH 130/657] Add slash to package dir URI after resolving reference against base. Used to add slash to reference before resolving it. It only makes a difference for the empty URI reference which never makes sense anyway - this just ensures the error is the same as on the VM. It is, arguably, what the specification requires. R=sgjesse@google.com Review URL: https://codereview.chromium.org//1297923004. --- pkgs/package_config/lib/packages_file.dart | 2 +- pkgs/package_config/test/parse_test.dart | 32 ++++++++++++++++------ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 3f432aa70..f30781dc3 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -57,11 +57,11 @@ Map parse(List source, Uri baseLocation) { } var packageUri = new String.fromCharCodes(source, separatorIndex + 1, end); var packageLocation = Uri.parse(packageUri); + packageLocation = baseLocation.resolveUri(packageLocation); if (!packageLocation.path.endsWith('/')) { packageLocation = packageLocation.replace(path: packageLocation.path + "/"); } - packageLocation = baseLocation.resolveUri(packageLocation); if (result.containsKey(packageName)) { throw new FormatException( "Same package name occured twice.", source, start); diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 6f830a103..8ed5c2eb7 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -50,13 +50,27 @@ main() { equals(base.resolve("../test/").resolve("bar/baz.dart"))); }); - test("single absolute", () { + test("single absolute authority", () { var packages = doParse(singleAbsoluteSample, base); expect(packages.packages.toList(), equals(["foo"])); expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), equals(Uri.parse("http://example.com/some/where/bar/baz.dart"))); }); + test("single empty path", () { + var packages = doParse(singleEmptyPathSample, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.replace(path: "${base.path}/bar/baz.dart"))); + }); + + test("single absolute path", () { + var packages = doParse(singleAbsolutePathSample, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.replace(path: "/test/bar/baz.dart"))); + }); + test("multiple", () { var packages = doParse(multiRelativeSample, base); expect( @@ -121,14 +135,16 @@ Packages doParse(String sample, Uri baseUri) { } // Valid samples. -var emptySample = ""; -var commentOnlySample = "# comment only\n"; -var emptyLinesSample = "\n\n\r\n"; -var singleRelativeSample = "foo:../test/\n"; -var singleRelativeSampleNoSlash = "foo:../test\n"; +var emptySample = ""; +var commentOnlySample = "# comment only\n"; +var emptyLinesSample = "\n\n\r\n"; +var singleRelativeSample = "foo:../test/\n"; +var singleRelativeSampleNoSlash = "foo:../test\n"; var singleRelativeSampleNoNewline = "foo:../test/"; -var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; -var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; +var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; +var singleEmptyPathSample = "foo:\n"; +var singleAbsolutePathSample = "foo:/test/\n"; +var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; // All valid path segment characters in an URI. var allValidChars = r"!$&'()*+,-.0123456789;=" From 24e3e0c664fc0a667b825f722244956bdfb7a15c Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 20 Aug 2015 12:46:36 +0200 Subject: [PATCH 131/657] Update version number before publishing. BUG= Review URL: https://codereview.chromium.org/1301443005 . --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 4cc000616..f2c4e06cc 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.1.3-dev +version: 0.1.3 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From 433b99839a2fc64644d2d3e17a16afad1662a43c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 27 Aug 2015 18:14:01 -0700 Subject: [PATCH 132/657] Eliminate dart2js warning about overriding `==`, but not `hashCode`. Closes dart-lang/source_spandart-lang/source_span#5 R=nweiz@google.com Review URL: https://codereview.chromium.org//1315423002 . --- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/lib/src/file.dart | 3 +++ pkgs/source_span/pubspec.yaml | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 8ca9e5cf0..5f87aeeaf 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.1.4 + +* Eliminated dart2js warning about overriding `==`, but not `hashCode`. + # 1.1.3 * `FileSpan.compareTo`, `FileSpan.==`, `FileSpan.union`, and `FileSpan.expand` diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index c180929f7..aee3d7831 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -263,6 +263,9 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { sourceUrl == other.sourceUrl; } + // Eliminates dart2js warning about overriding `==`, but not `hashCode` + int get hashCode => super.hashCode; + /// Returns a new span that covers both [this] and [other]. /// /// Unlike [union], [other] may be disjoint from [this]. If it is, the text diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index daee3f61c..3da9c289a 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,8 +1,8 @@ name: source_span -version: 1.1.3 +version: 1.1.4 author: Dart Team description: A library for identifying source spans and locations. -homepage: http://github.com/dart-lang/source_span +homepage: https://github.com/dart-lang/source_span dependencies: path: '>=1.2.0 <2.0.0' environment: From b1e9d7546144392632dab050dded563267e642d4 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 1 Sep 2015 15:45:23 -0700 Subject: [PATCH 133/657] Make the package strong-mode clean. This caught a bug in which we were calling _FileSpan._start and _FileSpan._end on a span we couldn't guarantee to be a _FileSpan. R=sigmund@google.com Review URL: https://codereview.chromium.org//1328583002 . --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/file.dart | 13 +++++++++---- pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 5f87aeeaf..10d94f6ab 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.1.5 + +* Fixed another case in which `FileSpan.union` could throw an exception for + external implementations of `FileSpan`. + # 1.1.4 * Eliminated dart2js warning about overriding `==`, but not `hashCode`. diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index aee3d7831..e5bc53c81 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -242,12 +242,17 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { SourceSpan union(SourceSpan other) { if (other is! FileSpan) return super.union(other); + _FileSpan span = expand(other); - var beginSpan = span._start == _start ? this : other; - var endSpan = span._end == _end ? this : other; - if (beginSpan._end < endSpan._start) { - throw new ArgumentError("Spans $this and $other are disjoint."); + if (other is _FileSpan) { + if (this._start > other._end || other._start > this._end) { + throw new ArgumentError("Spans $this and $other are disjoint."); + } + } else { + if (this._start > other.end.offset || other.start.offset > this._end) { + throw new ArgumentError("Spans $this and $other are disjoint."); + } } return span; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 3da9c289a..2bfbe4e2f 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.1.4 +version: 1.1.5 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From 445aa0ec6c4d0c95e79b398451659b46b4fd448a Mon Sep 17 00:00:00 2001 From: Robert Nystrom Date: Tue, 1 Sep 2015 17:37:16 -0700 Subject: [PATCH 134/657] Optimize successive calls SourceFile.getLine(). R=nweiz@google.com Review URL: https://codereview.chromium.org//1319303004 . --- pkgs/source_span/CHANGELOG.md | 1 + pkgs/source_span/lib/src/file.dart | 62 +++++++++++++++++++++++++- pkgs/source_span/lib/src/location.dart | 6 +-- pkgs/source_span/lib/src/utils.dart | 23 ---------- pkgs/source_span/test/utils_test.dart | 34 -------------- 5 files changed, 64 insertions(+), 62 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 10d94f6ab..caf8af5e5 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -2,6 +2,7 @@ * Fixed another case in which `FileSpan.union` could throw an exception for external implementations of `FileSpan`. +* Optimize `getLine()` in `SourceFile` when repeatedly called. # 1.1.4 diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index e5bc53c81..c2b97e782 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -11,7 +11,6 @@ import 'location.dart'; import 'span.dart'; import 'span_mixin.dart'; import 'span_with_context.dart'; -import 'utils.dart'; // Constants to determine end-of-lines. const int _LF = 10; @@ -43,6 +42,14 @@ class SourceFile { /// The number of lines in the file. int get lines => _lineStarts.length; + /// The line that the offset fell on the last time [getLine] was called. + /// + /// In many cases, sequential calls to getLine() are for nearby, usually + /// 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; + /// Creates a new source file from [text]. /// /// [url] may be either a [String], a [Uri], or `null`. @@ -85,7 +92,58 @@ class SourceFile { throw new RangeError("Offset $offset must not be greater than the number " "of characters in the file, $length."); } - return binarySearch(_lineStarts, (o) => o > offset) - 1; + + if (offset < _lineStarts.first) return -1; + if (offset >= _lineStarts.last) return _lineStarts.length - 1; + + if (_isNearCachedLine(offset)) return _cachedLine; + + _cachedLine = _binarySearch(offset) - 1; + return _cachedLine; + } + + /// Returns `true` if [offset] is near [_cachedLine]. + /// + /// Checks on [_cachedLine] and the next line. If it's on the next line, it + /// updates [_cachedLine] to point to that. + bool _isNearCachedLine(int offset) { + if (_cachedLine == null) return false; + + // See if it's before the cached line. + if (offset < _lineStarts[_cachedLine]) return false; + + // See if it's on the cached line. + 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++; + return true; + } + + return false; + } + + /// Binary search through [_lineStarts] to find the line containing [offset]. + /// + /// Returns the index of the line in [_lineStarts]. + int _binarySearch(int offset) { + int min = 0; + int max = _lineStarts.length - 1; + while (min < max) { + var half = min + ((max - min) ~/ 2); + if (_lineStarts[half] > offset) { + max = half; + } else { + min = half + 1; + } + } + + return max; } /// Gets the 0-based column corresponding to [offset]. diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 27057424b..42e2b7dd7 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -44,11 +44,11 @@ class SourceLocation implements Comparable { line = line == null ? 0 : line, column = column == null ? offset : column { if (this.offset < 0) { - throw new RangeError("Offset may not be negative, was $offset."); + throw new RangeError("Offset may not be negative, was ${this.offset}."); } else if (this.line < 0) { - throw new RangeError("Line may not be negative, was $line."); + throw new RangeError("Line may not be negative, was ${this.line}."); } else if (this.column < 0) { - throw new RangeError("Column may not be negative, was $column."); + throw new RangeError("Column may not be negative, was ${this.column}."); } } diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 2d3386542..fa0895784 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -14,29 +14,6 @@ Comparable min(Comparable obj1, Comparable obj2) => Comparable max(Comparable obj1, Comparable obj2) => obj1.compareTo(obj2) > 0 ? obj1 : obj2; -/// Find the first entry in a sorted [list] that matches a monotonic predicate. -/// -/// Given a result `n`, that all items before `n` will not match, `n` matches, -/// and all items after `n` match too. The result is -1 when there are no -/// items, 0 when all items match, and list.length when none does. -int binarySearch(List list, bool matches(item)) { - if (list.length == 0) return -1; - if (matches(list.first)) return 0; - if (!matches(list.last)) return list.length; - - int min = 0; - int max = list.length - 1; - while (min < max) { - var half = min + ((max - min) ~/ 2); - if (matches(list[half])) { - max = half; - } else { - min = half + 1; - } - } - return max; -} - /// Finds a line in [context] containing [text] at the specified [column]. /// /// Returns the index in [context] where that line begins, or null if none diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index 3b6238b55..5d973f58a 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -6,40 +6,6 @@ import 'package:test/test.dart'; import 'package:source_span/src/utils.dart'; main() { - group('binary search', () { - test('empty', () { - expect(binarySearch([], (x) => true), -1); - }); - - test('single element', () { - expect(binarySearch([1], (x) => true), 0); - expect(binarySearch([1], (x) => false), 1); - }); - - test('no matches', () { - var list = [1, 2, 3, 4, 5, 6, 7]; - expect(binarySearch(list, (x) => false), list.length); - }); - - test('all match', () { - var list = [1, 2, 3, 4, 5, 6, 7]; - expect(binarySearch(list, (x) => true), 0); - }); - - test('compare with linear search', () { - for (int size = 0; size < 100; size++) { - var list = []; - for (int i = 0; i < size; i++) { - list.add(i); - } - for (int pos = 0; pos <= size; pos++) { - expect(binarySearch(list, (x) => x >= pos), - _linearSearch(list, (x) => x >= pos)); - } - } - }); - }); - group('find line start', () { test('skip entries in wrong column', () { var context = '0_bb\n1_bbb\n2b____\n3bbb\n'; From b7846b03244d6121735badb9009158cc4aa642cd Mon Sep 17 00:00:00 2001 From: Robert Nystrom Date: Tue, 1 Sep 2015 17:42:23 -0700 Subject: [PATCH 135/657] Bump version. R=nweiz@google.com Review URL: https://codereview.chromium.org//1312623006 . --- pkgs/source_span/CHANGELOG.md | 5 ++++- pkgs/source_span/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index caf8af5e5..59923d511 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,8 +1,11 @@ +# 1.1.6 + +* Optimize `getLine()` in `SourceFile` when repeatedly called. + # 1.1.5 * Fixed another case in which `FileSpan.union` could throw an exception for external implementations of `FileSpan`. -* Optimize `getLine()` in `SourceFile` when repeatedly called. # 1.1.4 diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 2bfbe4e2f..a084bdf52 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.1.5 +version: 1.1.6 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From 7d0ff863609f07a8bf994c948ec0803c05aaa6ac Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 2 Sep 2015 11:44:06 -0700 Subject: [PATCH 136/657] Fix a performance bug with FileLocation. The bug was actually located in SourceLocation. The constructor accesses this.line and `this.column` in preference to the arguments it was passed, which was fine for normal SourceLocations but for FileLocations caused two binary searches to be performed every time a location was instantiated. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1328613002 . --- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/lib/src/location.dart | 12 ++++++------ pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 59923d511..6bd18f170 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.2.0 + +* Dramatically improve the performance of `FileLocation`. + # 1.1.6 * Optimize `getLine()` in `SourceFile` when repeatedly called. diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 42e2b7dd7..024c6e278 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -43,12 +43,12 @@ class SourceLocation implements Comparable { offset = offset, line = line == null ? 0 : line, column = column == null ? offset : column { - if (this.offset < 0) { - throw new RangeError("Offset may not be negative, was ${this.offset}."); - } else if (this.line < 0) { - throw new RangeError("Line may not be negative, was ${this.line}."); - } else if (this.column < 0) { - throw new RangeError("Column may not be negative, was ${this.column}."); + if (offset < 0) { + throw new RangeError("Offset may not be negative, was $offset."); + } else if (line != null && line < 0) { + throw new RangeError("Line may not be negative, was $line."); + } else if (column != null && column < 0) { + throw new RangeError("Column may not be negative, was $column."); } } diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index a084bdf52..7ffbc6448 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.1.6 +version: 1.2.0-dev author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From e61c7fd3bf510660bc4d7f129d3ad7f1536ea3e8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 2 Sep 2015 13:32:02 -0700 Subject: [PATCH 137/657] Add SourceLocationMixin and SourceLocationBase. This allows FileLocation to avoid extending SourceLocation at all, which avoids unused line, column, and sourceUrl fields. This produces a speed improvement of approximately 5% in the YAML parser, and will likely do more in code that uses locations more heavily relative to spans. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1307123004 . --- pkgs/source_span/CHANGELOG.md | 4 ++ pkgs/source_span/lib/source_span.dart | 1 + pkgs/source_span/lib/src/file.dart | 11 +++-- pkgs/source_span/lib/src/location.dart | 15 +++++- pkgs/source_span/lib/src/location_mixin.dart | 51 ++++++++++++++++++++ pkgs/source_span/pubspec.yaml | 2 +- 6 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 pkgs/source_span/lib/src/location_mixin.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 6bd18f170..ab13bda83 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,5 +1,9 @@ # 1.2.0 +* **Deprecated:** Extending `SourceLocation` directly is deprecated. Instead, + extend the new `SourceLocationBase` class or mix in the new + `SourceLocationMixin` mixin. + * Dramatically improve the performance of `FileLocation`. # 1.1.6 diff --git a/pkgs/source_span/lib/source_span.dart b/pkgs/source_span/lib/source_span.dart index 89b1650ea..9666dc296 100644 --- a/pkgs/source_span/lib/source_span.dart +++ b/pkgs/source_span/lib/source_span.dart @@ -6,6 +6,7 @@ library source_span; export "src/file.dart"; export "src/location.dart"; +export "src/location_mixin.dart"; export "src/span.dart"; export "src/span_exception.dart"; export "src/span_mixin.dart"; diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index c2b97e782..95fa92ca3 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -8,6 +8,7 @@ import 'dart:math' as math; import 'dart:typed_data'; import 'location.dart'; +import 'location_mixin.dart'; import 'span.dart'; import 'span_mixin.dart'; import 'span_with_context.dart'; @@ -212,17 +213,19 @@ class SourceFile { /// and column values based on its offset and the contents of [file]. /// /// A [FileLocation] can be created using [SourceFile.location]. -class FileLocation extends SourceLocation { +class FileLocation extends SourceLocationMixin implements SourceLocation { /// The [file] that [this] belongs to. final SourceFile file; + final int offset; Uri get sourceUrl => file.url; int get line => file.getLine(offset); int get column => file.getColumn(offset); - FileLocation._(this.file, int offset) - : super(offset) { - if (offset > file.length) { + FileLocation._(this.file, this.offset) { + if (offset < 0) { + throw new RangeError("Offset may not be negative, was $offset."); + } else if (offset > file.length) { throw new RangeError("Offset $offset must not be greater than the number " "of characters in the file, ${file.length}."); } diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 024c6e278..afb37c768 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -6,7 +6,13 @@ library source_span.location; import 'span.dart'; -// A class that describes a single location within a source file. +// TODO(nweiz): Use SourceLocationMixin once we decide to cut a release with +// breaking changes. See SourceLocationMixin for details. + +/// A class that describes a single location within a source file. +/// +/// This class should not be extended. Instead, [SourceLocationBase] should be +/// extended instead. class SourceLocation implements Comparable { /// URL of the source containing this location. /// @@ -85,3 +91,10 @@ class SourceLocation implements Comparable { String toString() => '<$runtimeType: $offset $toolString>'; } + +/// 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}) + : super(offset, sourceUrl: sourceUrl, line: line, column: column); +} diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart new file mode 100644 index 000000000..5aa0de5ce --- /dev/null +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2015, 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. + +library source_span.location_mixin; + +import 'location.dart'; +import 'span.dart'; + +// Note: this class duplicates a lot of functionality of [SourceLocation]. This +// is because in order for SourceLocation to use SourceLocationMixin, +// SourceLocationMixin couldn't implement SourceLocation. In SourceSpan we +// handle this by making the class itself non-extensible, but that would be a +// breaking change for SourceLocation. So until we want to endure the pain of +// cutting a release with breaking changes, we duplicate the code here. + +/// A mixin for easily implementing [SourceLocation]. +abstract class SourceLocationMixin implements SourceLocation { + String get toolString { + var source = sourceUrl == null ? 'unknown source' : sourceUrl; + return '$source:${line + 1}:${column + 1}'; + } + + int distance(SourceLocation other) { + if (sourceUrl != other.sourceUrl) { + throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + "\"${other.sourceUrl}\" don't match."); + } + return (offset - other.offset).abs(); + } + + SourceSpan pointSpan() => new SourceSpan(this, this, ""); + + int compareTo(SourceLocation other) { + if (sourceUrl != other.sourceUrl) { + throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + "\"${other.sourceUrl}\" don't match."); + } + return offset - other.offset; + } + + bool operator ==(other) => + other is SourceLocation && + sourceUrl == other.sourceUrl && + offset == other.offset; + + int get hashCode => sourceUrl.hashCode + offset; + + String toString() => '<$runtimeType: $offset $toolString>'; +} + diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 7ffbc6448..25de799d7 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.2.0-dev +version: 1.2.0 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From ba56d6613604908223abf6dd484daf66ac531f88 Mon Sep 17 00:00:00 2001 From: Seth Ladd Date: Wed, 16 Sep 2015 10:00:40 -0700 Subject: [PATCH 138/657] Go SSL --- pkgs/package_config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 9a0995d6b..0463719b3 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -4,7 +4,7 @@ Support for working with **Package Resolution Configuration** files as described in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), under review [here] (https://github.com/dart-lang/dart_enhancement_proposals/issues/5). -[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](http://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) +[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) ## Features and bugs From 5cedf8e1431947e4284a31562813e789c9b38f68 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Sat, 19 Sep 2015 17:40:05 -0700 Subject: [PATCH 139/657] fix param types on methods in _EmptyVersion --- pkgs/pub_semver/.gitignore | 1 + pkgs/pub_semver/CHANGELOG.md | 6 ++++++ pkgs/pub_semver/lib/src/version_constraint.dart | 4 ++-- pkgs/pub_semver/pubspec.yaml | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/pkgs/pub_semver/.gitignore b/pkgs/pub_semver/.gitignore index 7178642c2..98fed01aa 100644 --- a/pkgs/pub_semver/.gitignore +++ b/pkgs/pub_semver/.gitignore @@ -1,3 +1,4 @@ +.packages packages pubspec.lock diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 58190a8a6..7dca24ce3 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.2.2 + +* Make the package analyze under strong mode and compile with the DDC (Dart Dev + Compiler). Fix two issues with a private subclass of `VersionConstraint` + having different types for overridden methods. + # 1.2.1 * Allow version ranges like `>=1.2.3-dev.1 <1.2.3` to match pre-release versions diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 3f4d5b8c8..dbd0aa5ad 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -209,8 +209,8 @@ class _EmptyVersion implements VersionConstraint { bool get isEmpty => true; bool get isAny => false; bool allows(Version other) => false; - bool allowsAll(Version other) => other.isEmpty; - bool allowsAny(Version other) => false; + bool allowsAll(VersionConstraint other) => other.isEmpty; + bool allowsAny(VersionConstraint other) => false; VersionConstraint intersect(VersionConstraint other) => this; VersionConstraint union(VersionConstraint other) => other; String toString() => ''; diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 33545a37b..530a4cea8 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.2.1 +version: 1.2.2 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 57c51dd58735056e73fa5615d61a7946949fb862 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 30 Sep 2015 13:37:33 -0700 Subject: [PATCH 140/657] Fix the typing of FileSpan.{start,end}. R=kevmoo@google.com Review URL: https://codereview.chromium.org//1376433003 . --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/file.dart | 3 +++ pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index ab13bda83..ce7198068 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.2.1 + +* Fix the declared type of `FileSpan.start` and `FileSpan.end`. In 1.2.0 these + were mistakenly changed from `FileLocation` to `SourceLocation`. + # 1.2.0 * **Deprecated:** Extending `SourceLocation` directly is deprecated. Instead, diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 95fa92ca3..37790ce92 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -246,6 +246,9 @@ abstract class FileSpan implements SourceSpanWithContext { /// The [file] that [this] belongs to. SourceFile get file; + FileLocation get start; + FileLocation get end; + /// Returns a new span that covers both [this] and [other]. /// /// Unlike [union], [other] may be disjoint from [this]. If it is, the text diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 25de799d7..4c703cdc2 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.2.0 +version: 1.2.1 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From f3bd1c5082a019d63d93432fdeec15a207327889 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 8 Oct 2015 17:46:26 -0700 Subject: [PATCH 141/657] Add Pool.close(). R=rnystrom@google.com Review URL: https://codereview.chromium.org//1393193004 . --- pkgs/pool/CHANGELOG.md | 5 ++ pkgs/pool/lib/pool.dart | 76 ++++++++++++++++--- pkgs/pool/pubspec.yaml | 3 +- pkgs/pool/test/pool_test.dart | 133 ++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 13 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index ec8fd79a8..9f74d07b4 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.2.0 + +* Add `Pool.close()`, which forbids new resource requests and releases all + releasable resources. + ## 1.1.0 * Add `PoolResource.allowRelease()`, which allows a resource to indicate that it diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index e8ee99cab..59b949e0e 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -7,6 +7,7 @@ library pool; import 'dart:async'; import 'dart:collection'; +import 'package:async/async.dart'; import 'package:stack_trace/stack_trace.dart'; /// Manages an abstract pool of resources with a limit on how many may be in use @@ -55,6 +56,15 @@ class Pool { /// The amount of time to wait before timing out the pending resources. final Duration _timeout; + /// A [FutureGroup] that tracks all the `onRelease` callbacks for resources + /// that have been marked releasable. + /// + /// This is `null` until [close] is called. + FutureGroup _closeGroup; + + /// Whether [close] has been called. + bool get isClosed => _closeGroup != null; + /// Creates a new pool with the given limit on how many resources may be /// allocated at once. /// @@ -69,6 +79,10 @@ class Pool { /// If the maximum number of resources is already allocated, this will delay /// until one of them is released. Future request() { + if (isClosed) { + throw new StateError("request() may not be called on a closed Pool."); + } + if (_allocatedResources < _maxAllocatedResources) { _allocatedResources++; return new Future.value(new PoolResource._(this)); @@ -87,20 +101,56 @@ class Pool { /// /// The return value of [callback] is piped to the returned Future. Future withResource(callback()) { - return request().then((resource) => new Future.sync(callback).whenComplete(resource.release)); + if (isClosed) { + throw new StateError( + "withResource() may not be called on a closed Pool."); + } + + // TODO(nweiz): Use async/await when sdk#23497 is fixed. + return request().then((resource) { + return new Future.sync(callback).whenComplete(resource.release); + }); + } + + /// Closes the pool so that no more resources are requested. + /// + /// Existing resource requests remain unchanged. + /// + /// Any resources that are marked as releasable using + /// [PoolResource.allowRelease] are released immediately. Once all resources + /// have been released and any `onRelease` callbacks have completed, the + /// returned future completes successfully. If any `onRelease` callback throws + /// an error, the returned future completes with that error. + /// + /// This may be called more than once; it returns the same [Future] each time. + Future close() { + if (_closeGroup != null) return _closeGroup.future; + + _resetTimer(); + + _closeGroup = new FutureGroup(); + for (var callback in _onReleaseCallbacks) { + _closeGroup.add(new Future.sync(callback)); + } + + _allocatedResources -= _onReleaseCallbacks.length; + _onReleaseCallbacks.clear(); + + if (_allocatedResources == 0) _closeGroup.close(); + return _closeGroup.future; } /// If there are any pending requests, this will fire the oldest one. void _onResourceReleased() { _resetTimer(); - if (_requestedResources.isEmpty) { + if (_requestedResources.isNotEmpty) { + var pending = _requestedResources.removeFirst(); + pending.complete(new PoolResource._(this)); + } else { _allocatedResources--; - return; + if (isClosed && _allocatedResources == 0) _closeGroup.close(); } - - var pending = _requestedResources.removeFirst(); - pending.complete(new PoolResource._(this)); } /// If there are any pending requests, this will fire the oldest one after @@ -108,14 +158,17 @@ class Pool { void _onResourceReleaseAllowed(onRelease()) { _resetTimer(); - if (_requestedResources.isEmpty) { + if (_requestedResources.isNotEmpty) { + var pending = _requestedResources.removeFirst(); + pending.complete(_runOnRelease(onRelease)); + } else if (isClosed) { + _closeGroup.add(new Future.sync(onRelease)); + _allocatedResources--; + if (_allocatedResources == 0) _closeGroup.close(); + } else { _onReleaseCallbacks.add( Zone.current.bindCallback(onRelease, runGuarded: false)); - return; } - - var pending = _requestedResources.removeFirst(); - pending.complete(_runOnRelease(onRelease)); } /// Runs [onRelease] and returns a Future that completes to a resource once an @@ -202,4 +255,3 @@ class PoolResource { _pool._onResourceReleaseAllowed(onRelease); } } - diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index cc2d367be..0013e9e2e 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,9 +1,10 @@ name: pool -version: 1.1.1-dev +version: 1.2.0 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool dependencies: + async: "^1.3.0" stack_trace: ">=0.9.2 <2.0.0" environment: sdk: ">=1.9.0 <2.0.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 5dfef2a24..65fd00ee2 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -271,6 +271,139 @@ void main() { pool.request(); }); }); + + group("close()", () { + test("disallows request() and withResource()", () { + var pool = new Pool(1)..close(); + expect(pool.request, throwsStateError); + expect(() => pool.withResource(() {}), throwsStateError); + }); + + test("pending requests are fulfilled", () async { + var pool = new Pool(1); + var resource1 = await pool.request(); + expect(pool.request().then((resource2) { + resource2.release(); + }), completes); + expect(pool.close(), completes); + resource1.release(); + }); + + test("pending requests are fulfilled with allowRelease", () async { + var pool = new Pool(1); + var resource1 = await pool.request(); + + var completer = new Completer(); + expect(pool.request().then((resource2) { + expect(completer.isCompleted, isTrue); + resource2.release(); + }), completes); + expect(pool.close(), completes); + + resource1.allowRelease(() => completer.future); + await new Future.delayed(Duration.ZERO); + + completer.complete(); + }); + + test("doesn't complete until all resources are released", () async { + var pool = new Pool(2); + var resource1 = await pool.request(); + var resource2 = await pool.request(); + var resource3Future = pool.request(); + + var resource1Released = false; + var resource2Released = false; + var resource3Released = false; + expect(pool.close().then((_) { + expect(resource1Released, isTrue); + expect(resource2Released, isTrue); + expect(resource3Released, isTrue); + }), completes); + + resource1Released = true; + resource1.release(); + await new Future.delayed(Duration.ZERO); + + resource2Released = true; + resource2.release(); + await new Future.delayed(Duration.ZERO); + + var resource3 = await resource3Future; + resource3Released = true; + resource3.release(); + }); + + test("active onReleases complete as usual", () async { + var pool = new Pool(1); + var resource = await pool.request(); + + // Set up an onRelease callback whose completion is controlled by + // [completer]. + var completer = new Completer(); + resource.allowRelease(() => completer.future); + expect(pool.request().then((_) { + expect(completer.isCompleted, isTrue); + }), completes); + + await new Future.delayed(Duration.ZERO); + pool.close(); + + await new Future.delayed(Duration.ZERO); + completer.complete(); + }); + + test("inactive onReleases fire", () async { + var pool = new Pool(2); + var resource1 = await pool.request(); + var resource2 = await pool.request(); + + var completer1 = new Completer(); + resource1.allowRelease(() => completer1.future); + var completer2 = new Completer(); + resource2.allowRelease(() => completer2.future); + + expect(pool.close().then((_) { + expect(completer1.isCompleted, isTrue); + expect(completer2.isCompleted, isTrue); + }), completes); + + await new Future.delayed(Duration.ZERO); + completer1.complete(); + + await new Future.delayed(Duration.ZERO); + completer2.complete(); + }); + + test("new allowReleases fire immediately", () async { + var pool = new Pool(1); + var resource = await pool.request(); + + var completer = new Completer(); + expect(pool.close().then((_) { + expect(completer.isCompleted, isTrue); + }), completes); + + await new Future.delayed(Duration.ZERO); + resource.allowRelease(() => completer.future); + + await new Future.delayed(Duration.ZERO); + completer.complete(); + }); + + test("an onRelease error is piped to the return value", () async { + var pool = new Pool(1); + var resource = await pool.request(); + + var completer = new Completer(); + resource.allowRelease(() => completer.future); + + expect(pool.close(), throwsA("oh no!")); + + await new Future.delayed(Duration.ZERO); + completer.completeError("oh no!"); + }); + }); } /// Returns a function that will cause the test to fail if it's called. From a166eafb1660b9891e67aa8b864db1d928313fcb Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 28 Oct 2015 14:47:31 -0700 Subject: [PATCH 142/657] Use the async package's new RestartableTimer class. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1415223004 . --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/lib/pool.dart | 31 ++++++++++++++++++++----------- pkgs/pool/pubspec.yaml | 4 ++-- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 9f74d07b4..dc852aa35 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.1 + +* Internal changes only. + ## 1.2.0 * Add `Pool.close()`, which forbids new resource requests and releases all diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 59b949e0e..ef3861418 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -46,12 +46,14 @@ class Pool { /// The timeout timer. /// - /// If [_timeout] isn't null, this timer is set as soon as the resource limit - /// is reached and is reset every time an resource is released or a new - /// resource is requested. If it fires, that indicates that the caller became - /// deadlocked, likely due to files waiting for additional files to be read - /// before they could be closed. - Timer _timer; + /// This timer is canceled as long as the pool is below the resource limit. + /// It's reset once the resource limit is reached and again every time an + /// resource is released or a new resource is requested. If it fires, that + /// indicates that the caller became deadlocked, likely due to files waiting + /// for additional files to be read before they could be closed. + /// + /// This is `null` if this pool shouldn't time out. + RestartableTimer _timer; /// The amount of time to wait before timing out the pending resources. final Duration _timeout; @@ -72,7 +74,13 @@ class Pool { /// all pending [request] futures will throw a [TimeoutException]. This is /// intended to avoid deadlocks. Pool(this._maxAllocatedResources, {Duration timeout}) - : _timeout = timeout; + : _timeout = timeout { + if (timeout != null) { + // Start the timer canceled since we only want to start counting down once + // we've run out of available resources. + _timer = new RestartableTimer(timeout, _onTimeout)..cancel(); + } + } /// Request a [PoolResource]. /// @@ -190,11 +198,12 @@ class Pool { /// A resource has been requested, allocated, or released. void _resetTimer() { - if (_timer != null) _timer.cancel(); - if (_timeout == null || _requestedResources.isEmpty) { - _timer = null; + if (_timer == null) return; + + if (_requestedResources.isEmpty) { + _timer.cancel(); } else { - _timer = new Timer(_timeout, _onTimeout); + _timer.reset(); } } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 0013e9e2e..963562007 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,10 +1,10 @@ name: pool -version: 1.2.0 +version: 1.2.1 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool dependencies: - async: "^1.3.0" + async: "^1.4.0" stack_trace: ">=0.9.2 <2.0.0" environment: sdk: ">=1.9.0 <2.0.0" From 245e70cade2a7db29f605c828a12cb63437d2b7d Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 30 Oct 2015 15:43:12 -0700 Subject: [PATCH 143/657] Fix three strong mode analysis issues. BUG=https://github.com/dart-lang/pub_semver/issues/10 R=nweiz@google.com Review URL: https://codereview.chromium.org//1417163006 . --- pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/lib/src/version_constraint.dart | 2 +- pkgs/pub_semver/lib/src/version_union.dart | 4 ++-- pkgs/pub_semver/pubspec.yaml | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 7dca24ce3..b505230e7 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.2.3 + +* Addressed three strong mode warnings. + # 1.2.2 * Make the package analyze under strong mode and compile with the DDC (Dart Dev diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index dbd0aa5ad..f84d8820e 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -114,7 +114,7 @@ abstract class VersionConstraint { var compatibleWith = matchCompatibleWith(); if (compatibleWith != null) return compatibleWith; - var constraints = []; + var constraints = []; while (true) { skipWhitespace(); diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index ee9f657ac..a6715145a 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -59,7 +59,7 @@ class VersionUnion implements VersionConstraint { (flattened as List).sort(compareMax); - var merged = []; + var merged = []; for (var constraint in flattened) { // Merge this constraint with the previous one, but only if they touch. if (merged.isEmpty || @@ -132,7 +132,7 @@ class VersionUnion implements VersionConstraint { // Because both lists of constraints are ordered by minimum version, we can // safely move through them linearly here. - var newConstraints = []; + var newConstraints = []; ourConstraints.moveNext(); theirConstraints.moveNext(); while (ourConstraints.current != null && theirConstraints.current != null) { diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 530a4cea8..0ed3e3bfc 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.2.2 +version: 1.2.3 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 389ddb974a7df6e7b2a71490e657d5653103d6dc Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 12 Jan 2016 17:22:16 -0800 Subject: [PATCH 144/657] Get rid of all the library tags. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1572383005 . --- pkgs/pool/lib/pool.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index ef3861418..3279160be 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -2,8 +2,6 @@ // 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. -library pool; - import 'dart:async'; import 'dart:collection'; From 150736782a2154b2a1875c9f55d2130951e303ed Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 12 Jan 2016 17:22:29 -0800 Subject: [PATCH 145/657] Get rid of all the library tags. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1581853003 . --- pkgs/pub_semver/lib/pub_semver.dart | 2 -- pkgs/pub_semver/lib/src/patterns.dart | 2 -- pkgs/pub_semver/lib/src/utils.dart | 2 -- pkgs/pub_semver/lib/src/version.dart | 2 -- pkgs/pub_semver/lib/src/version_constraint.dart | 2 -- pkgs/pub_semver/lib/src/version_range.dart | 2 -- pkgs/pub_semver/lib/src/version_union.dart | 2 -- pkgs/pub_semver/test/utils.dart | 2 -- pkgs/pub_semver/test/version_constraint_test.dart | 2 -- pkgs/pub_semver/test/version_range_test.dart | 2 -- pkgs/pub_semver/test/version_test.dart | 2 -- 11 files changed, 22 deletions(-) diff --git a/pkgs/pub_semver/lib/pub_semver.dart b/pkgs/pub_semver/lib/pub_semver.dart index 436e22600..fd2320e1c 100644 --- a/pkgs/pub_semver/lib/pub_semver.dart +++ b/pkgs/pub_semver/lib/pub_semver.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver; - export 'src/version.dart'; export 'src/version_constraint.dart'; export 'src/version_range.dart'; diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart index 8b3290095..4e57ec908 100644 --- a/pkgs/pub_semver/lib/src/patterns.dart +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.src.patterns; - /// Regex that matches a version number at the beginning of a string. final START_VERSION = new RegExp( r'^' // Start at beginning. diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index 2853e5cb4..74d015ac1 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.src.utils; - import 'version_range.dart'; /// Returns whether [range1] is immediately next to, but not overlapping, diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 51972f7dd..528c3a201 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.src.version; - import 'dart:math' as math; import 'package:collection/equality.dart'; diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index f84d8820e..f222b5199 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.src.version_constraint; - import 'patterns.dart'; import 'version.dart'; import 'version_range.dart'; diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 5c53834c6..668b9b28e 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.src.version_range; - import 'version.dart'; import 'version_constraint.dart'; import 'version_union.dart'; diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index a6715145a..27993416c 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.src.version_union; - import 'package:collection/collection.dart'; import 'utils.dart'; diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index 6fefdae76..e1d7446cc 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.test.utils; - import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index b38305498..bd6bf75cf 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.test.version_constraint_test; - import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 6df6b310a..9eaa98046 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.test.version_range_test; - import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index e3d1b49a9..ddc6c94b5 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -2,8 +2,6 @@ // 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. -library pub_semver.test.version_test; - import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; From ee812d53fe33e40942e013220fabab5e859ea9ac Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 12 Jan 2016 17:23:05 -0800 Subject: [PATCH 146/657] Get rid of all the library tags. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1583453004 . --- pkgs/source_span/lib/source_span.dart | 2 -- pkgs/source_span/lib/src/colors.dart | 2 -- pkgs/source_span/lib/src/file.dart | 2 -- pkgs/source_span/lib/src/location.dart | 2 -- pkgs/source_span/lib/src/location_mixin.dart | 2 -- pkgs/source_span/lib/src/span.dart | 2 -- pkgs/source_span/lib/src/span_exception.dart | 2 -- pkgs/source_span/lib/src/span_mixin.dart | 2 -- pkgs/source_span/lib/src/span_with_context.dart | 2 -- pkgs/source_span/lib/src/utils.dart | 2 -- 10 files changed, 20 deletions(-) diff --git a/pkgs/source_span/lib/source_span.dart b/pkgs/source_span/lib/source_span.dart index 9666dc296..6ed10a0e6 100644 --- a/pkgs/source_span/lib/source_span.dart +++ b/pkgs/source_span/lib/source_span.dart @@ -2,8 +2,6 @@ // 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. -library source_span; - export "src/file.dart"; export "src/location.dart"; export "src/location_mixin.dart"; diff --git a/pkgs/source_span/lib/src/colors.dart b/pkgs/source_span/lib/src/colors.dart index 274fc92af..e934cded7 100644 --- a/pkgs/source_span/lib/src/colors.dart +++ b/pkgs/source_span/lib/src/colors.dart @@ -3,8 +3,6 @@ // BSD-style license that can be found in the LICENSE file. // Color constants used for generating messages. -library source_span.colors; - const String RED = '\u001b[31m'; const String YELLOW = '\u001b[33m'; diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 37790ce92..1d39cf17a 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -2,8 +2,6 @@ // 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. -library source_span.file; - import 'dart:math' as math; import 'dart:typed_data'; diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index afb37c768..2d23db1a3 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -2,8 +2,6 @@ // 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. -library source_span.location; - import 'span.dart'; // TODO(nweiz): Use SourceLocationMixin once we decide to cut a release with diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index 5aa0de5ce..653c2c441 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -2,8 +2,6 @@ // 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. -library source_span.location_mixin; - import 'location.dart'; import 'span.dart'; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 9f150482c..fe1ac3956 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -2,8 +2,6 @@ // 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. -library source_span.span; - import 'location.dart'; import 'span_mixin.dart'; diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index 36f248832..ab0704614 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -2,8 +2,6 @@ // 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. -library source_span.span_exception; - import 'span.dart'; /// A class for exceptions that have source span information attached. diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index b4503facd..2d390b6a7 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -2,8 +2,6 @@ // 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. -library source_span.span_mixin; - import 'dart:math' as math; import 'package:path/path.dart' as p; diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart index 0012e3f3d..1336b1225 100644 --- a/pkgs/source_span/lib/src/span_with_context.dart +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -2,8 +2,6 @@ // 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. -library source_span.span_with_context; - import 'location.dart'; import 'span.dart'; import 'utils.dart'; diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index fa0895784..69385476c 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -2,8 +2,6 @@ // 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. -library source_span.utils; - /// Returns the minimum of [obj1] and [obj2] according to /// [Comparable.compareTo]. Comparable min(Comparable obj1, Comparable obj2) => From 64d82cadae71b1b77c5b76b01a2fccee983a0a0c Mon Sep 17 00:00:00 2001 From: Vijay Menon Date: Tue, 23 Feb 2016 05:46:50 -0800 Subject: [PATCH 147/657] Make SourceSpanException.source a getter The override in https://github.com/dart-lang/string_scanner/blob/master/lib/src/exception.dart is causing a problem in DDC / strong mode. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1722603005 . --- pkgs/source_span/lib/src/span_exception.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index ab0704614..921e62095 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -32,10 +32,13 @@ class SourceSpanException implements Exception { /// A [SourceSpanException] that's also a [FormatException]. class SourceSpanFormatException extends SourceSpanException implements FormatException { - final source; + final _source; + + // Subclasses may narrow the type. + dynamic get source => _source; int get offset => span == null ? null : span.start.offset; - SourceSpanFormatException(String message, SourceSpan span, [this.source]) + SourceSpanFormatException(String message, SourceSpan span, [this._source]) : super(message, span); } From cf91b57d90e500fce31fd5fc516c5d4948972560 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 2 Mar 2016 12:46:14 -0800 Subject: [PATCH 148/657] Allow some fields to be overridden in strong mode. For consistency, any field in a class that's meant to be extended can be overridden. R=lrn@google.com, rnystrom@google.com Review URL: https://codereview.chromium.org//1728113002 . --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/span_exception.dart | 15 +++++++++------ pkgs/source_span/lib/src/span_with_context.dart | 6 ++++-- pkgs/source_span/pubspec.yaml | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index ce7198068..cca6f11e6 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.2.2 + +* Allow `SourceSpanException.message`, `SourceSpanFormatException.source`, and + `SourceSpanWithContext.context` to be overridden in strong mode. + # 1.2.1 * Fix the declared type of `FileSpan.start` and `FileSpan.end`. In 1.2.0 these diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index 921e62095..6d3448b6c 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -6,15 +6,19 @@ import 'span.dart'; /// A class for exceptions that have source span information attached. class SourceSpanException implements Exception { + // This is a getter so that subclasses can override it. /// A message describing the exception. - final String message; + String get message => _message; + final String _message; + // This is a getter so that subclasses can override it. /// The span associated with this exception. /// /// This may be `null` if the source location can't be determined. - final SourceSpan span; + SourceSpan get span => _span; + final SourceSpan _span; - SourceSpanException(this.message, this.span); + SourceSpanException(this._message, this._span); /// Returns a string representation of [this]. /// @@ -32,10 +36,9 @@ class SourceSpanException implements Exception { /// A [SourceSpanException] that's also a [FormatException]. class SourceSpanFormatException extends SourceSpanException implements FormatException { - final _source; - - // Subclasses may narrow the type. + // This is a getter so that subclasses can override it. dynamic get source => _source; + final _source; int get offset => span == null ? null : span.start.offset; diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart index 1336b1225..a02d78047 100644 --- a/pkgs/source_span/lib/src/span_with_context.dart +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -8,8 +8,10 @@ import 'utils.dart'; /// A class that describes a segment of source text with additional context. class SourceSpanWithContext extends SourceSpanBase { + // This is a getter so that subclasses can override it. /// Text around the span, which includes the line containing this span. - final String context; + String get context => _context; + final String _context; /// Creates a new span from [start] to [end] (exclusive) containing [text], in /// the given [context]. @@ -20,7 +22,7 @@ class SourceSpanWithContext extends SourceSpanBase { /// [text] should start at `start.column` from the beginning of a line in /// [context]. SourceSpanWithContext( - SourceLocation start, SourceLocation end, String text, this.context) + SourceLocation start, SourceLocation end, String text, this._context) : super(start, end, text) { if (!context.contains(text)) { throw new ArgumentError( diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 4c703cdc2..7ca7de46d 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.2.1 +version: 1.2.2 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From 8ba5f7c7fca2f169df82f4533bc7494c56381f6b Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 8 Mar 2016 17:22:47 -0800 Subject: [PATCH 149/657] Fix unused import --- pkgs/source_maps/test/run.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart index b37fdcd6f..477da8a37 100755 --- a/pkgs/source_maps/test/run.dart +++ b/pkgs/source_maps/test/run.dart @@ -7,7 +7,6 @@ library test.run; import 'package:test/compact_vm_config.dart'; import 'package:test/test.dart'; -import 'dart:io' show Options; import 'builder_test.dart' as builder_test; import 'end2end_test.dart' as end2end_test; From 51e3022771f3e69af4327b544b8dfbbff17c3493 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 24 Mar 2016 13:21:49 -0700 Subject: [PATCH 150/657] Fix strong-mode warnings. R=sigmund@google.com Review URL: https://codereview.chromium.org//1826093002 . --- pkgs/source_maps/.analysis_options | 2 ++ pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/lib/parser.dart | 6 +++--- pkgs/source_maps/pubspec.yaml | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 pkgs/source_maps/.analysis_options diff --git a/pkgs/source_maps/.analysis_options b/pkgs/source_maps/.analysis_options new file mode 100644 index 000000000..a10d4c5a0 --- /dev/null +++ b/pkgs/source_maps/.analysis_options @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 3066293dd..4872d79a9 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.1+1 + +* Fix all strong mode warnings. + ## 0.10.1 * Add a `mapUrl` named argument to `parse` and `parseJson`. This argument is diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index a9fcff578..b659654f0 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -182,7 +182,7 @@ class SingleMapping extends Mapping { var names = new LinkedHashMap(); var lineNum; - var targetEntries; + List targetEntries; for (var sourceEntry in sourceEntries) { if (lineNum == null || sourceEntry.target.line > lineNum) { lineNum = sourceEntry.target.line; @@ -212,8 +212,8 @@ class SingleMapping extends Mapping { SingleMapping.fromJson(Map map, {mapUrl}) : targetUrl = map['file'], - urls = map['sources'], - names = map['names'], + urls = new List.from(map['sources']), + names = new List.from(map['names']), sourceRoot = map['sourceRoot'], lines = [], _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl { diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 86015d540..e8dd7940a 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.2-dev +version: 0.10.1+1 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps From bc986bb59e04b72b046850a6d7bf2bfb2d0469b5 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 31 Mar 2016 16:26:08 -0700 Subject: [PATCH 151/657] Fix strong mode warnings. R=jmesserly@google.com Review URL: https://codereview.chromium.org//1843303002 . --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/lib/pool.dart | 14 ++++++++------ pkgs/pool/pubspec.yaml | 2 +- pkgs/pool/test/pool_test.dart | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index dc852aa35..9ad86d0a8 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.2 + +* Fix strong mode warnings and add generic method annotations. + ## 1.2.1 * Internal changes only. diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 3279160be..f7bfd828b 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -106,16 +106,18 @@ class Pool { /// Future. /// /// The return value of [callback] is piped to the returned Future. - Future withResource(callback()) { + Future/**/ withResource/**/(/*=T*/ callback()) async { if (isClosed) { throw new StateError( "withResource() may not be called on a closed Pool."); } - // TODO(nweiz): Use async/await when sdk#23497 is fixed. - return request().then((resource) { - return new Future.sync(callback).whenComplete(resource.release); - }); + var resource = await request(); + try { + return await callback(); + } finally { + resource.release(); + } } /// Closes the pool so that no more resources are requested. @@ -189,7 +191,7 @@ class Pool { _onReleaseCompleters.removeFirst().completeError(error, stackTrace); }); - var completer = new Completer.sync(); + var completer = new Completer.sync(); _onReleaseCompleters.add(completer); return completer.future; } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 963562007..314ac044c 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.2.1 +version: 1.2.2 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 65fd00ee2..91e683310 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -276,7 +276,7 @@ void main() { test("disallows request() and withResource()", () { var pool = new Pool(1)..close(); expect(pool.request, throwsStateError); - expect(() => pool.withResource(() {}), throwsStateError); + expect(pool.withResource(() {}), throwsStateError); }); test("pending requests are fulfilled", () async { From cc6ce78eafd3d3d19f526cf5cc574c66945af40b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 31 Mar 2016 17:23:22 -0700 Subject: [PATCH 152/657] Fix all strong mode warnings. R=rnystrom@google.com Review URL: https://codereview.chromium.org//1843133004 . --- pkgs/pub_semver/.analysis_options | 2 ++ pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/lib/src/version.dart | 2 +- pkgs/pub_semver/lib/src/version_union.dart | 2 +- pkgs/pub_semver/pubspec.yaml | 2 +- 5 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 pkgs/pub_semver/.analysis_options diff --git a/pkgs/pub_semver/.analysis_options b/pkgs/pub_semver/.analysis_options new file mode 100644 index 000000000..a10d4c5a0 --- /dev/null +++ b/pkgs/pub_semver/.analysis_options @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index b505230e7..78c85e723 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.2.4 + +* Fix all remaining strong mode warnings. + # 1.2.3 * Addressed three strong mode warnings. diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 528c3a201..98722897c 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -4,7 +4,7 @@ import 'dart:math' as math; -import 'package:collection/equality.dart'; +import 'package:collection/collection.dart'; import 'patterns.dart'; import 'version_constraint.dart'; diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index 27993416c..5d525647e 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -55,7 +55,7 @@ class VersionUnion implements VersionConstraint { throw new ArgumentError('Unknown VersionConstraint type $constraint.'); } - (flattened as List).sort(compareMax); + flattened.sort(compareMax); var merged = []; for (var constraint in flattened) { diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 0ed3e3bfc..a026e25c7 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.2.3 +version: 1.2.4 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From fda1a0114d110bb5bcb1d2037ef3afac922dc3e8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 4 Apr 2016 15:44:05 -0700 Subject: [PATCH 153/657] Don't use async/await for Pool.withResource(). The async gap introduces a potential race condition. Closes dart-lang/pool#3 R=rnystrom@google.com Review URL: https://codereview.chromium.org//1853273002 . --- pkgs/pool/CHANGELOG.md | 5 +++++ pkgs/pool/lib/pool.dart | 15 ++++++++------- pkgs/pool/pubspec.yaml | 2 +- pkgs/pool/test/pool_test.dart | 9 ++++++++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 9ad86d0a8..70f914ba2 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.2.3 + +* Fix a bug in which `Pool.withResource()` could throw a `StateError` when + called immediately before closing the pool. + ## 1.2.2 * Fix strong mode warnings and add generic method annotations. diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index f7bfd828b..deb53334b 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -106,18 +106,19 @@ class Pool { /// Future. /// /// The return value of [callback] is piped to the returned Future. - Future/**/ withResource/**/(/*=T*/ callback()) async { + Future/**/ withResource/**/(/*=T*/ callback()) { if (isClosed) { throw new StateError( "withResource() may not be called on a closed Pool."); } - var resource = await request(); - try { - return await callback(); - } finally { - resource.release(); - } + // We can't use async/await here because we need to start the request + // synchronously in case the pool is closed immediately afterwards. Async + // functions have an asynchronous gap between calling and running the body, + // and [close] could be called during that gap. See #3. + return request().then((resource) { + return new Future.sync(callback).whenComplete(resource.release); + }); } /// Closes the pool so that no more resources are requested. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 314ac044c..58321cfae 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.2.2 +version: 1.2.3 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 91e683310..bd44cb275 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -96,6 +96,13 @@ void main() { async.elapse(new Duration(seconds: 1)); }); }); + + // Regression test for #3. + test("can be called immediately before close()", () async { + var pool = new Pool(1); + pool.withResource(expectAsync(() {})); + await pool.close(); + }); }); group("with a timeout", () { @@ -276,7 +283,7 @@ void main() { test("disallows request() and withResource()", () { var pool = new Pool(1)..close(); expect(pool.request, throwsStateError); - expect(pool.withResource(() {}), throwsStateError); + expect(() => pool.withResource(() {}), throwsStateError); }); test("pending requests are fulfilled", () async { From 4b38a40721d812bf98dffba968db745972aeaa10 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 3 May 2016 16:27:14 -0700 Subject: [PATCH 154/657] Fix a new strong-mode error. R=jmesserly@google.com Review URL: https://codereview.chromium.org//1949803002 . --- pkgs/pool/.analysis_options | 2 ++ pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/lib/pool.dart | 4 ++-- pkgs/pool/pubspec.yaml | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 pkgs/pool/.analysis_options diff --git a/pkgs/pool/.analysis_options b/pkgs/pool/.analysis_options new file mode 100644 index 000000000..a10d4c5a0 --- /dev/null +++ b/pkgs/pool/.analysis_options @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 70f914ba2..96d4c2f51 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.4 + +* Fix a strong-mode error. + ## 1.2.3 * Fix a bug in which `Pool.withResource()` could throw a `StateError` when diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index deb53334b..faa9f0e12 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -116,8 +116,8 @@ class Pool { // synchronously in case the pool is closed immediately afterwards. Async // functions have an asynchronous gap between calling and running the body, // and [close] could be called during that gap. See #3. - return request().then((resource) { - return new Future.sync(callback).whenComplete(resource.release); + return request().then/*>*/((resource) { + return new Future/**/.sync(callback).whenComplete(resource.release); }); } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 58321cfae..145df2bbf 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.2.3 +version: 1.2.4 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool From 469c2234b1281836646e658a225cf56d8aa2ebb1 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 4 May 2016 11:27:29 -0700 Subject: [PATCH 155/657] dartfmt --- pkgs/package_config/lib/discovery.dart | 8 +- .../lib/discovery_analysis.dart | 9 +- pkgs/package_config/lib/packages.dart | 1 - pkgs/package_config/lib/packages_file.dart | 2 +- .../package_config/lib/src/packages_impl.dart | 10 +- .../lib/src/packages_io_impl.dart | 9 +- pkgs/package_config/lib/src/util.dart | 28 ++-- .../test/discovery_analysis_test.dart | 37 ++--- pkgs/package_config/test/discovery_test.dart | 152 ++++++++---------- pkgs/package_config/test/parse_test.dart | 44 +++-- .../package_config/test/parse_write_test.dart | 15 +- 11 files changed, 151 insertions(+), 164 deletions(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 8e42af79d..10dbb8ef4 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -28,7 +28,7 @@ import "src/packages_io_impl.dart"; /// resolution file, for example one specified using a `--packages` /// command-line parameter. Future loadPackagesFile(Uri packagesFile, - {Future> loader(Uri uri)}) { + {Future> loader(Uri uri)}) { Packages parseBytes(List bytes) { Map packageMap = pkgfile.parse(bytes, packagesFile); return new MapPackages(packageMap); @@ -43,7 +43,6 @@ Future loadPackagesFile(Uri packagesFile, return loader(packagesFile).then(parseBytes); } - /// Create a [Packages] object for a package directory. /// /// The [packagesDir] URI should refer to a directory. @@ -63,7 +62,6 @@ Packages getPackagesDirectory(Uri packagesDir) { return new NonFilePackagesDirectoryPackages(packagesDir); } - /// Discover the package configuration for a Dart script. /// /// The [baseUri] points to either the Dart script or its directory. @@ -93,7 +91,7 @@ Packages getPackagesDirectory(Uri packagesDir) { /// The content should be a UTF-8 encoded `.packages` file, and must return an /// error future if loading fails for any reason. Future findPackages(Uri baseUri, - {Future> loader(Uri unsupportedUri)}) { + {Future> loader(Uri unsupportedUri)}) { if (baseUri.scheme == "file") { return new Future.sync(() => findPackagesFromFile(baseUri)); } else if (loader != null) { @@ -191,7 +189,7 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// of the requested `.packages` file as bytes, which will be assumed to be /// UTF-8 encoded. Future findPackagesFromNonFile(Uri nonFileUri, - {Future> loader(Uri name)}) { + {Future> loader(Uri name)}) { if (loader == null) loader = _httpGet; Uri packagesFileUri = nonFileUri.resolve(".packages"); return loader(packagesFileUri).then((List fileBytes) { diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart index af4df070a..6d4b9edd7 100644 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -41,7 +41,7 @@ abstract class PackageContext { /// Look up the [PackageContext] that applies to a specific directory. /// /// The directory must be inside [directory]. - PackageContext operator[](Directory directory); + PackageContext operator [](Directory directory); /// A map from directory to package resolver. /// @@ -57,7 +57,7 @@ abstract class PackageContext { /// directory of `directory`. If there is, its corresponding `Packages` object /// should be provided as `root`. static PackageContext findAll(Directory directory, - {Packages root: Packages.noPackages}) { + {Packages root: Packages.noPackages}) { if (!directory.existsSync()) { throw new ArgumentError("Directory not found: $directory"); } @@ -93,8 +93,7 @@ abstract class PackageContext { } findRoots(directory); // If the root is not itself context root, add a the wrapper context. - if (contexts.length == 1 && - contexts[0].directory == directory) { + if (contexts.length == 1 && contexts[0].directory == directory) { return contexts[0]; } return new _PackageContext(directory, root, contexts); @@ -120,7 +119,7 @@ class _PackageContext implements PackageContext { return result; } - PackageContext operator[](Directory directory) { + PackageContext operator [](Directory directory) { String path = directory.path; if (!path.startsWith(this.directory.path)) { throw new ArgumentError("Not inside $path: $directory"); diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart index dbaa06dfd..890f4485c 100644 --- a/pkgs/package_config/lib/packages.dart +++ b/pkgs/package_config/lib/packages.dart @@ -17,7 +17,6 @@ import "src/packages_impl.dart"; /// One such case is if the packages are resolved relative to a /// `packages/` directory available over HTTP. abstract class Packages { - /// A [Packages] resolver containing no packages. /// /// This constant object is returned by [find] above if no diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index f30781dc3..93ccd3c18 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -84,7 +84,7 @@ Map parse(List source, Uri baseLocation) { /// All the keys of [packageMapping] must be valid package names, /// and the values must be URIs that do not have the `package:` scheme. void write(StringSink output, Map packageMapping, - {Uri baseUri, String comment}) { + {Uri baseUri, String comment}) { if (baseUri != null && !baseUri.isAbsolute) { throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute"); } diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index e85f75581..fa9115fc6 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -18,13 +18,13 @@ class NoPackages implements Packages { Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { String packageName = checkValidPackageUri(packageUri); if (notFound != null) return notFound(packageUri); - throw new ArgumentError.value(packageUri, "packageUri", - 'No package named "$packageName"'); + throw new ArgumentError.value( + packageUri, "packageUri", 'No package named "$packageName"'); } Iterable get packages => new Iterable.generate(0); - Map asMap() => const{}; + Map asMap() => const {}; } /// Base class for [Packages] implementations. @@ -38,8 +38,8 @@ abstract class PackagesBase implements Packages { Uri packageBase = getBase(packageName); if (packageBase == null) { if (notFound != null) return notFound(packageUri); - throw new ArgumentError.value(packageUri, "packageUri", - 'No package named "$packageName"'); + throw new ArgumentError.value( + packageUri, "packageUri", 'No package named "$packageName"'); } String packagePath = packageUri.path.substring(packageName.length + 1); return packageBase.resolve(packagePath); diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart index 21b61fdab..db39bdb58 100644 --- a/pkgs/package_config/lib/src/packages_io_impl.dart +++ b/pkgs/package_config/lib/src/packages_io_impl.dart @@ -17,12 +17,13 @@ class FilePackagesDirectoryPackages extends PackagesBase { FilePackagesDirectoryPackages(this._packageDir); Uri getBase(String packageName) => - new Uri.file(path.join(_packageDir.path, packageName, '.')); + new Uri.file(path.join(_packageDir.path, packageName, '.')); Iterable _listPackageNames() { - return _packageDir.listSync() - .where((e) => e is Directory) - .map((e) => path.basename(e.path)); + return _packageDir + .listSync() + .where((e) => e is Directory) + .map((e) => path.basename(e.path)); } Iterable get packages => _listPackageNames(); diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index badf64086..f1e1afd0a 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -43,29 +43,29 @@ int _findInvalidCharacter(String string) { /// Validate that a Uri is a valid package:URI. String checkValidPackageUri(Uri packageUri) { if (packageUri.scheme != "package") { - throw new ArgumentError.value(packageUri, "packageUri", - "Not a package: URI"); + throw new ArgumentError.value( + packageUri, "packageUri", "Not a package: URI"); } if (packageUri.hasAuthority) { - throw new ArgumentError.value(packageUri, "packageUri", - "Package URIs must not have a host part"); + throw new ArgumentError.value( + packageUri, "packageUri", "Package URIs must not have a host part"); } if (packageUri.hasQuery) { // A query makes no sense if resolved to a file: URI. - throw new ArgumentError.value(packageUri, "packageUri", - "Package URIs must not have a query part"); + throw new ArgumentError.value( + packageUri, "packageUri", "Package URIs must not have a query part"); } if (packageUri.hasFragment) { // We could leave the fragment after the URL when resolving, // but it would be odd if "package:foo/foo.dart#1" and // "package:foo/foo.dart#2" were considered different libraries. // Keep the syntax open in case we ever get multiple libraries in one file. - throw new ArgumentError.value(packageUri, "packageUri", - "Package URIs must not have a fragment part"); + throw new ArgumentError.value( + packageUri, "packageUri", "Package URIs must not have a fragment part"); } if (packageUri.path.startsWith('/')) { - throw new ArgumentError.value(packageUri, "packageUri", - "Package URIs must not start with a '/'"); + throw new ArgumentError.value( + packageUri, "packageUri", "Package URIs must not start with a '/'"); } int firstSlash = packageUri.path.indexOf('/'); if (firstSlash == -1) { @@ -76,8 +76,8 @@ String checkValidPackageUri(Uri packageUri) { int badIndex = _findInvalidCharacter(packageName); if (badIndex >= 0) { if (packageName.isEmpty) { - throw new ArgumentError.value(packageUri, "packageUri", - "Package names mus be non-empty"); + throw new ArgumentError.value( + packageUri, "packageUri", "Package names mus be non-empty"); } if (badIndex == packageName.length) { throw new ArgumentError.value(packageUri, "packageUri", @@ -90,8 +90,8 @@ String checkValidPackageUri(Uri packageUri) { // Printable character. badChar = "'${packageName[badIndex]}' ($badChar)"; } - throw new ArgumentError.value(packageUri, "packageUri", - "Package names must not contain $badChar"); + throw new ArgumentError.value( + packageUri, "packageUri", "Package names must not contain $badChar"); } return packageName; } diff --git a/pkgs/package_config/test/discovery_analysis_test.dart b/pkgs/package_config/test/discovery_analysis_test.dart index f33a4a8c6..0a2876726 100644 --- a/pkgs/package_config/test/discovery_analysis_test.dart +++ b/pkgs/package_config/test/discovery_analysis_test.dart @@ -13,12 +13,14 @@ import "package:path/path.dart" as path; import "package:test/test.dart"; main() { - fileTest("basic", - {".packages": packagesFile, - "foo": {".packages": packagesFile}, - "bar": {"packages": {"foo": {}, "bar":{}, "baz": {}}}, - "baz": {}}, - (Directory directory) { + fileTest("basic", { + ".packages": packagesFile, + "foo": {".packages": packagesFile}, + "bar": { + "packages": {"foo": {}, "bar": {}, "baz": {}} + }, + "baz": {} + }, (Directory directory) { var dirUri = new Uri.directory(directory.path); PackageContext ctx = PackageContext.findAll(directory); PackageContext root = ctx[directory]; @@ -32,13 +34,13 @@ main() { PackageContext bar = ctx[sub(directory, "bar")]; validatePackagesDir(bar.packages, dirUri.resolve("bar/")); PackageContext barbar = ctx[sub(barDir, "bar")]; - expect(barbar, same(bar)); // inherited. + expect(barbar, same(bar)); // inherited. PackageContext baz = ctx[sub(directory, "baz")]; - expect(baz, same(root)); // inherited. + expect(baz, same(root)); // inherited. var map = ctx.asMap(); expect(map.keys.map((dir) => dir.path), - unorderedEquals([directory.path, fooDir.path, barDir.path])); + unorderedEquals([directory.path, fooDir.path, barDir.path])); }); } @@ -56,11 +58,11 @@ baz:packages/baz/ void validatePackagesFile(Packages resolver, Uri location) { expect(resolver, isNotNull); expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); + equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); + equals(location.resolve("packages/baz/qux/foo"))); expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); } @@ -68,11 +70,11 @@ void validatePackagesDir(Packages resolver, Uri location) { // Expect three packages: foo, bar and baz expect(resolver, isNotNull); expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(location.resolve("packages/foo/bar/baz"))); + equals(location.resolve("packages/foo/bar/baz"))); expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(location.resolve("packages/bar/baz/qux"))); + equals(location.resolve("packages/bar/baz/qux"))); expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); + equals(location.resolve("packages/baz/qux/foo"))); if (location.scheme == "file") { expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); } else { @@ -95,9 +97,8 @@ Uri pkg(String packageName, String packagePath) { /// Description is a map, each key is a file entry. If the value is a map, /// it's a sub-dir, otherwise it's a file and the value is the content /// as a string. -void fileTest(String name, - Map description, - Future fileTest(Directory directory)) { +void fileTest( + String name, Map description, Future fileTest(Directory directory)) { group("file-test", () { Directory tempDir = Directory.systemTemp.createTempSync("file-test"); setUp(() { diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 4f780c2ad..97b7bbf91 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -21,11 +21,11 @@ baz:packages/baz/ void validatePackagesFile(Packages resolver, Uri location) { expect(resolver, isNotNull); expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); + equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); + equals(location.resolve("packages/baz/qux/foo"))); expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); } @@ -33,11 +33,11 @@ void validatePackagesDir(Packages resolver, Uri location) { // Expect three packages: foo, bar and baz expect(resolver, isNotNull); expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(location.resolve("packages/foo/bar/baz"))); + equals(location.resolve("packages/foo/bar/baz"))); expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(location.resolve("packages/bar/baz/qux"))); + equals(location.resolve("packages/bar/baz/qux"))); expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); + equals(location.resolve("packages/baz/qux/foo"))); if (location.scheme == "file") { expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); } else { @@ -45,7 +45,6 @@ void validatePackagesDir(Packages resolver, Uri location) { } } - Uri pkg(String packageName, String packagePath) { var path; if (packagePath.startsWith('/')) { @@ -57,11 +56,11 @@ Uri pkg(String packageName, String packagePath) { } main() { - generalTest(".packages", - {".packages": packagesFile, - "script.dart": "main(){}", - "packages": {"shouldNotBeFound": {}}}, - (Uri location) async { + generalTest(".packages", { + ".packages": packagesFile, + "script.dart": "main(){}", + "packages": {"shouldNotBeFound": {}} + }, (Uri location) async { Packages resolver; resolver = await findPackages(location); validatePackagesFile(resolver, location); @@ -76,36 +75,36 @@ main() { validatePackagesFile(resolver, location); }); - generalTest("packages/", - {"packages": { "foo": {}, "bar": {}, "baz": {}}, - "script.dart": "main(){}"}, - (Uri location) async { + generalTest("packages/", { + "packages": {"foo": {}, "bar": {}, "baz": {}}, + "script.dart": "main(){}" + }, (Uri location) async { Packages resolver; bool isFile = (location.scheme == "file"); resolver = await findPackages(location); validatePackagesDir(resolver, location); resolver = await findPackages(location.resolve("script.dart")); validatePackagesDir(resolver, location); - var specificDiscovery = isFile - ? findPackagesFromFile - : findPackagesFromNonFile; + var specificDiscovery = + isFile ? findPackagesFromFile : findPackagesFromNonFile; resolver = await specificDiscovery(location); validatePackagesDir(resolver, location); resolver = await specificDiscovery(location.resolve("script.dart")); validatePackagesDir(resolver, location); }); - generalTest("underscore packages", - {"packages": {"_foo": {}}}, - (Uri location) async { + generalTest("underscore packages", { + "packages": {"_foo": {}} + }, (Uri location) async { Packages resolver = await findPackages(location); expect(resolver.resolve(pkg("_foo", "foo.dart")), - equals(location.resolve("packages/_foo/foo.dart"))); + equals(location.resolve("packages/_foo/foo.dart"))); }); - fileTest(".packages recursive", - {".packages": packagesFile, "subdir": {"script.dart": "main(){}"}}, - (Uri location) async { + fileTest(".packages recursive", { + ".packages": packagesFile, + "subdir": {"script.dart": "main(){}"} + }, (Uri location) async { Packages resolver; resolver = await findPackages(location.resolve("subdir/")); validatePackagesFile(resolver, location); @@ -118,9 +117,10 @@ main() { validatePackagesFile(resolver, location); }); - httpTest(".packages not recursive", - {".packages": packagesFile, "subdir": {"script.dart": "main(){}"}}, - (Uri location) async { + httpTest(".packages not recursive", { + ".packages": packagesFile, + "subdir": {"script.dart": "main(){}"} + }, (Uri location) async { Packages resolver; var subdir = location.resolve("subdir/"); resolver = await findPackages(subdir); @@ -133,9 +133,7 @@ main() { validatePackagesDir(resolver, subdir); }); - fileTest("no packages", - {"script.dart": "main(){}"}, - (Uri location) async { + fileTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { // A file: location with no .packages or packages returns // Packages.noPackages. Packages resolver; @@ -149,9 +147,7 @@ main() { expect(resolver, same(Packages.noPackages)); }); - httpTest("no packages", - {"script.dart": "main(){}"}, - (Uri location) async { + httpTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { // A non-file: location with no .packages or packages/: // Assumes a packages dir exists, and resolves relative to that. Packages resolver; @@ -178,13 +174,13 @@ main() { Packages resolver; resolver = await findPackages(location, loader: loader); validatePackagesFile(resolver, location); - resolver = await findPackages(location.resolve("script.dart"), - loader: loader); + resolver = + await findPackages(location.resolve("script.dart"), loader: loader); validatePackagesFile(resolver, location); resolver = await findPackagesFromNonFile(location, loader: loader); validatePackagesFile(resolver, location); resolver = await findPackagesFromNonFile(location.resolve("script.dart"), - loader: loader); + loader: loader); validatePackagesFile(resolver, location); }); @@ -198,27 +194,26 @@ main() { Packages resolver; resolver = await findPackages(location, loader: loader); validatePackagesDir(resolver, location); - resolver = await findPackages(location.resolve("script.dart"), - loader: loader); + resolver = + await findPackages(location.resolve("script.dart"), loader: loader); validatePackagesDir(resolver, location); resolver = await findPackagesFromNonFile(location, loader: loader); validatePackagesDir(resolver, location); resolver = await findPackagesFromNonFile(location.resolve("script.dart"), - loader:loader); + loader: loader); validatePackagesDir(resolver, location); }); - generalTest("loadPackagesFile", - {".packages": packagesFile}, - (Uri directory) async { + generalTest("loadPackagesFile", {".packages": packagesFile}, + (Uri directory) async { Uri file = directory.resolve(".packages"); Packages resolver = await loadPackagesFile(file); validatePackagesFile(resolver, file); }); - generalTest("loadPackagesFile non-default name", - {"pheldagriff": packagesFile}, - (Uri directory) async { + generalTest( + "loadPackagesFile non-default name", {"pheldagriff": packagesFile}, + (Uri directory) async { Uri file = directory.resolve("pheldagriff"); Packages resolver = await loadPackagesFile(file); validatePackagesFile(resolver, file); @@ -231,26 +226,23 @@ main() { validatePackagesFile(resolver, file); }); - generalTest("loadPackagesFile not found", - {}, - (Uri directory) async { + generalTest("loadPackagesFile not found", {}, (Uri directory) async { Uri file = directory.resolve(".packages"); expect(loadPackagesFile(file), throws); }); - generalTest("loadPackagesFile syntax error", - {".packages": "syntax error"}, - (Uri directory) async { + generalTest("loadPackagesFile syntax error", {".packages": "syntax error"}, + (Uri directory) async { Uri file = directory.resolve(".packages"); expect(loadPackagesFile(file), throws); }); - generalTest("getPackagesDir", - {"packages": {"foo": {}, "bar": {}, "baz": {}}}, - (Uri directory) async { + generalTest("getPackagesDir", { + "packages": {"foo": {}, "bar": {}, "baz": {}} + }, (Uri directory) async { Uri packages = directory.resolve("packages/"); Packages resolver = getPackagesDirectory(packages); - Uri resolved = resolver.resolve(pkg("foo","flip/flop")); + Uri resolved = resolver.resolve(pkg("foo", "flip/flop")); expect(resolved, packages.resolve("foo/flip/flop")); }); } @@ -260,9 +252,7 @@ main() { /// Description is a map, each key is a file entry. If the value is a map, /// it's a sub-dir, otherwise it's a file and the value is the content /// as a string. -void fileTest(String name, - Map description, - Future fileTest(Uri directory)) { +void fileTest(String name, Map description, Future fileTest(Uri directory)) { group("file-test", () { Directory tempDir = Directory.systemTemp.createTempSync("file-test"); setUp(() { @@ -285,31 +275,27 @@ void httpTest(String name, Map description, Future httpTest(Uri directory)) { var serverSub; var uri; setUp(() { - return HttpServer - .bind(InternetAddress.LOOPBACK_IP_V4, 0) - .then((server) { - uri = new Uri(scheme: "http", - host: "127.0.0.1", - port: server.port, - path: "/"); - serverSub = server.listen((HttpRequest request) { - // No error handling. - var path = request.uri.path; - if (path.startsWith('/')) path = path.substring(1); - if (path.endsWith('/')) path = path.substring(0, path.length - 1); - var parts = path.split('/'); - var fileOrDir = description; - for (int i = 0; i < parts.length; i++) { - fileOrDir = fileOrDir[parts[i]]; - if (fileOrDir == null) { - request.response.statusCode = 404; - request.response.close(); - } + return HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { + uri = new Uri( + scheme: "http", host: "127.0.0.1", port: server.port, path: "/"); + serverSub = server.listen((HttpRequest request) { + // No error handling. + var path = request.uri.path; + if (path.startsWith('/')) path = path.substring(1); + if (path.endsWith('/')) path = path.substring(0, path.length - 1); + var parts = path.split('/'); + var fileOrDir = description; + for (int i = 0; i < parts.length; i++) { + fileOrDir = fileOrDir[parts[i]]; + if (fileOrDir == null) { + request.response.statusCode = 404; + request.response.close(); } - request.response.write(fileOrDir); - request.response.close(); - }); + } + request.response.write(fileOrDir); + request.response.close(); }); + }); }); tearDown(() => serverSub.cancel()); test(name, () => httpTest(uri)); diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 8ed5c2eb7..7a2fce7e2 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -73,8 +73,7 @@ main() { test("multiple", () { var packages = doParse(multiRelativeSample, base); - expect( - packages.packages.toList()..sort(), equals(["bar", "foo"])); + expect(packages.packages.toList()..sort(), equals(["bar", "foo"])); expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), equals(base.resolve("../test/").resolve("bar/baz.dart"))); expect(packages.resolve(Uri.parse("package:bar/foo/baz.dart")), @@ -135,33 +134,32 @@ Packages doParse(String sample, Uri baseUri) { } // Valid samples. -var emptySample = ""; -var commentOnlySample = "# comment only\n"; -var emptyLinesSample = "\n\n\r\n"; -var singleRelativeSample = "foo:../test/\n"; -var singleRelativeSampleNoSlash = "foo:../test\n"; +var emptySample = ""; +var commentOnlySample = "# comment only\n"; +var emptyLinesSample = "\n\n\r\n"; +var singleRelativeSample = "foo:../test/\n"; +var singleRelativeSampleNoSlash = "foo:../test\n"; var singleRelativeSampleNoNewline = "foo:../test/"; -var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; -var singleEmptyPathSample = "foo:\n"; -var singleAbsolutePathSample = "foo:/test/\n"; -var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; +var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; +var singleEmptyPathSample = "foo:\n"; +var singleAbsolutePathSample = "foo:/test/\n"; +var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; // All valid path segment characters in an URI. -var allValidChars = - r"!$&'()*+,-.0123456789;=" +var allValidChars = r"!$&'()*+,-.0123456789;=" r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; var allValidCharsSample = "${allValidChars}:../test/\n"; // Invalid samples. var invalid = [ - ":baz.dart", // empty. - "foobar=baz.dart", // no colon (but an equals, which is not the same) - ".:../test/", // dot segment - "..:../test/", // dot-dot segment - "...:../test/", // dot-dot-dot segment - "foo/bar:../test/", // slash in name - "/foo:../test/", // slash at start of name - "?:../test/", // invalid characters. - "[:../test/", // invalid characters. - "x#:../test/", // invalid characters. + ":baz.dart", // empty. + "foobar=baz.dart", // no colon (but an equals, which is not the same) + ".:../test/", // dot segment + "..:../test/", // dot-dot segment + "...:../test/", // dot-dot-dot segment + "foo/bar:../test/", // slash in name + "/foo:../test/", // slash at start of name + "?:../test/", // invalid characters. + "[:../test/", // invalid characters. + "x#:../test/", // invalid characters. ]; diff --git a/pkgs/package_config/test/parse_write_test.dart b/pkgs/package_config/test/parse_write_test.dart index 6a185db20..29c2224a5 100644 --- a/pkgs/package_config/test/parse_write_test.dart +++ b/pkgs/package_config/test/parse_write_test.dart @@ -52,12 +52,17 @@ main() { roundTripTest("http directory", {"foo": httpDir}); roundTripTest("other scheme directory", {"foo": otherDir}); roundTripTest("multiple same-type directories", - {"foo": lowerDir, "bar": higherDir, "baz": parallelDir}); + {"foo": lowerDir, "bar": higherDir, "baz": parallelDir}); roundTripTest("multiple scheme directories", - {"foo": fileDir, "bar": httpDir, "baz": otherDir}); - roundTripTest("multiple scheme directories and mutliple same type", - {"foo": fileDir, "bar": httpDir, "baz": otherDir, - "qux": lowerDir, "hip": higherDir, "dep": parallelDir}); + {"foo": fileDir, "bar": httpDir, "baz": otherDir}); + roundTripTest("multiple scheme directories and mutliple same type", { + "foo": fileDir, + "bar": httpDir, + "baz": otherDir, + "qux": lowerDir, + "hip": higherDir, + "dep": parallelDir + }); }); } From 4cd7dfb3f6c0f528a5cb4baff7779a818d3a850b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 4 May 2016 11:31:07 -0700 Subject: [PATCH 156/657] strong-mode clean --- pkgs/package_config/.analysis_options | 2 ++ pkgs/package_config/lib/discovery_analysis.dart | 4 ++-- pkgs/package_config/test/discovery_test.dart | 6 +++--- pkgs/package_config/test/parse_write_test.dart | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 pkgs/package_config/.analysis_options diff --git a/pkgs/package_config/.analysis_options b/pkgs/package_config/.analysis_options new file mode 100644 index 000000000..a10d4c5a0 --- /dev/null +++ b/pkgs/package_config/.analysis_options @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart index 6d4b9edd7..058330b19 100644 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -61,10 +61,10 @@ abstract class PackageContext { if (!directory.existsSync()) { throw new ArgumentError("Directory not found: $directory"); } - List contexts = []; + var contexts = []; void findRoots(Directory directory) { Packages packages; - List oldContexts; + List oldContexts; File packagesFile = new File(path.join(directory.path, ".packages")); if (packagesFile.existsSync()) { packages = _loadPackagesFile(packagesFile); diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 97b7bbf91..8807ac497 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -163,7 +163,7 @@ main() { test(".packages w/ loader", () async { Uri location = Uri.parse("krutch://example.com/path/"); - Future loader(Uri file) async { + Future> loader(Uri file) async { if (file.path.endsWith(".packages")) { return packagesFile.codeUnits; } @@ -186,7 +186,7 @@ main() { test("no packages w/ loader", () async { Uri location = Uri.parse("krutch://example.com/path/"); - Future loader(Uri file) async { + Future> loader(Uri file) async { throw "not found"; } // A non-file: location with no .packages or packages/: @@ -220,7 +220,7 @@ main() { }); test("loadPackagesFile w/ loader", () async { - loader(Uri uri) async => packagesFile.codeUnits; + Future> loader(Uri uri) async => packagesFile.codeUnits; Uri file = Uri.parse("krutz://example.com/.packages"); Packages resolver = await loadPackagesFile(file, loader: loader); validatePackagesFile(resolver, file); diff --git a/pkgs/package_config/test/parse_write_test.dart b/pkgs/package_config/test/parse_write_test.dart index 29c2224a5..430218791 100644 --- a/pkgs/package_config/test/parse_write_test.dart +++ b/pkgs/package_config/test/parse_write_test.dart @@ -81,7 +81,7 @@ main() { }); } -String writeToString(Map map, {Uri baseUri, String comment}) { +String writeToString(Map map, {Uri baseUri, String comment}) { var buffer = new StringBuffer(); write(buffer, map, baseUri: baseUri, comment: comment); return buffer.toString(); From 019debf0c1f45c5d572329bdf399a0fe4f4719b3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 4 May 2016 11:32:13 -0700 Subject: [PATCH 157/657] cleanup gitignore --- pkgs/package_config/.gitignore | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore index b46f3df8e..aac1f4fe8 100644 --- a/pkgs/package_config/.gitignore +++ b/pkgs/package_config/.gitignore @@ -1,8 +1,4 @@ -.idea +.packages .pub packages -build -.project -.settings pubspec.lock -.packages From 039fc63849e1c80df318aaf64403133509dba032 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 4 May 2016 14:40:03 -0700 Subject: [PATCH 158/657] Declare the package strong-mode clean. R=jmesserly@google.com Review URL: https://codereview.chromium.org//1955433002 . --- pkgs/source_span/.analysis_options | 2 ++ pkgs/source_span/test/utils_test.dart | 8 -------- 2 files changed, 2 insertions(+), 8 deletions(-) create mode 100644 pkgs/source_span/.analysis_options diff --git a/pkgs/source_span/.analysis_options b/pkgs/source_span/.analysis_options new file mode 100644 index 000000000..a10d4c5a0 --- /dev/null +++ b/pkgs/source_span/.analysis_options @@ -0,0 +1,2 @@ +analyzer: + strong-mode: true diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index 5d973f58a..2a86cc070 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -45,11 +45,3 @@ main() { }); }); } - -_linearSearch(list, predicate) { - if (list.length == 0) return -1; - for (int i = 0; i < list.length; i++) { - if (predicate(list[i])) return i; - } - return list.length; -} From 52f15c0fdbf5a791749335b1807d4dcdee4e0bae Mon Sep 17 00:00:00 2001 From: pq Date: Wed, 4 May 2016 16:05:42 -0700 Subject: [PATCH 159/657] More strong-mode fixes --- pkgs/package_config/CHANGELOG.md | 11 +++++------ pkgs/package_config/lib/discovery.dart | 18 ++++++++++-------- pkgs/package_config/pubspec.yaml | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index f4e355e2c..6ac42ec58 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,16 +1,15 @@ -# Changelog +## 0.1.4 -## 0.1.3-dev +- Strong mode fixes. -- Invalid test cleanup (to keepup with changes in `Uri`). +## 0.1.3 + +- Invalid test cleanup (to keep up with changes in `Uri`). ## 0.1.1 - Syntax updates. - ## 0.1.0 - Initial implementation. - - diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 10dbb8ef4..4c09eecfb 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -28,19 +28,19 @@ import "src/packages_io_impl.dart"; /// resolution file, for example one specified using a `--packages` /// command-line parameter. Future loadPackagesFile(Uri packagesFile, - {Future> loader(Uri uri)}) { + {Future> loader(Uri uri)}) async { Packages parseBytes(List bytes) { Map packageMap = pkgfile.parse(bytes, packagesFile); return new MapPackages(packageMap); } if (packagesFile.scheme == "file") { File file = new File.fromUri(packagesFile); - return file.readAsBytes().then(parseBytes); + return parseBytes(await file.readAsBytes()); } if (loader == null) { - return _httpGet(packagesFile).then(parseBytes); + return parseBytes(await _httpGet(packagesFile)); } - return loader(packagesFile).then(parseBytes); + return parseBytes(await loader(packagesFile)); } /// Create a [Packages] object for a package directory. @@ -189,17 +189,19 @@ Packages findPackagesFromFile(Uri fileBaseUri) { /// of the requested `.packages` file as bytes, which will be assumed to be /// UTF-8 encoded. Future findPackagesFromNonFile(Uri nonFileUri, - {Future> loader(Uri name)}) { + {Future> loader(Uri name)}) async { if (loader == null) loader = _httpGet; Uri packagesFileUri = nonFileUri.resolve(".packages"); - return loader(packagesFileUri).then((List fileBytes) { + + try { + List fileBytes = await loader(packagesFileUri); Map map = pkgfile.parse(fileBytes, packagesFileUri); return new MapPackages(map); - }, onError: (_) { + } catch (_) { // Didn't manage to load ".packages". Assume a "packages/" directory. Uri packagesDirectoryUri = nonFileUri.resolve("packages/"); return new NonFilePackagesDirectoryPackages(packagesDirectoryUri); - }); + } } /// Fetches a file over http. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index f2c4e06cc..80aea6dd1 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.1.3 +version: 0.1.4 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From 351e57c662610d9f33a7aa99b2053ca66d727e58 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 1 Jun 2016 17:56:00 -0700 Subject: [PATCH 160/657] Make the VersionUnion class public. This is the first of several pub_semver changes to support my solver work. R=rnystrom@google.com Review URL: https://codereview.chromium.org//2029263003 . --- pkgs/pub_semver/CHANGELOG.md | 6 + pkgs/pub_semver/lib/pub_semver.dart | 1 + .../lib/src/version_constraint.dart | 41 ++++- pkgs/pub_semver/lib/src/version_range.dart | 4 +- pkgs/pub_semver/lib/src/version_union.dart | 151 +++++++----------- pkgs/pub_semver/pubspec.yaml | 2 +- 6 files changed, 105 insertions(+), 100 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 78c85e723..dc169fbe8 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.3.0 + +* Make the `VersionUnion` class public. This was previously used internally to + implement `new VersionConstraint.unionOf()` and `VersionConstraint.union()`. + Now it's public so you can use it too. + # 1.2.4 * Fix all remaining strong mode warnings. diff --git a/pkgs/pub_semver/lib/pub_semver.dart b/pkgs/pub_semver/lib/pub_semver.dart index fd2320e1c..bfb7d8b70 100644 --- a/pkgs/pub_semver/lib/pub_semver.dart +++ b/pkgs/pub_semver/lib/pub_semver.dart @@ -5,3 +5,4 @@ export 'src/version.dart'; export 'src/version_constraint.dart'; export 'src/version_range.dart'; +export 'src/version_union.dart'; diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index f222b5199..9f55da025 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -6,6 +6,7 @@ import 'patterns.dart'; import 'version.dart'; import 'version_range.dart'; import 'version_union.dart'; +import 'utils.dart'; /// A [VersionConstraint] is a predicate that can determine whether a given /// version is valid or not. @@ -172,8 +173,44 @@ abstract class VersionConstraint { /// It allows any versions that any of those constraints allows. If /// [constraints] is empty, this returns a constraint that allows no versions. factory VersionConstraint.unionOf( - Iterable constraints) => - VersionUnion.create(constraints); + Iterable constraints) { + var flattened = constraints.expand((constraint) { + if (constraint.isEmpty) return []; + if (constraint is VersionUnion) return constraint.ranges; + return [constraint]; + }).toList(); + + if (flattened.isEmpty) return VersionConstraint.empty; + + if (flattened.any((constraint) => constraint.isAny)) { + return VersionConstraint.any; + } + + // Only allow Versions and VersionRanges here so we can more easily reason + // about everything in [flattened]. _EmptyVersions and VersionUnions are + // filtered out above. + for (var constraint in flattened) { + if (constraint is VersionRange) continue; + throw new ArgumentError('Unknown VersionConstraint type $constraint.'); + } + + flattened.sort(compareMax); + + var merged = []; + for (var constraint in flattened) { + // Merge this constraint with the previous one, but only if they touch. + if (merged.isEmpty || + (!merged.last.allowsAny(constraint) && + !areAdjacent(merged.last, constraint))) { + merged.add(constraint); + } else { + merged[merged.length - 1] = merged.last.union(constraint); + } + } + + if (merged.length == 1) return merged.single; + return new VersionUnion.fromRanges(merged); + } /// Returns `true` if this constraint allows no versions. bool get isEmpty; diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 668b9b28e..145151f0a 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -124,7 +124,7 @@ class VersionRange implements VersionConstraint { if (other is Version) return allows(other); if (other is VersionUnion) { - return other.constraints.every((constraint) => allowsAll(constraint)); + return other.ranges.every((constraint) => allowsAll(constraint)); } if (other is VersionRange) { @@ -151,7 +151,7 @@ class VersionRange implements VersionConstraint { if (other is Version) return allows(other); if (other is VersionUnion) { - return other.constraints.any((constraint) => allowsAny(constraint)); + return other.ranges.any((constraint) => allowsAny(constraint)); } if (other is VersionRange) { diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index 5d525647e..dbdadcf0d 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -9,8 +9,8 @@ import 'version.dart'; import 'version_constraint.dart'; import 'version_range.dart'; -/// A (package-private) version constraint representing a union of multiple -/// disjoint version constraints. +/// A version constraint representing a union of multiple disjoint version +/// ranges. /// /// An instance of this will only be created if the version can't be represented /// as a non-compound value. @@ -23,101 +23,63 @@ class VersionUnion implements VersionConstraint { /// * Its contents are disjoint and non-adjacent. In other words, for any two /// constraints next to each other in the list, there's some version between /// those constraints that they don't match. - final List constraints; + final List ranges; bool get isEmpty => false; bool get isAny => false; - /// Returns the union of [constraints]. + /// Creates a union from a list of ranges with no pre-processing. /// - /// This ensures that an actual [VersionUnion] is only returned if necessary. - /// It also takes care of sorting and merging the constraints to ensure that - /// they're disjoint. - static VersionConstraint create(Iterable constraints) { - var flattened = constraints.expand((constraint) { - if (constraint.isEmpty) return []; - if (constraint is VersionUnion) return constraint.constraints; - return [constraint]; - }).toList(); - - if (flattened.isEmpty) return VersionConstraint.empty; - - if (flattened.any((constraint) => constraint.isAny)) { - return VersionConstraint.any; - } - - // Only allow Versions and VersionRanges here so we can more easily reason - // about everything in [flattened]. _EmptyVersions and VersionUnions are - // filtered out above. - for (var constraint in flattened) { - if (constraint is VersionRange) continue; - throw new ArgumentError('Unknown VersionConstraint type $constraint.'); - } - - flattened.sort(compareMax); - - var merged = []; - for (var constraint in flattened) { - // Merge this constraint with the previous one, but only if they touch. - if (merged.isEmpty || - (!merged.last.allowsAny(constraint) && - !areAdjacent(merged.last, constraint))) { - merged.add(constraint); - } else { - merged[merged.length - 1] = merged.last.union(constraint); - } - } - - if (merged.length == 1) return merged.single; - return new VersionUnion._(merged); - } - - VersionUnion._(this.constraints); + /// It's up to the caller to ensure that the invariants described in [ranges] + /// are maintained. They are not verified by this constructor. To + /// automatically ensure that they're maintained, use [new + /// VersionConstraint.unionOf] instead. + VersionUnion.fromRanges(this.ranges); bool allows(Version version) => - constraints.any((constraint) => constraint.allows(version)); + ranges.any((constraint) => constraint.allows(version)); bool allowsAll(VersionConstraint other) { - var ourConstraints = constraints.iterator; - var theirConstraints = _constraintsFor(other).iterator; + var ourRanges = ranges.iterator; + var theirRanges = _rangesFor(other).iterator; - // Because both lists of constraints are ordered by minimum version, we can + // Because both lists of ranges are ordered by minimum version, we can // safely move through them linearly here. - ourConstraints.moveNext(); - theirConstraints.moveNext(); - while (ourConstraints.current != null && theirConstraints.current != null) { - if (ourConstraints.current.allowsAll(theirConstraints.current)) { - theirConstraints.moveNext(); + ourRanges.moveNext(); + theirRanges.moveNext(); + while (ourRanges.current != null && theirRanges.current != null) { + if (ourRanges.current.allowsAll(theirRanges.current)) { + theirRanges.moveNext(); } else { - ourConstraints.moveNext(); + ourRanges.moveNext(); } } - // If our constraints have allowed all of their constraints, we'll have - // consumed all of them. - return theirConstraints.current == null; + // If our ranges have allowed all of their ranges, we'll have consumed all + // of them. + return theirRanges.current == null; } bool allowsAny(VersionConstraint other) { - var ourConstraints = constraints.iterator; - var theirConstraints = _constraintsFor(other).iterator; + var ourRanges = ranges.iterator; + var theirRanges = _rangesFor(other).iterator; - // Because both lists of constraints are ordered by minimum version, we can + // Because both lists of ranges are ordered by minimum version, we can // safely move through them linearly here. - ourConstraints.moveNext(); - theirConstraints.moveNext(); - while (ourConstraints.current != null && theirConstraints.current != null) { - if (ourConstraints.current.allowsAny(theirConstraints.current)) { + ourRanges.moveNext(); + theirRanges.moveNext(); + while (ourRanges.current != null && theirRanges.current != null) { + if (ourRanges.current.allowsAny(theirRanges.current)) { return true; } // Move the constraint with the higher max value forward. This ensures // that we keep both lists in sync as much as possible. - if (compareMax(ourConstraints.current, theirConstraints.current) < 0) { - ourConstraints.moveNext(); + if (compareMax(ourRanges.current, theirRanges.current) < 0) { + ourRanges.moveNext(); } else { - theirConstraints.moveNext(); + theirRanges.moveNext(); } } @@ -125,43 +87,42 @@ class VersionUnion implements VersionConstraint { } VersionConstraint intersect(VersionConstraint other) { - var ourConstraints = constraints.iterator; - var theirConstraints = _constraintsFor(other).iterator; + var ourRanges = ranges.iterator; + var theirRanges = _rangesFor(other).iterator; - // Because both lists of constraints are ordered by minimum version, we can + // Because both lists of ranges are ordered by minimum version, we can // safely move through them linearly here. - var newConstraints = []; - ourConstraints.moveNext(); - theirConstraints.moveNext(); - while (ourConstraints.current != null && theirConstraints.current != null) { - var intersection = ourConstraints.current - .intersect(theirConstraints.current); + var newRanges = []; + ourRanges.moveNext(); + theirRanges.moveNext(); + while (ourRanges.current != null && theirRanges.current != null) { + var intersection = ourRanges.current + .intersect(theirRanges.current); - if (!intersection.isEmpty) newConstraints.add(intersection); + if (!intersection.isEmpty) newRanges.add(intersection); // Move the constraint with the higher max value forward. This ensures // that we keep both lists in sync as much as possible, and that large - // constraints have a chance to match multiple small constraints that they - // contain. - if (compareMax(ourConstraints.current, theirConstraints.current) < 0) { - ourConstraints.moveNext(); + // ranges have a chance to match multiple small ranges that they contain. + if (compareMax(ourRanges.current, theirRanges.current) < 0) { + ourRanges.moveNext(); } else { - theirConstraints.moveNext(); + theirRanges.moveNext(); } } - if (newConstraints.isEmpty) return VersionConstraint.empty; - if (newConstraints.length == 1) return newConstraints.single; + if (newRanges.isEmpty) return VersionConstraint.empty; + if (newRanges.length == 1) return newRanges.single; - return new VersionUnion._(newConstraints); + return new VersionUnion.fromRanges(newRanges); } - /// Returns [constraint] as a list of constraints. + /// Returns [constraint] as a list of ranges. /// - /// This is used to normalize constraints of various types. - List _constraintsFor(VersionConstraint constraint) { + /// This is used to normalize ranges of various types. + List _rangesFor(VersionConstraint constraint) { if (constraint.isEmpty) return []; - if (constraint is VersionUnion) return constraint.constraints; + if (constraint is VersionUnion) return constraint.ranges; if (constraint is VersionRange) return [constraint]; throw new ArgumentError('Unknown VersionConstraint type $constraint.'); } @@ -171,10 +132,10 @@ class VersionUnion implements VersionConstraint { bool operator ==(other) { if (other is! VersionUnion) return false; - return const ListEquality().equals(constraints, other.constraints); + return const ListEquality().equals(ranges, other.ranges); } - int get hashCode => const ListEquality().hash(constraints); + int get hashCode => const ListEquality().hash(ranges); - String toString() => constraints.join(" or "); + String toString() => ranges.join(" or "); } diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index a026e25c7..53ef4d397 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.2.4 +version: 1.3.0-dev author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 7038accb8748853222c5700aa01364bbf5461c13 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 6 Jun 2016 15:59:04 -0700 Subject: [PATCH 161/657] Make VersionRange implement Comparable. This changes the ordering of ranges in a VersionUnion. It used to order solely by the upper bound; it now orders by lower bound, then upper bound. In addition to being a more intuitive ordering, this is easier to programatically work with, because iterating through the ranges reaches each one in the order of the versions it contains. R=rnystrom@google.com Review URL: https://codereview.chromium.org//2035983002 . --- pkgs/pub_semver/CHANGELOG.md | 3 + pkgs/pub_semver/lib/src/utils.dart | 13 +++-- pkgs/pub_semver/lib/src/version.dart | 38 +++++++------ .../lib/src/version_constraint.dart | 2 +- pkgs/pub_semver/lib/src/version_range.dart | 22 ++++++- pkgs/pub_semver/lib/src/version_union.dart | 12 ++-- pkgs/pub_semver/test/version_range_test.dart | 57 +++++++++++++++++++ 7 files changed, 118 insertions(+), 29 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index dc169fbe8..cf9542710 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -4,6 +4,9 @@ implement `new VersionConstraint.unionOf()` and `VersionConstraint.union()`. Now it's public so you can use it too. +* Make `VersionRange` implement `Comparable`. Ranges are ordered + first by lower bound, then by upper bound. + # 1.2.4 * Fix all remaining strong mode warnings. diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index 74d015ac1..6493ddac5 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -15,10 +15,15 @@ bool areAdjacent(VersionRange range1, VersionRange range2) { /// A [Comparator] that compares the maximum versions of [range1] and [range2]. int compareMax(VersionRange range1, VersionRange range2) { - if (range1.max < range2.max) return -1; - if (range1.max > range2.max) return 1; + if (range1.max == null) { + if (range2.max == null) return 0; + return 1; + } else if (range2.max == null) { + return -1; + } - if (!range1.includeMax && range2.includeMax) return -1; - if (range1.includeMax && !range2.includeMax) return 1; + var result = range1.max.compareTo(range2.max); + if (result != 0) return result; + if (range1.includeMax != range2.includeMax) return range1.includeMax ? 1 : -1; return 0; } diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 98722897c..f2662b9aa 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -14,7 +14,7 @@ import 'version_range.dart'; final _equality = const IterableEquality(); /// A parsed semantic version number. -class Version implements Comparable, VersionConstraint, VersionRange { +class Version implements VersionConstraint, VersionRange { /// No released version: i.e. "0.0.0". static Version get none => new Version(0, 0, 0); @@ -267,22 +267,26 @@ class Version implements Comparable, VersionConstraint, VersionRange { return new VersionConstraint.unionOf([this, other]); } - int compareTo(Version other) { - if (major != other.major) return major.compareTo(other.major); - if (minor != other.minor) return minor.compareTo(other.minor); - if (patch != other.patch) return patch.compareTo(other.patch); - - // Pre-releases always come before no pre-release string. - if (!isPreRelease && other.isPreRelease) return 1; - if (!other.isPreRelease && isPreRelease) return -1; - - var comparison = _compareLists(preRelease, other.preRelease); - if (comparison != 0) return comparison; - - // Builds always come after no build string. - if (build.isEmpty && other.build.isNotEmpty) return -1; - if (other.build.isEmpty && build.isNotEmpty) return 1; - return _compareLists(build, other.build); + int compareTo(VersionRange other) { + if (other is Version) { + if (major != other.major) return major.compareTo(other.major); + if (minor != other.minor) return minor.compareTo(other.minor); + if (patch != other.patch) return patch.compareTo(other.patch); + + // Pre-releases always come before no pre-release string. + if (!isPreRelease && other.isPreRelease) return 1; + if (!other.isPreRelease && isPreRelease) return -1; + + var comparison = _compareLists(preRelease, other.preRelease); + if (comparison != 0) return comparison; + + // Builds always come after no build string. + if (build.isEmpty && other.build.isNotEmpty) return -1; + if (other.build.isEmpty && build.isNotEmpty) return 1; + return _compareLists(build, other.build); + } else { + return -other.compareTo(this); + } } String toString() => _text; diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 9f55da025..68827a40c 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -194,7 +194,7 @@ abstract class VersionConstraint { throw new ArgumentError('Unknown VersionConstraint type $constraint.'); } - flattened.sort(compareMax); + flattened.sort(); var merged = []; for (var constraint in flattened) { diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 145151f0a..a8d60698f 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -2,6 +2,7 @@ // 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 'utils.dart'; import 'version.dart'; import 'version_constraint.dart'; import 'version_union.dart'; @@ -11,7 +12,11 @@ import 'version_union.dart'; /// If there is a minimum, then this only allows versions that are at that /// minimum or greater. If there is a maximum, then only versions less than /// that are allowed. In other words, this allows `>= min, < max`. -class VersionRange implements VersionConstraint { +/// +/// Version ranges are ordered first by their lower bounds, then by their upper +/// bounds. For example, `>=1.0.0 <2.0.0` is before `>=1.5.0 <2.0.0` is before +/// `>=1.5.0 <3.0.0`. +class VersionRange implements Comparable, VersionConstraint { /// The minimum end of the range. /// /// If [includeMin] is `true`, this will be the minimum allowed version. @@ -315,6 +320,21 @@ class VersionRange implements VersionConstraint { return new VersionConstraint.unionOf([this, other]); } + int compareTo(VersionRange other) { + if (min == null) { + if (other.min == null) return compareMax(this, other); + return -1; + } else if (other.min == null) { + return 1; + } + + var result = min.compareTo(other.min); + if (result != 0) return result; + if (includeMin != other.includeMin) return includeMin ? -1 : 1; + + return compareMax(this, other); + } + String toString() { var buffer = new StringBuffer(); diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index dbdadcf0d..d0e1e2bf4 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -19,7 +19,7 @@ class VersionUnion implements VersionConstraint { /// /// This list has two invariants: /// - /// * Its contents are sorted from lowest to highest matched versions. + /// * Its contents are sorted using the standard ordering of [VersionRange]s. /// * Its contents are disjoint and non-adjacent. In other words, for any two /// constraints next to each other in the list, there's some version between /// those constraints that they don't match. @@ -74,8 +74,8 @@ class VersionUnion implements VersionConstraint { return true; } - // Move the constraint with the higher max value forward. This ensures - // that we keep both lists in sync as much as possible. + // Move the constraint with the lower max value forward. This ensures that + // we keep both lists in sync as much as possible. if (compareMax(ourRanges.current, theirRanges.current) < 0) { ourRanges.moveNext(); } else { @@ -101,9 +101,9 @@ class VersionUnion implements VersionConstraint { if (!intersection.isEmpty) newRanges.add(intersection); - // Move the constraint with the higher max value forward. This ensures - // that we keep both lists in sync as much as possible, and that large - // ranges have a chance to match multiple small ranges that they contain. + // Move the constraint with the lower max value forward. This ensures that + // we keep both lists in sync as much as possible, and that large ranges + // have a chance to match multiple small ranges that they contain. if (compareMax(ourRanges.current, theirRanges.current) < 0) { ourRanges.moveNext(); } else { diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 9eaa98046..eaa473f03 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -445,4 +445,61 @@ main() { expect(new VersionRange().isEmpty, isFalse); expect(new VersionRange(min: v123, max: v124).isEmpty, isFalse); }); + + group('compareTo()', () { + test("orders by minimum first", () { + _expectComparesSmaller( + new VersionRange(min: v003, max: v080), + new VersionRange(min: v010, max: v072)); + _expectComparesSmaller( + new VersionRange(min: v003, max: v080), + new VersionRange(min: v010, max: v080)); + _expectComparesSmaller( + new VersionRange(min: v003, max: v080), + new VersionRange(min: v010, max: v114)); + }); + + test("orders by maximum second", () { + _expectComparesSmaller( + new VersionRange(min: v003, max: v010), + new VersionRange(min: v003, max: v072)); + }); + + test("includeMin comes before !includeMin", () { + _expectComparesSmaller( + new VersionRange(min: v003, max: v080, includeMin: true), + new VersionRange(min: v003, max: v080, includeMin: false)); + }); + + test("includeMax comes after !includeMax", () { + _expectComparesSmaller( + new VersionRange(min: v003, max: v080, includeMax: false), + new VersionRange(min: v003, max: v080, includeMax: true)); + }); + + test("no minimum comes before small minimum", () { + _expectComparesSmaller( + new VersionRange(max: v010), + new VersionRange(min: v003, max: v010)); + _expectComparesSmaller( + new VersionRange(max: v010, includeMin: true), + new VersionRange(min: v003, max: v010)); + }); + + test("no maximium comes after large maximum", () { + _expectComparesSmaller( + new VersionRange(min: v003, max: v300), + new VersionRange(min: v003)); + _expectComparesSmaller( + new VersionRange(min: v003, max: v300), + new VersionRange(min: v003, includeMax: true)); + }); + }); +} + +void _expectComparesSmaller(VersionRange smaller, VersionRange larger) { + expect(smaller.compareTo(larger), lessThan(0), + reason: "expected $smaller to sort below $larger"); + expect(larger.compareTo(smaller), greaterThan(0), + reason: "expected $larger to sort above $smaller"); } From 0e70668b1de4b464ab429a9453c50fd41837efd8 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Tue, 7 Jun 2016 18:49:55 -0700 Subject: [PATCH 162/657] Cache packageName to base Uri mapping. This makes analysis with using incremental analysis cache 30% faster. Without this change getBase() takes 40% (!) of total analysis time. With this change - just 0.79% of total time. Although the remaining 17% of PackagesBase.resolve() make my cry. Why URI manipulations are SO SLOW?! R=brianwilkerson@google.com, pquitslund@google.com, kevmoo@google.com BUG= Review URL: https://codereview.chromium.org/2041103005 . --- pkgs/package_config/lib/src/packages_io_impl.dart | 9 +++++++-- pkgs/package_config/pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart index db39bdb58..0e9474639 100644 --- a/pkgs/package_config/lib/src/packages_io_impl.dart +++ b/pkgs/package_config/lib/src/packages_io_impl.dart @@ -14,10 +14,15 @@ import "packages_impl.dart"; /// A [Packages] implementation based on a local directory. class FilePackagesDirectoryPackages extends PackagesBase { final Directory _packageDir; + final Map _packageToBaseUriMap = {}; + FilePackagesDirectoryPackages(this._packageDir); - Uri getBase(String packageName) => - new Uri.file(path.join(_packageDir.path, packageName, '.')); + Uri getBase(String packageName) { + return _packageToBaseUriMap.putIfAbsent(packageName, () { + return new Uri.file(path.join(_packageDir.path, packageName, '.')); + }); + } Iterable _listPackageNames() { return _packageDir diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 80aea6dd1..3d9bd45f9 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.1.4 +version: 0.1.5 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From bf1cbd980563fe38a2e7289c1e5631a8eee80bcd Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 8 Jun 2016 16:41:52 -0700 Subject: [PATCH 163/657] Add VersionConstraint.difference(). See dart-lang/pubdart-lang/pub_semver#912 R=rnystrom@google.com Review URL: https://codereview.chromium.org//2045803002 . --- pkgs/pub_semver/CHANGELOG.md | 3 + pkgs/pub_semver/lib/src/utils.dart | 55 ++++-- pkgs/pub_semver/lib/src/version.dart | 3 + .../lib/src/version_constraint.dart | 13 +- pkgs/pub_semver/lib/src/version_range.dart | 142 +++++++++++---- pkgs/pub_semver/lib/src/version_union.dart | 78 ++++++++- pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_range_test.dart | 162 +++++++++++++++++- pkgs/pub_semver/test/version_test.dart | 21 +++ pkgs/pub_semver/test/version_union_test.dart | 58 +++++++ 10 files changed, 482 insertions(+), 55 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index cf9542710..db3d320ff 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -4,6 +4,9 @@ implement `new VersionConstraint.unionOf()` and `VersionConstraint.union()`. Now it's public so you can use it too. +* Added `VersionConstraint.difference()`. This returns a constraint matching all + versions matched by one constraint but not another. + * Make `VersionRange` implement `Comparable`. Ranges are ordered first by lower bound, then by upper bound. diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index 6493ddac5..efe105abe 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -13,17 +13,46 @@ bool areAdjacent(VersionRange range1, VersionRange range2) { (!range1.includeMax && range2.includeMin); } -/// A [Comparator] that compares the maximum versions of [range1] and [range2]. -int compareMax(VersionRange range1, VersionRange range2) { - if (range1.max == null) { - if (range2.max == null) return 0; - return 1; - } else if (range2.max == null) { - return -1; - } - - var result = range1.max.compareTo(range2.max); - if (result != 0) return result; - if (range1.includeMax != range2.includeMax) return range1.includeMax ? 1 : -1; - return 0; +/// Returns whether [range1] allows lower versions than [range2]. +bool allowsLower(VersionRange range1, VersionRange range2) { + if (range1.min == null) return range2.min != null; + if (range2.min == null) return false; + + var comparison = range1.min.compareTo(range2.min); + if (comparison == -1) return true; + if (comparison == 1) return false; + return range1.includeMin && !range2.includeMin; +} + +/// Returns whether [range1] allows higher versions than [range2]. +bool allowsHigher(VersionRange range1, VersionRange range2) { + if (range1.max == null) return range2.max != null; + if (range2.max == null) return false; + + var comparison = range1.max.compareTo(range2.max); + if (comparison == 1) return true; + if (comparison == -1) return false; + return range1.includeMax && !range2.includeMax; +} + +/// Returns whether [range1] allows only versions lower than those allowed by +/// [range2]. +bool strictlyLower(VersionRange range1, VersionRange range2) { + if (range1.max == null || range2.min == null) return false; + + var comparison = range1.max.compareTo(range2.min); + if (comparison == -1) return true; + if (comparison == 1) return false; + return !range1.includeMax || !range2.includeMin; +} + +/// Returns whether [range1] allows only versions higher than those allowed by +/// [range2]. +bool strictlyHigher(VersionRange range1, VersionRange range2) { + if (range1.min == null || range2.max == null) return false; + + var comparison = range1.min.compareTo(range2.max); + if (comparison == 1) return true; + if (comparison == -1) return false; + return !range1.includeMin || !range2.includeMax; } diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index f2662b9aa..2d43a1aa8 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -267,6 +267,9 @@ class Version implements VersionConstraint, VersionRange { return new VersionConstraint.unionOf([this, other]); } + VersionConstraint difference(VersionConstraint other) => + other.allows(this) ? VersionConstraint.empty : this; + int compareTo(VersionRange other) { if (other is Version) { if (major != other.major) return major.compareTo(other.major); diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 68827a40c..edd8abd07 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -229,13 +229,17 @@ abstract class VersionConstraint { /// allows. bool allowsAny(VersionConstraint other); - /// Creates a new [VersionConstraint] that only allows [Version]s allowed by - /// both this and [other]. + /// Returns a [VersionConstraint] that only allows [Version]s allowed by both + /// this and [other]. VersionConstraint intersect(VersionConstraint other); - /// Creates a new [VersionConstraint] that allows [Versions]s allowed by - /// either this or [other]. + /// Returns a [VersionConstraint] that allows [Versions]s allowed by either + /// this or [other]. VersionConstraint union(VersionConstraint other); + + /// Returns a [VersionConstraint] that allows [Version]s allowed by this but + /// not [other]. + VersionConstraint difference(VersionConstraint other); } class _EmptyVersion implements VersionConstraint { @@ -248,6 +252,7 @@ class _EmptyVersion implements VersionConstraint { bool allowsAny(VersionConstraint other) => false; VersionConstraint intersect(VersionConstraint other) => this; VersionConstraint union(VersionConstraint other) => other; + VersionConstraint difference(VersionConstraint other) => this; String toString() => ''; } diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index a8d60698f..ffa50ab6b 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -160,37 +160,7 @@ class VersionRange implements Comparable, VersionConstraint { } if (other is VersionRange) { - // If neither range has a minimum, they'll overlap at some point. - // - // ... this ] - // ... other ] - if (min == null && other.min == null) return true; - - // If this range has a lower minimum than the other range, it overlaps as - // long as its maximum is higher than or the same as the other range's - // minimum. - // - // [ this ] [ this ] - // [ other ] [ other ] - if (min == null || (other.min != null && min < other.min)) { - if (max == null) return true; - if (max > other.min) return true; - if (max < other.min) return false; - assert(max == other.min); - return includeMax && other.includeMin; - } - - // If this range has a higher minimum than the other range, it overlaps as - // long as its minimum is lower than or the same as the other range's - // maximum. - // - // [ this ] [ this ] - // [ other ] [ other ] - if (other.max == null) return true; - if (min < other.max) return true; - if (min > other.max) return false; - assert(min == other.max); - return includeMin && other.includeMax; + return !strictlyLower(other, this) && !strictlyHigher(other, this); } throw new ArgumentError('Unknown VersionConstraint type $other.'); @@ -320,9 +290,100 @@ class VersionRange implements Comparable, VersionConstraint { return new VersionConstraint.unionOf([this, other]); } + VersionConstraint difference(VersionConstraint other) { + if (other.isEmpty) return this; + + if (other is Version) { + if (!allows(other)) return this; + + if (other == min) { + if (!includeMin) return this; + return new VersionRange( + min: min, max: max, + includeMin: false, includeMax: includeMax); + } + + if (other == max) { + if (!includeMax) return this; + return new VersionRange( + min: min, max: max, + includeMin: includeMin, includeMax: false); + } + + return new VersionUnion.fromRanges([ + new VersionRange( + min: min, max: other, + includeMin: includeMin, includeMax: false), + new VersionRange( + min: other, max: max, + includeMin: false, includeMax: includeMax) + ]); + } else if (other is VersionRange) { + if (!allowsAny(other)) return this; + + VersionConstraint before; + if (!allowsLower(this, other)) { + before = VersionConstraint.empty; + } else if (min == other.min) { + assert(includeMin && !other.includeMin); + assert(min != null); + before = min; + } else { + before = new VersionRange( + min: min, max: other.min, + includeMin: includeMin, includeMax: !other.includeMin); + } + + VersionConstraint after; + if (!allowsHigher(this, other)) { + after = VersionConstraint.empty; + } else if (max == other.max) { + assert(includeMax && !other.includeMax); + assert(max != null); + after = max; + } else { + after = new VersionRange( + min: other.max, max: max, + includeMin: !other.includeMax, includeMax: includeMax); + } + + if (before == VersionConstraint.empty) return after; + if (after == VersionConstraint.empty) return before; + return new VersionUnion.fromRanges([before, after]); + } else if (other is VersionUnion) { + var ranges = []; + var current = this; + + for (var range in other.ranges) { + // Skip any ranges that are strictly lower than [current]. + if (strictlyLower(range, current)) continue; + + // If we reach a range strictly higher than [current], no more ranges + // will be relevant so we can bail early. + if (strictlyHigher(range, current)) break; + + var difference = current.difference(range); + if (difference is VersionUnion) { + // If [range] split [current] in half, we only need to continue + // checking future ranges against the latter half. + assert(difference.ranges.length == 2); + ranges.add(difference.ranges.first); + current = difference.ranges.last; + } else { + current = difference as VersionRange; + } + } + + if (ranges.isEmpty) return current; + return new VersionUnion.fromRanges(ranges..add(current)); + } + + throw new ArgumentError('Unknown VersionConstraint type $other.'); + } + int compareTo(VersionRange other) { if (min == null) { - if (other.min == null) return compareMax(this, other); + if (other.min == null) return _compareMax(other); return -1; } else if (other.min == null) { return 1; @@ -332,7 +393,22 @@ class VersionRange implements Comparable, VersionConstraint { if (result != 0) return result; if (includeMin != other.includeMin) return includeMin ? -1 : 1; - return compareMax(this, other); + return _compareMax(other); + } + + /// Compares the maximum values of [this] and [other]. + int _compareMax(VersionRange other) { + if (max == null) { + if (other.max == null) return 0; + return 1; + } else if (other.max == null) { + return -1; + } + + var result = max.compareTo(other.max); + if (result != 0) return result; + if (includeMax != other.includeMax) return includeMax ? 1 : -1; + return 0; } String toString() { diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index d0e1e2bf4..a26cb528d 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -76,7 +76,7 @@ class VersionUnion implements VersionConstraint { // Move the constraint with the lower max value forward. This ensures that // we keep both lists in sync as much as possible. - if (compareMax(ourRanges.current, theirRanges.current) < 0) { + if (allowsHigher(theirRanges.current, ourRanges.current)) { ourRanges.moveNext(); } else { theirRanges.moveNext(); @@ -104,7 +104,7 @@ class VersionUnion implements VersionConstraint { // Move the constraint with the lower max value forward. This ensures that // we keep both lists in sync as much as possible, and that large ranges // have a chance to match multiple small ranges that they contain. - if (compareMax(ourRanges.current, theirRanges.current) < 0) { + if (allowsHigher(theirRanges.current, ourRanges.current)) { ourRanges.moveNext(); } else { theirRanges.moveNext(); @@ -117,6 +117,80 @@ class VersionUnion implements VersionConstraint { return new VersionUnion.fromRanges(newRanges); } + VersionConstraint difference(VersionConstraint other) { + var ourRanges = ranges.iterator; + var theirRanges = _rangesFor(other).iterator; + + var newRanges = []; + ourRanges.moveNext(); + theirRanges.moveNext(); + var current = ourRanges.current; + + theirNextRange() { + if (theirRanges.moveNext()) return true; + + // If there are no more of their ranges, none of the rest of our ranges + // need to be subtracted so we can add them as-is. + newRanges.add(current); + while (ourRanges.moveNext()) { + newRanges.add(ourRanges.current); + } + return false; + } + + ourNextRange({bool includeCurrent: true}) { + if (includeCurrent) newRanges.add(current); + if (!ourRanges.moveNext()) return false; + current = ourRanges.current; + return true; + } + + while (true) { + // If the current ranges are disjoint, move the lowest one forward. + if (strictlyLower(theirRanges.current, current)) { + if (!theirNextRange()) break; + continue; + } + + if (strictlyHigher(theirRanges.current, current)) { + if (!ourNextRange()) break; + continue; + } + + // If we're here, we know [theirRanges.current] overlaps [current]. + var difference = current.difference(theirRanges.current); + if (difference is VersionUnion) { + // If their range split [current] in half, we only need to continue + // checking future ranges against the latter half. + assert(difference.ranges.length == 2); + newRanges.add(difference.ranges.first); + current = difference.ranges.last; + + // Since their range split [current], it definitely doesn't allow higher + // versions, so we should move their ranges forward. + if (!theirNextRange()) break; + } else if (difference.isEmpty) { + if (!ourNextRange(includeCurrent: false)) break; + } else { + current = difference as VersionRange; + + // Move the constraint with the lower max value forward. This ensures + // that we keep both lists in sync as much as possible, and that large + // ranges have a chance to subtract or be subtracted by multiple small + // ranges that they contain. + if (allowsHigher(current, theirRanges.current)) { + if (!theirNextRange()) break; + } else { + if (!ourNextRange()) break; + } + } + } + + if (newRanges.isEmpty) return VersionConstraint.empty; + if (newRanges.length == 1) return newRanges.single; + return new VersionUnion.fromRanges(newRanges); + } + /// Returns [constraint] as a list of ranges. /// /// This is used to normalize ranges of various types. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 53ef4d397..531ace6ba 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.0-dev +version: 1.3.0 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index eaa473f03..a2dbf9810 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -340,8 +340,8 @@ main() { }); test('adjacent ranges allow no versions if exclusive', () { - var a = new VersionRange(min: v114, max: v124, includeMax: false); - var b = new VersionRange(min: v124, max: v200, includeMin: true); + var a = new VersionRange(min: v114, max: v124); + var b = new VersionRange(min: v124, max: v200); expect(a.intersect(b).isEmpty, isTrue); }); @@ -441,6 +441,164 @@ main() { }); }); + group('difference()', () { + test("with an empty range returns the original range", () { + expect( + new VersionRange(min: v003, max: v114) + .difference(VersionConstraint.empty), + equals(new VersionRange(min: v003, max: v114))); + }); + + test("with a version outside the range returns the original range", () { + expect( + new VersionRange(min: v003, max: v114).difference(v200), + equals(new VersionRange(min: v003, max: v114))); + }); + + test("with a version in the range splits the range", () { + expect( + new VersionRange(min: v003, max: v114).difference(v072), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v072, max: v114) + ]))); + }); + + test("with the max version makes the max exclusive", () { + expect( + new VersionRange(min: v003, max: v114, includeMax: true) + .difference(v114), + equals(new VersionRange(min: v003, max: v114))); + }); + + test("with the min version makes the min exclusive", () { + expect( + new VersionRange(min: v003, max: v114, includeMin: true) + .difference(v003), + equals(new VersionRange(min: v003, max: v114))); + }); + + test("with a disjoint range returns the original", () { + expect( + new VersionRange(min: v003, max: v114) + .difference(new VersionRange(min: v123, max: v140)), + equals(new VersionRange(min: v003, max: v114))); + }); + + test("with an adjacent range returns the original", () { + expect( + new VersionRange(min: v003, max: v114, includeMax: true) + .difference(new VersionRange(min: v114, max: v140)), + equals(new VersionRange(min: v003, max: v114, includeMax: true))); + }); + + test("with a range at the beginning cuts off the beginning of the range", + () { + expect( + new VersionRange(min: v080, max: v130) + .difference(new VersionRange(min: v010, max: v114)), + equals(new VersionRange(min: v114, max: v130, includeMin: true))); + expect( + new VersionRange(min: v080, max: v130) + .difference(new VersionRange(max: v114)), + equals(new VersionRange(min: v114, max: v130, includeMin: true))); + expect( + new VersionRange(min: v080, max: v130).difference( + new VersionRange(min: v010, max: v114, includeMax: true)), + equals(new VersionRange(min: v114, max: v130))); + expect( + new VersionRange(min: v080, max: v130, includeMin: true).difference( + new VersionRange(min: v010, max: v080, includeMax: true)), + equals(new VersionRange(min: v080, max: v130))); + expect( + new VersionRange(min: v080, max: v130, includeMax: true) + .difference(new VersionRange(min: v080, max: v130)), + equals(v130)); + }); + + test("with a range at the end cuts off the end of the range", + () { + expect( + new VersionRange(min: v080, max: v130) + .difference(new VersionRange(min: v114, max: v140)), + equals(new VersionRange(min: v080, max: v114, includeMax: true))); + expect( + new VersionRange(min: v080, max: v130) + .difference(new VersionRange(min: v114)), + equals(new VersionRange(min: v080, max: v114, includeMax: true))); + expect( + new VersionRange(min: v080, max: v130).difference( + new VersionRange(min: v114, max: v140, includeMin: true)), + equals(new VersionRange(min: v080, max: v114))); + expect( + new VersionRange(min: v080, max: v130, includeMax: true).difference( + new VersionRange(min: v130, max: v140, includeMin: true)), + equals(new VersionRange(min: v080, max: v130))); + expect( + new VersionRange(min: v080, max: v130, includeMin: true) + .difference(new VersionRange(min: v080, max: v130)), + equals(v080)); + }); + + test("with a range in the middle cuts the range in half", () { + expect( + new VersionRange(min: v003, max: v130) + .difference(new VersionRange(min: v072, max: v114)), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072, includeMax: true), + new VersionRange(min: v114, max: v130, includeMin: true) + ]))); + }); + + test("with a totally covering range returns empty", () { + expect( + new VersionRange(min: v114, max: v200) + .difference(new VersionRange(min: v072, max: v300)), + isEmpty); + expect( + new VersionRange(min: v003, max: v114) + .difference(new VersionRange(min: v003, max: v114)), + isEmpty); + expect( + new VersionRange( + min: v003, max: v114, includeMin: true, includeMax: true) + .difference(new VersionRange( + min: v003, max: v114, includeMin: true, includeMax: true)), + isEmpty); + }); + + test("with a version union that doesn't cover the range, returns the " + "original", () { + expect( + new VersionRange(min: v114, max: v140) + .difference(new VersionConstraint.unionOf([v010, v200])), + equals(new VersionRange(min: v114, max: v140))); + }); + + test("with a version union that intersects the ends, chops them off", () { + expect( + new VersionRange(min: v114, max: v140) + .difference(new VersionConstraint.unionOf([ + new VersionRange(min: v080, max: v123), + new VersionRange(min: v130, max: v200) + ])), + equals(new VersionRange( + min: v123, max: v130, includeMin: true, includeMax: true))); + }); + + test("with a version union that intersects the middle, chops it up", () { + expect( + new VersionRange(min: v114, max: v140) + .difference(new VersionConstraint.unionOf([v123, v124, v130])), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v114, max: v123), + new VersionRange(min: v123, max: v124), + new VersionRange(min: v124, max: v130), + new VersionRange(min: v130, max: v140) + ]))); + }); + }); + test('isEmpty', () { expect(new VersionRange().isEmpty, isFalse); expect(new VersionRange(min: v123, max: v124).isEmpty, isFalse); diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index ddc6c94b5..b278d4c61 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -202,6 +202,27 @@ main() { }); }); + group('difference()', () { + test("with the same version returns an empty constraint", () { + expect(v123.difference(v123), isEmpty); + }); + + test("with a different version returns the original version", () { + expect(v123.difference(v080), equals(v123)); + }); + + test("returns an empty constraint with a range that contains the version", + () { + expect(v123.difference(new VersionRange(min: v114, max: v124)), isEmpty); + }); + + test("returns the version constraint with a range that doesn't contain it", + () { + expect(v123.difference(new VersionRange(min: v140, max: v300)), + equals(v123)); + }); + }); + test('isEmpty', () { expect(v123.isEmpty, isFalse); }); diff --git a/pkgs/pub_semver/test/version_union_test.dart b/pkgs/pub_semver/test/version_union_test.dart index f3518a06a..06a427dd9 100644 --- a/pkgs/pub_semver/test/version_union_test.dart +++ b/pkgs/pub_semver/test/version_union_test.dart @@ -349,4 +349,62 @@ main() { }); }); }); + + group("difference()", () { + test("ignores ranges that don't intersect", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v130) + ]).difference(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v010), + new VersionRange(min: v080, max: v123), + new VersionRange(min: v140) + ])), equals(new VersionConstraint.unionOf([ + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v130) + ]))); + }); + + test("removes overlapping portions", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v130) + ]).difference(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v124) + ])), equals(new VersionConstraint.unionOf([ + new VersionRange(min: v072, max: v080, includeMin: true), + new VersionRange(min: v123, max: v124, includeMax: true) + ]))); + }); + + test("removes multiple portions from the same range", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v114), + new VersionRange(min: v130, max: v200) + ]).difference(new VersionConstraint.unionOf([v072, v080])), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v072, max: v080), + new VersionRange(min: v080, max: v114), + new VersionRange(min: v130, max: v200) + ]))); + }); + + test("removes the same range from multiple ranges", () { + expect(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v080, max: v123), + new VersionRange(min: v124, max: v130), + new VersionRange(min: v200, max: v234), + new VersionRange(min: v250, max: v300) + ]).difference(new VersionRange(min: v114, max: v201)), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v080, max: v114, includeMax: true), + new VersionRange(min: v201, max: v234, includeMin: true), + new VersionRange(min: v250, max: v300) + ]))); + }); + }); } \ No newline at end of file From 65b68c2597dd2325a113316698276b12ef2053a2 Mon Sep 17 00:00:00 2001 From: pq Date: Thu, 9 Jun 2016 09:00:57 -0700 Subject: [PATCH 164/657] `0.1.5` CHANGELOG update pre-publish. Adds: * FilePackagesDirectoryPackages.getBase(..)` performance improvements. BUG= R=scheglov@google.com Review URL: https://codereview.chromium.org//2051143002 . --- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/codereview.settings | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 pkgs/package_config/codereview.settings diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 6ac42ec58..b7b441e9e 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.5 + +- `FilePackagesDirectoryPackages.getBase(..)` performance improvements. + ## 0.1.4 - Strong mode fixes. diff --git a/pkgs/package_config/codereview.settings b/pkgs/package_config/codereview.settings new file mode 100644 index 000000000..1099f0594 --- /dev/null +++ b/pkgs/package_config/codereview.settings @@ -0,0 +1,3 @@ +CODE_REVIEW_SERVER: https://codereview.chromium.org/ +VIEW_VC: https://github.com/dart-lang/package_config/commit/ +CC_LIST: reviews@dartlang.org From 8732d800dfeeab614ffdcc83509ec91bc0dfc3b8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 9 Jun 2016 15:37:44 -0700 Subject: [PATCH 165/657] Fix a message bug. If a point span appeared past the end of a file, and that file *didn't* end with a trailing newline, that span would be printed as though it pointed at the last character of the file. R=jmesserly@google.com Review URL: https://codereview.chromium.org//2056913002 . --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/span_mixin.dart | 2 +- pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/file_message_test.dart | 9 +++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index cca6f11e6..d1bcda5ea 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.2.3 + +* Fix a bug where a point span at the end of a file without a trailing newline + would be printed incorrectly. + # 1.2.2 * Allow `SourceSpanException.message`, `SourceSpanFormatException.source`, and diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 2d390b6a7..f6d04fa7c 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -70,7 +70,7 @@ abstract class SourceSpanMixin implements SourceSpan { } var endIndex = context.indexOf('\n'); textLine = endIndex == -1 ? context : context.substring(0, endIndex + 1); - column = math.min(column, textLine.length - 1); + column = math.min(column, textLine.length); } else { textLine = text.split("\n").first; column = 0; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 7ca7de46d..3ef97ed13 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.2.2 +version: 1.2.3 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/file_message_test.dart b/pkgs/source_span/test/file_message_test.dart index 5935c5882..d78a65172 100644 --- a/pkgs/source_span/test/file_message_test.dart +++ b/pkgs/source_span/test/file_message_test.dart @@ -59,6 +59,15 @@ zip zap zop ^""")); }); + test("works for a point span at the end of the file with no trailing newline", + () { + file = new SourceFile("zip zap zop"); + expect(file.location(11).pointSpan().message("oh no"), equals(""" +line 1, column 12: oh no +zip zap zop + ^""")); + }); + test("works for a point span in an empty file", () { expect(new SourceFile("").location(0).pointSpan().message("oh no"), equals(""" From 08cc6269bab6827b78d8b554582d16d925ceb000 Mon Sep 17 00:00:00 2001 From: pq Date: Tue, 14 Jun 2016 09:37:11 -0700 Subject: [PATCH 166/657] Bump `package_config` to 1.0.0. BUG= R=lrn@google.com Review URL: https://codereview.chromium.org//2061863002 . --- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index b7b441e9e..18a42ce71 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.0 + +- Public API marked stable. + ## 0.1.5 - `FilePackagesDirectoryPackages.getBase(..)` performance improvements. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 3d9bd45f9..e1afec23c 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 0.1.5 +version: 1.0.0 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From 049f31212fb58e5fbc8e6204dce74d20a5191c9b Mon Sep 17 00:00:00 2001 From: William Hesse Date: Thu, 7 Jul 2016 10:01:30 +0200 Subject: [PATCH 167/657] Use the test runner on the test bots for this package BUG= R=nweiz@google.com Review URL: https://codereview.chromium.org//2123933002 . --- pkgs/pub_semver/.test_config | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 pkgs/pub_semver/.test_config diff --git a/pkgs/pub_semver/.test_config b/pkgs/pub_semver/.test_config new file mode 100644 index 000000000..25355634f --- /dev/null +++ b/pkgs/pub_semver/.test_config @@ -0,0 +1,3 @@ +{ + "test_package": true +} From c5a436d21659b3134bce9c86549997eeca392ae5 Mon Sep 17 00:00:00 2001 From: Vittorio Ballestra Date: Sun, 7 Aug 2016 12:13:16 +0200 Subject: [PATCH 168/657] fixes dart-lang/source_maps#16 --- pkgs/source_maps/lib/builder.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 091e220c5..1f36b999b 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -77,7 +77,8 @@ class Entry implements Comparable { /// location in the target file. We sort primarily by the target offset /// because source map files are encoded by printing each mapping in order as /// they appear in the target file. - int compareTo(Entry other) { + int compareTo(_other) { + Entry other = _other as Entry; int res = target.compareTo(other.target); if (res != 0) return res; res = source.sourceUrl.toString().compareTo( From 4e30af0b5e5bf55fad647d450d4588ebc5792003 Mon Sep 17 00:00:00 2001 From: Vittorio Ballestra Date: Tue, 9 Aug 2016 10:41:26 +0200 Subject: [PATCH 169/657] much better indeed --- pkgs/source_maps/lib/builder.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 1f36b999b..c8596fe63 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -60,7 +60,7 @@ class SourceMapBuilder { } /// An entry in the source map builder. -class Entry implements Comparable { +class Entry implements Comparable { /// Span denoting the original location in the input source file final SourceLocation source; @@ -77,8 +77,7 @@ class Entry implements Comparable { /// location in the target file. We sort primarily by the target offset /// because source map files are encoded by printing each mapping in order as /// they appear in the target file. - int compareTo(_other) { - Entry other = _other as Entry; + int compareTo(Entry other) { int res = target.compareTo(other.target); if (res != 0) return res; res = source.sourceUrl.toString().compareTo( From afcf0d0f0309ae7b42e5ca2acee24c3b41f722d2 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Tue, 16 Aug 2016 17:53:12 +0100 Subject: [PATCH 170/657] Remove space that causes link not to render on pub.dartlang.org. The link doesn't render correctly here because of the space: https://pub.dartlang.org/packages/package_config --- pkgs/package_config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 0463719b3..942822002 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -2,7 +2,7 @@ Support for working with **Package Resolution Configuration** files as described in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), -under review [here] (https://github.com/dart-lang/dart_enhancement_proposals/issues/5). +under review [here](https://github.com/dart-lang/dart_enhancement_proposals/issues/5). [![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) From fe0d59a2a6353f8aa2d961327f91e91847919ab4 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 2 Sep 2016 07:04:05 -0700 Subject: [PATCH 171/657] Some minor changes: - organize imports - add the generated doc directory to the gitignore file BUG= R=pquitslund@google.com Review URL: https://codereview.chromium.org//2298063005 . --- pkgs/package_config/.gitignore | 1 + pkgs/package_config/lib/discovery_analysis.dart | 2 +- pkgs/package_config/lib/packages_file.dart | 1 + pkgs/package_config/lib/src/packages_impl.dart | 1 + pkgs/package_config/lib/src/packages_io_impl.dart | 2 ++ 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore index aac1f4fe8..a8b93ef38 100644 --- a/pkgs/package_config/.gitignore +++ b/pkgs/package_config/.gitignore @@ -2,3 +2,4 @@ .pub packages pubspec.lock +doc/api/ diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart index 058330b19..ce7e98a1a 100644 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -12,8 +12,8 @@ /// determined to be "package directories" themselves. library package_config.discovery_analysis; -import "dart:io" show File, Directory; import "dart:collection" show HashMap; +import "dart:io" show File, Directory; import "package:path/path.dart" as path; diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 93ccd3c18..0f1a6e635 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -5,6 +5,7 @@ library package_config.packages_file; import "package:charcode/ascii.dart"; + import "src/util.dart" show isValidPackageName; /// Parses a `.packages` file into a map from package name to base URI. diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index fa9115fc6..df89e4623 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -8,6 +8,7 @@ library package_config.packages_impl; import "dart:collection" show UnmodifiableMapView; + import "../packages.dart"; import "util.dart" show checkValidPackageUri; diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart index 0e9474639..9eba9ce44 100644 --- a/pkgs/package_config/lib/src/packages_io_impl.dart +++ b/pkgs/package_config/lib/src/packages_io_impl.dart @@ -8,7 +8,9 @@ library package_config.packages_io_impl; import "dart:collection" show UnmodifiableMapView; import "dart:io" show Directory; + import "package:path/path.dart" as path; + import "packages_impl.dart"; /// A [Packages] implementation based on a local directory. From 825a02483a28af9deb0eb9f0c7df98b1ad058f4d Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 17 Oct 2016 11:23:51 -0700 Subject: [PATCH 172/657] fix new strong mode error --- pkgs/source_span/lib/src/span_mixin.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index f6d04fa7c..a258cf5b4 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -60,7 +60,7 @@ abstract class SourceSpanMixin implements SourceSpan { if (length == 0 && this is! SourceSpanWithContext) return buffer.toString(); buffer.write("\n"); - var textLine; + String textLine; if (this is SourceSpanWithContext) { var context = (this as SourceSpanWithContext).context; var lineStart = findLineStart(context, text, column); From 9b64b5773486ba4ddc6149bd55e07015ea625791 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 17 Oct 2016 11:24:47 -0700 Subject: [PATCH 173/657] update pubspec/changelog for 1.2.4 --- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index d1bcda5ea..6da848706 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.2.4 + +* Fix a new strong mode error. + # 1.2.3 * Fix a bug where a point span at the end of a file without a trailing newline diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 3ef97ed13..9e41fdda0 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.2.3 +version: 1.2.4 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From d9853149e09a3ea73a42b9f63c6460479adcf9f4 Mon Sep 17 00:00:00 2001 From: Sigmund Cherem Date: Mon, 31 Oct 2016 09:32:35 -0700 Subject: [PATCH 174/657] Publish new version of source_maps with extra strong mode fixes --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 4872d79a9..fe88e6db4 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.1+2 + +* Fix more strong mode warnings. + ## 0.10.1+1 * Fix all strong mode warnings. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index e8dd7940a..0aea12baa 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.1+1 +version: 0.10.1+2 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps From 1efa400c47aaedc47da778b46232fde591baf4cb Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 8 Nov 2016 11:35:21 -0800 Subject: [PATCH 175/657] Add SourceSpan.highlight(). (dart-lang/source_span#10) This is useful for constructing a message with a non-standard file/line/column display. --- pkgs/source_span/CHANGELOG.md | 5 ++ pkgs/source_span/lib/src/span.dart | 13 +++++ pkgs/source_span/lib/src/span_mixin.dart | 26 ++++++---- pkgs/source_span/pubspec.yaml | 2 +- ..._message_test.dart => highlight_test.dart} | 52 ++++++++++--------- pkgs/source_span/test/span_test.dart | 36 +------------ 6 files changed, 65 insertions(+), 69 deletions(-) rename pkgs/source_span/test/{file_message_test.dart => highlight_test.dart} (59%) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 6da848706..afcc49378 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.3.0 + +* Add `SourceSpan.highlight()`, which returns just the highlighted text that + would be included in `SourceSpan.message()`. + # 1.2.4 * Fix a new strong mode error. diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index fe1ac3956..599d66806 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -53,6 +53,19 @@ abstract class SourceSpan implements Comparable { /// should be highlighted using the default color. If it's `false` or `null`, /// it indicates that the text shouldn't be highlighted. String message(String message, {color}); + + /// Prints the text associated with this span in a user-friendly way. + /// + /// This is identical to [message], except that it doesn't print the file + /// name, line number, column number, or message. If [length] is 0 and this + /// isn't a [SourceSpanWithContext], returns an empty string. + /// + /// [color] may either be a [String], a [bool], or `null`. If it's a string, + /// it indicates an ANSII terminal color escape that should be used to + /// highlight the span's text. If it's `true`, it indicates that the text + /// should be highlighted using the default color. If it's `false` or `null`, + /// it indicates that the text shouldn't be highlighted. + String highlight({color}); } /// A base class for source spans with [start], [end], and [text] known at diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index a258cf5b4..8d84ceaa7 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -46,20 +46,26 @@ abstract class SourceSpanMixin implements SourceSpan { } String message(String message, {color}) { - if (color == true) color = colors.RED; - if (color == false) color = null; - - var line = start.line; - var column = start.column; - var buffer = new StringBuffer(); - buffer.write('line ${line + 1}, column ${column + 1}'); + buffer.write('line ${start.line + 1}, column ${start.column + 1}'); if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); buffer.write(': $message'); - if (length == 0 && this is! SourceSpanWithContext) return buffer.toString(); - buffer.write("\n"); + var highlight = this.highlight(color: color); + if (!highlight.isEmpty) { + buffer.writeln(); + buffer.write(highlight); + } + + return buffer.toString(); + } + String highlight({color}) { + if (color == true) color = colors.RED; + if (color == false) color = null; + + var column = start.column; + var buffer = new StringBuffer(); String textLine; if (this is SourceSpanWithContext) { var context = (this as SourceSpanWithContext).context; @@ -71,6 +77,8 @@ abstract class SourceSpanMixin implements SourceSpan { var endIndex = context.indexOf('\n'); textLine = endIndex == -1 ? context : context.substring(0, endIndex + 1); column = math.min(column, textLine.length); + } else if (length == 0) { + return ""; } else { textLine = text.split("\n").first; column = 0; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 9e41fdda0..8fa871120 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.2.4 +version: 1.3.0 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/file_message_test.dart b/pkgs/source_span/test/highlight_test.dart similarity index 59% rename from pkgs/source_span/test/file_message_test.dart rename to pkgs/source_span/test/highlight_test.dart index d78a65172..32b09ff09 100644 --- a/pkgs/source_span/test/file_message_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -13,48 +13,42 @@ main() { foo bar baz whiz bang boom zip zap zop -""", url: "foo.dart"); +"""); }); test("points to the span in the source", () { - expect(file.span(4, 7).message("oh no"), equals(""" -line 1, column 5 of foo.dart: oh no + expect(file.span(4, 7).highlight(), equals(""" foo bar baz ^^^""")); }); test("gracefully handles a missing source URL", () { var span = new SourceFile("foo bar baz").span(4, 7); - expect(span.message("oh no"), equals(""" -line 1, column 5: oh no + expect(span.highlight(), equals(""" foo bar baz ^^^""")); }); test("highlights the first line of a multiline span", () { - expect(file.span(4, 20).message("oh no"), equals(""" -line 1, column 5 of foo.dart: oh no + expect(file.span(4, 20).highlight(), equals(""" foo bar baz ^^^^^^^^""")); }); test("works for a point span", () { - expect(file.location(4).pointSpan().message("oh no"), equals(""" -line 1, column 5 of foo.dart: oh no + expect(file.location(4).pointSpan().highlight(), equals(""" foo bar baz ^""")); }); test("works for a point span at the end of a line", () { - expect(file.location(11).pointSpan().message("oh no"), equals(""" -line 1, column 12 of foo.dart: oh no + expect(file.location(11).pointSpan().highlight(), equals(""" foo bar baz ^""")); }); test("works for a point span at the end of the file", () { - expect(file.location(38).pointSpan().message("oh no"), equals(""" -line 3, column 12 of foo.dart: oh no + expect(file.location(38).pointSpan().highlight(), equals(""" zip zap zop ^""")); }); @@ -62,46 +56,54 @@ zip zap zop test("works for a point span at the end of the file with no trailing newline", () { file = new SourceFile("zip zap zop"); - expect(file.location(11).pointSpan().message("oh no"), equals(""" -line 1, column 12: oh no + expect(file.location(11).pointSpan().highlight(), equals(""" zip zap zop ^""")); }); test("works for a point span in an empty file", () { - expect(new SourceFile("").location(0).pointSpan().message("oh no"), + expect(new SourceFile("").location(0).pointSpan().highlight(), equals(""" -line 1, column 1: oh no ^""")); }); test("works for a single-line file without a newline", () { - expect(new SourceFile("foo bar").span(0, 7).message("oh no"), + expect(new SourceFile("foo bar").span(0, 7).highlight(), equals(""" -line 1, column 1: oh no foo bar ^^^^^^^""")); }); + test("supports lines of preceding context", () { + var span = new SourceSpanWithContext( + new SourceLocation(5, line: 3, column: 5, sourceUrl: "foo.dart"), + new SourceLocation(12, line: 3, column: 12, sourceUrl: "foo.dart"), + "foo bar", + "previous\nlines\n-----foo bar-----\nfollowing line\n"); + + expect(span.highlight(color: colors.YELLOW), equals(""" +previous +lines +-----${colors.YELLOW}foo bar${colors.NONE}----- + ${colors.YELLOW}^^^^^^^${colors.NONE}""")); + }); + group("colors", () { test("doesn't colorize if color is false", () { - expect(file.span(4, 7).message("oh no", color: false), equals(""" -line 1, column 5 of foo.dart: oh no + expect(file.span(4, 7).highlight(color: false), equals(""" foo bar baz ^^^""")); }); test("colorizes if color is true", () { - expect(file.span(4, 7).message("oh no", color: true), equals(""" -line 1, column 5 of foo.dart: oh no + expect(file.span(4, 7).highlight(color: true), equals(""" foo ${colors.RED}bar${colors.NONE} baz ${colors.RED}^^^${colors.NONE}""")); }); test("uses the given color if it's passed", () { - expect(file.span(4, 7).message("oh no", color: colors.YELLOW), equals(""" -line 1, column 5 of foo.dart: oh no + expect(file.span(4, 7).highlight(color: colors.YELLOW), equals(""" foo ${colors.YELLOW}bar${colors.NONE} baz ${colors.YELLOW}^^^${colors.NONE}""")); }); diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 113848acf..f980f30cb 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -234,48 +234,16 @@ line 1, column 6 of foo.dart: oh no ${colors.YELLOW}foo bar${colors.NONE} ${colors.YELLOW}^^^^^^^${colors.NONE}""")); }); - }); - group("message() with context", () { - var spanWithContext; - setUp(() { - spanWithContext = new SourceSpanWithContext( + test("with context, underlines the right column", () { + var spanWithContext = new SourceSpanWithContext( new SourceLocation(5, sourceUrl: "foo.dart"), new SourceLocation(12, sourceUrl: "foo.dart"), "foo bar", "-----foo bar-----"); - }); - test("underlines under the right column", () { expect(spanWithContext.message("oh no", color: colors.YELLOW), equals(""" line 1, column 6 of foo.dart: oh no ------${colors.YELLOW}foo bar${colors.NONE}----- - ${colors.YELLOW}^^^^^^^${colors.NONE}""")); - }); - - test("underlines correctly when text appears twice", () { - var span = new SourceSpanWithContext( - new SourceLocation(9, column: 9, sourceUrl: "foo.dart"), - new SourceLocation(12, column: 12, sourceUrl: "foo.dart"), - "foo", - "-----foo foo-----"); - expect(span.message("oh no", color: colors.YELLOW), equals(""" -line 1, column 10 of foo.dart: oh no ------foo ${colors.YELLOW}foo${colors.NONE}----- - ${colors.YELLOW}^^^${colors.NONE}""")); - }); - - test("supports lines of preceeding context", () { - var span = new SourceSpanWithContext( - new SourceLocation(5, line: 3, column: 5, sourceUrl: "foo.dart"), - new SourceLocation(12, line: 3, column: 12, sourceUrl: "foo.dart"), - "foo bar", - "previous\nlines\n-----foo bar-----\nfollowing line\n"); - - expect(span.message("oh no", color: colors.YELLOW), equals(""" -line 4, column 6 of foo.dart: oh no -previous -lines -----${colors.YELLOW}foo bar${colors.NONE}----- ${colors.YELLOW}^^^^^^^${colors.NONE}""")); }); From a9d721a5a1225b6ed9a8ca2d5d9f49f8f0c98e93 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 16 Nov 2016 12:25:51 -0800 Subject: [PATCH 176/657] Fix a new strong mode error. (dart-lang/pub_semver#13) Closes dart-lang/pub_semver#12 --- pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/lib/src/version_range.dart | 4 ++-- pkgs/pub_semver/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index db3d320ff..3ba6f6ea1 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.3.1 + +* Fix a new strong mode error. + # 1.3.0 * Make the `VersionUnion` class public. This was previously used internally to diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index ffa50ab6b..861ae46db 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -321,7 +321,7 @@ class VersionRange implements Comparable, VersionConstraint { } else if (other is VersionRange) { if (!allowsAny(other)) return this; - VersionConstraint before; + VersionRange before; if (!allowsLower(this, other)) { before = VersionConstraint.empty; } else if (min == other.min) { @@ -334,7 +334,7 @@ class VersionRange implements Comparable, VersionConstraint { includeMin: includeMin, includeMax: !other.includeMin); } - VersionConstraint after; + VersionRange after; if (!allowsHigher(this, other)) { after = VersionConstraint.empty; } else if (max == other.max) { diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 531ace6ba..1712f6eb7 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.0 +version: 1.3.1 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From a0429ed8d8be51af36d1785fa7eb61352014849c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 21 Nov 2016 14:33:37 -0800 Subject: [PATCH 177/657] Fix a checked mode bug. (dart-lang/pub_semver#14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I missed this because I was running a version of test that relied on pub to turn on checked mode 😩. --- pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/lib/src/version_range.dart | 9 +++++---- pkgs/pub_semver/pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 3ba6f6ea1..6d54692d9 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.3.2 + +* Fix a checked-mode error in `VersionRange.difference()`. + # 1.3.1 * Fix a new strong mode error. diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 861ae46db..580f3feba 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -323,7 +323,7 @@ class VersionRange implements Comparable, VersionConstraint { VersionRange before; if (!allowsLower(this, other)) { - before = VersionConstraint.empty; + before = null; } else if (min == other.min) { assert(includeMin && !other.includeMin); assert(min != null); @@ -336,7 +336,7 @@ class VersionRange implements Comparable, VersionConstraint { VersionRange after; if (!allowsHigher(this, other)) { - after = VersionConstraint.empty; + after = null; } else if (max == other.max) { assert(includeMax && !other.includeMax); assert(max != null); @@ -347,8 +347,9 @@ class VersionRange implements Comparable, VersionConstraint { includeMin: !other.includeMax, includeMax: includeMax); } - if (before == VersionConstraint.empty) return after; - if (after == VersionConstraint.empty) return before; + if (before == null && after == null) return VersionConstraint.empty; + if (before == null) return after; + if (after == null) return before; return new VersionUnion.fromRanges([before, after]); } else if (other is VersionUnion) { var ranges = []; diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 1712f6eb7..2fe68a1f4 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.1 +version: 1.3.2 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 5e3d46ed16bd97d99b27b2e81e53d1c97d3ef4e3 Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Thu, 8 Dec 2016 08:20:42 -0800 Subject: [PATCH 178/657] Support a new source map bundle format useful for the Dart Dev Compiler. A source map bundle is a JSON array where each entry is a source map. BUG= R=sigmund@google.com Review URL: https://codereview.chromium.org//2560623003 . --- pkgs/source_maps/CHANGELOG.md | 7 + pkgs/source_maps/lib/parser.dart | 211 +++++++++++++++++-------- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 159 ++++++++++++++++--- 4 files changed, 290 insertions(+), 89 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index fe88e6db4..4e3286662 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.10.1+3 + +* Add `MappingBundle` class that handles extended source map format that + supports source maps for multiple output files in a single mapper. + Extend `Mapping.spanFor` API to accept a uri parameter that is optional + for normal source maps but required for MappingBundle source maps. + ## 0.10.1+2 * Fix more strong mode warnings. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index b659654f0..c651f89ff 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -8,6 +8,7 @@ library source_maps.parser; import 'dart:collection'; import 'dart:convert'; +import 'package:path/path.dart' as path; import 'package:source_span/source_span.dart'; import 'builder.dart' as builder; @@ -25,22 +26,44 @@ import 'src/vlq.dart'; // TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string // `)]}'` begins the string representation of the map. Mapping parse(String jsonMap, {Map otherMaps, mapUrl}) => - parseJson(JSON.decode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); + parseJson(JSON.decode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); -/// Parses a source map directly from a json map object. +/// Parses a source map or source map bundle directly from a json string. +/// +/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of +/// the source map file itself. If it's passed, any URLs in the source +/// map will be interpreted as relative to this URL when generating spans. +Mapping parseExtended(String jsonMap, {Map otherMaps, mapUrl}) => + parseJsonExtended(JSON.decode(jsonMap), + otherMaps: otherMaps, mapUrl: mapUrl); + +/// Parses a source map or source map bundle. +/// +/// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of +/// the source map file itself. If it's passed, any URLs in the source +/// map will be interpreted as relative to this URL when generating spans. +Mapping parseJsonExtended(/*List|Map*/ json, + {Map otherMaps, mapUrl}) { + if (json is List) { + return new MappingBundle.fromJson(json, mapUrl: mapUrl); + } + return parseJson(json as Map); +} + +/// Parses a source map /// /// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of /// the source map file itself. If it's passed, any URLs in the source /// map will be interpreted as relative to this URL when generating spans. Mapping parseJson(Map map, {Map otherMaps, mapUrl}) { if (map['version'] != 3) { - throw new ArgumentError( - 'unexpected source map version: ${map["version"]}. ' + throw new ArgumentError('unexpected source map version: ${map["version"]}. ' 'Only version 3 is supported.'); } if (map.containsKey('sections')) { - if (map.containsKey('mappings') || map.containsKey('sources') || + if (map.containsKey('mappings') || + map.containsKey('sources') || map.containsKey('names')) { throw new FormatException('map containing "sections" ' 'cannot contain "mappings", "sources", or "names".'); @@ -51,16 +74,21 @@ Mapping parseJson(Map map, {Map otherMaps, mapUrl}) { return new SingleMapping.fromJson(map, mapUrl: mapUrl); } - /// A mapping parsed out of a source map. abstract class Mapping { /// Returns the span associated with [line] and [column]. - SourceMapSpan spanFor(int line, int column, {Map files}); + /// + /// [uri] is the optional location of the output file to find the span for + /// to disambiguate cases where a mapping may have different mappings for + /// different output files. + SourceMapSpan spanFor(int line, int column, + {Map files, String uri}); /// Returns the span associated with [location]. SourceMapSpan spanForLocation(SourceLocation location, {Map files}) { - return spanFor(location.line, location.column, files: files); + return spanFor(location.line, location.column, + uri: location.sourceUrl?.toString(), files: files); } } @@ -116,35 +144,79 @@ class MultiSectionMapping extends Mapping { } int _indexFor(line, column) { - for(int i = 0; i < _lineStart.length; i++) { + for (int i = 0; i < _lineStart.length; i++) { if (line < _lineStart[i]) return i - 1; if (line == _lineStart[i] && column < _columnStart[i]) return i - 1; } return _lineStart.length - 1; } - SourceMapSpan spanFor(int line, int column, {Map files}) { + SourceMapSpan spanFor(int line, int column, + {Map files, String uri}) { + // TODO(jacobr): perhaps verify that targetUrl matches the actual uri + // or at least ends in the same file name. int index = _indexFor(line, column); return _maps[index].spanFor( - line - _lineStart[index], column - _columnStart[index], files: files); + line - _lineStart[index], column - _columnStart[index], + files: files); } String toString() { var buff = new StringBuffer("$runtimeType : ["); for (int i = 0; i < _lineStart.length; i++) { - buff..write('(') - ..write(_lineStart[i]) - ..write(',') - ..write(_columnStart[i]) - ..write(':') - ..write(_maps[i]) - ..write(')'); + buff + ..write('(') + ..write(_lineStart[i]) + ..write(',') + ..write(_columnStart[i]) + ..write(':') + ..write(_maps[i]) + ..write(')'); } buff.write(']'); return buff.toString(); } } +class MappingBundle extends Mapping { + Map _mappings = {}; + + MappingBundle.fromJson(List json, {String mapUrl}) { + for (var map in json) { + var mapping = parseJson(map, mapUrl: mapUrl) as SingleMapping; + var targetUrl = mapping.targetUrl; + _mappings[targetUrl] = mapping; + } + } + + /// Encodes the Mapping mappings as a json map. + List toJson() => _mappings.values.map((v) => v.toJson()).toList(); + + String toString() { + var buff = new StringBuffer(); + for (var map in _mappings.values) { + buff.write(map.toString()); + } + return buff.toString(); + } + + SourceMapSpan spanFor(int line, int column, + {Map files, String uri}) { + if (uri == null) { + throw new ArgumentError.notNull('uri'); + } + if (_mappings.containsKey(uri)) { + return _mappings[uri].spanFor(line, column, files: files, uri: uri); + } + // Fall back to looking up the source map on just the basename. + var name = path.basename(uri.toString()); + if (_mappings.containsKey(name)) { + return _mappings[name].spanFor(line, column, files: files, uri: name); + } + return null; + } +} + /// A map containing direct source mappings. class SingleMapping extends Mapping { /// Source urls used in the mapping, indexed by id. @@ -167,8 +239,8 @@ class SingleMapping extends Mapping { SingleMapping._(this.targetUrl, this.urls, this.names, this.lines) : _mapUrl = null; - factory SingleMapping.fromEntries( - Iterable entries, [String fileUrl]) { + factory SingleMapping.fromEntries(Iterable entries, + [String fileUrl]) { // The entries needs to be sorted by the target offsets. var sourceEntries = new List.from(entries)..sort(); var lines = []; @@ -196,14 +268,11 @@ class SingleMapping extends Mapping { var sourceUrl = sourceEntry.source.sourceUrl; var urlId = urls.putIfAbsent( sourceUrl == null ? '' : sourceUrl.toString(), () => urls.length); - var srcNameId = sourceEntry.identifierName == null ? null : - names.putIfAbsent(sourceEntry.identifierName, () => names.length); - targetEntries.add(new TargetEntry( - sourceEntry.target.column, - urlId, - sourceEntry.source.line, - sourceEntry.source.column, - srcNameId)); + var srcNameId = sourceEntry.identifierName == null + ? null + : names.putIfAbsent(sourceEntry.identifierName, () => names.length); + targetEntries.add(new TargetEntry(sourceEntry.target.column, urlId, + sourceEntry.source.line, sourceEntry.source.column, srcNameId)); } } return new SingleMapping._( @@ -271,8 +340,8 @@ class SingleMapping extends Mapping { throw new StateError( 'Invalid name id: $targetUrl, $line, $srcNameId'); } - entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn, - srcNameId)); + entries.add( + new TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId)); } } if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment(); @@ -326,8 +395,8 @@ class SingleMapping extends Mapping { 'version': 3, 'sourceRoot': sourceRoot == null ? '' : sourceRoot, 'sources': urls, - 'names' : names, - 'mappings' : buff.toString() + 'names': names, + 'mappings': buff.toString() }; if (targetUrl != null) { result['file'] = targetUrl; @@ -342,9 +411,9 @@ class SingleMapping extends Mapping { return newValue; } - _segmentError(int seen, int line) => new StateError( - 'Invalid entry in sourcemap, expected 1, 4, or 5' - ' values, but got $seen.\ntargeturl: $targetUrl, line: $line'); + _segmentError(int seen, int line) => + new StateError('Invalid entry in sourcemap, expected 1, 4, or 5' + ' values, but got $seen.\ntargeturl: $targetUrl, line: $line'); /// Returns [TargetLineEntry] which includes the location in the target [line] /// number. In particular, the resulting entry is the last entry whose line @@ -367,7 +436,8 @@ class SingleMapping extends Mapping { return (index <= 0) ? null : entries[index - 1]; } - SourceMapSpan spanFor(int line, int column, {Map files}) { + SourceMapSpan spanFor(int line, int column, + {Map files, String uri}) { var entry = _findColumn(line, column, _findLine(line)); if (entry == null || entry.sourceUrlId == null) return null; var url = urls[entry.sourceUrlId]; @@ -402,17 +472,18 @@ class SingleMapping extends Mapping { String toString() { return (new StringBuffer("$runtimeType : [") - ..write('targetUrl: ') - ..write(targetUrl) - ..write(', sourceRoot: ') - ..write(sourceRoot) - ..write(', urls: ') - ..write(urls) - ..write(', names: ') - ..write(names) - ..write(', lines: ') - ..write(lines) - ..write(']')).toString(); + ..write('targetUrl: ') + ..write(targetUrl) + ..write(', sourceRoot: ') + ..write(sourceRoot) + ..write(', urls: ') + ..write(urls) + ..write(', names: ') + ..write(names) + ..write(', lines: ') + ..write(lines) + ..write(']')) + .toString(); } String get debugString { @@ -420,24 +491,24 @@ class SingleMapping extends Mapping { for (var lineEntry in lines) { var line = lineEntry.line; for (var entry in lineEntry.entries) { - buff..write(targetUrl) + buff + ..write(targetUrl) + ..write(': ') + ..write(line) + ..write(':') + ..write(entry.column); + if (entry.sourceUrlId != null) { + buff + ..write(' --> ') + ..write(sourceRoot) + ..write(urls[entry.sourceUrlId]) ..write(': ') - ..write(line) + ..write(entry.sourceLine) ..write(':') - ..write(entry.column); - if (entry.sourceUrlId != null) { - buff..write(' --> ') - ..write(sourceRoot) - ..write(urls[entry.sourceUrlId]) - ..write(': ') - ..write(entry.sourceLine) - ..write(':') - ..write(entry.sourceColumn); + ..write(entry.sourceColumn); } if (entry.sourceNameId != null) { - buff..write(' (') - ..write(names[entry.sourceNameId]) - ..write(')'); + buff..write(' (')..write(names[entry.sourceNameId])..write(')'); } buff.write('\n'); } @@ -463,8 +534,11 @@ class TargetEntry { final int sourceColumn; final int sourceNameId; - TargetEntry(this.column, [this.sourceUrlId, this.sourceLine, - this.sourceColumn, this.sourceNameId]); + TargetEntry(this.column, + [this.sourceUrlId, + this.sourceLine, + this.sourceColumn, + this.sourceNameId]); String toString() => '$runtimeType: ' '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; @@ -482,7 +556,7 @@ class _MappingTokenizer implements Iterator { // Iterator API is used by decodeVlq to consume VLQ entries. bool moveNext() => ++index < _length; String get current => - (index >= 0 && index < _length) ? _internal[index] : null; + (index >= 0 && index < _length) ? _internal[index] : null; bool get hasTokens => index < _length - 1 && _length > 0; @@ -495,8 +569,13 @@ class _MappingTokenizer implements Iterator { } int _consumeValue() => decodeVlq(this); - void _consumeNewLine() { ++index; } - void _consumeNewSegment() { ++index; } + void _consumeNewLine() { + ++index; + } + + void _consumeNewSegment() { + ++index; + } // Print the state of the iterator, with colors indicating the current // position. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 0aea12baa..33626c550 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.1+2 +version: 0.10.1+3 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 88da8c547..9448ea08f 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -7,35 +7,59 @@ library test.parser_test; import 'dart:convert'; import 'package:test/test.dart'; import 'package:source_maps/source_maps.dart'; +import 'package:source_span/source_span.dart'; import 'common.dart'; const Map MAP_WITH_NO_SOURCE_LOCATION = const { - 'version': 3, - 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const [], - 'mappings': 'A', - 'file': 'output.dart' + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const [], + 'mappings': 'A', + 'file': 'output.dart' }; const Map MAP_WITH_SOURCE_LOCATION = const { - 'version': 3, - 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const [], - 'mappings': 'AAAA', - 'file': 'output.dart' + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const [], + 'mappings': 'AAAA', + 'file': 'output.dart' }; const Map MAP_WITH_SOURCE_LOCATION_AND_NAME = const { - 'version': 3, - 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const ['var'], - 'mappings': 'AAAAA', - 'file': 'output.dart' + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const ['var'], + 'mappings': 'AAAAA', + 'file': 'output.dart' }; +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_1 = const { + 'version': 3, + 'sourceRoot': 'pkg/', + 'sources': const ['input1.dart'], + 'names': const ['var1'], + 'mappings': 'AAAAA', + 'file': 'output1.dart' +}; + +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_2 = const { + 'version': 3, + 'sourceRoot': 'pkg/', + 'sources': const ['input2.dart'], + 'names': const ['var2'], + 'mappings': 'AAAAA', + 'file': 'output2.dart' +}; + +const List SOURCE_MAP_BUNDLE = const [ + MAP_WITH_SOURCE_LOCATION_AND_NAME_1, + MAP_WITH_SOURCE_LOCATION_AND_NAME_2 +]; + main() { test('parse', () { var mapping = parseJson(EXPECTED_MAP); @@ -105,6 +129,12 @@ main() { inputMap['sourceRoot'] = '/pkg/'; var mapping = parseJson(inputMap); expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse("/pkg/input.dart")); + expect( + mapping + .spanForLocation( + new SourceLocation(0, sourceUrl: Uri.parse("ignored.dart"))) + .sourceUrl, + Uri.parse("/pkg/input.dart")); var newSourceRoot = '/new/'; @@ -122,14 +152,99 @@ main() { Uri.parse("file:///path/to/pkg/input.dart")); }); + group('parse with bundle', () { + var mapping = + parseJsonExtended(SOURCE_MAP_BUNDLE, mapUrl: "file:///path/to/map"); + test('simple', () { + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: new Uri.file('/path/to/output1.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: new Uri.file('/path/to/output2.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + + expect( + mapping.spanFor(0, 0, uri: "file:///path/to/output1.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect( + mapping.spanFor(0, 0, uri: "file:///path/to/output2.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + }); + + test('unmapped path', () { + expect(mapping.spanFor(0, 0, uri: "unmapped_output.dart"), isNull); + }); + + test('missing path', () { + expect(() => mapping.spanFor(0, 0), throws); + }); + + test('incomplete paths', () { + expect(mapping.spanFor(0, 0, uri: "output1.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + }); + + test('parseExtended', () { + var mapping = parseExtended(JSON.encode(SOURCE_MAP_BUNDLE), + mapUrl: "file:///path/to/map"); + + expect(mapping.spanFor(0, 0, uri: "output1.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + }); + + // Test that the source map can handle cases where the uri passed in is + // not from the expected host but it is still unambiguous which source + // map should be used. + test('different paths', () { + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: Uri.parse('http://localhost/output1.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: Uri.parse('http://localhost/output2.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + + expect( + mapping.spanFor(0, 0, uri: "http://localhost/output1.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect( + mapping.spanFor(0, 0, uri: "http://localhost/output2.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + }); + }); + test('parse and re-emit', () { for (var expected in [ - EXPECTED_MAP, - MAP_WITH_NO_SOURCE_LOCATION, - MAP_WITH_SOURCE_LOCATION, - MAP_WITH_SOURCE_LOCATION_AND_NAME]) { + EXPECTED_MAP, + MAP_WITH_NO_SOURCE_LOCATION, + MAP_WITH_SOURCE_LOCATION, + MAP_WITH_SOURCE_LOCATION_AND_NAME + ]) { var mapping = parseJson(expected); expect(mapping.toJson(), equals(expected)); + + mapping = parseJsonExtended(expected); + expect(mapping.toJson(), equals(expected)); } + // Invalid for this case + expect(() => parseJson(SOURCE_MAP_BUNDLE), throws); + + var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE); + expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); }); } From c05a686f4dd048b0d269464f428da760d063dac2 Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Fri, 9 Dec 2016 09:56:09 -0800 Subject: [PATCH 179/657] Improve handling of locations not from the uris the source map is for. Make `MappingBundle` distinguish between locations from a file with source maps that do not have a source map entry and locations that are from a file that does not have a source map. This enables more graceful generation of stack traces with mixed Dart and JS stack frames. Support a new source map bundle format useful for the Dart Dev Compiler. A source map bundle is a JSON array where each entry is a source map. BUG= R=sigmund@google.com Review URL: https://codereview.chromium.org//2564683003 . --- pkgs/source_maps/CHANGELOG.md | 5 +++++ pkgs/source_maps/lib/parser.dart | 12 +++++++++++- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 10 +++++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 4e3286662..e5f3ae2e6 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.1+4 + +* Extend `MappingBundle.spanFor` to accept requests for output files that + don't have source maps. + ## 0.10.1+3 * Add `MappingBundle` class that handles extended source map format that diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index c651f89ff..492e6cf65 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -213,7 +213,17 @@ class MappingBundle extends Mapping { if (_mappings.containsKey(name)) { return _mappings[name].spanFor(line, column, files: files, uri: name); } - return null; + + // Note: when there is no source map for an uri, this behaves like an + // identity function, returning the requested location as the result. + + // Create a mock offset for the output location. We compute it in terms + // of the input line and column to minimize the chances that two different + // line and column locations are mapped to the same offset. + var offset = line * 1000000 + column; + var location = new SourceLocation(offset, + line: line, column: column, sourceUrl: Uri.parse(uri)); + return new SourceMapSpan(location, location, ""); } } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 33626c550..d0d455fff 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.1+3 +version: 0.10.1+4 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 9448ea08f..a317f7e63 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -178,7 +178,15 @@ main() { }); test('unmapped path', () { - expect(mapping.spanFor(0, 0, uri: "unmapped_output.dart"), isNull); + var span = mapping.spanFor(0, 0, uri: "unmapped_output.dart"); + expect(span.sourceUrl, Uri.parse("unmapped_output.dart")); + expect(span.start.line, equals(0)); + expect(span.start.column, equals(0)); + + span = mapping.spanFor(10, 5, uri: "unmapped_output.dart"); + expect(span.sourceUrl, Uri.parse("unmapped_output.dart")); + expect(span.start.line, equals(10)); + expect(span.start.column, equals(5)); }); test('missing path', () { From fb162a9c6db95499e372c49d3f17fc7b4c7a57e1 Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Mon, 12 Dec 2016 08:57:43 -0800 Subject: [PATCH 180/657] Fix strong mode error in test. Closes https://github.com/dart-lang/source_maps/issues/21 BUG= R=sigmund@google.com Review URL: https://codereview.chromium.org//2565053002 . --- pkgs/source_maps/CHANGELOG.md | 3 +++ pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index e5f3ae2e6..425e7aec5 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.10.1+5 + * Fix strong mode warning in test. + ## 0.10.1+4 * Extend `MappingBundle.spanFor` to accept requests for output files that diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index d0d455fff..3beb3eae0 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.1+4 +version: 0.10.1+5 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index a317f7e63..4b2d94713 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -250,7 +250,7 @@ main() { expect(mapping.toJson(), equals(expected)); } // Invalid for this case - expect(() => parseJson(SOURCE_MAP_BUNDLE), throws); + expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throws); var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE); expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); From 6f9505f8b60d4b184d3fb782afe83aadb9d23619 Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Wed, 14 Dec 2016 11:35:40 -0800 Subject: [PATCH 181/657] Rev package version as the extended source map format is a new feature. Polish `MappingBundle.spanFor` handling of uris that have a suffix that exactly match a source map in the MappingBundle. R=nweiz@google.com, sigmund@google.com Review URL: https://codereview.chromium.org//2574593004 . --- pkgs/source_maps/CHANGELOG.md | 5 ++ pkgs/source_maps/lib/parser.dart | 33 ++++++++--- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 79 +++++++++++++++++++++++--- 4 files changed, 102 insertions(+), 17 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 425e7aec5..d2bed8aca 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.2 + * Support for extended source map format. + * Polish `MappingBundle.spanFor` handling of URIs that have a suffix that + exactly match a source map in the MappingBundle. + ## 0.10.1+5 * Fix strong mode warning in test. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 492e6cf65..1c2318774 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -8,7 +8,6 @@ library source_maps.parser; import 'dart:collection'; import 'dart:convert'; -import 'package:path/path.dart' as path; import 'package:source_span/source_span.dart'; import 'builder.dart' as builder; @@ -185,6 +184,8 @@ class MappingBundle extends Mapping { for (var map in json) { var mapping = parseJson(map, mapUrl: mapUrl) as SingleMapping; var targetUrl = mapping.targetUrl; + // TODO(jacobr): verify that targetUrl is valid uri instead of a windows + // path. _mappings[targetUrl] = mapping; } } @@ -205,13 +206,29 @@ class MappingBundle extends Mapping { if (uri == null) { throw new ArgumentError.notNull('uri'); } - if (_mappings.containsKey(uri)) { - return _mappings[uri].spanFor(line, column, files: files, uri: uri); - } - // Fall back to looking up the source map on just the basename. - var name = path.basename(uri.toString()); - if (_mappings.containsKey(name)) { - return _mappings[name].spanFor(line, column, files: files, uri: name); + + // Find the longest suffix of the uri that matches the sourcemap + // where the suffix starts after a path segment boundary. + // We consider ":" and "/" as path segment boundaries so that + // "package:" uris can be handled with minimal special casing. Having a + // few false positive path segment boundaries is not a significant issue + // as we prefer the longest matching prefix. + // Using package:path `path.split` to find path segment boundaries would + // not generate all of the path segment boundaries we want for "package:" + // urls as "package:package_name" would be one path segment when we want + // "package" and "package_name" to be sepearate path segments. + + bool onBoundary = true; + var separatorCodeUnits = ['/'.codeUnitAt(0), ':'.codeUnitAt(0)]; + for (var i = 0; i < uri.length; ++i) { + if (onBoundary) { + var candidate = uri.substring(i); + if (_mappings.containsKey(candidate)) { + return _mappings[candidate] + .spanFor(line, column, files: files, uri: candidate); + } + } + onBoundary = separatorCodeUnits.contains(uri.codeUnitAt(i)); } // Note: when there is no source map for an uri, this behaves like an diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 3beb3eae0..64c0e9c7b 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.1+5 +version: 0.10.2 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 4b2d94713..3cccf4413 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -43,7 +43,7 @@ const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_1 = const { 'sources': const ['input1.dart'], 'names': const ['var1'], 'mappings': 'AAAAA', - 'file': 'output1.dart' + 'file': 'output.dart' }; const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_2 = const { @@ -55,9 +55,19 @@ const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_2 = const { 'file': 'output2.dart' }; +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_3 = const { + 'version': 3, + 'sourceRoot': 'pkg/', + 'sources': const ['input3.dart'], + 'names': const ['var3'], + 'mappings': 'AAAAA', + 'file': '3/output.dart' +}; + const List SOURCE_MAP_BUNDLE = const [ MAP_WITH_SOURCE_LOCATION_AND_NAME_1, - MAP_WITH_SOURCE_LOCATION_AND_NAME_2 + MAP_WITH_SOURCE_LOCATION_AND_NAME_2, + MAP_WITH_SOURCE_LOCATION_AND_NAME_3, ]; main() { @@ -155,11 +165,12 @@ main() { group('parse with bundle', () { var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE, mapUrl: "file:///path/to/map"); + test('simple', () { expect( mapping .spanForLocation(new SourceLocation(0, - sourceUrl: new Uri.file('/path/to/output1.dart'))) + sourceUrl: new Uri.file('/path/to/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect( @@ -168,13 +179,50 @@ main() { sourceUrl: new Uri.file('/path/to/output2.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: new Uri.file('/path/to/3/output.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); expect( - mapping.spanFor(0, 0, uri: "file:///path/to/output1.dart").sourceUrl, + mapping.spanFor(0, 0, uri: "file:///path/to/output.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect( mapping.spanFor(0, 0, uri: "file:///path/to/output2.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); + expect( + mapping.spanFor(0, 0, uri: "file:///path/to/3/output.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); + }); + + test('package uris', () { + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: Uri.parse('package:1/output.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: Uri.parse('package:2/output2.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: Uri.parse('package:3/output.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); + + expect(mapping.spanFor(0, 0, uri: "package:1/output.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + expect(mapping.spanFor(0, 0, uri: "package:2/output2.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + expect(mapping.spanFor(0, 0, uri: "package:3/output.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); }); test('unmapped path', () { @@ -194,20 +242,24 @@ main() { }); test('incomplete paths', () { - expect(mapping.spanFor(0, 0, uri: "output1.dart").sourceUrl, + expect(mapping.spanFor(0, 0, uri: "output.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); + expect(mapping.spanFor(0, 0, uri: "3/output.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); }); test('parseExtended', () { var mapping = parseExtended(JSON.encode(SOURCE_MAP_BUNDLE), mapUrl: "file:///path/to/map"); - expect(mapping.spanFor(0, 0, uri: "output1.dart").sourceUrl, + expect(mapping.spanFor(0, 0, uri: "output.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); + expect(mapping.spanFor(0, 0, uri: "3/output.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); }); // Test that the source map can handle cases where the uri passed in is @@ -217,7 +269,7 @@ main() { expect( mapping .spanForLocation(new SourceLocation(0, - sourceUrl: Uri.parse('http://localhost/output1.dart'))) + sourceUrl: Uri.parse('http://localhost/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect( @@ -226,13 +278,24 @@ main() { sourceUrl: Uri.parse('http://localhost/output2.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); + expect( + mapping + .spanForLocation(new SourceLocation(0, + sourceUrl: Uri.parse('http://localhost/3/output.dart'))) + .sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); expect( - mapping.spanFor(0, 0, uri: "http://localhost/output1.dart").sourceUrl, + mapping.spanFor(0, 0, uri: "http://localhost/output.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect( mapping.spanFor(0, 0, uri: "http://localhost/output2.dart").sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); + expect( + mapping + .spanFor(0, 0, uri: "http://localhost/3/output.dart") + .sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); }); }); From 0158800db5273379101d5e0b57c249392858680b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 6 Jan 2017 17:42:12 -0800 Subject: [PATCH 182/657] Fix tab highlighting. (dart-lang/source_span#14) --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/span_mixin.dart | 12 +++++++++++- pkgs/source_span/pubspec.yaml | 3 ++- pkgs/source_span/test/highlight_test.dart | 7 +++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index afcc49378..0176b9f0b 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.3.1 + +* Properly highlight spans for lines that include tabs with + `SourceSpan.highlight()` and `SourceSpan.message()`. + # 1.3.0 * Add `SourceSpan.highlight()`, which returns just the highlighted text that diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 8d84ceaa7..06e2024c9 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -3,6 +3,8 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:math' as math; + +import 'package:charcode/charcode.dart'; import 'package:path/path.dart' as p; import 'colors.dart' as colors; @@ -96,7 +98,15 @@ abstract class SourceSpanMixin implements SourceSpan { buffer.write(textLine); } if (!textLine.endsWith('\n')) buffer.write('\n'); - buffer.write(' ' * column); + + for (var i = 0; i < column; i++) { + if (textLine.codeUnitAt(i) == $tab) { + buffer.writeCharCode($tab); + } else { + buffer.writeCharCode($space); + } + } + if (color != null) buffer.write(color); buffer.write('^' * math.max(toColumn - column, 1)); if (color != null) buffer.write(colors.NONE); diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 8fa871120..d340d85cc 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,9 +1,10 @@ name: source_span -version: 1.3.0 +version: 1.3.1 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span dependencies: + charcode: '^1.0.0' path: '>=1.2.0 <2.0.0' environment: sdk: '>=0.8.10+6 <2.0.0' diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 32b09ff09..74faed52a 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -75,6 +75,13 @@ foo bar ^^^^^^^""")); }); + test("emits tabs for tabs", () { + expect(new SourceFile(" \t \t\tfoo bar").span(5, 8).highlight(), + equals(""" + \t \t\tfoo bar + \t \t\t^^^""")); + }); + test("supports lines of preceding context", () { var span = new SourceSpanWithContext( new SourceLocation(5, line: 3, column: 5, sourceUrl: "foo.dart"), From 2829c3826c3e57e80e6ffcd5664653ca96cab105 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 6 Jan 2017 17:46:46 -0800 Subject: [PATCH 183/657] Update the SDK constraint. (dart-lang/source_span#15) If we're using ^ constraints, we need a tighter SDK constraint. --- pkgs/source_span/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index d340d85cc..70f4e108b 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -7,6 +7,6 @@ dependencies: charcode: '^1.0.0' path: '>=1.2.0 <2.0.0' environment: - sdk: '>=0.8.10+6 <2.0.0' + sdk: '>=1.8.0 <2.0.0' dev_dependencies: test: '>=0.12.0 <0.13.0' From 11c2f1cc946f9b2b1598e566c5049826cb02b4f9 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Thu, 26 Jan 2017 08:48:14 -0800 Subject: [PATCH 184/657] Fix strong mode error in test (dart-lang/pub_semver#15) --- pkgs/pub_semver/test/version_range_test.dart | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index a2dbf9810..23d771049 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -327,10 +327,12 @@ main() { var a = new VersionRange(min: v123, max: v250); var b = new VersionRange(min: v200, max: v300); var intersect = a.intersect(b); - expect(intersect.min, equals(v200)); - expect(intersect.max, equals(v250)); - expect(intersect.includeMin, isFalse); - expect(intersect.includeMax, isFalse); + expect(intersect, new isInstanceOf()); + var intersectRange = intersect as VersionRange; + expect(intersectRange.min, equals(v200)); + expect(intersectRange.max, equals(v250)); + expect(intersectRange.includeMin, isFalse); + expect(intersectRange.includeMax, isFalse); }); test('a non-overlapping range allows no versions', () { From 11e3f8c83b99f12b6a265970c95ed35aa5a37280 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 16 Feb 2017 13:10:41 -0800 Subject: [PATCH 185/657] Add a Pool.done getter. (dart-lang/pool#5) --- pkgs/pool/CHANGELOG.md | 5 +++++ pkgs/pool/lib/pool.dart | 14 +++++++++++--- pkgs/pool/pubspec.yaml | 2 +- pkgs/pool/test/pool_test.dart | 12 ++++++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 96d4c2f51..66b476920 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.3.0 + +* Add a `Pool.done` getter that returns the same future returned by + `Pool.close()`. + ## 1.2.4 * Fix a strong-mode error. diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index faa9f0e12..67c4a8287 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -63,7 +63,14 @@ class Pool { FutureGroup _closeGroup; /// Whether [close] has been called. - bool get isClosed => _closeGroup != null; + bool get isClosed => _closeMemo.hasRun; + + /// A future that completes once the pool is closed and all its outstanding + /// resources have been released. + /// + /// If any [PoolResource.allowRelease] callback throws an exception after the + /// pool is closed, this completes with that exception. + Future get done => _closeMemo.future; /// Creates a new pool with the given limit on how many resources may be /// allocated at once. @@ -132,7 +139,7 @@ class Pool { /// an error, the returned future completes with that error. /// /// This may be called more than once; it returns the same [Future] each time. - Future close() { + Future close() => _closeMemo.runOnce(() { if (_closeGroup != null) return _closeGroup.future; _resetTimer(); @@ -147,7 +154,8 @@ class Pool { if (_allocatedResources == 0) _closeGroup.close(); return _closeGroup.future; - } + }); + final _closeMemo = new AsyncMemoizer(); /// If there are any pending requests, this will fire the oldest one. void _onResourceReleased() { diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 145df2bbf..3029b9fc4 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.2.4 +version: 1.3.0 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index bd44cb275..7fba9c0b0 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -279,6 +279,16 @@ void main() { }); }); + test("done doesn't complete without close", () async { + var pool = new Pool(1); + pool.done.then(expectAsync1((_) {}, count: 0)); + + var resource = await pool.request(); + resource.release(); + + await new Future.delayed(Duration.ZERO); + }); + group("close()", () { test("disallows request() and withResource()", () { var pool = new Pool(1)..close(); @@ -292,6 +302,7 @@ void main() { expect(pool.request().then((resource2) { resource2.release(); }), completes); + expect(pool.done, completes); expect(pool.close(), completes); resource1.release(); }); @@ -405,6 +416,7 @@ void main() { var completer = new Completer(); resource.allowRelease(() => completer.future); + expect(pool.done, throwsA("oh no!")); expect(pool.close(), throwsA("oh no!")); await new Future.delayed(Duration.ZERO); From 78b28e9bbee08b51b856ef3adab8fa6f79e04c91 Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Tue, 7 Mar 2017 11:29:40 -0800 Subject: [PATCH 186/657] Enabling adding and querying for source maps in a MappingBundle. BUG= R=sigmund@google.com Review-Url: https://codereview.chromium.org//2736983002 . --- pkgs/source_maps/CHANGELOG.md | 3 +++ pkgs/source_maps/lib/parser.dart | 16 +++++++++++----- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 23 +++++++++++++++++++++++ 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index d2bed8aca..95b161daf 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.10.3 + * Add `addMapping` and `containsMapping` members to `MappingBundle`. + ## 0.10.2 * Support for extended source map format. * Polish `MappingBundle.spanFor` handling of URIs that have a suffix that diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 1c2318774..3b65e8910 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -180,16 +180,20 @@ class MultiSectionMapping extends Mapping { class MappingBundle extends Mapping { Map _mappings = {}; + MappingBundle() {} + MappingBundle.fromJson(List json, {String mapUrl}) { for (var map in json) { - var mapping = parseJson(map, mapUrl: mapUrl) as SingleMapping; - var targetUrl = mapping.targetUrl; - // TODO(jacobr): verify that targetUrl is valid uri instead of a windows - // path. - _mappings[targetUrl] = mapping; + addMapping(parseJson(map, mapUrl: mapUrl) as SingleMapping); } } + addMapping(SingleMapping mapping) { + // TODO(jacobr): verify that targetUrl is valid uri instead of a windows + // path. + _mappings[mapping.targetUrl] = mapping; + } + /// Encodes the Mapping mappings as a json map. List toJson() => _mappings.values.map((v) => v.toJson()).toList(); @@ -201,6 +205,8 @@ class MappingBundle extends Mapping { return buff.toString(); } + bool containsMapping(String url) => _mappings.containsKey(url); + SourceMapSpan spanFor(int line, int column, {Map files, String uri}) { if (uri == null) { diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 64c0e9c7b..618551236 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.2 +version: 0.10.3 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 3cccf4413..2c24d1b6f 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -262,6 +262,29 @@ main() { Uri.parse("file:///path/to/pkg/input3.dart")); }); + test('build bundle incrementally', () { + var mapping = new MappingBundle(); + + mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_1, + mapUrl: "file:///path/to/map")); + expect(mapping.spanFor(0, 0, uri: "output.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input1.dart")); + + expect(mapping.containsMapping("output2.dart"), isFalse); + mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_2, + mapUrl: "file:///path/to/map")); + expect(mapping.containsMapping("output2.dart"), isTrue); + expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input2.dart")); + + expect(mapping.containsMapping("3/output.dart"), isFalse); + mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_3, + mapUrl: "file:///path/to/map")); + expect(mapping.containsMapping("3/output.dart"), isTrue); + expect(mapping.spanFor(0, 0, uri: "3/output.dart").sourceUrl, + Uri.parse("file:///path/to/pkg/input3.dart")); + }); + // Test that the source map can handle cases where the uri passed in is // not from the expected host but it is still unambiguous which source // map should be used. From 8e233ce3ffb54ea6c9afd1ef363d852dc1277f11 Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Tue, 7 Mar 2017 14:39:54 -0800 Subject: [PATCH 187/657] Remove unused dependency on the path package. BUG= R=sigmund@google.com Review-Url: https://codereview.chromium.org//2732253003 . --- pkgs/source_maps/pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 618551236..c10127166 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -4,7 +4,6 @@ author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps dependencies: - path: ^1.2.0 source_span: ^1.1.1 environment: sdk: '>=1.8.0 <2.0.0' From 27f0d293f012ca440d9713ac27d49cb8ca72f17a Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Thu, 23 Mar 2017 09:33:24 -0700 Subject: [PATCH 188/657] implement highlight for SourceMapFileSpan --- pkgs/source_maps/lib/src/source_map_span.dart | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index b70bdfe98..37107e1c7 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -17,7 +17,7 @@ class SourceMapSpan extends SourceSpanBase { final bool isIdentifier; SourceMapSpan(SourceLocation start, SourceLocation end, String text, - {this.isIdentifier: false}) + {this.isIdentifier: false}) : super(start, end, text); /// Creates a [SourceMapSpan] for an identifier with value [text] starting at @@ -26,13 +26,13 @@ class SourceMapSpan extends SourceSpanBase { /// The [end] location is determined by adding [text] to [start]. SourceMapSpan.identifier(SourceLocation start, String text) : this( - start, - new SourceLocation(start.offset + text.length, - sourceUrl: start.sourceUrl, - line: start.line, - column: start.column + text.length), - text, - isIdentifier: true); + start, + new SourceLocation(start.offset + text.length, + sourceUrl: start.sourceUrl, + line: start.line, + column: start.column + text.length), + text, + isIdentifier: true); } /// A wrapper aruond a [FileSpan] that implements [SourceMapSpan]. @@ -51,10 +51,11 @@ class SourceMapFileSpan implements SourceMapSpan, FileSpan { SourceMapFileSpan(this._inner, {this.isIdentifier: false}); int compareTo(SourceSpan other) => _inner.compareTo(other); + String highlight({color}) => _inner.highlight(color: color); SourceSpan union(SourceSpan other) => _inner.union(other); FileSpan expand(FileSpan other) => _inner.expand(other); String message(String message, {color}) => _inner.message(message, color: color); - String toString() => _inner.toString() - .replaceAll("FileSpan", "SourceMapFileSpan"); + String toString() => + _inner.toString().replaceAll("FileSpan", "SourceMapFileSpan"); } From 06dea5e04daf524761d2a9c8df903e5c2d338add Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Thu, 23 Mar 2017 09:36:05 -0700 Subject: [PATCH 189/657] update pubspec/changelog for 0.10.4 --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 95b161daf..a7c1b0670 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.4 +* Implement `highlight` in `SourceMapFileSpan`. +* Require version `^1.3.0` of `source_span`. + ## 0.10.3 * Add `addMapping` and `containsMapping` members to `MappingBundle`. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index c10127166..1db777bdc 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,10 +1,10 @@ name: source_maps -version: 0.10.3 +version: 0.10.4 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps dependencies: - source_span: ^1.1.1 + source_span: ^1.3.0 environment: sdk: '>=1.8.0 <2.0.0' dev_dependencies: From 520ade132d7397f7f180a171d387f796b4718af6 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 4 May 2017 16:13:41 +0200 Subject: [PATCH 190/657] Fix write to sink after close in test code. R=floitsch@google.com Review-Url: https://codereview.chromium.org//2857383002 . --- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/discovery_test.dart | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 18a42ce71..c03367853 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.1 + +- Fix test to not write to sink after it's closed. + ## 1.0.0 - Public API marked stable. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index e1afec23c..eaef83e3a 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.0.0 +version: 1.0.1 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 8807ac497..897063f52 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -290,6 +290,7 @@ void httpTest(String name, Map description, Future httpTest(Uri directory)) { if (fileOrDir == null) { request.response.statusCode = 404; request.response.close(); + return; } } request.response.write(fileOrDir); From c289d1c07a23f780988040875385ff7ab3a955e9 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 16 May 2017 20:43:35 -0700 Subject: [PATCH 191/657] Pool.withResource() should take () -> FutureOr. (dart-lang/pool#7) Closes dart-lang/pool#6 --- pkgs/pool/CHANGELOG.md | 5 +++++ pkgs/pool/lib/pool.dart | 6 +++--- pkgs/pool/pubspec.yaml | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 66b476920..80d54c73f 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.3.1 + +* Fix the type annotation of `Pool.withResource()` to indicate that it takes + `() -> FutureOr`. + ## 1.3.0 * Add a `Pool.done` getter that returns the same future returned by diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 67c4a8287..04aaaea65 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -113,7 +113,7 @@ class Pool { /// Future. /// /// The return value of [callback] is piped to the returned Future. - Future/**/ withResource/**/(/*=T*/ callback()) { + Future withResource(FutureOr callback()) { if (isClosed) { throw new StateError( "withResource() may not be called on a closed Pool."); @@ -123,8 +123,8 @@ class Pool { // synchronously in case the pool is closed immediately afterwards. Async // functions have an asynchronous gap between calling and running the body, // and [close] could be called during that gap. See #3. - return request().then/*>*/((resource) { - return new Future/**/.sync(callback).whenComplete(resource.release); + return request().then>((resource) { + return new Future.sync(callback).whenComplete(resource.release); }); } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 3029b9fc4..8efc8e55a 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.3.0 +version: 1.3.1 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool @@ -7,7 +7,7 @@ dependencies: async: "^1.4.0" stack_trace: ">=0.9.2 <2.0.0" environment: - sdk: ">=1.9.0 <2.0.0" + sdk: ">=1.22.0 <2.0.0" dev_dependencies: fake_async: ">=0.1.0 <0.2.0" test: ">=0.12.0 <0.13.0" From 4d62afa97be1cd80f1404d91a5e5ce2faf42a7aa Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 16 May 2017 22:18:03 -0700 Subject: [PATCH 192/657] Deprecate the use of runes in SourceFile. (dart-lang/source_span#16) This behavior runs contrary to the rest of Dart's string handling, and in particular breaks string_scanner. See dart-lang/string_scannerdart-lang/source_span#4. --- pkgs/source_span/CHANGELOG.md | 13 +++++++++++++ pkgs/source_span/lib/src/file.dart | 19 ++++++++++++++++--- pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 0176b9f0b..68eafaaef 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,16 @@ +# 1.4.0 + +* The `new SourceFile()` constructor is deprecated. This constructed a source + file from a string's runes, rather than its code units, which runs counter to + the way Dart handles strings otherwise. The `new StringFile.fromString()` + constructor (see below) should be used instead. + +* The `new SourceFile.fromString()` constructor was added. This works like `new + SourceFile()`, except it uses code units rather than runes. + +* The current behavior when characters larger than `0xFFFF` are passed to `new + SourceFile.decoded()` is now considered deprecated. + # 1.3.1 * Properly highlight spans for lines that include tabs with diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 1d39cf17a..0217c2d43 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -49,15 +49,28 @@ class SourceFile { /// previous result. int _cachedLine; - /// Creates a new source file from [text]. + /// This constructor is deprecated. /// - /// [url] may be either a [String], a [Uri], or `null`. + /// Use [new SourceFile.fromString] instead. + @Deprecated("Will be removed in 2.0.0") SourceFile(String text, {url}) : this.decoded(text.runes, url: url); - /// Creates a new source file from a list of decoded characters. + /// Creates a new source file from [text]. /// /// [url] may be either a [String], a [Uri], or `null`. + SourceFile.fromString(String text, {url}) + : this.decoded(text.codeUnits, url: url); + + /// Creates a new source file from a list of decoded code units. + /// + /// [url] may be either a [String], a [Uri], or `null`. + /// + /// Currently, if [decodedChars] contains characters larger than `0xFFFF`, + /// they'll be treated as single characters rather than being split into + /// surrogate pairs. **This behavior is deprecated**. For + /// forwards-compatibility, callers should only pass in characters less than + /// or equal to `0xFFFF`. SourceFile.decoded(Iterable decodedChars, {url}) : url = url is String ? Uri.parse(url) : url, _decodedChars = new Uint32List.fromList(decodedChars.toList()) { diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 70f4e108b..46e3d522e 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.3.1 +version: 1.4.0 author: Dart Team description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span From 4b603539a0568f653b689cea40de435b8cc17f53 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 5 Jul 2017 22:45:45 +0200 Subject: [PATCH 193/657] Update README.md (dart-lang/pool#8) --- pkgs/pool/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/README.md b/pkgs/pool/README.md index 898728867..641e77287 100644 --- a/pkgs/pool/README.md +++ b/pkgs/pool/README.md @@ -13,7 +13,7 @@ final pool = new Pool(10, timeout: new Duration(seconds: 30)); Future readFile(String path) { // Since the call to [File.readAsString] is within [withResource], no more // than ten files will be open at once. - return pool.withResource(() => return new File(path).readAsString()); + return pool.withResource(() => new File(path).readAsString()); } ``` From e7805eaf4c4b21af38c2c9d72e78e092d1242761 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 19 Jul 2017 12:08:29 -0700 Subject: [PATCH 194/657] Update SDK constraint to be 2.0.0 dev friendly. --- pkgs/package_config/pubspec.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index eaef83e3a..a629eafef 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,15 +1,15 @@ name: package_config -version: 1.0.1 +version: 1.0.2 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=1.11.0-dev.0.0 <2.0.0' + sdk: '>=1.11.0 <2.0.0-dev.infinity' dependencies: charcode: ^1.1.0 path: ^1.0.0 dev_dependencies: - test: '>=0.12.0 <0.13.0' + test: ^0.12.0 From 4160a04201c62ea197f4df9ab0b4007dfc255237 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 19 Jul 2017 12:10:16 -0700 Subject: [PATCH 195/657] Update CHANGELOG.md --- pkgs/package_config/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index c03367853..c17c67498 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.2 + +- Update SDK constraint to be 2.0.0 dev friendly. + ## 1.0.1 - Fix test to not write to sink after it's closed. From 9d1c4cc5a4ba9740ef46bbebeee73fe882e22f8a Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 19 Jul 2017 12:19:59 -0700 Subject: [PATCH 196/657] Rename .analysis_options to analysis_options.yaml --- pkgs/package_config/{.analysis_options => analysis_options.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkgs/package_config/{.analysis_options => analysis_options.yaml} (100%) diff --git a/pkgs/package_config/.analysis_options b/pkgs/package_config/analysis_options.yaml similarity index 100% rename from pkgs/package_config/.analysis_options rename to pkgs/package_config/analysis_options.yaml From 5312c5efd70ea519f5356b83cdfab355e2729d1b Mon Sep 17 00:00:00 2001 From: pq Date: Thu, 3 Aug 2017 15:48:10 -0700 Subject: [PATCH 197/657] Make trusty default distro explicit. --- pkgs/package_config/.travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml index 7a20d25b2..d7febddd1 100644 --- a/pkgs/package_config/.travis.yml +++ b/pkgs/package_config/.travis.yml @@ -1,4 +1,5 @@ language: dart dart: dev script: ./tool/travis.sh +dist: trusty sudo: false From c8859a59688e71fb9d3a2a966340fbfaf45f6239 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 30 Aug 2017 13:55:49 -0700 Subject: [PATCH 198/657] Add Travis CI support --- pkgs/pub_semver/.travis.yml | 19 +++++++++++++++++++ pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 pkgs/pub_semver/.travis.yml diff --git a/pkgs/pub_semver/.travis.yml b/pkgs/pub_semver/.travis.yml new file mode 100644 index 000000000..6788deead --- /dev/null +++ b/pkgs/pub_semver/.travis.yml @@ -0,0 +1,19 @@ +language: dart +sudo: false +dart: + - dev + - stable + - 1.21.1 + +dart_task: + - test + - dartfmt + - dartanalyzer + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 2fe68a1f4..93fb03555 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.2 +version: 1.3.3-dev author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 24ee102718bfbad41dcc37e1667ac7f8c0eab003 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 30 Aug 2017 13:56:17 -0700 Subject: [PATCH 199/657] Rename analysis_options --- pkgs/pub_semver/{.analysis_options => analysis_options.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkgs/pub_semver/{.analysis_options => analysis_options.yaml} (100%) diff --git a/pkgs/pub_semver/.analysis_options b/pkgs/pub_semver/analysis_options.yaml similarity index 100% rename from pkgs/pub_semver/.analysis_options rename to pkgs/pub_semver/analysis_options.yaml From 9a0299ed5f12eb481a8c3722e65c01e0b0c8f463 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 30 Aug 2017 13:58:28 -0700 Subject: [PATCH 200/657] Sort directives --- pkgs/pub_semver/lib/src/version_constraint.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index edd8abd07..6fd438447 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -3,10 +3,10 @@ // BSD-style license that can be found in the LICENSE file. import 'patterns.dart'; +import 'utils.dart'; import 'version.dart'; import 'version_range.dart'; import 'version_union.dart'; -import 'utils.dart'; /// A [VersionConstraint] is a predicate that can determine whether a given /// version is valid or not. From 3779e27aa162f351523bf3c7ddc93fef9436b3d2 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 30 Aug 2017 14:06:14 -0700 Subject: [PATCH 201/657] dartfmt --- pkgs/pub_semver/lib/src/patterns.dart | 7 +- pkgs/pub_semver/lib/src/version.dart | 38 +- .../lib/src/version_constraint.dart | 24 +- pkgs/pub_semver/lib/src/version_range.dart | 81 +-- pkgs/pub_semver/lib/src/version_union.dart | 3 +- pkgs/pub_semver/test/utils.dart | 39 +- .../test/version_constraint_test.dart | 150 +++--- pkgs/pub_semver/test/version_range_test.dart | 151 +++--- pkgs/pub_semver/test/version_test.dart | 33 +- pkgs/pub_semver/test/version_union_test.dart | 481 ++++++++++-------- 10 files changed, 554 insertions(+), 453 deletions(-) diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart index 4e57ec908..c4d75d4b7 100644 --- a/pkgs/pub_semver/lib/src/patterns.dart +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -3,10 +3,9 @@ // BSD-style license that can be found in the LICENSE file. /// Regex that matches a version number at the beginning of a string. -final START_VERSION = new RegExp( - r'^' // Start at beginning. - r'(\d+).(\d+).(\d+)' // Version number. - r'(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?' // Pre-release. +final START_VERSION = new RegExp(r'^' // Start at beginning. + r'(\d+).(\d+).(\d+)' // Version number. + r'(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?' // Pre-release. r'(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?'); // Build. /// Like [START_VERSION] but matches the entire string. diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 2d43a1aa8..6665873de 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -89,15 +89,15 @@ class Version implements VersionConstraint, VersionRange { bool get includeMax => true; Version._(this.major, this.minor, this.patch, String preRelease, String build, - this._text) + this._text) : preRelease = preRelease == null ? [] : _splitParts(preRelease), build = build == null ? [] : _splitParts(build) { - if (major < 0) throw new ArgumentError( - 'Major version must be non-negative.'); - if (minor < 0) throw new ArgumentError( - 'Minor version must be non-negative.'); - if (patch < 0) throw new ArgumentError( - 'Patch version must be non-negative.'); + if (major < 0) + throw new ArgumentError('Major version must be non-negative.'); + if (minor < 0) + throw new ArgumentError('Minor version must be non-negative.'); + if (patch < 0) + throw new ArgumentError('Patch version must be non-negative.'); } /// Creates a new [Version] object. @@ -137,7 +137,8 @@ class Version implements VersionConstraint, VersionRange { static Version primary(List versions) { var primary; for (var version in versions) { - if (primary == null || (!version.isPreRelease && primary.isPreRelease) || + if (primary == null || + (!version.isPreRelease && primary.isPreRelease) || (version.isPreRelease == primary.isPreRelease && version > primary)) { primary = version; } @@ -161,13 +162,18 @@ class Version implements VersionConstraint, VersionRange { bool operator ==(other) { if (other is! Version) return false; - return major == other.major && minor == other.minor && + return major == other.major && + minor == other.minor && patch == other.patch && _equality.equals(preRelease, other.preRelease) && _equality.equals(build, other.build); } - int get hashCode => major ^ minor ^ patch ^ _equality.hash(preRelease) ^ + int get hashCode => + major ^ + minor ^ + patch ^ + _equality.hash(preRelease) ^ _equality.hash(build); bool operator <(Version other) => compareTo(other) < 0; @@ -253,14 +259,18 @@ class Version implements VersionConstraint, VersionRange { if (other is VersionRange) { if (other.min == this) { return new VersionRange( - min: other.min, max: other.max, - includeMin: true, includeMax: other.includeMax); + min: other.min, + max: other.max, + includeMin: true, + includeMax: other.includeMax); } if (other.max == this) { return new VersionRange( - min: other.min, max: other.max, - includeMin: other.includeMin, includeMax: true); + min: other.min, + max: other.max, + includeMin: other.includeMin, + includeMax: true); } } diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 6fd438447..36bbd9aba 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -81,10 +81,14 @@ abstract class VersionConstraint { } switch (op) { - case '<=': return new VersionRange(max: version, includeMax: true); - case '<': return new VersionRange(max: version, includeMax: false); - case '>=': return new VersionRange(min: version, includeMin: true); - case '>': return new VersionRange(min: version, includeMin: false); + case '<=': + return new VersionRange(max: version, includeMax: true); + case '<': + return new VersionRange(max: version, includeMax: false); + case '>=': + return new VersionRange(min: version, includeMin: true); + case '>': + return new VersionRange(min: version, includeMin: false); } throw "Unreachable."; } @@ -172,8 +176,7 @@ abstract class VersionConstraint { /// /// It allows any versions that any of those constraints allows. If /// [constraints] is empty, this returns a constraint that allows no versions. - factory VersionConstraint.unionOf( - Iterable constraints) { + factory VersionConstraint.unionOf(Iterable constraints) { var flattened = constraints.expand((constraint) { if (constraint.isEmpty) return []; if (constraint is VersionUnion) return constraint.ranges; @@ -257,9 +260,12 @@ class _EmptyVersion implements VersionConstraint { } class _CompatibleWithVersionRange extends VersionRange { - _CompatibleWithVersionRange(Version version) : super( - min: version, includeMin: true, - max: version.nextBreaking, includeMax: false); + _CompatibleWithVersionRange(Version version) + : super( + min: version, + includeMin: true, + max: version.nextBreaking, + includeMax: false); String toString() => '^$min'; } diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 580f3feba..99f292426 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -53,8 +53,8 @@ class VersionRange implements Comparable, VersionConstraint { /// /// If [includeMin] is `true`, then the minimum end of the range is inclusive. /// Likewise, passing [includeMax] as `true` makes the upper end inclusive. - VersionRange({this.min, this.max, - this.includeMin: false, this.includeMax: false}) { + VersionRange( + {this.min, this.max, this.includeMin: false, this.includeMax: false}) { if (min != null && max != null && min > max) { throw new ArgumentError( 'Minimum version ("$min") must be less than maximum ("$max").'); @@ -65,13 +65,16 @@ class VersionRange implements Comparable, VersionConstraint { if (other is! VersionRange) return false; return min == other.min && - max == other.max && - includeMin == other.includeMin && - includeMax == other.includeMax; + max == other.max && + includeMin == other.includeMin && + includeMax == other.includeMax; } - int get hashCode => min.hashCode ^ (max.hashCode * 3) ^ - (includeMin.hashCode * 5) ^ (includeMax.hashCode * 7); + int get hashCode => + min.hashCode ^ + (max.hashCode * 3) ^ + (includeMin.hashCode * 5) ^ + (includeMax.hashCode * 7); bool get isEmpty => false; @@ -88,7 +91,6 @@ class VersionRange implements Comparable, VersionConstraint { if (other > max) return false; if (!includeMax && other == max) return false; - // Disallow pre-release versions that have the same major, minor, and // patch version as the max, but only if neither the max nor the min is a // pre-release of that version. This ensures that "^1.2.3" doesn't include @@ -109,9 +111,11 @@ class VersionRange implements Comparable, VersionConstraint { // ">1.2.3" can still match prerelease versions if they're the only things // available. var maxIsReleaseOfOther = !includeMax && - !max.isPreRelease && other.isPreRelease && + !max.isPreRelease && + other.isPreRelease && _equalsWithoutPreRelease(other, max); - var minIsPreReleaseOfOther = min != null && min.isPreRelease && + var minIsPreReleaseOfOther = min != null && + min.isPreRelease && _equalsWithoutPreRelease(other, min); if (maxIsReleaseOfOther && !minIsPreReleaseOfOther) return false; } @@ -121,8 +125,8 @@ class VersionRange implements Comparable, VersionConstraint { bool _equalsWithoutPreRelease(Version version1, Version version2) => version1.major == version2.major && - version1.minor == version2.minor && - version1.patch == version2.patch; + version1.minor == version2.minor && + version1.patch == version2.patch; bool allowsAll(VersionConstraint other) { if (other.isEmpty) return true; @@ -216,15 +220,19 @@ class VersionRange implements Comparable, VersionConstraint { return VersionConstraint.empty; } - if (intersectMin != null && intersectMax != null && + if (intersectMin != null && + intersectMax != null && intersectMin > intersectMax) { // Non-overlapping ranges, so empty. return VersionConstraint.empty; } // If we got here, there is an actual range. - return new VersionRange(min: intersectMin, max: intersectMax, - includeMin: intersectIncludeMin, includeMax: intersectIncludeMax); + return new VersionRange( + min: intersectMin, + max: intersectMax, + includeMin: intersectIncludeMin, + includeMax: intersectIncludeMax); } throw new ArgumentError('Unknown VersionConstraint type $other.'); @@ -236,14 +244,18 @@ class VersionRange implements Comparable, VersionConstraint { if (other == min) { return new VersionRange( - min: this.min, max: this.max, - includeMin: true, includeMax: this.includeMax); + min: this.min, + max: this.max, + includeMin: true, + includeMax: this.includeMax); } if (other == max) { return new VersionRange( - min: this.min, max: this.max, - includeMin: this.includeMin, includeMax: true); + min: this.min, + max: this.max, + includeMin: this.includeMin, + includeMax: true); } return new VersionConstraint.unionOf([this, other]); @@ -283,8 +295,11 @@ class VersionRange implements Comparable, VersionConstraint { unionIncludeMax = true; } - return new VersionRange(min: unionMin, max: unionMax, - includeMin: unionIncludeMin, includeMax: unionIncludeMax); + return new VersionRange( + min: unionMin, + max: unionMax, + includeMin: unionIncludeMin, + includeMax: unionIncludeMax); } return new VersionConstraint.unionOf([this, other]); @@ -299,24 +314,20 @@ class VersionRange implements Comparable, VersionConstraint { if (other == min) { if (!includeMin) return this; return new VersionRange( - min: min, max: max, - includeMin: false, includeMax: includeMax); + min: min, max: max, includeMin: false, includeMax: includeMax); } if (other == max) { if (!includeMax) return this; return new VersionRange( - min: min, max: max, - includeMin: includeMin, includeMax: false); + min: min, max: max, includeMin: includeMin, includeMax: false); } return new VersionUnion.fromRanges([ new VersionRange( - min: min, max: other, - includeMin: includeMin, includeMax: false), + min: min, max: other, includeMin: includeMin, includeMax: false), new VersionRange( - min: other, max: max, - includeMin: false, includeMax: includeMax) + min: other, max: max, includeMin: false, includeMax: includeMax) ]); } else if (other is VersionRange) { if (!allowsAny(other)) return this; @@ -330,8 +341,10 @@ class VersionRange implements Comparable, VersionConstraint { before = min; } else { before = new VersionRange( - min: min, max: other.min, - includeMin: includeMin, includeMax: !other.includeMin); + min: min, + max: other.min, + includeMin: includeMin, + includeMax: !other.includeMin); } VersionRange after; @@ -343,8 +356,10 @@ class VersionRange implements Comparable, VersionConstraint { after = max; } else { after = new VersionRange( - min: other.max, max: max, - includeMin: !other.includeMax, includeMax: includeMax); + min: other.max, + max: max, + includeMin: !other.includeMax, + includeMax: includeMax); } if (before == null && after == null) return VersionConstraint.empty; diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index a26cb528d..9324d3fb7 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -96,8 +96,7 @@ class VersionUnion implements VersionConstraint { ourRanges.moveNext(); theirRanges.moveNext(); while (ourRanges.current != null && theirRanges.current != null) { - var intersection = ourRanges.current - .intersect(theirRanges.current); + var intersection = ourRanges.current.intersect(theirRanges.current); if (!intersection.isEmpty) newRanges.add(intersection); diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index e1d7446cc..9b28c6a22 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -30,7 +30,8 @@ class _VersionConstraintMatcher implements Matcher { _VersionConstraintMatcher(this._expected, this._allow); - bool matches(item, Map matchState) => (item is VersionConstraint) && + bool matches(item, Map matchState) => + (item is VersionConstraint) && _expected.every((version) => item.allows(version) == _allow); Description describe(Description description) { @@ -39,8 +40,8 @@ class _VersionConstraintMatcher implements Matcher { return description; } - Description describeMismatch(item, Description mismatchDescription, - Map matchState, bool verbose) { + Description describeMismatch( + item, Description mismatchDescription, Map matchState, bool verbose) { if (item is! VersionConstraint) { mismatchDescription.add('was not a VersionConstraint'); return mismatchDescription; @@ -70,22 +71,40 @@ class _VersionConstraintMatcher implements Matcher { /// Gets a [Matcher] that validates that a [VersionConstraint] allows all /// given versions. -Matcher allows(Version v1, [Version v2, Version v3, Version v4, - Version v5, Version v6, Version v7, Version v8]) { +Matcher allows(Version v1, + [Version v2, + Version v3, + Version v4, + Version v5, + Version v6, + Version v7, + Version v8]) { var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); return new _VersionConstraintMatcher(versions, true); } /// Gets a [Matcher] that validates that a [VersionConstraint] allows none of /// the given versions. -Matcher doesNotAllow(Version v1, [Version v2, Version v3, Version v4, - Version v5, Version v6, Version v7, Version v8]) { +Matcher doesNotAllow(Version v1, + [Version v2, + Version v3, + Version v4, + Version v5, + Version v6, + Version v7, + Version v8]) { var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); return new _VersionConstraintMatcher(versions, false); } -List _makeVersionList(Version v1, [Version v2, Version v3, Version v4, - Version v5, Version v6, Version v7, Version v8]) { +List _makeVersionList(Version v1, + [Version v2, + Version v3, + Version v4, + Version v5, + Version v6, + Version v7, + Version v8]) { var versions = [v1]; if (v2 != null) versions.add(v2); if (v3 != null) versions.add(v3); @@ -95,4 +114,4 @@ List _makeVersionList(Version v1, [Version v2, Version v3, Version v4, if (v7 != null) versions.add(v7); if (v8 != null) versions.add(v8); return versions; -} \ No newline at end of file +} diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index bd6bf75cf..bc378325e 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -11,19 +11,19 @@ import 'utils.dart'; main() { test('any', () { expect(VersionConstraint.any.isAny, isTrue); - expect(VersionConstraint.any, allows( - new Version.parse('0.0.0-blah'), - new Version.parse('1.2.3'), - new Version.parse('12345.678.90'))); + expect( + VersionConstraint.any, + allows(new Version.parse('0.0.0-blah'), new Version.parse('1.2.3'), + new Version.parse('12345.678.90'))); }); test('empty', () { expect(VersionConstraint.empty.isEmpty, isTrue); expect(VersionConstraint.empty.isAny, isFalse); - expect(VersionConstraint.empty, doesNotAllow( - new Version.parse('0.0.0-blah'), - new Version.parse('1.2.3'), - new Version.parse('12345.678.90'))); + expect( + VersionConstraint.empty, + doesNotAllow(new Version.parse('0.0.0-blah'), + new Version.parse('1.2.3'), new Version.parse('12345.678.90'))); }); group('parse()', () { @@ -38,82 +38,80 @@ main() { var constraint = new VersionConstraint.parse('any'); expect(constraint is VersionConstraint, isTrue); - expect(constraint, allows( - new Version.parse('0.0.0'), - new Version.parse('1.2.3'), - new Version.parse('12345.678.90'))); + expect( + constraint, + allows(new Version.parse('0.0.0'), new Version.parse('1.2.3'), + new Version.parse('12345.678.90'))); }); test('parses a ">" minimum version', () { var constraint = new VersionConstraint.parse('>1.2.3'); - expect(constraint, allows( - new Version.parse('1.2.3+foo'), - new Version.parse('1.2.4'))); - expect(constraint, doesNotAllow( - new Version.parse('1.2.1'), - new Version.parse('1.2.3-build'), - new Version.parse('1.2.3'))); + expect(constraint, + allows(new Version.parse('1.2.3+foo'), new Version.parse('1.2.4'))); + expect( + constraint, + doesNotAllow(new Version.parse('1.2.1'), + new Version.parse('1.2.3-build'), new Version.parse('1.2.3'))); }); test('parses a ">=" minimum version', () { var constraint = new VersionConstraint.parse('>=1.2.3'); - expect(constraint, allows( - new Version.parse('1.2.3'), - new Version.parse('1.2.3+foo'), - new Version.parse('1.2.4'))); - expect(constraint, doesNotAllow( - new Version.parse('1.2.1'), - new Version.parse('1.2.3-build'))); + expect( + constraint, + allows(new Version.parse('1.2.3'), new Version.parse('1.2.3+foo'), + new Version.parse('1.2.4'))); + expect( + constraint, + doesNotAllow( + new Version.parse('1.2.1'), new Version.parse('1.2.3-build'))); }); test('parses a "<" maximum version', () { var constraint = new VersionConstraint.parse('<1.2.3'); - expect(constraint, allows( - new Version.parse('1.2.1'), - new Version.parse('1.2.2+foo'))); - expect(constraint, doesNotAllow( - new Version.parse('1.2.3'), - new Version.parse('1.2.3+foo'), - new Version.parse('1.2.4'))); + expect(constraint, + allows(new Version.parse('1.2.1'), new Version.parse('1.2.2+foo'))); + expect( + constraint, + doesNotAllow(new Version.parse('1.2.3'), + new Version.parse('1.2.3+foo'), new Version.parse('1.2.4'))); }); test('parses a "<=" maximum version', () { var constraint = new VersionConstraint.parse('<=1.2.3'); - expect(constraint, allows( - new Version.parse('1.2.1'), - new Version.parse('1.2.3-build'), - new Version.parse('1.2.3'))); - expect(constraint, doesNotAllow( - new Version.parse('1.2.3+foo'), - new Version.parse('1.2.4'))); + expect( + constraint, + allows(new Version.parse('1.2.1'), new Version.parse('1.2.3-build'), + new Version.parse('1.2.3'))); + expect( + constraint, + doesNotAllow( + new Version.parse('1.2.3+foo'), new Version.parse('1.2.4'))); }); test('parses a series of space-separated constraints', () { var constraint = new VersionConstraint.parse('>1.0.0 >=1.2.3 <1.3.0'); - expect(constraint, allows( - new Version.parse('1.2.3'), - new Version.parse('1.2.5'))); - expect(constraint, doesNotAllow( - new Version.parse('1.2.3-pre'), - new Version.parse('1.3.0'), - new Version.parse('3.4.5'))); + expect(constraint, + allows(new Version.parse('1.2.3'), new Version.parse('1.2.5'))); + expect( + constraint, + doesNotAllow(new Version.parse('1.2.3-pre'), + new Version.parse('1.3.0'), new Version.parse('3.4.5'))); }); test('ignores whitespace around comparison operators', () { var constraint = new VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0'); - expect(constraint, allows( - new Version.parse('1.2.3'), - new Version.parse('1.2.5'))); - expect(constraint, doesNotAllow( - new Version.parse('1.2.3-pre'), - new Version.parse('1.3.0'), - new Version.parse('3.4.5'))); + expect(constraint, + allows(new Version.parse('1.2.3'), new Version.parse('1.2.5'))); + expect( + constraint, + doesNotAllow(new Version.parse('1.2.3-pre'), + new Version.parse('1.3.0'), new Version.parse('3.4.5'))); }); test('does not allow "any" to be mixed with other constraints', () { @@ -122,18 +120,18 @@ main() { }); test('parses a "^" version', () { - expect(new VersionConstraint.parse('^0.0.3'), equals( - new VersionConstraint.compatibleWith(v003))); + expect(new VersionConstraint.parse('^0.0.3'), + equals(new VersionConstraint.compatibleWith(v003))); - expect(new VersionConstraint.parse('^0.7.2'), equals( - new VersionConstraint.compatibleWith(v072))); + expect(new VersionConstraint.parse('^0.7.2'), + equals(new VersionConstraint.compatibleWith(v072))); - expect(new VersionConstraint.parse('^1.2.3'), equals( - new VersionConstraint.compatibleWith(v123))); + expect(new VersionConstraint.parse('^1.2.3'), + equals(new VersionConstraint.compatibleWith(v123))); var min = new Version.parse('0.7.2-pre+1'); - expect(new VersionConstraint.parse('^0.7.2-pre+1'), equals( - new VersionConstraint.compatibleWith(min))); + expect(new VersionConstraint.parse('^0.7.2-pre+1'), + equals(new VersionConstraint.compatibleWith(min))); }); test('does not allow "^" to be mixed with other constraints', () { @@ -146,25 +144,23 @@ main() { test('ignores whitespace around "^"', () { var constraint = new VersionConstraint.parse(' ^ 1.2.3 '); - expect(constraint, equals( - new VersionConstraint.compatibleWith(v123))); + expect(constraint, equals(new VersionConstraint.compatibleWith(v123))); }); test('throws FormatException on a bad string', () { var bad = [ - "", " ", // Empty string. - "foo", // Bad text. - ">foo", // Bad text after operator. - "^foo", // Bad text after "^". - "1.0.0 foo", "1.0.0foo", // Bad text after version. - "anything", // Bad text after "any". - "<>1.0.0", // Multiple operators. - "1.0.0<" // Trailing operator. + "", " ", // Empty string. + "foo", // Bad text. + ">foo", // Bad text after operator. + "^foo", // Bad text after "^". + "1.0.0 foo", "1.0.0foo", // Bad text after version. + "anything", // Bad text after "any". + "<>1.0.0", // Multiple operators. + "1.0.0<" // Trailing operator. ]; for (var text in bad) { - expect(() => new VersionConstraint.parse(text), - throwsFormatException); + expect(() => new VersionConstraint.parse(text), throwsFormatException); } }); }); @@ -173,8 +169,10 @@ main() { test('returns the range of compatible versions', () { var constraint = new VersionConstraint.compatibleWith(v072); - expect(constraint, equals(new VersionRange(min: v072, includeMin: true, - max: v072.nextBreaking))); + expect( + constraint, + equals(new VersionRange( + min: v072, includeMin: true, max: v072.nextBreaking))); }); test('toString() uses "^"', () { diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 23d771049..e95b3d697 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -60,21 +60,19 @@ main() { test('version must be greater than min', () { var range = new VersionRange(min: v123); - expect(range, allows( - new Version.parse('1.3.3'), - new Version.parse('2.3.3'))); - expect(range, doesNotAllow( - new Version.parse('1.2.2'), - new Version.parse('1.2.3'))); + expect(range, + allows(new Version.parse('1.3.3'), new Version.parse('2.3.3'))); + expect(range, + doesNotAllow(new Version.parse('1.2.2'), new Version.parse('1.2.3'))); }); test('version must be min or greater if includeMin', () { var range = new VersionRange(min: v123, includeMin: true); - expect(range, allows( - new Version.parse('1.2.3'), - new Version.parse('1.3.3'), - new Version.parse('2.3.3'))); + expect( + range, + allows(new Version.parse('1.2.3'), new Version.parse('1.3.3'), + new Version.parse('2.3.3'))); expect(range, doesNotAllow(new Version.parse('1.2.2'))); }); @@ -89,50 +87,53 @@ main() { var range = new VersionRange(max: v234); expect(range, allows(new Version.parse('2.3.3'))); - expect(range, doesNotAllow( - new Version.parse('2.3.4'), - new Version.parse('2.4.3'))); + expect(range, + doesNotAllow(new Version.parse('2.3.4'), new Version.parse('2.4.3'))); }); test('pre-release versions of non-pre-release max are excluded', () { var range = new VersionRange(max: v234); expect(range, allows(new Version.parse('2.3.3'))); - expect(range, doesNotAllow( - new Version.parse('2.3.4-dev'), - new Version.parse('2.3.4'))); + expect( + range, + doesNotAllow( + new Version.parse('2.3.4-dev'), new Version.parse('2.3.4'))); }); - test('pre-release versions of non-pre-release max are included if min is a ' + test( + 'pre-release versions of non-pre-release max are included if min is a ' 'pre-release of the same version', () { - var range = new VersionRange( - min: new Version.parse('2.3.4-dev.0'), max: v234); + var range = + new VersionRange(min: new Version.parse('2.3.4-dev.0'), max: v234); expect(range, allows(new Version.parse('2.3.4-dev.1'))); - expect(range, doesNotAllow( - new Version.parse('2.3.3'), - new Version.parse('2.3.4-dev'), - new Version.parse('2.3.4'))); + expect( + range, + doesNotAllow(new Version.parse('2.3.3'), + new Version.parse('2.3.4-dev'), new Version.parse('2.3.4'))); }); test('pre-release versions of pre-release max are included', () { var range = new VersionRange(max: new Version.parse('2.3.4-dev.2')); - expect(range, allows( - new Version.parse('2.3.4-dev.1'))); - expect(range, doesNotAllow( - new Version.parse('2.3.4-dev.2'), - new Version.parse('2.3.4-dev.3'))); + expect(range, allows(new Version.parse('2.3.4-dev.1'))); + expect( + range, + doesNotAllow(new Version.parse('2.3.4-dev.2'), + new Version.parse('2.3.4-dev.3'))); }); test('version must be max or less if includeMax', () { var range = new VersionRange(min: v123, max: v234, includeMax: true); - expect(range, allows( - new Version.parse('2.3.3'), - new Version.parse('2.3.4'), - // Pre-releases of the max are allowed. - new Version.parse('2.3.4-dev'))); + expect( + range, + allows( + new Version.parse('2.3.3'), + new Version.parse('2.3.4'), + // Pre-releases of the max are allowed. + new Version.parse('2.3.4-dev'))); expect(range, doesNotAllow(new Version.parse('2.4.3'))); }); @@ -146,18 +147,16 @@ main() { test('has no max if one was not set', () { var range = new VersionRange(min: v123); - expect(range, allows( - new Version.parse('1.3.3'), - new Version.parse('999.3.3'))); + expect(range, + allows(new Version.parse('1.3.3'), new Version.parse('999.3.3'))); expect(range, doesNotAllow(new Version.parse('1.2.3'))); }); test('allows any version if there is no min or max', () { var range = new VersionRange(); - expect(range, allows( - new Version.parse('0.0.0'), - new Version.parse('999.99.9'))); + expect(range, + allows(new Version.parse('0.0.0'), new Version.parse('999.99.9'))); }); }); @@ -280,30 +279,36 @@ main() { expect(new VersionRange(max: v250).allowsAny(new VersionRange(min: v250)), isFalse); - expect(new VersionRange(max: v250, includeMax: true) + expect( + new VersionRange(max: v250, includeMax: true) .allowsAny(new VersionRange(min: v250)), isFalse); - expect(new VersionRange(max: v250) + expect( + new VersionRange(max: v250) .allowsAny(new VersionRange(min: v250, includeMin: true)), isFalse); - expect(new VersionRange(max: v250, includeMax: true) + expect( + new VersionRange(max: v250, includeMax: true) .allowsAny(new VersionRange(min: v250, includeMin: true)), isTrue); expect(new VersionRange(min: v250).allowsAny(new VersionRange(max: v250)), isFalse); - expect(new VersionRange(min: v250, includeMin: true) + expect( + new VersionRange(min: v250, includeMin: true) .allowsAny(new VersionRange(max: v250)), isFalse); - expect(new VersionRange(min: v250) + expect( + new VersionRange(min: v250) .allowsAny(new VersionRange(max: v250, includeMax: true)), isFalse); - expect(new VersionRange(min: v250, includeMin: true) + expect( + new VersionRange(min: v250, includeMin: true) .allowsAny(new VersionRange(max: v250, includeMax: true)), isTrue); }); @@ -361,8 +366,8 @@ main() { }); test('returns the version if the range allows it', () { - expect(new VersionRange(min: v114, max: v124).intersect(v123), - equals(v123)); + expect( + new VersionRange(min: v114, max: v124).intersect(v123), equals(v123)); expect(new VersionRange(min: v123, max: v124).intersect(v114).isEmpty, isTrue); }); @@ -381,7 +386,8 @@ main() { equals(new VersionRange(min: v114, max: v124, includeMin: true))); }); - test("with a version allows both the range and the version if the range " + test( + "with a version allows both the range and the version if the range " "doesn't contain the version", () { var result = new VersionRange(min: v003, max: v114).union(v124); expect(result, allows(v010)); @@ -438,8 +444,10 @@ main() { test("includes edges if either range does", () { var result = new VersionRange(min: v003, max: v114, includeMin: true) .union(new VersionRange(min: v003, max: v114, includeMax: true)); - expect(result, equals(new VersionRange( - min: v003, max: v114, includeMin: true, includeMax: true))); + expect( + result, + equals(new VersionRange( + min: v003, max: v114, includeMin: true, includeMax: true))); }); }); @@ -452,8 +460,7 @@ main() { }); test("with a version outside the range returns the original range", () { - expect( - new VersionRange(min: v003, max: v114).difference(v200), + expect(new VersionRange(min: v003, max: v114).difference(v200), equals(new VersionRange(min: v003, max: v114))); }); @@ -518,8 +525,7 @@ main() { equals(v130)); }); - test("with a range at the end cuts off the end of the range", - () { + test("with a range at the end cuts off the end of the range", () { expect( new VersionRange(min: v080, max: v130) .difference(new VersionRange(min: v114, max: v140)), @@ -569,7 +575,8 @@ main() { isEmpty); }); - test("with a version union that doesn't cover the range, returns the " + test( + "with a version union that doesn't cover the range, returns the " "original", () { expect( new VersionRange(min: v114, max: v140) @@ -579,11 +586,11 @@ main() { test("with a version union that intersects the ends, chops them off", () { expect( - new VersionRange(min: v114, max: v140) - .difference(new VersionConstraint.unionOf([ - new VersionRange(min: v080, max: v123), - new VersionRange(min: v130, max: v200) - ])), + new VersionRange(min: v114, max: v140).difference( + new VersionConstraint.unionOf([ + new VersionRange(min: v080, max: v123), + new VersionRange(min: v130, max: v200) + ])), equals(new VersionRange( min: v123, max: v130, includeMin: true, includeMax: true))); }); @@ -608,20 +615,16 @@ main() { group('compareTo()', () { test("orders by minimum first", () { - _expectComparesSmaller( - new VersionRange(min: v003, max: v080), + _expectComparesSmaller(new VersionRange(min: v003, max: v080), new VersionRange(min: v010, max: v072)); - _expectComparesSmaller( - new VersionRange(min: v003, max: v080), + _expectComparesSmaller(new VersionRange(min: v003, max: v080), new VersionRange(min: v010, max: v080)); - _expectComparesSmaller( - new VersionRange(min: v003, max: v080), + _expectComparesSmaller(new VersionRange(min: v003, max: v080), new VersionRange(min: v010, max: v114)); }); test("orders by maximum second", () { - _expectComparesSmaller( - new VersionRange(min: v003, max: v010), + _expectComparesSmaller(new VersionRange(min: v003, max: v010), new VersionRange(min: v003, max: v072)); }); @@ -639,19 +642,15 @@ main() { test("no minimum comes before small minimum", () { _expectComparesSmaller( - new VersionRange(max: v010), - new VersionRange(min: v003, max: v010)); - _expectComparesSmaller( - new VersionRange(max: v010, includeMin: true), + new VersionRange(max: v010), new VersionRange(min: v003, max: v010)); + _expectComparesSmaller(new VersionRange(max: v010, includeMin: true), new VersionRange(min: v003, max: v010)); }); test("no maximium comes after large maximum", () { _expectComparesSmaller( - new VersionRange(min: v003, max: v300), - new VersionRange(min: v003)); - _expectComparesSmaller( - new VersionRange(min: v003, max: v300), + new VersionRange(min: v003, max: v300), new VersionRange(min: v003)); + _expectComparesSmaller(new VersionRange(min: v003, max: v300), new VersionRange(min: v003, includeMax: true)); }); }); diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index b278d4c61..fc6dfef33 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -119,21 +119,23 @@ main() { expect(new Version.parse('01.2.3'), equals(new Version.parse('1.2.3'))); expect(new Version.parse('1.02.3'), equals(new Version.parse('1.2.3'))); expect(new Version.parse('1.2.03'), equals(new Version.parse('1.2.3'))); - expect(new Version.parse('1.2.3-01'), - equals(new Version.parse('1.2.3-1'))); - expect(new Version.parse('1.2.3+01'), - equals(new Version.parse('1.2.3+1'))); + expect( + new Version.parse('1.2.3-01'), equals(new Version.parse('1.2.3-1'))); + expect( + new Version.parse('1.2.3+01'), equals(new Version.parse('1.2.3+1'))); }); }); test('allows()', () { expect(v123, allows(v123)); - expect(v123, doesNotAllow( - new Version.parse('2.2.3'), - new Version.parse('1.3.3'), - new Version.parse('1.2.4'), - new Version.parse('1.2.3-dev'), - new Version.parse('1.2.3+build'))); + expect( + v123, + doesNotAllow( + new Version.parse('2.2.3'), + new Version.parse('1.3.3'), + new Version.parse('1.2.4'), + new Version.parse('1.2.3-dev'), + new Version.parse('1.2.3+build'))); }); test('allowsAll()', () { @@ -160,12 +162,12 @@ main() { expect(v123.intersect(v114).isEmpty, isTrue); // Intersecting a range returns the version if the range allows it. - expect(v123.intersect(new VersionRange(min: v114, max: v124)), - equals(v123)); + expect( + v123.intersect(new VersionRange(min: v114, max: v124)), equals(v123)); // Intersecting a range allows no versions if the range doesn't allow it. - expect(v114.intersect(new VersionRange(min: v123, max: v124)).isEmpty, - isTrue); + expect( + v114.intersect(new VersionRange(min: v123, max: v124)).isEmpty, isTrue); }); group('union()', () { @@ -194,7 +196,8 @@ main() { equals(new VersionRange(min: v114, max: v124, includeMin: true))); }); - test("with a range allows both the range and the version if the range " + test( + "with a range allows both the range and the version if the range " "doesn't contain the version", () { var result = v123.union(new VersionRange(min: v003, max: v114)); expect(result, allows(v123)); diff --git a/pkgs/pub_semver/test/version_union_test.dart b/pkgs/pub_semver/test/version_union_test.dart index 06a427dd9..f94883294 100644 --- a/pkgs/pub_semver/test/version_union_test.dart +++ b/pkgs/pub_semver/test/version_union_test.dart @@ -11,17 +11,19 @@ import 'utils.dart'; main() { group('factory', () { test('ignores empty constraints', () { - expect(new VersionConstraint.unionOf([ - VersionConstraint.empty, - VersionConstraint.empty, - v123, - VersionConstraint.empty - ]), equals(v123)); - - expect(new VersionConstraint.unionOf([ - VersionConstraint.empty, - VersionConstraint.empty - ]), isEmpty); + expect( + new VersionConstraint.unionOf([ + VersionConstraint.empty, + VersionConstraint.empty, + v123, + VersionConstraint.empty + ]), + equals(v123)); + + expect( + new VersionConstraint.unionOf( + [VersionConstraint.empty, VersionConstraint.empty]), + isEmpty); }); test('returns an empty constraint for an empty list', () { @@ -29,120 +31,142 @@ main() { }); test('any constraints override everything', () { - expect(new VersionConstraint.unionOf([ - v123, - VersionConstraint.any, - v200, - new VersionRange(min: v234, max: v250) - ]), equals(VersionConstraint.any)); + expect( + new VersionConstraint.unionOf([ + v123, + VersionConstraint.any, + v200, + new VersionRange(min: v234, max: v250) + ]), + equals(VersionConstraint.any)); }); test('flattens other unions', () { - expect(new VersionConstraint.unionOf([ - v072, - new VersionConstraint.unionOf([v123, v124]), - v250 - ]), equals(new VersionConstraint.unionOf([v072, v123, v124, v250]))); + expect( + new VersionConstraint.unionOf([ + v072, + new VersionConstraint.unionOf([v123, v124]), + v250 + ]), + equals(new VersionConstraint.unionOf([v072, v123, v124, v250]))); }); test('returns a single merged range as-is', () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v080, max: v140), - new VersionRange(min: v123, max: v200) - ]), equals(new VersionRange(min: v080, max: v200))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v080, max: v140), + new VersionRange(min: v123, max: v200) + ]), + equals(new VersionRange(min: v080, max: v200))); }); }); group('equality', () { test("doesn't depend on original order", () { - expect(new VersionConstraint.unionOf([ - v250, - new VersionRange(min: v201, max: v234), - v124, - v072, - new VersionRange(min: v080, max: v114), - v123 - ]), equals(new VersionConstraint.unionOf([ - v072, - new VersionRange(min: v080, max: v114), - v123, - v124, - new VersionRange(min: v201, max: v234), - v250 - ]))); + expect( + new VersionConstraint.unionOf([ + v250, + new VersionRange(min: v201, max: v234), + v124, + v072, + new VersionRange(min: v080, max: v114), + v123 + ]), + equals(new VersionConstraint.unionOf([ + v072, + new VersionRange(min: v080, max: v114), + v123, + v124, + new VersionRange(min: v201, max: v234), + v250 + ]))); }); test("merges overlapping ranges", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v010, max: v080), - new VersionRange(min: v114, max: v124), - new VersionRange(min: v123, max: v130) - ]), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v114, max: v130) - ]))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v010, max: v080), + new VersionRange(min: v114, max: v124), + new VersionRange(min: v123, max: v130) + ]), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v114, max: v130) + ]))); }); test("merges adjacent ranges", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072, includeMax: true), - new VersionRange(min: v072, max: v080), - new VersionRange(min: v114, max: v124), - new VersionRange(min: v124, max: v130, includeMin: true) - ]), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v114, max: v130) - ]))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072, includeMax: true), + new VersionRange(min: v072, max: v080), + new VersionRange(min: v114, max: v124), + new VersionRange(min: v124, max: v130, includeMin: true) + ]), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v114, max: v130) + ]))); }); test("doesn't merge not-quite-adjacent ranges", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v072, max: v080) - ]), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v072, max: v080) - ]))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v072, max: v080) + ]), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v072, max: v080) + ]))); }); - + test("merges version numbers into ranges", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - v010, - new VersionRange(min: v114, max: v124), - v123 - ]), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v114, max: v124) - ]))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + v010, + new VersionRange(min: v114, max: v124), + v123 + ]), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v114, max: v124) + ]))); }); - + test("merges adjacent version numbers into ranges", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - v072, - v114, - new VersionRange(min: v114, max: v124) - ]), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072, includeMax: true), - new VersionRange(min: v114, max: v124, includeMin: true) - ]))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + v072, + v114, + new VersionRange(min: v114, max: v124) + ]), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072, includeMax: true), + new VersionRange(min: v114, max: v124, includeMin: true) + ]))); }); }); test('isEmpty returns false', () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130), - ]), isNot(isEmpty)); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130), + ]), + isNot(isEmpty)); }); test('isAny returns false', () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130), - ]).isAny, isFalse); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v080), + new VersionRange(min: v123, max: v130), + ]).isAny, + isFalse); }); test('allows() allows anything the components allow', () { @@ -174,7 +198,8 @@ main() { expect(union.allowsAll(v200), isTrue); }); - test('for a version range, returns true if any component allows the whole ' + test( + 'for a version range, returns true if any component allows the whole ' 'range', () { var union = new VersionConstraint.unionOf([ new VersionRange(min: v003, max: v080), @@ -194,32 +219,40 @@ main() { test('returns true if every constraint matches a different constraint', () { - expect(union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v124, max: v130) - ])), isTrue); + expect( + union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v124, max: v130) + ])), + isTrue); }); test('returns true if every constraint matches the same constraint', () { - expect(union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v010), - new VersionRange(min: v072, max: v080) - ])), isTrue); + expect( + union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v010), + new VersionRange(min: v072, max: v080) + ])), + isTrue); }); - + test("returns false if there's an unmatched constraint", () { - expect(union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v124, max: v130), - new VersionRange(min: v140, max: v200) - ])), isFalse); + expect( + union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v124, max: v130), + new VersionRange(min: v140, max: v200) + ])), + isFalse); }); test("returns false if a constraint isn't fully matched", () { - expect(union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v114), - new VersionRange(min: v124, max: v130) - ])), isFalse); + expect( + union.allowsAll(new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v114), + new VersionRange(min: v124, max: v130) + ])), + isFalse); }); }); }); @@ -239,12 +272,11 @@ main() { expect(union.allowsAny(v200), isTrue); }); - test('for a version range, returns true if any component allows part of ' + test( + 'for a version range, returns true if any component allows part of ' 'the range', () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - v123 - ]); + var union = new VersionConstraint.unionOf( + [new VersionRange(min: v003, max: v080), v123]); expect(union.allowsAny(new VersionRange(min: v010, max: v114)), isTrue); expect(union.allowsAny(new VersionRange(min: v114, max: v124)), isTrue); @@ -258,67 +290,78 @@ main() { ]); test('returns true if any constraint matches', () { - expect(union.allowsAny(new VersionConstraint.unionOf([ - v072, - new VersionRange(min: v200, max: v300) - ])), isTrue); - - expect(union.allowsAny(new VersionConstraint.unionOf([ - v003, - new VersionRange(min: v124, max: v300) - ])), isTrue); + expect( + union.allowsAny(new VersionConstraint.unionOf( + [v072, new VersionRange(min: v200, max: v300)])), + isTrue); + + expect( + union.allowsAny(new VersionConstraint.unionOf( + [v003, new VersionRange(min: v124, max: v300)])), + isTrue); }); - + test("returns false if no constraint matches", () { - expect(union.allowsAny(new VersionConstraint.unionOf([ - v003, - new VersionRange(min: v130, max: v140), - new VersionRange(min: v140, max: v200) - ])), isFalse); + expect( + union.allowsAny(new VersionConstraint.unionOf([ + v003, + new VersionRange(min: v130, max: v140), + new VersionRange(min: v140, max: v200) + ])), + isFalse); }); }); }); group("intersect()", () { test("with an overlapping version, returns that version", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) - ]).intersect(v072), equals(v072)); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(v072), + equals(v072)); }); test("with a non-overlapping version, returns an empty constraint", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) - ]).intersect(v300), isEmpty); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(v300), + isEmpty); }); test("with an overlapping range, returns that range", () { var range = new VersionRange(min: v072, max: v080); - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) - ]).intersect(range), equals(range)); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(range), + equals(range)); }); test("with a non-overlapping range, returns an empty constraint", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) - ]).intersect(new VersionRange(min: v080, max: v123)), isEmpty); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(new VersionRange(min: v080, max: v123)), + isEmpty); }); test("with a parially-overlapping range, returns the overlapping parts", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) - ]).intersect(new VersionRange(min: v072, max: v130)), + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v140) + ]).intersect(new VersionRange(min: v072, max: v130)), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v130) - ]))); + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v130) + ]))); }); group("for a union,", () { @@ -328,83 +371,93 @@ main() { ]); test("returns the overlapping parts", () { - expect(union.intersect(new VersionConstraint.unionOf([ - v010, - new VersionRange(min: v072, max: v124), - new VersionRange(min: v124, max: v130) - ])), equals(new VersionConstraint.unionOf([ - v010, - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v124), - new VersionRange(min: v124, max: v130) - ]))); + expect( + union.intersect(new VersionConstraint.unionOf([ + v010, + new VersionRange(min: v072, max: v124), + new VersionRange(min: v124, max: v130) + ])), + equals(new VersionConstraint.unionOf([ + v010, + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v124), + new VersionRange(min: v124, max: v130) + ]))); }); test("drops parts that don't match", () { - expect(union.intersect(new VersionConstraint.unionOf([ - v003, - new VersionRange(min: v072, max: v080), - new VersionRange(min: v080, max: v123) - ])), equals(new VersionRange(min: v072, max: v080))); + expect( + union.intersect(new VersionConstraint.unionOf([ + v003, + new VersionRange(min: v072, max: v080), + new VersionRange(min: v080, max: v123) + ])), + equals(new VersionRange(min: v072, max: v080))); }); }); }); group("difference()", () { test("ignores ranges that don't intersect", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v130) - ]).difference(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v010), - new VersionRange(min: v080, max: v123), - new VersionRange(min: v140) - ])), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v130) - ]))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v130) + ]).difference(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v010), + new VersionRange(min: v080, max: v123), + new VersionRange(min: v140) + ])), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v072, max: v080), + new VersionRange(min: v123, max: v130) + ]))); }); test("removes overlapping portions", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v130) - ]).difference(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v124) - ])), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080, includeMin: true), - new VersionRange(min: v123, max: v124, includeMax: true) - ]))); + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v080), + new VersionRange(min: v123, max: v130) + ]).difference(new VersionConstraint.unionOf([ + new VersionRange(min: v003, max: v072), + new VersionRange(min: v124) + ])), + equals(new VersionConstraint.unionOf([ + new VersionRange(min: v072, max: v080, includeMin: true), + new VersionRange(min: v123, max: v124, includeMax: true) + ]))); }); test("removes multiple portions from the same range", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v114), - new VersionRange(min: v130, max: v200) - ]).difference(new VersionConstraint.unionOf([v072, v080])), + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v114), + new VersionRange(min: v130, max: v200) + ]).difference(new VersionConstraint.unionOf([v072, v080])), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v072, max: v080), - new VersionRange(min: v080, max: v114), - new VersionRange(min: v130, max: v200) - ]))); + new VersionRange(min: v010, max: v072), + new VersionRange(min: v072, max: v080), + new VersionRange(min: v080, max: v114), + new VersionRange(min: v130, max: v200) + ]))); }); test("removes the same range from multiple ranges", () { - expect(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v080, max: v123), - new VersionRange(min: v124, max: v130), - new VersionRange(min: v200, max: v234), - new VersionRange(min: v250, max: v300) - ]).difference(new VersionRange(min: v114, max: v201)), + expect( + new VersionConstraint.unionOf([ + new VersionRange(min: v010, max: v072), + new VersionRange(min: v080, max: v123), + new VersionRange(min: v124, max: v130), + new VersionRange(min: v200, max: v234), + new VersionRange(min: v250, max: v300) + ]).difference(new VersionRange(min: v114, max: v201)), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v080, max: v114, includeMax: true), - new VersionRange(min: v201, max: v234, includeMin: true), - new VersionRange(min: v250, max: v300) - ]))); + new VersionRange(min: v010, max: v072), + new VersionRange(min: v080, max: v114, includeMax: true), + new VersionRange(min: v201, max: v234, includeMin: true), + new VersionRange(min: v250, max: v300) + ]))); }); }); -} \ No newline at end of file +} From 8f1ff683b44d236dfbc772d5e9711ae7395db768 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 20 Sep 2017 20:35:48 -0700 Subject: [PATCH 202/657] Update to make the code work with strong-mode clean Zone API. --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/lib/pool.dart | 5 +++-- pkgs/pool/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 80d54c73f..63cf0069f 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.2 + +* Update to make the code work with strong-mode clean Zone API. + ## 1.3.1 * Fix the type annotation of `Pool.withResource()` to indicate that it takes diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 04aaaea65..d81386fa2 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -183,8 +183,9 @@ class Pool { _allocatedResources--; if (_allocatedResources == 0) _closeGroup.close(); } else { - _onReleaseCallbacks.add( - Zone.current.bindCallback(onRelease, runGuarded: false)); + var zone = Zone.current; + var registered = zone.registerCallback(onRelease); + _onReleaseCallbacks.add(() => zone.run(registered)); } } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 8efc8e55a..4a8271b87 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.3.1 +version: 1.3.2 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool From 002dcd781b10ac9211ba76bd0a8fadbbc9532dfd Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 20 Sep 2017 20:33:03 -0700 Subject: [PATCH 203/657] Move analysis_options file --- pkgs/pool/{.analysis_options => analysis_options.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pkgs/pool/{.analysis_options => analysis_options.yaml} (100%) diff --git a/pkgs/pool/.analysis_options b/pkgs/pool/analysis_options.yaml similarity index 100% rename from pkgs/pool/.analysis_options rename to pkgs/pool/analysis_options.yaml From d61475c66b66f63e10faf3399025a7c4204834da Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 20 Sep 2017 20:34:16 -0700 Subject: [PATCH 204/657] Add travis-ci config --- pkgs/pool/.travis.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 pkgs/pool/.travis.yml diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml new file mode 100644 index 000000000..b202aac3e --- /dev/null +++ b/pkgs/pool/.travis.yml @@ -0,0 +1,22 @@ +language: dart +sudo: false +dart: + - dev + - stable + - 1.22.0 + +dart_task: + - test: --platform vm + - test: --platform firefox + - test: --platform dartium + install_dartium: true + - dartfmt + - dartanalyzer + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache From d955b75554d8e66762e1d2cc957fc748adc98cf5 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 20 Sep 2017 20:40:44 -0700 Subject: [PATCH 205/657] dartfmt --- pkgs/pool/lib/pool.dart | 28 +++++++-------- pkgs/pool/test/pool_test.dart | 68 ++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index d81386fa2..86f8363ce 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -78,8 +78,7 @@ class Pool { /// If [timeout] is passed, then if that much time passes without any activity /// all pending [request] futures will throw a [TimeoutException]. This is /// intended to avoid deadlocks. - Pool(this._maxAllocatedResources, {Duration timeout}) - : _timeout = timeout { + Pool(this._maxAllocatedResources, {Duration timeout}) : _timeout = timeout { if (timeout != null) { // Start the timer canceled since we only want to start counting down once // we've run out of available resources. @@ -140,21 +139,21 @@ class Pool { /// /// This may be called more than once; it returns the same [Future] each time. Future close() => _closeMemo.runOnce(() { - if (_closeGroup != null) return _closeGroup.future; + if (_closeGroup != null) return _closeGroup.future; - _resetTimer(); + _resetTimer(); - _closeGroup = new FutureGroup(); - for (var callback in _onReleaseCallbacks) { - _closeGroup.add(new Future.sync(callback)); - } + _closeGroup = new FutureGroup(); + for (var callback in _onReleaseCallbacks) { + _closeGroup.add(new Future.sync(callback)); + } - _allocatedResources -= _onReleaseCallbacks.length; - _onReleaseCallbacks.clear(); + _allocatedResources -= _onReleaseCallbacks.length; + _onReleaseCallbacks.clear(); - if (_allocatedResources == 0) _closeGroup.close(); - return _closeGroup.future; - }); + if (_allocatedResources == 0) _closeGroup.close(); + return _closeGroup.future; + }); final _closeMemo = new AsyncMemoizer(); /// If there are any pending requests, this will fire the oldest one. @@ -222,7 +221,8 @@ class Pool { void _onTimeout() { for (var completer in _requestedResources) { completer.completeError( - new TimeoutException("Pool deadlock: all resources have been " + new TimeoutException( + "Pool deadlock: all resources have been " "allocated for too long.", _timeout), new Chain.current()); diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 7fba9c0b0..6feba75c3 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -299,9 +299,11 @@ void main() { test("pending requests are fulfilled", () async { var pool = new Pool(1); var resource1 = await pool.request(); - expect(pool.request().then((resource2) { - resource2.release(); - }), completes); + expect( + pool.request().then((resource2) { + resource2.release(); + }), + completes); expect(pool.done, completes); expect(pool.close(), completes); resource1.release(); @@ -312,10 +314,12 @@ void main() { var resource1 = await pool.request(); var completer = new Completer(); - expect(pool.request().then((resource2) { - expect(completer.isCompleted, isTrue); - resource2.release(); - }), completes); + expect( + pool.request().then((resource2) { + expect(completer.isCompleted, isTrue); + resource2.release(); + }), + completes); expect(pool.close(), completes); resource1.allowRelease(() => completer.future); @@ -333,11 +337,13 @@ void main() { var resource1Released = false; var resource2Released = false; var resource3Released = false; - expect(pool.close().then((_) { - expect(resource1Released, isTrue); - expect(resource2Released, isTrue); - expect(resource3Released, isTrue); - }), completes); + expect( + pool.close().then((_) { + expect(resource1Released, isTrue); + expect(resource2Released, isTrue); + expect(resource3Released, isTrue); + }), + completes); resource1Released = true; resource1.release(); @@ -360,9 +366,11 @@ void main() { // [completer]. var completer = new Completer(); resource.allowRelease(() => completer.future); - expect(pool.request().then((_) { - expect(completer.isCompleted, isTrue); - }), completes); + expect( + pool.request().then((_) { + expect(completer.isCompleted, isTrue); + }), + completes); await new Future.delayed(Duration.ZERO); pool.close(); @@ -381,10 +389,12 @@ void main() { var completer2 = new Completer(); resource2.allowRelease(() => completer2.future); - expect(pool.close().then((_) { - expect(completer1.isCompleted, isTrue); - expect(completer2.isCompleted, isTrue); - }), completes); + expect( + pool.close().then((_) { + expect(completer1.isCompleted, isTrue); + expect(completer2.isCompleted, isTrue); + }), + completes); await new Future.delayed(Duration.ZERO); completer1.complete(); @@ -398,9 +408,11 @@ void main() { var resource = await pool.request(); var completer = new Completer(); - expect(pool.close().then((_) { - expect(completer.isCompleted, isTrue); - }), completes); + expect( + pool.close().then((_) { + expect(completer.isCompleted, isTrue); + }), + completes); await new Future.delayed(Duration.ZERO); resource.allowRelease(() => completer.future); @@ -438,10 +450,10 @@ Function expectNoAsync() { /// /// This should only be called within a [FakeAsync.run] zone. Matcher get doesNotComplete => predicate((future) { - expect(future, new isInstanceOf()); + expect(future, new isInstanceOf()); - var stack = new Trace.current(1); - future.then((_) => registerException( - new TestFailure("Expected future not to complete."), stack)); - return true; -}); + var stack = new Trace.current(1); + future.then((_) => registerException( + new TestFailure("Expected future not to complete."), stack)); + return true; + }); From d45732291af1f389c68c4359093841c37cacd37b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 20 Sep 2017 20:57:07 -0700 Subject: [PATCH 206/657] Update minimum SDK --- pkgs/pool/.travis.yml | 2 +- pkgs/pool/CHANGELOG.md | 2 ++ pkgs/pool/pubspec.yaml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index b202aac3e..bf601a14f 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -3,7 +3,7 @@ sudo: false dart: - dev - stable - - 1.22.0 + - 1.23.0 dart_task: - test: --platform vm diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 63cf0069f..fbf12f2cb 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -2,6 +2,8 @@ * Update to make the code work with strong-mode clean Zone API. +* Required minimum SDK of 1.23.0. + ## 1.3.1 * Fix the type annotation of `Pool.withResource()` to indicate that it takes diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 4a8271b87..3c65826e2 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -7,7 +7,7 @@ dependencies: async: "^1.4.0" stack_trace: ">=0.9.2 <2.0.0" environment: - sdk: ">=1.22.0 <2.0.0" + sdk: ">=1.23.0 <2.0.0" dev_dependencies: fake_async: ">=0.1.0 <0.2.0" test: ">=0.12.0 <0.13.0" From ac2c0728aac408b177fd997ef170df830f881ba2 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 Sep 2017 12:05:30 -0700 Subject: [PATCH 207/657] Stop using deprecated pkg/test APIs - throw an HttpException ...instead of a String --- pkgs/package_config/lib/discovery.dart | 4 ++-- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/discovery_analysis_test.dart | 2 +- pkgs/package_config/test/discovery_test.dart | 9 ++++++--- pkgs/package_config/test/parse_test.dart | 8 +++++--- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 4c09eecfb..2abf443fb 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -210,8 +210,8 @@ Future> _httpGet(Uri uri) async { HttpClientRequest request = await client.getUrl(uri); HttpClientResponse response = await request.close(); if (response.statusCode != HttpStatus.OK) { - throw 'Failure getting $uri: ' - '${response.statusCode} ${response.reasonPhrase}'; + throw new HttpException('${response.statusCode} ${response.reasonPhrase}', + uri: uri); } List> splitContent = await response.toList(); int totalLength = 0; diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index a629eafef..89b1855a9 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.0.2 +version: 1.0.3-dev description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/discovery_analysis_test.dart b/pkgs/package_config/test/discovery_analysis_test.dart index 0a2876726..c819a9074 100644 --- a/pkgs/package_config/test/discovery_analysis_test.dart +++ b/pkgs/package_config/test/discovery_analysis_test.dart @@ -78,7 +78,7 @@ void validatePackagesDir(Packages resolver, Uri location) { if (location.scheme == "file") { expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); } else { - expect(() => resolver.packages, throws); + expect(() => resolver.packages, throwsUnsupportedError); } } diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 897063f52..cbbca9a5d 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -41,7 +41,7 @@ void validatePackagesDir(Packages resolver, Uri location) { if (location.scheme == "file") { expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); } else { - expect(() => resolver.packages, throws); + expect(() => resolver.packages, throwsUnsupportedError); } } @@ -228,13 +228,16 @@ main() { generalTest("loadPackagesFile not found", {}, (Uri directory) async { Uri file = directory.resolve(".packages"); - expect(loadPackagesFile(file), throws); + expect( + loadPackagesFile(file), + throwsA(anyOf(new isInstanceOf(), + new isInstanceOf()))); }); generalTest("loadPackagesFile syntax error", {".packages": "syntax error"}, (Uri directory) async { Uri file = directory.resolve(".packages"); - expect(loadPackagesFile(file), throws); + expect(loadPackagesFile(file), throwsFormatException); }); generalTest("getPackagesDir", { diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 7a2fce7e2..fb3a6fab4 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -102,16 +102,18 @@ main() { for (int i = 0; i <= 255; i++) { if (map[i] == true) continue; var char = new String.fromCharCode(i); - expect(() => doParse("x${char}x:x", null), throws); + expect(() => doParse("x${char}x:x", null), + anyOf(throwsNoSuchMethodError, throwsFormatException)); } }); test("no escapes", () { - expect(() => doParse("x%41x:x", base), throws); + expect(() => doParse("x%41x:x", base), throwsFormatException); }); test("same name twice", () { - expect(() => doParse(singleRelativeSample * 2, base), throws); + expect( + () => doParse(singleRelativeSample * 2, base), throwsFormatException); }); for (String invalidSample in invalid) { From f0823a14d4f9cf4e9418dec716b2251087216de3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 Sep 2017 12:06:22 -0700 Subject: [PATCH 208/657] Use travis tasks --- pkgs/package_config/.travis.yml | 18 +++++++++++++++--- pkgs/package_config/tool/travis.sh | 17 ----------------- 2 files changed, 15 insertions(+), 20 deletions(-) delete mode 100755 pkgs/package_config/tool/travis.sh diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml index d7febddd1..24d56a3aa 100644 --- a/pkgs/package_config/.travis.yml +++ b/pkgs/package_config/.travis.yml @@ -1,5 +1,17 @@ language: dart -dart: dev -script: ./tool/travis.sh -dist: trusty sudo: false +dart: + - dev + - stable +dart_task: + - test + - dartfmt + - dartanalyzer: --fatal-warnings . + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache diff --git a/pkgs/package_config/tool/travis.sh b/pkgs/package_config/tool/travis.sh deleted file mode 100755 index 6d8cfe375..000000000 --- a/pkgs/package_config/tool/travis.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Copyright (c) 2015, 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. - -# Fast fail the script on failures. -set -e - -# Verify that the libraries are error free. -dartanalyzer --fatal-warnings \ - lib/packages.dart \ - test/all.dart - -# Run the tests. -dart test/all.dart - From 25cf81831c5baf6c616c73bbca5325fbcb20cc4c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 Sep 2017 12:06:38 -0700 Subject: [PATCH 209/657] Remove unneeded SDK constraint --- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index c17c67498..a9ac0ec03 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.3 + +- Removed unneeded dependency constraint on SDK. + ## 1.0.2 - Update SDK constraint to be 2.0.0 dev friendly. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 89b1855a9..3d81eb2a4 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -5,7 +5,7 @@ author: Dart Team homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=1.11.0 <2.0.0-dev.infinity' + sdk: '>=1.11.0 <2.0.0' dependencies: charcode: ^1.1.0 From f37ecac7ba3642c72f55bc0d8da7283ddb2874f9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 Sep 2017 12:06:44 -0700 Subject: [PATCH 210/657] dartfmt --- pkgs/package_config/lib/discovery.dart | 2 ++ pkgs/package_config/lib/discovery_analysis.dart | 2 ++ pkgs/package_config/test/discovery_test.dart | 2 ++ pkgs/package_config/test/parse_write_test.dart | 1 + 4 files changed, 7 insertions(+) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 2abf443fb..020d99a80 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -33,6 +33,7 @@ Future loadPackagesFile(Uri packagesFile, Map packageMap = pkgfile.parse(bytes, packagesFile); return new MapPackages(packageMap); } + if (packagesFile.scheme == "file") { File file = new File.fromUri(packagesFile); return parseBytes(await file.readAsBytes()); @@ -125,6 +126,7 @@ FileSystemEntity _findPackagesFile(String workingDirectory) { if (file.existsSync()) return file; return null; } + // Check for $cwd/.packages var packagesCfgFile = checkForConfigFile(dir); if (packagesCfgFile != null) return packagesCfgFile; diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart index ce7e98a1a..67798e129 100644 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -91,6 +91,7 @@ abstract class PackageContext { contexts = oldContexts; } } + findRoots(directory); // If the root is not itself context root, add a the wrapper context. if (contexts.length == 1 && contexts[0].directory == directory) { @@ -115,6 +116,7 @@ class _PackageContext implements PackageContext { recurse(child); } } + recurse(this); return result; } diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index cbbca9a5d..6a5bcdee9 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -169,6 +169,7 @@ main() { } throw "not found"; } + // A non-file: location with no .packages or packages/: // Assumes a packages dir exists, and resolves relative to that. Packages resolver; @@ -189,6 +190,7 @@ main() { Future> loader(Uri file) async { throw "not found"; } + // A non-file: location with no .packages or packages/: // Assumes a packages dir exists, and resolves relative to that. Packages resolver; diff --git a/pkgs/package_config/test/parse_write_test.dart b/pkgs/package_config/test/parse_write_test.dart index 430218791..b963eb5b5 100644 --- a/pkgs/package_config/test/parse_write_test.dart +++ b/pkgs/package_config/test/parse_write_test.dart @@ -34,6 +34,7 @@ main() { }); }); } + var lowerDir = baseDir.resolve("path3/path4/"); var higherDir = baseDir.resolve("../"); var parallelDir = baseDir.resolve("../path3/"); From cae7ab5e1cb56408a2b7cbd66fbcd7da266dd27b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 Sep 2017 12:28:07 -0700 Subject: [PATCH 211/657] Prepare for release --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 3d81eb2a4..bd2c6abaf 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.0.3-dev +version: 1.0.3 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From d531ea65453351093814b909891aaba2323b7563 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 22 Sep 2017 13:41:56 -0700 Subject: [PATCH 212/657] Declare support for async 2.0.0 (dart-lang/pool#11) --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index fbf12f2cb..d9db81c13 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.3 + +* Declare support for `async` 2.0.0. + ## 1.3.2 * Update to make the code work with strong-mode clean Zone API. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 3c65826e2..b9c5c8d9a 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,10 +1,10 @@ name: pool -version: 1.3.2 +version: 1.3.3 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool dependencies: - async: "^1.4.0" + async: ">=1.4.0 <3.0.0" stack_trace: ">=0.9.2 <2.0.0" environment: sdk: ">=1.23.0 <2.0.0" From 162b1a9b58eac382180240f123759884cdc3afe5 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Tue, 12 Dec 2017 13:27:55 +0100 Subject: [PATCH 213/657] Fix analyzer warnings in parser_test.dart --- pkgs/source_maps/test/parser_test.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 2c24d1b6f..87141522d 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -137,7 +137,7 @@ main() { test('parse with source root', () { var inputMap = new Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = '/pkg/'; - var mapping = parseJson(inputMap); + var mapping = parseJson(inputMap) as SingleMapping; expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse("/pkg/input.dart")); expect( mapping @@ -329,14 +329,14 @@ main() { MAP_WITH_SOURCE_LOCATION, MAP_WITH_SOURCE_LOCATION_AND_NAME ]) { - var mapping = parseJson(expected); + var mapping = parseJson(expected) as SingleMapping; expect(mapping.toJson(), equals(expected)); - mapping = parseJsonExtended(expected); + mapping = parseJsonExtended(expected) as SingleMapping; expect(mapping.toJson(), equals(expected)); } // Invalid for this case - expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throws); + expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throws) as MappingBundle; var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE); expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); From dffd5c30d8355097f30edef138fd53a2bb5bc5e2 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Tue, 12 Dec 2017 17:37:36 +0100 Subject: [PATCH 214/657] Update following review comments --- pkgs/source_maps/test/parser_test.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 87141522d..8c98c8178 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -329,16 +329,16 @@ main() { MAP_WITH_SOURCE_LOCATION, MAP_WITH_SOURCE_LOCATION_AND_NAME ]) { - var mapping = parseJson(expected) as SingleMapping; + SingleMapping mapping = parseJson(expected); expect(mapping.toJson(), equals(expected)); - mapping = parseJsonExtended(expected) as SingleMapping; + mapping = parseJsonExtended(expected); expect(mapping.toJson(), equals(expected)); } // Invalid for this case - expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throws) as MappingBundle; + expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throws); - var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE); + var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE) as MappingBundle; expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); }); } From 1515f5e0da4141e288588cc99edb5013c14c1d84 Mon Sep 17 00:00:00 2001 From: keertip Date: Wed, 3 Jan 2018 13:22:26 -0800 Subject: [PATCH 215/657] Changes to eliminate future flattening --- pkgs/pool/lib/pool.dart | 2 +- pkgs/pool/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 86f8363ce..ea3d2f016 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -122,7 +122,7 @@ class Pool { // synchronously in case the pool is closed immediately afterwards. Async // functions have an asynchronous gap between calling and running the body, // and [close] could be called during that gap. See #3. - return request().then>((resource) { + return request().then((resource) { return new Future.sync(callback).whenComplete(resource.release); }); } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index b9c5c8d9a..08f3b70f4 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.3.3 +version: 1.3.3-dev author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool From 59a18837dcfe9f293e83e785d34a1e43d19e057e Mon Sep 17 00:00:00 2001 From: keertip Date: Wed, 3 Jan 2018 14:47:44 -0800 Subject: [PATCH 216/657] prepare for release --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index d9db81c13..84b72c0f3 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.4 + +* Modify code to eliminate Future flattening. + ## 1.3.3 * Declare support for `async` 2.0.0. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 08f3b70f4..a5f043429 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.3.3-dev +version: 1.3.4 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool From cdd6d0bbe112ed98190684a1f555453200ac15b8 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 14 Feb 2018 21:09:33 -0800 Subject: [PATCH 217/657] Remove tests on Dartium --- pkgs/pool/.travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index bf601a14f..a3c98ae1f 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -1,5 +1,5 @@ language: dart -sudo: false + dart: - dev - stable @@ -8,8 +8,6 @@ dart: dart_task: - test: --platform vm - test: --platform firefox - - test: --platform dartium - install_dartium: true - dartfmt - dartanalyzer From 3f8bd495964fb7696edac168c4494417d98d9459 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 1 Mar 2018 15:49:51 -0800 Subject: [PATCH 218/657] Enable Travis-CI (dart-lang/source_span#19) Fixes dart-lang/source_span#18 --- pkgs/source_span/.travis.yml | 24 ++++ pkgs/source_span/lib/src/colors.dart | 1 - pkgs/source_span/lib/src/file.dart | 7 +- pkgs/source_span/lib/src/location.dart | 3 +- pkgs/source_span/lib/src/location_mixin.dart | 1 - pkgs/source_span/lib/src/span_mixin.dart | 4 +- .../lib/src/span_with_context.dart | 2 +- pkgs/source_span/test/file_test.dart | 12 +- pkgs/source_span/test/highlight_test.dart | 9 +- pkgs/source_span/test/location_test.dart | 13 +- pkgs/source_span/test/span_test.dart | 128 +++++++----------- 11 files changed, 98 insertions(+), 106 deletions(-) create mode 100644 pkgs/source_span/.travis.yml diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml new file mode 100644 index 000000000..44a054287 --- /dev/null +++ b/pkgs/source_span/.travis.yml @@ -0,0 +1,24 @@ +language: dart + +dart: + - dev + - stable + +dart_task: + - test: --platform vm,chrome + +matrix: + include: + # Only validate formatting using the dev release + - dart: dev + dart_task: dartfmt + - dart: dev + dart_task: dartanalyzer + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache diff --git a/pkgs/source_span/lib/src/colors.dart b/pkgs/source_span/lib/src/colors.dart index e934cded7..b9afab0db 100644 --- a/pkgs/source_span/lib/src/colors.dart +++ b/pkgs/source_span/lib/src/colors.dart @@ -8,4 +8,3 @@ const String RED = '\u001b[31m'; const String YELLOW = '\u001b[33m'; const String NONE = '\u001b[0m'; - diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 0217c2d43..6154e1343 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -53,8 +53,7 @@ class SourceFile { /// /// Use [new SourceFile.fromString] instead. @Deprecated("Will be removed in 2.0.0") - SourceFile(String text, {url}) - : this.decoded(text.runes, url: url); + SourceFile(String text, {url}) : this.decoded(text.runes, url: url); /// Creates a new source file from [text]. /// @@ -317,7 +316,6 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { SourceSpan union(SourceSpan other) { if (other is! FileSpan) return super.union(other); - _FileSpan span = expand(other); if (other is _FileSpan) { @@ -339,7 +337,8 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { return super == other && sourceUrl == other.sourceUrl; } - return _start == other._start && _end == other._end && + return _start == other._start && + _end == other._end && sourceUrl == other.sourceUrl; } diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 2d23db1a3..cf9931951 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -82,7 +82,8 @@ class SourceLocation implements Comparable { } bool operator ==(other) => - other is SourceLocation && sourceUrl == other.sourceUrl && + other is SourceLocation && + sourceUrl == other.sourceUrl && offset == other.offset; int get hashCode => sourceUrl.hashCode + offset; diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index 653c2c441..1e5fc66f8 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -46,4 +46,3 @@ abstract class SourceLocationMixin implements SourceLocation { String toString() => '<$runtimeType: $offset $toolString>'; } - diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 06e2024c9..1f7799d67 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -113,8 +113,8 @@ abstract class SourceSpanMixin implements SourceSpan { return buffer.toString(); } - bool operator ==(other) => other is SourceSpan && - start == other.start && end == other.end; + bool operator ==(other) => + other is SourceSpan && start == other.start && end == other.end; int get hashCode => start.hashCode + (31 * end.hashCode); diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart index a02d78047..41697a0a6 100644 --- a/pkgs/source_span/lib/src/span_with_context.dart +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -22,7 +22,7 @@ class SourceSpanWithContext extends SourceSpanBase { /// [text] should start at `start.column` from the beginning of a line in /// [context]. SourceSpanWithContext( - SourceLocation start, SourceLocation end, String text, this._context) + SourceLocation start, SourceLocation end, String text, this._context) : super(start, end, text) { if (!context.contains(text)) { throw new ArgumentError( diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 54bc3d34e..3f02a8bd9 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -87,7 +87,7 @@ zip zap zop""", url: "foo.dart"); test("column may not be outside the file", () { expect(() => file.getOffset(2, 100), throwsRangeError); }); - + test("column may not be outside the line", () { expect(() => file.getOffset(1, 20), throwsRangeError); }); @@ -109,8 +109,8 @@ zip zap zop""", url: "foo.dart"); group("for span().union()", () { test("source URLs must match", () { - var other = new SourceSpan( - new SourceLocation(10), new SourceLocation(11), "_"); + var other = + new SourceSpan(new SourceLocation(10), new SourceLocation(11), "_"); expect(() => file.span(9, 10).union(other), throwsArgumentError); }); @@ -312,10 +312,8 @@ zip zap zop""", url: "bar.dart").span(10, 11); }); test("returns a base SourceSpan for a SourceSpan input", () { - var other = new SourceSpan( - new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(5, sourceUrl: "foo.dart"), - "hey, "); + var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); var result = span.union(other); expect(result, isNot(new isInstanceOf())); expect(result.start, equals(other.start)); diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 74faed52a..08d2e17c5 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -62,22 +62,19 @@ zip zap zop }); test("works for a point span in an empty file", () { - expect(new SourceFile("").location(0).pointSpan().highlight(), - equals(""" + expect(new SourceFile("").location(0).pointSpan().highlight(), equals(""" ^""")); }); test("works for a single-line file without a newline", () { - expect(new SourceFile("foo bar").span(0, 7).highlight(), - equals(""" + expect(new SourceFile("foo bar").span(0, 7).highlight(), equals(""" foo bar ^^^^^^^""")); }); test("emits tabs for tabs", () { - expect(new SourceFile(" \t \t\tfoo bar").span(5, 8).highlight(), - equals(""" + expect(new SourceFile(" \t \t\tfoo bar").span(5, 8).highlight(), equals(""" \t \t\tfoo bar \t \t\t^^^""")); }); diff --git a/pkgs/source_span/test/location_test.dart b/pkgs/source_span/test/location_test.dart index dcd497a9f..3a32a92ef 100644 --- a/pkgs/source_span/test/location_test.dart +++ b/pkgs/source_span/test/location_test.dart @@ -8,8 +8,8 @@ import 'package:source_span/source_span.dart'; main() { var location; setUp(() { - location = new SourceLocation(15, - line: 2, column: 6, sourceUrl: "foo.dart"); + location = + new SourceLocation(15, line: 2, column: 6, sourceUrl: "foo.dart"); }); group('errors', () { @@ -28,13 +28,13 @@ main() { }); test('for distance() source URLs must match', () { - expect(() => location.distance(new SourceLocation(0)), - throwsArgumentError); + expect( + () => location.distance(new SourceLocation(0)), throwsArgumentError); }); test('for compareTo() source URLs must match', () { - expect(() => location.compareTo(new SourceLocation(0)), - throwsArgumentError); + expect( + () => location.compareTo(new SourceLocation(0)), throwsArgumentError); }); }); @@ -81,7 +81,6 @@ main() { }); }); - group("equality", () { test("two locations with the same offset and source are equal", () { var other = new SourceLocation(15, sourceUrl: "foo.dart"); diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index f980f30cb..b7637cf7c 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -9,10 +9,8 @@ import 'package:source_span/src/colors.dart' as colors; main() { var span; setUp(() { - span = new SourceSpan( - new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(12, sourceUrl: "foo.dart"), - "foo bar"); + span = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); }); group('errors', () { @@ -40,26 +38,28 @@ main() { test('context must contain text', () { var start = new SourceLocation(2); var end = new SourceLocation(5); - expect(() => new SourceSpanWithContext( - start, end, "abc", "--axc--"), throwsArgumentError); + expect(() => new SourceSpanWithContext(start, end, "abc", "--axc--"), + throwsArgumentError); }); test('text starts at start.column in context', () { var start = new SourceLocation(3); var end = new SourceLocation(5); - expect(() => new SourceSpanWithContext( - start, end, "abc", "--abc--"), throwsArgumentError); + expect(() => new SourceSpanWithContext(start, end, "abc", "--abc--"), + throwsArgumentError); }); test('text starts at start.column of line in multi-line context', () { var start = new SourceLocation(4, line: 55, column: 3); var end = new SourceLocation(7, line: 55, column: 6); - expect(() => new SourceSpanWithContext( - start, end, "abc", "\n--abc--"), throwsArgumentError); - expect(() => new SourceSpanWithContext( - start, end, "abc", "\n----abc--"), throwsArgumentError); - expect(() => new SourceSpanWithContext( - start, end, "abc", "\n\n--abc--"), throwsArgumentError); + expect(() => new SourceSpanWithContext(start, end, "abc", "\n--abc--"), + throwsArgumentError); + expect( + () => new SourceSpanWithContext(start, end, "abc", "\n----abc--"), + throwsArgumentError); + expect( + () => new SourceSpanWithContext(start, end, "abc", "\n\n--abc--"), + throwsArgumentError); // However, these are valid: new SourceSpanWithContext(start, end, "abc", "\n---abc--"); @@ -75,10 +75,14 @@ main() { new SourceSpanWithContext(start1, end1, "abc", "--abc--abc--\n"); new SourceSpanWithContext(start2, end2, "abc", "--abc---abc--\n"); new SourceSpanWithContext(start2, end2, "abc", "---abc--abc--\n"); - expect(() => new SourceSpanWithContext( - start1, end1, "abc", "---abc--abc--\n"), throwsArgumentError); - expect(() => new SourceSpanWithContext( - start2, end2, "abc", "--abc--abc--\n"), throwsArgumentError); + expect( + () => new SourceSpanWithContext( + start1, end1, "abc", "---abc--abc--\n"), + throwsArgumentError); + expect( + () => new SourceSpanWithContext( + start2, end2, "abc", "--abc--abc--\n"), + throwsArgumentError); }); }); @@ -103,10 +107,8 @@ main() { }); test('for compareTo() source URLs must match', () { - var other = new SourceSpan( - new SourceLocation(12, sourceUrl: "bar.dart"), - new SourceLocation(13, sourceUrl: "bar.dart"), - "_"); + var other = new SourceSpan(new SourceLocation(12, sourceUrl: "bar.dart"), + new SourceLocation(13, sourceUrl: "bar.dart"), "_"); expect(() => span.compareTo(other), throwsArgumentError); }); @@ -121,10 +123,8 @@ main() { group("union()", () { test("works with a preceding adjacent span", () { - var other = new SourceSpan( - new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(5, sourceUrl: "foo.dart"), - "hey, "); + var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); var result = span.union(other); expect(result.start, equals(other.start)); @@ -133,10 +133,8 @@ main() { }); test("works with a preceding overlapping span", () { - var other = new SourceSpan( - new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(8, sourceUrl: "foo.dart"), - "hey, foo"); + var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(8, sourceUrl: "foo.dart"), "hey, foo"); var result = span.union(other); expect(result.start, equals(other.start)); @@ -145,10 +143,8 @@ main() { }); test("works with a following adjacent span", () { - var other = new SourceSpan( - new SourceLocation(12, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), - " baz"); + var other = new SourceSpan(new SourceLocation(12, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), " baz"); var result = span.union(other); expect(result.start, equals(span.start)); @@ -157,10 +153,8 @@ main() { }); test("works with a following overlapping span", () { - var other = new SourceSpan( - new SourceLocation(9, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), - "bar baz"); + var other = new SourceSpan(new SourceLocation(9, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), "bar baz"); var result = span.union(other); expect(result.start, equals(span.start)); @@ -169,19 +163,15 @@ main() { }); test("works with an internal overlapping span", () { - var other = new SourceSpan( - new SourceLocation(7, sourceUrl: "foo.dart"), - new SourceLocation(10, sourceUrl: "foo.dart"), - "o b"); + var other = new SourceSpan(new SourceLocation(7, sourceUrl: "foo.dart"), + new SourceLocation(10, sourceUrl: "foo.dart"), "o b"); expect(span.union(other), equals(span)); }); test("works with an external overlapping span", () { - var other = new SourceSpan( - new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), - "hey, foo bar baz"); + var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), "hey, foo bar baz"); expect(span.union(other), equals(other)); }); @@ -206,11 +196,10 @@ foo bar }); test("gracefully handles empty text", () { - var span = new SourceSpan( - new SourceLocation(5), new SourceLocation(5), ""); + var span = + new SourceSpan(new SourceLocation(5), new SourceLocation(5), ""); - expect(span.message("oh no"), - equals("line 1, column 6: oh no")); + expect(span.message("oh no"), equals("line 1, column 6: oh no")); }); test("doesn't colorize if color is false", () { @@ -221,8 +210,7 @@ foo bar }); test("colorizes if color is true", () { - expect(span.message("oh no", color: true), - equals(""" + expect(span.message("oh no", color: true), equals(""" line 1, column 6 of foo.dart: oh no ${colors.RED}foo bar${colors.NONE} ${colors.RED}^^^^^^^${colors.NONE}""")); @@ -251,20 +239,16 @@ line 1, column 6 of foo.dart: oh no group("compareTo()", () { test("sorts by start location first", () { - var other = new SourceSpan( - new SourceLocation(6, sourceUrl: "foo.dart"), - new SourceLocation(14, sourceUrl: "foo.dart"), - "oo bar b"); + var other = new SourceSpan(new SourceLocation(6, sourceUrl: "foo.dart"), + new SourceLocation(14, sourceUrl: "foo.dart"), "oo bar b"); expect(span.compareTo(other), lessThan(0)); expect(other.compareTo(span), greaterThan(0)); }); test("sorts by length second", () { - var other = new SourceSpan( - new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(14, sourceUrl: "foo.dart"), - "foo bar b"); + var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(14, sourceUrl: "foo.dart"), "foo bar b"); expect(span.compareTo(other), lessThan(0)); expect(other.compareTo(span), greaterThan(0)); @@ -277,37 +261,29 @@ line 1, column 6 of foo.dart: oh no group("equality", () { test("two spans with the same locations are equal", () { - var other = new SourceSpan( - new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(12, sourceUrl: "foo.dart"), - "foo bar"); + var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); expect(span, equals(other)); }); test("a different start isn't equal", () { - var other = new SourceSpan( - new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(12, sourceUrl: "foo.dart"), - "hey, foo bar"); + var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), + new SourceLocation(12, sourceUrl: "foo.dart"), "hey, foo bar"); expect(span, isNot(equals(other))); }); test("a different end isn't equal", () { - var other = new SourceSpan( - new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), - "foo bar baz"); + var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), + new SourceLocation(16, sourceUrl: "foo.dart"), "foo bar baz"); expect(span, isNot(equals(other))); }); test("a different source URL isn't equal", () { - var other = new SourceSpan( - new SourceLocation(5, sourceUrl: "bar.dart"), - new SourceLocation(12, sourceUrl: "bar.dart"), - "foo bar"); + var other = new SourceSpan(new SourceLocation(5, sourceUrl: "bar.dart"), + new SourceLocation(12, sourceUrl: "bar.dart"), "foo bar"); expect(span, isNot(equals(other))); }); From 0480257ce840ae9b9f64b5d6f4eb7484a8c690d3 Mon Sep 17 00:00:00 2001 From: pq Date: Sat, 10 Mar 2018 14:43:00 -0800 Subject: [PATCH 219/657] Update .gitignore to new `dart_tool` pub cache See: https://github.com/dart-lang/sdk/issues/32030 --- pkgs/package_config/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore index a8b93ef38..4b1d87897 100644 --- a/pkgs/package_config/.gitignore +++ b/pkgs/package_config/.gitignore @@ -1,5 +1,5 @@ .packages -.pub +.dart_tool packages pubspec.lock doc/api/ From 14631cd03338d3c828438e98c1c7e89985e192a3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 10 Mar 2018 16:50:41 -0800 Subject: [PATCH 220/657] Enable Travis, rename analysis_options, update .gitignore --- pkgs/source_maps/.gitignore | 17 ++------- pkgs/source_maps/.travis.yml | 23 ++++++++++++ ...analysis_options => analysis_options.yaml} | 0 pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/run.dart | 36 ------------------- 5 files changed, 27 insertions(+), 51 deletions(-) create mode 100644 pkgs/source_maps/.travis.yml rename pkgs/source_maps/{.analysis_options => analysis_options.yaml} (100%) delete mode 100755 pkgs/source_maps/test/run.dart diff --git a/pkgs/source_maps/.gitignore b/pkgs/source_maps/.gitignore index 7dbf0350d..f73b2f917 100644 --- a/pkgs/source_maps/.gitignore +++ b/pkgs/source_maps/.gitignore @@ -1,15 +1,4 @@ -# Don’t commit the following directories created by pub. -.buildlog -.pub/ -build/ -packages +.dart_tool/ .packages - -# Or the files created by dart2js. -*.dart.js -*.js_ -*.js.deps -*.js.map - -# Include when developing application packages. -pubspec.lock \ No newline at end of file +.pub/ +pubspec.lock diff --git a/pkgs/source_maps/.travis.yml b/pkgs/source_maps/.travis.yml new file mode 100644 index 000000000..25aeabec0 --- /dev/null +++ b/pkgs/source_maps/.travis.yml @@ -0,0 +1,23 @@ +language: dart + +dart: + - dev + - stable + +dart_task: + - test: -p vm,chrome + - dartanalyzer + +matrix: + include: + # Only validate formatting using the dev release + - dart: dev + dart_task: dartfmt + +# Only building master means that we don't run two builds for each pull request. +branches: + only: [master] + +cache: + directories: + - $HOME/.pub-cache diff --git a/pkgs/source_maps/.analysis_options b/pkgs/source_maps/analysis_options.yaml similarity index 100% rename from pkgs/source_maps/.analysis_options rename to pkgs/source_maps/analysis_options.yaml diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 1db777bdc..ecf277ba8 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.4 +version: 0.10.5-dev author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart deleted file mode 100755 index 477da8a37..000000000 --- a/pkgs/source_maps/test/run.dart +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env dart -// Copyright (c) 2013, 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. - -library test.run; - -import 'package:test/compact_vm_config.dart'; -import 'package:test/test.dart'; - -import 'builder_test.dart' as builder_test; -import 'end2end_test.dart' as end2end_test; -import 'parser_test.dart' as parser_test; -import 'printer_test.dart' as printer_test; -import 'refactor_test.dart' as refactor_test; -import 'utils_test.dart' as utils_test; -import 'vlq_test.dart' as vlq_test; - -main(List arguments) { - var pattern = new RegExp(arguments.length > 0 ? arguments[0] : '.'); - useCompactVMConfiguration(); - - void addGroup(testFile, testMain) { - if (pattern.hasMatch(testFile)) { - group(testFile.replaceAll('_test.dart', ':'), testMain); - } - } - - addGroup('builder_test.dart', builder_test.main); - addGroup('end2end_test.dart', end2end_test.main); - addGroup('parser_test.dart', parser_test.main); - addGroup('printer_test.dart', printer_test.main); - addGroup('refactor_test.dart', refactor_test.main); - addGroup('utils_test.dart', utils_test.main); - addGroup('vlq_test.dart', vlq_test.main); -} From 83a68264f32d45f3947af8fe00c05d87db435c87 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 10 Mar 2018 16:54:32 -0800 Subject: [PATCH 221/657] dartfmt --- pkgs/source_maps/lib/builder.dart | 14 +-- pkgs/source_maps/lib/printer.dart | 6 +- pkgs/source_maps/lib/refactor.dart | 20 ++-- pkgs/source_maps/lib/src/vlq.dart | 1 - pkgs/source_maps/test/builder_test.dart | 16 ++-- pkgs/source_maps/test/common.dart | 14 +-- pkgs/source_maps/test/end2end_test.dart | 58 ++++++------ pkgs/source_maps/test/printer_test.dart | 115 ++++++++++++----------- pkgs/source_maps/test/refactor_test.dart | 55 +++++++---- pkgs/source_maps/test/utils_test.dart | 1 - pkgs/source_maps/test/vlq_test.dart | 1 - 11 files changed, 160 insertions(+), 141 deletions(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index c8596fe63..cdba2d2dc 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -16,7 +16,6 @@ import 'src/source_map_span.dart'; /// Builds a source map given a set of mappings. class SourceMapBuilder { - final List _entries = []; /// Adds an entry mapping the [targetOffset] to [source]. @@ -25,8 +24,8 @@ class SourceMapBuilder { if (targetFile == null) { throw new ArgumentError('targetFile cannot be null'); } - _entries.add( - new Entry(source, targetFile.location(targetOffset), identifier)); + _entries + .add(new Entry(source, targetFile.location(targetOffset), identifier)); } /// Adds an entry mapping [target] to [source]. @@ -45,8 +44,8 @@ class SourceMapBuilder { } /// Adds an entry mapping [target] to [source]. - void addLocation(SourceLocation source, SourceLocation target, - String identifier) { + void addLocation( + SourceLocation source, SourceLocation target, String identifier) { _entries.add(new Entry(source, target, identifier)); } @@ -80,8 +79,9 @@ class Entry implements Comparable { int compareTo(Entry other) { int res = target.compareTo(other.target); if (res != 0) return res; - res = source.sourceUrl.toString().compareTo( - other.source.sourceUrl.toString()); + res = source.sourceUrl + .toString() + .compareTo(other.source.sourceUrl.toString()); if (res != 0) return res; return source.compareTo(other.source); } diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 906e260f8..6187dba81 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -63,7 +63,6 @@ class Printer { _buff.write(str); } - /// Append a [total] number of spaces in the target file. Typically used for /// formatting indentation. void addSpaces(int total) { @@ -101,7 +100,6 @@ class Printer { /// peices of the code are generated independently on separate printers, and are /// finally put together in the end. class NestedPrinter implements NestedItem { - /// Items recoded by this printer, which can be [String] literals, /// [NestedItem]s, and source map information like [SourceLocation] and /// [SourceSpan]. @@ -134,8 +132,8 @@ class NestedPrinter implements NestedItem { /// Indicate [isOriginal] when [object] is copied directly from the user code. /// Setting [isOriginal] will make this printer propagate source map locations /// on every line-break. - void add(object, {SourceLocation location, SourceSpan span, - bool isOriginal: false}) { + void add(object, + {SourceLocation location, SourceSpan span, bool isOriginal: false}) { if (object is! String || location != null || span != null || isOriginal) { _flush(); assert(location == null || span == null); diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index a33b86bec..d6b129a29 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -41,7 +41,7 @@ class TextEditTransaction { /// rewritten string and source map information. [filename] is given to the /// underlying printer to indicate the name of the generated file that will /// contains the source map information. - /// + /// /// Throws [UnsupportedError] if the edits were overlapping. If no edits were /// made, the printer simply contains the original string. NestedPrinter commit() { @@ -57,12 +57,13 @@ class TextEditTransaction { for (var edit in _edits) { if (consumed > edit.begin) { var sb = new StringBuffer(); - sb..write(file.location(edit.begin).toolString) - ..write(': overlapping edits. Insert at offset ') - ..write(edit.begin) - ..write(' but have consumed ') - ..write(consumed) - ..write(' input characters. List of edits:'); + sb + ..write(file.location(edit.begin).toolString) + ..write(': overlapping edits. Insert at offset ') + ..write(edit.begin) + ..write(' but have consumed ') + ..write(consumed) + ..write(' input characters. List of edits:'); for (var e in _edits) sb..write('\n ')..write(e); throw new UnsupportedError(sb.toString()); } @@ -70,8 +71,9 @@ class TextEditTransaction { // Add characters from the original string between this edit and the last // one, if any. var betweenEdits = original.substring(consumed, edit.begin); - printer..add(betweenEdits, location: _loc(consumed), isOriginal: true) - ..add(edit.replace, location: _loc(edit.begin)); + printer + ..add(betweenEdits, location: _loc(consumed), isOriginal: true) + ..add(edit.replace, location: _loc(edit.begin)); consumed = edit.end; } diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index e4ab4eb69..0c54dbf66 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -2,7 +2,6 @@ // 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. - /// Utilities to encode and decode VLQ values used in source maps. /// /// Sourcemaps are encoded with variable length numbers as base64 encoded diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index dcc583cfd..7c27e4e17 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -12,20 +12,20 @@ import 'common.dart'; main() { test('builder - with span', () { var map = (new SourceMapBuilder() - ..addSpan(inputVar1, outputVar1) - ..addSpan(inputFunction, outputFunction) - ..addSpan(inputVar2, outputVar2) - ..addSpan(inputExpr, outputExpr)) + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr)) .build(output.url.toString()); expect(map, equals(EXPECTED_MAP)); }); test('builder - with location', () { var str = (new SourceMapBuilder() - ..addLocation(inputVar1.start, outputVar1.start, 'longVar1') - ..addLocation(inputFunction.start, outputFunction.start, 'longName') - ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') - ..addLocation(inputExpr.start, outputExpr.start, null)) + ..addLocation(inputVar1.start, outputVar1.start, 'longVar1') + ..addLocation(inputFunction.start, outputFunction.start, 'longName') + ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') + ..addLocation(inputExpr.start, outputExpr.start, null)) .toJson(output.url.toString()); expect(str, JSON.encode(EXPECTED_MAP)); }); diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index 3bc512cdf..01ffdada6 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -63,19 +63,19 @@ SourceMapSpan outputExpr = ospan(19, 24); /// This mapping is stored in the tests so we can independently test the builder /// and parser algorithms without relying entirely on end2end tests. const Map EXPECTED_MAP = const { - 'version': 3, - 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const ['longVar1','longName','longVar2'], - 'mappings': 'IACIA;AAGAC,EAAaC,MACR', - 'file': 'output.dart' + 'version': 3, + 'sourceRoot': '', + 'sources': const ['input.dart'], + 'names': const ['longVar1', 'longName', 'longVar2'], + 'mappings': 'IACIA;AAGAC,EAAaC,MACR', + 'file': 'output.dart' }; check(SourceSpan outputSpan, Mapping mapping, SourceMapSpan inputSpan, bool realOffsets) { var line = outputSpan.start.line; var column = outputSpan.start.column; - var files = realOffsets ? {'input.dart': input} : null; + var files = realOffsets ? {'input.dart': input} : null; var span = mapping.spanFor(line, column, files: files); var span2 = mapping.spanForLocation(outputSpan.start, files: files); diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 8caf2e9ea..dd5bced00 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -30,10 +30,10 @@ main() { test('build + parse', () { var map = (new SourceMapBuilder() - ..addSpan(inputVar1, outputVar1) - ..addSpan(inputFunction, outputFunction) - ..addSpan(inputVar2, outputVar2) - ..addSpan(inputExpr, outputExpr)) + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr)) .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1, mapping, inputVar1, false); @@ -44,10 +44,10 @@ main() { test('build + parse - no symbols', () { var map = (new SourceMapBuilder() - ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) - ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) - ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) - ..addSpan(inputExpr, outputExpr)) + ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) + ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) + ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) + ..addSpan(inputExpr, outputExpr)) .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false); @@ -58,14 +58,14 @@ main() { test('build + parse, repeated entries', () { var map = (new SourceMapBuilder() - ..addSpan(inputVar1, outputVar1) - ..addSpan(inputVar1, outputVar1) - ..addSpan(inputFunction, outputFunction) - ..addSpan(inputFunction, outputFunction) - ..addSpan(inputVar2, outputVar2) - ..addSpan(inputVar2, outputVar2) - ..addSpan(inputExpr, outputExpr) - ..addSpan(inputExpr, outputExpr)) + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr) + ..addSpan(inputExpr, outputExpr)) .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1, mapping, inputVar1, false); @@ -76,13 +76,13 @@ main() { test('build + parse - no symbols, repeated entries', () { var map = (new SourceMapBuilder() - ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) - ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) - ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) - ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) - ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) - ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) - ..addSpan(inputExpr, outputExpr)) + ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) + ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) + ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) + ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) + ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) + ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) + ..addSpan(inputExpr, outputExpr)) .build(output.url.toString()); var mapping = parseJson(map); check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false); @@ -93,10 +93,10 @@ main() { test('build + parse with file', () { var json = (new SourceMapBuilder() - ..addSpan(inputVar1, outputVar1) - ..addSpan(inputFunction, outputFunction) - ..addSpan(inputVar2, outputVar2) - ..addSpan(inputExpr, outputExpr)) + ..addSpan(inputVar1, outputVar1) + ..addSpan(inputFunction, outputFunction) + ..addSpan(inputVar2, outputVar2) + ..addSpan(inputExpr, outputExpr)) .toJson(output.url.toString()); var mapping = parse(json); check(outputVar1, mapping, inputVar1, true); @@ -156,7 +156,7 @@ main() { var oOffset = out.length - 2; var iOffset = INPUT.length - 2; check(file.span(oOffset, oOffset), mapping, ispan(iOffset, iOffset), true); - check(file.span(oOffset + 1, oOffset + 1), mapping, - ispan(iOffset, iOffset), true); + check(file.span(oOffset + 1, oOffset + 1), mapping, ispan(iOffset, iOffset), + true); }); } diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index 25036eee9..3fd768d8c 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -13,15 +13,16 @@ import 'common.dart'; main() { test('printer', () { var printer = new Printer('output.dart'); - printer..add('var ') - ..mark(inputVar1) - ..add('x = 3;\n') - ..mark(inputFunction) - ..add('f(') - ..mark(inputVar2) - ..add('y) => ') - ..mark(inputExpr) - ..add('x + y;\n'); + printer + ..add('var ') + ..mark(inputVar1) + ..add('x = 3;\n') + ..mark(inputFunction) + ..add('f(') + ..mark(inputVar2) + ..add('y) => ') + ..mark(inputExpr) + ..add('x + y;\n'); expect(printer.text, OUTPUT); expect(printer.map, JSON.encode(EXPECTED_MAP)); }); @@ -32,48 +33,50 @@ main() { var segments = INPUT.split('long'); expect(segments.length, 6); - printer..mark(ispan(0, 0)) - ..add(segments[0], projectMarks: true) - ..mark(inputVar1) - ..add('_s') - ..add(segments[1], projectMarks: true) - ..mark(inputFunction) - ..add('_s') - ..add(segments[2], projectMarks: true) - ..mark(inputVar2) - ..add('_s') - ..add(segments[3], projectMarks: true) - ..mark(inputExpr) - ..add('_s') - ..add(segments[4], projectMarks: true) - ..add('_s') - ..add(segments[5], projectMarks: true); + printer + ..mark(ispan(0, 0)) + ..add(segments[0], projectMarks: true) + ..mark(inputVar1) + ..add('_s') + ..add(segments[1], projectMarks: true) + ..mark(inputFunction) + ..add('_s') + ..add(segments[2], projectMarks: true) + ..mark(inputVar2) + ..add('_s') + ..add(segments[3], projectMarks: true) + ..mark(inputExpr) + ..add('_s') + ..add(segments[4], projectMarks: true) + ..add('_s') + ..add(segments[5], projectMarks: true); expect(printer.text, out); // 8 new lines in the source map: expect(printer.map.split(';').length, 8); - asFixed(SourceMapSpan s) => new SourceMapSpan(s.start, s.end, s.text, - isIdentifier: s.isIdentifier); + asFixed(SourceMapSpan s) => + new SourceMapSpan(s.start, s.end, s.text, isIdentifier: s.isIdentifier); // The result is the same if we use fixed positions var printer2 = new Printer('output2.dart'); - printer2..mark(new SourceLocation(0, sourceUrl: 'input.dart').pointSpan()) - ..add(segments[0], projectMarks: true) - ..mark(asFixed(inputVar1)) - ..add('_s') - ..add(segments[1], projectMarks: true) - ..mark(asFixed(inputFunction)) - ..add('_s') - ..add(segments[2], projectMarks: true) - ..mark(asFixed(inputVar2)) - ..add('_s') - ..add(segments[3], projectMarks: true) - ..mark(asFixed(inputExpr)) - ..add('_s') - ..add(segments[4], projectMarks: true) - ..add('_s') - ..add(segments[5], projectMarks: true); + printer2 + ..mark(new SourceLocation(0, sourceUrl: 'input.dart').pointSpan()) + ..add(segments[0], projectMarks: true) + ..mark(asFixed(inputVar1)) + ..add('_s') + ..add(segments[1], projectMarks: true) + ..mark(asFixed(inputFunction)) + ..add('_s') + ..add(segments[2], projectMarks: true) + ..mark(asFixed(inputVar2)) + ..add('_s') + ..add(segments[3], projectMarks: true) + ..mark(asFixed(inputExpr)) + ..add('_s') + ..add(segments[4], projectMarks: true) + ..add('_s') + ..add(segments[5], projectMarks: true); expect(printer2.text, out); expect(printer2.map, printer.map); @@ -82,24 +85,26 @@ main() { group('nested printer', () { test('simple use', () { var printer = new NestedPrinter(); - printer..add('var ') - ..add('x = 3;\n', span: inputVar1) - ..add('f(', span: inputFunction) - ..add('y) => ', span: inputVar2) - ..add('x + y;\n', span: inputExpr) - ..build('output.dart'); + printer + ..add('var ') + ..add('x = 3;\n', span: inputVar1) + ..add('f(', span: inputFunction) + ..add('y) => ', span: inputVar2) + ..add('x + y;\n', span: inputExpr) + ..build('output.dart'); expect(printer.text, OUTPUT); expect(printer.map, JSON.encode(EXPECTED_MAP)); }); test('nested use', () { var printer = new NestedPrinter(); - printer..add('var ') - ..add(new NestedPrinter()..add('x = 3;\n', span: inputVar1)) - ..add('f(', span: inputFunction) - ..add(new NestedPrinter()..add('y) => ', span: inputVar2)) - ..add('x + y;\n', span: inputExpr) - ..build('output.dart'); + printer + ..add('var ') + ..add(new NestedPrinter()..add('x = 3;\n', span: inputVar1)) + ..add('f(', span: inputFunction) + ..add(new NestedPrinter()..add('y) => ', span: inputVar2)) + ..add('x + y;\n', span: inputExpr) + ..build('output.dart'); expect(printer.text, OUTPUT); expect(printer.map, JSON.encode(EXPECTED_MAP)); }); diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 03292d1db..afaeec26e 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -33,15 +33,16 @@ main() { txn.edit(6, 7, '_'); txn.edit(6, 6, '-'); expect((txn.commit()..build('')).text, "01.4|5-_789abcdefghij"); - }); test('conflict', () { var txn = new TextEditTransaction(original, file); txn.edit(2, 4, '.'); txn.edit(3, 3, '-'); - expect(() => txn.commit(), throwsA(predicate( - (e) => e.toString().contains('overlapping edits')))); + expect( + () => txn.commit(), + throwsA( + predicate((e) => e.toString().contains('overlapping edits')))); }); }); @@ -60,40 +61,48 @@ main() { // Line 1 and 2 are unmodified: mapping any column returns the beginning // of the corresponding line: - expect(_span(1, 1, map, file), + expect( + _span(1, 1, map, file), "line 1, column 1: \n" "0123456789\n" "^"); - expect(_span(1, 5, map, file), + expect( + _span(1, 5, map, file), "line 1, column 1: \n" "0123456789\n" "^"); - expect(_span(2, 1, map, file), + expect( + _span(2, 1, map, file), "line 2, column 1: \n" "0*23456789\n" "^"); - expect(_span(2, 8, map, file), + expect( + _span(2, 8, map, file), "line 2, column 1: \n" "0*23456789\n" "^"); // Line 3 is modified part way: mappings before the edits have the right // mapping, after the edits the mapping is null. - expect(_span(3, 1, map, file), + expect( + _span(3, 1, map, file), "line 3, column 1: \n" "01*3456789\n" "^"); - expect(_span(3, 5, map, file), + expect( + _span(3, 5, map, file), "line 3, column 1: \n" "01*3456789\n" "^"); // Start of edits map to beginning of the edit secion: - expect(_span(3, 6, map, file), + expect( + _span(3, 6, map, file), "line 3, column 6: \n" "01*3456789\n" " ^"); - expect(_span(3, 7, map, file), + expect( + _span(3, 7, map, file), "line 3, column 6: \n" "01*3456789\n" " ^"); @@ -101,42 +110,50 @@ main() { // Lines added have no mapping (they should inherit the last mapping), // but the end of the edit region continues were we left off: expect(_span(4, 1, map, file), isNull); - expect(_span(4, 5, map, file), + expect( + _span(4, 5, map, file), "line 3, column 8: \n" "01*3456789\n" " ^"); // Subsequent lines are still mapped correctly: // a (in a___cd...) - expect(_span(5, 1, map, file), + expect( + _span(5, 1, map, file), "line 4, column 1: \n" "abcdefghij\n" "^"); // _ (in a___cd...) - expect(_span(5, 2, map, file), + expect( + _span(5, 2, map, file), "line 4, column 2: \n" "abcdefghij\n" " ^"); // _ (in a___cd...) - expect(_span(5, 3, map, file), + expect( + _span(5, 3, map, file), "line 4, column 2: \n" "abcdefghij\n" " ^"); // _ (in a___cd...) - expect(_span(5, 4, map, file), + expect( + _span(5, 4, map, file), "line 4, column 2: \n" "abcdefghij\n" " ^"); // c (in a___cd...) - expect(_span(5, 5, map, file), + expect( + _span(5, 5, map, file), "line 4, column 3: \n" "abcdefghij\n" " ^"); - expect(_span(6, 1, map, file), + expect( + _span(6, 1, map, file), "line 5, column 1: \n" "abcd*fghij\n" "^"); - expect(_span(6, 8, map, file), + expect( + _span(6, 8, map, file), "line 5, column 1: \n" "abcd*fghij\n" "^"); diff --git a/pkgs/source_maps/test/utils_test.dart b/pkgs/source_maps/test/utils_test.dart index cbbb40ab3..6790082aa 100644 --- a/pkgs/source_maps/test/utils_test.dart +++ b/pkgs/source_maps/test/utils_test.dart @@ -51,4 +51,3 @@ _linearSearch(list, predicate) { } return list.length; } - diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index d1b543da0..30b6d4529 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -42,7 +42,6 @@ main() { expect(() => encodeVlq(min_int - 1), throws); expect(() => encodeVlq(min_int - 2), throws); - // if we allowed more than 32 bits, these would be the expected encodings // for the large numbers above. expect(() => decodeVlq('ggggggE'.split('').iterator), throws); From 589e7f23facd09b896b9b67bb63459dd8d79f705 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Sat, 10 Mar 2018 17:31:14 -0800 Subject: [PATCH 222/657] Update .gitignore --- pkgs/package_config/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore index 4b1d87897..3b32e387c 100644 --- a/pkgs/package_config/.gitignore +++ b/pkgs/package_config/.gitignore @@ -1,5 +1,5 @@ .packages -.dart_tool +.dart_tool/ packages pubspec.lock doc/api/ From 7666429f5fa4adf5ca7cd9460b5ae25f256fcd2d Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Mon, 12 Mar 2018 09:30:31 -0700 Subject: [PATCH 223/657] Update .gitignore --- pkgs/package_config/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore index 3b32e387c..e41fc1916 100644 --- a/pkgs/package_config/.gitignore +++ b/pkgs/package_config/.gitignore @@ -1,4 +1,5 @@ .packages +.pub .dart_tool/ packages pubspec.lock From 9db25860147cb96ab64291b99ea099e9e6504fad Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 30 Mar 2018 01:05:19 -0700 Subject: [PATCH 224/657] Fix a crashing bug (dart-lang/pub_semver#19) VersionRange.difference() with a VersionUnion didn't expect to get an empty constraint, but it was possible to do so. Closes dart-lang/pub_semver#18 --- pkgs/pub_semver/CHANGELOG.md | 5 +++++ pkgs/pub_semver/lib/src/version_range.dart | 4 +++- pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_range_test.dart | 8 ++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 6d54692d9..d50c76826 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.3.3 + +* Fix a bug where `VersionRange.difference()` with a union constraint that + covered the entire range would crash. + # 1.3.2 * Fix a checked-mode error in `VersionRange.difference()`. diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 99f292426..bce869b48 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -379,7 +379,9 @@ class VersionRange implements Comparable, VersionConstraint { if (strictlyHigher(range, current)) break; var difference = current.difference(range); - if (difference is VersionUnion) { + if (difference.isEmpty) { + return VersionConstraint.empty; + } else if (difference is VersionUnion) { // If [range] split [current] in half, we only need to continue // checking future ranges against the latter half. assert(difference.ranges.length == 2); diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 93fb03555..eac5cb05e 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.3-dev +version: 1.3.3 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index e95b3d697..cefd9d370 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -606,6 +606,14 @@ main() { new VersionRange(min: v130, max: v140) ]))); }); + + test("with a version union that covers the whole range, returns empty", () { + expect( + new VersionRange(min: v114, max: v140).difference( + new VersionConstraint.unionOf( + [v003, new VersionRange(min: v010)])), + equals(VersionConstraint.empty)); + }); }); test('isEmpty', () { From 7186e3f44cc96bab547db53f37f42a49c7d7c0bc Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 3 Apr 2018 13:59:32 -0700 Subject: [PATCH 225/657] Implement strictlyHigher() in terms of strictlyLower() --- pkgs/pub_semver/lib/src/utils.dart | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index efe105abe..9527d2dba 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -48,11 +48,5 @@ bool strictlyLower(VersionRange range1, VersionRange range2) { /// Returns whether [range1] allows only versions higher than those allowed by /// [range2]. -bool strictlyHigher(VersionRange range1, VersionRange range2) { - if (range1.min == null || range2.max == null) return false; - - var comparison = range1.min.compareTo(range2.max); - if (comparison == 1) return true; - if (comparison == -1) return false; - return !range1.includeMin || !range2.includeMax; -} +bool strictlyHigher(VersionRange range1, VersionRange range2) => + strictlyLower(range2, range1); From 4f7ae4186cb3a0cbdbdb3be98bb792c845b52e5f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 3 Apr 2018 14:22:05 -0700 Subject: [PATCH 226/657] Implement VersionRange.allowsAll() in terms of allowsLower/Higher() --- pkgs/pub_semver/lib/src/version_range.dart | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index bce869b48..8e9b4ad13 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -137,19 +137,7 @@ class VersionRange implements Comparable, VersionConstraint { } if (other is VersionRange) { - if (min != null) { - if (other.min == null) return false; - if (min > other.min) return false; - if (min == other.min && !includeMin && other.includeMin) return false; - } - - if (max != null) { - if (other.max == null) return false; - if (max < other.max) return false; - if (max == other.max && !includeMax && other.includeMax) return false; - } - - return true; + return !allowsLower(other, this) && !allowsHigher(other, this); } throw new ArgumentError('Unknown VersionConstraint type $other.'); From 087550fd40d6e96bfe366ec3df828926dfb661c2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 3 Apr 2018 14:28:55 -0700 Subject: [PATCH 227/657] Fix a pre-release-exclusion bug The special logic for excluding 1.0.0-dev from <1.0.0 was only implemented for VersionRange.allows(), not for any other methods. This brings the other methods in line with allows(). Closes dart-lang/pub_semver#20 --- pkgs/pub_semver/CHANGELOG.md | 6 ++ pkgs/pub_semver/lib/src/utils.dart | 46 ++++++++++ pkgs/pub_semver/lib/src/version_range.dart | 34 +------ pkgs/pub_semver/test/version_range_test.dart | 97 ++++++++++++++++++++ 4 files changed, 150 insertions(+), 33 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index d50c76826..53de84120 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.3.4 + +* Fix a bug where `VersionRange.allowsAll()`, `VersionRange.allowsAny()`, and + `VersionRange.difference()` would return incorrect results for pre-release + versions with the same base version number as release versions. + # 1.3.3 * Fix a bug where `VersionRange.difference()` with a union constraint that diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index 9527d2dba..d793e7a95 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -2,6 +2,9 @@ // 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:collection/collection.dart'; + +import 'version.dart'; import 'version_range.dart'; /// Returns whether [range1] is immediately next to, but not overlapping, @@ -29,6 +32,10 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { if (range1.max == null) return range2.max != null; if (range2.max == null) return false; + // `<1.0.0-dev.1` allows `1.0.0-dev.0` which is higher than any versions + // allowed by `<1.0.0`. + if (disallowedByPreRelease(range2, range1.max)) return true; + var comparison = range1.max.compareTo(range2.max); if (comparison == 1) return true; if (comparison == -1) return false; @@ -39,6 +46,7 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { /// [range2]. bool strictlyLower(VersionRange range1, VersionRange range2) { if (range1.max == null || range2.min == null) return false; + if (disallowedByPreRelease(range1, range2.min)) return true; var comparison = range1.max.compareTo(range2.min); if (comparison == -1) return true; @@ -50,3 +58,41 @@ bool strictlyLower(VersionRange range1, VersionRange range2) { /// [range2]. bool strictlyHigher(VersionRange range1, VersionRange range2) => strictlyLower(range2, range1); + +// Returns whether [other] is disallowed by [range] because we disallow +// pre-release versions that have the same major, minor, and patch version as +// the max of a range, but only if neither the max nor the min is a pre-release +// of that version. +// +// This ensures that `^1.2.3` doesn't include `2.0.0-pre`, while also allowing +// both `>=2.0.0-pre.2 <2.0.0` and `>=1.2.3 <2.0.0-pre.7` to match +// `2.0.0-pre.5`. +// +// It's worth noting that this is different than [NPM's semantics][]. NPM +// disallows **all** pre-release versions unless their major, minor, and +// patch numbers match those of a prerelease min or max. This ensures that +// no prerelease versions will ever be selected if the user doesn't +// explicitly allow them. +// +// [NPM's semantics]: https://www.npmjs.org/doc/misc/semver.html#prerelease-tags +// +// Instead, we ensure that release versions will always be preferred over +// prerelease versions by ordering the release versions first in +// [Version.prioritize]. This means that constraints like `any` or +// `>1.2.3` can still match prerelease versions if they're the only things +// available. +bool disallowedByPreRelease(VersionRange range, Version other) { + var maxIsReleaseOfOther = !range.includeMax && + !range.max.isPreRelease && + other.isPreRelease && + _equalsWithoutPreRelease(other, range.max); + var minIsPreReleaseOfOther = range.min != null && + range.min.isPreRelease && + _equalsWithoutPreRelease(other, range.min); + return maxIsReleaseOfOther && !minIsPreReleaseOfOther; +} + +bool _equalsWithoutPreRelease(Version version1, Version version2) => + version1.major == version2.major && + version1.minor == version2.minor && + version1.patch == version2.patch; diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 8e9b4ad13..b615c6f3d 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -90,44 +90,12 @@ class VersionRange implements Comparable, VersionConstraint { if (max != null) { if (other > max) return false; if (!includeMax && other == max) return false; - - // Disallow pre-release versions that have the same major, minor, and - // patch version as the max, but only if neither the max nor the min is a - // pre-release of that version. This ensures that "^1.2.3" doesn't include - // "2.0.0-pre", while also allowing both ">=2.0.0-pre.2 <2.0.0" and - // ">=1.2.3 <2.0.0-pre.7" to match "2.0.0-pre.5". - // - // It's worth noting that this is different than [NPM's semantics][]. NPM - // disallows **all** pre-release versions unless their major, minor, and - // patch numbers match those of a prerelease min or max. This ensures that - // no prerelease versions will ever be selected if the user doesn't - // explicitly allow them. - // - // [NPM's semantics]: https://www.npmjs.org/doc/misc/semver.html#prerelease-tags - // - // Instead, we ensure that release versions will always be preferred over - // prerelease versions by ordering the release versions first in - // [Version.prioritize]. This means that constraints like "any" or - // ">1.2.3" can still match prerelease versions if they're the only things - // available. - var maxIsReleaseOfOther = !includeMax && - !max.isPreRelease && - other.isPreRelease && - _equalsWithoutPreRelease(other, max); - var minIsPreReleaseOfOther = min != null && - min.isPreRelease && - _equalsWithoutPreRelease(other, min); - if (maxIsReleaseOfOther && !minIsPreReleaseOfOther) return false; + if (disallowedByPreRelease(this, other)) return false; } return true; } - bool _equalsWithoutPreRelease(Version version1, Version version2) => - version1.major == version2.major && - version1.minor == version2.minor && - version1.patch == version2.patch; - bool allowsAll(VersionConstraint other) { if (other.isEmpty) return true; if (other is Version) return allows(other); diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index cefd9d370..f01101269 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -228,6 +228,50 @@ main() { range.allowsAll(new VersionRange(min: v123, max: v234).union(v140)), isFalse); }); + + group('pre-release versions', () { + test('of inclusive min are excluded', () { + var range = new VersionRange(min: v123, includeMin: true); + + expect( + range.allowsAll(new VersionConstraint.parse('>1.2.4-dev')), isTrue); + expect(range.allowsAll(new VersionConstraint.parse('>1.2.3-dev')), + isFalse); + }); + + test('of non-pre-release max are excluded', () { + var range = new VersionRange(max: v234); + + expect(range.allowsAll(new VersionConstraint.parse('<2.3.3')), isTrue); + expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev')), + isFalse); + }); + + test( + 'of non-pre-release max are included if min is a pre-release of the ' + 'same version', () { + var range = + new VersionRange(min: new Version.parse('2.3.4-dev.0'), max: v234); + + expect( + range.allowsAll( + new VersionConstraint.parse('>2.3.4-dev.0 <2.3.4-dev.1')), + isTrue); + }); + + test('of pre-release max are included', () { + var range = new VersionRange(max: new Version.parse('2.3.4-dev.2')); + + expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev.1')), + isTrue); + expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev.2')), + isTrue); + expect(range.allowsAll(new VersionConstraint.parse('<=2.3.4-dev.2')), + isFalse); + expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev.3')), + isFalse); + }); + }); }); group('allowsAny()', () { @@ -325,6 +369,52 @@ main() { range.allowsAny(new VersionRange(min: v234, max: v300).union(v010)), isFalse); }); + + group('pre-release versions', () { + test('of inclusive min are excluded', () { + var range = new VersionRange(min: v123, includeMin: true); + + expect( + range.allowsAny(new VersionConstraint.parse('<1.2.4-dev')), isTrue); + expect(range.allowsAny(new VersionConstraint.parse('<1.2.3-dev')), + isFalse); + }); + + test('of non-pre-release max are excluded', () { + var range = new VersionRange(max: v234); + + expect(range.allowsAny(new VersionConstraint.parse('>2.3.3')), isTrue); + expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev')), + isFalse); + }); + + test( + 'of non-pre-release max are included if min is a pre-release of the ' + 'same version', () { + var range = + new VersionRange(min: new Version.parse('2.3.4-dev.0'), max: v234); + + expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.1')), + isTrue); + expect(range.allowsAny(new VersionConstraint.parse('>2.3.4')), isFalse); + + expect(range.allowsAny(new VersionConstraint.parse('<2.3.4-dev.1')), + isTrue); + expect(range.allowsAny(new VersionConstraint.parse('<2.3.4-dev')), + isFalse); + }); + + test('of pre-release max are included', () { + var range = new VersionConstraint.parse('<2.3.4-dev.2'); + + expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.1')), + isTrue); + expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.2')), + isFalse); + expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.3')), + isFalse); + }); + }); }); group('intersect()', () { @@ -614,6 +704,13 @@ main() { [v003, new VersionRange(min: v010)])), equals(VersionConstraint.empty)); }); + + test("with a range with a pre-release min, returns the original", () { + expect( + new VersionRange(max: v200) + .difference(new VersionConstraint.parse(">=2.0.0-dev")), + equals(new VersionRange(max: v200))); + }); }); test('isEmpty', () { From a4536c2c60f2fb25580aadf2fcc9c96c07b85f37 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 3 Apr 2018 15:56:47 -0700 Subject: [PATCH 228/657] Release 1.3.4 (dart-lang/pub_semver#22) --- pkgs/pub_semver/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index eac5cb05e..7f6dd0c25 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.3 +version: 1.3.4 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From fcf5ca86a422cfcc27c49501e9d7d19ca87a9a6d Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 5 Apr 2018 16:26:15 -0700 Subject: [PATCH 229/657] Fix another pre-release version bug (dart-lang/pub_semver#24) I think at this point we're testing this edge case in all our public APIs. Closes dart-lang/pub_semver#17 Closes dart-lang/pub_semver#23 --- pkgs/pub_semver/CHANGELOG.md | 5 +++ pkgs/pub_semver/lib/src/version_range.dart | 47 ++++++++------------ pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_range_test.dart | 19 ++++++++ 4 files changed, 43 insertions(+), 30 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 53de84120..207ba2922 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.3.5 + +* Fix a bug where `VersionRange.intersect()` would return incorrect results for + pre-release versions with the same base version number as release versions. + # 1.3.4 * Fix a bug where `VersionRange.allowsAll()`, `VersionRange.allowsAny()`, and diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index b615c6f3d..ae190029f 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -137,29 +137,26 @@ class VersionRange implements Comparable, VersionConstraint { if (other is VersionRange) { // Intersect the two ranges. - var intersectMin = min; - var intersectIncludeMin = includeMin; - var intersectMax = max; - var intersectIncludeMax = includeMax; - - if (other.min == null) { - // Do nothing. - } else if (intersectMin == null || intersectMin < other.min) { + Version intersectMin; + bool intersectIncludeMin; + if (allowsLower(this, other)) { + if (strictlyLower(this, other)) return VersionConstraint.empty; intersectMin = other.min; intersectIncludeMin = other.includeMin; - } else if (intersectMin == other.min && !other.includeMin) { - // The edges are the same, but one is exclusive, make it exclusive. - intersectIncludeMin = false; + } else { + if (strictlyLower(other, this)) return VersionConstraint.empty; + intersectMin = this.min; + intersectIncludeMin = this.includeMin; } - if (other.max == null) { - // Do nothing. - } else if (intersectMax == null || intersectMax > other.max) { + Version intersectMax; + bool intersectIncludeMax; + if (allowsHigher(this, other)) { intersectMax = other.max; intersectIncludeMax = other.includeMax; - } else if (intersectMax == other.max && !other.includeMax) { - // The edges are the same, but one is exclusive, make it exclusive. - intersectIncludeMax = false; + } else { + intersectMax = this.max; + intersectIncludeMax = this.includeMax; } if (intersectMin == null && intersectMax == null) { @@ -169,18 +166,10 @@ class VersionRange implements Comparable, VersionConstraint { // If the range is just a single version. if (intersectMin == intersectMax) { - // If both ends are inclusive, allow that version. - if (intersectIncludeMin && intersectIncludeMax) return intersectMin; - - // Otherwise, no versions. - return VersionConstraint.empty; - } - - if (intersectMin != null && - intersectMax != null && - intersectMin > intersectMax) { - // Non-overlapping ranges, so empty. - return VersionConstraint.empty; + // Because we already verified that the lower range isn't strictly + // lower, there must be some overlap. + assert(intersectIncludeMin && intersectIncludeMax); + return intersectMin; } // If we got here, there is an actual range. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 7f6dd0c25..4dbabe47f 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.4 +version: 1.3.5 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index f01101269..2c311f585 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -461,6 +461,14 @@ main() { expect(new VersionRange(min: v123, max: v124).intersect(v114).isEmpty, isTrue); }); + + test("with a range with a pre-release min, returns an empty constraint", + () { + expect( + new VersionRange(max: v200) + .intersect(new VersionConstraint.parse(">=2.0.0-dev")), + equals(VersionConstraint.empty)); + }); }); group('union()', () { @@ -539,6 +547,17 @@ main() { equals(new VersionRange( min: v003, max: v114, includeMin: true, includeMax: true))); }); + + test("with a range with a pre-release min, returns a constraint with a gap", + () { + var result = new VersionRange(max: v200) + .union(new VersionConstraint.parse(">=2.0.0-dev")); + expect(result, allows(v140)); + expect(result, doesNotAllow(new Version.parse("2.0.0-alpha"))); + expect(result, allows(new Version.parse("2.0.0-dev"))); + expect(result, allows(new Version.parse("2.0.0-dev.1"))); + expect(result, allows(new Version.parse("2.0.0"))); + }); }); group('difference()', () { From 93ec025b06ce2a60b477ffc662ad94c30a39e50b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 9 Apr 2018 17:46:57 -0700 Subject: [PATCH 230/657] Fix a bug where we'd parse pre-release constraints as empty (dart-lang/pub_semver#25) --- pkgs/pub_semver/CHANGELOG.md | 5 ++ .../lib/src/version_constraint.dart | 52 +++++++++++++------ pkgs/pub_semver/pubspec.yaml | 2 +- .../test/version_constraint_test.dart | 12 +++++ 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 207ba2922..0246edd7a 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.3.6 + +* Fix a bug where constraints that only allowed pre-release versions would be + parsed as empty constraints. + # 1.3.5 * Fix a bug where `VersionRange.intersect()` would return incorrect results for diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 36bbd9aba..670a9287d 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -57,7 +57,7 @@ abstract class VersionConstraint { if (text == "any") return any; // Try to parse and consume a version number. - matchVersion() { + Version matchVersion() { var version = START_VERSION.firstMatch(text); if (version == null) return null; @@ -66,7 +66,7 @@ abstract class VersionConstraint { } // Try to parse and consume a comparison operator followed by a version. - matchComparison() { + VersionRange matchComparison() { var comparison = START_COMPARISON.firstMatch(text); if (comparison == null) return null; @@ -117,35 +117,55 @@ abstract class VersionConstraint { var compatibleWith = matchCompatibleWith(); if (compatibleWith != null) return compatibleWith; - var constraints = []; + Version min; + var includeMin = false; + Version max; + var includeMax = false; while (true) { skipWhitespace(); if (text.isEmpty) break; - var version = matchVersion(); - if (version != null) { - constraints.add(version); - continue; + var newRange = matchVersion() ?? matchComparison(); + if (newRange == null) { + throw new FormatException('Could not parse version "$originalText". ' + 'Unknown text at "$text".'); } - var comparison = matchComparison(); - if (comparison != null) { - constraints.add(comparison); - continue; + if (newRange.min != null) { + if (min == null || newRange.min > min) { + min = newRange.min; + includeMin = newRange.includeMin; + } else if (newRange.min == min && !newRange.includeMin) { + includeMin = false; + } } - // If we got here, we couldn't parse the remaining string. - throw new FormatException('Could not parse version "$originalText". ' - 'Unknown text at "$text".'); + if (newRange.max != null) { + if (max == null || newRange.max < max) { + max = newRange.max; + includeMax = newRange.includeMax; + } else if (newRange.max == max && !newRange.includeMax) { + includeMax = false; + } + } } - if (constraints.isEmpty) { + if (min == null && max == null) { throw new FormatException('Cannot parse an empty string.'); } - return new VersionConstraint.intersection(constraints); + if (min != null && max != null) { + if (min > max) return VersionConstraint.empty; + if (min == max) { + if (includeMin && includeMax) return min; + return VersionConstraint.empty; + } + } + + return new VersionRange( + min: min, includeMin: includeMin, max: max, includeMax: includeMax); } /// Creates a version constraint which allows all versions that are diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 4dbabe47f..1b0beb8ce 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.5 +version: 1.3.6 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index bc378325e..bf3a01862 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -103,6 +103,18 @@ main() { new Version.parse('1.3.0'), new Version.parse('3.4.5'))); }); + test('parses a pre-release-only constraint', () { + var constraint = new VersionConstraint.parse('>=1.0.0-dev.2 <1.0.0'); + expect( + constraint, + allows(new Version.parse('1.0.0-dev.2'), + new Version.parse('1.0.0-dev.3'))); + expect( + constraint, + doesNotAllow( + new Version.parse('1.0.0-dev.1'), new Version.parse('1.0.0'))); + }); + test('ignores whitespace around comparison operators', () { var constraint = new VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0'); From 9612e2cb556c9934c314f257cf7234df1ad9af65 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 13 Apr 2018 11:46:58 -0700 Subject: [PATCH 231/657] Fix more pre-release constraint bugs (dart-lang/pub_semver#26) I hadn't thought to test version ranges with max pre-release constraints, but they turn out to be relevant in some situations. Closes dart-lang/pub_semver#20 --- pkgs/pub_semver/CHANGELOG.md | 5 ++++ pkgs/pub_semver/lib/src/utils.dart | 10 +++++-- pkgs/pub_semver/lib/src/version_range.dart | 29 ++++++++------------ pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_range_test.dart | 22 +++++++++++++++ 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 0246edd7a..f2e5e62e6 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.3.7 + +* Fix more bugs with `VersionRange.intersect()`, `VersionRange.difference()`, + and `VersionRange.union()` involving version ranges with pre-release maximums. + # 1.3.6 * Fix a bug where constraints that only allowed pre-release versions would be diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index d793e7a95..adc1faee9 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -32,10 +32,12 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { if (range1.max == null) return range2.max != null; if (range2.max == null) return false; - // `<1.0.0-dev.1` allows `1.0.0-dev.0` which is higher than any versions - // allowed by `<1.0.0`. + // `<1.0.0-dev.1` allows higher versions than `<1.0.0`, such as `1.0.0-dev.0`. if (disallowedByPreRelease(range2, range1.max)) return true; + // `<1.0.0` doesn't allow any versions higher than `<1.0.0-dev`. + if (disallowedByPreRelease(range1, range2.max)) return false; + var comparison = range1.max.compareTo(range2.max); if (comparison == 1) return true; if (comparison == -1) return false; @@ -46,8 +48,12 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { /// [range2]. bool strictlyLower(VersionRange range1, VersionRange range2) { if (range1.max == null || range2.min == null) return false; + + // `<1.0.0` doesn't allow any versions allowed by `>=1.0.0-dev.0`. if (disallowedByPreRelease(range1, range2.min)) return true; + //if (disallowedByPreRelease(range2, range1.min)) return true; + var comparison = range1.max.compareTo(range2.min); if (comparison == -1) return true; if (comparison == 1) return false; diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index ae190029f..ec15de432 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -215,29 +215,24 @@ class VersionRange implements Comparable, VersionConstraint { return new VersionConstraint.unionOf([this, other]); } - var unionMin = min; - var unionIncludeMin = includeMin; - var unionMax = max; - var unionIncludeMax = includeMax; - - if (unionMin == null) { - // Do nothing. - } else if (other.min == null || other.min < min) { + Version unionMin; + bool unionIncludeMin; + if (allowsLower(this, other)) { + unionMin = this.min; + unionIncludeMin = this.includeMin; + } else { unionMin = other.min; unionIncludeMin = other.includeMin; - } else if (min == other.min && other.includeMin) { - // If the edges are the same but one is inclusive, make it inclusive. - unionIncludeMin = true; } - if (unionMax == null) { - // Do nothing. - } else if (other.max == null || other.max > max) { + Version unionMax; + bool unionIncludeMax; + if (allowsHigher(this, other)) { + unionMax = this.max; + unionIncludeMax = this.includeMax; + } else { unionMax = other.max; unionIncludeMax = other.includeMax; - } else if (max == other.max && other.includeMax) { - // If the edges are the same but one is inclusive, make it inclusive. - unionIncludeMax = true; } return new VersionRange( diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 1b0beb8ce..1b738d755 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.6 +version: 1.3.7 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 2c311f585..63cf30257 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -469,6 +469,13 @@ main() { .intersect(new VersionConstraint.parse(">=2.0.0-dev")), equals(VersionConstraint.empty)); }); + + test("with a range with a pre-release max, returns the original", () { + expect( + new VersionRange(max: v200) + .intersect(new VersionConstraint.parse("<2.0.0-dev")), + equals(new VersionRange(max: v200))); + }); }); group('union()', () { @@ -558,6 +565,14 @@ main() { expect(result, allows(new Version.parse("2.0.0-dev.1"))); expect(result, allows(new Version.parse("2.0.0"))); }); + + test("with a range with a pre-release max, returns the larger constraint", + () { + expect( + new VersionRange(max: v200) + .union(new VersionConstraint.parse("<2.0.0-dev")), + equals(new VersionConstraint.parse("<2.0.0-dev"))); + }); }); group('difference()', () { @@ -730,6 +745,13 @@ main() { .difference(new VersionConstraint.parse(">=2.0.0-dev")), equals(new VersionRange(max: v200))); }); + + test("with a range with a pre-release max, returns null", () { + expect( + new VersionRange(max: v200) + .difference(new VersionConstraint.parse("<2.0.0-dev")), + equals(VersionConstraint.empty)); + }); }); test('isEmpty', () { From 2f368b1c5453f3ebf70009432b9f0fe4f0be2e7e Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Tue, 17 Apr 2018 09:51:16 +0200 Subject: [PATCH 232/657] Remove upper case constants (dart-lang/pool#13) Remove usage of upper-case constants. Updates SDK version to 2.0.0-dev.17.0 --- pkgs/pool/.travis.yml | 2 -- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/pubspec.yaml | 4 ++-- pkgs/pool/test/pool_test.dart | 40 +++++++++++++++++------------------ 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index a3c98ae1f..a9b5166a4 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -2,8 +2,6 @@ language: dart dart: - dev - - stable - - 1.23.0 dart_task: - test: --platform vm diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 84b72c0f3..46d142fca 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.5 + +- Updated SDK version to 2.0.0-dev.17.0 + ## 1.3.4 * Modify code to eliminate Future flattening. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index a5f043429..a628ec617 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.3.4 +version: 1.3.5 author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool @@ -7,7 +7,7 @@ dependencies: async: ">=1.4.0 <3.0.0" stack_trace: ">=0.9.2 <2.0.0" environment: - sdk: ">=1.23.0 <2.0.0" + sdk: ">=2.0.0-dev.17.0 <2.0.0" dev_dependencies: fake_async: ">=0.1.0 <0.2.0" test: ">=0.12.0 <0.13.0" diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 6feba75c3..d0e70170e 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -177,11 +177,11 @@ void main() { var resource = await pool.request(); var onReleaseCalled = false; resource.allowRelease(() => onReleaseCalled = true); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(onReleaseCalled, isFalse); expect(pool.request(), completes); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(onReleaseCalled, isTrue); }); @@ -195,7 +195,7 @@ void main() { var onReleaseCalled = false; resource.allowRelease(() => onReleaseCalled = true); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(onReleaseCalled, isTrue); }); @@ -208,11 +208,11 @@ void main() { var completer = new Completer(); resource.allowRelease(() => completer.future); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(requestComplete, isFalse); completer.complete(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(requestComplete, isTrue); }); @@ -233,7 +233,7 @@ void main() { onRelease1Called = true; return completer1.future; }); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(onRelease1Called, isTrue); var onRelease2Called = false; @@ -242,7 +242,7 @@ void main() { onRelease2Called = true; return completer2.future; }); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(onRelease2Called, isTrue); expect(request1Complete, isFalse); expect(request2Complete, isFalse); @@ -251,12 +251,12 @@ void main() { // was triggered by the second blocking request, it should complete the // first one to preserve ordering. completer2.complete(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(request1Complete, isTrue); expect(request2Complete, isFalse); completer1.complete(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); expect(request1Complete, isTrue); expect(request2Complete, isTrue); }); @@ -286,7 +286,7 @@ void main() { var resource = await pool.request(); resource.release(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); }); group("close()", () { @@ -323,7 +323,7 @@ void main() { expect(pool.close(), completes); resource1.allowRelease(() => completer.future); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); completer.complete(); }); @@ -347,11 +347,11 @@ void main() { resource1Released = true; resource1.release(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); resource2Released = true; resource2.release(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); var resource3 = await resource3Future; resource3Released = true; @@ -372,10 +372,10 @@ void main() { }), completes); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); pool.close(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); completer.complete(); }); @@ -396,10 +396,10 @@ void main() { }), completes); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); completer1.complete(); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); completer2.complete(); }); @@ -414,10 +414,10 @@ void main() { }), completes); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); resource.allowRelease(() => completer.future); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); completer.complete(); }); @@ -431,7 +431,7 @@ void main() { expect(pool.done, throwsA("oh no!")); expect(pool.close(), throwsA("oh no!")); - await new Future.delayed(Duration.ZERO); + await new Future.delayed(Duration.zero); completer.completeError("oh no!"); }); }); From 1595c816dc28891cbfee62246ce3bc89f16206f3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 23 Apr 2018 16:43:45 -0700 Subject: [PATCH 233/657] Remove an unused import (dart-lang/pub_semver#27) --- pkgs/pub_semver/lib/src/utils.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index adc1faee9..55025a0af 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -2,8 +2,6 @@ // 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:collection/collection.dart'; - import 'version.dart'; import 'version_range.dart'; From 70c30cd2bd3aa08f87a11f338679ce1fa24f65c8 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 25 Apr 2018 15:32:00 -0700 Subject: [PATCH 234/657] Add support for the sourcesContent field (dart-lang/source_maps#28) --- pkgs/source_maps/CHANGELOG.md | 8 ++++ pkgs/source_maps/lib/parser.dart | 58 +++++++++++++++++++++----- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 51 ++++++++++++++++++++++ 4 files changed, 108 insertions(+), 11 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index a7c1b0670..8ef25be0e 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.10.5 + +* Add a `SingleMapping.files` field which provides access to `SourceFile`s + representing the `"sourcesContent"` fields in the source map. + +* Add an `includeSourceContents` flag to `SingleMapping.toJson()` which + indicates whether to include source file contents in the source map. + ## 0.10.4 * Implement `highlight` in `SourceMapFileSpan`. * Require version `^1.3.0` of `source_span`. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 3b65e8910..e46b78341 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -5,7 +5,6 @@ /// Contains the top-level function to parse source maps version 3. library source_maps.parser; -import 'dart:collection'; import 'dart:convert'; import 'package:source_span/source_span.dart'; @@ -258,6 +257,16 @@ class SingleMapping extends Mapping { /// Source names used in the mapping, indexed by id. final List names; + /// The [SourceFile]s to which the entries in [lines] refer. + /// + /// This is in the same order as [urls]. If this was constructed using + /// [fromEntries], this contains files from any [FileLocation]s used to build + /// the mapping. If it was parsed from JSON, it contains files for any sources + /// whose contents were provided via the `"sourcesContent"` field. + /// + /// Files whose contents aren't available are `null`. + final List files; + /// Entries indicating the beginning of each span. final List lines; @@ -269,7 +278,7 @@ class SingleMapping extends Mapping { final Uri _mapUrl; - SingleMapping._(this.targetUrl, this.urls, this.names, this.lines) + SingleMapping._(this.targetUrl, this.files, this.urls, this.names, this.lines) : _mapUrl = null; factory SingleMapping.fromEntries(Iterable entries, @@ -279,12 +288,15 @@ class SingleMapping extends Mapping { var lines = []; // Indices associated with file urls that will be part of the source map. We - // use a linked hash-map so that `_urls.keys[_urls[u]] == u` - var urls = new LinkedHashMap(); + // rely on map order so that `urls.keys[urls[u]] == u` + var urls = {}; // Indices associated with identifiers that will be part of the source map. - // We use a linked hash-map so that `_names.keys[_names[n]] == n` - var names = new LinkedHashMap(); + // We rely on map order so that `names.keys[names[n]] == n` + var names = {}; + + /// The file for each URL, indexed by [urls]' values. + var files = {}; var lineNum; List targetEntries; @@ -301,6 +313,12 @@ class SingleMapping extends Mapping { var sourceUrl = sourceEntry.source.sourceUrl; var urlId = urls.putIfAbsent( sourceUrl == null ? '' : sourceUrl.toString(), () => urls.length); + + if (sourceEntry.source is FileLocation) { + files.putIfAbsent( + urlId, () => (sourceEntry.source as FileLocation).file); + } + var srcNameId = sourceEntry.identifierName == null ? null : names.putIfAbsent(sourceEntry.identifierName, () => names.length); @@ -309,16 +327,30 @@ class SingleMapping extends Mapping { } } return new SingleMapping._( - fileUrl, urls.keys.toList(), names.keys.toList(), lines); + fileUrl, + urls.values.map((i) => files[i]).toList(), + urls.keys.toList(), + names.keys.toList(), + lines); } SingleMapping.fromJson(Map map, {mapUrl}) : targetUrl = map['file'], urls = new List.from(map['sources']), names = new List.from(map['names']), + files = new List(map['sources'].length), sourceRoot = map['sourceRoot'], lines = [], _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl { + var sourcesContent = map['sourcesContent'] == null + ? const [] + : new List.from(map['sourcesContent']); + for (var i = 0; i < urls.length && i < sourcesContent.length; i++) { + var source = sourcesContent[i]; + if (source == null) continue; + files[i] = new SourceFile.fromString(source, url: urls[i]); + } + int line = 0; int column = 0; int srcUrlId = 0; @@ -385,7 +417,10 @@ class SingleMapping extends Mapping { } /// Encodes the Mapping mappings as a json map. - Map toJson() { + /// + /// If [sourcesContent] is `true`, this includes the source file contents from + /// [files] in the map if possible. + Map toJson({bool includeSourceContents: false}) { var buff = new StringBuffer(); var line = 0; var column = 0; @@ -431,9 +466,12 @@ class SingleMapping extends Mapping { 'names': names, 'mappings': buff.toString() }; - if (targetUrl != null) { - result['file'] = targetUrl; + if (targetUrl != null) result['file'] = targetUrl; + + if (includeSourceContents) { + result['sourcesContent'] = files.map((file) => file?.getText(0)).toList(); } + return result; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index ecf277ba8..7bf7bcd26 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.5-dev +version: 0.10.5 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 8c98c8178..78963418f 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -341,4 +341,55 @@ main() { var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE) as MappingBundle; expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); }); + + group("source files", () { + group("from fromEntries()", () { + test("are null for non-FileLocations", () { + var mapping = new SingleMapping.fromEntries([ + new Entry(new SourceLocation(10, line: 1, column: 8), + outputVar1.start, null) + ]); + expect(mapping.files, equals([null])); + }); + + test("use a file location's file", () { + var mapping = new SingleMapping.fromEntries( + [new Entry(inputVar1.start, outputVar1.start, null)]); + expect(mapping.files, equals([input])); + }); + }); + + group("from parse()", () { + group("are null", () { + test("with no sourcesContent field", () { + var mapping = parseJson(EXPECTED_MAP) as SingleMapping; + expect(mapping.files, equals([null])); + }); + + test("with null sourcesContent values", () { + var map = new Map.from(EXPECTED_MAP); + map["sourcesContent"] = [null]; + var mapping = parseJson(map) as SingleMapping; + expect(mapping.files, equals([null])); + }); + + test("with a too-short sourcesContent", () { + var map = new Map.from(EXPECTED_MAP); + map["sourcesContent"] = []; + var mapping = parseJson(map) as SingleMapping; + expect(mapping.files, equals([null])); + }); + }); + + test("are parsed from sourcesContent", () { + var map = new Map.from(EXPECTED_MAP); + map["sourcesContent"] = ["hello, world!"]; + var mapping = parseJson(map) as SingleMapping; + + var file = mapping.files[0]; + expect(file.url, equals(Uri.parse("input.dart"))); + expect(file.getText(0), equals("hello, world!")); + }); + }); + }); } From 5ae16b9a169b4f35611e9340b3395cb46a93827a Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 1 May 2018 17:22:15 -0700 Subject: [PATCH 235/657] Handle pre-release semantics by adjusting the max version of ranges (dart-lang/pub_semver#28) Rather than adding special-cases to each operation, we now just modify the upper bound of version ranges when the special pre-release semantics would come into play. Closes dart-lang/pubdart-lang/pub_semver#1885 --- pkgs/pub_semver/CHANGELOG.md | 22 ++ pkgs/pub_semver/lib/pub_semver.dart | 2 +- pkgs/pub_semver/lib/src/utils.dart | 46 +--- pkgs/pub_semver/lib/src/version.dart | 12 +- .../lib/src/version_constraint.dart | 18 +- pkgs/pub_semver/lib/src/version_range.dart | 98 +++++-- pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/utils.dart | 4 + pkgs/pub_semver/test/version_range_test.dart | 254 ++++++++++++++++-- pkgs/pub_semver/test/version_test.dart | 8 +- pkgs/pub_semver/test/version_union_test.dart | 53 +++- 11 files changed, 400 insertions(+), 119 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index f2e5e62e6..0efa0ea7b 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,25 @@ +# 1.4.0 + +* Add a `Version.firstPreRelease` getter that returns the first possible + pre-release of a version. + +* Add a `Version.isFirstPreRelease` getter that returns whether a version is the + first possible pre-release. + +* `new VersionRange()` with an exclusive maximum now replaces the maximum with + its first pre-release version. This matches the existing semantics, where an + exclusive maximum would exclude pre-release versions of that maximum. + + Explicitly representing this by changing the maximum version ensures that all + operations behave correctly with respect to the special pre-release semantics. + In particular, it fixes bugs where, for example, + `(>=1.0.0 <2.0.0-dev).union(>=2.0.0-dev <2.0.0)` and + `(>=1.0.0 <3.0.0).difference(^1.0.0)` wouldn't include `2.0.0-dev`. + +* Add an `alwaysIncludeMaxPreRelease` parameter to `new VersionRange()`, which + disables the replacement described above and allows users to create ranges + that do include the pre-release versions of an exclusive max version. + # 1.3.7 * Fix more bugs with `VersionRange.intersect()`, `VersionRange.difference()`, diff --git a/pkgs/pub_semver/lib/pub_semver.dart b/pkgs/pub_semver/lib/pub_semver.dart index bfb7d8b70..4b6487c9e 100644 --- a/pkgs/pub_semver/lib/pub_semver.dart +++ b/pkgs/pub_semver/lib/pub_semver.dart @@ -4,5 +4,5 @@ export 'src/version.dart'; export 'src/version_constraint.dart'; -export 'src/version_range.dart'; +export 'src/version_range.dart' hide CompatibleWithVersionRange; export 'src/version_union.dart'; diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index 55025a0af..60617f22e 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -30,12 +30,6 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { if (range1.max == null) return range2.max != null; if (range2.max == null) return false; - // `<1.0.0-dev.1` allows higher versions than `<1.0.0`, such as `1.0.0-dev.0`. - if (disallowedByPreRelease(range2, range1.max)) return true; - - // `<1.0.0` doesn't allow any versions higher than `<1.0.0-dev`. - if (disallowedByPreRelease(range1, range2.max)) return false; - var comparison = range1.max.compareTo(range2.max); if (comparison == 1) return true; if (comparison == -1) return false; @@ -47,11 +41,6 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { bool strictlyLower(VersionRange range1, VersionRange range2) { if (range1.max == null || range2.min == null) return false; - // `<1.0.0` doesn't allow any versions allowed by `>=1.0.0-dev.0`. - if (disallowedByPreRelease(range1, range2.min)) return true; - - //if (disallowedByPreRelease(range2, range1.min)) return true; - var comparison = range1.max.compareTo(range2.min); if (comparison == -1) return true; if (comparison == 1) return false; @@ -63,40 +52,7 @@ bool strictlyLower(VersionRange range1, VersionRange range2) { bool strictlyHigher(VersionRange range1, VersionRange range2) => strictlyLower(range2, range1); -// Returns whether [other] is disallowed by [range] because we disallow -// pre-release versions that have the same major, minor, and patch version as -// the max of a range, but only if neither the max nor the min is a pre-release -// of that version. -// -// This ensures that `^1.2.3` doesn't include `2.0.0-pre`, while also allowing -// both `>=2.0.0-pre.2 <2.0.0` and `>=1.2.3 <2.0.0-pre.7` to match -// `2.0.0-pre.5`. -// -// It's worth noting that this is different than [NPM's semantics][]. NPM -// disallows **all** pre-release versions unless their major, minor, and -// patch numbers match those of a prerelease min or max. This ensures that -// no prerelease versions will ever be selected if the user doesn't -// explicitly allow them. -// -// [NPM's semantics]: https://www.npmjs.org/doc/misc/semver.html#prerelease-tags -// -// Instead, we ensure that release versions will always be preferred over -// prerelease versions by ordering the release versions first in -// [Version.prioritize]. This means that constraints like `any` or -// `>1.2.3` can still match prerelease versions if they're the only things -// available. -bool disallowedByPreRelease(VersionRange range, Version other) { - var maxIsReleaseOfOther = !range.includeMax && - !range.max.isPreRelease && - other.isPreRelease && - _equalsWithoutPreRelease(other, range.max); - var minIsPreReleaseOfOther = range.min != null && - range.min.isPreRelease && - _equalsWithoutPreRelease(other, range.min); - return maxIsReleaseOfOther && !minIsPreReleaseOfOther; -} - -bool _equalsWithoutPreRelease(Version version1, Version version2) => +bool equalsWithoutPreRelease(Version version1, Version version2) => version1.major == version2.major && version1.minor == version2.minor && version1.patch == version2.patch; diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 6665873de..19ae96262 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -239,6 +239,12 @@ class Version implements VersionConstraint, VersionRange { return _incrementMajor(); } + /// Returns the first possible pre-release of this version. + Version get firstPreRelease => new Version(major, minor, patch, pre: "0"); + + /// Returns whether this is the first possible pre-release of its version. + bool get isFirstPreRelease => preRelease.length == 1 && preRelease.first == 0; + Version _incrementMajor() => new Version(major + 1, 0, 0); Version _incrementMinor() => new Version(major, minor + 1, 0); Version _incrementPatch() => new Version(major, minor, patch + 1); @@ -262,7 +268,8 @@ class Version implements VersionConstraint, VersionRange { min: other.min, max: other.max, includeMin: true, - includeMax: other.includeMax); + includeMax: other.includeMax, + alwaysIncludeMaxPreRelease: true); } if (other.max == this) { @@ -270,7 +277,8 @@ class Version implements VersionConstraint, VersionRange { min: other.min, max: other.max, includeMin: other.includeMin, - includeMax: true); + includeMax: true, + alwaysIncludeMaxPreRelease: true); } } diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 670a9287d..67093f701 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -84,7 +84,10 @@ abstract class VersionConstraint { case '<=': return new VersionRange(max: version, includeMax: true); case '<': - return new VersionRange(max: version, includeMax: false); + return new VersionRange( + max: version, + includeMax: false, + alwaysIncludeMaxPreRelease: true); case '>=': return new VersionRange(min: version, includeMin: true); case '>': @@ -175,7 +178,7 @@ abstract class VersionConstraint { /// are greater than or equal to [version], but less than the next breaking /// version ([Version.nextBreaking]) of [version]. factory VersionConstraint.compatibleWith(Version version) => - new _CompatibleWithVersionRange(version); + new CompatibleWithVersionRange(version); /// Creates a new version constraint that is the intersection of /// [constraints]. @@ -278,14 +281,3 @@ class _EmptyVersion implements VersionConstraint { VersionConstraint difference(VersionConstraint other) => this; String toString() => ''; } - -class _CompatibleWithVersionRange extends VersionRange { - _CompatibleWithVersionRange(Version version) - : super( - min: version, - includeMin: true, - max: version.nextBreaking, - includeMax: false); - - String toString() => '^$min'; -} diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index ec15de432..99dc7189d 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -53,14 +53,36 @@ class VersionRange implements Comparable, VersionConstraint { /// /// If [includeMin] is `true`, then the minimum end of the range is inclusive. /// Likewise, passing [includeMax] as `true` makes the upper end inclusive. - VersionRange( - {this.min, this.max, this.includeMin: false, this.includeMax: false}) { + /// + /// If [alwaysIncludeMaxPreRelease] is `true`, this will always include + /// pre-release versions of an exclusive [max]. Otherwise, it will use the + /// default behavior for pre-release versions of [max]. + factory VersionRange( + {Version min, + Version max, + bool includeMin: false, + bool includeMax: false, + bool alwaysIncludeMaxPreRelease: false}) { if (min != null && max != null && min > max) { throw new ArgumentError( 'Minimum version ("$min") must be less than maximum ("$max").'); } + + if (!alwaysIncludeMaxPreRelease && + !includeMax && + max != null && + !max.isPreRelease && + (min == null || + !min.isPreRelease || + !equalsWithoutPreRelease(min, max))) { + max = max.firstPreRelease; + } + + return new VersionRange._(min, max, includeMin, includeMax); } + VersionRange._(this.min, this.max, this.includeMin, this.includeMax); + bool operator ==(other) { if (other is! VersionRange) return false; @@ -90,7 +112,6 @@ class VersionRange implements Comparable, VersionConstraint { if (max != null) { if (other > max) return false; if (!includeMax && other == max) return false; - if (disallowedByPreRelease(this, other)) return false; } return true; @@ -177,7 +198,8 @@ class VersionRange implements Comparable, VersionConstraint { min: intersectMin, max: intersectMax, includeMin: intersectIncludeMin, - includeMax: intersectIncludeMax); + includeMax: intersectIncludeMax, + alwaysIncludeMaxPreRelease: true); } throw new ArgumentError('Unknown VersionConstraint type $other.'); @@ -192,7 +214,8 @@ class VersionRange implements Comparable, VersionConstraint { min: this.min, max: this.max, includeMin: true, - includeMax: this.includeMax); + includeMax: this.includeMax, + alwaysIncludeMaxPreRelease: true); } if (other == max) { @@ -200,7 +223,8 @@ class VersionRange implements Comparable, VersionConstraint { min: this.min, max: this.max, includeMin: this.includeMin, - includeMax: true); + includeMax: true, + alwaysIncludeMaxPreRelease: true); } return new VersionConstraint.unionOf([this, other]); @@ -239,7 +263,8 @@ class VersionRange implements Comparable, VersionConstraint { min: unionMin, max: unionMax, includeMin: unionIncludeMin, - includeMax: unionIncludeMax); + includeMax: unionIncludeMax, + alwaysIncludeMaxPreRelease: true); } return new VersionConstraint.unionOf([this, other]); @@ -254,20 +279,36 @@ class VersionRange implements Comparable, VersionConstraint { if (other == min) { if (!includeMin) return this; return new VersionRange( - min: min, max: max, includeMin: false, includeMax: includeMax); + min: min, + max: max, + includeMin: false, + includeMax: includeMax, + alwaysIncludeMaxPreRelease: true); } if (other == max) { if (!includeMax) return this; return new VersionRange( - min: min, max: max, includeMin: includeMin, includeMax: false); + min: min, + max: max, + includeMin: includeMin, + includeMax: false, + alwaysIncludeMaxPreRelease: true); } return new VersionUnion.fromRanges([ new VersionRange( - min: min, max: other, includeMin: includeMin, includeMax: false), + min: min, + max: other, + includeMin: includeMin, + includeMax: false, + alwaysIncludeMaxPreRelease: true), new VersionRange( - min: other, max: max, includeMin: false, includeMax: includeMax) + min: other, + max: max, + includeMin: false, + includeMax: includeMax, + alwaysIncludeMaxPreRelease: true) ]); } else if (other is VersionRange) { if (!allowsAny(other)) return this; @@ -284,7 +325,8 @@ class VersionRange implements Comparable, VersionConstraint { min: min, max: other.min, includeMin: includeMin, - includeMax: !other.includeMin); + includeMax: !other.includeMin, + alwaysIncludeMaxPreRelease: true); } VersionRange after; @@ -299,7 +341,8 @@ class VersionRange implements Comparable, VersionConstraint { min: other.max, max: max, includeMin: !other.includeMax, - includeMax: includeMax); + includeMax: includeMax, + alwaysIncludeMaxPreRelease: true); } if (before == null && after == null) return VersionConstraint.empty; @@ -379,11 +422,36 @@ class VersionRange implements Comparable, VersionConstraint { if (max != null) { if (min != null) buffer.write(' '); - buffer.write(includeMax ? '<=' : '<'); - buffer.write(max); + if (includeMax) { + buffer.write('<='); + buffer.write(max); + } else { + buffer.write('<'); + if (max.isFirstPreRelease) { + // Since `"<$max"` would parse the same as `"<$max-0"`, we just emit + // `<$max` to avoid confusing "-0" suffixes. + buffer.write("${max.major}.${max.minor}.${max.patch}"); + } else { + buffer.write(max); + + // If `">=$min <$max"` would parse as `">=$min <$max-0"`, add `-*` to + // indicate that actually does allow pre-release versions. + var minIsPreReleaseOfMax = min != null && + min.isPreRelease && + equalsWithoutPreRelease(min, max); + if (!max.isPreRelease && !minIsPreReleaseOfMax) buffer.write("-∞"); + } + } } if (min == null && max == null) buffer.write('any'); return buffer.toString(); } } + +class CompatibleWithVersionRange extends VersionRange { + CompatibleWithVersionRange(Version version) + : super._(version, version.nextBreaking.firstPreRelease, true, false); + + String toString() => '^$min'; +} diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 1b738d755..a537788f5 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.3.7 +version: 1.4.0 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index 9b28c6a22..8ecd8f5d6 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -22,6 +22,10 @@ final v234 = new Version.parse('2.3.4'); final v250 = new Version.parse('2.5.0'); final v300 = new Version.parse('3.0.0'); +/// A range that allows pre-release versions of its max version. +final includeMaxPreReleaseRange = + new VersionRange(max: v200, alwaysIncludeMaxPreRelease: true); + /// A [Matcher] that tests if a [VersionConstraint] allows or does not allow a /// given list of [Version]s. class _VersionConstraintMatcher implements Matcher { diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 63cf30257..4bdc21c92 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -14,7 +14,25 @@ main() { var range = new VersionRange(min: v123, max: v124); expect(range.isAny, isFalse); expect(range.min, equals(v123)); - expect(range.max, equals(v124)); + expect(range.max, equals(v124.firstPreRelease)); + }); + + group("doesn't make the max a pre-release if", () { + test("it's already a pre-release", () { + expect(new VersionRange(max: new Version.parse("1.2.4-pre")).max, + equals(new Version.parse("1.2.4-pre"))); + }); + + test("includeMax is true", () { + expect(new VersionRange(max: v124, includeMax: true).max, equals(v124)); + }); + + test("min is a prerelease of max", () { + expect( + new VersionRange(min: new Version.parse("1.2.4-pre"), max: v124) + .max, + equals(v124)); + }); }); test('allows omitting max', () { @@ -158,6 +176,10 @@ main() { expect(range, allows(new Version.parse('0.0.0'), new Version.parse('999.99.9'))); }); + + test('allows pre-releases of the max with includeMaxPreRelease', () { + expect(includeMaxPreReleaseRange, allows(new Version.parse('2.0.0-dev'))); + }); }); group('allowsAll()', () { @@ -247,6 +269,13 @@ main() { isFalse); }); + test('of non-pre-release max are included with includeMaxPreRelease', () { + expect( + includeMaxPreReleaseRange + .allowsAll(new VersionConstraint.parse('<2.0.0-dev')), + isTrue); + }); + test( 'of non-pre-release max are included if min is a pre-release of the ' 'same version', () { @@ -388,6 +417,13 @@ main() { isFalse); }); + test('of non-pre-release max are included with includeMaxPreRelease', () { + expect( + includeMaxPreReleaseRange + .allowsAny(new VersionConstraint.parse('>2.0.0-dev')), + isTrue); + }); + test( 'of non-pre-release max are included if min is a pre-release of the ' 'same version', () { @@ -419,15 +455,10 @@ main() { group('intersect()', () { test('two overlapping ranges', () { - var a = new VersionRange(min: v123, max: v250); - var b = new VersionRange(min: v200, max: v300); - var intersect = a.intersect(b); - expect(intersect, new isInstanceOf()); - var intersectRange = intersect as VersionRange; - expect(intersectRange.min, equals(v200)); - expect(intersectRange.max, equals(v250)); - expect(intersectRange.includeMin, isFalse); - expect(intersectRange.includeMax, isFalse); + expect( + new VersionRange(min: v123, max: v250) + .intersect(new VersionRange(min: v200, max: v300)), + equals(new VersionRange(min: v200, max: v250))); }); test('a non-overlapping range allows no versions', () { @@ -476,6 +507,48 @@ main() { .intersect(new VersionConstraint.parse("<2.0.0-dev")), equals(new VersionRange(max: v200))); }); + + group("with includeMaxPreRelease", () { + test('preserves includeMaxPreRelease if the max version is included', () { + expect( + includeMaxPreReleaseRange + .intersect(new VersionConstraint.parse("<1.0.0")), + equals(new VersionConstraint.parse("<1.0.0"))); + expect( + includeMaxPreReleaseRange + .intersect(new VersionConstraint.parse("<2.0.0")), + equals(new VersionConstraint.parse("<2.0.0"))); + expect(includeMaxPreReleaseRange.intersect(includeMaxPreReleaseRange), + equals(includeMaxPreReleaseRange)); + expect( + includeMaxPreReleaseRange + .intersect(new VersionConstraint.parse("<3.0.0")), + equals(includeMaxPreReleaseRange)); + expect( + includeMaxPreReleaseRange + .intersect(new VersionConstraint.parse(">1.1.4")), + equals(new VersionRange( + min: v114, max: v200, alwaysIncludeMaxPreRelease: true))); + }); + + test( + "and a range with a pre-release min, returns " + "an intersection", () { + expect( + includeMaxPreReleaseRange + .intersect(new VersionConstraint.parse(">=2.0.0-dev")), + equals(new VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); + }); + + test( + "and a range with a pre-release max, returns " + "the narrower constraint", () { + expect( + includeMaxPreReleaseRange + .intersect(new VersionConstraint.parse("<2.0.0-dev")), + equals(new VersionConstraint.parse("<2.0.0-dev"))); + }); + }); }); group('union()', () { @@ -485,7 +558,10 @@ main() { }); test("with a version on the edge of the range, expands the range", () { - expect(new VersionRange(min: v114, max: v124).union(v124), + expect( + new VersionRange( + min: v114, max: v124, alwaysIncludeMaxPreRelease: true) + .union(v124), equals(new VersionRange(min: v114, max: v124, includeMax: true))); expect(new VersionRange(min: v114, max: v124).union(v114), equals(new VersionRange(min: v114, max: v124, includeMin: true))); @@ -533,7 +609,8 @@ main() { .union(new VersionRange(min: v114, max: v200)); expect(result, equals(new VersionRange(min: v003, max: v200))); - result = new VersionRange(min: v003, max: v114) + result = new VersionRange( + min: v003, max: v114, alwaysIncludeMaxPreRelease: true) .union(new VersionRange(min: v114, max: v200, includeMin: true)); expect(result, equals(new VersionRange(min: v003, max: v200))); @@ -541,8 +618,9 @@ main() { .union(new VersionRange(min: v003, max: v114, includeMax: true)); expect(result, equals(new VersionRange(min: v003, max: v200))); - result = new VersionRange(min: v114, max: v200, includeMin: true) - .union(new VersionRange(min: v003, max: v114)); + result = new VersionRange(min: v114, max: v200, includeMin: true).union( + new VersionRange( + min: v003, max: v114, alwaysIncludeMaxPreRelease: true)); expect(result, equals(new VersionRange(min: v003, max: v200))); }); @@ -573,6 +651,39 @@ main() { .union(new VersionConstraint.parse("<2.0.0-dev")), equals(new VersionConstraint.parse("<2.0.0-dev"))); }); + + group("with includeMaxPreRelease", () { + test('adds includeMaxPreRelease if the max version is included', () { + expect( + includeMaxPreReleaseRange + .union(new VersionConstraint.parse("<1.0.0")), + equals(includeMaxPreReleaseRange)); + expect(includeMaxPreReleaseRange.union(includeMaxPreReleaseRange), + equals(includeMaxPreReleaseRange)); + expect( + includeMaxPreReleaseRange + .union(new VersionConstraint.parse("<2.0.0")), + equals(includeMaxPreReleaseRange)); + expect( + includeMaxPreReleaseRange + .union(new VersionConstraint.parse("<3.0.0")), + equals(new VersionConstraint.parse("<3.0.0"))); + }); + + test("and a range with a pre-release min, returns any", () { + expect( + includeMaxPreReleaseRange + .union(new VersionConstraint.parse(">=2.0.0-dev")), + equals(VersionConstraint.any)); + }); + + test("and a range with a pre-release max, returns the original", () { + expect( + includeMaxPreReleaseRange + .union(new VersionConstraint.parse("<2.0.0-dev")), + equals(includeMaxPreReleaseRange)); + }); + }); }); group('difference()', () { @@ -592,7 +703,8 @@ main() { expect( new VersionRange(min: v003, max: v114).difference(v072), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), + new VersionRange( + min: v003, max: v072, alwaysIncludeMaxPreRelease: true), new VersionRange(min: v072, max: v114) ]))); }); @@ -601,7 +713,8 @@ main() { expect( new VersionRange(min: v003, max: v114, includeMax: true) .difference(v114), - equals(new VersionRange(min: v003, max: v114))); + equals(new VersionRange( + min: v003, max: v114, alwaysIncludeMaxPreRelease: true))); }); test("with the min version makes the min exclusive", () { @@ -630,11 +743,11 @@ main() { expect( new VersionRange(min: v080, max: v130) .difference(new VersionRange(min: v010, max: v114)), - equals(new VersionRange(min: v114, max: v130, includeMin: true))); + equals(new VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); expect( new VersionRange(min: v080, max: v130) .difference(new VersionRange(max: v114)), - equals(new VersionRange(min: v114, max: v130, includeMin: true))); + equals(new VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); expect( new VersionRange(min: v080, max: v130).difference( new VersionRange(min: v010, max: v114, includeMax: true)), @@ -646,7 +759,7 @@ main() { expect( new VersionRange(min: v080, max: v130, includeMax: true) .difference(new VersionRange(min: v080, max: v130)), - equals(v130)); + equals(new VersionConstraint.parse(">=1.3.0-0 <=1.3.0"))); }); test("with a range at the end cuts off the end of the range", () { @@ -661,11 +774,13 @@ main() { expect( new VersionRange(min: v080, max: v130).difference( new VersionRange(min: v114, max: v140, includeMin: true)), - equals(new VersionRange(min: v080, max: v114))); + equals(new VersionRange( + min: v080, max: v114, alwaysIncludeMaxPreRelease: true))); expect( new VersionRange(min: v080, max: v130, includeMax: true).difference( new VersionRange(min: v130, max: v140, includeMin: true)), - equals(new VersionRange(min: v080, max: v130))); + equals(new VersionRange( + min: v080, max: v130, alwaysIncludeMaxPreRelease: true))); expect( new VersionRange(min: v080, max: v130, includeMin: true) .difference(new VersionRange(min: v080, max: v130)), @@ -678,7 +793,7 @@ main() { .difference(new VersionRange(min: v072, max: v114)), equals(new VersionConstraint.unionOf([ new VersionRange(min: v003, max: v072, includeMax: true), - new VersionRange(min: v114, max: v130, includeMin: true) + new VersionConstraint.parse(">=1.1.4-0 <1.3.0") ]))); }); @@ -715,8 +830,7 @@ main() { new VersionRange(min: v080, max: v123), new VersionRange(min: v130, max: v200) ])), - equals(new VersionRange( - min: v123, max: v130, includeMin: true, includeMax: true))); + equals(new VersionConstraint.parse(">=1.2.3-0 <=1.3.0"))); }); test("with a version union that intersects the middle, chops it up", () { @@ -724,9 +838,12 @@ main() { new VersionRange(min: v114, max: v140) .difference(new VersionConstraint.unionOf([v123, v124, v130])), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v114, max: v123), - new VersionRange(min: v123, max: v124), - new VersionRange(min: v124, max: v130), + new VersionRange( + min: v114, max: v123, alwaysIncludeMaxPreRelease: true), + new VersionRange( + min: v123, max: v124, alwaysIncludeMaxPreRelease: true), + new VersionRange( + min: v124, max: v130, alwaysIncludeMaxPreRelease: true), new VersionRange(min: v130, max: v140) ]))); }); @@ -752,6 +869,84 @@ main() { .difference(new VersionConstraint.parse("<2.0.0-dev")), equals(VersionConstraint.empty)); }); + + group("with includeMaxPreRelease", () { + group("for the minuend", () { + test("preserves includeMaxPreRelease if the max version is included", + () { + expect( + includeMaxPreReleaseRange + .difference(new VersionConstraint.parse("<1.0.0")), + equals(new VersionRange( + min: new Version.parse("1.0.0-0"), + max: v200, + includeMin: true, + alwaysIncludeMaxPreRelease: true))); + expect( + includeMaxPreReleaseRange + .difference(new VersionConstraint.parse("<2.0.0")), + equals(new VersionRange( + min: v200.firstPreRelease, + max: v200, + includeMin: true, + alwaysIncludeMaxPreRelease: true))); + expect( + includeMaxPreReleaseRange.difference(includeMaxPreReleaseRange), + equals(VersionConstraint.empty)); + expect( + includeMaxPreReleaseRange + .difference(new VersionConstraint.parse("<3.0.0")), + equals(VersionConstraint.empty)); + }); + + test("with a range with a pre-release min, adjusts the max", () { + expect( + includeMaxPreReleaseRange + .difference(new VersionConstraint.parse(">=2.0.0-dev")), + equals(new VersionConstraint.parse("<2.0.0-dev"))); + }); + + test("with a range with a pre-release max, adjusts the min", () { + expect( + includeMaxPreReleaseRange + .difference(new VersionConstraint.parse("<2.0.0-dev")), + equals(new VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); + }); + }); + + group("for the subtrahend", () { + group("doesn't create a pre-release minimum", () { + test("when cutting off the bottom", () { + expect( + new VersionConstraint.parse("<3.0.0") + .difference(includeMaxPreReleaseRange), + equals( + new VersionRange(min: v200, max: v300, includeMin: true))); + }); + + test("with splitting down the middle", () { + expect( + new VersionConstraint.parse("<4.0.0").difference( + new VersionRange( + min: v200, + max: v300, + includeMin: true, + alwaysIncludeMaxPreRelease: true)), + equals(new VersionConstraint.unionOf([ + new VersionRange(max: v200, alwaysIncludeMaxPreRelease: true), + new VersionConstraint.parse(">=3.0.0 <4.0.0") + ]))); + }); + + test("can leave a single version", () { + expect( + new VersionConstraint.parse("<=2.0.0") + .difference(includeMaxPreReleaseRange), + equals(v200)); + }); + }); + }); + }); }); test('isEmpty', () { @@ -786,6 +981,11 @@ main() { new VersionRange(min: v003, max: v080, includeMax: true)); }); + test("includeMaxPreRelease comes after !includeMaxPreRelease", () { + _expectComparesSmaller( + new VersionRange(max: v200), includeMaxPreReleaseRange); + }); + test("no minimum comes before small minimum", () { _expectComparesSmaller( new VersionRange(max: v010), new VersionRange(min: v003, max: v010)); diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index fc6dfef33..448435a57 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -190,8 +190,14 @@ main() { }); test("with a range with the version on the edge, expands the range", () { - expect(v124.union(new VersionRange(min: v114, max: v124)), + expect( + v124.union(new VersionRange( + min: v114, max: v124, alwaysIncludeMaxPreRelease: true)), equals(new VersionRange(min: v114, max: v124, includeMax: true))); + expect( + v124.firstPreRelease.union(new VersionRange(min: v114, max: v124)), + equals(new VersionRange( + min: v114, max: v124.firstPreRelease, includeMax: true))); expect(v114.union(new VersionRange(min: v114, max: v124)), equals(new VersionRange(min: v114, max: v124, includeMin: true))); }); diff --git a/pkgs/pub_semver/test/version_union_test.dart b/pkgs/pub_semver/test/version_union_test.dart index f94883294..f629c83d4 100644 --- a/pkgs/pub_semver/test/version_union_test.dart +++ b/pkgs/pub_semver/test/version_union_test.dart @@ -101,25 +101,32 @@ main() { new VersionConstraint.unionOf([ new VersionRange(min: v003, max: v072, includeMax: true), new VersionRange(min: v072, max: v080), - new VersionRange(min: v114, max: v124), - new VersionRange(min: v124, max: v130, includeMin: true) + new VersionRange( + min: v114, max: v124, alwaysIncludeMaxPreRelease: true), + new VersionRange(min: v124, max: v130, includeMin: true), + new VersionRange( + min: v130.firstPreRelease, max: v200, includeMin: true) ]), equals(new VersionConstraint.unionOf([ new VersionRange(min: v003, max: v080), - new VersionRange(min: v114, max: v130) + new VersionRange(min: v114, max: v200) ]))); }); test("doesn't merge not-quite-adjacent ranges", () { expect( new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v072, max: v080) + new VersionRange(min: v114, max: v124), + new VersionRange(min: v124, max: v130, includeMin: true) ]), - equals(new VersionConstraint.unionOf([ + isNot(equals(new VersionRange(min: v114, max: v130)))); + + expect( + new VersionConstraint.unionOf([ new VersionRange(min: v003, max: v072), new VersionRange(min: v072, max: v080) - ]))); + ]), + isNot(equals(new VersionRange(min: v003, max: v080)))); }); test("merges version numbers into ranges", () { @@ -139,16 +146,30 @@ main() { test("merges adjacent version numbers into ranges", () { expect( new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), + new VersionRange( + min: v003, max: v072, alwaysIncludeMaxPreRelease: true), v072, v114, - new VersionRange(min: v114, max: v124) + new VersionRange(min: v114, max: v124), + v124.firstPreRelease ]), equals(new VersionConstraint.unionOf([ new VersionRange(min: v003, max: v072, includeMax: true), - new VersionRange(min: v114, max: v124, includeMin: true) + new VersionRange( + min: v114, + max: v124.firstPreRelease, + includeMin: true, + includeMax: true) ]))); }); + + test("doesn't merge not-quite-adjacent version numbers into ranges", () { + expect( + new VersionConstraint.unionOf( + [new VersionRange(min: v003, max: v072), v072]), + isNot(equals( + new VersionRange(min: v003, max: v072, includeMax: true)))); + }); }); test('isEmpty returns false', () { @@ -424,7 +445,8 @@ main() { new VersionRange(min: v124) ])), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080, includeMin: true), + new VersionRange( + min: v072.firstPreRelease, max: v080, includeMin: true), new VersionRange(min: v123, max: v124, includeMax: true) ]))); }); @@ -436,8 +458,10 @@ main() { new VersionRange(min: v130, max: v200) ]).difference(new VersionConstraint.unionOf([v072, v080])), equals(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v072, max: v080), + new VersionRange( + min: v010, max: v072, alwaysIncludeMaxPreRelease: true), + new VersionRange( + min: v072, max: v080, alwaysIncludeMaxPreRelease: true), new VersionRange(min: v080, max: v114), new VersionRange(min: v130, max: v200) ]))); @@ -455,7 +479,8 @@ main() { equals(new VersionConstraint.unionOf([ new VersionRange(min: v010, max: v072), new VersionRange(min: v080, max: v114, includeMax: true), - new VersionRange(min: v201, max: v234, includeMin: true), + new VersionRange( + min: v201.firstPreRelease, max: v234, includeMin: true), new VersionRange(min: v250, max: v300) ]))); }); From ab3e3dd6e8e6b92f468914aacdb9646955fee315 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 1 May 2018 18:28:37 -0700 Subject: [PATCH 236/657] Fix a bug with build identifiers (dart-lang/pub_semver#29) --- pkgs/pub_semver/CHANGELOG.md | 5 +++++ pkgs/pub_semver/lib/src/version_range.dart | 5 ++++- pkgs/pub_semver/test/version_range_test.dart | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 0efa0ea7b..78865c886 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.4.1 + +* Fix a bug where there upper bound of a version range with a build identifier + could accidentally be rewritten. + # 1.4.0 * Add a `Version.firstPreRelease` getter that returns the first possible diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 99dc7189d..a566891ea 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -72,6 +72,7 @@ class VersionRange implements Comparable, VersionConstraint { !includeMax && max != null && !max.isPreRelease && + max.build.isEmpty && (min == null || !min.isPreRelease || !equalsWithoutPreRelease(min, max))) { @@ -439,7 +440,9 @@ class VersionRange implements Comparable, VersionConstraint { var minIsPreReleaseOfMax = min != null && min.isPreRelease && equalsWithoutPreRelease(min, max); - if (!max.isPreRelease && !minIsPreReleaseOfMax) buffer.write("-∞"); + if (!max.isPreRelease && max.build.isEmpty && !minIsPreReleaseOfMax) { + buffer.write("-∞"); + } } } } diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 4bdc21c92..a24faaea7 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -33,6 +33,11 @@ main() { .max, equals(v124)); }); + + test("max has a build identifier", () { + expect(new VersionRange(max: new Version.parse("1.2.4+1")).max, + equals(new Version.parse("1.2.4+1"))); + }); }); test('allows omitting max', () { From 98f32005dc4faf3e0534232817129a4ecb759fec Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 2 May 2018 13:00:56 -0700 Subject: [PATCH 237/657] Increase the pubspec version (dart-lang/pub_semver#30) I meant to do this in the last PR. --- pkgs/pub_semver/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index a537788f5..ec526bf89 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.4.0 +version: 1.4.1 author: Dart Team description: > Versions and version constraints implementing pub's versioning policy. This From 67cb71299015780b813612862109596ee0a6243b Mon Sep 17 00:00:00 2001 From: BC Ko Date: Thu, 24 May 2018 02:56:36 -0700 Subject: [PATCH 238/657] Update .gitignore to new `dart_tool` pub cache dart-lang/sdkdart-lang/source_span#32030 --- pkgs/source_span/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/source_span/.gitignore b/pkgs/source_span/.gitignore index 7dbf0350d..ab3cb76e6 100644 --- a/pkgs/source_span/.gitignore +++ b/pkgs/source_span/.gitignore @@ -1,5 +1,6 @@ # Don’t commit the following directories created by pub. .buildlog +.dart_tool/ .pub/ build/ packages @@ -12,4 +13,4 @@ packages *.js.map # Include when developing application packages. -pubspec.lock \ No newline at end of file +pubspec.lock From 239cd166346c69646d9f5f723fbe10d638db458c Mon Sep 17 00:00:00 2001 From: BC Ko Date: Thu, 24 May 2018 09:04:38 -0700 Subject: [PATCH 239/657] Update .gitignore to new `dart_tool` pub cache (dart-lang/pool#14) dart-lang/sdkdart-lang/pool#32030 --- pkgs/pool/.gitignore | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/pkgs/pool/.gitignore b/pkgs/pool/.gitignore index 7dbf0350d..e450c836d 100644 --- a/pkgs/pool/.gitignore +++ b/pkgs/pool/.gitignore @@ -1,15 +1,5 @@ # Don’t commit the following directories created by pub. -.buildlog -.pub/ -build/ -packages +.dart_tool/ .packages - -# Or the files created by dart2js. -*.dart.js -*.js_ -*.js.deps -*.js.map - -# Include when developing application packages. -pubspec.lock \ No newline at end of file +.pub/ +pubspec.lock From 27c6f125ca91786281541e1e9b60fe7070995dc6 Mon Sep 17 00:00:00 2001 From: BC Ko Date: Thu, 24 May 2018 09:05:30 -0700 Subject: [PATCH 240/657] Update .gitignore to new `dart_tool` pub cache (dart-lang/pub_semver#31) dart-lang/sdkdart-lang/pub_semver#32030 --- pkgs/pub_semver/.gitignore | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkgs/pub_semver/.gitignore b/pkgs/pub_semver/.gitignore index 98fed01aa..49ce72d76 100644 --- a/pkgs/pub_semver/.gitignore +++ b/pkgs/pub_semver/.gitignore @@ -1,6 +1,3 @@ +.dart_tool/ .packages -packages pubspec.lock - -# IntelliJ project. -.idea From fbf2d23870bf1e2c417e0e41bcabce7a2c4bcf57 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 25 May 2018 14:03:44 +0200 Subject: [PATCH 241/657] Remove upper case constants (dart-lang/source_maps#27) * Remove usage of upper-case constants. * update SDK version * remove stable from Travis config --- pkgs/source_maps/.travis.yml | 2 -- pkgs/source_maps/CHANGELOG.md | 1 + pkgs/source_maps/lib/builder.dart | 2 +- pkgs/source_maps/lib/parser.dart | 4 ++-- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/builder_test.dart | 2 +- pkgs/source_maps/test/parser_test.dart | 10 +++++----- pkgs/source_maps/test/printer_test.dart | 6 +++--- 8 files changed, 14 insertions(+), 15 deletions(-) diff --git a/pkgs/source_maps/.travis.yml b/pkgs/source_maps/.travis.yml index 25aeabec0..a49fc6ff0 100644 --- a/pkgs/source_maps/.travis.yml +++ b/pkgs/source_maps/.travis.yml @@ -2,8 +2,6 @@ language: dart dart: - dev - - stable - dart_task: - test: -p vm,chrome - dartanalyzer diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 8ef25be0e..9a0879cb5 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -9,6 +9,7 @@ ## 0.10.4 * Implement `highlight` in `SourceMapFileSpan`. * Require version `^1.3.0` of `source_span`. +* Require version 2.0.0 of the Dart SDK. ## 0.10.3 * Add `addMapping` and `containsMapping` members to `MappingBundle`. diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index cdba2d2dc..0769d5052 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -55,7 +55,7 @@ class SourceMapBuilder { } /// Encodes all mappings added to this builder as a json string. - String toJson(String fileUrl) => JSON.encode(build(fileUrl)); + String toJson(String fileUrl) => jsonEncode(build(fileUrl)); } /// An entry in the source map builder. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index e46b78341..a500b13ec 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -24,7 +24,7 @@ import 'src/vlq.dart'; // TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string // `)]}'` begins the string representation of the map. Mapping parse(String jsonMap, {Map otherMaps, mapUrl}) => - parseJson(JSON.decode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); + parseJson(jsonDecode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); /// Parses a source map or source map bundle directly from a json string. /// @@ -32,7 +32,7 @@ Mapping parse(String jsonMap, {Map otherMaps, mapUrl}) => /// the source map file itself. If it's passed, any URLs in the source /// map will be interpreted as relative to this URL when generating spans. Mapping parseExtended(String jsonMap, {Map otherMaps, mapUrl}) => - parseJsonExtended(JSON.decode(jsonMap), + parseJsonExtended(jsonDecode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); /// Parses a source map or source map bundle. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 7bf7bcd26..8598aefea 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -6,6 +6,6 @@ homepage: http://github.com/dart-lang/source_maps dependencies: source_span: ^1.3.0 environment: - sdk: '>=1.8.0 <2.0.0' + sdk: '>=2.0.0-dev.17.0 <2.0.0' dev_dependencies: test: '>=0.12.0 <0.13.0' diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index 7c27e4e17..1e2efdd5c 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -27,6 +27,6 @@ main() { ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') ..addLocation(inputExpr.start, outputExpr.start, null)) .toJson(output.url.toString()); - expect(str, JSON.encode(EXPECTED_MAP)); + expect(str, jsonEncode(EXPECTED_MAP)); }); } diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 78963418f..398a40eb3 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -80,7 +80,7 @@ main() { }); test('parse + json', () { - var mapping = parse(JSON.encode(EXPECTED_MAP)); + var mapping = parse(jsonEncode(EXPECTED_MAP)); check(outputVar1, mapping, inputVar1, false); check(outputVar2, mapping, inputVar2, false); check(outputFunction, mapping, inputFunction, false); @@ -96,7 +96,7 @@ main() { }); test('parse with no source location', () { - SingleMapping map = parse(JSON.encode(MAP_WITH_NO_SOURCE_LOCATION)); + SingleMapping map = parse(jsonEncode(MAP_WITH_NO_SOURCE_LOCATION)); expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); TargetEntry entry = map.lines.first.entries.first; @@ -109,7 +109,7 @@ main() { }); test('parse with source location and no name', () { - SingleMapping map = parse(JSON.encode(MAP_WITH_SOURCE_LOCATION)); + SingleMapping map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION)); expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); TargetEntry entry = map.lines.first.entries.first; @@ -122,7 +122,7 @@ main() { }); test('parse with source location and name', () { - SingleMapping map = parse(JSON.encode(MAP_WITH_SOURCE_LOCATION_AND_NAME)); + SingleMapping map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_NAME)); expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); TargetEntry entry = map.lines.first.entries.first; @@ -251,7 +251,7 @@ main() { }); test('parseExtended', () { - var mapping = parseExtended(JSON.encode(SOURCE_MAP_BUNDLE), + var mapping = parseExtended(jsonEncode(SOURCE_MAP_BUNDLE), mapUrl: "file:///path/to/map"); expect(mapping.spanFor(0, 0, uri: "output.dart").sourceUrl, diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index 3fd768d8c..32db69565 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -24,7 +24,7 @@ main() { ..mark(inputExpr) ..add('x + y;\n'); expect(printer.text, OUTPUT); - expect(printer.map, JSON.encode(EXPECTED_MAP)); + expect(printer.map, jsonEncode(EXPECTED_MAP)); }); test('printer projecting marks', () { @@ -93,7 +93,7 @@ main() { ..add('x + y;\n', span: inputExpr) ..build('output.dart'); expect(printer.text, OUTPUT); - expect(printer.map, JSON.encode(EXPECTED_MAP)); + expect(printer.map, jsonEncode(EXPECTED_MAP)); }); test('nested use', () { @@ -106,7 +106,7 @@ main() { ..add('x + y;\n', span: inputExpr) ..build('output.dart'); expect(printer.text, OUTPUT); - expect(printer.map, JSON.encode(EXPECTED_MAP)); + expect(printer.map, jsonEncode(EXPECTED_MAP)); }); test('add indentation', () { From c15609e86734c64496bee259b55510bb214c3648 Mon Sep 17 00:00:00 2001 From: pq Date: Thu, 21 Jun 2018 10:50:26 -0700 Subject: [PATCH 242/657] core api use migrations --- pkgs/package_config/lib/packages_file.dart | 7 ++----- pkgs/package_config/lib/src/packages_impl.dart | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 0f1a6e635..85de1942d 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -159,12 +159,12 @@ Uri _relativize(Uri uri, Uri baseUri) { } } - baseUri = _normalizePath(baseUri); + baseUri = baseUri.normalizePath(); List base = baseUri.pathSegments.toList(); if (base.isNotEmpty) { base = new List.from(base)..removeLast(); } - uri = _normalizePath(uri); + uri = uri.normalizePath(); List target = uri.pathSegments.toList(); if (target.isNotEmpty && target.last.isEmpty) target.removeLast(); int index = 0; @@ -186,6 +186,3 @@ Uri _relativize(Uri uri, Uri baseUri) { return uri; } } - -// TODO: inline to uri.normalizePath() when we move to 1.11 -Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index df89e4623..e89d94d22 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -23,7 +23,7 @@ class NoPackages implements Packages { packageUri, "packageUri", 'No package named "$packageName"'); } - Iterable get packages => new Iterable.generate(0); + Iterable get packages => new Iterable.empty(); Map asMap() => const {}; } @@ -34,7 +34,7 @@ class NoPackages implements Packages { /// member abstract class PackagesBase implements Packages { Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { - packageUri = _normalizePath(packageUri); + packageUri = packageUri.normalizePath(); String packageName = checkValidPackageUri(packageUri); Uri packageBase = getBase(packageName); if (packageBase == null) { @@ -51,9 +51,6 @@ abstract class PackagesBase implements Packages { /// Returns `null` if no package exists with that name, and that can be /// determined. Uri getBase(String packageName); - - // TODO: inline to uri.normalizePath() when we move to 1.11 - static Uri _normalizePath(Uri uri) => new Uri().resolveUri(uri); } /// A [Packages] implementation based on an existing map. From 0ef6277d76402930b87be453b9b2bb7db2d6dd12 Mon Sep 17 00:00:00 2001 From: pq Date: Thu, 21 Jun 2018 14:01:44 -0700 Subject: [PATCH 243/657] dart2 --- pkgs/package_config/pubspec.yaml | 4 ++-- pkgs/package_config/test/discovery_test.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index bd2c6abaf..56d44f5ff 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -5,11 +5,11 @@ author: Dart Team homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=1.11.0 <2.0.0' + sdk: '>=2.0.0-dev <2.0.0' dependencies: charcode: ^1.1.0 path: ^1.0.0 dev_dependencies: - test: ^0.12.0 + test: ^1.0.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 6a5bcdee9..2c60db389 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -289,7 +289,7 @@ void httpTest(String name, Map description, Future httpTest(Uri directory)) { if (path.startsWith('/')) path = path.substring(1); if (path.endsWith('/')) path = path.substring(0, path.length - 1); var parts = path.split('/'); - var fileOrDir = description; + dynamic fileOrDir = description; for (int i = 0; i < parts.length; i++) { fileOrDir = fileOrDir[parts[i]]; if (fileOrDir == null) { From 8785d418144ccd4efa2525375f91286c9acf0300 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 21 Jun 2018 14:05:58 -0700 Subject: [PATCH 244/657] Update .travis.yml --- pkgs/package_config/.travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml index 24d56a3aa..655bf3dc1 100644 --- a/pkgs/package_config/.travis.yml +++ b/pkgs/package_config/.travis.yml @@ -2,7 +2,6 @@ language: dart sudo: false dart: - dev - - stable dart_task: - test - dartfmt From cbca72365e0805712a3742f2a5d906a43bf3cbc1 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 22 Jun 2018 09:38:36 -0700 Subject: [PATCH 245/657] misc(test): update dev dependencies, fix deprecations (dart-lang/pool#16) --- pkgs/pool/pubspec.yaml | 13 ++++++++----- pkgs/pool/test/pool_test.dart | 14 +++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index a628ec617..e10dadfdd 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,13 +1,16 @@ name: pool -version: 1.3.5 +version: 1.3.6-dev author: Dart Team description: A class for managing a finite pool of resources. homepage: https://github.com/dart-lang/pool + +environment: + sdk: ">=2.0.0-dev.17.0 <2.0.0" + dependencies: async: ">=1.4.0 <3.0.0" stack_trace: ">=0.9.2 <2.0.0" -environment: - sdk: ">=2.0.0-dev.17.0 <2.0.0" + dev_dependencies: - fake_async: ">=0.1.0 <0.2.0" - test: ">=0.12.0 <0.13.0" + fake_async: ^1.0.0 + test: ^1.0.0 diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index d0e70170e..cb0dd3009 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -55,7 +55,7 @@ void main() { test("can be called freely up to the limit", () { var pool = new Pool(50); for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync(() => new Completer().future)); + pool.withResource(expectAsync0(() => new Completer().future)); } }); @@ -63,7 +63,7 @@ void main() { new FakeAsync().run((async) { var pool = new Pool(50); for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync(() => new Completer().future)); + pool.withResource(expectAsync0(() => new Completer().future)); } pool.withResource(expectNoAsync()); @@ -75,7 +75,7 @@ void main() { new FakeAsync().run((async) { var pool = new Pool(50); for (var i = 0; i < 49; i++) { - pool.withResource(expectAsync(() => new Completer().future)); + pool.withResource(expectAsync0(() => new Completer().future)); } var completer = new Completer(); @@ -100,7 +100,7 @@ void main() { // Regression test for #3. test("can be called immediately before close()", () async { var pool = new Pool(1); - pool.withResource(expectAsync(() {})); + pool.withResource(expectAsync0(() {})); await pool.close(); }); }); @@ -160,7 +160,7 @@ void main() { for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } - expect(pool.request(), throwsA(new isInstanceOf())); + expect(pool.request(), throwsA(new TypeMatcher())); async.elapse(new Duration(seconds: 6)); }); @@ -270,7 +270,7 @@ void main() { var innerZone = Zone.current; expect(innerZone, isNot(equals(outerZone))); - resource.allowRelease(expectAsync(() { + resource.allowRelease(expectAsync0(() { expect(Zone.current, equals(innerZone)); })); }); @@ -450,7 +450,7 @@ Function expectNoAsync() { /// /// This should only be called within a [FakeAsync.run] zone. Matcher get doesNotComplete => predicate((future) { - expect(future, new isInstanceOf()); + expect(future, new TypeMatcher()); var stack = new Trace.current(1); future.then((_) => registerException( From 6245184d74c916adebe2cc602579ef5bac76adcc Mon Sep 17 00:00:00 2001 From: sigmundch Date: Tue, 26 Jun 2018 16:30:07 -0700 Subject: [PATCH 246/657] Prepare to publish 0.10.6 (dart-lang/source_maps#29) --- pkgs/source_maps/CHANGELOG.md | 5 ++++- pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 9a0879cb5..d8ee77a61 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.6 + +* Require version 2.0.0 of the Dart SDK. + ## 0.10.5 * Add a `SingleMapping.files` field which provides access to `SourceFile`s @@ -9,7 +13,6 @@ ## 0.10.4 * Implement `highlight` in `SourceMapFileSpan`. * Require version `^1.3.0` of `source_span`. -* Require version 2.0.0 of the Dart SDK. ## 0.10.3 * Add `addMapping` and `containsMapping` members to `MappingBundle`. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 8598aefea..2c70f6b59 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.5 +version: 0.10.6 author: Dart Team description: Library to programmatically manipulate source map files. homepage: http://github.com/dart-lang/source_maps From ae24ecbe7ee7ca69bd52af8f519c371a63631585 Mon Sep 17 00:00:00 2001 From: pq Date: Mon, 2 Jul 2018 16:27:38 -0700 Subject: [PATCH 247/657] Remove `strong`. --- pkgs/package_config/analysis_options.yaml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 pkgs/package_config/analysis_options.yaml diff --git a/pkgs/package_config/analysis_options.yaml b/pkgs/package_config/analysis_options.yaml deleted file mode 100644 index a10d4c5a0..000000000 --- a/pkgs/package_config/analysis_options.yaml +++ /dev/null @@ -1,2 +0,0 @@ -analyzer: - strong-mode: true From 38f80e287fceeba4b135076c6a76f8a5cc160140 Mon Sep 17 00:00:00 2001 From: Aske Simon Christensen Date: Fri, 6 Jul 2018 22:15:15 +0200 Subject: [PATCH 248/657] Avoid uninitialized final fields. (dart-lang/source_span#22) --- pkgs/source_span/lib/src/span.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 599d66806..ff5c4b0dc 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -8,22 +8,22 @@ import 'span_mixin.dart'; /// A class that describes a segment of source text. abstract class SourceSpan implements Comparable { /// The start location of this span. - final SourceLocation start; + SourceLocation get start; /// The end location of this span, exclusive. - final SourceLocation end; + SourceLocation get end; /// The source text for this span. - final String text; + String get text; /// The URL of the source (typically a file) of this span. /// /// This may be null, indicating that the source URL is unknown or /// unavailable. - final Uri sourceUrl; + Uri get sourceUrl; /// The length of this span, in characters. - final int length; + int get length; /// Creates a new span from [start] to [end] (exclusive) containing [text]. /// From 5e14a449fa4fabf99960ad7f3df0aab91a0a5b23 Mon Sep 17 00:00:00 2001 From: pq Date: Sat, 14 Jul 2018 08:16:37 -0700 Subject: [PATCH 249/657] bump sdk constraint to 3.0.0 --- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index a9ac0ec03..8c179c708 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.4 + +- Set max SDK version to <3.0.0. + ## 1.0.3 - Removed unneeded dependency constraint on SDK. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 56d44f5ff..c58468167 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,11 +1,11 @@ name: package_config -version: 1.0.3 +version: 1.0.4 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=2.0.0-dev <2.0.0' + sdk: '>=2.0.0-dev <3.0.0' dependencies: charcode: ^1.1.0 From e3efcb3400597b0bb9aa6dbea132680d5b4554e5 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Tue, 17 Jul 2018 13:11:37 -0400 Subject: [PATCH 250/657] chore: set max SDK version to <3.0.0 (dart-lang/source_maps#30) --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/analysis_options.yaml | 1 - pkgs/source_maps/pubspec.yaml | 14 +++++++++----- pkgs/source_maps/test/end2end_test.dart | 1 - 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index d8ee77a61..8411c74b5 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.7 + +* Set max SDK version to `<3.0.0`, and adjust other dependencies. + ## 0.10.6 * Require version 2.0.0 of the Dart SDK. diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml index a10d4c5a0..2e6cdca29 100644 --- a/pkgs/source_maps/analysis_options.yaml +++ b/pkgs/source_maps/analysis_options.yaml @@ -1,2 +1 @@ analyzer: - strong-mode: true diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 2c70f6b59..0f4980eac 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,11 +1,15 @@ name: source_maps -version: 0.10.6 -author: Dart Team +version: 0.10.7 + description: Library to programmatically manipulate source map files. +author: Dart Team homepage: http://github.com/dart-lang/source_maps + +environment: + sdk: '>=2.0.0-dev.17.0 <3.0.0' + dependencies: source_span: ^1.3.0 -environment: - sdk: '>=2.0.0-dev.17.0 <2.0.0' + dev_dependencies: - test: '>=0.12.0 <0.13.0' + test: ^1.2.0 diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index dd5bced00..1082c979b 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -111,7 +111,6 @@ main() { var printer = new Printer('output2.dart'); printer.mark(ispan(0, 0)); - bool first = true; var segments = INPUT.split('long'); expect(segments.length, 6); printer.add(segments[0], projectMarks: true); From cb0b2b16c733abc7e6c1d472da0f1ad18b9f326c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 18 Jul 2018 13:38:22 -0700 Subject: [PATCH 251/657] misc: fix usage of deprecated SDK constants (dart-lang/package_config#50) Also fixed usage of deprecated matcher classes --- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/lib/discovery.dart | 2 +- pkgs/package_config/pubspec.yaml | 4 ++-- pkgs/package_config/test/discovery_test.dart | 6 +++--- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 8c179c708..e802d7deb 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.5 + +- Fix usage of SDK constants. + ## 1.0.4 - Set max SDK version to <3.0.0. diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index 020d99a80..57584b682 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -211,7 +211,7 @@ Future> _httpGet(Uri uri) async { HttpClient client = new HttpClient(); HttpClientRequest request = await client.getUrl(uri); HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) { + if (response.statusCode != HttpStatus.ok) { throw new HttpException('${response.statusCode} ${response.reasonPhrase}', uri: uri); } diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index c58468167..4bad1cf52 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.0.4 +version: 1.0.5 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config @@ -12,4 +12,4 @@ dependencies: path: ^1.0.0 dev_dependencies: - test: ^1.0.0 + test: ^1.3.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 2c60db389..282427289 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -232,8 +232,8 @@ main() { Uri file = directory.resolve(".packages"); expect( loadPackagesFile(file), - throwsA(anyOf(new isInstanceOf(), - new isInstanceOf()))); + throwsA(anyOf(new TypeMatcher(), + new TypeMatcher()))); }); generalTest("loadPackagesFile syntax error", {".packages": "syntax error"}, @@ -280,7 +280,7 @@ void httpTest(String name, Map description, Future httpTest(Uri directory)) { var serverSub; var uri; setUp(() { - return HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) { + return HttpServer.bind(InternetAddress.loopbackIPv4, 0).then((server) { uri = new Uri( scheme: "http", host: "127.0.0.1", port: server.port, path: "/"); serverSub = server.listen((HttpRequest request) { From 4359f93cfec83b03e4141d63273929a36d948cfa Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 18 Jul 2018 16:50:44 -0400 Subject: [PATCH 252/657] chore: set max SDK version to <3.0.0 (dart-lang/source_span#23) --- pkgs/source_span/.analysis_options | 2 -- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/pubspec.yaml | 16 ++++++++++------ pkgs/source_span/test/file_test.dart | 8 ++++---- pkgs/source_span/test/highlight_test.dart | 15 +++++++++------ 5 files changed, 27 insertions(+), 18 deletions(-) delete mode 100644 pkgs/source_span/.analysis_options diff --git a/pkgs/source_span/.analysis_options b/pkgs/source_span/.analysis_options deleted file mode 100644 index a10d4c5a0..000000000 --- a/pkgs/source_span/.analysis_options +++ /dev/null @@ -1,2 +0,0 @@ -analyzer: - strong-mode: true diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 68eafaaef..53a700cf1 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.4.1 + +* Set max SDK version to `<3.0.0`, and adjust other dependencies. + # 1.4.0 * The `new SourceFile()` constructor is deprecated. This constructed a source diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 46e3d522e..1d5321007 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,16 @@ name: source_span -version: 1.4.0 -author: Dart Team +version: 1.4.1 + description: A library for identifying source spans and locations. +author: Dart Team homepage: https://github.com/dart-lang/source_span + +environment: + sdk: '>=1.8.0 <3.0.0' + dependencies: - charcode: '^1.0.0' + charcode: ^1.0.0 path: '>=1.2.0 <2.0.0' -environment: - sdk: '>=1.8.0 <2.0.0' + dev_dependencies: - test: '>=0.12.0 <0.13.0' + test: '>=0.12.0 <2.0.0' diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 3f02a8bd9..071f3f9d7 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -8,7 +8,7 @@ import 'package:source_span/source_span.dart'; main() { var file; setUp(() { - file = new SourceFile(""" + file = new SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop""", url: "foo.dart"); @@ -122,7 +122,7 @@ zip zap zop""", url: "foo.dart"); }); test("for span().expand() source URLs must match", () { - var other = new SourceFile(""" + var other = new SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop""", url: "bar.dart").span(10, 11); @@ -139,11 +139,11 @@ zip zap zop""", url: "bar.dart").span(10, 11); group("new SourceFile()", () { test("handles CRLF correctly", () { - expect(new SourceFile("foo\r\nbar").getLine(6), equals(1)); + expect(new SourceFile.fromString("foo\r\nbar").getLine(6), equals(1)); }); test("handles a lone CR correctly", () { - expect(new SourceFile("foo\rbar").getLine(5), equals(1)); + expect(new SourceFile.fromString("foo\rbar").getLine(5), equals(1)); }); }); diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 08d2e17c5..ac8334bd5 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -9,7 +9,7 @@ import 'package:source_span/src/colors.dart' as colors; main() { var file; setUp(() { - file = new SourceFile(""" + file = new SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop @@ -23,7 +23,7 @@ foo bar baz }); test("gracefully handles a missing source URL", () { - var span = new SourceFile("foo bar baz").span(4, 7); + var span = new SourceFile.fromString("foo bar baz").span(4, 7); expect(span.highlight(), equals(""" foo bar baz ^^^""")); @@ -55,26 +55,29 @@ zip zap zop test("works for a point span at the end of the file with no trailing newline", () { - file = new SourceFile("zip zap zop"); + file = new SourceFile.fromString("zip zap zop"); expect(file.location(11).pointSpan().highlight(), equals(""" zip zap zop ^""")); }); test("works for a point span in an empty file", () { - expect(new SourceFile("").location(0).pointSpan().highlight(), equals(""" + expect(new SourceFile.fromString("").location(0).pointSpan().highlight(), + equals(""" ^""")); }); test("works for a single-line file without a newline", () { - expect(new SourceFile("foo bar").span(0, 7).highlight(), equals(""" + expect( + new SourceFile.fromString("foo bar").span(0, 7).highlight(), equals(""" foo bar ^^^^^^^""")); }); test("emits tabs for tabs", () { - expect(new SourceFile(" \t \t\tfoo bar").span(5, 8).highlight(), equals(""" + expect(new SourceFile.fromString(" \t \t\tfoo bar").span(5, 8).highlight(), + equals(""" \t \t\tfoo bar \t \t\t^^^""")); }); From 7340a952a2afb228f16209b141745d178c04f8cb Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Thu, 19 Jul 2018 15:09:02 -0400 Subject: [PATCH 253/657] chore: set max SDK version to <3.0.0 (dart-lang/pub_semver#32) --- pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/analysis_options.yaml | 2 -- pkgs/pub_semver/pubspec.yaml | 16 ++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) delete mode 100644 pkgs/pub_semver/analysis_options.yaml diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 78865c886..f8feb2460 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.4.2 + +* Set max SDK version to `<3.0.0`. + # 1.4.1 * Fix a bug where there upper bound of a version range with a build identifier diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml deleted file mode 100644 index a10d4c5a0..000000000 --- a/pkgs/pub_semver/analysis_options.yaml +++ /dev/null @@ -1,2 +0,0 @@ -analyzer: - strong-mode: true diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index ec526bf89..56fa52bf8 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,13 +1,17 @@ name: pub_semver -version: 1.4.1 -author: Dart Team +version: 1.4.2 + description: > Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. +author: Dart Team homepage: http://github.com/dart-lang/pub_semver + +environment: + sdk: '>=1.0.0 <3.0.0' + dependencies: - collection: ">=0.9.0 <2.0.0" + collection: '>=0.9.0 <2.0.0' + dev_dependencies: - test: ">=0.12.0 <0.13.0" -environment: - sdk: ">=1.0.0 <2.0.0" + test: '>=0.12.0 <2.0.0' From 4469273f26aa8584f271769853b5335ac62a7a21 Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Fri, 20 Jul 2018 17:46:02 -0400 Subject: [PATCH 254/657] chore: set max SDK version to <3.0.0 (dart-lang/pool#17) --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/analysis_options.yaml | 2 -- pkgs/pool/pubspec.yaml | 11 ++++++----- 3 files changed, 10 insertions(+), 7 deletions(-) delete mode 100644 pkgs/pool/analysis_options.yaml diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 46d142fca..98805184a 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.6 + +* Set max SDK version to `<3.0.0`, and adjust other dependencies. + ## 1.3.5 - Updated SDK version to 2.0.0-dev.17.0 diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml deleted file mode 100644 index a10d4c5a0..000000000 --- a/pkgs/pool/analysis_options.yaml +++ /dev/null @@ -1,2 +0,0 @@ -analyzer: - strong-mode: true diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index e10dadfdd..84b97b236 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,15 +1,16 @@ name: pool -version: 1.3.6-dev -author: Dart Team +version: 1.3.6 + description: A class for managing a finite pool of resources. +author: Dart Team homepage: https://github.com/dart-lang/pool environment: - sdk: ">=2.0.0-dev.17.0 <2.0.0" + sdk: '>=2.0.0-dev.17.0 <3.0.0' dependencies: - async: ">=1.4.0 <3.0.0" - stack_trace: ">=0.9.2 <2.0.0" + async: '>=1.4.0 <3.0.0' + stack_trace: '>=0.9.2 <2.0.0' dev_dependencies: fake_async: ^1.0.0 From 1585cde93b0bb1463b0ed3fdfb287ba847c184db Mon Sep 17 00:00:00 2001 From: Patrice Chalin Date: Wed, 25 Jul 2018 19:30:26 -0400 Subject: [PATCH 255/657] Don't test under 1.21.1 (dart-lang/pub_semver#33) Context: https://github.com/dart-lang/pub_semver/commit/c8859a59688e71fb9d3a2a966340fbfaf45f6239#r29835939 --- pkgs/pub_semver/.travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/pub_semver/.travis.yml b/pkgs/pub_semver/.travis.yml index 6788deead..c65407225 100644 --- a/pkgs/pub_semver/.travis.yml +++ b/pkgs/pub_semver/.travis.yml @@ -3,7 +3,6 @@ sudo: false dart: - dev - stable - - 1.21.1 dart_task: - test From 1c0a9842c8ad9c4632273053d056729d1cf8ed87 Mon Sep 17 00:00:00 2001 From: sigmundch Date: Thu, 27 Sep 2018 16:30:13 -0700 Subject: [PATCH 256/657] Preserve source-map extensions in SingleMapping (dart-lang/source_maps#31) * Preserve source-map extensions in SingleMapping * include test that extensions are preserved --- pkgs/source_maps/CHANGELOG.md | 5 +++++ pkgs/source_maps/lib/parser.dart | 13 +++++++++++-- pkgs/source_maps/pubspec.yaml | 2 +- pkgs/source_maps/test/parser_test.dart | 10 ++++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 8411c74b5..af62d9460 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.8 + +* Preserve source-map extensions in `SingleMapping`. Extensions are keys in the + json map that start with `"x_"`. + ## 0.10.7 * Set max SDK version to `<3.0.0`, and adjust other dependencies. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index a500b13ec..7fe45654f 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -278,8 +278,11 @@ class SingleMapping extends Mapping { final Uri _mapUrl; + final Map extensions; + SingleMapping._(this.targetUrl, this.files, this.urls, this.names, this.lines) - : _mapUrl = null; + : _mapUrl = null, + extensions = {}; factory SingleMapping.fromEntries(Iterable entries, [String fileUrl]) { @@ -341,7 +344,8 @@ class SingleMapping extends Mapping { files = new List(map['sources'].length), sourceRoot = map['sourceRoot'], lines = [], - _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl { + _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl, + extensions = {} { var sourcesContent = map['sourcesContent'] == null ? const [] : new List.from(map['sourcesContent']); @@ -414,6 +418,10 @@ class SingleMapping extends Mapping { if (!entries.isEmpty) { lines.add(new TargetLineEntry(line, entries)); } + + map.forEach((name, value) { + if (name.startsWith("x_")) extensions[name] = value; + }); } /// Encodes the Mapping mappings as a json map. @@ -471,6 +479,7 @@ class SingleMapping extends Mapping { if (includeSourceContents) { result['sourcesContent'] = files.map((file) => file?.getText(0)).toList(); } + extensions.forEach((name, value) => result[name] = value); return result; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 0f4980eac..49ab53da1 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.7 +version: 0.10.8 description: Library to programmatically manipulate source map files. author: Dart Team diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 398a40eb3..390184292 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -342,6 +342,16 @@ main() { expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); }); + test('parse extensions', () { + var map = new Map.from(EXPECTED_MAP); + map["x_foo"] = "a"; + map["x_bar"] = [3]; + SingleMapping mapping = parseJson(map); + expect(mapping.toJson(), equals(map)); + expect(mapping.extensions["x_foo"], equals("a")); + expect(mapping.extensions["x_bar"].first, equals(3)); + }); + group("source files", () { group("from fromEntries()", () { test("are null for non-FileLocations", () { From 328a91696b1f6ea03b581dd144eef4c8d861e441 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Thu, 13 Dec 2018 14:09:07 -0800 Subject: [PATCH 257/657] Fix typo and add example to message() and highlight() (dart-lang/source_span#24) --- pkgs/source_span/lib/src/span.dart | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index ff5c4b0dc..19655a54a 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -48,10 +48,12 @@ abstract class SourceSpan implements Comparable { /// Formats [message] in a human-friendly way associated with this span. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, - /// it indicates an ANSII terminal color escape that should be used to - /// highlight the span's text. If it's `true`, it indicates that the text - /// should be highlighted using the default color. If it's `false` or `null`, - /// it indicates that the text shouldn't be highlighted. + /// it indicates an [ANSI terminal color + /// escape](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) that should + /// be used to highlight the span's text (for example, `"\u001b[31m"` will + /// color red). If it's `true`, it indicates that the text should be + /// highlighted using the default color. If it's `false` or `null`, it + /// indicates that the text shouldn't be highlighted. String message(String message, {color}); /// Prints the text associated with this span in a user-friendly way. @@ -61,10 +63,12 @@ abstract class SourceSpan implements Comparable { /// isn't a [SourceSpanWithContext], returns an empty string. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, - /// it indicates an ANSII terminal color escape that should be used to - /// highlight the span's text. If it's `true`, it indicates that the text - /// should be highlighted using the default color. If it's `false` or `null`, - /// it indicates that the text shouldn't be highlighted. + /// it indicates an [ANSI terminal color + /// escape](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) that should + /// be used to highlight the span's text (for example, `"\u001b[31m"` will + /// color red). If it's `true`, it indicates that the text should be + /// highlighted using the default color. If it's `false` or `null`, it + /// indicates that the text shouldn't be highlighted. String highlight({color}); } From c084ccd037399473e3c88ad79a48e937049cbf7c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 20 Dec 2018 14:34:28 -0800 Subject: [PATCH 258/657] Improve span highlighting * Fully highlights multiline spans. * Includes line numbers. * Uses Unicode glyphs for highlighting when available. * Includes context after the last line of the span for a manually-constructed SourceSpanWithContext. This draws heavy inspiration from Rust's multiline error highlighting. --- pkgs/source_span/CHANGELOG.md | 11 + pkgs/source_span/lib/src/colors.dart | 2 + pkgs/source_span/lib/src/highlighter.dart | 354 ++++++++++++++++++++++ pkgs/source_span/lib/src/span.dart | 10 + pkgs/source_span/lib/src/span_mixin.dart | 55 +--- pkgs/source_span/lib/src/utils.dart | 34 ++- pkgs/source_span/pubspec.yaml | 3 +- pkgs/source_span/test/highlight_test.dart | 331 +++++++++++++++++--- pkgs/source_span/test/span_test.dart | 48 ++- pkgs/source_span/test/utils_test.dart | 11 + 10 files changed, 749 insertions(+), 110 deletions(-) create mode 100644 pkgs/source_span/lib/src/highlighter.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 53a700cf1..2248a3937 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,14 @@ +# 1.5.0 + +* Improve the output of `SourceSpan.highlight()` and `SourceSpan.message()`: + + * They now include line numbers. + * They will now print every line of a multiline span. + * They will now use Unicode box-drawing characters by default (this can be + controlled using [`term_glyph.ascii`][]). + +[`term_glyph.ascii`]: https://pub.dartlang.org/documentation/term_glyph/latest/term_glyph/ascii.html + # 1.4.1 * Set max SDK version to `<3.0.0`, and adjust other dependencies. diff --git a/pkgs/source_span/lib/src/colors.dart b/pkgs/source_span/lib/src/colors.dart index b9afab0db..2931eea9e 100644 --- a/pkgs/source_span/lib/src/colors.dart +++ b/pkgs/source_span/lib/src/colors.dart @@ -7,4 +7,6 @@ const String RED = '\u001b[31m'; const String YELLOW = '\u001b[33m'; +const String BLUE = '\u001b[34m'; + const String NONE = '\u001b[0m'; diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart new file mode 100644 index 000000000..bc0fe6981 --- /dev/null +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -0,0 +1,354 @@ +// 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. + +import 'dart:math' as math; + +import 'package:charcode/charcode.dart'; +import 'package:term_glyph/term_glyph.dart' as glyph; + +import 'colors.dart' as colors; +import 'location.dart'; +import 'span.dart'; +import 'span_with_context.dart'; +import 'utils.dart'; + +/// A class for writing a chunk of text with a particular span highlighted. +class Highlighter { + /// The span to highlight. + final SourceSpanWithContext _span; + + /// The color to highlight [_span] within its context, or `null` if the span + /// should not be colored. + final String _color; + + /// Whether [_span] covers multiple lines. + final bool _multiline; + + /// The number of characters before the bar in the sidebar. + final int _paddingBeforeSidebar; + + // The number of characters between the bar in the sidebar and the text + // being highlighted. + int get _paddingAfterSidebar => + // This is just a space for a single-line span, but for a multi-line span + // needs to accommodate " | ". + _multiline ? 3 : 1; + + /// The buffer to which to write the result. + final _buffer = new StringBuffer(); + + /// The number of spaces to render for hard tabs that appear in `_span.text`. + /// + /// We don't want to render raw tabs, because they'll mess up our character + /// alignment. + static const _spacesPerTab = 4; + + factory Highlighter(SourceSpan span, {color}) { + if (color == true) color = colors.RED; + if (color == false) color = null; + + // Normalize [span] to ensure that it's a [SourceSpanWithContext] whose + // context actually contains its text at the expected column. If it's not, + // adjust the start and end locations' line and column fields so that the + // highlighter can assume they match up with the context. + SourceSpanWithContext newSpan; + if (span is SourceSpanWithContext && + findLineStart(span.context, span.text, span.start.column) != null) { + newSpan = span; + } else { + newSpan = new SourceSpanWithContext( + new SourceLocation(span.start.offset, + sourceUrl: span.sourceUrl, line: 0, column: 0), + new SourceLocation(span.end.offset, + sourceUrl: span.sourceUrl, + line: countCodeUnits(span.text, $lf), + column: _lastColumn(span.text)), + span.text, + span.text); + } + + // Normalize [span] to remove a trailing newline from `span.context`. If + // necessary, also adjust `span.end` so that it doesn't point past where the + // trailing newline used to be. + if (newSpan.context.endsWith("\n")) { + var context = newSpan.context.substring(0, newSpan.context.length - 1); + + var text = newSpan.text; + var start = newSpan.start; + var end = newSpan.end; + if (newSpan.text.endsWith("\n") && _isTextAtEndOfContext(newSpan)) { + text = newSpan.text.substring(0, newSpan.text.length - 1); + end = new SourceLocation(newSpan.end.offset - 1, + sourceUrl: newSpan.sourceUrl, + line: newSpan.end.line - 1, + column: _lastColumn(text)); + start = + newSpan.start.offset == newSpan.end.offset ? end : newSpan.start; + } + newSpan = new SourceSpanWithContext(start, end, text, context); + } + + return new Highlighter._(newSpan, color); + } + + /// Returns the (0-based) column number of the last column of the last line in [text]. + static int _lastColumn(String text) => + text.length - text.lastIndexOf("\n") + 1; + + /// 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) + + span.start.column + + span.length == + span.context.length; + + Highlighter._(this._span, this._color) + : _multiline = _span.start.line != _span.end.line, + // In a purely mathematical world, floor(log10(n)) would give the number of + // digits in n, but floating point errors render that unreliable in + // practice. + _paddingBeforeSidebar = _span.end.line.toString().length + 1; + + /// Returns the highlighted span text. + /// + /// This method should only be called once. + String highlight() { + //if (_span.length == 0 && _span.context.isEmpty) return ""; + + _writeSidebar(end: glyph.downEnd); + _buffer.writeln(); + + // If [context] contains lines prior to the one [text] appears on, write + // those first. + var lineStart = + findLineStart(_span.context, _span.text, _span.start.column); + assert(lineStart != null); // enfoced by [new Highlighter] + + var context = _span.context; + if (lineStart > 0) { + // Take a substring to one character *before* [lineStart] because + // [findLineStart] is guaranteed to return a position immediately after a + // newline. Including that newline would add an extra empty line to the + // end of [lines]. + var lines = context.substring(0, lineStart - 1).split("\n"); + var lineNumber = _span.start.line - lines.length; + for (var line in lines) { + _writeSidebar(line: lineNumber); + _buffer.write(" " * _paddingAfterSidebar); + _writeText(line); + _buffer.writeln(); + lineNumber++; + } + context = context.substring(lineStart); + } + + var lines = context.split("\n"); + + // Trim a trailing newline so we don't add an empty line to the end of the + // highlight. + if (lines.last.isEmpty && lines.length > 1) lines.removeLast(); + + _writeFirstLine(lines.first); + if (_multiline) { + _writeIntermediateLines( + lines.skip(1).take(_span.end.line - _span.start.line - 1)); + _writeLastLine(lines[_span.end.line - _span.start.line]); + } + _writeTrailingLines(lines.skip(1 + _span.end.line - _span.start.line)); + + _writeSidebar(end: glyph.upEnd); + + return _buffer.toString(); + } + + // Writes the first (and possibly only) line highlighted by the span. + void _writeFirstLine(String line) { + _writeSidebar(line: _span.start.line); + + var startColumn = math.min(_span.start.column, line.length); + var endColumn = math.min( + startColumn + _span.end.offset - _span.start.offset, line.length); + var textBefore = line.substring(0, startColumn); + + // If the span covers the entire first line other than initial whitespace, + // don't bother pointing out exactly where it begins. + if (_multiline && _isOnlyWhitespace(textBefore)) { + _buffer.write(" "); + _colorize(() { + _buffer.write(glyph.glyphOrAscii("┌", "/")); + _buffer.write(" "); + _writeText(line); + }); + _buffer.writeln(); + return; + } + + _buffer.write(" " * _paddingAfterSidebar); + _writeText(textBefore); + var textInside = line.substring(startColumn, endColumn); + _colorize(() => _writeText(textInside)); + _writeText(line.substring(endColumn)); + _buffer.writeln(); + + // Adjust the start and end column to account for any tabs that were + // converted to spaces. + var tabsBefore = _countTabs(textBefore); + var tabsInside = _countTabs(textInside); + startColumn = startColumn + tabsBefore * (_spacesPerTab - 1); + endColumn = endColumn + (tabsBefore + tabsInside) * (_spacesPerTab - 1); + + // Write the highlight for the first line. This is a series of carets for a + // single-line span, and a pointer to the beginning of a multi-line span. + _writeSidebar(); + if (_multiline) { + _buffer.write(" "); + _colorize(() { + _buffer.write(glyph.topLeftCorner); + _buffer.write(glyph.horizontalLine * (startColumn + 1)); + _buffer.write("^"); + }); + } else { + _buffer.write(" " * (startColumn + 1)); + _colorize( + () => _buffer.write("^" * math.max(endColumn - startColumn, 1))); + } + _buffer.writeln(); + } + + /// Writes the lines between the first and last lines highlighted by the span. + void _writeIntermediateLines(Iterable lines) { + assert(_multiline); + + // +1 because the first line was already written. + var lineNumber = _span.start.line + 1; + for (var line in lines) { + _writeSidebar(line: lineNumber); + + _buffer.write(" "); + _colorize(() { + _buffer.write(glyph.verticalLine); + _buffer.write(" "); + _writeText(line); + }); + _buffer.writeln(); + + lineNumber++; + } + } + + // Writes the last line highlighted by the span. + void _writeLastLine(String line) { + assert(_multiline); + + _writeSidebar(line: _span.end.line); + + var endColumn = math.min(_span.end.column, line.length); + + // If the span covers the entire last line, don't bother pointing out + // exactly where it ends. + if (_multiline && endColumn == line.length) { + _buffer.write(" "); + _colorize(() { + _buffer.write(glyph.glyphOrAscii("└", "\\")); + _buffer.write(" "); + _writeText(line); + }); + _buffer.writeln(); + return; + } + + _buffer.write(" "); + var textInside = line.substring(0, endColumn); + _colorize(() { + _buffer.write(glyph.verticalLine); + _buffer.write(" "); + _writeText(textInside); + }); + _writeText(line.substring(endColumn)); + _buffer.writeln(); + + // Adjust the end column to account for any tabs that were converted to + // spaces. + var tabsInside = _countTabs(textInside); + endColumn = endColumn + tabsInside * (_spacesPerTab - 1); + + // Write the highlight for the final line, which is an arrow pointing to the + // end of the span. + _writeSidebar(); + _buffer.write(" "); + _colorize(() { + _buffer.write(glyph.bottomLeftCorner); + _buffer.write(glyph.horizontalLine * endColumn); + _buffer.write("^"); + }); + _buffer.writeln(); + } + + /// Writes lines that appear in the context string but come after the span. + void _writeTrailingLines(Iterable lines) { + // +1 because this comes after any lines covered by the span. + var lineNumber = _span.end.line + 1; + for (var line in lines) { + _writeSidebar(line: lineNumber); + _buffer.write(" " * _paddingAfterSidebar); + _writeText(line); + _buffer.writeln(); + lineNumber++; + } + } + + /// Writes a snippet from the source text, converting hard tab characters into + /// plain indentation. + void _writeText(String text) { + for (var char in text.codeUnits) { + if (char == $tab) { + _buffer.write(" " * _spacesPerTab); + } else { + _buffer.writeCharCode(char); + } + } + } + + // Writes a sidebar to [buffer] that includes [line] as the line number if + // given and writes [end] at the end (defaults to [glyphs.verticalLine]). + void _writeSidebar({int line, String end}) { + _colorize(() { + if (line != null) { + // Add 1 to line to convert from computer-friendly 0-indexed line + // numbers to human-friendly 1-indexed line numbers. + _buffer.write((line + 1).toString().padRight(_paddingBeforeSidebar)); + } else { + _buffer.write(" " * _paddingBeforeSidebar); + } + _buffer.write(end ?? glyph.verticalLine); + }, color: colors.BLUE); + } + + /// Returns the number of hard tabs in [text]. + int _countTabs(String text) { + var count = 0; + for (var char in text.codeUnits) { + if (char == $tab) count++; + } + return count; + } + + /// Returns whether [text] contains only space or tab characters. + bool _isOnlyWhitespace(String text) { + for (var char in text.codeUnits) { + if (char != $space && char != $tab) return false; + } + return true; + } + + /// Colors all text written to [_buffer] during [callback], if colorization is + /// enabled. + /// + /// If [color] is passed, it's used as the color; otherwise, [_color] is used. + void _colorize(void callback(), {String color}) { + if (_color != null) _buffer.write(color ?? _color); + callback(); + if (_color != null) _buffer.write(colors.NONE); + } +} diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 19655a54a..57ffe79cb 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -2,6 +2,8 @@ // 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:term_glyph/term_glyph.dart' as glyph; + import 'location.dart'; import 'span_mixin.dart'; @@ -54,6 +56,10 @@ abstract class SourceSpan implements Comparable { /// color red). If it's `true`, it indicates that the text should be /// highlighted using the default color. If it's `false` or `null`, it /// indicates that the text shouldn't be highlighted. + /// + /// This uses the full range of Unicode characters to highlight the source + /// span if [glyph.ascii] is `false` (the default), but only uses ASCII + /// characters if it's `true`. String message(String message, {color}); /// Prints the text associated with this span in a user-friendly way. @@ -69,6 +75,10 @@ abstract class SourceSpan implements Comparable { /// color red). If it's `true`, it indicates that the text should be /// highlighted using the default color. If it's `false` or `null`, it /// indicates that the text shouldn't be highlighted. + /// + /// This uses the full range of Unicode characters to highlight the source + /// span if [glyph.ascii] is `false` (the default), but only uses ASCII + /// characters if it's `true`. String highlight({color}); } diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 1f7799d67..d8ac8f2ba 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -2,12 +2,9 @@ // 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 'dart:math' as math; - -import 'package:charcode/charcode.dart'; import 'package:path/path.dart' as p; -import 'colors.dart' as colors; +import 'highlighter.dart'; import 'span.dart'; import 'span_with_context.dart'; import 'utils.dart'; @@ -63,54 +60,8 @@ abstract class SourceSpanMixin implements SourceSpan { } String highlight({color}) { - if (color == true) color = colors.RED; - if (color == false) color = null; - - var column = start.column; - var buffer = new StringBuffer(); - String textLine; - if (this is SourceSpanWithContext) { - var context = (this as SourceSpanWithContext).context; - var lineStart = findLineStart(context, text, column); - if (lineStart != null && lineStart > 0) { - buffer.write(context.substring(0, lineStart)); - context = context.substring(lineStart); - } - var endIndex = context.indexOf('\n'); - textLine = endIndex == -1 ? context : context.substring(0, endIndex + 1); - column = math.min(column, textLine.length); - } else if (length == 0) { - return ""; - } else { - textLine = text.split("\n").first; - column = 0; - } - - var toColumn = - math.min(column + end.offset - start.offset, textLine.length); - if (color != null) { - buffer.write(textLine.substring(0, column)); - buffer.write(color); - buffer.write(textLine.substring(column, toColumn)); - buffer.write(colors.NONE); - buffer.write(textLine.substring(toColumn)); - } else { - buffer.write(textLine); - } - if (!textLine.endsWith('\n')) buffer.write('\n'); - - for (var i = 0; i < column; i++) { - if (textLine.codeUnitAt(i) == $tab) { - buffer.writeCharCode($tab); - } else { - buffer.writeCharCode($space); - } - } - - if (color != null) buffer.write(color); - buffer.write('^' * math.max(toColumn - column, 1)); - if (color != null) buffer.write(colors.NONE); - return buffer.toString(); + if (this is! SourceSpanWithContext && this.length == 0) return ""; + return new Highlighter(this, color: color).highlight(); } bool operator ==(other) => diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 69385476c..228b240e0 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -12,19 +12,43 @@ Comparable min(Comparable obj1, Comparable obj2) => Comparable max(Comparable obj1, Comparable obj2) => obj1.compareTo(obj2) > 0 ? obj1 : obj2; +/// Returns the number of instances of [codeUnit] in [string]. +int countCodeUnits(String string, int codeUnit) { + var count = 0; + for (var codeUnitToCheck in string.codeUnits) { + if (codeUnitToCheck == codeUnit) count++; + } + return count; +} + /// Finds a line in [context] containing [text] at the specified [column]. /// /// Returns the index in [context] where that line begins, or null if none /// exists. int findLineStart(String context, String text, int column) { - var isEmpty = text == ''; + // If the text is empty, we just want to find the first line that has at least + // [column] characters. + if (text.isEmpty) { + var beginningOfLine = 0; + while (true) { + var index = context.indexOf("\n", beginningOfLine); + if (index == -1) { + return context.length - beginningOfLine >= column + ? beginningOfLine + : null; + } + + if (index - beginningOfLine >= column) return beginningOfLine; + beginningOfLine = index + 1; + } + } + var index = context.indexOf(text); while (index != -1) { - var lineStart = context.lastIndexOf('\n', index) + 1; + // Start looking before [index] in case [text] starts with a newline. + var lineStart = index == 0 ? 0 : context.lastIndexOf('\n', index - 1) + 1; var textColumn = index - lineStart; - if (column == textColumn || (isEmpty && column == textColumn + 1)) { - return lineStart; - } + if (column == textColumn) return lineStart; index = context.indexOf(text, index + 1); } return null; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 1d5321007..ebd3a72a4 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.4.1 +version: 1.5.0 description: A library for identifying source spans and locations. author: Dart Team @@ -11,6 +11,7 @@ environment: dependencies: charcode: ^1.0.0 path: '>=1.2.0 <2.0.0' + term_glyph: ^1.0.0 dev_dependencies: test: '>=0.12.0 <2.0.0' diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index ac8334bd5..4eceaa823 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -3,10 +3,21 @@ // BSD-style license that can be found in the LICENSE file. import 'package:test/test.dart'; + import 'package:source_span/source_span.dart'; import 'package:source_span/src/colors.dart' as colors; main() { + bool oldAscii; + setUpAll(() { + oldAscii = glyph.ascii; + glyph.ascii = true; + }); + + tearDownAll(() { + glyph.ascii = oldAscii; + }); + var file; setUp(() { file = new SourceFile.fromString(""" @@ -18,101 +29,341 @@ zip zap zop test("points to the span in the source", () { expect(file.span(4, 7).highlight(), equals(""" -foo bar baz - ^^^""")); + , +1 | foo bar baz + | ^^^ + '""")); }); test("gracefully handles a missing source URL", () { var span = new SourceFile.fromString("foo bar baz").span(4, 7); expect(span.highlight(), equals(""" -foo bar baz - ^^^""")); - }); - - test("highlights the first line of a multiline span", () { - expect(file.span(4, 20).highlight(), equals(""" -foo bar baz - ^^^^^^^^""")); + , +1 | foo bar baz + | ^^^ + '""")); }); test("works for a point span", () { expect(file.location(4).pointSpan().highlight(), equals(""" -foo bar baz - ^""")); + , +1 | foo bar baz + | ^ + '""")); }); test("works for a point span at the end of a line", () { expect(file.location(11).pointSpan().highlight(), equals(""" -foo bar baz - ^""")); + , +1 | foo bar baz + | ^ + '""")); }); test("works for a point span at the end of the file", () { expect(file.location(38).pointSpan().highlight(), equals(""" -zip zap zop - ^""")); + , +3 | zip zap zop + | ^ + '""")); }); test("works for a point span at the end of the file with no trailing newline", () { file = new SourceFile.fromString("zip zap zop"); expect(file.location(11).pointSpan().highlight(), equals(""" -zip zap zop - ^""")); + , +1 | zip zap zop + | ^ + '""")); }); test("works for a point span in an empty file", () { expect(new SourceFile.fromString("").location(0).pointSpan().highlight(), equals(""" - -^""")); + , +1 | + | ^ + '""")); }); test("works for a single-line file without a newline", () { expect( new SourceFile.fromString("foo bar").span(0, 7).highlight(), equals(""" -foo bar -^^^^^^^""")); + , +1 | foo bar + | ^^^^^^^ + '""")); }); - test("emits tabs for tabs", () { - expect(new SourceFile.fromString(" \t \t\tfoo bar").span(5, 8).highlight(), - equals(""" - \t \t\tfoo bar - \t \t\t^^^""")); + group("with a multiline span", () { + test("highlights the middle of the first and last lines", () { + expect(file.span(4, 34).highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom +3 | | zip zap zop + | '-------^ + '""")); + }); + + test("works when it begins at the end of a line", () { + expect(file.span(11, 34).highlight(), equals(""" + , +1 | foo bar baz + | ,------------^ +2 | | whiz bang boom +3 | | zip zap zop + | '-------^ + '""")); + }); + + test("works when it ends at the beginning of a line", () { + expect(file.span(4, 28).highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom +3 | | zip zap zop + | '-^ + '""")); + }); + + test("highlights the full first line", () { + expect(file.span(0, 34).highlight(), equals(""" + , +1 | / foo bar baz +2 | | whiz bang boom +3 | | zip zap zop + | '-------^ + '""")); + }); + + test("highlights the full first line even if it's indented", () { + var file = new SourceFile.fromString(""" + foo bar baz + whiz bang boom + zip zap zop +"""); + + expect(file.span(2, 38).highlight(), equals(""" + , +1 | / foo bar baz +2 | | whiz bang boom +3 | | zip zap zop + | '-------^ + '""")); + }); + + test("highlights the full last line", () { + expect(file.span(4, 26).highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | \\ whiz bang boom + '""")); + }); + + test("highlights the full last line at the end of the file", () { + expect(file.span(4, 39).highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom +3 | \\ zip zap zop + '""")); + }); + + test("highlights the full last line with no trailing newline", () { + var file = new SourceFile.fromString(""" +foo bar baz +whiz bang boom +zip zap zop"""); + + expect(file.span(4, 38).highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom +3 | \\ zip zap zop + '""")); + }); }); - test("supports lines of preceding context", () { + group("prints tabs as spaces", () { + group("in a single-line span", () { + test("before the highlighted section", () { + var span = new SourceFile.fromString("foo\tbar baz").span(4, 7); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ^^^ + '""")); + }); + + test("within the highlighted section", () { + var span = new SourceFile.fromString("foo bar\tbaz bang").span(4, 11); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz bang + | ^^^^^^^^^^ + '""")); + }); + + test("after the highlighted section", () { + var span = new SourceFile.fromString("foo bar\tbaz").span(4, 7); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ^^^ + '""")); + }); + }); + + group("in a multi-line span", () { + test("before the highlighted section", () { + var span = new SourceFile.fromString(""" +foo\tbar baz +whiz bang boom +""").span(4, 21); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ,--------^ +2 | | whiz bang boom + | '---------^ + '""")); + }); + + test("within the first highlighted line", () { + var span = new SourceFile.fromString(""" +foo bar\tbaz +whiz bang boom +""").span(4, 21); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom + | '---------^ + '""")); + }); + + test("within a middle highlighted line", () { + var span = new SourceFile.fromString(""" +foo bar baz +whiz\tbang boom +zip zap zop +""").span(4, 34); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom +3 | | zip zap zop + | '-------^ + '""")); + }); + + test("within the last highlighted line", () { + var span = new SourceFile.fromString(""" +foo bar baz +whiz\tbang boom +""").span(4, 21); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom + | '------------^ + '""")); + }); + + test("after the highlighted section", () { + var span = new SourceFile.fromString(""" +foo bar baz +whiz bang\tboom +""").span(4, 21); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom + | '---------^ + '""")); + }); + }); + }); + + test("supports lines of preceding and following context", () { var span = new SourceSpanWithContext( - new SourceLocation(5, line: 3, column: 5, sourceUrl: "foo.dart"), - new SourceLocation(12, line: 3, column: 12, sourceUrl: "foo.dart"), + new SourceLocation(5, line: 2, column: 5, sourceUrl: "foo.dart"), + new SourceLocation(12, line: 2, column: 12, sourceUrl: "foo.dart"), "foo bar", "previous\nlines\n-----foo bar-----\nfollowing line\n"); expect(span.highlight(color: colors.YELLOW), equals(""" -previous -lines ------${colors.YELLOW}foo bar${colors.NONE}----- - ${colors.YELLOW}^^^^^^^${colors.NONE}""")); +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} previous +${colors.BLUE}2 |${colors.NONE} lines +${colors.BLUE}3 |${colors.NONE} -----${colors.YELLOW}foo bar${colors.NONE}----- +${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^^^^^${colors.NONE} +${colors.BLUE}4 |${colors.NONE} following line +${colors.BLUE} '${colors.NONE}""")); }); group("colors", () { test("doesn't colorize if color is false", () { expect(file.span(4, 7).highlight(color: false), equals(""" -foo bar baz - ^^^""")); + , +1 | foo bar baz + | ^^^ + '""")); }); test("colorizes if color is true", () { expect(file.span(4, 7).highlight(color: true), equals(""" -foo ${colors.RED}bar${colors.NONE} baz - ${colors.RED}^^^${colors.NONE}""")); +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} foo ${colors.RED}bar${colors.NONE} baz +${colors.BLUE} |${colors.NONE} ${colors.RED}^^^${colors.NONE} +${colors.BLUE} '${colors.NONE}""")); }); test("uses the given color if it's passed", () { expect(file.span(4, 7).highlight(color: colors.YELLOW), equals(""" -foo ${colors.YELLOW}bar${colors.NONE} baz - ${colors.YELLOW}^^^${colors.NONE}""")); +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} foo ${colors.YELLOW}bar${colors.NONE} baz +${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^${colors.NONE} +${colors.BLUE} '${colors.NONE}""")); + }); + + test("colorizes a multiline span", () { + expect(file.span(4, 34).highlight(color: true), equals(""" +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} foo ${colors.RED}bar baz${colors.NONE} +${colors.BLUE} |${colors.NONE} ${colors.RED},-----^${colors.NONE} +${colors.BLUE}2 |${colors.NONE} ${colors.RED}| whiz bang boom${colors.NONE} +${colors.BLUE}3 |${colors.NONE} ${colors.RED}| zip zap${colors.NONE} zop +${colors.BLUE} |${colors.NONE} ${colors.RED}'-------^${colors.NONE} +${colors.BLUE} '${colors.NONE}""")); + }); + + test("colorizes a multiline span that highlights full lines", () { + expect(file.span(0, 39).highlight(color: true), equals(""" +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} ${colors.RED}/ foo bar baz${colors.NONE} +${colors.BLUE}2 |${colors.NONE} ${colors.RED}| whiz bang boom${colors.NONE} +${colors.BLUE}3 |${colors.NONE} ${colors.RED}\\ zip zap zop${colors.NONE} +${colors.BLUE} '${colors.NONE}""")); }); }); } diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index b7637cf7c..99895162a 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -3,10 +3,22 @@ // BSD-style license that can be found in the LICENSE file. import 'package:test/test.dart'; +import 'package:term_glyph/term_glyph.dart' as glyph; + import 'package:source_span/source_span.dart'; import 'package:source_span/src/colors.dart' as colors; main() { + bool oldAscii; + setUpAll(() { + oldAscii = glyph.ascii; + glyph.ascii = true; + }); + + tearDownAll(() { + glyph.ascii = oldAscii; + }); + var span; setUp(() { span = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), @@ -181,8 +193,10 @@ main() { test("prints the text being described", () { expect(span.message("oh no"), equals(""" line 1, column 6 of foo.dart: oh no -foo bar -^^^^^^^""")); + , +1 | foo bar + | ^^^^^^^ + '""")); }); test("gracefully handles a missing source URL", () { @@ -191,8 +205,10 @@ foo bar expect(span.message("oh no"), equalsIgnoringWhitespace(""" line 1, column 6: oh no -foo bar -^^^^^^^""")); + , +1 | foo bar + | ^^^^^^^ + '""")); }); test("gracefully handles empty text", () { @@ -205,22 +221,28 @@ foo bar test("doesn't colorize if color is false", () { expect(span.message("oh no", color: false), equals(""" line 1, column 6 of foo.dart: oh no -foo bar -^^^^^^^""")); + , +1 | foo bar + | ^^^^^^^ + '""")); }); test("colorizes if color is true", () { expect(span.message("oh no", color: true), equals(""" line 1, column 6 of foo.dart: oh no -${colors.RED}foo bar${colors.NONE} -${colors.RED}^^^^^^^${colors.NONE}""")); +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} ${colors.RED}foo bar${colors.NONE} +${colors.BLUE} |${colors.NONE} ${colors.RED}^^^^^^^${colors.NONE} +${colors.BLUE} '${colors.NONE}""")); }); test("uses the given color if it's passed", () { expect(span.message("oh no", color: colors.YELLOW), equals(""" line 1, column 6 of foo.dart: oh no -${colors.YELLOW}foo bar${colors.NONE} -${colors.YELLOW}^^^^^^^${colors.NONE}""")); +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} ${colors.YELLOW}foo bar${colors.NONE} +${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^^^^^${colors.NONE} +${colors.BLUE} '${colors.NONE}""")); }); test("with context, underlines the right column", () { @@ -232,8 +254,10 @@ ${colors.YELLOW}^^^^^^^${colors.NONE}""")); expect(spanWithContext.message("oh no", color: colors.YELLOW), equals(""" line 1, column 6 of foo.dart: oh no ------${colors.YELLOW}foo bar${colors.NONE}----- - ${colors.YELLOW}^^^^^^^${colors.NONE}""")); +${colors.BLUE} ,${colors.NONE} +${colors.BLUE}1 |${colors.NONE} -----${colors.YELLOW}foo bar${colors.NONE}----- +${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^^^^^${colors.NONE} +${colors.BLUE} '${colors.NONE}""")); }); }); diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index 2a86cc070..a8146e33b 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -32,12 +32,23 @@ main() { expect(index, 4); }); + test('empty text in empty context', () { + var index = findLineStart('', '', 0); + expect(index, 0); + }); + test('found on the first line', () { var context = '0\n2\n45\n'; var index = findLineStart(context, '0', 0); expect(index, 0); }); + test('finds text that starts with a newline', () { + var context = '0\n2\n45\n'; + var index = findLineStart(context, '\n2', 1); + expect(index, 0); + }); + test('not found', () { var context = '0\n2\n45\n'; var index = findLineStart(context, '0', 1); From 1073d5e97fee8416cf36e146f74a7814482d2430 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 20 Dec 2018 14:51:48 -0800 Subject: [PATCH 259/657] Add a missing import --- pkgs/source_span/test/highlight_test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 4eceaa823..19f8ca815 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -2,6 +2,7 @@ // 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:term_glyph/term_glyph.dart' as glyph; import 'package:test/test.dart'; import 'package:source_span/source_span.dart'; From 855d5ec02d98c0ca8c7a3a89817b87219681e544 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 26 Dec 2018 12:52:06 -0800 Subject: [PATCH 260/657] Code review --- pkgs/source_span/lib/src/highlighter.dart | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index bc0fe6981..a709d243a 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -44,6 +44,16 @@ class Highlighter { /// alignment. static const _spacesPerTab = 4; + /// Creats a [Highlighter] that will return a message associated with [span] + /// when [write] is called. + /// + /// [color] may either be a [String], a [bool], or `null`. If it's a string, + /// it indicates an [ANSI terminal color + /// escape](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) that should + /// be used to highlight the span's text (for example, `"\u001b[31m"` will + /// color red). If it's `true`, it indicates that the text should be + /// highlighted using the default color. If it's `false` or `null`, it + /// indicates that the text shouldn't be highlighted. factory Highlighter(SourceSpan span, {color}) { if (color == true) color = colors.RED; if (color == false) color = null; @@ -114,8 +124,6 @@ class Highlighter { /// /// This method should only be called once. String highlight() { - //if (_span.length == 0 && _span.context.isEmpty) return ""; - _writeSidebar(end: glyph.downEnd); _buffer.writeln(); @@ -123,7 +131,7 @@ class Highlighter { // those first. var lineStart = findLineStart(_span.context, _span.text, _span.start.column); - assert(lineStart != null); // enfoced by [new Highlighter] + assert(lineStart != null); // enforced by [new Highlighter] var context = _span.context; if (lineStart > 0) { @@ -150,12 +158,13 @@ class Highlighter { if (lines.last.isEmpty && lines.length > 1) lines.removeLast(); _writeFirstLine(lines.first); + var lastLineIndex = _span.end.line - _span.start.line; if (_multiline) { _writeIntermediateLines( - lines.skip(1).take(_span.end.line - _span.start.line - 1)); - _writeLastLine(lines[_span.end.line - _span.start.line]); + lines.skip(1).take(lastLineIndex - 1)); + _writeLastLine(lines[lastLineIndex]); } - _writeTrailingLines(lines.skip(1 + _span.end.line - _span.start.line)); + _writeTrailingLines(lines.skip(lastLineIndex + 1)); _writeSidebar(end: glyph.upEnd); From 182b21945130cdd4476a6affd8b70efcc1982837 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 28 Dec 2018 14:16:55 -0800 Subject: [PATCH 261/657] Enable and fix a number of lints (dart-lang/pool#19) --- pkgs/pool/analysis_options.yaml | 11 ++ pkgs/pool/lib/pool.dart | 45 ++++---- pkgs/pool/pubspec.yaml | 3 +- pkgs/pool/test/pool_test.dart | 187 ++++++++++++++++---------------- 4 files changed, 129 insertions(+), 117 deletions(-) create mode 100644 pkgs/pool/analysis_options.yaml diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml new file mode 100644 index 000000000..749f62afe --- /dev/null +++ b/pkgs/pool/analysis_options.yaml @@ -0,0 +1,11 @@ +include: package:pedantic/analysis_options.yaml +analyzer: + strong-mode: + implicit-casts: false +linter: + rules: + - await_only_futures + - implementation_imports + - prefer_typing_uninitialized_variables + - unnecessary_const + - unnecessary_new diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index ea3d2f016..416b14b73 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -21,20 +21,20 @@ class Pool { /// /// When an item is released, the next element of [_requestedResources] will /// be completed. - final _requestedResources = new Queue>(); + final _requestedResources = Queue>(); /// Callbacks that must be called before additional resources can be /// allocated. /// /// See [PoolResource.allowRelease]. - final _onReleaseCallbacks = new Queue(); + final _onReleaseCallbacks = Queue(); /// Completers that will be completed once `onRelease` callbacks are done /// running. /// /// These are kept in a queue to ensure that the earliest request completes /// first regardless of what order the `onRelease` callbacks complete in. - final _onReleaseCompleters = new Queue>(); + final _onReleaseCompleters = Queue>(); /// The maximum number of resources that may be allocated at once. final int _maxAllocatedResources; @@ -82,7 +82,7 @@ class Pool { if (timeout != null) { // Start the timer canceled since we only want to start counting down once // we've run out of available resources. - _timer = new RestartableTimer(timeout, _onTimeout)..cancel(); + _timer = RestartableTimer(timeout, _onTimeout)..cancel(); } } @@ -92,16 +92,16 @@ class Pool { /// until one of them is released. Future request() { if (isClosed) { - throw new StateError("request() may not be called on a closed Pool."); + throw StateError("request() may not be called on a closed Pool."); } if (_allocatedResources < _maxAllocatedResources) { _allocatedResources++; - return new Future.value(new PoolResource._(this)); + return Future.value(PoolResource._(this)); } else if (_onReleaseCallbacks.isNotEmpty) { return _runOnRelease(_onReleaseCallbacks.removeFirst()); } else { - var completer = new Completer(); + var completer = Completer(); _requestedResources.add(completer); _resetTimer(); return completer.future; @@ -114,8 +114,7 @@ class Pool { /// The return value of [callback] is piped to the returned Future. Future withResource(FutureOr callback()) { if (isClosed) { - throw new StateError( - "withResource() may not be called on a closed Pool."); + throw StateError("withResource() may not be called on a closed Pool."); } // We can't use async/await here because we need to start the request @@ -123,7 +122,7 @@ class Pool { // functions have an asynchronous gap between calling and running the body, // and [close] could be called during that gap. See #3. return request().then((resource) { - return new Future.sync(callback).whenComplete(resource.release); + return Future.sync(callback).whenComplete(resource.release); }); } @@ -143,9 +142,9 @@ class Pool { _resetTimer(); - _closeGroup = new FutureGroup(); + _closeGroup = FutureGroup(); for (var callback in _onReleaseCallbacks) { - _closeGroup.add(new Future.sync(callback)); + _closeGroup.add(Future.sync(callback)); } _allocatedResources -= _onReleaseCallbacks.length; @@ -154,7 +153,7 @@ class Pool { if (_allocatedResources == 0) _closeGroup.close(); return _closeGroup.future; }); - final _closeMemo = new AsyncMemoizer(); + final _closeMemo = AsyncMemoizer(); /// If there are any pending requests, this will fire the oldest one. void _onResourceReleased() { @@ -162,7 +161,7 @@ class Pool { if (_requestedResources.isNotEmpty) { var pending = _requestedResources.removeFirst(); - pending.complete(new PoolResource._(this)); + pending.complete(PoolResource._(this)); } else { _allocatedResources--; if (isClosed && _allocatedResources == 0) _closeGroup.close(); @@ -178,7 +177,7 @@ class Pool { var pending = _requestedResources.removeFirst(); pending.complete(_runOnRelease(onRelease)); } else if (isClosed) { - _closeGroup.add(new Future.sync(onRelease)); + _closeGroup.add(Future.sync(onRelease)); _allocatedResources--; if (_allocatedResources == 0) _closeGroup.close(); } else { @@ -194,13 +193,13 @@ class Pool { /// Futures returned by [_runOnRelease] always complete in the order they were /// created, even if earlier [onRelease] callbacks take longer to run. Future _runOnRelease(onRelease()) { - new Future.sync(onRelease).then((value) { - _onReleaseCompleters.removeFirst().complete(new PoolResource._(this)); - }).catchError((error, stackTrace) { + Future.sync(onRelease).then((value) { + _onReleaseCompleters.removeFirst().complete(PoolResource._(this)); + }).catchError((error, StackTrace stackTrace) { _onReleaseCompleters.removeFirst().completeError(error, stackTrace); }); - var completer = new Completer.sync(); + var completer = Completer.sync(); _onReleaseCompleters.add(completer); return completer.future; } @@ -221,11 +220,11 @@ class Pool { void _onTimeout() { for (var completer in _requestedResources) { completer.completeError( - new TimeoutException( + TimeoutException( "Pool deadlock: all resources have been " "allocated for too long.", _timeout), - new Chain.current()); + Chain.current()); } _requestedResources.clear(); _timer = null; @@ -248,7 +247,7 @@ class PoolResource { /// no longer allocated, and that a new [PoolResource] may be allocated. void release() { if (_released) { - throw new StateError("A PoolResource may only be released once."); + throw StateError("A PoolResource may only be released once."); } _released = true; _pool._onResourceReleased(); @@ -268,7 +267,7 @@ class PoolResource { /// may be complete, but it could still emit asynchronous errors. void allowRelease(onRelease()) { if (_released) { - throw new StateError("A PoolResource may only be released once."); + throw StateError("A PoolResource may only be released once."); } _released = true; _pool._onResourceReleaseAllowed(onRelease); diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 84b97b236..a709842c9 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.3.6 +version: 1.3.7-dev description: A class for managing a finite pool of resources. author: Dart Team @@ -14,4 +14,5 @@ dependencies: dev_dependencies: fake_async: ^1.0.0 + pedantic: ^1.4.0 test: ^1.0.0 diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index cb0dd3009..a156c521e 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:fake_async/fake_async.dart'; +import 'package:pedantic/pedantic.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart'; import 'package:test/test.dart'; @@ -12,27 +13,27 @@ import 'package:test/test.dart'; void main() { group("request()", () { test("resources can be requested freely up to the limit", () { - var pool = new Pool(50); + var pool = Pool(50); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } }); test("resources block past the limit", () { - new FakeAsync().run((async) { - var pool = new Pool(50); + FakeAsync().run((async) { + var pool = Pool(50); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } expect(pool.request(), doesNotComplete); - async.elapse(new Duration(seconds: 1)); + async.elapse(Duration(seconds: 1)); }); }); test("a blocked resource is allocated when another is released", () { - new FakeAsync().run((async) { - var pool = new Pool(50); + FakeAsync().run((async) { + var pool = Pool(50); for (var i = 0; i < 49; i++) { expect(pool.request(), completes); } @@ -41,85 +42,85 @@ void main() { // This will only complete once [lastAllocatedResource] is released. expect(pool.request(), completes); - new Future.delayed(new Duration(microseconds: 1)).then((_) { + Future.delayed(Duration(microseconds: 1)).then((_) { lastAllocatedResource.release(); }); }); - async.elapse(new Duration(seconds: 1)); + async.elapse(Duration(seconds: 1)); }); }); }); group("withResource()", () { test("can be called freely up to the limit", () { - var pool = new Pool(50); + var pool = Pool(50); for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync0(() => new Completer().future)); + pool.withResource(expectAsync0(() => Completer().future)); } }); test("blocks the callback past the limit", () { - new FakeAsync().run((async) { - var pool = new Pool(50); + FakeAsync().run((async) { + var pool = Pool(50); for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync0(() => new Completer().future)); + pool.withResource(expectAsync0(() => Completer().future)); } pool.withResource(expectNoAsync()); - async.elapse(new Duration(seconds: 1)); + async.elapse(Duration(seconds: 1)); }); }); test("a blocked resource is allocated when another is released", () { - new FakeAsync().run((async) { - var pool = new Pool(50); + FakeAsync().run((async) { + var pool = Pool(50); for (var i = 0; i < 49; i++) { - pool.withResource(expectAsync0(() => new Completer().future)); + pool.withResource(expectAsync0(() => Completer().future)); } - var completer = new Completer(); + var completer = Completer(); pool.withResource(() => completer.future); var blockedResourceAllocated = false; pool.withResource(() { blockedResourceAllocated = true; }); - new Future.delayed(new Duration(microseconds: 1)).then((_) { + Future.delayed(Duration(microseconds: 1)).then((_) { expect(blockedResourceAllocated, isFalse); completer.complete(); - return new Future.delayed(new Duration(microseconds: 1)); + return Future.delayed(Duration(microseconds: 1)); }).then((_) { expect(blockedResourceAllocated, isTrue); }); - async.elapse(new Duration(seconds: 1)); + async.elapse(Duration(seconds: 1)); }); }); // Regression test for #3. test("can be called immediately before close()", () async { - var pool = new Pool(1); - pool.withResource(expectAsync0(() {})); + var pool = Pool(1); + unawaited(pool.withResource(expectAsync0(() {}))); await pool.close(); }); }); group("with a timeout", () { test("doesn't time out if there are no pending requests", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); + FakeAsync().run((async) { + var pool = Pool(50, timeout: Duration(seconds: 5)); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } - async.elapse(new Duration(seconds: 6)); + async.elapse(Duration(seconds: 6)); }); }); test("resets the timer if a resource is returned", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); + FakeAsync().run((async) { + var pool = Pool(50, timeout: Duration(seconds: 5)); for (var i = 0; i < 49; i++) { expect(pool.request(), completes); } @@ -128,48 +129,48 @@ void main() { // This will only complete once [lastAllocatedResource] is released. expect(pool.request(), completes); - new Future.delayed(new Duration(seconds: 3)).then((_) { + Future.delayed(Duration(seconds: 3)).then((_) { lastAllocatedResource.release(); expect(pool.request(), doesNotComplete); }); }); - async.elapse(new Duration(seconds: 6)); + async.elapse(Duration(seconds: 6)); }); }); test("resets the timer if a resource is requested", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); + FakeAsync().run((async) { + var pool = Pool(50, timeout: Duration(seconds: 5)); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } expect(pool.request(), doesNotComplete); - new Future.delayed(new Duration(seconds: 3)).then((_) { + Future.delayed(Duration(seconds: 3)).then((_) { expect(pool.request(), doesNotComplete); }); - async.elapse(new Duration(seconds: 6)); + async.elapse(Duration(seconds: 6)); }); }); test("times out if nothing happens", () { - new FakeAsync().run((async) { - var pool = new Pool(50, timeout: new Duration(seconds: 5)); + FakeAsync().run((async) { + var pool = Pool(50, timeout: Duration(seconds: 5)); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } - expect(pool.request(), throwsA(new TypeMatcher())); + expect(pool.request(), throwsA(TypeMatcher())); - async.elapse(new Duration(seconds: 6)); + async.elapse(Duration(seconds: 6)); }); }); }); group("allowRelease()", () { test("runs the callback once the resource limit is exceeded", () async { - var pool = new Pool(50); + var pool = Pool(50); for (var i = 0; i < 49; i++) { expect(pool.request(), completes); } @@ -177,17 +178,17 @@ void main() { var resource = await pool.request(); var onReleaseCalled = false; resource.allowRelease(() => onReleaseCalled = true); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onReleaseCalled, isFalse); expect(pool.request(), completes); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onReleaseCalled, isTrue); }); test("runs the callback immediately if there are blocked requests", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource = await pool.request(); // This will be blocked until [resource.allowRelease] is called. @@ -195,54 +196,54 @@ void main() { var onReleaseCalled = false; resource.allowRelease(() => onReleaseCalled = true); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onReleaseCalled, isTrue); }); test("blocks the request until the callback completes", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource = await pool.request(); var requestComplete = false; - pool.request().then((_) => requestComplete = true); + unawaited(pool.request().then((_) => requestComplete = true)); - var completer = new Completer(); + var completer = Completer(); resource.allowRelease(() => completer.future); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(requestComplete, isFalse); completer.complete(); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(requestComplete, isTrue); }); test("completes requests in request order regardless of callback order", () async { - var pool = new Pool(2); + var pool = Pool(2); var resource1 = await pool.request(); var resource2 = await pool.request(); var request1Complete = false; - pool.request().then((_) => request1Complete = true); + unawaited(pool.request().then((_) => request1Complete = true)); var request2Complete = false; - pool.request().then((_) => request2Complete = true); + unawaited(pool.request().then((_) => request2Complete = true)); var onRelease1Called = false; - var completer1 = new Completer(); + var completer1 = Completer(); resource1.allowRelease(() { onRelease1Called = true; return completer1.future; }); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onRelease1Called, isTrue); var onRelease2Called = false; - var completer2 = new Completer(); + var completer2 = Completer(); resource2.allowRelease(() { onRelease2Called = true; return completer2.future; }); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onRelease2Called, isTrue); expect(request1Complete, isFalse); expect(request2Complete, isFalse); @@ -251,18 +252,18 @@ void main() { // was triggered by the second blocking request, it should complete the // first one to preserve ordering. completer2.complete(); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(request1Complete, isTrue); expect(request2Complete, isFalse); completer1.complete(); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(request1Complete, isTrue); expect(request2Complete, isTrue); }); test("runs onRequest in the zone it was created", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource = await pool.request(); var outerZone = Zone.current; @@ -275,29 +276,29 @@ void main() { })); }); - pool.request(); + await pool.request(); }); }); test("done doesn't complete without close", () async { - var pool = new Pool(1); - pool.done.then(expectAsync1((_) {}, count: 0)); + var pool = Pool(1); + unawaited(pool.done.then(expectAsync1((_) {}, count: 0))); var resource = await pool.request(); resource.release(); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); }); group("close()", () { test("disallows request() and withResource()", () { - var pool = new Pool(1)..close(); + var pool = Pool(1)..close(); expect(pool.request, throwsStateError); expect(() => pool.withResource(() {}), throwsStateError); }); test("pending requests are fulfilled", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource1 = await pool.request(); expect( pool.request().then((resource2) { @@ -310,10 +311,10 @@ void main() { }); test("pending requests are fulfilled with allowRelease", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource1 = await pool.request(); - var completer = new Completer(); + var completer = Completer(); expect( pool.request().then((resource2) { expect(completer.isCompleted, isTrue); @@ -323,13 +324,13 @@ void main() { expect(pool.close(), completes); resource1.allowRelease(() => completer.future); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.complete(); }); test("doesn't complete until all resources are released", () async { - var pool = new Pool(2); + var pool = Pool(2); var resource1 = await pool.request(); var resource2 = await pool.request(); var resource3Future = pool.request(); @@ -347,11 +348,11 @@ void main() { resource1Released = true; resource1.release(); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); resource2Released = true; resource2.release(); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); var resource3 = await resource3Future; resource3Released = true; @@ -359,12 +360,12 @@ void main() { }); test("active onReleases complete as usual", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource = await pool.request(); // Set up an onRelease callback whose completion is controlled by // [completer]. - var completer = new Completer(); + var completer = Completer(); resource.allowRelease(() => completer.future); expect( pool.request().then((_) { @@ -372,21 +373,21 @@ void main() { }), completes); - await new Future.delayed(Duration.zero); - pool.close(); + await Future.delayed(Duration.zero); + unawaited(pool.close()); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.complete(); }); test("inactive onReleases fire", () async { - var pool = new Pool(2); + var pool = Pool(2); var resource1 = await pool.request(); var resource2 = await pool.request(); - var completer1 = new Completer(); + var completer1 = Completer(); resource1.allowRelease(() => completer1.future); - var completer2 = new Completer(); + var completer2 = Completer(); resource2.allowRelease(() => completer2.future); expect( @@ -396,42 +397,42 @@ void main() { }), completes); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer1.complete(); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer2.complete(); }); test("new allowReleases fire immediately", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource = await pool.request(); - var completer = new Completer(); + var completer = Completer(); expect( pool.close().then((_) { expect(completer.isCompleted, isTrue); }), completes); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); resource.allowRelease(() => completer.future); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.complete(); }); test("an onRelease error is piped to the return value", () async { - var pool = new Pool(1); + var pool = Pool(1); var resource = await pool.request(); - var completer = new Completer(); + var completer = Completer(); resource.allowRelease(() => completer.future); expect(pool.done, throwsA("oh no!")); expect(pool.close(), throwsA("oh no!")); - await new Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.completeError("oh no!"); }); }); @@ -440,20 +441,20 @@ void main() { /// Returns a function that will cause the test to fail if it's called. /// /// This should only be called within a [FakeAsync.run] zone. -Function expectNoAsync() { - var stack = new Trace.current(1); +void Function() expectNoAsync() { + var stack = Trace.current(1); return () => registerException( - new TestFailure("Expected function not to be called."), stack); + TestFailure("Expected function not to be called."), stack); } /// A matcher for Futures that asserts that they don't complete. /// /// This should only be called within a [FakeAsync.run] zone. Matcher get doesNotComplete => predicate((future) { - expect(future, new TypeMatcher()); + expect(future, TypeMatcher()); - var stack = new Trace.current(1); + var stack = Trace.current(1); future.then((_) => registerException( - new TestFailure("Expected future not to complete."), stack)); + TestFailure("Expected future not to complete."), stack)); return true; }); From 78e15a61f29cd9e25c58c934e132b6e114158501 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 28 Dec 2018 15:24:33 -0800 Subject: [PATCH 262/657] Update Pool.withResource to use async/await (dart-lang/pool#21) Dart 2+ implements sync-async, so the root issue is no longer applicable A regression test exists to validate the behavior --- pkgs/pool/lib/pool.dart | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 416b14b73..a4a7d93ec 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -112,18 +112,17 @@ class Pool { /// Future. /// /// The return value of [callback] is piped to the returned Future. - Future withResource(FutureOr callback()) { + Future withResource(FutureOr callback()) async { if (isClosed) { throw StateError("withResource() may not be called on a closed Pool."); } - // We can't use async/await here because we need to start the request - // synchronously in case the pool is closed immediately afterwards. Async - // functions have an asynchronous gap between calling and running the body, - // and [close] could be called during that gap. See #3. - return request().then((resource) { - return Future.sync(callback).whenComplete(resource.release); - }); + var resource = await request(); + try { + return await callback(); + } finally { + resource.release(); + } } /// Closes the pool so that no more resources are requested. From 85c565435aa9f42f10d102a08efb982a94d4d8c9 Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 8 Jan 2019 00:25:08 +0200 Subject: [PATCH 263/657] Fix: Throw ArgumentError if poolSize <= 0 (dart-lang/pool#24) Fixes dart-lang/pool#20 --- pkgs/pool/lib/pool.dart | 4 ++++ pkgs/pool/test/pool_test.dart | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index a4a7d93ec..40a258054 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -79,6 +79,10 @@ class Pool { /// all pending [request] futures will throw a [TimeoutException]. This is /// intended to avoid deadlocks. Pool(this._maxAllocatedResources, {Duration timeout}) : _timeout = timeout { + if (_maxAllocatedResources <= 0) { + throw ArgumentError('pool limit should be > 0'); + } + if (timeout != null) { // Start the timer canceled since we only want to start counting down once // we've run out of available resources. diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index a156c521e..66624cf24 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -436,6 +436,11 @@ void main() { completer.completeError("oh no!"); }); }); + + test("throw error when pool limit <= 0", () { + expect(() => Pool(-1), throwsArgumentError); + expect(() => Pool(0), throwsArgumentError); + }); } /// Returns a function that will cause the test to fail if it's called. From 0424d6e87c46c7c0836fb80d12eb3f7910e765aa Mon Sep 17 00:00:00 2001 From: Ivan Date: Tue, 8 Jan 2019 00:48:29 +0200 Subject: [PATCH 264/657] Update CHANGELOG (dart-lang/pool#25) --- pkgs/pool/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 98805184a..10727a56d 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## x.x.x + +* Throw ArgumentError if poolSize <= 0 + ## 1.3.6 * Set max SDK version to `<3.0.0`, and adjust other dependencies. From e8cfb7f3e7163f7cc73c6704e9fb8038d084522d Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 7 Jan 2019 14:30:19 -0800 Subject: [PATCH 265/657] Throw a more descriptive ArgumentError for invalid maxAllocatedResources --- pkgs/pool/lib/pool.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 40a258054..6994c7606 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -80,7 +80,8 @@ class Pool { /// intended to avoid deadlocks. Pool(this._maxAllocatedResources, {Duration timeout}) : _timeout = timeout { if (_maxAllocatedResources <= 0) { - throw ArgumentError('pool limit should be > 0'); + throw ArgumentError.value(_maxAllocatedResources, 'maxAllocatedResources', + 'Must be greater than zero.'); } if (timeout != null) { From b0fce41b2bc78944ab541e16466bdc05a6b71a01 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 7 Jan 2019 14:33:05 -0800 Subject: [PATCH 266/657] enable and fix a number of lints --- pkgs/pool/analysis_options.yaml | 72 +++++++++++++++++++++++++++++++++ pkgs/pool/lib/pool.dart | 10 ++--- pkgs/pool/test/pool_test.dart | 4 +- 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index 749f62afe..f8eebb47a 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -4,8 +4,80 @@ analyzer: implicit-casts: false linter: rules: + - always_declare_return_types + - annotate_overrides + - avoid_empty_else + - avoid_function_literals_in_foreach_calls + - avoid_init_to_null + - avoid_null_checks_in_equality_operators + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null + - avoid_returning_null_for_future + - avoid_shadowing_type_parameters + - avoid_types_as_parameter_names + - avoid_unused_constructor_parameters - await_only_futures + - camel_case_types + - cancel_subscriptions + - comment_references + - constant_identifier_names + - control_flow_in_finally + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + - hash_and_equals - implementation_imports + - invariant_booleans + - iterable_contains_unrelated_type + - library_names + - library_prefixes + - list_remove_unrelated_type + - literal_only_boolean_expressions + - no_adjacent_strings_in_list + - no_duplicate_case_values + - non_constant_identifier_names + - null_closures + - omit_local_variable_types + - only_throw_errors + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + - prefer_adjacent_string_concatenation + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_contains + - prefer_equal_for_default_values + - prefer_final_fields + #- prefer_final_locals + - prefer_initializing_formals + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + #- prefer_single_quotes - prefer_typing_uninitialized_variables + - recursive_getters + - slash_for_doc_comments + - super_goes_last + - test_types_in_equals + - throw_in_finally + - type_init_formals + - unawaited_futures + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps - unnecessary_const + - unnecessary_getters_setters + - unnecessary_lambdas - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_this + - unrelated_type_equality_checks + - use_function_type_syntax_for_parameters + - use_rethrow_when_possible + - valid_regexps diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 6994c7606..a97ec75c2 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -117,7 +117,7 @@ class Pool { /// Future. /// /// The return value of [callback] is piped to the returned Future. - Future withResource(FutureOr callback()) async { + Future withResource(FutureOr Function() callback) async { if (isClosed) { throw StateError("withResource() may not be called on a closed Pool."); } @@ -174,7 +174,7 @@ class Pool { /// If there are any pending requests, this will fire the oldest one after /// running [onRelease]. - void _onResourceReleaseAllowed(onRelease()) { + void _onResourceReleaseAllowed(Function() onRelease) { _resetTimer(); if (_requestedResources.isNotEmpty) { @@ -196,7 +196,7 @@ class Pool { /// /// Futures returned by [_runOnRelease] always complete in the order they were /// created, even if earlier [onRelease] callbacks take longer to run. - Future _runOnRelease(onRelease()) { + Future _runOnRelease(Function() onRelease) { Future.sync(onRelease).then((value) { _onReleaseCompleters.removeFirst().complete(PoolResource._(this)); }).catchError((error, StackTrace stackTrace) { @@ -242,7 +242,7 @@ class Pool { class PoolResource { final Pool _pool; - /// Whether [this] has been released yet. + /// Whether `this` has been released yet. bool _released = false; PoolResource._(this._pool); @@ -269,7 +269,7 @@ class PoolResource { /// This is useful when a resource's main function is complete, but it may /// produce additional information later on. For example, an isolate's task /// may be complete, but it could still emit asynchronous errors. - void allowRelease(onRelease()) { + void allowRelease(Function() onRelease) { if (_released) { throw StateError("A PoolResource may only be released once."); } diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 66624cf24..6c9d0a56b 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -161,7 +161,7 @@ void main() { for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } - expect(pool.request(), throwsA(TypeMatcher())); + expect(pool.request(), throwsA(const TypeMatcher())); async.elapse(Duration(seconds: 6)); }); @@ -456,7 +456,7 @@ void Function() expectNoAsync() { /// /// This should only be called within a [FakeAsync.run] zone. Matcher get doesNotComplete => predicate((future) { - expect(future, TypeMatcher()); + expect(future, const TypeMatcher()); var stack = Trace.current(1); future.then((_) => registerException( From 2e815524c07349b076fc4f29bb6898dbd07d2647 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 8 Jan 2019 16:09:49 -0800 Subject: [PATCH 267/657] add forEach to Pool (dart-lang/pool#23) Fixes https://github.com/dart-lang/pool/issues/22 --- pkgs/pool/.travis.yml | 2 +- pkgs/pool/CHANGELOG.md | 5 +- pkgs/pool/lib/pool.dart | 97 +++++++++++ pkgs/pool/pubspec.yaml | 2 +- pkgs/pool/test/pool_test.dart | 316 ++++++++++++++++++++++++++++++++-- 5 files changed, 402 insertions(+), 20 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index a9b5166a4..07e132f33 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -7,7 +7,7 @@ dart_task: - test: --platform vm - test: --platform firefox - dartfmt - - dartanalyzer + - dartanalyzer: --fatal-infos --fatal-warnings . # Only building master means that we don't run two builds for each pull request. branches: diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 10727a56d..0c3d314a6 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,4 +1,7 @@ -## x.x.x +## 1.4.0 + +* Add `forEach` to `Pool` to support efficient async processing of an + `Iterable`. * Throw ArgumentError if poolSize <= 0 diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index a97ec75c2..779300e2b 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -130,6 +130,103 @@ class Pool { } } + /// Returns a [Stream] containing the result of [action] applied to each + /// element of [elements]. + /// + /// While [action] is invoked on each element of [elements] in order, + /// it's possible the return [Stream] may have items out-of-order – especially + /// if the completion time of [action] varies. + /// + /// If [action] throws an error the source item along with the error object + /// and [StackTrace] are passed to [onError], if it is provided. If [onError] + /// returns `true`, the error is added to the returned [Stream], otherwise + /// it is ignored. + /// + /// Errors thrown from iterating [elements] will not be passed to + /// [onError]. They will always be added to the returned stream as an error. + /// + /// Note: all of the resources of the this [Pool] will be used when the + /// returned [Stream] is listened to until it is completed or canceled. + /// + /// Note: if this [Pool] is closed before the returned [Stream] is listened + /// to, a [StateError] is thrown. + Stream forEach( + Iterable elements, FutureOr Function(S source) action, + {bool Function(S item, Object error, StackTrace stack) onError}) { + onError ??= (item, e, s) => true; + + var cancelPending = false; + + Completer resumeCompleter; + StreamController controller; + + Iterator iterator; + + Future run(int i) async { + while (iterator.moveNext()) { + // caching `current` is necessary because there are async breaks + // in this code and `iterator` is shared across many workers + final current = iterator.current; + + _resetTimer(); + + await resumeCompleter?.future; + + if (cancelPending) { + break; + } + + T value; + try { + value = await action(current); + } catch (e, stack) { + if (onError(current, e, stack)) { + controller.addError(e, stack); + } + continue; + } + controller.add(value); + } + } + + Future doneFuture; + + void onListen() { + assert(iterator == null); + iterator = elements.iterator; + + assert(doneFuture == null); + doneFuture = Future.wait( + Iterable.generate(_maxAllocatedResources) + .map((i) => withResource(() => run(i))), + eagerError: true) + .catchError(controller.addError); + + doneFuture.whenComplete(controller.close); + } + + controller = StreamController( + sync: true, + onListen: onListen, + onCancel: () async { + assert(!cancelPending); + cancelPending = true; + await doneFuture; + }, + onPause: () { + assert(resumeCompleter == null); + resumeCompleter = Completer(); + }, + onResume: () { + assert(resumeCompleter != null); + resumeCompleter.complete(); + resumeCompleter = null; + }, + ); + + return controller.stream; + } + /// Closes the pool so that no more resources are requested. /// /// Existing resource requests remain unchanged. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index a709842c9..095c38564 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.3.7-dev +version: 1.4.0-dev description: A class for managing a finite pool of resources. author: Dart Team diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 6c9d0a56b..d4d778992 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -27,7 +27,7 @@ void main() { } expect(pool.request(), doesNotComplete); - async.elapse(Duration(seconds: 1)); + async.elapse(const Duration(seconds: 1)); }); }); @@ -42,12 +42,12 @@ void main() { // This will only complete once [lastAllocatedResource] is released. expect(pool.request(), completes); - Future.delayed(Duration(microseconds: 1)).then((_) { + Future.delayed(const Duration(microseconds: 1)).then((_) { lastAllocatedResource.release(); }); }); - async.elapse(Duration(seconds: 1)); + async.elapse(const Duration(seconds: 1)); }); }); }); @@ -68,7 +68,7 @@ void main() { } pool.withResource(expectNoAsync()); - async.elapse(Duration(seconds: 1)); + async.elapse(const Duration(seconds: 1)); }); }); @@ -86,15 +86,15 @@ void main() { blockedResourceAllocated = true; }); - Future.delayed(Duration(microseconds: 1)).then((_) { + Future.delayed(const Duration(microseconds: 1)).then((_) { expect(blockedResourceAllocated, isFalse); completer.complete(); - return Future.delayed(Duration(microseconds: 1)); + return Future.delayed(const Duration(microseconds: 1)); }).then((_) { expect(blockedResourceAllocated, isTrue); }); - async.elapse(Duration(seconds: 1)); + async.elapse(const Duration(seconds: 1)); }); }); @@ -109,18 +109,18 @@ void main() { group("with a timeout", () { test("doesn't time out if there are no pending requests", () { FakeAsync().run((async) { - var pool = Pool(50, timeout: Duration(seconds: 5)); + var pool = Pool(50, timeout: const Duration(seconds: 5)); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } - async.elapse(Duration(seconds: 6)); + async.elapse(const Duration(seconds: 6)); }); }); test("resets the timer if a resource is returned", () { FakeAsync().run((async) { - var pool = Pool(50, timeout: Duration(seconds: 5)); + var pool = Pool(50, timeout: const Duration(seconds: 5)); for (var i = 0; i < 49; i++) { expect(pool.request(), completes); } @@ -129,41 +129,41 @@ void main() { // This will only complete once [lastAllocatedResource] is released. expect(pool.request(), completes); - Future.delayed(Duration(seconds: 3)).then((_) { + Future.delayed(const Duration(seconds: 3)).then((_) { lastAllocatedResource.release(); expect(pool.request(), doesNotComplete); }); }); - async.elapse(Duration(seconds: 6)); + async.elapse(const Duration(seconds: 6)); }); }); test("resets the timer if a resource is requested", () { FakeAsync().run((async) { - var pool = Pool(50, timeout: Duration(seconds: 5)); + var pool = Pool(50, timeout: const Duration(seconds: 5)); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } expect(pool.request(), doesNotComplete); - Future.delayed(Duration(seconds: 3)).then((_) { + Future.delayed(const Duration(seconds: 3)).then((_) { expect(pool.request(), doesNotComplete); }); - async.elapse(Duration(seconds: 6)); + async.elapse(const Duration(seconds: 6)); }); }); test("times out if nothing happens", () { FakeAsync().run((async) { - var pool = Pool(50, timeout: Duration(seconds: 5)); + var pool = Pool(50, timeout: const Duration(seconds: 5)); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } expect(pool.request(), throwsA(const TypeMatcher())); - async.elapse(Duration(seconds: 6)); + async.elapse(const Duration(seconds: 6)); }); }); }); @@ -437,6 +437,288 @@ void main() { }); }); + group('forEach', () { + Pool pool; + + tearDown(() async { + await pool.close(); + }); + + const delayedToStringDuration = Duration(milliseconds: 10); + + Future delayedToString(int i) => + Future.delayed(delayedToStringDuration, () => i.toString()); + + for (var itemCount in [0, 5]) { + for (var poolSize in [1, 5, 6]) { + test('poolSize: $poolSize, itemCount: $itemCount', () async { + pool = Pool(poolSize); + + var finishedItems = 0; + + await for (var item in pool.forEach( + Iterable.generate(itemCount, (i) { + expect(i, lessThanOrEqualTo(finishedItems + poolSize), + reason: 'the iterator should be called lazily'); + return i; + }), + delayedToString)) { + expect(int.parse(item), lessThan(itemCount)); + finishedItems++; + } + + expect(finishedItems, itemCount); + }); + } + } + + test('pool closed before listen', () async { + pool = Pool(2); + + var stream = pool.forEach(Iterable.generate(5), delayedToString); + + await pool.close(); + + expect(stream.toList(), throwsStateError); + }); + + test('completes even if the pool is partially used', () async { + pool = Pool(2); + + var resource = await pool.request(); + + var stream = pool.forEach([], delayedToString); + + expect(await stream.length, 0); + + resource.release(); + }); + + test('stream paused longer than timeout', () async { + pool = Pool(2, timeout: delayedToStringDuration); + + var resource = await pool.request(); + + var stream = pool.forEach( + Iterable.generate(100, (i) { + expect(i, lessThan(20), + reason: 'The timeout should happen ' + 'before the entire iterable is iterated.'); + return i; + }), (i) async { + await Future.delayed(Duration(milliseconds: i)); + return i; + }); + + await expectLater( + stream.toList, + throwsA(const TypeMatcher().having( + (te) => te.message, + 'message', + contains('Pool deadlock: ' + 'all resources have been allocated for too long.')))); + + resource.release(); + }); + + group('timing and timeout', () { + for (var poolSize in [2, 8, 64]) { + for (var otherTaskCount + in [0, 1, 7, 63].where((otc) => otc < poolSize)) { + test('poolSize: $poolSize, otherTaskCount: $otherTaskCount', + () async { + final itemCount = 128; + pool = Pool(poolSize, timeout: const Duration(milliseconds: 20)); + + var otherTasks = await Future.wait( + Iterable.generate(otherTaskCount) + .map((i) => pool.request())); + + try { + var finishedItems = 0; + + var watch = Stopwatch()..start(); + + await for (var item in pool.forEach( + Iterable.generate(itemCount, (i) { + expect(i, lessThanOrEqualTo(finishedItems + poolSize), + reason: 'the iterator should be called lazily'); + return i; + }), + delayedToString)) { + expect(int.parse(item), lessThan(itemCount)); + finishedItems++; + } + + expect(finishedItems, itemCount); + + final expectedElapsed = + delayedToStringDuration.inMicroseconds * 3; + + expect((watch.elapsed ~/ itemCount).inMicroseconds, + lessThan(expectedElapsed / (poolSize - otherTaskCount)), + reason: 'Average time per task should be ' + 'proportionate to the available pool resources.'); + } finally { + for (var task in otherTasks) { + task.release(); + } + } + }); + } + } + }, testOn: 'vm'); + + test('partial iteration', () async { + pool = Pool(5); + var stream = pool.forEach(Iterable.generate(100), delayedToString); + expect(await stream.take(10).toList(), hasLength(10)); + }); + + test('pool close during data with waiting to be done', () async { + pool = Pool(5); + + var stream = pool.forEach(Iterable.generate(100), delayedToString); + + var dataCount = 0; + var subscription = stream.listen((data) { + dataCount++; + pool.close(); + }); + + await subscription.asFuture(); + expect(dataCount, 100); + await subscription.cancel(); + }); + + test('pause and resume ', () async { + var generatedCount = 0; + var dataCount = 0; + final poolSize = 5; + + pool = Pool(poolSize); + + var stream = pool.forEach( + Iterable.generate(40, (i) { + expect(generatedCount, lessThanOrEqualTo(dataCount + 2 * poolSize), + reason: 'The iterator should not be called ' + 'much faster than the data is consumed.'); + generatedCount++; + return i; + }), + delayedToString); + + // ignore: cancel_subscriptions + StreamSubscription subscription; + + subscription = stream.listen( + (data) { + dataCount++; + + if (int.parse(data) % 3 == 1) { + subscription.pause(Future(() async { + await Future.delayed(const Duration(milliseconds: 100)); + })); + } + }, + onError: registerException, + onDone: expectAsync0(() { + expect(dataCount, 40); + }), + ); + }); + + group('cancel', () { + final dataSize = 32; + for (var i = 1; i < 5; i++) { + test('with pool size $i', () async { + pool = Pool(i); + + var stream = + pool.forEach(Iterable.generate(dataSize), delayedToString); + + var cancelCompleter = Completer(); + + StreamSubscription subscription; + + var eventCount = 0; + subscription = stream.listen((data) { + eventCount++; + if (int.parse(data) == dataSize ~/ 2) { + cancelCompleter.complete(); + } + }, onError: registerException); + + await cancelCompleter.future; + + await subscription.cancel(); + + expect(eventCount, 1 + dataSize ~/ 2); + }); + } + }); + + group('errors', () { + Future errorInIterator( + {bool Function(int item, Object error, StackTrace stack) + onError}) async { + pool = Pool(20); + + var listFuture = pool + .forEach( + Iterable.generate(100, (i) { + if (i == 50) { + throw StateError('error while generating item in iterator'); + } + + return i; + }), + delayedToString, + onError: onError) + .toList(); + + await expectLater(() async => listFuture, throwsStateError); + } + + test('iteration, no onError', () async { + await errorInIterator(); + }); + test('iteration, with onError', () async { + await errorInIterator(onError: (i, e, s) => false); + }); + + test('error in action, no onError', () async { + pool = Pool(20); + + var listFuture = pool.forEach(Iterable.generate(100), (i) async { + await Future.delayed(const Duration(milliseconds: 10)); + if (i == 10) { + throw UnsupportedError('10 is not supported'); + } + return i.toString(); + }).toList(); + + await expectLater(() async => listFuture, throwsUnsupportedError); + }); + + test('error in action, no onError', () async { + pool = Pool(20); + + var list = await pool.forEach(Iterable.generate(100), (i) async { + await Future.delayed(const Duration(milliseconds: 10)); + if (i % 10 == 0) { + throw UnsupportedError('Multiples of 10 not supported'); + } + return i.toString(); + }, + onError: (item, error, stack) => + error is! UnsupportedError).toList(); + + expect(list, hasLength(90)); + }); + }); + }); + test("throw error when pool limit <= 0", () { expect(() => Pool(-1), throwsArgumentError); expect(() => Pool(0), throwsArgumentError); From eb689f6e131c85e4a09f90839ae07c0788e03ab1 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 8 Jan 2019 17:06:06 -0800 Subject: [PATCH 268/657] Prepare for v1.4.0 release (dart-lang/pool#27) --- pkgs/pool/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 095c38564..248d9199b 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,12 +1,12 @@ name: pool -version: 1.4.0-dev +version: 1.4.0 description: A class for managing a finite pool of resources. author: Dart Team homepage: https://github.com/dart-lang/pool environment: - sdk: '>=2.0.0-dev.17.0 <3.0.0' + sdk: '>=2.0.0 <3.0.0' dependencies: async: '>=1.4.0 <3.0.0' From f29cfd07622c3374e7adceb8756eea2cb6590dd3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 8 Jan 2019 17:10:24 -0800 Subject: [PATCH 269/657] update description --- pkgs/pool/pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 248d9199b..c9e78cb77 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,7 +1,9 @@ name: pool version: 1.4.0 -description: A class for managing a finite pool of resources. +description: >- + Manage a finite pool of resources. + Useful for controlling concurrent I/O requests on the file system or network. author: Dart Team homepage: https://github.com/dart-lang/pool From ad6eef43088eb330ef3b327719683fad6459f757 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 8 Jan 2019 17:10:48 -0800 Subject: [PATCH 270/657] update description --- pkgs/pool/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index c9e78cb77..35fb62dee 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -3,7 +3,7 @@ version: 1.4.0 description: >- Manage a finite pool of resources. - Useful for controlling concurrent I/O requests on the file system or network. + Useful for controlling concurrent file system or network requests. author: Dart Team homepage: https://github.com/dart-lang/pool From 8aba87e8b2e939a532ff2f35614f3821ac830af7 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 10 Jan 2019 14:49:42 -0500 Subject: [PATCH 271/657] Format --- pkgs/source_span/lib/src/highlighter.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index a709d243a..17aa7b5f4 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -160,8 +160,7 @@ class Highlighter { _writeFirstLine(lines.first); var lastLineIndex = _span.end.line - _span.start.line; if (_multiline) { - _writeIntermediateLines( - lines.skip(1).take(lastLineIndex - 1)); + _writeIntermediateLines(lines.skip(1).take(lastLineIndex - 1)); _writeLastLine(lines[lastLineIndex]); } _writeTrailingLines(lines.skip(lastLineIndex + 1)); From 98b05ae788a8037becebd10c6da307bca20152a6 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 10 Jan 2019 14:50:14 -0500 Subject: [PATCH 272/657] More code review --- pkgs/source_span/lib/src/highlighter.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 17aa7b5f4..a05412a6f 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -127,8 +127,8 @@ class Highlighter { _writeSidebar(end: glyph.downEnd); _buffer.writeln(); - // If [context] contains lines prior to the one [text] appears on, write - // those first. + // If [_span.context] contains lines prior to the one [_span.text] appears + // on, write those first. var lineStart = findLineStart(_span.context, _span.text, _span.start.column); assert(lineStart != null); // enforced by [new Highlighter] From a526c2d57bbb60fbdbaa02c97fb6fc369dc989d2 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 10 Jan 2019 15:45:57 -0800 Subject: [PATCH 273/657] Add basic forEach benchmark --- pkgs/pool/benchmark/for_each_benchmark.dart | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 pkgs/pool/benchmark/for_each_benchmark.dart diff --git a/pkgs/pool/benchmark/for_each_benchmark.dart b/pkgs/pool/benchmark/for_each_benchmark.dart new file mode 100644 index 000000000..7438ace78 --- /dev/null +++ b/pkgs/pool/benchmark/for_each_benchmark.dart @@ -0,0 +1,51 @@ +import 'package:pool/pool.dart'; + +void main(List args) async { + var poolSize = args.isEmpty ? 5 : int.parse(args.first); + print('Pool size: $poolSize'); + + final pool = Pool(poolSize); + final watch = Stopwatch()..start(); + final start = DateTime.now(); + + DateTime lastLog; + Duration fastest; + int fastestIteration; + var i = 1; + + void log(bool force) { + var now = DateTime.now(); + if (force || + lastLog == null || + now.difference(lastLog) > const Duration(seconds: 1)) { + lastLog = now; + print([ + now.difference(start), + i.toString().padLeft(10), + fastestIteration.toString().padLeft(7), + fastest.inMicroseconds.toString().padLeft(9) + ].join(' ')); + } + } + + print(['Elapsed ', 'Iterations', 'Fastest', 'Time (us)'].join(' ')); + + for (;; i++) { + watch.reset(); + + var sum = await pool + .forEach(Iterable.generate(100000), (i) => i) + .reduce((a, b) => a + b); + + assert(sum == 4999950000, 'was $sum'); + + var elapsed = watch.elapsed; + if (fastest == null || fastest > elapsed) { + fastest = elapsed; + fastestIteration = i; + log(true); + } else { + log(false); + } + } +} From 41a61d57d361e1194c40f5a04c5d563969f9fe77 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 10 Jan 2019 15:49:29 -0800 Subject: [PATCH 274/657] fix `await null` in forEach Benchmark goes from ~54ms to ~33ms --- pkgs/pool/CHANGELOG.md | 5 +++++ pkgs/pool/lib/pool.dart | 4 +++- pkgs/pool/pubspec.yaml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 0c3d314a6..c680dd2bf 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.4.1 + +* `forEach`: Avoid `await null` if the `Stream` is not paused. + Improves trivial benchmark by 40%. + ## 1.4.0 * Add `forEach` to `Pool` to support efficient async processing of an diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 779300e2b..12dd5e1b0 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -170,7 +170,9 @@ class Pool { _resetTimer(); - await resumeCompleter?.future; + if (resumeCompleter != null) { + await resumeCompleter.future; + } if (cancelPending) { break; diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 35fb62dee..ebb05d9a2 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.4.0 +version: 1.4.1-dev description: >- Manage a finite pool of resources. From ecec3a2a2c11915613c08a745700573905d0570e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 11 Jan 2019 17:07:30 -0800 Subject: [PATCH 275/657] Improve FileSpan.context Previously, if FileSpan.end was directly after a newline, FileSpan.context would include the entire next line in the span. Then when this span was highlighted, the end would point confusingly to the beginning of that next line. --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/file.dart | 25 +++++++++++++++++++++-- pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/highlight_test.dart | 13 +++++++++++- 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 2248a3937..74ab342af 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.5.1 + +* Produce better source span highlights for multi-line spans that cover the + entire last line of the span, including the newline. + # 1.5.0 * Improve the output of `SourceSpan.highlight()` and `SourceSpan.message()`: diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 6154e1343..18c46e66c 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -291,8 +291,29 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { FileLocation get start => new FileLocation._(file, _start); FileLocation get end => new FileLocation._(file, _end); String get text => file.getText(_start, _end); - String get context => file.getText(file.getOffset(start.line), - end.line == file.lines - 1 ? null : file.getOffset(end.line + 1)); + + String get context { + var endLine = file.getLine(_end); + var endColumn = file.getColumn(_end); + + 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 + // context. + endOffset = _end; + } else if (endLine == file.lines - 1) { + // If the span covers the last line of the file, the context should go all + // the way to the end of the file. + endOffset = file.length; + } else { + // Otherwise, the context should cover the full line on which [end] + // appears. + endOffset = file.getOffset(endLine + 1); + } + + return file.getText(file.getOffset(file.getLine(_start)), endOffset); + } _FileSpan(this.file, this._start, this._end) { if (_end < _start) { diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index ebd3a72a4..fc5ba2b5b 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.0 +version: 1.5.1 description: A library for identifying source spans and locations. author: Dart Team diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 19f8ca815..71b58c382 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -158,6 +158,15 @@ zip zap zop }); test("highlights the full last line", () { + expect(file.span(4, 27).highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | \\ whiz bang boom + '""")); + }); + + test("highlights the full last line with no trailing newline", () { expect(file.span(4, 26).highlight(), equals(""" , 1 | foo bar baz @@ -176,7 +185,9 @@ zip zap zop '""")); }); - test("highlights the full last line with no trailing newline", () { + test( + "highlights the full last line at the end of the file with no trailing" + " newline", () { var file = new SourceFile.fromString(""" foo bar baz whiz bang boom From 219ded1bc95deb0fa6660971ff31118cf689a85f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 11 Jan 2019 17:22:23 -0800 Subject: [PATCH 276/657] Make sure all full-line spans are highlighted properly Even if the context covers lines after the fully-covered line, the span shouldn't point to them. --- pkgs/source_span/lib/src/highlighter.dart | 16 ++++++ pkgs/source_span/test/highlight_test.dart | 66 +++++++++++++++++------ 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index a05412a6f..97d696d50 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -99,6 +99,22 @@ class Highlighter { newSpan = new SourceSpanWithContext(start, end, text, context); } + // Normalize [span] so that the end location is at the end of a line, rather + // than on the beginning of the next line. + if (newSpan.end.column == 0 && newSpan.end.line != newSpan.start.line) { + assert(newSpan.text.endsWith("\n")); + + var text = newSpan.text.substring(0, newSpan.text.length - 1); + newSpan = new SourceSpanWithContext( + newSpan.start, + new SourceLocation(span.end.offset - 1, + sourceUrl: span.sourceUrl, + line: span.end.line - 1, + column: _lastColumn(text)), + text, + newSpan.context); + } + return new Highlighter._(newSpan, color); } diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 71b58c382..e2536ba10 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -316,21 +316,57 @@ whiz bang\tboom }); }); - test("supports lines of preceding and following context", () { - var span = new SourceSpanWithContext( - new SourceLocation(5, line: 2, column: 5, sourceUrl: "foo.dart"), - new SourceLocation(12, line: 2, column: 12, sourceUrl: "foo.dart"), - "foo bar", - "previous\nlines\n-----foo bar-----\nfollowing line\n"); - - expect(span.highlight(color: colors.YELLOW), equals(""" -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} previous -${colors.BLUE}2 |${colors.NONE} lines -${colors.BLUE}3 |${colors.NONE} -----${colors.YELLOW}foo bar${colors.NONE}----- -${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^^^^^${colors.NONE} -${colors.BLUE}4 |${colors.NONE} following line -${colors.BLUE} '${colors.NONE}""")); + group("supports lines of preceding and following context for a span", () { + test("within a single line", () { + var span = new SourceSpanWithContext( + new SourceLocation(20, line: 2, column: 5, sourceUrl: "foo.dart"), + new SourceLocation(27, line: 2, column: 12, sourceUrl: "foo.dart"), + "foo bar", + "previous\nlines\n-----foo bar-----\nfollowing line\n"); + + expect(span.highlight(), equals(""" + , +1 | previous +2 | lines +3 | -----foo bar----- + | ^^^^^^^ +4 | following line + '""")); + }); + + test("covering a full line", () { + var span = new SourceSpanWithContext( + new SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), + new SourceLocation(33, line: 3, column: 0, sourceUrl: "foo.dart"), + "-----foo bar-----\n", + "previous\nlines\n-----foo bar-----\nfollowing line\n"); + + expect(span.highlight(), equals(""" + , +1 | previous +2 | lines +3 | -----foo bar----- + | ^^^^^^^^^^^^^^^^^ +4 | following line + '""")); + }); + + test("covering multiple full lines", () { + var span = new SourceSpanWithContext( + new SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), + new SourceLocation(23, line: 4, column: 0, sourceUrl: "foo.dart"), + "foo\nbar\n", + "previous\nlines\nfoo\nbar\nfollowing line\n"); + + expect(span.highlight(), equals(""" + , +1 | previous +2 | lines +3 | / foo +4 | \\ bar +5 | following line + '""")); + }); }); group("colors", () { From 8bb0c145ed5ed3734a40146b2378d50c4cebb59c Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 11 Jan 2019 18:05:30 -0800 Subject: [PATCH 277/657] Mark this as a dev version --- pkgs/source_span/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index fc5ba2b5b..13fa6481d 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.1 +version: 1.5.1-dev description: A library for identifying source spans and locations. author: Dart Team From dbe9b972ec57452513ea992fa60f082fdd739c90 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 12 Jan 2019 01:34:25 -0500 Subject: [PATCH 278/657] Refactor highlighter normalizations --- pkgs/source_span/lib/src/highlighter.dart | 119 ++++++++++++---------- 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 97d696d50..62709128f 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -58,64 +58,73 @@ class Highlighter { if (color == true) color = colors.RED; if (color == false) color = null; - // Normalize [span] to ensure that it's a [SourceSpanWithContext] whose - // context actually contains its text at the expected column. If it's not, - // adjust the start and end locations' line and column fields so that the - // highlighter can assume they match up with the context. - SourceSpanWithContext newSpan; - if (span is SourceSpanWithContext && - findLineStart(span.context, span.text, span.start.column) != null) { - newSpan = span; - } else { - newSpan = new SourceSpanWithContext( - new SourceLocation(span.start.offset, - sourceUrl: span.sourceUrl, line: 0, column: 0), - new SourceLocation(span.end.offset, - sourceUrl: span.sourceUrl, - line: countCodeUnits(span.text, $lf), - column: _lastColumn(span.text)), - span.text, - span.text); - } + var newSpan = _normalizeContext(span); + newSpan = _normalizeTrailingNewline(newSpan); + newSpan = _normalizeEndOfLine(newSpan); - // Normalize [span] to remove a trailing newline from `span.context`. If - // necessary, also adjust `span.end` so that it doesn't point past where the - // trailing newline used to be. - if (newSpan.context.endsWith("\n")) { - var context = newSpan.context.substring(0, newSpan.context.length - 1); - - var text = newSpan.text; - var start = newSpan.start; - var end = newSpan.end; - if (newSpan.text.endsWith("\n") && _isTextAtEndOfContext(newSpan)) { - text = newSpan.text.substring(0, newSpan.text.length - 1); - end = new SourceLocation(newSpan.end.offset - 1, - sourceUrl: newSpan.sourceUrl, - line: newSpan.end.line - 1, - column: _lastColumn(text)); - start = - newSpan.start.offset == newSpan.end.offset ? end : newSpan.start; - } - newSpan = new SourceSpanWithContext(start, end, text, context); - } + return new Highlighter._(newSpan, color); + } - // Normalize [span] so that the end location is at the end of a line, rather - // than on the beginning of the next line. - if (newSpan.end.column == 0 && newSpan.end.line != newSpan.start.line) { - assert(newSpan.text.endsWith("\n")); - - var text = newSpan.text.substring(0, newSpan.text.length - 1); - newSpan = new SourceSpanWithContext( - newSpan.start, - new SourceLocation(span.end.offset - 1, - sourceUrl: span.sourceUrl, - line: span.end.line - 1, - column: _lastColumn(text)), - text, - newSpan.context); + /// Normalizes [span] to ensure that it's a [SourceSpanWithContext] whose + /// context actually contains its text at the expected column. + /// + /// If it's not already a [SourceSpanWithContext], adjust the start and end + /// locations' line and column fields so that the highlighter can assume they + /// match up with the context. + static SourceSpanWithContext _normalizeContext(SourceSpan span) => + span is SourceSpanWithContext && + findLineStart(span.context, span.text, span.start.column) != null + ? span + : new SourceSpanWithContext( + new SourceLocation(span.start.offset, + sourceUrl: span.sourceUrl, line: 0, column: 0), + new SourceLocation(span.end.offset, + sourceUrl: span.sourceUrl, + line: countCodeUnits(span.text, $lf), + column: _lastColumn(span.text)), + span.text, + span.text); + + /// Normalizes [span] to remove a trailing newline from `span.context`. + /// + /// If necessary, also adjust `span.end` so that it doesn't point past where + /// the trailing newline used to be. + static SourceSpanWithContext _normalizeTrailingNewline( + SourceSpanWithContext span) { + if (!span.context.endsWith("\n")) return span; + + var context = span.context.substring(0, span.context.length - 1); + var text = span.text; + var start = span.start; + var end = span.end; + if (span.text.endsWith("\n") && _isTextAtEndOfContext(span)) { + text = span.text.substring(0, span.text.length - 1); + end = new SourceLocation(span.end.offset - 1, + sourceUrl: span.sourceUrl, + line: span.end.line - 1, + column: _lastColumn(text)); + start = span.start.offset == span.end.offset ? end : span.start; } + return new SourceSpanWithContext(start, end, text, context); + } - return new Highlighter._(newSpan, color); + /// Normalizes [span] so that the end location is at the end of a line, rather + /// than on the beginning of the next line. + static SourceSpanWithContext _normalizeEndOfLine(SourceSpanWithContext span) { + if (span.end.column != 0) return span; + if (span.end.line == span.start.line) return span; + + assert(span.text.endsWith("\n")); + + var text = span.text.substring(0, span.text.length - 1); + return new SourceSpanWithContext( + span.start, + new SourceLocation(span.end.offset - 1, + sourceUrl: span.sourceUrl, + line: span.end.line - 1, + column: _lastColumn(text)), + text, + span.context); } /// Returns the (0-based) column number of the last column of the last line in [text]. @@ -147,7 +156,7 @@ class Highlighter { // on, write those first. var lineStart = findLineStart(_span.context, _span.text, _span.start.column); - assert(lineStart != null); // enforced by [new Highlighter] + assert(lineStart != null); // enforced by [_normalizeContext] var context = _span.context; if (lineStart > 0) { From d57354a31c779fef63b03ce760aabdc0455b1346 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Sat, 12 Jan 2019 02:17:15 -0500 Subject: [PATCH 279/657] Produce better highlights for Windows newlines --- pkgs/source_span/CHANGELOG.md | 3 +++ pkgs/source_span/lib/src/highlighter.dart | 24 +++++++++++++++++++++++ pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/highlight_test.dart | 19 ++++++++++++++++-- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 74ab342af..489f01a72 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -3,6 +3,9 @@ * Produce better source span highlights for multi-line spans that cover the entire last line of the span, including the newline. +* Produce better source span highlights for spans that contain Windows-style + newlines. + # 1.5.0 * Improve the output of `SourceSpan.highlight()` and `SourceSpan.message()`: diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 62709128f..3ed1749b8 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -59,6 +59,7 @@ class Highlighter { if (color == false) color = null; var newSpan = _normalizeContext(span); + newSpan = _normalizeNewlines(newSpan); newSpan = _normalizeTrailingNewline(newSpan); newSpan = _normalizeEndOfLine(newSpan); @@ -85,6 +86,29 @@ class Highlighter { span.text, span.text); + /// Normalizes [span] to replace Windows-style newlines with Unix-style + /// newlines. + static SourceSpanWithContext _normalizeNewlines(SourceSpanWithContext span) { + var text = span.text; + if (!text.contains("\r\n")) return span; + + var endOffset = span.end.offset; + for (var i = 0; i < text.length - 1; i++) { + if (text.codeUnitAt(i) == $cr && text.codeUnitAt(i + 1) == $lf) { + endOffset--; + } + } + + return new SourceSpanWithContext( + span.start, + new SourceLocation(endOffset, + sourceUrl: span.sourceUrl, + line: span.end.line, + column: span.end.column), + text.replaceAll("\r\n", "\n"), + span.context.replaceAll("\r\n", "\n")); + } + /// Normalizes [span] to remove a trailing newline from `span.context`. /// /// If necessary, also adjust `span.end` so that it doesn't point past where diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 13fa6481d..fc5ba2b5b 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.1-dev +version: 1.5.1 description: A library for identifying source spans and locations. author: Dart Team diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index e2536ba10..b9e7ded87 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -175,6 +175,21 @@ zip zap zop '""")); }); + test("highlights the full last line with a trailing Windows newline", () { + var file = new SourceFile.fromString(""" +foo bar baz\r +whiz bang boom\r +zip zap zop\r +"""); + + expect(file.span(4, 29).highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | \\ whiz bang boom + '""")); + }); + test("highlights the full last line at the end of the file", () { expect(file.span(4, 39).highlight(), equals(""" , @@ -186,8 +201,8 @@ zip zap zop }); test( - "highlights the full last line at the end of the file with no trailing" - " newline", () { + "highlights the full last line at the end of the file with no trailing " + "newline", () { var file = new SourceFile.fromString(""" foo bar baz whiz bang boom From 1679e1f7f3ceab6f5c6f7ca6410b662c0b692a41 Mon Sep 17 00:00:00 2001 From: Evan Weible Date: Thu, 17 Jan 2019 14:07:13 -0700 Subject: [PATCH 280/657] SourceFile.span() should include last char when end offset omitted (dart-lang/source_span#28) --- pkgs/source_span/CHANGELOG.md | 6 ++++++ pkgs/source_span/lib/src/file.dart | 2 +- pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/file_test.dart | 6 +++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 489f01a72..44c3ca5ed 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.5.2 + +* `SourceFile.span()` now goes to the end of the file by default, rather than + ending one character before the end of the file. This matches the documented + behavior. + # 1.5.1 * Produce better source span highlights for multi-line spans that cover the diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 18c46e66c..3941042f5 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -88,7 +88,7 @@ class SourceFile { /// /// If [end] isn't passed, it defaults to the end of the file. FileSpan span(int start, [int end]) { - if (end == null) end = length - 1; + if (end == null) end = length; return new _FileSpan(this, start, end); } diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index fc5ba2b5b..ffd9df32b 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.1 +version: 1.5.2-dev description: A library for identifying source spans and locations. author: Dart Team diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 071f3f9d7..3f32a3cf5 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -157,7 +157,7 @@ zip zap zop""", url: "bar.dart").span(10, 11); test("end defaults to the end of the file", () { var span = file.span(5); expect(span.start, equals(file.location(5))); - expect(span.end, equals(file.location(file.length - 1))); + expect(span.end, equals(file.location(file.length))); }); }); @@ -253,6 +253,10 @@ zip zap zop""", url: "bar.dart").span(10, 11); expect(file.span(8, 15).text, equals("baz\nwhi")); }); + test("text includes the last char when end is defaulted to EOF", () { + expect(file.span(29).text, equals("p zap zop")); + }); + test("context contains the span's text", () { var span = file.span(8, 15); expect(span.context.contains(span.text), isTrue); From 6978f7eecbdbc70115442606f1daa478d3c9e914 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 17 Jan 2019 16:44:06 -0500 Subject: [PATCH 281/657] Make FileSpan.context include the full line for all point spans Previously, if a point span appeared at the beginning of a line or at the end of the last line of the file, FileSpan.context returned an empty string. --- pkgs/source_span/CHANGELOG.md | 3 +++ pkgs/source_span/lib/src/file.dart | 12 ++++++++- pkgs/source_span/test/file_test.dart | 40 +++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 44c3ca5ed..67ba8d5d9 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -4,6 +4,9 @@ ending one character before the end of the file. This matches the documented behavior. +* `FileSpan.context` now includes the full line on which the span appears for + empty spans at the beginning and end of lines. + # 1.5.1 * Produce better source span highlights for multi-line spans that cover the diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 3941042f5..ec4db63bc 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -300,7 +300,17 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { 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 - // context. + // context... + + if (length == 0) { + // ...unless this is a point span, in which case we want to include the + // next line (or the last line if this is the end of the file). + return endLine == file.lines - 1 + ? file.getText(file.getOffset(endLine - 1)) + : file.getText( + file.getOffset(endLine), file.getOffset(endLine + 1)); + } + endOffset = _end; } else if (endLine == file.lines - 1) { // If the span covers the last line of the file, the context should go all diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 3f32a3cf5..117458d10 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -257,10 +257,42 @@ zip zap zop""", url: "bar.dart").span(10, 11); expect(file.span(29).text, equals("p zap zop")); }); - test("context contains the span's text", () { - var span = file.span(8, 15); - expect(span.context.contains(span.text), isTrue); - expect(span.context, equals('foo bar baz\nwhiz bang boom\n')); + group("context", () { + test("contains the span's text", () { + var span = file.span(8, 15); + expect(span.context.contains(span.text), isTrue); + expect(span.context, equals('foo bar baz\nwhiz bang boom\n')); + }); + + test("contains the previous line for a point span at the end of a line", + () { + var span = file.span(25, 25); + expect(span.context, equals('whiz bang boom\n')); + }); + + test("contains the next line for a point span at the beginning of a line", + () { + var span = file.span(12, 12); + expect(span.context, equals('whiz bang boom\n')); + }); + + group("contains the last line for a point span at the end of a file", () { + test("without a newline", () { + var span = file.span(file.length, file.length); + expect(span.context, equals('zip zap zop')); + }); + + test("with a newline", () { + file = new SourceFile.fromString(""" +foo bar baz +whiz bang boom +zip zap zop +""", url: "foo.dart"); + + var span = file.span(file.length, file.length); + expect(span.context, equals('zip zap zop\n')); + }); + }); }); group("union()", () { From 16c9fd3d523d76a008d1df768dfaaa832f0c0aa2 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 17 Jan 2019 17:09:13 -0500 Subject: [PATCH 282/657] Don't crash on spans that end on empty lines --- pkgs/source_span/CHANGELOG.md | 3 +++ pkgs/source_span/lib/src/highlighter.dart | 10 ++++---- pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/highlight_test.dart | 28 +++++++++++++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 67ba8d5d9..afba8b744 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -7,6 +7,9 @@ * `FileSpan.context` now includes the full line on which the span appears for empty spans at the beginning and end of lines. +* Fix an edge case where `FileSpan.highlight()` could crash when highlighting a + span that ended with an empty line. + # 1.5.1 * Produce better source span highlights for multi-line spans that cover the diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 3ed1749b8..f29a89d6d 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -202,12 +202,14 @@ class Highlighter { var lines = context.split("\n"); - // Trim a trailing newline so we don't add an empty line to the end of the - // highlight. - if (lines.last.isEmpty && lines.length > 1) lines.removeLast(); + var lastLineIndex = _span.end.line - _span.start.line; + if (lines.last.isEmpty && lines.length > lastLineIndex + 1) { + // Trim a trailing newline so we don't add an empty line to the end of the + // highlight. + lines.removeLast(); + } _writeFirstLine(lines.first); - var lastLineIndex = _span.end.line - _span.start.line; if (_multiline) { _writeIntermediateLines(lines.skip(1).take(lastLineIndex - 1)); _writeLastLine(lines[lastLineIndex]); diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index ffd9df32b..fd80bc851 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.2-dev +version: 1.5.2 description: A library for identifying source spans and locations. author: Dart Team diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index b9e7ded87..8418367f7 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -154,6 +154,20 @@ zip zap zop 2 | | whiz bang boom 3 | | zip zap zop | '-------^ + '""")); + }); + + test("highlights the full last line if it's empty", () { + var file = new SourceFile.fromString(""" +foo + +bar +"""); + + expect(file.span(4, 9).highlight(), equals(""" + , +2 | / +3 | \\ bar '""")); }); @@ -214,6 +228,20 @@ zip zap zop"""); | ,-----^ 2 | | whiz bang boom 3 | \\ zip zap zop + '""")); + }); + + test("highlights the full last line if it's empty", () { + var file = new SourceFile.fromString(""" +foo + +bar +"""); + + expect(file.span(0, 5).highlight(), equals(""" + , +1 | / foo +2 | \\ '""")); }); }); From 45587fef3f4e664d36fb849eb59a6d4be4df28ac Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 17 Jan 2019 18:07:45 -0500 Subject: [PATCH 283/657] Support dart-lang/source_spandart-lang/source_maps#25 (dart-lang/source_maps#33) Close dart-lang/source_maps#32 --- pkgs/source_maps/pubspec.yaml | 1 + pkgs/source_maps/test/refactor_test.dart | 101 ++++++++++++++++------- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 49ab53da1..3e41803ba 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -13,3 +13,4 @@ dependencies: dev_dependencies: test: ^1.2.0 + term_glyph: ^1.0.0 diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index afaeec26e..857d30dce 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -8,8 +8,13 @@ import 'package:test/test.dart'; import 'package:source_maps/refactor.dart'; import 'package:source_maps/parser.dart' show parse, Mapping; import 'package:source_span/source_span.dart'; +import 'package:term_glyph/term_glyph.dart' as term_glyph; main() { + setUpAll(() { + term_glyph.ascii = true; + }); + group('conflict detection', () { var original = "0123456789abcdefghij"; var file = new SourceFile(original); @@ -64,48 +69,64 @@ main() { expect( _span(1, 1, map, file), "line 1, column 1: \n" - "0123456789\n" - "^"); + " ,\n" + "1 | 0123456789\n" + " | ^\n" + " '"); expect( _span(1, 5, map, file), "line 1, column 1: \n" - "0123456789\n" - "^"); + " ,\n" + "1 | 0123456789\n" + " | ^\n" + " '"); expect( _span(2, 1, map, file), "line 2, column 1: \n" - "0*23456789\n" - "^"); + " ,\n" + "2 | 0*23456789\n" + " | ^\n" + " '"); expect( _span(2, 8, map, file), "line 2, column 1: \n" - "0*23456789\n" - "^"); + " ,\n" + "2 | 0*23456789\n" + " | ^\n" + " '"); // Line 3 is modified part way: mappings before the edits have the right // mapping, after the edits the mapping is null. expect( _span(3, 1, map, file), "line 3, column 1: \n" - "01*3456789\n" - "^"); + " ,\n" + "3 | 01*3456789\n" + " | ^\n" + " '"); expect( _span(3, 5, map, file), "line 3, column 1: \n" - "01*3456789\n" - "^"); + " ,\n" + "3 | 01*3456789\n" + " | ^\n" + " '"); // Start of edits map to beginning of the edit secion: expect( _span(3, 6, map, file), "line 3, column 6: \n" - "01*3456789\n" - " ^"); + " ,\n" + "3 | 01*3456789\n" + " | ^\n" + " '"); expect( _span(3, 7, map, file), "line 3, column 6: \n" - "01*3456789\n" - " ^"); + " ,\n" + "3 | 01*3456789\n" + " | ^\n" + " '"); // Lines added have no mapping (they should inherit the last mapping), // but the end of the edit region continues were we left off: @@ -113,50 +134,66 @@ main() { expect( _span(4, 5, map, file), "line 3, column 8: \n" - "01*3456789\n" - " ^"); + " ,\n" + "3 | 01*3456789\n" + " | ^\n" + " '"); // Subsequent lines are still mapped correctly: // a (in a___cd...) expect( _span(5, 1, map, file), "line 4, column 1: \n" - "abcdefghij\n" - "^"); + " ,\n" + "4 | abcdefghij\n" + " | ^\n" + " '"); // _ (in a___cd...) expect( _span(5, 2, map, file), "line 4, column 2: \n" - "abcdefghij\n" - " ^"); + " ,\n" + "4 | abcdefghij\n" + " | ^\n" + " '"); // _ (in a___cd...) expect( _span(5, 3, map, file), "line 4, column 2: \n" - "abcdefghij\n" - " ^"); + " ,\n" + "4 | abcdefghij\n" + " | ^\n" + " '"); // _ (in a___cd...) expect( _span(5, 4, map, file), "line 4, column 2: \n" - "abcdefghij\n" - " ^"); + " ,\n" + "4 | abcdefghij\n" + " | ^\n" + " '"); // c (in a___cd...) expect( _span(5, 5, map, file), "line 4, column 3: \n" - "abcdefghij\n" - " ^"); + " ,\n" + "4 | abcdefghij\n" + " | ^\n" + " '"); expect( _span(6, 1, map, file), "line 5, column 1: \n" - "abcd*fghij\n" - "^"); + " ,\n" + "5 | abcd*fghij\n" + " | ^\n" + " '"); expect( _span(6, 8, map, file), "line 5, column 1: \n" - "abcd*fghij\n" - "^"); + " ,\n" + "5 | abcd*fghij\n" + " | ^\n" + " '"); }); } From 4c07f419ea9dd14fc573f5efb34ced3d7e79f62e Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 23 Jan 2019 19:49:51 -0500 Subject: [PATCH 284/657] Fix a bug when highlighting an end-of-file point span (dart-lang/source_span#30) --- pkgs/source_span/CHANGELOG.md | 6 +++ pkgs/source_span/lib/src/highlighter.dart | 57 ++++++++++++++++------- pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/highlight_test.dart | 29 +++++++++++- 4 files changed, 74 insertions(+), 20 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index afba8b744..6e79fbc46 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.5.3 + +* Fix an edge case where `FileSpan.highlight()` would put the highlight + indicator in the wrong position when highlighting a point span after the end + of a file. + # 1.5.2 * `SourceFile.span()` now goes to the end of the file by default, rather than diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index f29a89d6d..8100f1839 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -82,7 +82,7 @@ class Highlighter { new SourceLocation(span.end.offset, sourceUrl: span.sourceUrl, line: countCodeUnits(span.text, $lf), - column: _lastColumn(span.text)), + column: _lastLineLength(span.text)), span.text, span.text); @@ -126,34 +126,55 @@ class Highlighter { end = new SourceLocation(span.end.offset - 1, sourceUrl: span.sourceUrl, line: span.end.line - 1, - column: _lastColumn(text)); + column: _lastLineLength(text)); start = span.start.offset == span.end.offset ? end : span.start; } return new SourceSpanWithContext(start, end, text, context); } - /// Normalizes [span] so that the end location is at the end of a line, rather - /// than on the beginning of the next line. + /// Normalizes [span] so that the end location is at the end of a line rather + /// than at the beginning of the next line. static SourceSpanWithContext _normalizeEndOfLine(SourceSpanWithContext span) { if (span.end.column != 0) return span; - if (span.end.line == span.start.line) return span; - assert(span.text.endsWith("\n")); + if (span.length == 0) { + if (span.end.offset == 0) return span; - var text = span.text.substring(0, span.text.length - 1); - return new SourceSpanWithContext( - span.start, - new SourceLocation(span.end.offset - 1, - sourceUrl: span.sourceUrl, - line: span.end.line - 1, - column: _lastColumn(text)), - text, - span.context); + // If [span] is a point span with an empty context, there's no useful + // adjustment we can do. + if (span.context.isEmpty) return span; + + var location = new SourceLocation(span.end.offset - 1, + sourceUrl: span.sourceUrl, + line: span.end.line - 1, + column: _lastLineLength(span.context)); + return new SourceSpanWithContext(location, location, "", span.context); + } else { + if (span.end.line == span.start.line) return span; + + var text = span.text.substring(0, span.text.length - 1); + + return new SourceSpanWithContext( + span.start, + new SourceLocation(span.end.offset - 1, + sourceUrl: span.sourceUrl, + line: span.end.line - 1, + column: _lastLineLength(text)), + text, + span.context); + } } - /// Returns the (0-based) column number of the last column of the last line in [text]. - static int _lastColumn(String text) => - text.length - text.lastIndexOf("\n") + 1; + /// Returns the length of the last line in [text], whether or not it ends in a + /// newline. + static int _lastLineLength(String text) { + if (text.isEmpty) return 0; + + // The "- 1" here avoids counting the newline itself. + return text.codeUnitAt(text.length - 1) == $lf + ? text.length - text.lastIndexOf("\n", text.length - 2) - 1 + : text.length - text.lastIndexOf("\n") - 1; + } /// Returns whether [span]'s text runs all the way to the end of its context. static bool _isTextAtEndOfContext(SourceSpanWithContext span) => diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index fd80bc851..c4b4ccfdc 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.2 +version: 1.5.3 description: A library for identifying source spans and locations. author: Dart Team diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 8418367f7..7832e5106 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -53,6 +53,14 @@ zip zap zop '""")); }); + test("works for a point span at the beginning of the file", () { + expect(file.location(0).pointSpan().highlight(), equals(""" + , +1 | foo bar baz + | ^ + '""")); + }); + test("works for a point span at the end of a line", () { expect(file.location(11).pointSpan().highlight(), equals(""" , @@ -69,9 +77,28 @@ zip zap zop '""")); }); + test("works for a point span after the end of the file", () { + expect(file.location(39).pointSpan().highlight(), equals(""" + , +3 | zip zap zop + | ^ + '""")); + }); + test("works for a point span at the end of the file with no trailing newline", () { file = new SourceFile.fromString("zip zap zop"); + expect(file.location(10).pointSpan().highlight(), equals(""" + , +1 | zip zap zop + | ^ + '""")); + }); + + test( + "works for a point span after the end of the file with no trailing newline", + () { + file = new SourceFile.fromString("zip zap zop"); expect(file.location(11).pointSpan().highlight(), equals(""" , 1 | zip zap zop @@ -157,7 +184,7 @@ zip zap zop '""")); }); - test("highlights the full last line if it's empty", () { + test("highlights the full first line if it's empty", () { var file = new SourceFile.fromString(""" foo From 96e3b6e3c578e2b5007572eaa6886eb3ed70a1ad Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Mon, 28 Jan 2019 19:01:23 -0500 Subject: [PATCH 285/657] Drop special support for point spans at the end of files (dart-lang/source_span#31) Drop special support for point spans at the end of files This broke point spans at the beginning of lines elsewhere in the file. Unfortunately, there's no way to disambiguate these currently. SourceSpanWithContext doesn't have any information about where the span appears in the context, so for point spans at column 0, it could be at the beginning of the line or after the trailing newline. We should eventually add something like SourceSpanWithContext.indexInContext, but that'll require a breaking release, since downstream users implement FileSpan as an interface. --- pkgs/source_span/CHANGELOG.md | 5 ++ pkgs/source_span/lib/src/file.dart | 4 +- pkgs/source_span/lib/src/highlighter.dart | 35 ++++------- pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/file_test.dart | 8 +-- pkgs/source_span/test/highlight_test.dart | 71 +++++++++++++---------- 6 files changed, 61 insertions(+), 64 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 6e79fbc46..a07a0e6b4 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.5.4 + +* `FileSpan.highlight()` now properly highlights point spans at the beginning of + lines. + # 1.5.3 * Fix an edge case where `FileSpan.highlight()` would put the highlight diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index ec4db63bc..27dae5db2 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -304,9 +304,9 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { if (length == 0) { // ...unless this is a point span, in which case we want to include the - // next line (or the last line if this is the end of the file). + // next line (or the empty string if this is the end of the file). return endLine == file.lines - 1 - ? file.getText(file.getOffset(endLine - 1)) + ? "" : file.getText( file.getOffset(endLine), file.getOffset(endLine + 1)); } diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 8100f1839..8a928b3f3 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -136,33 +136,18 @@ class Highlighter { /// than at the beginning of the next line. static SourceSpanWithContext _normalizeEndOfLine(SourceSpanWithContext span) { if (span.end.column != 0) return span; + if (span.end.line == span.start.line) return span; - if (span.length == 0) { - if (span.end.offset == 0) return span; + var text = span.text.substring(0, span.text.length - 1); - // If [span] is a point span with an empty context, there's no useful - // adjustment we can do. - if (span.context.isEmpty) return span; - - var location = new SourceLocation(span.end.offset - 1, - sourceUrl: span.sourceUrl, - line: span.end.line - 1, - column: _lastLineLength(span.context)); - return new SourceSpanWithContext(location, location, "", span.context); - } else { - if (span.end.line == span.start.line) return span; - - var text = span.text.substring(0, span.text.length - 1); - - return new SourceSpanWithContext( - span.start, - new SourceLocation(span.end.offset - 1, - sourceUrl: span.sourceUrl, - line: span.end.line - 1, - column: _lastLineLength(text)), - text, - span.context); - } + return new SourceSpanWithContext( + span.start, + new SourceLocation(span.end.offset - 1, + sourceUrl: span.sourceUrl, + line: span.end.line - 1, + column: _lastLineLength(text)), + text, + span.context); } /// Returns the length of the last line in [text], whether or not it ends in a diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index c4b4ccfdc..a47087561 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.3 +version: 1.5.4 description: A library for identifying source spans and locations. author: Dart Team diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 117458d10..e043ac3ae 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -276,13 +276,13 @@ zip zap zop""", url: "bar.dart").span(10, 11); expect(span.context, equals('whiz bang boom\n')); }); - group("contains the last line for a point span at the end of a file", () { - test("without a newline", () { + group("for a point span at the end of a file", () { + test("without a newline, contains the last line", () { var span = file.span(file.length, file.length); expect(span.context, equals('zip zap zop')); }); - test("with a newline", () { + test("with a newline, contains an empty line", () { file = new SourceFile.fromString(""" foo bar baz whiz bang boom @@ -290,7 +290,7 @@ zip zap zop """, url: "foo.dart"); var span = file.span(file.length, file.length); - expect(span.context, equals('zip zap zop\n')); + expect(span.context, isEmpty); }); }); }); diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 7832e5106..af9cd1ba0 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -45,77 +45,84 @@ zip zap zop '""")); }); - test("works for a point span", () { - expect(file.location(4).pointSpan().highlight(), equals(""" + group("highlights a point span", () { + test("in the middle of a line", () { + expect(file.location(4).pointSpan().highlight(), equals(""" , 1 | foo bar baz | ^ '""")); - }); + }); - test("works for a point span at the beginning of the file", () { - expect(file.location(0).pointSpan().highlight(), equals(""" + test("at the beginning of the file", () { + expect(file.location(0).pointSpan().highlight(), equals(""" , 1 | foo bar baz | ^ '""")); - }); + }); + + test("at the beginning of a line", () { + expect(file.location(12).pointSpan().highlight(), equals(""" + , +2 | whiz bang boom + | ^ + '""")); + }); - test("works for a point span at the end of a line", () { - expect(file.location(11).pointSpan().highlight(), equals(""" + test("at the end of a line", () { + expect(file.location(11).pointSpan().highlight(), equals(""" , 1 | foo bar baz | ^ '""")); - }); + }); - test("works for a point span at the end of the file", () { - expect(file.location(38).pointSpan().highlight(), equals(""" + test("at the end of the file", () { + expect(file.location(38).pointSpan().highlight(), equals(""" , 3 | zip zap zop | ^ '""")); - }); + }); - test("works for a point span after the end of the file", () { - expect(file.location(39).pointSpan().highlight(), equals(""" + test("after the end of the file", () { + expect(file.location(39).pointSpan().highlight(), equals(""" , -3 | zip zap zop - | ^ +4 | + | ^ '""")); - }); + }); - test("works for a point span at the end of the file with no trailing newline", - () { - file = new SourceFile.fromString("zip zap zop"); - expect(file.location(10).pointSpan().highlight(), equals(""" + test("at the end of the file with no trailing newline", () { + file = new SourceFile.fromString("zip zap zop"); + expect(file.location(10).pointSpan().highlight(), equals(""" , 1 | zip zap zop | ^ '""")); - }); + }); - test( - "works for a point span after the end of the file with no trailing newline", - () { - file = new SourceFile.fromString("zip zap zop"); - expect(file.location(11).pointSpan().highlight(), equals(""" + test("after the end of the file with no trailing newline", () { + file = new SourceFile.fromString("zip zap zop"); + expect(file.location(11).pointSpan().highlight(), equals(""" , 1 | zip zap zop | ^ '""")); - }); + }); - test("works for a point span in an empty file", () { - expect(new SourceFile.fromString("").location(0).pointSpan().highlight(), - equals(""" + test("in an empty file", () { + expect(new SourceFile.fromString("").location(0).pointSpan().highlight(), + equals(""" , 1 | | ^ '""")); + }); }); - test("works for a single-line file without a newline", () { + test("highlights a single-line file without a newline", () { expect( new SourceFile.fromString("foo bar").span(0, 7).highlight(), equals(""" , From fc558d27f3eb0f3b74e58063ae2719f426c4c19b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Fri, 15 Feb 2019 17:52:50 -0800 Subject: [PATCH 286/657] Support the latest source_span (dart-lang/source_maps#34) --- pkgs/source_maps/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 3e41803ba..0a35df6e0 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -12,5 +12,6 @@ dependencies: source_span: ^1.3.0 dev_dependencies: + source_span: ^1.5.4 test: ^1.2.0 term_glyph: ^1.0.0 From 99fa2b803d67c5d14fcaa781a9d9e76836d80d61 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 25 Feb 2019 11:16:14 -0800 Subject: [PATCH 287/657] Update time test expectation to account for runtime variations (dart-lang/pool#31) Fixes https://github.com/dart-lang/pool/issues/30 --- pkgs/pool/test/pool_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index d4d778992..77ef13d42 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -553,7 +553,7 @@ void main() { expect(finishedItems, itemCount); final expectedElapsed = - delayedToStringDuration.inMicroseconds * 3; + delayedToStringDuration.inMicroseconds * 4; expect((watch.elapsed ~/ itemCount).inMicroseconds, lessThan(expectedElapsed / (poolSize - otherTaskCount)), From e75afeaf7cd16e5e588d76af8413f9bc8d667e70 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Thu, 28 Feb 2019 14:30:54 -0800 Subject: [PATCH 288/657] Fix a highlighting bug (dart-lang/source_span#33) If a span covered a trailing newline and a single additional line, it went down a code path that resulted in a range error. That code path has now been fixed. Closes dart-lang/source_span#32 --- pkgs/source_span/CHANGELOG.md | 5 +++ pkgs/source_span/lib/src/highlighter.dart | 14 ++++++-- pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/highlight_test.dart | 39 +++++++++++++++++++++++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index a07a0e6b4..ddb4ff05a 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.5.5 + +* Fix a bug where `FileSpan.highlight()` would crash for spans that covered a + trailing newline and a single additional empty line. + # 1.5.4 * `FileSpan.highlight()` now properly highlights point spans at the beginning of diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 8a928b3f3..17a47bcea 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -117,6 +117,10 @@ class Highlighter { SourceSpanWithContext span) { if (!span.context.endsWith("\n")) return span; + // If there's a full blank line on the end of [span.context], it's probably + // significant, so we shouldn't trim it. + if (span.text.endsWith("\n\n")) return span; + var context = span.context.substring(0, span.context.length - 1); var text = span.text; var start = span.start; @@ -156,9 +160,13 @@ class Highlighter { if (text.isEmpty) return 0; // The "- 1" here avoids counting the newline itself. - return text.codeUnitAt(text.length - 1) == $lf - ? text.length - text.lastIndexOf("\n", text.length - 2) - 1 - : text.length - text.lastIndexOf("\n") - 1; + if (text.codeUnitAt(text.length - 1) == $lf) { + return text.length == 1 + ? 0 + : text.length - text.lastIndexOf("\n", text.length - 2) - 1; + } else { + return text.length - text.lastIndexOf("\n") - 1; + } } /// Returns whether [span]'s text runs all the way to the end of its context. diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index a47087561..0cb932656 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.5.4 +version: 1.5.5 description: A library for identifying source spans and locations. author: Dart Team diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index af9cd1ba0..5fdf622f4 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -117,6 +117,15 @@ zip zap zop equals(""" , 1 | + | ^ + '""")); + }); + + test("on an empty line", () { + var file = new SourceFile.fromString("foo\n\nbar"); + expect(file.location(4).pointSpan().highlight(), equals(""" + , +2 | | ^ '""")); }); @@ -131,6 +140,15 @@ zip zap zop '""")); }); + test("highlights a single empty line", () { + expect(new SourceFile.fromString("foo\n\nbar").span(4, 5).highlight(), + equals(""" + , +2 | + | ^ + '""")); + }); + group("with a multiline span", () { test("highlights the middle of the first and last lines", () { expect(file.span(4, 34).highlight(), equals(""" @@ -275,6 +293,27 @@ bar expect(file.span(0, 5).highlight(), equals(""" , 1 | / foo +2 | \\ + '""")); + }); + + test("highlights multiple empty lines", () { + var file = new SourceFile.fromString("foo\n\n\n\nbar"); + expect(file.span(4, 7).highlight(), equals(""" + , +2 | / +3 | | +4 | \\ + '""")); + }); + + // Regression test for #32 + test("highlights the end of a line and an empty line", () { + var file = new SourceFile.fromString("foo\n\n"); + expect(file.span(3, 5).highlight(), equals(""" + , +1 | foo + | ,----^ 2 | \\ '""")); }); From ce9aa9d6d43538e4f2bc66f0a68afe55faddcc1c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 12 Apr 2019 11:25:16 -0700 Subject: [PATCH 289/657] Delete analysis_options.yaml --- pkgs/source_maps/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 pkgs/source_maps/analysis_options.yaml diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml deleted file mode 100644 index 2e6cdca29..000000000 --- a/pkgs/source_maps/analysis_options.yaml +++ /dev/null @@ -1 +0,0 @@ -analyzer: From 86871c2bfbcef2b0257fa9d08a20521e90293da4 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 12 Apr 2019 11:25:33 -0700 Subject: [PATCH 290/657] Delete codereview.settings --- pkgs/source_maps/codereview.settings | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/source_maps/codereview.settings diff --git a/pkgs/source_maps/codereview.settings b/pkgs/source_maps/codereview.settings deleted file mode 100644 index 313ad0a67..000000000 --- a/pkgs/source_maps/codereview.settings +++ /dev/null @@ -1,3 +0,0 @@ -CODE_REVIEW_SERVER: http://codereview.chromium.org/ -VIEW_VC: https://github.com/dart-lang/source_maps/commit/ -CC_LIST: reviews@dartlang.org \ No newline at end of file From 8d99f34578a2643de285d7926a37a9e8bb8587bb Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 26 Apr 2019 13:44:20 -0700 Subject: [PATCH 291/657] travis: test on the oldest supported SDK (dart-lang/source_span#34) --- pkgs/source_span/.travis.yml | 2 +- pkgs/source_span/pubspec.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index 44a054287..18267fca2 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -2,7 +2,7 @@ language: dart dart: - dev - - stable + - 2.0.0 dart_task: - test: --platform vm,chrome diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 0cb932656..813dd3b2a 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,12 @@ name: source_span -version: 1.5.5 +version: 1.5.6-dev description: A library for identifying source spans and locations. author: Dart Team homepage: https://github.com/dart-lang/source_span environment: - sdk: '>=1.8.0 <3.0.0' + sdk: '>=2.0.0 <3.0.0' dependencies: charcode: ^1.0.0 @@ -14,4 +14,4 @@ dependencies: term_glyph: ^1.0.0 dev_dependencies: - test: '>=0.12.0 <2.0.0' + test: ^1.0.0 From 7d1503abfe738282fc31096f9a0f164f1326d784 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 6 May 2019 10:15:36 -0700 Subject: [PATCH 292/657] Enable and fix a number of lints, test on oldest supported SDK (dart-lang/pub_semver#37) Bump min SDK to Dart 2.0 --- pkgs/pub_semver/.travis.yml | 18 +- pkgs/pub_semver/CHANGELOG.md | 5 + pkgs/pub_semver/analysis_options.yaml | 93 +++ pkgs/pub_semver/lib/src/patterns.dart | 10 +- pkgs/pub_semver/lib/src/version.dart | 53 +- .../lib/src/version_constraint.dart | 64 +- pkgs/pub_semver/lib/src/version_range.dart | 94 ++- pkgs/pub_semver/lib/src/version_union.dart | 14 +- pkgs/pub_semver/pubspec.yaml | 10 +- pkgs/pub_semver/test/utils.dart | 34 +- .../test/version_constraint_test.dart | 131 ++- pkgs/pub_semver/test/version_range_test.dart | 746 +++++++++--------- pkgs/pub_semver/test/version_test.dart | 159 ++-- pkgs/pub_semver/test/version_union_test.dart | 373 +++++---- 14 files changed, 929 insertions(+), 875 deletions(-) create mode 100644 pkgs/pub_semver/analysis_options.yaml diff --git a/pkgs/pub_semver/.travis.yml b/pkgs/pub_semver/.travis.yml index c65407225..0e732d0e7 100644 --- a/pkgs/pub_semver/.travis.yml +++ b/pkgs/pub_semver/.travis.yml @@ -1,13 +1,23 @@ language: dart -sudo: false + dart: - dev - - stable + - 2.0.0 dart_task: - test - - dartfmt - - dartanalyzer + +matrix: + include: + # Only validate formatting using the dev release + - dart: dev + dart_task: dartfmt + - dart: dev + dart_task: + dartanalyzer: --fatal-warnings --fatal-hints . + - dart: 2.0.0 + dart_task: + dartanalyzer: --fatal-warnings . # Only building master means that we don't run two builds for each pull request. branches: diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index f8feb2460..418325255 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.4.3 + +- Update Dart SDK constraint to `>=2.0.0 <3.0.0`. +- Update `package:collection` constraint to `^1.0.0`. + # 1.4.2 * Set max SDK version to `<3.0.0`. diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml new file mode 100644 index 000000000..c970ea7aa --- /dev/null +++ b/pkgs/pub_semver/analysis_options.yaml @@ -0,0 +1,93 @@ +include: package:pedantic/analysis_options.yaml +analyzer: +# strong-mode: +# implicit-casts: false +linter: + rules: + - always_declare_return_types + #- annotate_overrides + - avoid_bool_literals_in_conditional_expressions + - avoid_classes_with_only_static_members + - avoid_empty_else + - avoid_function_literals_in_foreach_calls + - avoid_init_to_null + - avoid_null_checks_in_equality_operators + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null + - avoid_returning_null_for_future + - avoid_returning_null_for_void + - avoid_returning_this + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_types_as_parameter_names + - avoid_unused_constructor_parameters + - await_only_futures + - camel_case_types + - cancel_subscriptions + - cascade_invocations + - comment_references + - constant_identifier_names + - control_flow_in_finally + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + - file_names + - hash_and_equals + - implementation_imports + - invariant_booleans + - iterable_contains_unrelated_type + - join_return_with_assignment + - library_names + - library_prefixes + - list_remove_unrelated_type + - literal_only_boolean_expressions + - no_adjacent_strings_in_list + - no_duplicate_case_values + - non_constant_identifier_names + - null_closures + - omit_local_variable_types + - only_throw_errors + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + - prefer_adjacent_string_concatenation + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_contains + - prefer_equal_for_default_values + - prefer_final_fields + #- prefer_final_locals + - prefer_generic_function_type_aliases + - prefer_initializing_formals + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + - prefer_null_aware_operators + #- prefer_single_quotes + - prefer_typing_uninitialized_variables + - recursive_getters + - slash_for_doc_comments + - test_types_in_equals + - throw_in_finally + - type_init_formals + - unawaited_futures + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_getters_setters + - unnecessary_lambdas + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_this + - unrelated_type_equality_checks + - use_function_type_syntax_for_parameters + - use_rethrow_when_possible + - valid_regexps + - void_checks diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart index c4d75d4b7..8829447fa 100644 --- a/pkgs/pub_semver/lib/src/patterns.dart +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -3,17 +3,17 @@ // BSD-style license that can be found in the LICENSE file. /// Regex that matches a version number at the beginning of a string. -final START_VERSION = new RegExp(r'^' // Start at beginning. +final startVersion = RegExp(r'^' // Start at beginning. r'(\d+).(\d+).(\d+)' // Version number. r'(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?' // Pre-release. r'(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?'); // Build. -/// Like [START_VERSION] but matches the entire string. -final COMPLETE_VERSION = new RegExp(START_VERSION.pattern + r'$'); +/// Like [startVersion] but matches the entire string. +final completeVersion = RegExp('${startVersion.pattern}\$'); /// Parses a comparison operator ("<", ">", "<=", or ">=") at the beginning of /// a string. -final START_COMPARISON = new RegExp(r"^[<>]=?"); +final startComparison = RegExp(r"^[<>]=?"); /// The "compatible with" operator. -const COMPATIBLE_WITH = "^"; +const compatibleWithChar = "^"; diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 19ae96262..031af5201 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -16,7 +16,7 @@ final _equality = const IterableEquality(); /// A parsed semantic version number. class Version implements VersionConstraint, VersionRange { /// No released version: i.e. "0.0.0". - static Version get none => new Version(0, 0, 0); + static Version get none => Version(0, 0, 0); /// Compares [a] and [b] to see which takes priority over the other. /// @@ -92,12 +92,9 @@ class Version implements VersionConstraint, VersionRange { this._text) : preRelease = preRelease == null ? [] : _splitParts(preRelease), build = build == null ? [] : _splitParts(build) { - if (major < 0) - throw new ArgumentError('Major version must be non-negative.'); - if (minor < 0) - throw new ArgumentError('Minor version must be non-negative.'); - if (patch < 0) - throw new ArgumentError('Patch version must be non-negative.'); + if (major < 0) throw ArgumentError('Major version must be non-negative.'); + if (minor < 0) throw ArgumentError('Minor version must be non-negative.'); + if (patch < 0) throw ArgumentError('Patch version must be non-negative.'); } /// Creates a new [Version] object. @@ -106,27 +103,27 @@ class Version implements VersionConstraint, VersionRange { if (pre != null) text += "-$pre"; if (build != null) text += "+$build"; - return new Version._(major, minor, patch, pre, build, text); + return Version._(major, minor, patch, pre, build, text); } /// Creates a new [Version] by parsing [text]. factory Version.parse(String text) { - final match = COMPLETE_VERSION.firstMatch(text); + final match = completeVersion.firstMatch(text); if (match == null) { - throw new FormatException('Could not parse "$text".'); + throw FormatException('Could not parse "$text".'); } try { - int major = int.parse(match[1]); - int minor = int.parse(match[2]); - int patch = int.parse(match[3]); + var major = int.parse(match[1]); + var minor = int.parse(match[2]); + var patch = int.parse(match[3]); - String preRelease = match[5]; - String build = match[8]; + var preRelease = match[5]; + var build = match[8]; - return new Version._(major, minor, patch, preRelease, build, text); + return Version._(major, minor, patch, preRelease, build, text); } on FormatException { - throw new FormatException('Could not parse "$text".'); + throw FormatException('Could not parse "$text".'); } } @@ -135,7 +132,7 @@ class Version implements VersionConstraint, VersionRange { /// This is the highest-numbered stable (non-prerelease) version. If there /// are no stable versions, it's just the highest-numbered version. static Version primary(List versions) { - var primary; + Version primary; for (var version in versions) { if (primary == null || (!version.isPreRelease && primary.isPreRelease) || @@ -195,7 +192,7 @@ class Version implements VersionConstraint, VersionRange { /// and patch. Version get nextMajor { if (isPreRelease && minor == 0 && patch == 0) { - return new Version(major, minor, patch); + return Version(major, minor, patch); } return _incrementMajor(); @@ -208,7 +205,7 @@ class Version implements VersionConstraint, VersionRange { /// Otherwise, it increments the minor version and resets the patch. Version get nextMinor { if (isPreRelease && patch == 0) { - return new Version(major, minor, patch); + return Version(major, minor, patch); } return _incrementMinor(); @@ -220,7 +217,7 @@ class Version implements VersionConstraint, VersionRange { /// suffix. Otherwise, it increments the patch version. Version get nextPatch { if (isPreRelease) { - return new Version(major, minor, patch); + return Version(major, minor, patch); } return _incrementPatch(); @@ -240,14 +237,14 @@ class Version implements VersionConstraint, VersionRange { } /// Returns the first possible pre-release of this version. - Version get firstPreRelease => new Version(major, minor, patch, pre: "0"); + Version get firstPreRelease => Version(major, minor, patch, pre: "0"); /// Returns whether this is the first possible pre-release of its version. bool get isFirstPreRelease => preRelease.length == 1 && preRelease.first == 0; - Version _incrementMajor() => new Version(major + 1, 0, 0); - Version _incrementMinor() => new Version(major, minor + 1, 0); - Version _incrementPatch() => new Version(major, minor, patch + 1); + Version _incrementMajor() => Version(major + 1, 0, 0); + Version _incrementMinor() => Version(major, minor + 1, 0); + Version _incrementPatch() => Version(major, minor, patch + 1); /// Tests if [other] matches this version exactly. bool allows(Version other) => this == other; @@ -264,7 +261,7 @@ class Version implements VersionConstraint, VersionRange { if (other is VersionRange) { if (other.min == this) { - return new VersionRange( + return VersionRange( min: other.min, max: other.max, includeMin: true, @@ -273,7 +270,7 @@ class Version implements VersionConstraint, VersionRange { } if (other.max == this) { - return new VersionRange( + return VersionRange( min: other.min, max: other.max, includeMin: other.includeMin, @@ -282,7 +279,7 @@ class Version implements VersionConstraint, VersionRange { } } - return new VersionConstraint.unionOf([this, other]); + return VersionConstraint.unionOf([this, other]); } VersionConstraint difference(VersionConstraint other) => diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 67093f701..6dfd396f5 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -16,7 +16,7 @@ import 'version_union.dart'; /// version. abstract class VersionConstraint { /// A [VersionConstraint] that allows all versions. - static VersionConstraint any = new VersionRange(); + static VersionConstraint any = VersionRange(); /// A [VersionConstraint] that allows no versions -- the empty set. static VersionConstraint empty = const _EmptyVersion(); @@ -47,7 +47,7 @@ abstract class VersionConstraint { factory VersionConstraint.parse(String text) { var originalText = text; - skipWhitespace() { + void skipWhitespace() { text = text.trim(); } @@ -58,16 +58,16 @@ abstract class VersionConstraint { // Try to parse and consume a version number. Version matchVersion() { - var version = START_VERSION.firstMatch(text); + var version = startVersion.firstMatch(text); if (version == null) return null; text = text.substring(version.end); - return new Version.parse(version[0]); + return Version.parse(version[0]); } // Try to parse and consume a comparison operator followed by a version. VersionRange matchComparison() { - var comparison = START_COMPARISON.firstMatch(text); + var comparison = startComparison.firstMatch(text); if (comparison == null) return null; var op = comparison[0]; @@ -76,45 +76,45 @@ abstract class VersionConstraint { var version = matchVersion(); if (version == null) { - throw new FormatException('Expected version number after "$op" in ' + throw FormatException('Expected version number after "$op" in ' '"$originalText", got "$text".'); } switch (op) { case '<=': - return new VersionRange(max: version, includeMax: true); + return VersionRange(max: version, includeMax: true); case '<': - return new VersionRange( + return VersionRange( max: version, includeMax: false, alwaysIncludeMaxPreRelease: true); case '>=': - return new VersionRange(min: version, includeMin: true); + return VersionRange(min: version, includeMin: true); case '>': - return new VersionRange(min: version, includeMin: false); + return VersionRange(min: version, includeMin: false); } - throw "Unreachable."; + throw FallThroughError(); } // Try to parse the "^" operator followed by a version. - matchCompatibleWith() { - if (!text.startsWith(COMPATIBLE_WITH)) return null; + VersionConstraint matchCompatibleWith() { + if (!text.startsWith(compatibleWithChar)) return null; - text = text.substring(COMPATIBLE_WITH.length); + text = text.substring(compatibleWithChar.length); skipWhitespace(); var version = matchVersion(); if (version == null) { - throw new FormatException('Expected version number after ' - '"$COMPATIBLE_WITH" in "$originalText", got "$text".'); + throw FormatException('Expected version number after ' + '"$compatibleWithChar" in "$originalText", got "$text".'); } if (text.isNotEmpty) { - throw new FormatException('Cannot include other constraints with ' - '"$COMPATIBLE_WITH" constraint in "$originalText".'); + throw FormatException('Cannot include other constraints with ' + '"$compatibleWithChar" constraint in "$originalText".'); } - return new VersionConstraint.compatibleWith(version); + return VersionConstraint.compatibleWith(version); } var compatibleWith = matchCompatibleWith(); @@ -125,14 +125,14 @@ abstract class VersionConstraint { Version max; var includeMax = false; - while (true) { + for (;;) { skipWhitespace(); if (text.isEmpty) break; var newRange = matchVersion() ?? matchComparison(); if (newRange == null) { - throw new FormatException('Could not parse version "$originalText". ' + throw FormatException('Could not parse version "$originalText". ' 'Unknown text at "$text".'); } @@ -156,7 +156,7 @@ abstract class VersionConstraint { } if (min == null && max == null) { - throw new FormatException('Cannot parse an empty string.'); + throw const FormatException('Cannot parse an empty string.'); } if (min != null && max != null) { @@ -167,7 +167,7 @@ abstract class VersionConstraint { } } - return new VersionRange( + return VersionRange( min: min, includeMin: includeMin, max: max, includeMax: includeMax); } @@ -178,7 +178,7 @@ abstract class VersionConstraint { /// are greater than or equal to [version], but less than the next breaking /// version ([Version.nextBreaking]) of [version]. factory VersionConstraint.compatibleWith(Version version) => - new CompatibleWithVersionRange(version); + CompatibleWithVersionRange(version); /// Creates a new version constraint that is the intersection of /// [constraints]. @@ -188,7 +188,7 @@ abstract class VersionConstraint { /// all versions. factory VersionConstraint.intersection( Iterable constraints) { - var constraint = new VersionRange(); + var constraint = VersionRange(); for (var other in constraints) { constraint = constraint.intersect(other); } @@ -217,7 +217,7 @@ abstract class VersionConstraint { // filtered out above. for (var constraint in flattened) { if (constraint is VersionRange) continue; - throw new ArgumentError('Unknown VersionConstraint type $constraint.'); + throw ArgumentError('Unknown VersionConstraint type $constraint.'); } flattened.sort(); @@ -235,7 +235,7 @@ abstract class VersionConstraint { } if (merged.length == 1) return merged.single; - return new VersionUnion.fromRanges(merged); + return VersionUnion.fromRanges(merged); } /// Returns `true` if this constraint allows no versions. @@ -259,7 +259,7 @@ abstract class VersionConstraint { /// this and [other]. VersionConstraint intersect(VersionConstraint other); - /// Returns a [VersionConstraint] that allows [Versions]s allowed by either + /// Returns a [VersionConstraint] that allows [Version]s allowed by either /// this or [other]. VersionConstraint union(VersionConstraint other); @@ -272,12 +272,20 @@ class _EmptyVersion implements VersionConstraint { const _EmptyVersion(); bool get isEmpty => true; + bool get isAny => false; + bool allows(Version other) => false; + bool allowsAll(VersionConstraint other) => other.isEmpty; + bool allowsAny(VersionConstraint other) => false; + VersionConstraint intersect(VersionConstraint other) => this; + VersionConstraint union(VersionConstraint other) => other; + VersionConstraint difference(VersionConstraint other) => this; + String toString() => ''; } diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index a566891ea..8ac79dab8 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -60,11 +60,11 @@ class VersionRange implements Comparable, VersionConstraint { factory VersionRange( {Version min, Version max, - bool includeMin: false, - bool includeMax: false, - bool alwaysIncludeMaxPreRelease: false}) { + bool includeMin = false, + bool includeMax = false, + bool alwaysIncludeMaxPreRelease = false}) { if (min != null && max != null && min > max) { - throw new ArgumentError( + throw ArgumentError( 'Minimum version ("$min") must be less than maximum ("$max").'); } @@ -79,7 +79,7 @@ class VersionRange implements Comparable, VersionConstraint { max = max.firstPreRelease; } - return new VersionRange._(min, max, includeMin, includeMax); + return VersionRange._(min, max, includeMin, includeMax); } VersionRange._(this.min, this.max, this.includeMin, this.includeMax); @@ -123,14 +123,14 @@ class VersionRange implements Comparable, VersionConstraint { if (other is Version) return allows(other); if (other is VersionUnion) { - return other.ranges.every((constraint) => allowsAll(constraint)); + return other.ranges.every(allowsAll); } if (other is VersionRange) { return !allowsLower(other, this) && !allowsHigher(other, this); } - throw new ArgumentError('Unknown VersionConstraint type $other.'); + throw ArgumentError('Unknown VersionConstraint type $other.'); } bool allowsAny(VersionConstraint other) { @@ -138,14 +138,14 @@ class VersionRange implements Comparable, VersionConstraint { if (other is Version) return allows(other); if (other is VersionUnion) { - return other.ranges.any((constraint) => allowsAny(constraint)); + return other.ranges.any(allowsAny); } if (other is VersionRange) { return !strictlyLower(other, this) && !strictlyHigher(other, this); } - throw new ArgumentError('Unknown VersionConstraint type $other.'); + throw ArgumentError('Unknown VersionConstraint type $other.'); } VersionConstraint intersect(VersionConstraint other) { @@ -167,8 +167,8 @@ class VersionRange implements Comparable, VersionConstraint { intersectIncludeMin = other.includeMin; } else { if (strictlyLower(other, this)) return VersionConstraint.empty; - intersectMin = this.min; - intersectIncludeMin = this.includeMin; + intersectMin = min; + intersectIncludeMin = includeMin; } Version intersectMax; @@ -177,13 +177,13 @@ class VersionRange implements Comparable, VersionConstraint { intersectMax = other.max; intersectIncludeMax = other.includeMax; } else { - intersectMax = this.max; - intersectIncludeMax = this.includeMax; + intersectMax = max; + intersectIncludeMax = includeMax; } if (intersectMin == null && intersectMax == null) { // Open range. - return new VersionRange(); + return VersionRange(); } // If the range is just a single version. @@ -195,7 +195,7 @@ class VersionRange implements Comparable, VersionConstraint { } // If we got here, there is an actual range. - return new VersionRange( + return VersionRange( min: intersectMin, max: intersectMax, includeMin: intersectIncludeMin, @@ -203,7 +203,7 @@ class VersionRange implements Comparable, VersionConstraint { alwaysIncludeMaxPreRelease: true); } - throw new ArgumentError('Unknown VersionConstraint type $other.'); + throw ArgumentError('Unknown VersionConstraint type $other.'); } VersionConstraint union(VersionConstraint other) { @@ -211,24 +211,24 @@ class VersionRange implements Comparable, VersionConstraint { if (allows(other)) return this; if (other == min) { - return new VersionRange( - min: this.min, - max: this.max, + return VersionRange( + min: min, + max: max, includeMin: true, - includeMax: this.includeMax, + includeMax: includeMax, alwaysIncludeMaxPreRelease: true); } if (other == max) { - return new VersionRange( - min: this.min, - max: this.max, - includeMin: this.includeMin, + return VersionRange( + min: min, + max: max, + includeMin: includeMin, includeMax: true, alwaysIncludeMaxPreRelease: true); } - return new VersionConstraint.unionOf([this, other]); + return VersionConstraint.unionOf([this, other]); } if (other is VersionRange) { @@ -237,14 +237,14 @@ class VersionRange implements Comparable, VersionConstraint { var edgesTouch = (max == other.min && (includeMax || other.includeMin)) || (min == other.max && (includeMin || other.includeMax)); if (!edgesTouch && !allowsAny(other)) { - return new VersionConstraint.unionOf([this, other]); + return VersionConstraint.unionOf([this, other]); } Version unionMin; bool unionIncludeMin; if (allowsLower(this, other)) { - unionMin = this.min; - unionIncludeMin = this.includeMin; + unionMin = min; + unionIncludeMin = includeMin; } else { unionMin = other.min; unionIncludeMin = other.includeMin; @@ -253,14 +253,14 @@ class VersionRange implements Comparable, VersionConstraint { Version unionMax; bool unionIncludeMax; if (allowsHigher(this, other)) { - unionMax = this.max; - unionIncludeMax = this.includeMax; + unionMax = max; + unionIncludeMax = includeMax; } else { unionMax = other.max; unionIncludeMax = other.includeMax; } - return new VersionRange( + return VersionRange( min: unionMin, max: unionMax, includeMin: unionIncludeMin, @@ -268,7 +268,7 @@ class VersionRange implements Comparable, VersionConstraint { alwaysIncludeMaxPreRelease: true); } - return new VersionConstraint.unionOf([this, other]); + return VersionConstraint.unionOf([this, other]); } VersionConstraint difference(VersionConstraint other) { @@ -279,7 +279,7 @@ class VersionRange implements Comparable, VersionConstraint { if (other == min) { if (!includeMin) return this; - return new VersionRange( + return VersionRange( min: min, max: max, includeMin: false, @@ -289,7 +289,7 @@ class VersionRange implements Comparable, VersionConstraint { if (other == max) { if (!includeMax) return this; - return new VersionRange( + return VersionRange( min: min, max: max, includeMin: includeMin, @@ -297,14 +297,14 @@ class VersionRange implements Comparable, VersionConstraint { alwaysIncludeMaxPreRelease: true); } - return new VersionUnion.fromRanges([ - new VersionRange( + return VersionUnion.fromRanges([ + VersionRange( min: min, max: other, includeMin: includeMin, includeMax: false, alwaysIncludeMaxPreRelease: true), - new VersionRange( + VersionRange( min: other, max: max, includeMin: false, @@ -322,7 +322,7 @@ class VersionRange implements Comparable, VersionConstraint { assert(min != null); before = min; } else { - before = new VersionRange( + before = VersionRange( min: min, max: other.min, includeMin: includeMin, @@ -338,7 +338,7 @@ class VersionRange implements Comparable, VersionConstraint { assert(max != null); after = max; } else { - after = new VersionRange( + after = VersionRange( min: other.max, max: max, includeMin: !other.includeMax, @@ -349,7 +349,7 @@ class VersionRange implements Comparable, VersionConstraint { if (before == null && after == null) return VersionConstraint.empty; if (before == null) return after; if (after == null) return before; - return new VersionUnion.fromRanges([before, after]); + return VersionUnion.fromRanges([before, after]); } else if (other is VersionUnion) { var ranges = []; var current = this; @@ -377,10 +377,10 @@ class VersionRange implements Comparable, VersionConstraint { } if (ranges.isEmpty) return current; - return new VersionUnion.fromRanges(ranges..add(current)); + return VersionUnion.fromRanges(ranges..add(current)); } - throw new ArgumentError('Unknown VersionConstraint type $other.'); + throw ArgumentError('Unknown VersionConstraint type $other.'); } int compareTo(VersionRange other) { @@ -398,7 +398,7 @@ class VersionRange implements Comparable, VersionConstraint { return _compareMax(other); } - /// Compares the maximum values of [this] and [other]. + /// Compares the maximum values of `this` and [other]. int _compareMax(VersionRange other) { if (max == null) { if (other.max == null) return 0; @@ -414,18 +414,16 @@ class VersionRange implements Comparable, VersionConstraint { } String toString() { - var buffer = new StringBuffer(); + var buffer = StringBuffer(); if (min != null) { - buffer.write(includeMin ? '>=' : '>'); - buffer.write(min); + buffer..write(includeMin ? '>=' : '>')..write(min); } if (max != null) { if (min != null) buffer.write(' '); if (includeMax) { - buffer.write('<='); - buffer.write(max); + buffer..write('<=')..write(max); } else { buffer.write('<'); if (max.isFirstPreRelease) { diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index 9324d3fb7..b774163ef 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -113,7 +113,7 @@ class VersionUnion implements VersionConstraint { if (newRanges.isEmpty) return VersionConstraint.empty; if (newRanges.length == 1) return newRanges.single; - return new VersionUnion.fromRanges(newRanges); + return VersionUnion.fromRanges(newRanges); } VersionConstraint difference(VersionConstraint other) { @@ -125,7 +125,7 @@ class VersionUnion implements VersionConstraint { theirRanges.moveNext(); var current = ourRanges.current; - theirNextRange() { + bool theirNextRange() { if (theirRanges.moveNext()) return true; // If there are no more of their ranges, none of the rest of our ranges @@ -137,14 +137,14 @@ class VersionUnion implements VersionConstraint { return false; } - ourNextRange({bool includeCurrent: true}) { + bool ourNextRange({bool includeCurrent = true}) { if (includeCurrent) newRanges.add(current); if (!ourRanges.moveNext()) return false; current = ourRanges.current; return true; } - while (true) { + for (;;) { // If the current ranges are disjoint, move the lowest one forward. if (strictlyLower(theirRanges.current, current)) { if (!theirNextRange()) break; @@ -187,7 +187,7 @@ class VersionUnion implements VersionConstraint { if (newRanges.isEmpty) return VersionConstraint.empty; if (newRanges.length == 1) return newRanges.single; - return new VersionUnion.fromRanges(newRanges); + return VersionUnion.fromRanges(newRanges); } /// Returns [constraint] as a list of ranges. @@ -197,11 +197,11 @@ class VersionUnion implements VersionConstraint { if (constraint.isEmpty) return []; if (constraint is VersionUnion) return constraint.ranges; if (constraint is VersionRange) return [constraint]; - throw new ArgumentError('Unknown VersionConstraint type $constraint.'); + throw ArgumentError('Unknown VersionConstraint type $constraint.'); } VersionConstraint union(VersionConstraint other) => - new VersionConstraint.unionOf([this, other]); + VersionConstraint.unionOf([this, other]); bool operator ==(other) { if (other is! VersionUnion) return false; diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 56fa52bf8..b92d2f66c 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,17 +1,17 @@ name: pub_semver -version: 1.4.2 +version: 1.4.3-dev -description: > +description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. author: Dart Team homepage: http://github.com/dart-lang/pub_semver environment: - sdk: '>=1.0.0 <3.0.0' + sdk: '>=2.0.0 <3.0.0' dependencies: - collection: '>=0.9.0 <2.0.0' + collection: ^1.0.0 dev_dependencies: - test: '>=0.12.0 <2.0.0' + test: ^1.0.0 diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index 8ecd8f5d6..a0fd684c1 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -7,24 +7,24 @@ import 'package:test/test.dart'; import 'package:pub_semver/pub_semver.dart'; /// Some stock example versions to use in tests. -final v003 = new Version.parse('0.0.3'); -final v010 = new Version.parse('0.1.0'); -final v072 = new Version.parse('0.7.2'); -final v080 = new Version.parse('0.8.0'); -final v114 = new Version.parse('1.1.4'); -final v123 = new Version.parse('1.2.3'); -final v124 = new Version.parse('1.2.4'); -final v130 = new Version.parse('1.3.0'); -final v140 = new Version.parse('1.4.0'); -final v200 = new Version.parse('2.0.0'); -final v201 = new Version.parse('2.0.1'); -final v234 = new Version.parse('2.3.4'); -final v250 = new Version.parse('2.5.0'); -final v300 = new Version.parse('3.0.0'); +final v003 = Version.parse('0.0.3'); +final v010 = Version.parse('0.1.0'); +final v072 = Version.parse('0.7.2'); +final v080 = Version.parse('0.8.0'); +final v114 = Version.parse('1.1.4'); +final v123 = Version.parse('1.2.3'); +final v124 = Version.parse('1.2.4'); +final v130 = Version.parse('1.3.0'); +final v140 = Version.parse('1.4.0'); +final v200 = Version.parse('2.0.0'); +final v201 = Version.parse('2.0.1'); +final v234 = Version.parse('2.3.4'); +final v250 = Version.parse('2.5.0'); +final v300 = Version.parse('3.0.0'); /// A range that allows pre-release versions of its max version. final includeMaxPreReleaseRange = - new VersionRange(max: v200, alwaysIncludeMaxPreRelease: true); + VersionRange(max: v200, alwaysIncludeMaxPreRelease: true); /// A [Matcher] that tests if a [VersionConstraint] allows or does not allow a /// given list of [Version]s. @@ -84,7 +84,7 @@ Matcher allows(Version v1, Version v7, Version v8]) { var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); - return new _VersionConstraintMatcher(versions, true); + return _VersionConstraintMatcher(versions, true); } /// Gets a [Matcher] that validates that a [VersionConstraint] allows none of @@ -98,7 +98,7 @@ Matcher doesNotAllow(Version v1, Version v7, Version v8]) { var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); - return new _VersionConstraintMatcher(versions, false); + return _VersionConstraintMatcher(versions, false); } List _makeVersionList(Version v1, diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index bf3a01862..1e48391ee 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -8,13 +8,13 @@ import 'package:pub_semver/pub_semver.dart'; import 'utils.dart'; -main() { +void main() { test('any', () { expect(VersionConstraint.any.isAny, isTrue); expect( VersionConstraint.any, - allows(new Version.parse('0.0.0-blah'), new Version.parse('1.2.3'), - new Version.parse('12345.678.90'))); + allows(Version.parse('0.0.0-blah'), Version.parse('1.2.3'), + Version.parse('12345.678.90'))); }); test('empty', () { @@ -22,141 +22,132 @@ main() { expect(VersionConstraint.empty.isAny, isFalse); expect( VersionConstraint.empty, - doesNotAllow(new Version.parse('0.0.0-blah'), - new Version.parse('1.2.3'), new Version.parse('12345.678.90'))); + doesNotAllow(Version.parse('0.0.0-blah'), Version.parse('1.2.3'), + Version.parse('12345.678.90'))); }); group('parse()', () { test('parses an exact version', () { - var constraint = new VersionConstraint.parse('1.2.3-alpha'); + var constraint = VersionConstraint.parse('1.2.3-alpha'); expect(constraint is Version, isTrue); - expect(constraint, equals(new Version(1, 2, 3, pre: 'alpha'))); + expect(constraint, equals(Version(1, 2, 3, pre: 'alpha'))); }); test('parses "any"', () { - var constraint = new VersionConstraint.parse('any'); + var constraint = VersionConstraint.parse('any'); expect(constraint is VersionConstraint, isTrue); expect( constraint, - allows(new Version.parse('0.0.0'), new Version.parse('1.2.3'), - new Version.parse('12345.678.90'))); + allows(Version.parse('0.0.0'), Version.parse('1.2.3'), + Version.parse('12345.678.90'))); }); test('parses a ">" minimum version', () { - var constraint = new VersionConstraint.parse('>1.2.3'); + var constraint = VersionConstraint.parse('>1.2.3'); expect(constraint, - allows(new Version.parse('1.2.3+foo'), new Version.parse('1.2.4'))); + allows(Version.parse('1.2.3+foo'), Version.parse('1.2.4'))); expect( constraint, - doesNotAllow(new Version.parse('1.2.1'), - new Version.parse('1.2.3-build'), new Version.parse('1.2.3'))); + doesNotAllow(Version.parse('1.2.1'), Version.parse('1.2.3-build'), + Version.parse('1.2.3'))); }); test('parses a ">=" minimum version', () { - var constraint = new VersionConstraint.parse('>=1.2.3'); + var constraint = VersionConstraint.parse('>=1.2.3'); expect( constraint, - allows(new Version.parse('1.2.3'), new Version.parse('1.2.3+foo'), - new Version.parse('1.2.4'))); - expect( - constraint, - doesNotAllow( - new Version.parse('1.2.1'), new Version.parse('1.2.3-build'))); + allows(Version.parse('1.2.3'), Version.parse('1.2.3+foo'), + Version.parse('1.2.4'))); + expect(constraint, + doesNotAllow(Version.parse('1.2.1'), Version.parse('1.2.3-build'))); }); test('parses a "<" maximum version', () { - var constraint = new VersionConstraint.parse('<1.2.3'); + var constraint = VersionConstraint.parse('<1.2.3'); expect(constraint, - allows(new Version.parse('1.2.1'), new Version.parse('1.2.2+foo'))); + allows(Version.parse('1.2.1'), Version.parse('1.2.2+foo'))); expect( constraint, - doesNotAllow(new Version.parse('1.2.3'), - new Version.parse('1.2.3+foo'), new Version.parse('1.2.4'))); + doesNotAllow(Version.parse('1.2.3'), Version.parse('1.2.3+foo'), + Version.parse('1.2.4'))); }); test('parses a "<=" maximum version', () { - var constraint = new VersionConstraint.parse('<=1.2.3'); + var constraint = VersionConstraint.parse('<=1.2.3'); expect( constraint, - allows(new Version.parse('1.2.1'), new Version.parse('1.2.3-build'), - new Version.parse('1.2.3'))); - expect( - constraint, - doesNotAllow( - new Version.parse('1.2.3+foo'), new Version.parse('1.2.4'))); + allows(Version.parse('1.2.1'), Version.parse('1.2.3-build'), + Version.parse('1.2.3'))); + expect(constraint, + doesNotAllow(Version.parse('1.2.3+foo'), Version.parse('1.2.4'))); }); test('parses a series of space-separated constraints', () { - var constraint = new VersionConstraint.parse('>1.0.0 >=1.2.3 <1.3.0'); + var constraint = VersionConstraint.parse('>1.0.0 >=1.2.3 <1.3.0'); - expect(constraint, - allows(new Version.parse('1.2.3'), new Version.parse('1.2.5'))); + expect( + constraint, allows(Version.parse('1.2.3'), Version.parse('1.2.5'))); expect( constraint, - doesNotAllow(new Version.parse('1.2.3-pre'), - new Version.parse('1.3.0'), new Version.parse('3.4.5'))); + doesNotAllow(Version.parse('1.2.3-pre'), Version.parse('1.3.0'), + Version.parse('3.4.5'))); }); test('parses a pre-release-only constraint', () { - var constraint = new VersionConstraint.parse('>=1.0.0-dev.2 <1.0.0'); - expect( - constraint, - allows(new Version.parse('1.0.0-dev.2'), - new Version.parse('1.0.0-dev.3'))); - expect( - constraint, - doesNotAllow( - new Version.parse('1.0.0-dev.1'), new Version.parse('1.0.0'))); + var constraint = VersionConstraint.parse('>=1.0.0-dev.2 <1.0.0'); + expect(constraint, + allows(Version.parse('1.0.0-dev.2'), Version.parse('1.0.0-dev.3'))); + expect(constraint, + doesNotAllow(Version.parse('1.0.0-dev.1'), Version.parse('1.0.0'))); }); test('ignores whitespace around comparison operators', () { - var constraint = new VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0'); + var constraint = VersionConstraint.parse(' >1.0.0>=1.2.3 < 1.3.0'); - expect(constraint, - allows(new Version.parse('1.2.3'), new Version.parse('1.2.5'))); + expect( + constraint, allows(Version.parse('1.2.3'), Version.parse('1.2.5'))); expect( constraint, - doesNotAllow(new Version.parse('1.2.3-pre'), - new Version.parse('1.3.0'), new Version.parse('3.4.5'))); + doesNotAllow(Version.parse('1.2.3-pre'), Version.parse('1.3.0'), + Version.parse('3.4.5'))); }); test('does not allow "any" to be mixed with other constraints', () { - expect(() => new VersionConstraint.parse('any 1.0.0'), - throwsFormatException); + expect(() => VersionConstraint.parse('any 1.0.0'), throwsFormatException); }); test('parses a "^" version', () { - expect(new VersionConstraint.parse('^0.0.3'), - equals(new VersionConstraint.compatibleWith(v003))); + expect(VersionConstraint.parse('^0.0.3'), + equals(VersionConstraint.compatibleWith(v003))); - expect(new VersionConstraint.parse('^0.7.2'), - equals(new VersionConstraint.compatibleWith(v072))); + expect(VersionConstraint.parse('^0.7.2'), + equals(VersionConstraint.compatibleWith(v072))); - expect(new VersionConstraint.parse('^1.2.3'), - equals(new VersionConstraint.compatibleWith(v123))); + expect(VersionConstraint.parse('^1.2.3'), + equals(VersionConstraint.compatibleWith(v123))); - var min = new Version.parse('0.7.2-pre+1'); - expect(new VersionConstraint.parse('^0.7.2-pre+1'), - equals(new VersionConstraint.compatibleWith(min))); + var min = Version.parse('0.7.2-pre+1'); + expect(VersionConstraint.parse('^0.7.2-pre+1'), + equals(VersionConstraint.compatibleWith(min))); }); test('does not allow "^" to be mixed with other constraints', () { - expect(() => new VersionConstraint.parse('>=1.2.3 ^1.0.0'), + expect(() => VersionConstraint.parse('>=1.2.3 ^1.0.0'), throwsFormatException); - expect(() => new VersionConstraint.parse('^1.0.0 <1.2.3'), + expect(() => VersionConstraint.parse('^1.0.0 <1.2.3'), throwsFormatException); }); test('ignores whitespace around "^"', () { - var constraint = new VersionConstraint.parse(' ^ 1.2.3 '); + var constraint = VersionConstraint.parse(' ^ 1.2.3 '); - expect(constraint, equals(new VersionConstraint.compatibleWith(v123))); + expect(constraint, equals(VersionConstraint.compatibleWith(v123))); }); test('throws FormatException on a bad string', () { @@ -172,23 +163,23 @@ main() { ]; for (var text in bad) { - expect(() => new VersionConstraint.parse(text), throwsFormatException); + expect(() => VersionConstraint.parse(text), throwsFormatException); } }); }); group('compatibleWith()', () { test('returns the range of compatible versions', () { - var constraint = new VersionConstraint.compatibleWith(v072); + var constraint = VersionConstraint.compatibleWith(v072); expect( constraint, - equals(new VersionRange( + equals(VersionRange( min: v072, includeMin: true, max: v072.nextBreaking))); }); test('toString() uses "^"', () { - var constraint = new VersionConstraint.compatibleWith(v072); + var constraint = VersionConstraint.compatibleWith(v072); expect(constraint.toString(), equals('^0.7.2')); }); diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index a24faaea7..cfd66d975 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -8,10 +8,10 @@ import 'package:pub_semver/pub_semver.dart'; import 'utils.dart'; -main() { +void main() { group('constructor', () { test('takes a min and max', () { - var range = new VersionRange(min: v123, max: v124); + var range = VersionRange(min: v123, max: v124); expect(range.isAny, isFalse); expect(range.min, equals(v123)); expect(range.max, equals(v124.firstPreRelease)); @@ -19,184 +19,175 @@ main() { group("doesn't make the max a pre-release if", () { test("it's already a pre-release", () { - expect(new VersionRange(max: new Version.parse("1.2.4-pre")).max, - equals(new Version.parse("1.2.4-pre"))); + expect(VersionRange(max: Version.parse("1.2.4-pre")).max, + equals(Version.parse("1.2.4-pre"))); }); test("includeMax is true", () { - expect(new VersionRange(max: v124, includeMax: true).max, equals(v124)); + expect(VersionRange(max: v124, includeMax: true).max, equals(v124)); }); test("min is a prerelease of max", () { - expect( - new VersionRange(min: new Version.parse("1.2.4-pre"), max: v124) - .max, + expect(VersionRange(min: Version.parse("1.2.4-pre"), max: v124).max, equals(v124)); }); test("max has a build identifier", () { - expect(new VersionRange(max: new Version.parse("1.2.4+1")).max, - equals(new Version.parse("1.2.4+1"))); + expect(VersionRange(max: Version.parse("1.2.4+1")).max, + equals(Version.parse("1.2.4+1"))); }); }); test('allows omitting max', () { - var range = new VersionRange(min: v123); + var range = VersionRange(min: v123); expect(range.isAny, isFalse); expect(range.min, equals(v123)); expect(range.max, isNull); }); test('allows omitting min and max', () { - var range = new VersionRange(); + var range = VersionRange(); expect(range.isAny, isTrue); expect(range.min, isNull); expect(range.max, isNull); }); test('takes includeMin', () { - var range = new VersionRange(min: v123, includeMin: true); + var range = VersionRange(min: v123, includeMin: true); expect(range.includeMin, isTrue); }); test('includeMin defaults to false if omitted', () { - var range = new VersionRange(min: v123); + var range = VersionRange(min: v123); expect(range.includeMin, isFalse); }); test('takes includeMax', () { - var range = new VersionRange(max: v123, includeMax: true); + var range = VersionRange(max: v123, includeMax: true); expect(range.includeMax, isTrue); }); test('includeMax defaults to false if omitted', () { - var range = new VersionRange(max: v123); + var range = VersionRange(max: v123); expect(range.includeMax, isFalse); }); test('throws if min > max', () { - expect(() => new VersionRange(min: v124, max: v123), throwsArgumentError); + expect(() => VersionRange(min: v124, max: v123), throwsArgumentError); }); }); group('allows()', () { test('version must be greater than min', () { - var range = new VersionRange(min: v123); + var range = VersionRange(min: v123); - expect(range, - allows(new Version.parse('1.3.3'), new Version.parse('2.3.3'))); - expect(range, - doesNotAllow(new Version.parse('1.2.2'), new Version.parse('1.2.3'))); + expect(range, allows(Version.parse('1.3.3'), Version.parse('2.3.3'))); + expect( + range, doesNotAllow(Version.parse('1.2.2'), Version.parse('1.2.3'))); }); test('version must be min or greater if includeMin', () { - var range = new VersionRange(min: v123, includeMin: true); + var range = VersionRange(min: v123, includeMin: true); expect( range, - allows(new Version.parse('1.2.3'), new Version.parse('1.3.3'), - new Version.parse('2.3.3'))); - expect(range, doesNotAllow(new Version.parse('1.2.2'))); + allows(Version.parse('1.2.3'), Version.parse('1.3.3'), + Version.parse('2.3.3'))); + expect(range, doesNotAllow(Version.parse('1.2.2'))); }); test('pre-release versions of inclusive min are excluded', () { - var range = new VersionRange(min: v123, includeMin: true); + var range = VersionRange(min: v123, includeMin: true); - expect(range, allows(new Version.parse('1.2.4-dev'))); - expect(range, doesNotAllow(new Version.parse('1.2.3-dev'))); + expect(range, allows(Version.parse('1.2.4-dev'))); + expect(range, doesNotAllow(Version.parse('1.2.3-dev'))); }); test('version must be less than max', () { - var range = new VersionRange(max: v234); + var range = VersionRange(max: v234); - expect(range, allows(new Version.parse('2.3.3'))); - expect(range, - doesNotAllow(new Version.parse('2.3.4'), new Version.parse('2.4.3'))); + expect(range, allows(Version.parse('2.3.3'))); + expect( + range, doesNotAllow(Version.parse('2.3.4'), Version.parse('2.4.3'))); }); test('pre-release versions of non-pre-release max are excluded', () { - var range = new VersionRange(max: v234); + var range = VersionRange(max: v234); - expect(range, allows(new Version.parse('2.3.3'))); - expect( - range, - doesNotAllow( - new Version.parse('2.3.4-dev'), new Version.parse('2.3.4'))); + expect(range, allows(Version.parse('2.3.3'))); + expect(range, + doesNotAllow(Version.parse('2.3.4-dev'), Version.parse('2.3.4'))); }); test( 'pre-release versions of non-pre-release max are included if min is a ' 'pre-release of the same version', () { - var range = - new VersionRange(min: new Version.parse('2.3.4-dev.0'), max: v234); + var range = VersionRange(min: Version.parse('2.3.4-dev.0'), max: v234); - expect(range, allows(new Version.parse('2.3.4-dev.1'))); + expect(range, allows(Version.parse('2.3.4-dev.1'))); expect( range, - doesNotAllow(new Version.parse('2.3.3'), - new Version.parse('2.3.4-dev'), new Version.parse('2.3.4'))); + doesNotAllow(Version.parse('2.3.3'), Version.parse('2.3.4-dev'), + Version.parse('2.3.4'))); }); test('pre-release versions of pre-release max are included', () { - var range = new VersionRange(max: new Version.parse('2.3.4-dev.2')); + var range = VersionRange(max: Version.parse('2.3.4-dev.2')); - expect(range, allows(new Version.parse('2.3.4-dev.1'))); + expect(range, allows(Version.parse('2.3.4-dev.1'))); expect( range, - doesNotAllow(new Version.parse('2.3.4-dev.2'), - new Version.parse('2.3.4-dev.3'))); + doesNotAllow( + Version.parse('2.3.4-dev.2'), Version.parse('2.3.4-dev.3'))); }); test('version must be max or less if includeMax', () { - var range = new VersionRange(min: v123, max: v234, includeMax: true); + var range = VersionRange(min: v123, max: v234, includeMax: true); expect( range, allows( - new Version.parse('2.3.3'), - new Version.parse('2.3.4'), + Version.parse('2.3.3'), + Version.parse('2.3.4'), // Pre-releases of the max are allowed. - new Version.parse('2.3.4-dev'))); - expect(range, doesNotAllow(new Version.parse('2.4.3'))); + Version.parse('2.3.4-dev'))); + expect(range, doesNotAllow(Version.parse('2.4.3'))); }); test('has no min if one was not set', () { - var range = new VersionRange(max: v123); + var range = VersionRange(max: v123); - expect(range, allows(new Version.parse('0.0.0'))); - expect(range, doesNotAllow(new Version.parse('1.2.3'))); + expect(range, allows(Version.parse('0.0.0'))); + expect(range, doesNotAllow(Version.parse('1.2.3'))); }); test('has no max if one was not set', () { - var range = new VersionRange(min: v123); + var range = VersionRange(min: v123); - expect(range, - allows(new Version.parse('1.3.3'), new Version.parse('999.3.3'))); - expect(range, doesNotAllow(new Version.parse('1.2.3'))); + expect(range, allows(Version.parse('1.3.3'), Version.parse('999.3.3'))); + expect(range, doesNotAllow(Version.parse('1.2.3'))); }); test('allows any version if there is no min or max', () { - var range = new VersionRange(); + var range = VersionRange(); - expect(range, - allows(new Version.parse('0.0.0'), new Version.parse('999.99.9'))); + expect(range, allows(Version.parse('0.0.0'), Version.parse('999.99.9'))); }); test('allows pre-releases of the max with includeMaxPreRelease', () { - expect(includeMaxPreReleaseRange, allows(new Version.parse('2.0.0-dev'))); + expect(includeMaxPreReleaseRange, allows(Version.parse('2.0.0-dev'))); }); }); group('allowsAll()', () { test('allows an empty constraint', () { expect( - new VersionRange(min: v123, max: v250) - .allowsAll(VersionConstraint.empty), + VersionRange(min: v123, max: v250).allowsAll(VersionConstraint.empty), isTrue); }); test('allows allowed versions', () { - var range = new VersionRange(min: v123, max: v250, includeMax: true); + var range = VersionRange(min: v123, max: v250, includeMax: true); expect(range.allowsAll(v123), isFalse); expect(range.allowsAll(v124), isTrue); expect(range.allowsAll(v250), isTrue); @@ -204,38 +195,38 @@ main() { }); test('with no min', () { - var range = new VersionRange(max: v250); - expect(range.allowsAll(new VersionRange(min: v080, max: v140)), isTrue); - expect(range.allowsAll(new VersionRange(min: v080, max: v300)), isFalse); - expect(range.allowsAll(new VersionRange(max: v140)), isTrue); - expect(range.allowsAll(new VersionRange(max: v300)), isFalse); + var range = VersionRange(max: v250); + expect(range.allowsAll(VersionRange(min: v080, max: v140)), isTrue); + expect(range.allowsAll(VersionRange(min: v080, max: v300)), isFalse); + expect(range.allowsAll(VersionRange(max: v140)), isTrue); + expect(range.allowsAll(VersionRange(max: v300)), isFalse); expect(range.allowsAll(range), isTrue); expect(range.allowsAll(VersionConstraint.any), isFalse); }); test('with no max', () { - var range = new VersionRange(min: v010); - expect(range.allowsAll(new VersionRange(min: v080, max: v140)), isTrue); - expect(range.allowsAll(new VersionRange(min: v003, max: v140)), isFalse); - expect(range.allowsAll(new VersionRange(min: v080)), isTrue); - expect(range.allowsAll(new VersionRange(min: v003)), isFalse); + var range = VersionRange(min: v010); + expect(range.allowsAll(VersionRange(min: v080, max: v140)), isTrue); + expect(range.allowsAll(VersionRange(min: v003, max: v140)), isFalse); + expect(range.allowsAll(VersionRange(min: v080)), isTrue); + expect(range.allowsAll(VersionRange(min: v003)), isFalse); expect(range.allowsAll(range), isTrue); expect(range.allowsAll(VersionConstraint.any), isFalse); }); test('with a min and max', () { - var range = new VersionRange(min: v010, max: v250); - expect(range.allowsAll(new VersionRange(min: v080, max: v140)), isTrue); - expect(range.allowsAll(new VersionRange(min: v080, max: v300)), isFalse); - expect(range.allowsAll(new VersionRange(min: v003, max: v140)), isFalse); - expect(range.allowsAll(new VersionRange(min: v080)), isFalse); - expect(range.allowsAll(new VersionRange(max: v140)), isFalse); + var range = VersionRange(min: v010, max: v250); + expect(range.allowsAll(VersionRange(min: v080, max: v140)), isTrue); + expect(range.allowsAll(VersionRange(min: v080, max: v300)), isFalse); + expect(range.allowsAll(VersionRange(min: v003, max: v140)), isFalse); + expect(range.allowsAll(VersionRange(min: v080)), isFalse); + expect(range.allowsAll(VersionRange(max: v140)), isFalse); expect(range.allowsAll(range), isTrue); }); test("allows a bordering range that's not more inclusive", () { - var exclusive = new VersionRange(min: v010, max: v250); - var inclusive = new VersionRange( + var exclusive = VersionRange(min: v010, max: v250); + var inclusive = VersionRange( min: v010, includeMin: true, max: v250, includeMax: true); expect(inclusive.allowsAll(exclusive), isTrue); expect(inclusive.allowsAll(inclusive), isTrue); @@ -244,66 +235,59 @@ main() { }); test('allows unions that are completely contained', () { - var range = new VersionRange(min: v114, max: v200); - expect( - range.allowsAll(new VersionRange(min: v123, max: v124).union(v140)), + var range = VersionRange(min: v114, max: v200); + expect(range.allowsAll(VersionRange(min: v123, max: v124).union(v140)), isTrue); - expect( - range.allowsAll(new VersionRange(min: v010, max: v124).union(v140)), + expect(range.allowsAll(VersionRange(min: v010, max: v124).union(v140)), isFalse); - expect( - range.allowsAll(new VersionRange(min: v123, max: v234).union(v140)), + expect(range.allowsAll(VersionRange(min: v123, max: v234).union(v140)), isFalse); }); group('pre-release versions', () { test('of inclusive min are excluded', () { - var range = new VersionRange(min: v123, includeMin: true); + var range = VersionRange(min: v123, includeMin: true); - expect( - range.allowsAll(new VersionConstraint.parse('>1.2.4-dev')), isTrue); - expect(range.allowsAll(new VersionConstraint.parse('>1.2.3-dev')), - isFalse); + expect(range.allowsAll(VersionConstraint.parse('>1.2.4-dev')), isTrue); + expect(range.allowsAll(VersionConstraint.parse('>1.2.3-dev')), isFalse); }); test('of non-pre-release max are excluded', () { - var range = new VersionRange(max: v234); + var range = VersionRange(max: v234); - expect(range.allowsAll(new VersionConstraint.parse('<2.3.3')), isTrue); - expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev')), - isFalse); + expect(range.allowsAll(VersionConstraint.parse('<2.3.3')), isTrue); + expect(range.allowsAll(VersionConstraint.parse('<2.3.4-dev')), isFalse); }); test('of non-pre-release max are included with includeMaxPreRelease', () { expect( includeMaxPreReleaseRange - .allowsAll(new VersionConstraint.parse('<2.0.0-dev')), + .allowsAll(VersionConstraint.parse('<2.0.0-dev')), isTrue); }); test( 'of non-pre-release max are included if min is a pre-release of the ' 'same version', () { - var range = - new VersionRange(min: new Version.parse('2.3.4-dev.0'), max: v234); + var range = VersionRange(min: Version.parse('2.3.4-dev.0'), max: v234); expect( range.allowsAll( - new VersionConstraint.parse('>2.3.4-dev.0 <2.3.4-dev.1')), + VersionConstraint.parse('>2.3.4-dev.0 <2.3.4-dev.1')), isTrue); }); test('of pre-release max are included', () { - var range = new VersionRange(max: new Version.parse('2.3.4-dev.2')); + var range = VersionRange(max: Version.parse('2.3.4-dev.2')); - expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev.1')), - isTrue); - expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev.2')), - isTrue); - expect(range.allowsAll(new VersionConstraint.parse('<=2.3.4-dev.2')), - isFalse); - expect(range.allowsAll(new VersionConstraint.parse('<2.3.4-dev.3')), - isFalse); + expect( + range.allowsAll(VersionConstraint.parse('<2.3.4-dev.1')), isTrue); + expect( + range.allowsAll(VersionConstraint.parse('<2.3.4-dev.2')), isTrue); + expect( + range.allowsAll(VersionConstraint.parse('<=2.3.4-dev.2')), isFalse); + expect( + range.allowsAll(VersionConstraint.parse('<2.3.4-dev.3')), isFalse); }); }); }); @@ -311,13 +295,12 @@ main() { group('allowsAny()', () { test('disallows an empty constraint', () { expect( - new VersionRange(min: v123, max: v250) - .allowsAny(VersionConstraint.empty), + VersionRange(min: v123, max: v250).allowsAny(VersionConstraint.empty), isFalse); }); test('allows allowed versions', () { - var range = new VersionRange(min: v123, max: v250, includeMax: true); + var range = VersionRange(min: v123, max: v250, includeMax: true); expect(range.allowsAny(v123), isFalse); expect(range.allowsAny(v124), isTrue); expect(range.allowsAny(v250), isTrue); @@ -325,135 +308,127 @@ main() { }); test('with no min', () { - var range = new VersionRange(max: v200); - expect(range.allowsAny(new VersionRange(min: v140, max: v300)), isTrue); - expect(range.allowsAny(new VersionRange(min: v234, max: v300)), isFalse); - expect(range.allowsAny(new VersionRange(min: v140)), isTrue); - expect(range.allowsAny(new VersionRange(min: v234)), isFalse); + var range = VersionRange(max: v200); + expect(range.allowsAny(VersionRange(min: v140, max: v300)), isTrue); + expect(range.allowsAny(VersionRange(min: v234, max: v300)), isFalse); + expect(range.allowsAny(VersionRange(min: v140)), isTrue); + expect(range.allowsAny(VersionRange(min: v234)), isFalse); expect(range.allowsAny(range), isTrue); }); test('with no max', () { - var range = new VersionRange(min: v072); - expect(range.allowsAny(new VersionRange(min: v003, max: v140)), isTrue); - expect(range.allowsAny(new VersionRange(min: v003, max: v010)), isFalse); - expect(range.allowsAny(new VersionRange(max: v080)), isTrue); - expect(range.allowsAny(new VersionRange(max: v003)), isFalse); + var range = VersionRange(min: v072); + expect(range.allowsAny(VersionRange(min: v003, max: v140)), isTrue); + expect(range.allowsAny(VersionRange(min: v003, max: v010)), isFalse); + expect(range.allowsAny(VersionRange(max: v080)), isTrue); + expect(range.allowsAny(VersionRange(max: v003)), isFalse); expect(range.allowsAny(range), isTrue); }); test('with a min and max', () { - var range = new VersionRange(min: v072, max: v200); - expect(range.allowsAny(new VersionRange(min: v003, max: v140)), isTrue); - expect(range.allowsAny(new VersionRange(min: v140, max: v300)), isTrue); - expect(range.allowsAny(new VersionRange(min: v003, max: v010)), isFalse); - expect(range.allowsAny(new VersionRange(min: v234, max: v300)), isFalse); - expect(range.allowsAny(new VersionRange(max: v010)), isFalse); - expect(range.allowsAny(new VersionRange(min: v234)), isFalse); + var range = VersionRange(min: v072, max: v200); + expect(range.allowsAny(VersionRange(min: v003, max: v140)), isTrue); + expect(range.allowsAny(VersionRange(min: v140, max: v300)), isTrue); + expect(range.allowsAny(VersionRange(min: v003, max: v010)), isFalse); + expect(range.allowsAny(VersionRange(min: v234, max: v300)), isFalse); + expect(range.allowsAny(VersionRange(max: v010)), isFalse); + expect(range.allowsAny(VersionRange(min: v234)), isFalse); expect(range.allowsAny(range), isTrue); }); test('allows a bordering range when both are inclusive', () { - expect(new VersionRange(max: v250).allowsAny(new VersionRange(min: v250)), - isFalse); + expect( + VersionRange(max: v250).allowsAny(VersionRange(min: v250)), isFalse); expect( - new VersionRange(max: v250, includeMax: true) - .allowsAny(new VersionRange(min: v250)), + VersionRange(max: v250, includeMax: true) + .allowsAny(VersionRange(min: v250)), isFalse); expect( - new VersionRange(max: v250) - .allowsAny(new VersionRange(min: v250, includeMin: true)), + VersionRange(max: v250) + .allowsAny(VersionRange(min: v250, includeMin: true)), isFalse); expect( - new VersionRange(max: v250, includeMax: true) - .allowsAny(new VersionRange(min: v250, includeMin: true)), + VersionRange(max: v250, includeMax: true) + .allowsAny(VersionRange(min: v250, includeMin: true)), isTrue); - expect(new VersionRange(min: v250).allowsAny(new VersionRange(max: v250)), - isFalse); + expect( + VersionRange(min: v250).allowsAny(VersionRange(max: v250)), isFalse); expect( - new VersionRange(min: v250, includeMin: true) - .allowsAny(new VersionRange(max: v250)), + VersionRange(min: v250, includeMin: true) + .allowsAny(VersionRange(max: v250)), isFalse); expect( - new VersionRange(min: v250) - .allowsAny(new VersionRange(max: v250, includeMax: true)), + VersionRange(min: v250) + .allowsAny(VersionRange(max: v250, includeMax: true)), isFalse); expect( - new VersionRange(min: v250, includeMin: true) - .allowsAny(new VersionRange(max: v250, includeMax: true)), + VersionRange(min: v250, includeMin: true) + .allowsAny(VersionRange(max: v250, includeMax: true)), isTrue); }); test('allows unions that are partially contained', () { - var range = new VersionRange(min: v114, max: v200); - expect( - range.allowsAny(new VersionRange(min: v010, max: v080).union(v140)), + var range = VersionRange(min: v114, max: v200); + expect(range.allowsAny(VersionRange(min: v010, max: v080).union(v140)), isTrue); - expect( - range.allowsAny(new VersionRange(min: v123, max: v234).union(v300)), + expect(range.allowsAny(VersionRange(min: v123, max: v234).union(v300)), isTrue); - expect( - range.allowsAny(new VersionRange(min: v234, max: v300).union(v010)), + expect(range.allowsAny(VersionRange(min: v234, max: v300).union(v010)), isFalse); }); group('pre-release versions', () { test('of inclusive min are excluded', () { - var range = new VersionRange(min: v123, includeMin: true); + var range = VersionRange(min: v123, includeMin: true); - expect( - range.allowsAny(new VersionConstraint.parse('<1.2.4-dev')), isTrue); - expect(range.allowsAny(new VersionConstraint.parse('<1.2.3-dev')), - isFalse); + expect(range.allowsAny(VersionConstraint.parse('<1.2.4-dev')), isTrue); + expect(range.allowsAny(VersionConstraint.parse('<1.2.3-dev')), isFalse); }); test('of non-pre-release max are excluded', () { - var range = new VersionRange(max: v234); + var range = VersionRange(max: v234); - expect(range.allowsAny(new VersionConstraint.parse('>2.3.3')), isTrue); - expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev')), - isFalse); + expect(range.allowsAny(VersionConstraint.parse('>2.3.3')), isTrue); + expect(range.allowsAny(VersionConstraint.parse('>2.3.4-dev')), isFalse); }); test('of non-pre-release max are included with includeMaxPreRelease', () { expect( includeMaxPreReleaseRange - .allowsAny(new VersionConstraint.parse('>2.0.0-dev')), + .allowsAny(VersionConstraint.parse('>2.0.0-dev')), isTrue); }); test( 'of non-pre-release max are included if min is a pre-release of the ' 'same version', () { - var range = - new VersionRange(min: new Version.parse('2.3.4-dev.0'), max: v234); + var range = VersionRange(min: Version.parse('2.3.4-dev.0'), max: v234); - expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.1')), - isTrue); - expect(range.allowsAny(new VersionConstraint.parse('>2.3.4')), isFalse); + expect( + range.allowsAny(VersionConstraint.parse('>2.3.4-dev.1')), isTrue); + expect(range.allowsAny(VersionConstraint.parse('>2.3.4')), isFalse); - expect(range.allowsAny(new VersionConstraint.parse('<2.3.4-dev.1')), - isTrue); - expect(range.allowsAny(new VersionConstraint.parse('<2.3.4-dev')), - isFalse); + expect( + range.allowsAny(VersionConstraint.parse('<2.3.4-dev.1')), isTrue); + expect(range.allowsAny(VersionConstraint.parse('<2.3.4-dev')), isFalse); }); test('of pre-release max are included', () { - var range = new VersionConstraint.parse('<2.3.4-dev.2'); + var range = VersionConstraint.parse('<2.3.4-dev.2'); - expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.1')), - isTrue); - expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.2')), - isFalse); - expect(range.allowsAny(new VersionConstraint.parse('>2.3.4-dev.3')), - isFalse); + expect( + range.allowsAny(VersionConstraint.parse('>2.3.4-dev.1')), isTrue); + expect( + range.allowsAny(VersionConstraint.parse('>2.3.4-dev.2')), isFalse); + expect( + range.allowsAny(VersionConstraint.parse('>2.3.4-dev.3')), isFalse); }); }); }); @@ -461,78 +436,77 @@ main() { group('intersect()', () { test('two overlapping ranges', () { expect( - new VersionRange(min: v123, max: v250) - .intersect(new VersionRange(min: v200, max: v300)), - equals(new VersionRange(min: v200, max: v250))); + VersionRange(min: v123, max: v250) + .intersect(VersionRange(min: v200, max: v300)), + equals(VersionRange(min: v200, max: v250))); }); test('a non-overlapping range allows no versions', () { - var a = new VersionRange(min: v114, max: v124); - var b = new VersionRange(min: v200, max: v250); + var a = VersionRange(min: v114, max: v124); + var b = VersionRange(min: v200, max: v250); expect(a.intersect(b).isEmpty, isTrue); }); test('adjacent ranges allow no versions if exclusive', () { - var a = new VersionRange(min: v114, max: v124); - var b = new VersionRange(min: v124, max: v200); + var a = VersionRange(min: v114, max: v124); + var b = VersionRange(min: v124, max: v200); expect(a.intersect(b).isEmpty, isTrue); }); test('adjacent ranges allow version if inclusive', () { - var a = new VersionRange(min: v114, max: v124, includeMax: true); - var b = new VersionRange(min: v124, max: v200, includeMin: true); + var a = VersionRange(min: v114, max: v124, includeMax: true); + var b = VersionRange(min: v124, max: v200, includeMin: true); expect(a.intersect(b), equals(v124)); }); test('with an open range', () { - var open = new VersionRange(); - var a = new VersionRange(min: v114, max: v124); + var open = VersionRange(); + var a = VersionRange(min: v114, max: v124); expect(open.intersect(open), equals(open)); expect(a.intersect(open), equals(a)); }); test('returns the version if the range allows it', () { + expect(VersionRange(min: v114, max: v124).intersect(v123), equals(v123)); expect( - new VersionRange(min: v114, max: v124).intersect(v123), equals(v123)); - expect(new VersionRange(min: v123, max: v124).intersect(v114).isEmpty, - isTrue); + VersionRange(min: v123, max: v124).intersect(v114).isEmpty, isTrue); }); test("with a range with a pre-release min, returns an empty constraint", () { expect( - new VersionRange(max: v200) - .intersect(new VersionConstraint.parse(">=2.0.0-dev")), + VersionRange(max: v200) + .intersect(VersionConstraint.parse(">=2.0.0-dev")), equals(VersionConstraint.empty)); }); test("with a range with a pre-release max, returns the original", () { expect( - new VersionRange(max: v200) - .intersect(new VersionConstraint.parse("<2.0.0-dev")), - equals(new VersionRange(max: v200))); + VersionRange(max: v200) + .intersect(VersionConstraint.parse("<2.0.0-dev")), + equals(VersionRange(max: v200))); }); group("with includeMaxPreRelease", () { test('preserves includeMaxPreRelease if the max version is included', () { expect( includeMaxPreReleaseRange - .intersect(new VersionConstraint.parse("<1.0.0")), - equals(new VersionConstraint.parse("<1.0.0"))); + .intersect(VersionConstraint.parse("<1.0.0")), + equals(VersionConstraint.parse("<1.0.0"))); expect( includeMaxPreReleaseRange - .intersect(new VersionConstraint.parse("<2.0.0")), - equals(new VersionConstraint.parse("<2.0.0"))); + .intersect(VersionConstraint.parse("<2.0.0")), + equals(VersionConstraint.parse("<2.0.0"))); expect(includeMaxPreReleaseRange.intersect(includeMaxPreReleaseRange), equals(includeMaxPreReleaseRange)); expect( includeMaxPreReleaseRange - .intersect(new VersionConstraint.parse("<3.0.0")), + .intersect(VersionConstraint.parse("<3.0.0")), equals(includeMaxPreReleaseRange)); expect( includeMaxPreReleaseRange - .intersect(new VersionConstraint.parse(">1.1.4")), - equals(new VersionRange( + .intersect(VersionConstraint.parse(">1.1.4")), + equals(VersionRange( min: v114, max: v200, alwaysIncludeMaxPreRelease: true))); }); @@ -541,8 +515,8 @@ main() { "an intersection", () { expect( includeMaxPreReleaseRange - .intersect(new VersionConstraint.parse(">=2.0.0-dev")), - equals(new VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); + .intersect(VersionConstraint.parse(">=2.0.0-dev")), + equals(VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); }); test( @@ -550,142 +524,136 @@ main() { "the narrower constraint", () { expect( includeMaxPreReleaseRange - .intersect(new VersionConstraint.parse("<2.0.0-dev")), - equals(new VersionConstraint.parse("<2.0.0-dev"))); + .intersect(VersionConstraint.parse("<2.0.0-dev")), + equals(VersionConstraint.parse("<2.0.0-dev"))); }); }); }); group('union()', () { test("with a version returns the range if it contains the version", () { - var range = new VersionRange(min: v114, max: v124); + var range = VersionRange(min: v114, max: v124); expect(range.union(v123), equals(range)); }); test("with a version on the edge of the range, expands the range", () { expect( - new VersionRange( - min: v114, max: v124, alwaysIncludeMaxPreRelease: true) + VersionRange(min: v114, max: v124, alwaysIncludeMaxPreRelease: true) .union(v124), - equals(new VersionRange(min: v114, max: v124, includeMax: true))); - expect(new VersionRange(min: v114, max: v124).union(v114), - equals(new VersionRange(min: v114, max: v124, includeMin: true))); + equals(VersionRange(min: v114, max: v124, includeMax: true))); + expect(VersionRange(min: v114, max: v124).union(v114), + equals(VersionRange(min: v114, max: v124, includeMin: true))); }); test( "with a version allows both the range and the version if the range " "doesn't contain the version", () { - var result = new VersionRange(min: v003, max: v114).union(v124); + var result = VersionRange(min: v003, max: v114).union(v124); expect(result, allows(v010)); expect(result, doesNotAllow(v123)); expect(result, allows(v124)); }); test("returns a VersionUnion for a disjoint range", () { - var result = new VersionRange(min: v003, max: v114) - .union(new VersionRange(min: v130, max: v200)); + var result = VersionRange(min: v003, max: v114) + .union(VersionRange(min: v130, max: v200)); expect(result, allows(v080)); expect(result, doesNotAllow(v123)); expect(result, allows(v140)); }); test("considers open ranges disjoint", () { - var result = new VersionRange(min: v003, max: v114) - .union(new VersionRange(min: v114, max: v200)); + var result = VersionRange(min: v003, max: v114) + .union(VersionRange(min: v114, max: v200)); expect(result, allows(v080)); expect(result, doesNotAllow(v114)); expect(result, allows(v140)); - result = new VersionRange(min: v114, max: v200) - .union(new VersionRange(min: v003, max: v114)); + result = VersionRange(min: v114, max: v200) + .union(VersionRange(min: v003, max: v114)); expect(result, allows(v080)); expect(result, doesNotAllow(v114)); expect(result, allows(v140)); }); test("returns a merged range for an overlapping range", () { - var result = new VersionRange(min: v003, max: v114) - .union(new VersionRange(min: v080, max: v200)); - expect(result, equals(new VersionRange(min: v003, max: v200))); + var result = VersionRange(min: v003, max: v114) + .union(VersionRange(min: v080, max: v200)); + expect(result, equals(VersionRange(min: v003, max: v200))); }); test("considers closed ranges overlapping", () { - var result = new VersionRange(min: v003, max: v114, includeMax: true) - .union(new VersionRange(min: v114, max: v200)); - expect(result, equals(new VersionRange(min: v003, max: v200))); + var result = VersionRange(min: v003, max: v114, includeMax: true) + .union(VersionRange(min: v114, max: v200)); + expect(result, equals(VersionRange(min: v003, max: v200))); - result = new VersionRange( - min: v003, max: v114, alwaysIncludeMaxPreRelease: true) - .union(new VersionRange(min: v114, max: v200, includeMin: true)); - expect(result, equals(new VersionRange(min: v003, max: v200))); + result = + VersionRange(min: v003, max: v114, alwaysIncludeMaxPreRelease: true) + .union(VersionRange(min: v114, max: v200, includeMin: true)); + expect(result, equals(VersionRange(min: v003, max: v200))); - result = new VersionRange(min: v114, max: v200) - .union(new VersionRange(min: v003, max: v114, includeMax: true)); - expect(result, equals(new VersionRange(min: v003, max: v200))); + result = VersionRange(min: v114, max: v200) + .union(VersionRange(min: v003, max: v114, includeMax: true)); + expect(result, equals(VersionRange(min: v003, max: v200))); - result = new VersionRange(min: v114, max: v200, includeMin: true).union( - new VersionRange( - min: v003, max: v114, alwaysIncludeMaxPreRelease: true)); - expect(result, equals(new VersionRange(min: v003, max: v200))); + result = VersionRange(min: v114, max: v200, includeMin: true).union( + VersionRange(min: v003, max: v114, alwaysIncludeMaxPreRelease: true)); + expect(result, equals(VersionRange(min: v003, max: v200))); }); test("includes edges if either range does", () { - var result = new VersionRange(min: v003, max: v114, includeMin: true) - .union(new VersionRange(min: v003, max: v114, includeMax: true)); + var result = VersionRange(min: v003, max: v114, includeMin: true) + .union(VersionRange(min: v003, max: v114, includeMax: true)); expect( result, - equals(new VersionRange( + equals(VersionRange( min: v003, max: v114, includeMin: true, includeMax: true))); }); test("with a range with a pre-release min, returns a constraint with a gap", () { - var result = new VersionRange(max: v200) - .union(new VersionConstraint.parse(">=2.0.0-dev")); + var result = + VersionRange(max: v200).union(VersionConstraint.parse(">=2.0.0-dev")); expect(result, allows(v140)); - expect(result, doesNotAllow(new Version.parse("2.0.0-alpha"))); - expect(result, allows(new Version.parse("2.0.0-dev"))); - expect(result, allows(new Version.parse("2.0.0-dev.1"))); - expect(result, allows(new Version.parse("2.0.0"))); + expect(result, doesNotAllow(Version.parse("2.0.0-alpha"))); + expect(result, allows(Version.parse("2.0.0-dev"))); + expect(result, allows(Version.parse("2.0.0-dev.1"))); + expect(result, allows(Version.parse("2.0.0"))); }); test("with a range with a pre-release max, returns the larger constraint", () { expect( - new VersionRange(max: v200) - .union(new VersionConstraint.parse("<2.0.0-dev")), - equals(new VersionConstraint.parse("<2.0.0-dev"))); + VersionRange(max: v200).union(VersionConstraint.parse("<2.0.0-dev")), + equals(VersionConstraint.parse("<2.0.0-dev"))); }); group("with includeMaxPreRelease", () { test('adds includeMaxPreRelease if the max version is included', () { expect( - includeMaxPreReleaseRange - .union(new VersionConstraint.parse("<1.0.0")), + includeMaxPreReleaseRange.union(VersionConstraint.parse("<1.0.0")), equals(includeMaxPreReleaseRange)); expect(includeMaxPreReleaseRange.union(includeMaxPreReleaseRange), equals(includeMaxPreReleaseRange)); expect( - includeMaxPreReleaseRange - .union(new VersionConstraint.parse("<2.0.0")), + includeMaxPreReleaseRange.union(VersionConstraint.parse("<2.0.0")), equals(includeMaxPreReleaseRange)); expect( - includeMaxPreReleaseRange - .union(new VersionConstraint.parse("<3.0.0")), - equals(new VersionConstraint.parse("<3.0.0"))); + includeMaxPreReleaseRange.union(VersionConstraint.parse("<3.0.0")), + equals(VersionConstraint.parse("<3.0.0"))); }); test("and a range with a pre-release min, returns any", () { expect( includeMaxPreReleaseRange - .union(new VersionConstraint.parse(">=2.0.0-dev")), + .union(VersionConstraint.parse(">=2.0.0-dev")), equals(VersionConstraint.any)); }); test("and a range with a pre-release max, returns the original", () { expect( includeMaxPreReleaseRange - .union(new VersionConstraint.parse("<2.0.0-dev")), + .union(VersionConstraint.parse("<2.0.0-dev")), equals(includeMaxPreReleaseRange)); }); }); @@ -694,127 +662,124 @@ main() { group('difference()', () { test("with an empty range returns the original range", () { expect( - new VersionRange(min: v003, max: v114) + VersionRange(min: v003, max: v114) .difference(VersionConstraint.empty), - equals(new VersionRange(min: v003, max: v114))); + equals(VersionRange(min: v003, max: v114))); }); test("with a version outside the range returns the original range", () { - expect(new VersionRange(min: v003, max: v114).difference(v200), - equals(new VersionRange(min: v003, max: v114))); + expect(VersionRange(min: v003, max: v114).difference(v200), + equals(VersionRange(min: v003, max: v114))); }); test("with a version in the range splits the range", () { expect( - new VersionRange(min: v003, max: v114).difference(v072), - equals(new VersionConstraint.unionOf([ - new VersionRange( + VersionRange(min: v003, max: v114).difference(v072), + equals(VersionConstraint.unionOf([ + VersionRange( min: v003, max: v072, alwaysIncludeMaxPreRelease: true), - new VersionRange(min: v072, max: v114) + VersionRange(min: v072, max: v114) ]))); }); test("with the max version makes the max exclusive", () { expect( - new VersionRange(min: v003, max: v114, includeMax: true) - .difference(v114), - equals(new VersionRange( + VersionRange(min: v003, max: v114, includeMax: true).difference(v114), + equals(VersionRange( min: v003, max: v114, alwaysIncludeMaxPreRelease: true))); }); test("with the min version makes the min exclusive", () { expect( - new VersionRange(min: v003, max: v114, includeMin: true) - .difference(v003), - equals(new VersionRange(min: v003, max: v114))); + VersionRange(min: v003, max: v114, includeMin: true).difference(v003), + equals(VersionRange(min: v003, max: v114))); }); test("with a disjoint range returns the original", () { expect( - new VersionRange(min: v003, max: v114) - .difference(new VersionRange(min: v123, max: v140)), - equals(new VersionRange(min: v003, max: v114))); + VersionRange(min: v003, max: v114) + .difference(VersionRange(min: v123, max: v140)), + equals(VersionRange(min: v003, max: v114))); }); test("with an adjacent range returns the original", () { expect( - new VersionRange(min: v003, max: v114, includeMax: true) - .difference(new VersionRange(min: v114, max: v140)), - equals(new VersionRange(min: v003, max: v114, includeMax: true))); + VersionRange(min: v003, max: v114, includeMax: true) + .difference(VersionRange(min: v114, max: v140)), + equals(VersionRange(min: v003, max: v114, includeMax: true))); }); test("with a range at the beginning cuts off the beginning of the range", () { expect( - new VersionRange(min: v080, max: v130) - .difference(new VersionRange(min: v010, max: v114)), - equals(new VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); + VersionRange(min: v080, max: v130) + .difference(VersionRange(min: v010, max: v114)), + equals(VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); expect( - new VersionRange(min: v080, max: v130) - .difference(new VersionRange(max: v114)), - equals(new VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); + VersionRange(min: v080, max: v130) + .difference(VersionRange(max: v114)), + equals(VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); expect( - new VersionRange(min: v080, max: v130).difference( - new VersionRange(min: v010, max: v114, includeMax: true)), - equals(new VersionRange(min: v114, max: v130))); + VersionRange(min: v080, max: v130) + .difference(VersionRange(min: v010, max: v114, includeMax: true)), + equals(VersionRange(min: v114, max: v130))); expect( - new VersionRange(min: v080, max: v130, includeMin: true).difference( - new VersionRange(min: v010, max: v080, includeMax: true)), - equals(new VersionRange(min: v080, max: v130))); + VersionRange(min: v080, max: v130, includeMin: true) + .difference(VersionRange(min: v010, max: v080, includeMax: true)), + equals(VersionRange(min: v080, max: v130))); expect( - new VersionRange(min: v080, max: v130, includeMax: true) - .difference(new VersionRange(min: v080, max: v130)), - equals(new VersionConstraint.parse(">=1.3.0-0 <=1.3.0"))); + VersionRange(min: v080, max: v130, includeMax: true) + .difference(VersionRange(min: v080, max: v130)), + equals(VersionConstraint.parse(">=1.3.0-0 <=1.3.0"))); }); test("with a range at the end cuts off the end of the range", () { expect( - new VersionRange(min: v080, max: v130) - .difference(new VersionRange(min: v114, max: v140)), - equals(new VersionRange(min: v080, max: v114, includeMax: true))); + VersionRange(min: v080, max: v130) + .difference(VersionRange(min: v114, max: v140)), + equals(VersionRange(min: v080, max: v114, includeMax: true))); expect( - new VersionRange(min: v080, max: v130) - .difference(new VersionRange(min: v114)), - equals(new VersionRange(min: v080, max: v114, includeMax: true))); + VersionRange(min: v080, max: v130) + .difference(VersionRange(min: v114)), + equals(VersionRange(min: v080, max: v114, includeMax: true))); expect( - new VersionRange(min: v080, max: v130).difference( - new VersionRange(min: v114, max: v140, includeMin: true)), - equals(new VersionRange( + VersionRange(min: v080, max: v130) + .difference(VersionRange(min: v114, max: v140, includeMin: true)), + equals(VersionRange( min: v080, max: v114, alwaysIncludeMaxPreRelease: true))); expect( - new VersionRange(min: v080, max: v130, includeMax: true).difference( - new VersionRange(min: v130, max: v140, includeMin: true)), - equals(new VersionRange( + VersionRange(min: v080, max: v130, includeMax: true) + .difference(VersionRange(min: v130, max: v140, includeMin: true)), + equals(VersionRange( min: v080, max: v130, alwaysIncludeMaxPreRelease: true))); expect( - new VersionRange(min: v080, max: v130, includeMin: true) - .difference(new VersionRange(min: v080, max: v130)), + VersionRange(min: v080, max: v130, includeMin: true) + .difference(VersionRange(min: v080, max: v130)), equals(v080)); }); test("with a range in the middle cuts the range in half", () { expect( - new VersionRange(min: v003, max: v130) - .difference(new VersionRange(min: v072, max: v114)), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072, includeMax: true), - new VersionConstraint.parse(">=1.1.4-0 <1.3.0") + VersionRange(min: v003, max: v130) + .difference(VersionRange(min: v072, max: v114)), + equals(VersionConstraint.unionOf([ + VersionRange(min: v003, max: v072, includeMax: true), + VersionConstraint.parse(">=1.1.4-0 <1.3.0") ]))); }); test("with a totally covering range returns empty", () { expect( - new VersionRange(min: v114, max: v200) - .difference(new VersionRange(min: v072, max: v300)), + VersionRange(min: v114, max: v200) + .difference(VersionRange(min: v072, max: v300)), isEmpty); expect( - new VersionRange(min: v003, max: v114) - .difference(new VersionRange(min: v003, max: v114)), + VersionRange(min: v003, max: v114) + .difference(VersionRange(min: v003, max: v114)), isEmpty); expect( - new VersionRange( - min: v003, max: v114, includeMin: true, includeMax: true) - .difference(new VersionRange( + VersionRange(min: v003, max: v114, includeMin: true, includeMax: true) + .difference(VersionRange( min: v003, max: v114, includeMin: true, includeMax: true)), isEmpty); }); @@ -823,55 +788,54 @@ main() { "with a version union that doesn't cover the range, returns the " "original", () { expect( - new VersionRange(min: v114, max: v140) - .difference(new VersionConstraint.unionOf([v010, v200])), - equals(new VersionRange(min: v114, max: v140))); + VersionRange(min: v114, max: v140) + .difference(VersionConstraint.unionOf([v010, v200])), + equals(VersionRange(min: v114, max: v140))); }); test("with a version union that intersects the ends, chops them off", () { expect( - new VersionRange(min: v114, max: v140).difference( - new VersionConstraint.unionOf([ - new VersionRange(min: v080, max: v123), - new VersionRange(min: v130, max: v200) + VersionRange(min: v114, max: v140).difference( + VersionConstraint.unionOf([ + VersionRange(min: v080, max: v123), + VersionRange(min: v130, max: v200) ])), - equals(new VersionConstraint.parse(">=1.2.3-0 <=1.3.0"))); + equals(VersionConstraint.parse(">=1.2.3-0 <=1.3.0"))); }); test("with a version union that intersects the middle, chops it up", () { expect( - new VersionRange(min: v114, max: v140) - .difference(new VersionConstraint.unionOf([v123, v124, v130])), - equals(new VersionConstraint.unionOf([ - new VersionRange( + VersionRange(min: v114, max: v140) + .difference(VersionConstraint.unionOf([v123, v124, v130])), + equals(VersionConstraint.unionOf([ + VersionRange( min: v114, max: v123, alwaysIncludeMaxPreRelease: true), - new VersionRange( + VersionRange( min: v123, max: v124, alwaysIncludeMaxPreRelease: true), - new VersionRange( + VersionRange( min: v124, max: v130, alwaysIncludeMaxPreRelease: true), - new VersionRange(min: v130, max: v140) + VersionRange(min: v130, max: v140) ]))); }); test("with a version union that covers the whole range, returns empty", () { expect( - new VersionRange(min: v114, max: v140).difference( - new VersionConstraint.unionOf( - [v003, new VersionRange(min: v010)])), + VersionRange(min: v114, max: v140).difference( + VersionConstraint.unionOf([v003, VersionRange(min: v010)])), equals(VersionConstraint.empty)); }); test("with a range with a pre-release min, returns the original", () { expect( - new VersionRange(max: v200) - .difference(new VersionConstraint.parse(">=2.0.0-dev")), - equals(new VersionRange(max: v200))); + VersionRange(max: v200) + .difference(VersionConstraint.parse(">=2.0.0-dev")), + equals(VersionRange(max: v200))); }); test("with a range with a pre-release max, returns null", () { expect( - new VersionRange(max: v200) - .difference(new VersionConstraint.parse("<2.0.0-dev")), + VersionRange(max: v200) + .difference(VersionConstraint.parse("<2.0.0-dev")), equals(VersionConstraint.empty)); }); @@ -881,16 +845,16 @@ main() { () { expect( includeMaxPreReleaseRange - .difference(new VersionConstraint.parse("<1.0.0")), - equals(new VersionRange( - min: new Version.parse("1.0.0-0"), + .difference(VersionConstraint.parse("<1.0.0")), + equals(VersionRange( + min: Version.parse("1.0.0-0"), max: v200, includeMin: true, alwaysIncludeMaxPreRelease: true))); expect( includeMaxPreReleaseRange - .difference(new VersionConstraint.parse("<2.0.0")), - equals(new VersionRange( + .difference(VersionConstraint.parse("<2.0.0")), + equals(VersionRange( min: v200.firstPreRelease, max: v200, includeMin: true, @@ -900,22 +864,22 @@ main() { equals(VersionConstraint.empty)); expect( includeMaxPreReleaseRange - .difference(new VersionConstraint.parse("<3.0.0")), + .difference(VersionConstraint.parse("<3.0.0")), equals(VersionConstraint.empty)); }); test("with a range with a pre-release min, adjusts the max", () { expect( includeMaxPreReleaseRange - .difference(new VersionConstraint.parse(">=2.0.0-dev")), - equals(new VersionConstraint.parse("<2.0.0-dev"))); + .difference(VersionConstraint.parse(">=2.0.0-dev")), + equals(VersionConstraint.parse("<2.0.0-dev"))); }); test("with a range with a pre-release max, adjusts the min", () { expect( includeMaxPreReleaseRange - .difference(new VersionConstraint.parse("<2.0.0-dev")), - equals(new VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); + .difference(VersionConstraint.parse("<2.0.0-dev")), + equals(VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); }); }); @@ -923,29 +887,27 @@ main() { group("doesn't create a pre-release minimum", () { test("when cutting off the bottom", () { expect( - new VersionConstraint.parse("<3.0.0") + VersionConstraint.parse("<3.0.0") .difference(includeMaxPreReleaseRange), - equals( - new VersionRange(min: v200, max: v300, includeMin: true))); + equals(VersionRange(min: v200, max: v300, includeMin: true))); }); test("with splitting down the middle", () { expect( - new VersionConstraint.parse("<4.0.0").difference( - new VersionRange( - min: v200, - max: v300, - includeMin: true, - alwaysIncludeMaxPreRelease: true)), - equals(new VersionConstraint.unionOf([ - new VersionRange(max: v200, alwaysIncludeMaxPreRelease: true), - new VersionConstraint.parse(">=3.0.0 <4.0.0") + VersionConstraint.parse("<4.0.0").difference(VersionRange( + min: v200, + max: v300, + includeMin: true, + alwaysIncludeMaxPreRelease: true)), + equals(VersionConstraint.unionOf([ + VersionRange(max: v200, alwaysIncludeMaxPreRelease: true), + VersionConstraint.parse(">=3.0.0 <4.0.0") ]))); }); test("can leave a single version", () { expect( - new VersionConstraint.parse("<=2.0.0") + VersionConstraint.parse("<=2.0.0") .difference(includeMaxPreReleaseRange), equals(v200)); }); @@ -955,54 +917,54 @@ main() { }); test('isEmpty', () { - expect(new VersionRange().isEmpty, isFalse); - expect(new VersionRange(min: v123, max: v124).isEmpty, isFalse); + expect(VersionRange().isEmpty, isFalse); + expect(VersionRange(min: v123, max: v124).isEmpty, isFalse); }); group('compareTo()', () { test("orders by minimum first", () { - _expectComparesSmaller(new VersionRange(min: v003, max: v080), - new VersionRange(min: v010, max: v072)); - _expectComparesSmaller(new VersionRange(min: v003, max: v080), - new VersionRange(min: v010, max: v080)); - _expectComparesSmaller(new VersionRange(min: v003, max: v080), - new VersionRange(min: v010, max: v114)); + _expectComparesSmaller(VersionRange(min: v003, max: v080), + VersionRange(min: v010, max: v072)); + _expectComparesSmaller(VersionRange(min: v003, max: v080), + VersionRange(min: v010, max: v080)); + _expectComparesSmaller(VersionRange(min: v003, max: v080), + VersionRange(min: v010, max: v114)); }); test("orders by maximum second", () { - _expectComparesSmaller(new VersionRange(min: v003, max: v010), - new VersionRange(min: v003, max: v072)); + _expectComparesSmaller(VersionRange(min: v003, max: v010), + VersionRange(min: v003, max: v072)); }); test("includeMin comes before !includeMin", () { _expectComparesSmaller( - new VersionRange(min: v003, max: v080, includeMin: true), - new VersionRange(min: v003, max: v080, includeMin: false)); + VersionRange(min: v003, max: v080, includeMin: true), + VersionRange(min: v003, max: v080, includeMin: false)); }); test("includeMax comes after !includeMax", () { _expectComparesSmaller( - new VersionRange(min: v003, max: v080, includeMax: false), - new VersionRange(min: v003, max: v080, includeMax: true)); + VersionRange(min: v003, max: v080, includeMax: false), + VersionRange(min: v003, max: v080, includeMax: true)); }); test("includeMaxPreRelease comes after !includeMaxPreRelease", () { _expectComparesSmaller( - new VersionRange(max: v200), includeMaxPreReleaseRange); + VersionRange(max: v200), includeMaxPreReleaseRange); }); test("no minimum comes before small minimum", () { _expectComparesSmaller( - new VersionRange(max: v010), new VersionRange(min: v003, max: v010)); - _expectComparesSmaller(new VersionRange(max: v010, includeMin: true), - new VersionRange(min: v003, max: v010)); + VersionRange(max: v010), VersionRange(min: v003, max: v010)); + _expectComparesSmaller(VersionRange(max: v010, includeMin: true), + VersionRange(min: v003, max: v010)); }); test("no maximium comes after large maximum", () { _expectComparesSmaller( - new VersionRange(min: v003, max: v300), new VersionRange(min: v003)); - _expectComparesSmaller(new VersionRange(min: v003, max: v300), - new VersionRange(min: v003, includeMax: true)); + VersionRange(min: v003, max: v300), VersionRange(min: v003)); + _expectComparesSmaller(VersionRange(min: v003, max: v300), + VersionRange(min: v003, includeMax: true)); }); }); } diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 448435a57..634148bcc 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -8,7 +8,7 @@ import 'package:pub_semver/pub_semver.dart'; import 'utils.dart'; -main() { +void main() { test('none', () { expect(Version.none.toString(), equals('0.0.0')); }); @@ -29,8 +29,8 @@ main() { // appears in the list. for (var i = 0; i < versions.length; i++) { for (var j = 0; j < versions.length; j++) { - var a = new Version.parse(versions[i]); - var b = new Version.parse(versions[j]); + var a = Version.parse(versions[i]); + var b = Version.parse(versions[j]); expect(Version.prioritize(a, b), equals(i.compareTo(j))); } } @@ -52,8 +52,8 @@ main() { // appears in the list. for (var i = 0; i < versions.length; i++) { for (var j = 0; j < versions.length; j++) { - var a = new Version.parse(versions[i]); - var b = new Version.parse(versions[j]); + var a = Version.parse(versions[i]); + var b = Version.parse(versions[j]); expect(Version.antiprioritize(a, b), equals(i.compareTo(j))); } } @@ -61,9 +61,9 @@ main() { group('constructor', () { test('throws on negative numbers', () { - expect(() => new Version(-1, 1, 1), throwsArgumentError); - expect(() => new Version(1, -1, 1), throwsArgumentError); - expect(() => new Version(1, 1, -1), throwsArgumentError); + expect(() => Version(-1, 1, 1), throwsArgumentError); + expect(() => Version(1, -1, 1), throwsArgumentError); + expect(() => Version(1, 1, -1), throwsArgumentError); }); }); @@ -93,8 +93,8 @@ main() { // appears in the list. for (var i = 0; i < versions.length; i++) { for (var j = 0; j < versions.length; j++) { - var a = new Version.parse(versions[i]); - var b = new Version.parse(versions[j]); + var a = Version.parse(versions[i]); + var b = Version.parse(versions[j]); expect(a.compareTo(b), equals(i.compareTo(j))); } } @@ -103,8 +103,8 @@ main() { test('operators', () { for (var i = 0; i < versions.length; i++) { for (var j = 0; j < versions.length; j++) { - var a = new Version.parse(versions[i]); - var b = new Version.parse(versions[j]); + var a = Version.parse(versions[i]); + var b = Version.parse(versions[j]); expect(a < b, equals(i < j)); expect(a > b, equals(i > j)); expect(a <= b, equals(i <= j)); @@ -116,13 +116,11 @@ main() { }); test('equality', () { - expect(new Version.parse('01.2.3'), equals(new Version.parse('1.2.3'))); - expect(new Version.parse('1.02.3'), equals(new Version.parse('1.2.3'))); - expect(new Version.parse('1.2.03'), equals(new Version.parse('1.2.3'))); - expect( - new Version.parse('1.2.3-01'), equals(new Version.parse('1.2.3-1'))); - expect( - new Version.parse('1.2.3+01'), equals(new Version.parse('1.2.3+1'))); + expect(Version.parse('01.2.3'), equals(Version.parse('1.2.3'))); + expect(Version.parse('1.02.3'), equals(Version.parse('1.2.3'))); + expect(Version.parse('1.2.03'), equals(Version.parse('1.2.3'))); + expect(Version.parse('1.2.3-01'), equals(Version.parse('1.2.3-1'))); + expect(Version.parse('1.2.3+01'), equals(Version.parse('1.2.3+1'))); }); }); @@ -131,17 +129,17 @@ main() { expect( v123, doesNotAllow( - new Version.parse('2.2.3'), - new Version.parse('1.3.3'), - new Version.parse('1.2.4'), - new Version.parse('1.2.3-dev'), - new Version.parse('1.2.3+build'))); + Version.parse('2.2.3'), + Version.parse('1.3.3'), + Version.parse('1.2.4'), + Version.parse('1.2.3-dev'), + Version.parse('1.2.3+build'))); }); test('allowsAll()', () { expect(v123.allowsAll(v123), isTrue); expect(v123.allowsAll(v003), isFalse); - expect(v123.allowsAll(new VersionRange(min: v114, max: v124)), isFalse); + expect(v123.allowsAll(VersionRange(min: v114, max: v124)), isFalse); expect(v123.allowsAll(VersionConstraint.any), isFalse); expect(v123.allowsAll(VersionConstraint.empty), isTrue); }); @@ -149,7 +147,7 @@ main() { test('allowsAny()', () { expect(v123.allowsAny(v123), isTrue); expect(v123.allowsAny(v003), isFalse); - expect(v123.allowsAny(new VersionRange(min: v114, max: v124)), isTrue); + expect(v123.allowsAny(VersionRange(min: v114, max: v124)), isTrue); expect(v123.allowsAny(VersionConstraint.any), isTrue); expect(v123.allowsAny(VersionConstraint.empty), isFalse); }); @@ -162,12 +160,10 @@ main() { expect(v123.intersect(v114).isEmpty, isTrue); // Intersecting a range returns the version if the range allows it. - expect( - v123.intersect(new VersionRange(min: v114, max: v124)), equals(v123)); + expect(v123.intersect(VersionRange(min: v114, max: v124)), equals(v123)); // Intersecting a range allows no versions if the range doesn't allow it. - expect( - v114.intersect(new VersionRange(min: v123, max: v124)).isEmpty, isTrue); + expect(v114.intersect(VersionRange(min: v123, max: v124)).isEmpty, isTrue); }); group('union()', () { @@ -185,27 +181,27 @@ main() { }); test("with a range returns the range if it contains the version", () { - var range = new VersionRange(min: v114, max: v124); + var range = VersionRange(min: v114, max: v124); expect(v123.union(range), equals(range)); }); test("with a range with the version on the edge, expands the range", () { expect( - v124.union(new VersionRange( + v124.union(VersionRange( min: v114, max: v124, alwaysIncludeMaxPreRelease: true)), - equals(new VersionRange(min: v114, max: v124, includeMax: true))); + equals(VersionRange(min: v114, max: v124, includeMax: true))); expect( - v124.firstPreRelease.union(new VersionRange(min: v114, max: v124)), - equals(new VersionRange( + v124.firstPreRelease.union(VersionRange(min: v114, max: v124)), + equals(VersionRange( min: v114, max: v124.firstPreRelease, includeMax: true))); - expect(v114.union(new VersionRange(min: v114, max: v124)), - equals(new VersionRange(min: v114, max: v124, includeMin: true))); + expect(v114.union(VersionRange(min: v114, max: v124)), + equals(VersionRange(min: v114, max: v124, includeMin: true))); }); test( "with a range allows both the range and the version if the range " "doesn't contain the version", () { - var result = v123.union(new VersionRange(min: v003, max: v114)); + var result = v123.union(VersionRange(min: v003, max: v114)); expect(result, allows(v123)); expect(result, allows(v010)); }); @@ -222,13 +218,12 @@ main() { test("returns an empty constraint with a range that contains the version", () { - expect(v123.difference(new VersionRange(min: v114, max: v124)), isEmpty); + expect(v123.difference(VersionRange(min: v114, max: v124)), isEmpty); }); test("returns the version constraint with a range that doesn't contain it", () { - expect(v123.difference(new VersionRange(min: v140, max: v300)), - equals(v123)); + expect(v123.difference(VersionRange(min: v140, max: v300)), equals(v123)); }); }); @@ -242,13 +237,13 @@ main() { expect(v200.nextMajor, equals(v300)); // Ignores pre-release if not on a major version. - expect(new Version.parse('1.2.3-dev').nextMajor, equals(v200)); + expect(Version.parse('1.2.3-dev').nextMajor, equals(v200)); // Just removes it if on a major version. - expect(new Version.parse('2.0.0-dev').nextMajor, equals(v200)); + expect(Version.parse('2.0.0-dev').nextMajor, equals(v200)); // Strips build suffix. - expect(new Version.parse('1.2.3+patch').nextMajor, equals(v200)); + expect(Version.parse('1.2.3+patch').nextMajor, equals(v200)); }); test('nextMinor', () { @@ -256,13 +251,13 @@ main() { expect(v130.nextMinor, equals(v140)); // Ignores pre-release if not on a minor version. - expect(new Version.parse('1.2.3-dev').nextMinor, equals(v130)); + expect(Version.parse('1.2.3-dev').nextMinor, equals(v130)); // Just removes it if on a minor version. - expect(new Version.parse('1.3.0-dev').nextMinor, equals(v130)); + expect(Version.parse('1.3.0-dev').nextMinor, equals(v130)); // Strips build suffix. - expect(new Version.parse('1.2.3+patch').nextMinor, equals(v130)); + expect(Version.parse('1.2.3+patch').nextMinor, equals(v130)); }); test('nextPatch', () { @@ -270,10 +265,10 @@ main() { expect(v200.nextPatch, equals(v201)); // Just removes pre-release version if present. - expect(new Version.parse('1.2.4-dev').nextPatch, equals(v124)); + expect(Version.parse('1.2.4-dev').nextPatch, equals(v124)); // Strips build suffix. - expect(new Version.parse('1.2.3+patch').nextPatch, equals(v124)); + expect(Version.parse('1.2.3+patch').nextPatch, equals(v124)); }); test('nextBreaking', () { @@ -282,56 +277,56 @@ main() { expect(v003.nextBreaking, equals(v010)); // Removes pre-release version if present. - expect(new Version.parse('1.2.3-dev').nextBreaking, equals(v200)); + expect(Version.parse('1.2.3-dev').nextBreaking, equals(v200)); // Strips build suffix. - expect(new Version.parse('1.2.3+patch').nextBreaking, equals(v200)); + expect(Version.parse('1.2.3+patch').nextBreaking, equals(v200)); }); test('parse()', () { - expect(new Version.parse('0.0.0'), equals(new Version(0, 0, 0))); - expect(new Version.parse('12.34.56'), equals(new Version(12, 34, 56))); - - expect(new Version.parse('1.2.3-alpha.1'), - equals(new Version(1, 2, 3, pre: 'alpha.1'))); - expect(new Version.parse('1.2.3-x.7.z-92'), - equals(new Version(1, 2, 3, pre: 'x.7.z-92'))); - - expect(new Version.parse('1.2.3+build.1'), - equals(new Version(1, 2, 3, build: 'build.1'))); - expect(new Version.parse('1.2.3+x.7.z-92'), - equals(new Version(1, 2, 3, build: 'x.7.z-92'))); - - expect(new Version.parse('1.0.0-rc-1+build-1'), - equals(new Version(1, 0, 0, pre: 'rc-1', build: 'build-1'))); - - expect(() => new Version.parse('1.0'), throwsFormatException); - expect(() => new Version.parse('1.2.3.4'), throwsFormatException); - expect(() => new Version.parse('1234'), throwsFormatException); - expect(() => new Version.parse('-2.3.4'), throwsFormatException); - expect(() => new Version.parse('1.3-pre'), throwsFormatException); - expect(() => new Version.parse('1.3+build'), throwsFormatException); - expect(() => new Version.parse('1.3+bu?!3ild'), throwsFormatException); + expect(Version.parse('0.0.0'), equals(Version(0, 0, 0))); + expect(Version.parse('12.34.56'), equals(Version(12, 34, 56))); + + expect(Version.parse('1.2.3-alpha.1'), + equals(Version(1, 2, 3, pre: 'alpha.1'))); + expect(Version.parse('1.2.3-x.7.z-92'), + equals(Version(1, 2, 3, pre: 'x.7.z-92'))); + + expect(Version.parse('1.2.3+build.1'), + equals(Version(1, 2, 3, build: 'build.1'))); + expect(Version.parse('1.2.3+x.7.z-92'), + equals(Version(1, 2, 3, build: 'x.7.z-92'))); + + expect(Version.parse('1.0.0-rc-1+build-1'), + equals(Version(1, 0, 0, pre: 'rc-1', build: 'build-1'))); + + expect(() => Version.parse('1.0'), throwsFormatException); + expect(() => Version.parse('1.2.3.4'), throwsFormatException); + expect(() => Version.parse('1234'), throwsFormatException); + expect(() => Version.parse('-2.3.4'), throwsFormatException); + expect(() => Version.parse('1.3-pre'), throwsFormatException); + expect(() => Version.parse('1.3+build'), throwsFormatException); + expect(() => Version.parse('1.3+bu?!3ild'), throwsFormatException); }); group('toString()', () { test('returns the version string', () { - expect(new Version(0, 0, 0).toString(), equals('0.0.0')); - expect(new Version(12, 34, 56).toString(), equals('12.34.56')); + expect(Version(0, 0, 0).toString(), equals('0.0.0')); + expect(Version(12, 34, 56).toString(), equals('12.34.56')); - expect(new Version(1, 2, 3, pre: 'alpha.1').toString(), - equals('1.2.3-alpha.1')); - expect(new Version(1, 2, 3, pre: 'x.7.z-92').toString(), + expect( + Version(1, 2, 3, pre: 'alpha.1').toString(), equals('1.2.3-alpha.1')); + expect(Version(1, 2, 3, pre: 'x.7.z-92').toString(), equals('1.2.3-x.7.z-92')); - expect(new Version(1, 2, 3, build: 'build.1').toString(), + expect(Version(1, 2, 3, build: 'build.1').toString(), equals('1.2.3+build.1')); - expect(new Version(1, 2, 3, pre: 'pre', build: 'bui').toString(), + expect(Version(1, 2, 3, pre: 'pre', build: 'bui').toString(), equals('1.2.3-pre+bui')); }); test('preserves leading zeroes', () { - expect(new Version.parse('001.02.0003-01.dev+pre.002').toString(), + expect(Version.parse('001.02.0003-01.dev+pre.002').toString(), equals('001.02.0003-01.dev+pre.002')); }); }); diff --git a/pkgs/pub_semver/test/version_union_test.dart b/pkgs/pub_semver/test/version_union_test.dart index f629c83d4..11a5ecd73 100644 --- a/pkgs/pub_semver/test/version_union_test.dart +++ b/pkgs/pub_semver/test/version_union_test.dart @@ -8,11 +8,11 @@ import 'package:pub_semver/pub_semver.dart'; import 'utils.dart'; -main() { +void main() { group('factory', () { test('ignores empty constraints', () { expect( - new VersionConstraint.unionOf([ + VersionConstraint.unionOf([ VersionConstraint.empty, VersionConstraint.empty, v123, @@ -21,141 +21,140 @@ main() { equals(v123)); expect( - new VersionConstraint.unionOf( + VersionConstraint.unionOf( [VersionConstraint.empty, VersionConstraint.empty]), isEmpty); }); test('returns an empty constraint for an empty list', () { - expect(new VersionConstraint.unionOf([]), isEmpty); + expect(VersionConstraint.unionOf([]), isEmpty); }); test('any constraints override everything', () { expect( - new VersionConstraint.unionOf([ + VersionConstraint.unionOf([ v123, VersionConstraint.any, v200, - new VersionRange(min: v234, max: v250) + VersionRange(min: v234, max: v250) ]), equals(VersionConstraint.any)); }); test('flattens other unions', () { expect( - new VersionConstraint.unionOf([ + VersionConstraint.unionOf([ v072, - new VersionConstraint.unionOf([v123, v124]), + VersionConstraint.unionOf([v123, v124]), v250 ]), - equals(new VersionConstraint.unionOf([v072, v123, v124, v250]))); + equals(VersionConstraint.unionOf([v072, v123, v124, v250]))); }); test('returns a single merged range as-is', () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v080, max: v140), - new VersionRange(min: v123, max: v200) + VersionConstraint.unionOf([ + VersionRange(min: v080, max: v140), + VersionRange(min: v123, max: v200) ]), - equals(new VersionRange(min: v080, max: v200))); + equals(VersionRange(min: v080, max: v200))); }); }); group('equality', () { test("doesn't depend on original order", () { expect( - new VersionConstraint.unionOf([ + VersionConstraint.unionOf([ v250, - new VersionRange(min: v201, max: v234), + VersionRange(min: v201, max: v234), v124, v072, - new VersionRange(min: v080, max: v114), + VersionRange(min: v080, max: v114), v123 ]), - equals(new VersionConstraint.unionOf([ + equals(VersionConstraint.unionOf([ v072, - new VersionRange(min: v080, max: v114), + VersionRange(min: v080, max: v114), v123, v124, - new VersionRange(min: v201, max: v234), + VersionRange(min: v201, max: v234), v250 ]))); }); test("merges overlapping ranges", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v010, max: v080), - new VersionRange(min: v114, max: v124), - new VersionRange(min: v123, max: v130) + VersionConstraint.unionOf([ + VersionRange(min: v003, max: v072), + VersionRange(min: v010, max: v080), + VersionRange(min: v114, max: v124), + VersionRange(min: v123, max: v130) ]), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v114, max: v130) + equals(VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v114, max: v130) ]))); }); test("merges adjacent ranges", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072, includeMax: true), - new VersionRange(min: v072, max: v080), - new VersionRange( + VersionConstraint.unionOf([ + VersionRange(min: v003, max: v072, includeMax: true), + VersionRange(min: v072, max: v080), + VersionRange( min: v114, max: v124, alwaysIncludeMaxPreRelease: true), - new VersionRange(min: v124, max: v130, includeMin: true), - new VersionRange( - min: v130.firstPreRelease, max: v200, includeMin: true) + VersionRange(min: v124, max: v130, includeMin: true), + VersionRange(min: v130.firstPreRelease, max: v200, includeMin: true) ]), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v114, max: v200) + equals(VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v114, max: v200) ]))); }); test("doesn't merge not-quite-adjacent ranges", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v114, max: v124), - new VersionRange(min: v124, max: v130, includeMin: true) + VersionConstraint.unionOf([ + VersionRange(min: v114, max: v124), + VersionRange(min: v124, max: v130, includeMin: true) ]), - isNot(equals(new VersionRange(min: v114, max: v130)))); + isNot(equals(VersionRange(min: v114, max: v130)))); expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v072, max: v080) + VersionConstraint.unionOf([ + VersionRange(min: v003, max: v072), + VersionRange(min: v072, max: v080) ]), - isNot(equals(new VersionRange(min: v003, max: v080)))); + isNot(equals(VersionRange(min: v003, max: v080)))); }); test("merges version numbers into ranges", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), + VersionConstraint.unionOf([ + VersionRange(min: v003, max: v072), v010, - new VersionRange(min: v114, max: v124), + VersionRange(min: v114, max: v124), v123 ]), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v114, max: v124) + equals(VersionConstraint.unionOf([ + VersionRange(min: v003, max: v072), + VersionRange(min: v114, max: v124) ]))); }); test("merges adjacent version numbers into ranges", () { expect( - new VersionConstraint.unionOf([ - new VersionRange( + VersionConstraint.unionOf([ + VersionRange( min: v003, max: v072, alwaysIncludeMaxPreRelease: true), v072, v114, - new VersionRange(min: v114, max: v124), + VersionRange(min: v114, max: v124), v124.firstPreRelease ]), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072, includeMax: true), - new VersionRange( + equals(VersionConstraint.unionOf([ + VersionRange(min: v003, max: v072, includeMax: true), + VersionRange( min: v114, max: v124.firstPreRelease, includeMin: true, @@ -165,35 +164,33 @@ main() { test("doesn't merge not-quite-adjacent version numbers into ranges", () { expect( - new VersionConstraint.unionOf( - [new VersionRange(min: v003, max: v072), v072]), - isNot(equals( - new VersionRange(min: v003, max: v072, includeMax: true)))); + VersionConstraint.unionOf([VersionRange(min: v003, max: v072), v072]), + isNot(equals(VersionRange(min: v003, max: v072, includeMax: true)))); }); }); test('isEmpty returns false', () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130), + VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130), ]), isNot(isEmpty)); }); test('isAny returns false', () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130), + VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130), ]).isAny, isFalse); }); test('allows() allows anything the components allow', () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130), + var union = VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130), v200 ]); @@ -206,9 +203,9 @@ main() { group('allowsAll()', () { test('for a version, returns true if any component allows the version', () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130), + var union = VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130), v200 ]); @@ -222,56 +219,56 @@ main() { test( 'for a version range, returns true if any component allows the whole ' 'range', () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130) + var union = VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130) ]); - expect(union.allowsAll(new VersionRange(min: v003, max: v080)), isTrue); - expect(union.allowsAll(new VersionRange(min: v010, max: v072)), isTrue); - expect(union.allowsAll(new VersionRange(min: v010, max: v124)), isFalse); + expect(union.allowsAll(VersionRange(min: v003, max: v080)), isTrue); + expect(union.allowsAll(VersionRange(min: v010, max: v072)), isTrue); + expect(union.allowsAll(VersionRange(min: v010, max: v124)), isFalse); }); group('for a union,', () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130) + var union = VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130) ]); test('returns true if every constraint matches a different constraint', () { expect( - union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v124, max: v130) + union.allowsAll(VersionConstraint.unionOf([ + VersionRange(min: v010, max: v072), + VersionRange(min: v124, max: v130) ])), isTrue); }); test('returns true if every constraint matches the same constraint', () { expect( - union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v010), - new VersionRange(min: v072, max: v080) + union.allowsAll(VersionConstraint.unionOf([ + VersionRange(min: v003, max: v010), + VersionRange(min: v072, max: v080) ])), isTrue); }); test("returns false if there's an unmatched constraint", () { expect( - union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v124, max: v130), - new VersionRange(min: v140, max: v200) + union.allowsAll(VersionConstraint.unionOf([ + VersionRange(min: v010, max: v072), + VersionRange(min: v124, max: v130), + VersionRange(min: v140, max: v200) ])), isFalse); }); test("returns false if a constraint isn't fully matched", () { expect( - union.allowsAll(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v114), - new VersionRange(min: v124, max: v130) + union.allowsAll(VersionConstraint.unionOf([ + VersionRange(min: v010, max: v114), + VersionRange(min: v124, max: v130) ])), isFalse); }); @@ -280,9 +277,9 @@ main() { group('allowsAny()', () { test('for a version, returns true if any component allows the version', () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130), + var union = VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130), v200 ]); @@ -296,38 +293,38 @@ main() { test( 'for a version range, returns true if any component allows part of ' 'the range', () { - var union = new VersionConstraint.unionOf( - [new VersionRange(min: v003, max: v080), v123]); + var union = + VersionConstraint.unionOf([VersionRange(min: v003, max: v080), v123]); - expect(union.allowsAny(new VersionRange(min: v010, max: v114)), isTrue); - expect(union.allowsAny(new VersionRange(min: v114, max: v124)), isTrue); - expect(union.allowsAny(new VersionRange(min: v124, max: v130)), isFalse); + expect(union.allowsAny(VersionRange(min: v010, max: v114)), isTrue); + expect(union.allowsAny(VersionRange(min: v114, max: v124)), isTrue); + expect(union.allowsAny(VersionRange(min: v124, max: v130)), isFalse); }); group('for a union,', () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v130) + var union = VersionConstraint.unionOf([ + VersionRange(min: v010, max: v080), + VersionRange(min: v123, max: v130) ]); test('returns true if any constraint matches', () { expect( - union.allowsAny(new VersionConstraint.unionOf( - [v072, new VersionRange(min: v200, max: v300)])), + union.allowsAny(VersionConstraint.unionOf( + [v072, VersionRange(min: v200, max: v300)])), isTrue); expect( - union.allowsAny(new VersionConstraint.unionOf( - [v003, new VersionRange(min: v124, max: v300)])), + union.allowsAny(VersionConstraint.unionOf( + [v003, VersionRange(min: v124, max: v300)])), isTrue); }); test("returns false if no constraint matches", () { expect( - union.allowsAny(new VersionConstraint.unionOf([ + union.allowsAny(VersionConstraint.unionOf([ v003, - new VersionRange(min: v130, max: v140), - new VersionRange(min: v140, max: v200) + VersionRange(min: v130, max: v140), + VersionRange(min: v140, max: v200) ])), isFalse); }); @@ -337,83 +334,83 @@ main() { group("intersect()", () { test("with an overlapping version, returns that version", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v080), + VersionRange(min: v123, max: v140) ]).intersect(v072), equals(v072)); }); test("with a non-overlapping version, returns an empty constraint", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v080), + VersionRange(min: v123, max: v140) ]).intersect(v300), isEmpty); }); test("with an overlapping range, returns that range", () { - var range = new VersionRange(min: v072, max: v080); + var range = VersionRange(min: v072, max: v080); expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v080), + VersionRange(min: v123, max: v140) ]).intersect(range), equals(range)); }); test("with a non-overlapping range, returns an empty constraint", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) - ]).intersect(new VersionRange(min: v080, max: v123)), + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v080), + VersionRange(min: v123, max: v140) + ]).intersect(VersionRange(min: v080, max: v123)), isEmpty); }); test("with a parially-overlapping range, returns the overlapping parts", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v140) - ]).intersect(new VersionRange(min: v072, max: v130)), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v130) + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v080), + VersionRange(min: v123, max: v140) + ]).intersect(VersionRange(min: v072, max: v130)), + equals(VersionConstraint.unionOf([ + VersionRange(min: v072, max: v080), + VersionRange(min: v123, max: v130) ]))); }); group("for a union,", () { - var union = new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v080), - new VersionRange(min: v123, max: v130) + var union = VersionConstraint.unionOf([ + VersionRange(min: v003, max: v080), + VersionRange(min: v123, max: v130) ]); test("returns the overlapping parts", () { expect( - union.intersect(new VersionConstraint.unionOf([ + union.intersect(VersionConstraint.unionOf([ v010, - new VersionRange(min: v072, max: v124), - new VersionRange(min: v124, max: v130) + VersionRange(min: v072, max: v124), + VersionRange(min: v124, max: v130) ])), - equals(new VersionConstraint.unionOf([ + equals(VersionConstraint.unionOf([ v010, - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v124), - new VersionRange(min: v124, max: v130) + VersionRange(min: v072, max: v080), + VersionRange(min: v123, max: v124), + VersionRange(min: v124, max: v130) ]))); }); test("drops parts that don't match", () { expect( - union.intersect(new VersionConstraint.unionOf([ + union.intersect(VersionConstraint.unionOf([ v003, - new VersionRange(min: v072, max: v080), - new VersionRange(min: v080, max: v123) + VersionRange(min: v072, max: v080), + VersionRange(min: v080, max: v123) ])), - equals(new VersionRange(min: v072, max: v080))); + equals(VersionRange(min: v072, max: v080))); }); }); }); @@ -421,67 +418,65 @@ main() { group("difference()", () { test("ignores ranges that don't intersect", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v130) - ]).difference(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v010), - new VersionRange(min: v080, max: v123), - new VersionRange(min: v140) + VersionConstraint.unionOf([ + VersionRange(min: v072, max: v080), + VersionRange(min: v123, max: v130) + ]).difference(VersionConstraint.unionOf([ + VersionRange(min: v003, max: v010), + VersionRange(min: v080, max: v123), + VersionRange(min: v140) ])), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v072, max: v080), - new VersionRange(min: v123, max: v130) + equals(VersionConstraint.unionOf([ + VersionRange(min: v072, max: v080), + VersionRange(min: v123, max: v130) ]))); }); test("removes overlapping portions", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v080), - new VersionRange(min: v123, max: v130) - ]).difference(new VersionConstraint.unionOf([ - new VersionRange(min: v003, max: v072), - new VersionRange(min: v124) - ])), - equals(new VersionConstraint.unionOf([ - new VersionRange( + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v080), + VersionRange(min: v123, max: v130) + ]).difference(VersionConstraint.unionOf( + [VersionRange(min: v003, max: v072), VersionRange(min: v124)])), + equals(VersionConstraint.unionOf([ + VersionRange( min: v072.firstPreRelease, max: v080, includeMin: true), - new VersionRange(min: v123, max: v124, includeMax: true) + VersionRange(min: v123, max: v124, includeMax: true) ]))); }); test("removes multiple portions from the same range", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v114), - new VersionRange(min: v130, max: v200) - ]).difference(new VersionConstraint.unionOf([v072, v080])), - equals(new VersionConstraint.unionOf([ - new VersionRange( + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v114), + VersionRange(min: v130, max: v200) + ]).difference(VersionConstraint.unionOf([v072, v080])), + equals(VersionConstraint.unionOf([ + VersionRange( min: v010, max: v072, alwaysIncludeMaxPreRelease: true), - new VersionRange( + VersionRange( min: v072, max: v080, alwaysIncludeMaxPreRelease: true), - new VersionRange(min: v080, max: v114), - new VersionRange(min: v130, max: v200) + VersionRange(min: v080, max: v114), + VersionRange(min: v130, max: v200) ]))); }); test("removes the same range from multiple ranges", () { expect( - new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v080, max: v123), - new VersionRange(min: v124, max: v130), - new VersionRange(min: v200, max: v234), - new VersionRange(min: v250, max: v300) - ]).difference(new VersionRange(min: v114, max: v201)), - equals(new VersionConstraint.unionOf([ - new VersionRange(min: v010, max: v072), - new VersionRange(min: v080, max: v114, includeMax: true), - new VersionRange( + VersionConstraint.unionOf([ + VersionRange(min: v010, max: v072), + VersionRange(min: v080, max: v123), + VersionRange(min: v124, max: v130), + VersionRange(min: v200, max: v234), + VersionRange(min: v250, max: v300) + ]).difference(VersionRange(min: v114, max: v201)), + equals(VersionConstraint.unionOf([ + VersionRange(min: v010, max: v072), + VersionRange(min: v080, max: v114, includeMax: true), + VersionRange( min: v201.firstPreRelease, max: v234, includeMin: true), - new VersionRange(min: v250, max: v300) + VersionRange(min: v250, max: v300) ]))); }); }); From 2c3ab9e81f1964ae27329b8a0ff4563c23b48208 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Thu, 23 May 2019 11:16:58 -0700 Subject: [PATCH 293/657] Fix missing_return violation newly enforced in Dart ~2.3.2-dev.0.1 --- pkgs/package_config/test/discovery_analysis_test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/package_config/test/discovery_analysis_test.dart b/pkgs/package_config/test/discovery_analysis_test.dart index c819a9074..e43245468 100644 --- a/pkgs/package_config/test/discovery_analysis_test.dart +++ b/pkgs/package_config/test/discovery_analysis_test.dart @@ -41,6 +41,7 @@ main() { var map = ctx.asMap(); expect(map.keys.map((dir) => dir.path), unorderedEquals([directory.path, fooDir.path, barDir.path])); + return null; }); } From 547690ec9057f78780f352889b169fa11511eab3 Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Mon, 22 Jul 2019 13:57:02 +0200 Subject: [PATCH 294/657] Reference https://semver.org/spec/v2.0.0-rc.1.html --- pkgs/pub_semver/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index b35975407..5e0c36cd8 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -1,6 +1,7 @@ Handles version numbers and version constraints in the same way that [pub][] -does. The semantics here very closely follow the [Semantic Versioning][semver] -spec. It differs from semver in a few corner cases: +does. The semantics here very closely follow the +[Semantic Versioning spec version 2.0.0-rc.1][semver]. It differs from semver +in a few corner cases: * **Version ordering does take build suffixes into account.** This is unlike semver 2.0.0 but like earlier versions of semver. Version `1.2.3+1` is @@ -94,5 +95,5 @@ spec. It differs from semver in a few corner cases: constraint greater than or equal to a given version, but less than its next breaking one. -[pub]: http://pub.dartlang.org/ -[semver]: http://semver.org/ +[pub]: https://pub.dev +[semver]: https://semver.org/spec/v2.0.0-rc.1.html From a51b52678a4855fee1721a39cb8ad5030217dc1b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 21:02:43 -0700 Subject: [PATCH 295/657] Delete codereview.settings --- pkgs/pub_semver/codereview.settings | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/pub_semver/codereview.settings diff --git a/pkgs/pub_semver/codereview.settings b/pkgs/pub_semver/codereview.settings deleted file mode 100644 index 94ddf0ea9..000000000 --- a/pkgs/pub_semver/codereview.settings +++ /dev/null @@ -1,3 +0,0 @@ -CODE_REVIEW_SERVER: https://codereview.chromium.org/ -VIEW_VC: https://github.com/dart-lang/pub_semver/commit/ -CC_LIST: reviews@dartlang.org \ No newline at end of file From 8f445e6466b64a9d232a72a4e11929e1678f8b54 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 21:03:52 -0700 Subject: [PATCH 296/657] Delete codereview.settings --- pkgs/pool/codereview.settings | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/pool/codereview.settings diff --git a/pkgs/pool/codereview.settings b/pkgs/pool/codereview.settings deleted file mode 100644 index b474c08cb..000000000 --- a/pkgs/pool/codereview.settings +++ /dev/null @@ -1,3 +0,0 @@ -CODE_REVIEW_SERVER: http://codereview.chromium.org/ -VIEW_VC: https://github.com/dart-lang/pool/commit/ -CC_LIST: reviews@dartlang.org \ No newline at end of file From 393f6d532ba89ba6e23efef9772f26903cc56dde Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 21:06:27 -0700 Subject: [PATCH 297/657] Delete codereview.settings --- pkgs/package_config/codereview.settings | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/package_config/codereview.settings diff --git a/pkgs/package_config/codereview.settings b/pkgs/package_config/codereview.settings deleted file mode 100644 index 1099f0594..000000000 --- a/pkgs/package_config/codereview.settings +++ /dev/null @@ -1,3 +0,0 @@ -CODE_REVIEW_SERVER: https://codereview.chromium.org/ -VIEW_VC: https://github.com/dart-lang/package_config/commit/ -CC_LIST: reviews@dartlang.org From 77329f5d456e0692506c1bcca3faeb2d50405ec9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 Jul 2019 21:12:34 -0700 Subject: [PATCH 298/657] Delete codereview.settings --- pkgs/source_span/codereview.settings | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/source_span/codereview.settings diff --git a/pkgs/source_span/codereview.settings b/pkgs/source_span/codereview.settings deleted file mode 100644 index 6cae815a0..000000000 --- a/pkgs/source_span/codereview.settings +++ /dev/null @@ -1,3 +0,0 @@ -CODE_REVIEW_SERVER: http://codereview.chromium.org/ -VIEW_VC: https://github.com/dart-lang/source_span/commit/ -CC_LIST: reviews@dartlang.org \ No newline at end of file From 62c12f20026177ebdf7f6fa12040501ff867dbb9 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 16 Aug 2019 15:04:35 +0200 Subject: [PATCH 299/657] Add support for default package and metadata. (dart-lang/package_config#53) --- pkgs/package_config/CHANGELOG.md | 7 ++ .../lib/discovery_analysis.dart | 22 ++--- pkgs/package_config/lib/packages.dart | 36 ++++++++ pkgs/package_config/lib/packages_file.dart | 50 ++++++++--- .../package_config/lib/src/packages_impl.dart | 37 ++++++++- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/parse_test.dart | 82 ++++++++++++++++++- 7 files changed, 208 insertions(+), 28 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index e802d7deb..db4bb00d6 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.1.0 + +- Allow parsing files with default-package entries and metadata. + A default-package entry has an empty key and a valid package name + as value. + Metadata is attached as fragments to base URIs. + ## 1.0.5 - Fix usage of SDK constants. diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart index 67798e129..d623303c8 100644 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -59,22 +59,22 @@ abstract class PackageContext { static PackageContext findAll(Directory directory, {Packages root: Packages.noPackages}) { if (!directory.existsSync()) { - throw new ArgumentError("Directory not found: $directory"); + throw ArgumentError("Directory not found: $directory"); } var contexts = []; void findRoots(Directory directory) { Packages packages; List oldContexts; - File packagesFile = new File(path.join(directory.path, ".packages")); + File packagesFile = File(path.join(directory.path, ".packages")); if (packagesFile.existsSync()) { packages = _loadPackagesFile(packagesFile); oldContexts = contexts; contexts = []; } else { Directory packagesDir = - new Directory(path.join(directory.path, "packages")); + Directory(path.join(directory.path, "packages")); if (packagesDir.existsSync()) { - packages = new FilePackagesDirectoryPackages(packagesDir); + packages = FilePackagesDirectoryPackages(packagesDir); oldContexts = contexts; contexts = []; } @@ -87,7 +87,7 @@ abstract class PackageContext { } } if (packages != null) { - oldContexts.add(new _PackageContext(directory, packages, contexts)); + oldContexts.add(_PackageContext(directory, packages, contexts)); contexts = oldContexts; } } @@ -97,7 +97,7 @@ abstract class PackageContext { if (contexts.length == 1 && contexts[0].directory == directory) { return contexts[0]; } - return new _PackageContext(directory, root, contexts); + return _PackageContext(directory, root, contexts); } } @@ -106,10 +106,10 @@ class _PackageContext implements PackageContext { final Packages packages; final List children; _PackageContext(this.directory, this.packages, List children) - : children = new List.unmodifiable(children); + : children = List.unmodifiable(children); Map asMap() { - var result = new HashMap(); + var result = HashMap(); recurse(_PackageContext current) { result[current.directory] = current.packages; for (var child in current.children) { @@ -124,7 +124,7 @@ class _PackageContext implements PackageContext { PackageContext operator [](Directory directory) { String path = directory.path; if (!path.startsWith(this.directory.path)) { - throw new ArgumentError("Not inside $path: $directory"); + throw ArgumentError("Not inside $path: $directory"); } _PackageContext current = this; // The current path is know to agree with directory until deltaIndex. @@ -160,8 +160,8 @@ class _PackageContext implements PackageContext { } Packages _loadPackagesFile(File file) { - var uri = new Uri.file(file.path); + var uri = Uri.file(file.path); var bytes = file.readAsBytesSync(); var map = pkgfile.parse(bytes, uri); - return new MapPackages(map); + return MapPackages(map); } diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart index 890f4485c..886fbc83c 100644 --- a/pkgs/package_config/lib/packages.dart +++ b/pkgs/package_config/lib/packages.dart @@ -45,6 +45,32 @@ abstract class Packages { /// and getting `packages` from such a `Packages` object will throw. Iterable get packages; + /// Retrieve metadata associated with a package. + /// + /// Metadata have string keys and values, and are looked up by key. + /// + /// Returns `null` if the argument is not a valid package name, + /// or if the package is not one of the packages configured by + /// this packages object, or if the package does not have associated + /// metadata with the provided [key]. + /// + /// Not all `Packages` objects can support metadata. + /// Those will always return `null`. + String packageMetadata(String packageName, String key); + + /// Retrieve metadata associated with a library. + /// + /// If [libraryUri] is a `package:` URI, the returned value + /// is the same that would be returned by [packageMetadata] with + /// the package's name and the same key. + /// + /// If [libraryUri] is not a `package:` URI, and this [Packages] + /// object has a [defaultPackageName], then the [key] is looked + /// up on the default package instead. + /// + /// Otherwise the result is `null`. + String libraryMetadata(Uri libraryUri, String key); + /// Return the names-to-base-URI mapping of the available packages. /// /// Returns a map from package name to a base URI. @@ -55,4 +81,14 @@ abstract class Packages { /// Some `Packages` objects are unable to find the package names, /// and calling `asMap` on such a `Packages` object will throw. Map asMap(); + + /// The name of the "default package". + /// + /// A default package is a package that *non-package* libraries + /// may be considered part of for some purposes. + /// + /// The value is `null` if there is no default package. + /// Not all implementations of [Packages] supports a default package, + /// and will always have a `null` value for those. + String get defaultPackageName; } diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 85de1942d..284d8e90a 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -22,8 +22,15 @@ import "src/util.dart" show isValidPackageName; /// If the content was read from a file, `baseLocation` should be the /// location of that file. /// +/// If [allowDefaultPackage] is set to true, an entry with an empty package name +/// is accepted. This entry does not correspond to a package, but instead +/// represents a *default package* which non-package libraries may be considered +/// part of in some cases. The value of that entry must be a valid package name. +/// /// Returns a simple mapping from package name to package location. -Map parse(List source, Uri baseLocation) { +/// If default package is allowed, the map maps the empty string to the default package's name. +Map parse(List source, Uri baseLocation, + {bool allowDefaultPackage = false}) { int index = 0; Map result = {}; while (index < source.length) { @@ -36,7 +43,10 @@ Map parse(List source, Uri baseLocation) { continue; } if (char == $colon) { - throw new FormatException("Missing package name", source, index - 1); + if (!allowDefaultPackage) { + throw FormatException("Missing package name", source, index - 1); + } + separatorIndex = index - 1; } isComment = char == $hash; while (index < source.length) { @@ -50,22 +60,36 @@ Map parse(List source, Uri baseLocation) { } if (isComment) continue; if (separatorIndex < 0) { - throw new FormatException("No ':' on line", source, index - 1); + throw FormatException("No ':' on line", source, index - 1); } var packageName = new String.fromCharCodes(source, start, separatorIndex); - if (!isValidPackageName(packageName)) { - throw new FormatException("Not a valid package name", packageName, 0); + if (packageName.isEmpty + ? !allowDefaultPackage + : !isValidPackageName(packageName)) { + throw FormatException("Not a valid package name", packageName, 0); } - var packageUri = new String.fromCharCodes(source, separatorIndex + 1, end); - var packageLocation = Uri.parse(packageUri); - packageLocation = baseLocation.resolveUri(packageLocation); - if (!packageLocation.path.endsWith('/')) { - packageLocation = - packageLocation.replace(path: packageLocation.path + "/"); + var packageValue = + new String.fromCharCodes(source, separatorIndex + 1, end); + Uri packageLocation; + if (packageName.isEmpty) { + if (!isValidPackageName(packageValue)) { + throw FormatException( + "Default package entry value is not a valid package name"); + } + packageLocation = Uri(path: packageValue); + } else { + packageLocation = baseLocation.resolve(packageValue); + if (!packageLocation.path.endsWith('/')) { + packageLocation = + packageLocation.replace(path: packageLocation.path + "/"); + } } if (result.containsKey(packageName)) { - throw new FormatException( - "Same package name occured twice.", source, start); + if (packageName.isEmpty) { + throw FormatException( + "More than one default package entry", source, start); + } + throw FormatException("Same package name occured twice", source, start); } result[packageName] = packageLocation; } diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart index e89d94d22..817002f1e 100644 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -26,6 +26,12 @@ class NoPackages implements Packages { Iterable get packages => new Iterable.empty(); Map asMap() => const {}; + + String get defaultPackageName => null; + + String packageMetadata(String packageName, String key) => null; + + String libraryMetadata(Uri libraryUri, String key) => null; } /// Base class for [Packages] implementations. @@ -51,6 +57,12 @@ abstract class PackagesBase implements Packages { /// Returns `null` if no package exists with that name, and that can be /// determined. Uri getBase(String packageName); + + String get defaultPackageName => null; + + String packageMetadata(String packageName, String key) => null; + + String libraryMetadata(Uri libraryUri, String key) => null; } /// A [Packages] implementation based on an existing map. @@ -58,11 +70,34 @@ class MapPackages extends PackagesBase { final Map _mapping; MapPackages(this._mapping); - Uri getBase(String packageName) => _mapping[packageName]; + Uri getBase(String packageName) => + packageName.isEmpty ? null : _mapping[packageName]; Iterable get packages => _mapping.keys; Map asMap() => new UnmodifiableMapView(_mapping); + + String get defaultPackageName => _mapping[""]?.toString(); + + String packageMetadata(String packageName, String key) { + if (packageName.isEmpty) return null; + Uri uri = _mapping[packageName]; + if (uri == null || !uri.hasFragment) return null; + // This can be optimized, either by caching the map or by + // parsing incrementally instead of parsing the entire fragment. + return Uri.splitQueryString(uri.fragment)[key]; + } + + String libraryMetadata(Uri libraryUri, String key) { + if (libraryUri.isScheme("package")) { + return packageMetadata(libraryUri.pathSegments.first, key); + } + var defaultPackageNameUri = _mapping[""]; + if (defaultPackageNameUri != null) { + return packageMetadata(defaultPackageNameUri.toString(), key); + } + return null; + } } /// A [Packages] implementation based on a remote (e.g., HTTP) directory. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 4bad1cf52..a69096d58 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.0.5 +version: 1.1.0-pre description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index fb3a6fab4..b9b1bb510 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -116,6 +116,82 @@ main() { () => doParse(singleRelativeSample * 2, base), throwsFormatException); }); + test("disallow default package", () { + expect(() => doParse(":foo", base, allowDefaultPackage: false), + throwsFormatException); + }); + + test("allow default package", () { + var packages = doParse(":foo", base, allowDefaultPackage: true); + expect(packages.defaultPackageName, "foo"); + }); + + test("allow default package name with dot", () { + var packages = doParse(":foo.bar", base, allowDefaultPackage: true); + expect(packages.defaultPackageName, "foo.bar"); + }); + + test("not two default packages", () { + expect(() => doParse(":foo\n:bar", base, allowDefaultPackage: true), + throwsFormatException); + }); + + test("default package invalid package name", () { + // Not a valid *package name*. + expect(() => doParse(":foo/bar", base, allowDefaultPackage: true), + throwsFormatException); + }); + + group("metadata", () { + var packages = doParse( + ":foo\n" + "foo:foo#metafoo=1\n" + "bar:bar#metabar=2\n" + "baz:baz\n" + "qux:qux#metaqux1=3&metaqux2=4\n", + base, + allowDefaultPackage: true); + test("non-existing", () { + // non-package name. + expect(packages.packageMetadata("///", "f"), null); + expect(packages.packageMetadata("", "f"), null); + // unconfigured package name. + expect(packages.packageMetadata("absent", "f"), null); + // package name without that metadata + expect(packages.packageMetadata("foo", "notfoo"), null); + }); + test("lookup", () { + expect(packages.packageMetadata("foo", "metafoo"), "1"); + expect(packages.packageMetadata("bar", "metabar"), "2"); + expect(packages.packageMetadata("qux", "metaqux1"), "3"); + expect(packages.packageMetadata("qux", "metaqux2"), "4"); + }); + test("by library URI", () { + expect( + packages.libraryMetadata( + Uri.parse("package:foo/index.dart"), "metafoo"), + "1"); + expect( + packages.libraryMetadata( + Uri.parse("package:bar/index.dart"), "metabar"), + "2"); + expect( + packages.libraryMetadata( + Uri.parse("package:qux/index.dart"), "metaqux1"), + "3"); + expect( + packages.libraryMetadata( + Uri.parse("package:qux/index.dart"), "metaqux2"), + "4"); + }); + test("by default package", () { + expect( + packages.libraryMetadata( + Uri.parse("file:///whatever.dart"), "metafoo"), + "1"); + }); + }); + for (String invalidSample in invalid) { test("invalid '$invalidSample'", () { var result; @@ -130,8 +206,10 @@ main() { } } -Packages doParse(String sample, Uri baseUri) { - Map map = parse(sample.codeUnits, baseUri); +Packages doParse(String sample, Uri baseUri, + {bool allowDefaultPackage = false}) { + Map map = parse(sample.codeUnits, baseUri, + allowDefaultPackage: allowDefaultPackage); return new MapPackages(map); } From 95dada207519f41f974e8e63d7b702d47f8aff25 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 16 Aug 2019 15:06:22 +0200 Subject: [PATCH 300/657] Add .vscode/ to .gitignore. --- pkgs/package_config/.gitignore | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 pkgs/package_config/.gitignore diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore deleted file mode 100644 index e41fc1916..000000000 --- a/pkgs/package_config/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.packages -.pub -.dart_tool/ -packages -pubspec.lock -doc/api/ From 50a840de189ed8da8125df9d21763e8243eec849 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 16 Aug 2019 15:07:23 +0200 Subject: [PATCH 301/657] Readd .gitignore after deleting it. --- pkgs/package_config/.gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 pkgs/package_config/.gitignore diff --git a/pkgs/package_config/.gitignore b/pkgs/package_config/.gitignore new file mode 100644 index 000000000..7b888b84c --- /dev/null +++ b/pkgs/package_config/.gitignore @@ -0,0 +1,7 @@ +.packages +.pub +.dart_tool/ +.vscode/ +packages +pubspec.lock +doc/api/ From 375e28c38c17ca698999d1fd1fd3f383a5387a38 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 16 Aug 2019 15:08:45 +0200 Subject: [PATCH 302/657] Make version number ready for release. --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index a69096d58..b51932eb7 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.1.0-pre +version: 1.1.0 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config From 8e0739f064dabc72e9b2c218d829749e04c4ac9e Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Mon, 2 Sep 2019 14:06:28 +0200 Subject: [PATCH 303/657] Add support for writing defaultPackageName (dart-lang/package_config#54) --- pkgs/package_config/CHANGELOG.md | 3 ++ pkgs/package_config/lib/packages_file.dart | 22 ++++++++- pkgs/package_config/pubspec.yaml | 2 +- .../package_config/test/parse_write_test.dart | 47 ++++++++++++++++++- 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index db4bb00d6..048eedf94 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.2.0 + - Added support for writing default-package entries. + ## 1.1.0 - Allow parsing files with default-package entries and metadata. diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 284d8e90a..1fa18e740 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -106,10 +106,15 @@ Map parse(List source, Uri baseLocation, /// If [baseUri] is provided, package locations will be made relative /// to the base URI, if possible, before writing. /// +/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an +/// empty string mapping to the _default package name_. +/// /// All the keys of [packageMapping] must be valid package names, /// and the values must be URIs that do not have the `package:` scheme. void write(StringSink output, Map packageMapping, - {Uri baseUri, String comment}) { + {Uri baseUri, String comment, bool allowDefaultPackage = false}) { + ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage'); + if (baseUri != null && !baseUri.isAbsolute) { throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute"); } @@ -128,6 +133,21 @@ void write(StringSink output, Map packageMapping, } packageMapping.forEach((String packageName, Uri uri) { + // If [packageName] is empty then [uri] is the _default package name_. + if (allowDefaultPackage && packageName.isEmpty) { + final defaultPackageName = uri.toString(); + if (!isValidPackageName(defaultPackageName)) { + throw ArgumentError.value( + defaultPackageName, + 'defaultPackageName', + '"$defaultPackageName" is not a valid package name', + ); + } + output.write(':'); + output.write(defaultPackageName); + output.writeln(); + return; + } // Validate packageName. if (!isValidPackageName(packageName)) { throw new ArgumentError('"$packageName" is not a valid package name'); diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index b51932eb7..72d299bf2 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.1.0 +version: 1.2.0 description: Support for working with Package Resolution config files. author: Dart Team homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/parse_write_test.dart b/pkgs/package_config/test/parse_write_test.dart index b963eb5b5..415b479e9 100644 --- a/pkgs/package_config/test/parse_write_test.dart +++ b/pkgs/package_config/test/parse_write_test.dart @@ -4,6 +4,7 @@ library package_config.parse_write_test; +import "dart:convert" show utf8; import "package:package_config/packages_file.dart"; import "package:test/test.dart"; @@ -32,6 +33,40 @@ main() { var resultMap = parse(content, packagesFile); expect(resultMap, map); }); + + test("write with defaultPackageName", () { + var content = writeToString( + {'': Uri.parse('my_pkg')}..addAll(map), + allowDefaultPackage: true, + ).codeUnits; + var resultMap = parse( + content, + packagesFile, + allowDefaultPackage: true, + ); + expect(resultMap[''].toString(), 'my_pkg'); + expect( + resultMap, + {'': Uri.parse('my_pkg')}..addAll(map), + ); + }); + + test("write with defaultPackageName (utf8)", () { + var content = utf8.encode(writeToString( + {'': Uri.parse('my_pkg')}..addAll(map), + allowDefaultPackage: true, + )); + var resultMap = parse( + content, + packagesFile, + allowDefaultPackage: true, + ); + expect(resultMap[''].toString(), 'my_pkg'); + expect( + resultMap, + {'': Uri.parse('my_pkg')}..addAll(map), + ); + }); }); } @@ -82,8 +117,16 @@ main() { }); } -String writeToString(Map map, {Uri baseUri, String comment}) { +String writeToString( + Map map, { + Uri baseUri, + String comment, + bool allowDefaultPackage = false, +}) { var buffer = new StringBuffer(); - write(buffer, map, baseUri: baseUri, comment: comment); + write(buffer, map, + baseUri: baseUri, + comment: comment, + allowDefaultPackage: allowDefaultPackage); return buffer.toString(); } From fc6f50e6d9bde8135d3f4dbeea28d31eca8c5c7d Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Mon, 2 Sep 2019 15:54:17 +0200 Subject: [PATCH 304/657] Fix trailing slash logic when writing .packages (dart-lang/package_config#55) --- pkgs/package_config/CHANGELOG.md | 1 + pkgs/package_config/lib/packages_file.dart | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 048eedf94..50f1ede5a 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,5 +1,6 @@ ## 1.2.0 - Added support for writing default-package entries. + - Fixed bug when writing `Uri`s containing a fragment. ## 1.1.0 diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart index 1fa18e740..1c35d5b21 100644 --- a/pkgs/package_config/lib/packages_file.dart +++ b/pkgs/package_config/lib/packages_file.dart @@ -162,10 +162,10 @@ void write(StringSink output, Map packageMapping, if (baseUri != null) { uri = _relativize(uri, baseUri); } - output.write(uri); if (!uri.path.endsWith('/')) { - output.write('/'); + uri = uri.replace(path: uri.path + '/'); } + output.write(uri); output.writeln(); }); } From a7bc53e81c8ada625bc6cba892eaeade0e79ff87 Mon Sep 17 00:00:00 2001 From: Jennifer Thakar Date: Fri, 6 Sep 2019 14:40:32 -0700 Subject: [PATCH 305/657] Fix padding around certain line numbers Resolves dart-lang/source_span#38. --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/highlighter.dart | 2 +- pkgs/source_span/test/highlight_test.dart | 26 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index ddb4ff05a..0dfe483b6 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.5.6 + +* Fix padding around line numbers that are powers of 10 in + `FileSpan.highlight()`. + # 1.5.5 * Fix a bug where `FileSpan.highlight()` would crash for spans that covered a diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 17a47bcea..0714acdb4 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -181,7 +181,7 @@ class Highlighter { // In a purely mathematical world, floor(log10(n)) would give the number of // digits in n, but floating point errors render that unreliable in // practice. - _paddingBeforeSidebar = _span.end.line.toString().length + 1; + _paddingBeforeSidebar = (_span.end.line + 1).toString().length + 1; /// Returns the highlighted span text. /// diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 5fdf622f4..521f7484e 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -530,4 +530,30 @@ ${colors.BLUE}3 |${colors.NONE} ${colors.RED}\\ zip zap zop${colors.NONE} ${colors.BLUE} '${colors.NONE}""")); }); }); + + group("line numbers have appropriate padding", () { + test("with line number 9", () { + expect( + SourceFile.fromString("\n" * 8 + "foo bar baz\n") + .span(8, 11) + .highlight(), + equals(""" + , +9 | foo bar baz + | ^^^ + '""")); + }); + + test("with line number 10", () { + expect( + SourceFile.fromString("\n" * 9 + "foo bar baz\n") + .span(9, 12) + .highlight(), + equals(""" + , +10 | foo bar baz + | ^^^ + '""")); + }); + }); } From 34e1c6175626e4764c13358ffd190d508e6b7d7e Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 6 Nov 2019 17:15:02 -0800 Subject: [PATCH 306/657] Migrate off deprecated isInstanceOf (dart-lang/source_span#40) - Bump `package:test` to `1.6.0` which introduce `isA`. - Use `2.1.0` SDK on travis since it's the minimum supported by `test`. - Bump min SDK in the pubspec to `2.1.0` to match what is tested. - Replace `new isInstanceOf` with `isA`. --- pkgs/source_span/.travis.yml | 2 +- pkgs/source_span/pubspec.yaml | 4 ++-- pkgs/source_span/test/file_test.dart | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index 18267fca2..ace10ab04 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -2,7 +2,7 @@ language: dart dart: - dev - - 2.0.0 + - 2.1.0 dart_task: - test: --platform vm,chrome diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 813dd3b2a..71e10f60a 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -6,7 +6,7 @@ author: Dart Team homepage: https://github.com/dart-lang/source_span environment: - sdk: '>=2.0.0 <3.0.0' + sdk: '>=2.1.0 <3.0.0' dependencies: charcode: ^1.0.0 @@ -14,4 +14,4 @@ dependencies: term_glyph: ^1.0.0 dev_dependencies: - test: ^1.0.0 + test: ^1.6.0 diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index e043ac3ae..9a103c4ae 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -241,7 +241,7 @@ zip zap zop""", url: "bar.dart").span(10, 11); test("pointSpan() returns a FileSpan", () { var location = file.location(15); var span = location.pointSpan(); - expect(span, new isInstanceOf()); + expect(span, isA()); expect(span.start, equals(location)); expect(span.end, equals(location)); expect(span.text, isEmpty); @@ -344,14 +344,14 @@ zip zap zop }); test("returns a FileSpan for a FileSpan input", () { - expect(span.union(file.span(0, 5)), new isInstanceOf()); + expect(span.union(file.span(0, 5)), isA()); }); test("returns a base SourceSpan for a SourceSpan input", () { var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), new SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); var result = span.union(other); - expect(result, isNot(new isInstanceOf())); + expect(result, isNot(isA())); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); expect(result.text, equals("hey, ar baz\n")); From 73c4d394b1de6d70b8cd4998b70b9a24c3457a86 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 7 Nov 2019 10:07:46 -0800 Subject: [PATCH 307/657] Run dartfmt --fix (dart-lang/source_span#42) Drops unnecessary `new`. --- pkgs/source_span/lib/src/file.dart | 56 +++---- pkgs/source_span/lib/src/highlighter.dart | 22 +-- pkgs/source_span/lib/src/location.dart | 12 +- pkgs/source_span/lib/src/location_mixin.dart | 6 +- pkgs/source_span/lib/src/span.dart | 8 +- pkgs/source_span/lib/src/span_mixin.dart | 10 +- .../lib/src/span_with_context.dart | 5 +- pkgs/source_span/test/file_test.dart | 17 +- pkgs/source_span/test/highlight_test.dart | 67 ++++---- pkgs/source_span/test/location_test.dart | 27 ++-- pkgs/source_span/test/span_test.dart | 152 ++++++++---------- 11 files changed, 183 insertions(+), 199 deletions(-) diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 27dae5db2..5a193d34d 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -72,7 +72,7 @@ class SourceFile { /// or equal to `0xFFFF`. SourceFile.decoded(Iterable decodedChars, {url}) : url = url is String ? Uri.parse(url) : url, - _decodedChars = new Uint32List.fromList(decodedChars.toList()) { + _decodedChars = Uint32List.fromList(decodedChars.toList()) { for (var i = 0; i < _decodedChars.length; i++) { var c = _decodedChars[i]; if (c == _CR) { @@ -89,18 +89,18 @@ class SourceFile { /// If [end] isn't passed, it defaults to the end of the file. FileSpan span(int start, [int end]) { if (end == null) end = length; - return new _FileSpan(this, start, end); + return _FileSpan(this, start, end); } /// Returns a location in [this] at [offset]. - FileLocation location(int offset) => new FileLocation._(this, offset); + FileLocation location(int offset) => FileLocation._(this, offset); /// Gets the 0-based line corresponding to [offset]. int getLine(int offset) { if (offset < 0) { - throw new RangeError("Offset may not be negative, was $offset."); + throw RangeError("Offset may not be negative, was $offset."); } else if (offset > length) { - throw new RangeError("Offset $offset must not be greater than the number " + throw RangeError("Offset $offset must not be greater than the number " "of characters in the file, $length."); } @@ -163,24 +163,24 @@ class SourceFile { /// is used to more efficiently compute the column. int getColumn(int offset, {int line}) { if (offset < 0) { - throw new RangeError("Offset may not be negative, was $offset."); + throw RangeError("Offset may not be negative, was $offset."); } else if (offset > length) { - throw new RangeError("Offset $offset must be not be greater than the " + throw RangeError("Offset $offset must be not be greater than the " "number of characters in the file, $length."); } if (line == null) { line = getLine(offset); } else if (line < 0) { - throw new RangeError("Line may not be negative, was $line."); + throw RangeError("Line may not be negative, was $line."); } else if (line >= lines) { - throw new RangeError("Line $line must be less than the number of " + throw RangeError("Line $line must be less than the number of " "lines in the file, $lines."); } var lineStart = _lineStarts[line]; if (lineStart > offset) { - throw new RangeError("Line $line comes after offset $offset."); + throw RangeError("Line $line comes after offset $offset."); } return offset - lineStart; @@ -193,18 +193,18 @@ class SourceFile { if (column == null) column = 0; if (line < 0) { - throw new RangeError("Line may not be negative, was $line."); + throw RangeError("Line may not be negative, was $line."); } else if (line >= lines) { - throw new RangeError("Line $line must be less than the number of " + throw RangeError("Line $line must be less than the number of " "lines in the file, $lines."); } else if (column < 0) { - throw new RangeError("Column may not be negative, was $column."); + throw RangeError("Column may not be negative, was $column."); } var result = _lineStarts[line] + column; if (result > length || (line + 1 < lines && result >= _lineStarts[line + 1])) { - throw new RangeError("Line $line doesn't have $column columns."); + throw RangeError("Line $line doesn't have $column columns."); } return result; @@ -214,7 +214,7 @@ class SourceFile { /// /// If [end] isn't passed, it defaults to the end of the file. String getText(int start, [int end]) => - new String.fromCharCodes(_decodedChars.sublist(start, end)); + String.fromCharCodes(_decodedChars.sublist(start, end)); } /// A [SourceLocation] within a [SourceFile]. @@ -234,14 +234,14 @@ class FileLocation extends SourceLocationMixin implements SourceLocation { FileLocation._(this.file, this.offset) { if (offset < 0) { - throw new RangeError("Offset may not be negative, was $offset."); + throw RangeError("Offset may not be negative, was $offset."); } else if (offset > file.length) { - throw new RangeError("Offset $offset must not be greater than the number " + throw RangeError("Offset $offset must not be greater than the number " "of characters in the file, ${file.length}."); } } - FileSpan pointSpan() => new _FileSpan(file, offset, offset); + FileSpan pointSpan() => _FileSpan(file, offset, offset); } /// A [SourceSpan] within a [SourceFile]. @@ -288,8 +288,8 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { Uri get sourceUrl => file.url; int get length => _end - _start; - FileLocation get start => new FileLocation._(file, _start); - FileLocation get end => new FileLocation._(file, _end); + FileLocation get start => FileLocation._(file, _start); + FileLocation get end => FileLocation._(file, _end); String get text => file.getText(_start, _end); String get context { @@ -327,12 +327,12 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { _FileSpan(this.file, this._start, this._end) { if (_end < _start) { - throw new ArgumentError('End $_end must come after start $_start.'); + throw ArgumentError('End $_end must come after start $_start.'); } else if (_end > file.length) { - throw new RangeError("End $_end must not be greater than the number " + throw RangeError("End $_end must not be greater than the number " "of characters in the file, ${file.length}."); } else if (_start < 0) { - throw new RangeError("Start may not be negative, was $_start."); + throw RangeError("Start may not be negative, was $_start."); } } @@ -351,11 +351,11 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { if (other is _FileSpan) { if (this._start > other._end || other._start > this._end) { - throw new ArgumentError("Spans $this and $other are disjoint."); + throw ArgumentError("Spans $this and $other are disjoint."); } } else { if (this._start > other.end.offset || other.start.offset > this._end) { - throw new ArgumentError("Spans $this and $other are disjoint."); + throw ArgumentError("Spans $this and $other are disjoint."); } } @@ -382,18 +382,18 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { /// between the two will be covered by the returned span. FileSpan expand(FileSpan other) { if (sourceUrl != other.sourceUrl) { - throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"${sourceUrl}\" and " " \"${other.sourceUrl}\" don't match."); } if (other is _FileSpan) { var start = math.min(this._start, other._start); var end = math.max(this._end, other._end); - return new _FileSpan(file, start, end); + return _FileSpan(file, start, end); } else { var start = math.min(this._start, other.start.offset); var end = math.max(this._end, other.end.offset); - return new _FileSpan(file, start, end); + return _FileSpan(file, start, end); } } } diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 0714acdb4..f68e52a3e 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -36,7 +36,7 @@ class Highlighter { _multiline ? 3 : 1; /// The buffer to which to write the result. - final _buffer = new StringBuffer(); + final _buffer = StringBuffer(); /// The number of spaces to render for hard tabs that appear in `_span.text`. /// @@ -63,7 +63,7 @@ class Highlighter { newSpan = _normalizeTrailingNewline(newSpan); newSpan = _normalizeEndOfLine(newSpan); - return new Highlighter._(newSpan, color); + return Highlighter._(newSpan, color); } /// Normalizes [span] to ensure that it's a [SourceSpanWithContext] whose @@ -76,10 +76,10 @@ class Highlighter { span is SourceSpanWithContext && findLineStart(span.context, span.text, span.start.column) != null ? span - : new SourceSpanWithContext( - new SourceLocation(span.start.offset, + : SourceSpanWithContext( + SourceLocation(span.start.offset, sourceUrl: span.sourceUrl, line: 0, column: 0), - new SourceLocation(span.end.offset, + SourceLocation(span.end.offset, sourceUrl: span.sourceUrl, line: countCodeUnits(span.text, $lf), column: _lastLineLength(span.text)), @@ -99,9 +99,9 @@ class Highlighter { } } - return new SourceSpanWithContext( + return SourceSpanWithContext( span.start, - new SourceLocation(endOffset, + SourceLocation(endOffset, sourceUrl: span.sourceUrl, line: span.end.line, column: span.end.column), @@ -127,13 +127,13 @@ class Highlighter { var end = span.end; if (span.text.endsWith("\n") && _isTextAtEndOfContext(span)) { text = span.text.substring(0, span.text.length - 1); - end = new SourceLocation(span.end.offset - 1, + end = SourceLocation(span.end.offset - 1, sourceUrl: span.sourceUrl, line: span.end.line - 1, column: _lastLineLength(text)); start = span.start.offset == span.end.offset ? end : span.start; } - return new SourceSpanWithContext(start, end, text, context); + return SourceSpanWithContext(start, end, text, context); } /// Normalizes [span] so that the end location is at the end of a line rather @@ -144,9 +144,9 @@ class Highlighter { var text = span.text.substring(0, span.text.length - 1); - return new SourceSpanWithContext( + return SourceSpanWithContext( span.start, - new SourceLocation(span.end.offset - 1, + SourceLocation(span.end.offset - 1, sourceUrl: span.sourceUrl, line: span.end.line - 1, column: _lastLineLength(text)), diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index cf9931951..a27188046 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -48,11 +48,11 @@ class SourceLocation implements Comparable { line = line == null ? 0 : line, column = column == null ? offset : column { if (offset < 0) { - throw new RangeError("Offset may not be negative, was $offset."); + throw RangeError("Offset may not be negative, was $offset."); } else if (line != null && line < 0) { - throw new RangeError("Line may not be negative, was $line."); + throw RangeError("Line may not be negative, was $line."); } else if (column != null && column < 0) { - throw new RangeError("Column may not be negative, was $column."); + throw RangeError("Column may not be negative, was $column."); } } @@ -61,21 +61,21 @@ class SourceLocation implements Comparable { /// This always returns a non-negative value. int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"${sourceUrl}\" and " "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); } /// Returns a span that covers only a single point: this location. - SourceSpan pointSpan() => new SourceSpan(this, this, ""); + SourceSpan pointSpan() => SourceSpan(this, this, ""); /// Compares two locations. /// /// [other] must have the same source URL as [this]. int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"${sourceUrl}\" and " "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index 1e5fc66f8..7d34311fc 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -21,17 +21,17 @@ abstract class SourceLocationMixin implements SourceLocation { int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"${sourceUrl}\" and " "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); } - SourceSpan pointSpan() => new SourceSpan(this, this, ""); + SourceSpan pointSpan() => SourceSpan(this, this, ""); int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"${sourceUrl}\" and " "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 57ffe79cb..b32e1ff6a 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -33,7 +33,7 @@ abstract class SourceSpan implements Comparable { /// before [end]. [text] must have a number of characters equal to the /// distance between [start] and [end]. factory SourceSpan(SourceLocation start, SourceLocation end, String text) => - new SourceSpanBase(start, end, text); + SourceSpanBase(start, end, text); /// Creates a new span that's the union of [this] and [other]. /// @@ -91,12 +91,12 @@ class SourceSpanBase extends SourceSpanMixin { SourceSpanBase(this.start, this.end, this.text) { if (end.sourceUrl != start.sourceUrl) { - throw new ArgumentError("Source URLs \"${start.sourceUrl}\" and " + throw ArgumentError("Source URLs \"${start.sourceUrl}\" and " " \"${end.sourceUrl}\" don't match."); } else if (end.offset < start.offset) { - throw new ArgumentError('End $end must come after start $start.'); + throw ArgumentError('End $end must come after start $start.'); } else if (text.length != start.distance(end)) { - throw new ArgumentError('Text "$text" must be ${start.distance(end)} ' + throw ArgumentError('Text "$text" must be ${start.distance(end)} ' 'characters long.'); } } diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index d8ac8f2ba..9bf0937ec 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -26,7 +26,7 @@ abstract class SourceSpanMixin implements SourceSpan { SourceSpan union(SourceSpan other) { if (sourceUrl != other.sourceUrl) { - throw new ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"${sourceUrl}\" and " " \"${other.sourceUrl}\" don't match."); } @@ -36,16 +36,16 @@ abstract class SourceSpanMixin implements SourceSpan { var endSpan = end == this.end ? this : other; if (beginSpan.end.compareTo(endSpan.start) < 0) { - throw new ArgumentError("Spans $this and $other are disjoint."); + throw ArgumentError("Spans $this and $other are disjoint."); } var text = beginSpan.text + endSpan.text.substring(beginSpan.end.distance(endSpan.start)); - return new SourceSpan(start, end, text); + return SourceSpan(start, end, text); } String message(String message, {color}) { - var buffer = new StringBuffer(); + var buffer = StringBuffer(); buffer.write('line ${start.line + 1}, column ${start.column + 1}'); if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); buffer.write(': $message'); @@ -61,7 +61,7 @@ abstract class SourceSpanMixin implements SourceSpan { String highlight({color}) { if (this is! SourceSpanWithContext && this.length == 0) return ""; - return new Highlighter(this, color: color).highlight(); + return Highlighter(this, color: color).highlight(); } bool operator ==(other) => diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart index 41697a0a6..da09cc0b8 100644 --- a/pkgs/source_span/lib/src/span_with_context.dart +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -25,12 +25,11 @@ class SourceSpanWithContext extends SourceSpanBase { SourceLocation start, SourceLocation end, String text, this._context) : super(start, end, text) { if (!context.contains(text)) { - throw new ArgumentError( - 'The context line "$context" must contain "$text".'); + throw ArgumentError('The context line "$context" must contain "$text".'); } if (findLineStart(context, text, start.column) == null) { - throw new ArgumentError('The span text "$text" must start at ' + throw ArgumentError('The span text "$text" must start at ' 'column ${start.column + 1} in a line within "$context".'); } } diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 9a103c4ae..6759ca257 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -8,7 +8,7 @@ import 'package:source_span/source_span.dart'; main() { var file; setUp(() { - file = new SourceFile.fromString(""" + file = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop""", url: "foo.dart"); @@ -109,8 +109,7 @@ zip zap zop""", url: "foo.dart"); group("for span().union()", () { test("source URLs must match", () { - var other = - new SourceSpan(new SourceLocation(10), new SourceLocation(11), "_"); + var other = SourceSpan(SourceLocation(10), SourceLocation(11), "_"); expect(() => file.span(9, 10).union(other), throwsArgumentError); }); @@ -122,7 +121,7 @@ zip zap zop""", url: "foo.dart"); }); test("for span().expand() source URLs must match", () { - var other = new SourceFile.fromString(""" + var other = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop""", url: "bar.dart").span(10, 11); @@ -139,11 +138,11 @@ zip zap zop""", url: "bar.dart").span(10, 11); group("new SourceFile()", () { test("handles CRLF correctly", () { - expect(new SourceFile.fromString("foo\r\nbar").getLine(6), equals(1)); + expect(SourceFile.fromString("foo\r\nbar").getLine(6), equals(1)); }); test("handles a lone CR correctly", () { - expect(new SourceFile.fromString("foo\rbar").getLine(5), equals(1)); + expect(SourceFile.fromString("foo\rbar").getLine(5), equals(1)); }); }); @@ -283,7 +282,7 @@ zip zap zop""", url: "bar.dart").span(10, 11); }); test("with a newline, contains an empty line", () { - file = new SourceFile.fromString(""" + file = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop @@ -348,8 +347,8 @@ zip zap zop }); test("returns a base SourceSpan for a SourceSpan input", () { - var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); + var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); var result = span.union(other); expect(result, isNot(isA())); expect(result.start, equals(other.start)); diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 521f7484e..c2156803c 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -21,7 +21,7 @@ main() { var file; setUp(() { - file = new SourceFile.fromString(""" + file = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop @@ -37,7 +37,7 @@ zip zap zop }); test("gracefully handles a missing source URL", () { - var span = new SourceFile.fromString("foo bar baz").span(4, 7); + var span = SourceFile.fromString("foo bar baz").span(4, 7); expect(span.highlight(), equals(""" , 1 | foo bar baz @@ -95,7 +95,7 @@ zip zap zop }); test("at the end of the file with no trailing newline", () { - file = new SourceFile.fromString("zip zap zop"); + file = SourceFile.fromString("zip zap zop"); expect(file.location(10).pointSpan().highlight(), equals(""" , 1 | zip zap zop @@ -104,7 +104,7 @@ zip zap zop }); test("after the end of the file with no trailing newline", () { - file = new SourceFile.fromString("zip zap zop"); + file = SourceFile.fromString("zip zap zop"); expect(file.location(11).pointSpan().highlight(), equals(""" , 1 | zip zap zop @@ -113,7 +113,7 @@ zip zap zop }); test("in an empty file", () { - expect(new SourceFile.fromString("").location(0).pointSpan().highlight(), + expect(SourceFile.fromString("").location(0).pointSpan().highlight(), equals(""" , 1 | @@ -122,7 +122,7 @@ zip zap zop }); test("on an empty line", () { - var file = new SourceFile.fromString("foo\n\nbar"); + var file = SourceFile.fromString("foo\n\nbar"); expect(file.location(4).pointSpan().highlight(), equals(""" , 2 | @@ -132,8 +132,7 @@ zip zap zop }); test("highlights a single-line file without a newline", () { - expect( - new SourceFile.fromString("foo bar").span(0, 7).highlight(), equals(""" + expect(SourceFile.fromString("foo bar").span(0, 7).highlight(), equals(""" , 1 | foo bar | ^^^^^^^ @@ -141,8 +140,8 @@ zip zap zop }); test("highlights a single empty line", () { - expect(new SourceFile.fromString("foo\n\nbar").span(4, 5).highlight(), - equals(""" + expect( + SourceFile.fromString("foo\n\nbar").span(4, 5).highlight(), equals(""" , 2 | | ^ @@ -194,7 +193,7 @@ zip zap zop }); test("highlights the full first line even if it's indented", () { - var file = new SourceFile.fromString(""" + var file = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop @@ -210,7 +209,7 @@ zip zap zop }); test("highlights the full first line if it's empty", () { - var file = new SourceFile.fromString(""" + var file = SourceFile.fromString(""" foo bar @@ -242,7 +241,7 @@ bar }); test("highlights the full last line with a trailing Windows newline", () { - var file = new SourceFile.fromString(""" + var file = SourceFile.fromString(""" foo bar baz\r whiz bang boom\r zip zap zop\r @@ -269,7 +268,7 @@ zip zap zop\r test( "highlights the full last line at the end of the file with no trailing " "newline", () { - var file = new SourceFile.fromString(""" + var file = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop"""); @@ -284,7 +283,7 @@ zip zap zop"""); }); test("highlights the full last line if it's empty", () { - var file = new SourceFile.fromString(""" + var file = SourceFile.fromString(""" foo bar @@ -298,7 +297,7 @@ bar }); test("highlights multiple empty lines", () { - var file = new SourceFile.fromString("foo\n\n\n\nbar"); + var file = SourceFile.fromString("foo\n\n\n\nbar"); expect(file.span(4, 7).highlight(), equals(""" , 2 | / @@ -309,7 +308,7 @@ bar // Regression test for #32 test("highlights the end of a line and an empty line", () { - var file = new SourceFile.fromString("foo\n\n"); + var file = SourceFile.fromString("foo\n\n"); expect(file.span(3, 5).highlight(), equals(""" , 1 | foo @@ -322,7 +321,7 @@ bar group("prints tabs as spaces", () { group("in a single-line span", () { test("before the highlighted section", () { - var span = new SourceFile.fromString("foo\tbar baz").span(4, 7); + var span = SourceFile.fromString("foo\tbar baz").span(4, 7); expect(span.highlight(), equals(""" , @@ -332,7 +331,7 @@ bar }); test("within the highlighted section", () { - var span = new SourceFile.fromString("foo bar\tbaz bang").span(4, 11); + var span = SourceFile.fromString("foo bar\tbaz bang").span(4, 11); expect(span.highlight(), equals(""" , @@ -342,7 +341,7 @@ bar }); test("after the highlighted section", () { - var span = new SourceFile.fromString("foo bar\tbaz").span(4, 7); + var span = SourceFile.fromString("foo bar\tbaz").span(4, 7); expect(span.highlight(), equals(""" , @@ -354,7 +353,7 @@ bar group("in a multi-line span", () { test("before the highlighted section", () { - var span = new SourceFile.fromString(""" + var span = SourceFile.fromString(""" foo\tbar baz whiz bang boom """).span(4, 21); @@ -369,7 +368,7 @@ whiz bang boom }); test("within the first highlighted line", () { - var span = new SourceFile.fromString(""" + var span = SourceFile.fromString(""" foo bar\tbaz whiz bang boom """).span(4, 21); @@ -384,7 +383,7 @@ whiz bang boom }); test("within a middle highlighted line", () { - var span = new SourceFile.fromString(""" + var span = SourceFile.fromString(""" foo bar baz whiz\tbang boom zip zap zop @@ -401,7 +400,7 @@ zip zap zop }); test("within the last highlighted line", () { - var span = new SourceFile.fromString(""" + var span = SourceFile.fromString(""" foo bar baz whiz\tbang boom """).span(4, 21); @@ -416,7 +415,7 @@ whiz\tbang boom }); test("after the highlighted section", () { - var span = new SourceFile.fromString(""" + var span = SourceFile.fromString(""" foo bar baz whiz bang\tboom """).span(4, 21); @@ -434,9 +433,9 @@ whiz bang\tboom group("supports lines of preceding and following context for a span", () { test("within a single line", () { - var span = new SourceSpanWithContext( - new SourceLocation(20, line: 2, column: 5, sourceUrl: "foo.dart"), - new SourceLocation(27, line: 2, column: 12, sourceUrl: "foo.dart"), + var span = SourceSpanWithContext( + SourceLocation(20, line: 2, column: 5, sourceUrl: "foo.dart"), + SourceLocation(27, line: 2, column: 12, sourceUrl: "foo.dart"), "foo bar", "previous\nlines\n-----foo bar-----\nfollowing line\n"); @@ -451,9 +450,9 @@ whiz bang\tboom }); test("covering a full line", () { - var span = new SourceSpanWithContext( - new SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), - new SourceLocation(33, line: 3, column: 0, sourceUrl: "foo.dart"), + var span = SourceSpanWithContext( + SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), + SourceLocation(33, line: 3, column: 0, sourceUrl: "foo.dart"), "-----foo bar-----\n", "previous\nlines\n-----foo bar-----\nfollowing line\n"); @@ -468,9 +467,9 @@ whiz bang\tboom }); test("covering multiple full lines", () { - var span = new SourceSpanWithContext( - new SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), - new SourceLocation(23, line: 4, column: 0, sourceUrl: "foo.dart"), + var span = SourceSpanWithContext( + SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), + SourceLocation(23, line: 4, column: 0, sourceUrl: "foo.dart"), "foo\nbar\n", "previous\nlines\nfoo\nbar\nfollowing line\n"); diff --git a/pkgs/source_span/test/location_test.dart b/pkgs/source_span/test/location_test.dart index 3a32a92ef..90329362f 100644 --- a/pkgs/source_span/test/location_test.dart +++ b/pkgs/source_span/test/location_test.dart @@ -8,33 +8,30 @@ import 'package:source_span/source_span.dart'; main() { var location; setUp(() { - location = - new SourceLocation(15, line: 2, column: 6, sourceUrl: "foo.dart"); + location = SourceLocation(15, line: 2, column: 6, sourceUrl: "foo.dart"); }); group('errors', () { group('for new SourceLocation()', () { test('offset may not be negative', () { - expect(() => new SourceLocation(-1), throwsRangeError); + expect(() => SourceLocation(-1), throwsRangeError); }); test('line may not be negative', () { - expect(() => new SourceLocation(0, line: -1), throwsRangeError); + expect(() => SourceLocation(0, line: -1), throwsRangeError); }); test('column may not be negative', () { - expect(() => new SourceLocation(0, column: -1), throwsRangeError); + expect(() => SourceLocation(0, column: -1), throwsRangeError); }); }); test('for distance() source URLs must match', () { - expect( - () => location.distance(new SourceLocation(0)), throwsArgumentError); + expect(() => location.distance(SourceLocation(0)), throwsArgumentError); }); test('for compareTo() source URLs must match', () { - expect( - () => location.compareTo(new SourceLocation(0)), throwsArgumentError); + expect(() => location.compareTo(SourceLocation(0)), throwsArgumentError); }); }); @@ -51,13 +48,13 @@ main() { }); test('gracefully handles a missing source URL', () { - var location = new SourceLocation(15, line: 2, column: 6); + var location = SourceLocation(15, line: 2, column: 6); expect(location.toolString, equals('unknown source:3:7')); }); }); test("distance returns the absolute distance between locations", () { - var other = new SourceLocation(10, sourceUrl: "foo.dart"); + var other = SourceLocation(10, sourceUrl: "foo.dart"); expect(location.distance(other), equals(5)); expect(other.distance(location), equals(5)); }); @@ -71,7 +68,7 @@ main() { group("compareTo()", () { test("sorts by offset", () { - var other = new SourceLocation(20, sourceUrl: "foo.dart"); + var other = SourceLocation(20, sourceUrl: "foo.dart"); expect(location.compareTo(other), lessThan(0)); expect(other.compareTo(location), greaterThan(0)); }); @@ -83,17 +80,17 @@ main() { group("equality", () { test("two locations with the same offset and source are equal", () { - var other = new SourceLocation(15, sourceUrl: "foo.dart"); + var other = SourceLocation(15, sourceUrl: "foo.dart"); expect(location, equals(other)); }); test("a different offset isn't equal", () { - var other = new SourceLocation(10, sourceUrl: "foo.dart"); + var other = SourceLocation(10, sourceUrl: "foo.dart"); expect(location, isNot(equals(other))); }); test("a different source isn't equal", () { - var other = new SourceLocation(15, sourceUrl: "bar.dart"); + var other = SourceLocation(15, sourceUrl: "bar.dart"); expect(location, isNot(equals(other))); }); }); diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 99895162a..6a18b4293 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -21,122 +21,114 @@ main() { var span; setUp(() { - span = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); + span = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), + SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); }); group('errors', () { group('for new SourceSpan()', () { test('source URLs must match', () { - var start = new SourceLocation(0, sourceUrl: "foo.dart"); - var end = new SourceLocation(1, sourceUrl: "bar.dart"); - expect(() => new SourceSpan(start, end, "_"), throwsArgumentError); + var start = SourceLocation(0, sourceUrl: "foo.dart"); + var end = SourceLocation(1, sourceUrl: "bar.dart"); + expect(() => SourceSpan(start, end, "_"), throwsArgumentError); }); test('end must come after start', () { - var start = new SourceLocation(1); - var end = new SourceLocation(0); - expect(() => new SourceSpan(start, end, "_"), throwsArgumentError); + var start = SourceLocation(1); + var end = SourceLocation(0); + expect(() => SourceSpan(start, end, "_"), throwsArgumentError); }); test('text must be the right length', () { - var start = new SourceLocation(0); - var end = new SourceLocation(1); - expect(() => new SourceSpan(start, end, "abc"), throwsArgumentError); + var start = SourceLocation(0); + var end = SourceLocation(1); + expect(() => SourceSpan(start, end, "abc"), throwsArgumentError); }); }); group('for new SourceSpanWithContext()', () { test('context must contain text', () { - var start = new SourceLocation(2); - var end = new SourceLocation(5); - expect(() => new SourceSpanWithContext(start, end, "abc", "--axc--"), + var start = SourceLocation(2); + var end = SourceLocation(5); + expect(() => SourceSpanWithContext(start, end, "abc", "--axc--"), throwsArgumentError); }); test('text starts at start.column in context', () { - var start = new SourceLocation(3); - var end = new SourceLocation(5); - expect(() => new SourceSpanWithContext(start, end, "abc", "--abc--"), + var start = SourceLocation(3); + var end = SourceLocation(5); + expect(() => SourceSpanWithContext(start, end, "abc", "--abc--"), throwsArgumentError); }); test('text starts at start.column of line in multi-line context', () { - var start = new SourceLocation(4, line: 55, column: 3); - var end = new SourceLocation(7, line: 55, column: 6); - expect(() => new SourceSpanWithContext(start, end, "abc", "\n--abc--"), + var start = SourceLocation(4, line: 55, column: 3); + var end = SourceLocation(7, line: 55, column: 6); + expect(() => SourceSpanWithContext(start, end, "abc", "\n--abc--"), throwsArgumentError); - expect( - () => new SourceSpanWithContext(start, end, "abc", "\n----abc--"), + expect(() => SourceSpanWithContext(start, end, "abc", "\n----abc--"), throwsArgumentError); - expect( - () => new SourceSpanWithContext(start, end, "abc", "\n\n--abc--"), + expect(() => SourceSpanWithContext(start, end, "abc", "\n\n--abc--"), throwsArgumentError); // However, these are valid: - new SourceSpanWithContext(start, end, "abc", "\n---abc--"); - new SourceSpanWithContext(start, end, "abc", "\n\n---abc--"); + SourceSpanWithContext(start, end, "abc", "\n---abc--"); + SourceSpanWithContext(start, end, "abc", "\n\n---abc--"); }); test('text can occur multiple times in context', () { - var start1 = new SourceLocation(4, line: 55, column: 2); - var end1 = new SourceLocation(7, line: 55, column: 5); - var start2 = new SourceLocation(4, line: 55, column: 8); - var end2 = new SourceLocation(7, line: 55, column: 11); - new SourceSpanWithContext(start1, end1, "abc", "--abc---abc--\n"); - new SourceSpanWithContext(start1, end1, "abc", "--abc--abc--\n"); - new SourceSpanWithContext(start2, end2, "abc", "--abc---abc--\n"); - new SourceSpanWithContext(start2, end2, "abc", "---abc--abc--\n"); + var start1 = SourceLocation(4, line: 55, column: 2); + var end1 = SourceLocation(7, line: 55, column: 5); + var start2 = SourceLocation(4, line: 55, column: 8); + var end2 = SourceLocation(7, line: 55, column: 11); + SourceSpanWithContext(start1, end1, "abc", "--abc---abc--\n"); + SourceSpanWithContext(start1, end1, "abc", "--abc--abc--\n"); + SourceSpanWithContext(start2, end2, "abc", "--abc---abc--\n"); + SourceSpanWithContext(start2, end2, "abc", "---abc--abc--\n"); expect( - () => new SourceSpanWithContext( - start1, end1, "abc", "---abc--abc--\n"), + () => SourceSpanWithContext(start1, end1, "abc", "---abc--abc--\n"), throwsArgumentError); expect( - () => new SourceSpanWithContext( - start2, end2, "abc", "--abc--abc--\n"), + () => SourceSpanWithContext(start2, end2, "abc", "--abc--abc--\n"), throwsArgumentError); }); }); group('for union()', () { test('source URLs must match', () { - var other = new SourceSpan( - new SourceLocation(12, sourceUrl: "bar.dart"), - new SourceLocation(13, sourceUrl: "bar.dart"), - "_"); + var other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), + SourceLocation(13, sourceUrl: "bar.dart"), "_"); expect(() => span.union(other), throwsArgumentError); }); test('spans may not be disjoint', () { - var other = new SourceSpan( - new SourceLocation(13, sourceUrl: 'foo.dart'), - new SourceLocation(14, sourceUrl: 'foo.dart'), - "_"); + var other = SourceSpan(SourceLocation(13, sourceUrl: 'foo.dart'), + SourceLocation(14, sourceUrl: 'foo.dart'), "_"); expect(() => span.union(other), throwsArgumentError); }); }); test('for compareTo() source URLs must match', () { - var other = new SourceSpan(new SourceLocation(12, sourceUrl: "bar.dart"), - new SourceLocation(13, sourceUrl: "bar.dart"), "_"); + var other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), + SourceLocation(13, sourceUrl: "bar.dart"), "_"); expect(() => span.compareTo(other), throwsArgumentError); }); }); test('fields work correctly', () { - expect(span.start, equals(new SourceLocation(5, sourceUrl: "foo.dart"))); - expect(span.end, equals(new SourceLocation(12, sourceUrl: "foo.dart"))); + expect(span.start, equals(SourceLocation(5, sourceUrl: "foo.dart"))); + expect(span.end, equals(SourceLocation(12, sourceUrl: "foo.dart"))); expect(span.sourceUrl, equals(Uri.parse("foo.dart"))); expect(span.length, equals(7)); }); group("union()", () { test("works with a preceding adjacent span", () { - var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); + var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); var result = span.union(other); expect(result.start, equals(other.start)); @@ -145,8 +137,8 @@ main() { }); test("works with a preceding overlapping span", () { - var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(8, sourceUrl: "foo.dart"), "hey, foo"); + var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + SourceLocation(8, sourceUrl: "foo.dart"), "hey, foo"); var result = span.union(other); expect(result.start, equals(other.start)); @@ -155,8 +147,8 @@ main() { }); test("works with a following adjacent span", () { - var other = new SourceSpan(new SourceLocation(12, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), " baz"); + var other = SourceSpan(SourceLocation(12, sourceUrl: "foo.dart"), + SourceLocation(16, sourceUrl: "foo.dart"), " baz"); var result = span.union(other); expect(result.start, equals(span.start)); @@ -165,8 +157,8 @@ main() { }); test("works with a following overlapping span", () { - var other = new SourceSpan(new SourceLocation(9, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), "bar baz"); + var other = SourceSpan(SourceLocation(9, sourceUrl: "foo.dart"), + SourceLocation(16, sourceUrl: "foo.dart"), "bar baz"); var result = span.union(other); expect(result.start, equals(span.start)); @@ -175,15 +167,15 @@ main() { }); test("works with an internal overlapping span", () { - var other = new SourceSpan(new SourceLocation(7, sourceUrl: "foo.dart"), - new SourceLocation(10, sourceUrl: "foo.dart"), "o b"); + var other = SourceSpan(SourceLocation(7, sourceUrl: "foo.dart"), + SourceLocation(10, sourceUrl: "foo.dart"), "o b"); expect(span.union(other), equals(span)); }); test("works with an external overlapping span", () { - var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), "hey, foo bar baz"); + var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + SourceLocation(16, sourceUrl: "foo.dart"), "hey, foo bar baz"); expect(span.union(other), equals(other)); }); @@ -200,8 +192,7 @@ line 1, column 6 of foo.dart: oh no }); test("gracefully handles a missing source URL", () { - var span = new SourceSpan( - new SourceLocation(5), new SourceLocation(12), "foo bar"); + var span = SourceSpan(SourceLocation(5), SourceLocation(12), "foo bar"); expect(span.message("oh no"), equalsIgnoringWhitespace(""" line 1, column 6: oh no @@ -212,8 +203,7 @@ line 1, column 6: oh no }); test("gracefully handles empty text", () { - var span = - new SourceSpan(new SourceLocation(5), new SourceLocation(5), ""); + var span = SourceSpan(SourceLocation(5), SourceLocation(5), ""); expect(span.message("oh no"), equals("line 1, column 6: oh no")); }); @@ -246,9 +236,9 @@ ${colors.BLUE} '${colors.NONE}""")); }); test("with context, underlines the right column", () { - var spanWithContext = new SourceSpanWithContext( - new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(12, sourceUrl: "foo.dart"), + var spanWithContext = SourceSpanWithContext( + SourceLocation(5, sourceUrl: "foo.dart"), + SourceLocation(12, sourceUrl: "foo.dart"), "foo bar", "-----foo bar-----"); @@ -263,16 +253,16 @@ ${colors.BLUE} '${colors.NONE}""")); group("compareTo()", () { test("sorts by start location first", () { - var other = new SourceSpan(new SourceLocation(6, sourceUrl: "foo.dart"), - new SourceLocation(14, sourceUrl: "foo.dart"), "oo bar b"); + var other = SourceSpan(SourceLocation(6, sourceUrl: "foo.dart"), + SourceLocation(14, sourceUrl: "foo.dart"), "oo bar b"); expect(span.compareTo(other), lessThan(0)); expect(other.compareTo(span), greaterThan(0)); }); test("sorts by length second", () { - var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(14, sourceUrl: "foo.dart"), "foo bar b"); + var other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), + SourceLocation(14, sourceUrl: "foo.dart"), "foo bar b"); expect(span.compareTo(other), lessThan(0)); expect(other.compareTo(span), greaterThan(0)); @@ -285,29 +275,29 @@ ${colors.BLUE} '${colors.NONE}""")); group("equality", () { test("two spans with the same locations are equal", () { - var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); + var other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), + SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); expect(span, equals(other)); }); test("a different start isn't equal", () { - var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"), - new SourceLocation(12, sourceUrl: "foo.dart"), "hey, foo bar"); + var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + SourceLocation(12, sourceUrl: "foo.dart"), "hey, foo bar"); expect(span, isNot(equals(other))); }); test("a different end isn't equal", () { - var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"), - new SourceLocation(16, sourceUrl: "foo.dart"), "foo bar baz"); + var other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), + SourceLocation(16, sourceUrl: "foo.dart"), "foo bar baz"); expect(span, isNot(equals(other))); }); test("a different source URL isn't equal", () { - var other = new SourceSpan(new SourceLocation(5, sourceUrl: "bar.dart"), - new SourceLocation(12, sourceUrl: "bar.dart"), "foo bar"); + var other = SourceSpan(SourceLocation(5, sourceUrl: "bar.dart"), + SourceLocation(12, sourceUrl: "bar.dart"), "foo bar"); expect(span, isNot(equals(other))); }); From d65560c0743ad2df0ec646de5b4f71430b7b50ed Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 7 Nov 2019 11:00:13 -0800 Subject: [PATCH 308/657] Enable package:pedantic lints (dart-lang/source_span#43) Fix one case of `prefer_is_not_empty`. --- pkgs/source_span/analysis_options.yaml | 1 + pkgs/source_span/lib/src/span_mixin.dart | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 pkgs/source_span/analysis_options.yaml diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml new file mode 100644 index 000000000..108d1058a --- /dev/null +++ b/pkgs/source_span/analysis_options.yaml @@ -0,0 +1 @@ +include: package:pedantic/analysis_options.yaml diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 9bf0937ec..75ecb3d1d 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -51,7 +51,7 @@ abstract class SourceSpanMixin implements SourceSpan { buffer.write(': $message'); var highlight = this.highlight(color: color); - if (!highlight.isEmpty) { + if (highlight.isNotEmpty) { buffer.writeln(); buffer.write(highlight); } From ff838908bd75a6b3c1d8cebdb42b7b96f06e9c42 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 7 Nov 2019 15:26:43 -0800 Subject: [PATCH 309/657] Be more efficient with String.fromCharCodes (dart-lang/source_span#44) Fixes https://github.com/dart-lang/source_span/issues/37 --- pkgs/source_span/lib/src/file.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 5a193d34d..44760c779 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -214,7 +214,7 @@ class SourceFile { /// /// If [end] isn't passed, it defaults to the end of the file. String getText(int start, [int end]) => - String.fromCharCodes(_decodedChars.sublist(start, end)); + String.fromCharCodes(_decodedChars, start, end); } /// A [SourceLocation] within a [SourceFile]. From ecad5bbec29773c9e2050242fd17464f9dbdf953 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 8 Nov 2019 15:25:50 -0800 Subject: [PATCH 310/657] Enable and fix a number of lints (dart-lang/source_span#45) - Disable implicit casts and fix errors. - Enable lints that are used in other well maintained dart-lang repos. --- pkgs/source_span/analysis_options.yaml | 91 ++++++++++++++++ pkgs/source_span/lib/src/colors.dart | 8 +- pkgs/source_span/lib/src/file.dart | 101 ++++++++++------- pkgs/source_span/lib/src/highlighter.dart | 66 ++++++------ pkgs/source_span/lib/src/location.dart | 20 ++-- pkgs/source_span/lib/src/location_mixin.dart | 13 ++- pkgs/source_span/lib/src/span.dart | 11 +- pkgs/source_span/lib/src/span_exception.dart | 16 +-- pkgs/source_span/lib/src/span_mixin.dart | 37 ++++--- pkgs/source_span/lib/src/utils.dart | 11 +- pkgs/source_span/test/file_test.dart | 74 ++++++------- pkgs/source_span/test/highlight_test.dart | 91 ++++++++-------- pkgs/source_span/test/location_test.dart | 20 ++-- pkgs/source_span/test/span_test.dart | 108 +++++++++---------- pkgs/source_span/test/utils_test.dart | 24 ++--- 15 files changed, 419 insertions(+), 272 deletions(-) diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index 108d1058a..f28d5a1f1 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -1 +1,92 @@ include: package:pedantic/analysis_options.yaml +analyzer: + strong-mode: + implicit-casts: false +linter: + rules: + - always_declare_return_types + - annotate_overrides + - avoid_bool_literals_in_conditional_expressions + - avoid_classes_with_only_static_members + - avoid_empty_else + - avoid_function_literals_in_foreach_calls + - avoid_init_to_null + - avoid_null_checks_in_equality_operators + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + - avoid_returning_null + - avoid_returning_null_for_future + - avoid_returning_null_for_void + - avoid_returning_this + - avoid_shadowing_type_parameters + - avoid_single_cascade_in_expression_statements + - avoid_types_as_parameter_names + - avoid_unused_constructor_parameters + - await_only_futures + - camel_case_types + - cancel_subscriptions + - cascade_invocations + # Enable once https://github.com/dart-lang/sdk/issues/31761 is fixed + #- comment_references + - constant_identifier_names + - control_flow_in_finally + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + - file_names + - hash_and_equals + - implementation_imports + - invariant_booleans + - iterable_contains_unrelated_type + - library_names + - library_prefixes + - list_remove_unrelated_type + - no_adjacent_strings_in_list + - no_duplicate_case_values + - non_constant_identifier_names + - null_closures + - omit_local_variable_types + - only_throw_errors + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + - prefer_adjacent_string_concatenation + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_contains + - prefer_equal_for_default_values + - prefer_final_fields + - prefer_final_locals + - prefer_generic_function_type_aliases + - prefer_initializing_formals + - prefer_interpolation_to_compose_strings + - prefer_is_empty + - prefer_is_not_empty + - prefer_null_aware_operators + #- prefer_single_quotes + - prefer_typing_uninitialized_variables + - recursive_getters + - slash_for_doc_comments + - test_types_in_equals + - throw_in_finally + - type_init_formals + - unawaited_futures + - unnecessary_await_in_return + - unnecessary_brace_in_string_interps + - unnecessary_const + - unnecessary_getters_setters + - unnecessary_lambdas + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_this + - unrelated_type_equality_checks + - use_function_type_syntax_for_parameters + - use_rethrow_when_possible + - valid_regexps + - void_checks diff --git a/pkgs/source_span/lib/src/colors.dart b/pkgs/source_span/lib/src/colors.dart index 2931eea9e..b48d468ca 100644 --- a/pkgs/source_span/lib/src/colors.dart +++ b/pkgs/source_span/lib/src/colors.dart @@ -3,10 +3,10 @@ // BSD-style license that can be found in the LICENSE file. // Color constants used for generating messages. -const String RED = '\u001b[31m'; +const String red = '\u001b[31m'; -const String YELLOW = '\u001b[33m'; +const String yellow = '\u001b[33m'; -const String BLUE = '\u001b[34m'; +const String blue = '\u001b[34m'; -const String NONE = '\u001b[0m'; +const String none = '\u001b[0m'; diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 44760c779..97a2f6534 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -12,8 +12,8 @@ import 'span_mixin.dart'; import 'span_with_context.dart'; // Constants to determine end-of-lines. -const int _LF = 10; -const int _CR = 13; +const int _lf = 10; +const int _cr = 13; /// A class representing a source file. /// @@ -71,28 +71,28 @@ class SourceFile { /// forwards-compatibility, callers should only pass in characters less than /// or equal to `0xFFFF`. SourceFile.decoded(Iterable decodedChars, {url}) - : url = url is String ? Uri.parse(url) : url, + : 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]; - if (c == _CR) { + if (c == _cr) { // Return not followed by newline is treated as a newline - var j = i + 1; - if (j >= _decodedChars.length || _decodedChars[j] != _LF) c = _LF; + final j = i + 1; + if (j >= _decodedChars.length || _decodedChars[j] != _lf) c = _lf; } - if (c == _LF) _lineStarts.add(i + 1); + if (c == _lf) _lineStarts.add(i + 1); } } - /// Returns a span in [this] from [start] to [end] (exclusive). + /// 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]) { - if (end == null) end = length; + end ??= length; return _FileSpan(this, start, end); } - /// Returns a location in [this] at [offset]. + /// Returns a location at [offset]. FileLocation location(int offset) => FileLocation._(this, offset); /// Gets the 0-based line corresponding to [offset]. @@ -143,10 +143,10 @@ class SourceFile { /// /// Returns the index of the line in [_lineStarts]. int _binarySearch(int offset) { - int min = 0; - int max = _lineStarts.length - 1; + var min = 0; + var max = _lineStarts.length - 1; while (min < max) { - var half = min + ((max - min) ~/ 2); + final half = min + ((max - min) ~/ 2); if (_lineStarts[half] > offset) { max = half; } else { @@ -178,7 +178,7 @@ class SourceFile { "lines in the file, $lines."); } - var lineStart = _lineStarts[line]; + final lineStart = _lineStarts[line]; if (lineStart > offset) { throw RangeError("Line $line comes after offset $offset."); } @@ -190,7 +190,7 @@ class SourceFile { /// /// [column] defaults to 0. int getOffset(int line, [int column]) { - if (column == null) column = 0; + column ??= 0; if (line < 0) { throw RangeError("Line may not be negative, was $line."); @@ -201,7 +201,7 @@ class SourceFile { throw RangeError("Column may not be negative, was $column."); } - var result = _lineStarts[line] + column; + final result = _lineStarts[line] + column; if (result > length || (line + 1 < lines && result >= _lineStarts[line + 1])) { throw RangeError("Line $line doesn't have $column columns."); @@ -224,12 +224,19 @@ class SourceFile { /// /// A [FileLocation] can be created using [SourceFile.location]. class FileLocation extends SourceLocationMixin implements SourceLocation { - /// The [file] that [this] belongs to. + /// The [file] that `this` belongs to. final SourceFile file; + @override final int offset; + + @override Uri get sourceUrl => file.url; + + @override int get line => file.getLine(offset); + + @override int get column => file.getColumn(offset); FileLocation._(this.file, this.offset) { @@ -241,27 +248,31 @@ class FileLocation extends SourceLocationMixin implements SourceLocation { } } + @override FileSpan pointSpan() => _FileSpan(file, offset, offset); } /// A [SourceSpan] within a [SourceFile]. /// /// Unlike the base [SourceSpan], [FileSpan] lazily computes its line and column -/// values based on its offset and the contents of [file]. [FileSpan.message] is -/// also able to provide more context then [SourceSpan.message], and -/// [FileSpan.union] will return a [FileSpan] if possible. +/// values based on its offset and the contents of [file]. [SourceSpan.message] +/// is also able to provide more context then [SourceSpan.message], and +/// [SourceSpan.union] will return a [FileSpan] if possible. /// /// A [FileSpan] can be created using [SourceFile.span]. abstract class FileSpan implements SourceSpanWithContext { - /// The [file] that [this] belongs to. + /// The [file] that `this` belongs to. SourceFile get file; + @override FileLocation get start; + + @override FileLocation get end; - /// Returns a new span that covers both [this] and [other]. + /// Returns a new span that covers both `this` and [other]. /// - /// Unlike [union], [other] may be disjoint from [this]. If it is, the text + /// Unlike [union], [other] may be disjoint from `this`. If it is, the text /// between the two will be covered by the returned span. FileSpan expand(FileSpan other); } @@ -272,6 +283,7 @@ abstract class FileSpan implements SourceSpanWithContext { /// to make certain operations more efficient. If we used `is FileSpan`, that /// would break if external classes implemented the interface. class _FileSpan extends SourceSpanMixin implements FileSpan { + @override final SourceFile file; /// The offset of the beginning of the span. @@ -286,15 +298,25 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { /// objects. final int _end; + @override Uri get sourceUrl => file.url; + + @override int get length => _end - _start; + + @override FileLocation get start => FileLocation._(file, _start); + + @override FileLocation get end => FileLocation._(file, _end); + + @override String get text => file.getText(_start, _end); + @override String get context { - var endLine = file.getLine(_end); - var endColumn = file.getColumn(_end); + final endLine = file.getLine(_end); + final endColumn = file.getColumn(_end); int endOffset; if (endColumn == 0 && endLine != 0) { @@ -336,25 +358,27 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { } } + @override int compareTo(SourceSpan other) { if (other is! _FileSpan) return super.compareTo(other); - _FileSpan otherFile = other; - var result = _start.compareTo(otherFile._start); + final otherFile = other as _FileSpan; + final result = _start.compareTo(otherFile._start); return result == 0 ? _end.compareTo(otherFile._end) : result; } + @override SourceSpan union(SourceSpan other) { if (other is! FileSpan) return super.union(other); - _FileSpan span = expand(other); + final span = expand(other as _FileSpan); if (other is _FileSpan) { - if (this._start > other._end || other._start > this._end) { + if (_start > other._end || other._start > _end) { throw ArgumentError("Spans $this and $other are disjoint."); } } else { - if (this._start > other.end.offset || other.start.offset > this._end) { + if (_start > other.end.offset || other.start.offset > _end) { throw ArgumentError("Spans $this and $other are disjoint."); } } @@ -362,6 +386,7 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { return span; } + @override bool operator ==(other) { if (other is! FileSpan) return super == other; if (other is! _FileSpan) { @@ -374,25 +399,27 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { } // Eliminates dart2js warning about overriding `==`, but not `hashCode` + @override int get hashCode => super.hashCode; - /// Returns a new span that covers both [this] and [other]. + /// Returns a new span that covers both `this` and [other]. /// - /// Unlike [union], [other] may be disjoint from [this]. If it is, the text + /// Unlike [union], [other] may be disjoint from `this`. If it is, the text /// between the two will be covered by the returned span. + @override FileSpan expand(FileSpan other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"$sourceUrl\" and " " \"${other.sourceUrl}\" don't match."); } if (other is _FileSpan) { - var start = math.min(this._start, other._start); - var end = math.max(this._end, other._end); + final start = math.min(_start, other._start); + final end = math.max(_end, other._end); return _FileSpan(file, start, end); } else { - var start = math.min(this._start, other.start.offset); - var end = math.max(this._end, other.end.offset); + final start = math.min(_start, other.start.offset); + final end = math.max(_end, other.end.offset); return _FileSpan(file, start, end); } } diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index f68e52a3e..94bc85771 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -44,8 +44,8 @@ class Highlighter { /// alignment. static const _spacesPerTab = 4; - /// Creats a [Highlighter] that will return a message associated with [span] - /// when [write] is called. + /// Creates a [Highlighter] that will return a message associated with [span] + /// when [highlight] is called. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, /// it indicates an [ANSI terminal color @@ -55,7 +55,7 @@ class Highlighter { /// highlighted using the default color. If it's `false` or `null`, it /// indicates that the text shouldn't be highlighted. factory Highlighter(SourceSpan span, {color}) { - if (color == true) color = colors.RED; + if (color == true) color = colors.red; if (color == false) color = null; var newSpan = _normalizeContext(span); @@ -63,7 +63,7 @@ class Highlighter { newSpan = _normalizeTrailingNewline(newSpan); newSpan = _normalizeEndOfLine(newSpan); - return Highlighter._(newSpan, color); + return Highlighter._(newSpan, color as String); } /// Normalizes [span] to ensure that it's a [SourceSpanWithContext] whose @@ -89,7 +89,7 @@ class Highlighter { /// Normalizes [span] to replace Windows-style newlines with Unix-style /// newlines. static SourceSpanWithContext _normalizeNewlines(SourceSpanWithContext span) { - var text = span.text; + final text = span.text; if (!text.contains("\r\n")) return span; var endOffset = span.end.offset; @@ -121,7 +121,7 @@ class Highlighter { // significant, so we shouldn't trim it. if (span.text.endsWith("\n\n")) return span; - var context = span.context.substring(0, span.context.length - 1); + final context = span.context.substring(0, span.context.length - 1); var text = span.text; var start = span.start; var end = span.end; @@ -142,7 +142,7 @@ class Highlighter { if (span.end.column != 0) return span; if (span.end.line == span.start.line) return span; - var text = span.text.substring(0, span.text.length - 1); + final text = span.text.substring(0, span.text.length - 1); return SourceSpanWithContext( span.start, @@ -192,7 +192,7 @@ class Highlighter { // If [_span.context] contains lines prior to the one [_span.text] appears // on, write those first. - var lineStart = + final lineStart = findLineStart(_span.context, _span.text, _span.start.column); assert(lineStart != null); // enforced by [_normalizeContext] @@ -202,7 +202,7 @@ class Highlighter { // [findLineStart] is guaranteed to return a position immediately after a // newline. Including that newline would add an extra empty line to the // end of [lines]. - var lines = context.substring(0, lineStart - 1).split("\n"); + final lines = context.substring(0, lineStart - 1).split("\n"); var lineNumber = _span.start.line - lines.length; for (var line in lines) { _writeSidebar(line: lineNumber); @@ -214,9 +214,9 @@ class Highlighter { context = context.substring(lineStart); } - var lines = context.split("\n"); + final lines = context.split("\n"); - var lastLineIndex = _span.end.line - _span.start.line; + final lastLineIndex = _span.end.line - _span.start.line; if (lines.last.isEmpty && lines.length > lastLineIndex + 1) { // Trim a trailing newline so we don't add an empty line to the end of the // highlight. @@ -242,15 +242,14 @@ class Highlighter { var startColumn = math.min(_span.start.column, line.length); var endColumn = math.min( startColumn + _span.end.offset - _span.start.offset, line.length); - var textBefore = line.substring(0, startColumn); + final textBefore = line.substring(0, startColumn); // If the span covers the entire first line other than initial whitespace, // don't bother pointing out exactly where it begins. if (_multiline && _isOnlyWhitespace(textBefore)) { _buffer.write(" "); _colorize(() { - _buffer.write(glyph.glyphOrAscii("┌", "/")); - _buffer.write(" "); + _buffer..write(glyph.glyphOrAscii("┌", "/"))..write(" "); _writeText(line); }); _buffer.writeln(); @@ -259,15 +258,15 @@ class Highlighter { _buffer.write(" " * _paddingAfterSidebar); _writeText(textBefore); - var textInside = line.substring(startColumn, endColumn); + final textInside = line.substring(startColumn, endColumn); _colorize(() => _writeText(textInside)); _writeText(line.substring(endColumn)); _buffer.writeln(); // Adjust the start and end column to account for any tabs that were // converted to spaces. - var tabsBefore = _countTabs(textBefore); - var tabsInside = _countTabs(textInside); + final tabsBefore = _countTabs(textBefore); + final tabsInside = _countTabs(textInside); startColumn = startColumn + tabsBefore * (_spacesPerTab - 1); endColumn = endColumn + (tabsBefore + tabsInside) * (_spacesPerTab - 1); @@ -277,9 +276,10 @@ class Highlighter { if (_multiline) { _buffer.write(" "); _colorize(() { - _buffer.write(glyph.topLeftCorner); - _buffer.write(glyph.horizontalLine * (startColumn + 1)); - _buffer.write("^"); + _buffer + ..write(glyph.topLeftCorner) + ..write(glyph.horizontalLine * (startColumn + 1)) + ..write("^"); }); } else { _buffer.write(" " * (startColumn + 1)); @@ -300,8 +300,7 @@ class Highlighter { _buffer.write(" "); _colorize(() { - _buffer.write(glyph.verticalLine); - _buffer.write(" "); + _buffer..write(glyph.verticalLine)..write(" "); _writeText(line); }); _buffer.writeln(); @@ -323,8 +322,7 @@ class Highlighter { if (_multiline && endColumn == line.length) { _buffer.write(" "); _colorize(() { - _buffer.write(glyph.glyphOrAscii("└", "\\")); - _buffer.write(" "); + _buffer..write(glyph.glyphOrAscii("└", "\\"))..write(" "); _writeText(line); }); _buffer.writeln(); @@ -332,10 +330,9 @@ class Highlighter { } _buffer.write(" "); - var textInside = line.substring(0, endColumn); + final textInside = line.substring(0, endColumn); _colorize(() { - _buffer.write(glyph.verticalLine); - _buffer.write(" "); + _buffer..write(glyph.verticalLine)..write(" "); _writeText(textInside); }); _writeText(line.substring(endColumn)); @@ -343,7 +340,7 @@ class Highlighter { // Adjust the end column to account for any tabs that were converted to // spaces. - var tabsInside = _countTabs(textInside); + final tabsInside = _countTabs(textInside); endColumn = endColumn + tabsInside * (_spacesPerTab - 1); // Write the highlight for the final line, which is an arrow pointing to the @@ -351,9 +348,10 @@ class Highlighter { _writeSidebar(); _buffer.write(" "); _colorize(() { - _buffer.write(glyph.bottomLeftCorner); - _buffer.write(glyph.horizontalLine * endColumn); - _buffer.write("^"); + _buffer + ..write(glyph.bottomLeftCorner) + ..write(glyph.horizontalLine * endColumn) + ..write("^"); }); _buffer.writeln(); } @@ -395,7 +393,7 @@ class Highlighter { _buffer.write(" " * _paddingBeforeSidebar); } _buffer.write(end ?? glyph.verticalLine); - }, color: colors.BLUE); + }, color: colors.blue); } /// Returns the number of hard tabs in [text]. @@ -419,9 +417,9 @@ class Highlighter { /// enabled. /// /// If [color] is passed, it's used as the color; otherwise, [_color] is used. - void _colorize(void callback(), {String color}) { + void _colorize(void Function() callback, {String color}) { if (_color != null) _buffer.write(color ?? _color); callback(); - if (_color != null) _buffer.write(colors.NONE); + if (_color != null) _buffer.write(colors.none); } } diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index a27188046..c03c98c51 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -32,7 +32,7 @@ class SourceLocation implements Comparable { /// /// This prints 1-based lines and columns. String get toolString { - var source = sourceUrl == null ? 'unknown source' : sourceUrl; + final source = sourceUrl == null ? 'unknown source' : sourceUrl; return '$source:${line + 1}:${column + 1}'; } @@ -42,9 +42,9 @@ class SourceLocation implements Comparable { /// means that [line] defaults to 0 and [column] defaults to [offset]. /// /// [sourceUrl] may be either a [String], a [Uri], or `null`. - SourceLocation(int offset, {sourceUrl, int line, int column}) - : sourceUrl = sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl, - offset = offset, + SourceLocation(this.offset, {sourceUrl, int line, int column}) + : sourceUrl = + sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri, line = line == null ? 0 : line, column = column == null ? offset : column { if (offset < 0) { @@ -56,12 +56,12 @@ class SourceLocation implements Comparable { } } - /// Returns the distance in characters between [this] and [other]. + /// Returns the distance in characters between `this` and [other]. /// /// This always returns a non-negative value. int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"$sourceUrl\" and " "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); @@ -72,22 +72,26 @@ class SourceLocation implements Comparable { /// Compares two locations. /// - /// [other] must have the same source URL as [this]. + /// [other] must have the same source URL as `this`. + @override int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"$sourceUrl\" and " "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; } + @override bool operator ==(other) => other is SourceLocation && sourceUrl == other.sourceUrl && offset == other.offset; + @override int get hashCode => sourceUrl.hashCode + offset; + @override String toString() => '<$runtimeType: $offset $toolString>'; } diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index 7d34311fc..bd773ae76 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -14,35 +14,42 @@ import 'span.dart'; /// A mixin for easily implementing [SourceLocation]. abstract class SourceLocationMixin implements SourceLocation { + @override String get toolString { - var source = sourceUrl == null ? 'unknown source' : sourceUrl; + final source = sourceUrl == null ? 'unknown source' : sourceUrl; return '$source:${line + 1}:${column + 1}'; } + @override int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"$sourceUrl\" and " "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); } + @override SourceSpan pointSpan() => SourceSpan(this, this, ""); + @override int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"$sourceUrl\" and " "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; } + @override bool operator ==(other) => other is SourceLocation && sourceUrl == other.sourceUrl && offset == other.offset; + @override int get hashCode => sourceUrl.hashCode + offset; + @override String toString() => '<$runtimeType: $offset $toolString>'; } diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index b32e1ff6a..87ce846b0 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -6,6 +6,7 @@ import 'package:term_glyph/term_glyph.dart' as glyph; import 'location.dart'; import 'span_mixin.dart'; +import 'span_with_context.dart'; /// A class that describes a segment of source text. abstract class SourceSpan implements Comparable { @@ -35,16 +36,17 @@ abstract class SourceSpan implements Comparable { factory SourceSpan(SourceLocation start, SourceLocation end, String text) => SourceSpanBase(start, end, text); - /// Creates a new span that's the union of [this] and [other]. + /// Creates a new span that's the union of `this` and [other]. /// /// The two spans must have the same source URL and may not be disjoint. - /// [text] is computed by combining [this.text] and [other.text]. + /// [text] is computed by combining `this.text` and `other.text`. SourceSpan union(SourceSpan other); /// Compares two spans. /// - /// [other] must have the same source URL as [this]. This orders spans by + /// [other] must have the same source URL as `this`. This orders spans by /// [start] then [length]. + @override int compareTo(SourceSpan other); /// Formats [message] in a human-friendly way associated with this span. @@ -85,8 +87,11 @@ abstract class SourceSpan implements Comparable { /// A base class for source spans with [start], [end], and [text] known at /// construction time. class SourceSpanBase extends SourceSpanMixin { + @override final SourceLocation start; + @override final SourceLocation end; + @override final String text; SourceSpanBase(this.start, this.end, this.text) { diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index 6d3448b6c..2ce0f1a5a 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -20,16 +20,17 @@ class SourceSpanException implements Exception { SourceSpanException(this._message, this._span); - /// Returns a string representation of [this]. + /// Returns a string representation of `this`. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, - /// it indicates an ANSII terminal color escape that should be used to + /// it indicates an ANSI terminal color escape that should be used to /// highlight the span's text. If it's `true`, it indicates that the text /// should be highlighted using the default color. If it's `false` or `null`, /// it indicates that the text shouldn't be highlighted. + @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)}"; } } @@ -37,11 +38,12 @@ class SourceSpanException implements Exception { class SourceSpanFormatException extends SourceSpanException implements FormatException { // This is a getter so that subclasses can override it. - dynamic get source => _source; - final _source; + @override + final dynamic source; - int get offset => span == null ? null : span.start.offset; + @override + int get offset => span?.start?.offset; - SourceSpanFormatException(String message, SourceSpan span, [this._source]) + SourceSpanFormatException(String message, SourceSpan span, [this.source]) : super(message, span); } diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 75ecb3d1d..89606114a 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -16,58 +16,69 @@ import 'utils.dart'; /// [start] comes before [end], and that [text] has a number of characters equal /// to the distance between [start] and [end]. abstract class SourceSpanMixin implements SourceSpan { + @override Uri get sourceUrl => start.sourceUrl; + + @override int get length => end.offset - start.offset; + @override int compareTo(SourceSpan other) { - var result = start.compareTo(other.start); + final result = start.compareTo(other.start); return result == 0 ? end.compareTo(other.end) : result; } + @override SourceSpan union(SourceSpan other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"${sourceUrl}\" and " + throw ArgumentError("Source URLs \"$sourceUrl\" and " " \"${other.sourceUrl}\" don't match."); } - var start = min(this.start, other.start); - var end = max(this.end, other.end); - var beginSpan = start == this.start ? this : other; - var endSpan = end == this.end ? this : other; + final start = min(this.start, other.start); + final end = max(this.end, other.end); + final beginSpan = start == this.start ? this : other; + final endSpan = end == this.end ? this : other; if (beginSpan.end.compareTo(endSpan.start) < 0) { throw ArgumentError("Spans $this and $other are disjoint."); } - var text = beginSpan.text + + final text = beginSpan.text + endSpan.text.substring(beginSpan.end.distance(endSpan.start)); return SourceSpan(start, end, text); } + @override String message(String message, {color}) { - var buffer = StringBuffer(); - buffer.write('line ${start.line + 1}, column ${start.column + 1}'); + final buffer = StringBuffer() + ..write('line ${start.line + 1}, column ${start.column + 1}'); if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); buffer.write(': $message'); - var highlight = this.highlight(color: color); + final highlight = this.highlight(color: color); if (highlight.isNotEmpty) { - buffer.writeln(); - buffer.write(highlight); + buffer + ..writeln() + ..write(highlight); } return buffer.toString(); } + @override String highlight({color}) { - if (this is! SourceSpanWithContext && this.length == 0) return ""; + if (this is! SourceSpanWithContext && length == 0) return ""; return Highlighter(this, color: color).highlight(); } + @override bool operator ==(other) => other is SourceSpan && start == other.start && end == other.end; + @override int get hashCode => start.hashCode + (31 * end.hashCode); + @override String toString() => '<$runtimeType: from $start to $end "$text">'; } diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 228b240e0..33791debd 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -4,12 +4,12 @@ /// Returns the minimum of [obj1] and [obj2] according to /// [Comparable.compareTo]. -Comparable min(Comparable obj1, Comparable obj2) => +T min(T obj1, T obj2) => obj1.compareTo(obj2) > 0 ? obj2 : obj1; /// Returns the maximum of [obj1] and [obj2] according to /// [Comparable.compareTo]. -Comparable max(Comparable obj1, Comparable obj2) => +T max(T obj1, T obj2) => obj1.compareTo(obj2) > 0 ? obj1 : obj2; /// Returns the number of instances of [codeUnit] in [string]. @@ -31,7 +31,7 @@ int findLineStart(String context, String text, int column) { if (text.isEmpty) { var beginningOfLine = 0; while (true) { - var index = context.indexOf("\n", beginningOfLine); + final index = context.indexOf("\n", beginningOfLine); if (index == -1) { return context.length - beginningOfLine >= column ? beginningOfLine @@ -46,10 +46,11 @@ int findLineStart(String context, String text, int column) { var index = context.indexOf(text); while (index != -1) { // Start looking before [index] in case [text] starts with a newline. - var lineStart = index == 0 ? 0 : context.lastIndexOf('\n', index - 1) + 1; - var textColumn = index - lineStart; + final lineStart = index == 0 ? 0 : context.lastIndexOf('\n', index - 1) + 1; + final textColumn = index - lineStart; if (column == textColumn) return lineStart; index = context.indexOf(text, index + 1); } + // ignore: avoid_returning_null return null; } diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 6759ca257..2cfe2d4e7 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -5,8 +5,8 @@ import 'package:test/test.dart'; import 'package:source_span/source_span.dart'; -main() { - var file; +void main() { + SourceFile file; setUp(() { file = SourceFile.fromString(""" foo bar baz @@ -109,7 +109,7 @@ zip zap zop""", url: "foo.dart"); group("for span().union()", () { test("source URLs must match", () { - var other = SourceSpan(SourceLocation(10), SourceLocation(11), "_"); + final other = SourceSpan(SourceLocation(10), SourceLocation(11), "_"); expect(() => file.span(9, 10).union(other), throwsArgumentError); }); @@ -121,7 +121,7 @@ zip zap zop""", url: "foo.dart"); }); test("for span().expand() source URLs must match", () { - var other = SourceFile.fromString(""" + final other = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop""", url: "bar.dart").span(10, 11); @@ -148,13 +148,13 @@ zip zap zop""", url: "bar.dart").span(10, 11); group("span()", () { test("returns a span between the given offsets", () { - var span = file.span(5, 10); + final span = file.span(5, 10); expect(span.start, equals(file.location(5))); expect(span.end, equals(file.location(10))); }); test("end defaults to the end of the file", () { - var span = file.span(5); + final span = file.span(5); expect(span.start, equals(file.location(5))); expect(span.end, equals(file.location(file.length))); }); @@ -238,8 +238,8 @@ zip zap zop""", url: "bar.dart").span(10, 11); }); test("pointSpan() returns a FileSpan", () { - var location = file.location(15); - var span = location.pointSpan(); + final location = file.location(15); + final span = location.pointSpan(); expect(span, isA()); expect(span.start, equals(location)); expect(span.end, equals(location)); @@ -258,26 +258,26 @@ zip zap zop""", url: "bar.dart").span(10, 11); group("context", () { test("contains the span's text", () { - var span = file.span(8, 15); + final span = file.span(8, 15); expect(span.context.contains(span.text), isTrue); expect(span.context, equals('foo bar baz\nwhiz bang boom\n')); }); test("contains the previous line for a point span at the end of a line", () { - var span = file.span(25, 25); + final span = file.span(25, 25); expect(span.context, equals('whiz bang boom\n')); }); test("contains the next line for a point span at the beginning of a line", () { - var span = file.span(12, 12); + final span = file.span(12, 12); expect(span.context, equals('whiz bang boom\n')); }); group("for a point span at the end of a file", () { test("without a newline, contains the last line", () { - var span = file.span(file.length, file.length); + final span = file.span(file.length, file.length); expect(span.context, equals('zip zap zop')); }); @@ -288,57 +288,57 @@ whiz bang boom zip zap zop """, url: "foo.dart"); - var span = file.span(file.length, file.length); + final span = file.span(file.length, file.length); expect(span.context, isEmpty); }); }); }); group("union()", () { - var span; + FileSpan span; setUp(() { span = file.span(5, 12); }); test("works with a preceding adjacent span", () { - var other = file.span(0, 5); - var result = span.union(other); + final other = file.span(0, 5); + final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); expect(result.text, equals("foo bar baz\n")); }); test("works with a preceding overlapping span", () { - var other = file.span(0, 8); - var result = span.union(other); + final other = file.span(0, 8); + final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); expect(result.text, equals("foo bar baz\n")); }); test("works with a following adjacent span", () { - var other = file.span(12, 16); - var result = span.union(other); + final other = file.span(12, 16); + final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); expect(result.text, equals("ar baz\nwhiz")); }); test("works with a following overlapping span", () { - var other = file.span(9, 16); - var result = span.union(other); + final other = file.span(9, 16); + final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); expect(result.text, equals("ar baz\nwhiz")); }); test("works with an internal overlapping span", () { - var other = file.span(7, 10); + final other = file.span(7, 10); expect(span.union(other), equals(span)); }); test("works with an external overlapping span", () { - var other = file.span(0, 16); + final other = file.span(0, 16); expect(span.union(other), equals(other)); }); @@ -347,9 +347,9 @@ zip zap zop }); test("returns a base SourceSpan for a SourceSpan input", () { - var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); - var result = span.union(other); + final result = span.union(other); expect(result, isNot(isA())); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); @@ -358,50 +358,50 @@ zip zap zop }); group("expand()", () { - var span; + FileSpan span; setUp(() { span = file.span(5, 12); }); test("works with a preceding nonadjacent span", () { - var other = file.span(0, 3); - var result = span.expand(other); + final other = file.span(0, 3); + final result = span.expand(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); expect(result.text, equals("foo bar baz\n")); }); test("works with a preceding overlapping span", () { - var other = file.span(0, 8); - var result = span.expand(other); + final other = file.span(0, 8); + final result = span.expand(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); expect(result.text, equals("foo bar baz\n")); }); test("works with a following nonadjacent span", () { - var other = file.span(14, 16); - var result = span.expand(other); + final other = file.span(14, 16); + final result = span.expand(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); expect(result.text, equals("ar baz\nwhiz")); }); test("works with a following overlapping span", () { - var other = file.span(9, 16); - var result = span.expand(other); + final other = file.span(9, 16); + final result = span.expand(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); expect(result.text, equals("ar baz\nwhiz")); }); test("works with an internal overlapping span", () { - var other = file.span(7, 10); + final other = file.span(7, 10); expect(span.expand(other), equals(span)); }); test("works with an external overlapping span", () { - var other = file.span(0, 16); + final other = file.span(0, 16); expect(span.expand(other), equals(other)); }); }); diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index c2156803c..33719bc4a 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -2,13 +2,14 @@ // 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:term_glyph/term_glyph.dart' as glyph; -import 'package:test/test.dart'; +// ignore_for_file: prefer_interpolation_to_compose_strings import 'package:source_span/source_span.dart'; import 'package:source_span/src/colors.dart' as colors; +import 'package:term_glyph/term_glyph.dart' as glyph; +import 'package:test/test.dart'; -main() { +void main() { bool oldAscii; setUpAll(() { oldAscii = glyph.ascii; @@ -19,7 +20,7 @@ main() { glyph.ascii = oldAscii; }); - var file; + SourceFile file; setUp(() { file = SourceFile.fromString(""" foo bar baz @@ -37,7 +38,7 @@ zip zap zop }); test("gracefully handles a missing source URL", () { - var span = SourceFile.fromString("foo bar baz").span(4, 7); + final span = SourceFile.fromString("foo bar baz").span(4, 7); expect(span.highlight(), equals(""" , 1 | foo bar baz @@ -122,7 +123,7 @@ zip zap zop }); test("on an empty line", () { - var file = SourceFile.fromString("foo\n\nbar"); + final file = SourceFile.fromString("foo\n\nbar"); expect(file.location(4).pointSpan().highlight(), equals(""" , 2 | @@ -193,7 +194,7 @@ zip zap zop }); test("highlights the full first line even if it's indented", () { - var file = SourceFile.fromString(""" + final file = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop @@ -209,7 +210,7 @@ zip zap zop }); test("highlights the full first line if it's empty", () { - var file = SourceFile.fromString(""" + final file = SourceFile.fromString(""" foo bar @@ -241,7 +242,7 @@ bar }); test("highlights the full last line with a trailing Windows newline", () { - var file = SourceFile.fromString(""" + final file = SourceFile.fromString(""" foo bar baz\r whiz bang boom\r zip zap zop\r @@ -268,7 +269,7 @@ zip zap zop\r test( "highlights the full last line at the end of the file with no trailing " "newline", () { - var file = SourceFile.fromString(""" + final file = SourceFile.fromString(""" foo bar baz whiz bang boom zip zap zop"""); @@ -283,7 +284,7 @@ zip zap zop"""); }); test("highlights the full last line if it's empty", () { - var file = SourceFile.fromString(""" + final file = SourceFile.fromString(""" foo bar @@ -297,7 +298,7 @@ bar }); test("highlights multiple empty lines", () { - var file = SourceFile.fromString("foo\n\n\n\nbar"); + final file = SourceFile.fromString("foo\n\n\n\nbar"); expect(file.span(4, 7).highlight(), equals(""" , 2 | / @@ -308,7 +309,7 @@ bar // Regression test for #32 test("highlights the end of a line and an empty line", () { - var file = SourceFile.fromString("foo\n\n"); + final file = SourceFile.fromString("foo\n\n"); expect(file.span(3, 5).highlight(), equals(""" , 1 | foo @@ -321,7 +322,7 @@ bar group("prints tabs as spaces", () { group("in a single-line span", () { test("before the highlighted section", () { - var span = SourceFile.fromString("foo\tbar baz").span(4, 7); + final span = SourceFile.fromString("foo\tbar baz").span(4, 7); expect(span.highlight(), equals(""" , @@ -331,7 +332,7 @@ bar }); test("within the highlighted section", () { - var span = SourceFile.fromString("foo bar\tbaz bang").span(4, 11); + final span = SourceFile.fromString("foo bar\tbaz bang").span(4, 11); expect(span.highlight(), equals(""" , @@ -341,7 +342,7 @@ bar }); test("after the highlighted section", () { - var span = SourceFile.fromString("foo bar\tbaz").span(4, 7); + final span = SourceFile.fromString("foo bar\tbaz").span(4, 7); expect(span.highlight(), equals(""" , @@ -353,7 +354,7 @@ bar group("in a multi-line span", () { test("before the highlighted section", () { - var span = SourceFile.fromString(""" + final span = SourceFile.fromString(""" foo\tbar baz whiz bang boom """).span(4, 21); @@ -368,7 +369,7 @@ whiz bang boom }); test("within the first highlighted line", () { - var span = SourceFile.fromString(""" + final span = SourceFile.fromString(""" foo bar\tbaz whiz bang boom """).span(4, 21); @@ -383,7 +384,7 @@ whiz bang boom }); test("within a middle highlighted line", () { - var span = SourceFile.fromString(""" + final span = SourceFile.fromString(""" foo bar baz whiz\tbang boom zip zap zop @@ -400,7 +401,7 @@ zip zap zop }); test("within the last highlighted line", () { - var span = SourceFile.fromString(""" + final span = SourceFile.fromString(""" foo bar baz whiz\tbang boom """).span(4, 21); @@ -415,7 +416,7 @@ whiz\tbang boom }); test("after the highlighted section", () { - var span = SourceFile.fromString(""" + final span = SourceFile.fromString(""" foo bar baz whiz bang\tboom """).span(4, 21); @@ -433,7 +434,7 @@ whiz bang\tboom group("supports lines of preceding and following context for a span", () { test("within a single line", () { - var span = SourceSpanWithContext( + final span = SourceSpanWithContext( SourceLocation(20, line: 2, column: 5, sourceUrl: "foo.dart"), SourceLocation(27, line: 2, column: 12, sourceUrl: "foo.dart"), "foo bar", @@ -450,7 +451,7 @@ whiz bang\tboom }); test("covering a full line", () { - var span = SourceSpanWithContext( + final span = SourceSpanWithContext( SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), SourceLocation(33, line: 3, column: 0, sourceUrl: "foo.dart"), "-----foo bar-----\n", @@ -467,7 +468,7 @@ whiz bang\tboom }); test("covering multiple full lines", () { - var span = SourceSpanWithContext( + final span = SourceSpanWithContext( SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), SourceLocation(23, line: 4, column: 0, sourceUrl: "foo.dart"), "foo\nbar\n", @@ -495,38 +496,38 @@ whiz bang\tboom test("colorizes if color is true", () { expect(file.span(4, 7).highlight(color: true), equals(""" -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} foo ${colors.RED}bar${colors.NONE} baz -${colors.BLUE} |${colors.NONE} ${colors.RED}^^^${colors.NONE} -${colors.BLUE} '${colors.NONE}""")); +${colors.blue} ,${colors.none} +${colors.blue}1 |${colors.none} foo ${colors.red}bar${colors.none} baz +${colors.blue} |${colors.none} ${colors.red}^^^${colors.none} +${colors.blue} '${colors.none}""")); }); test("uses the given color if it's passed", () { - expect(file.span(4, 7).highlight(color: colors.YELLOW), equals(""" -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} foo ${colors.YELLOW}bar${colors.NONE} baz -${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^${colors.NONE} -${colors.BLUE} '${colors.NONE}""")); + expect(file.span(4, 7).highlight(color: colors.yellow), equals(""" +${colors.blue} ,${colors.none} +${colors.blue}1 |${colors.none} foo ${colors.yellow}bar${colors.none} baz +${colors.blue} |${colors.none} ${colors.yellow}^^^${colors.none} +${colors.blue} '${colors.none}""")); }); test("colorizes a multiline span", () { expect(file.span(4, 34).highlight(color: true), equals(""" -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} foo ${colors.RED}bar baz${colors.NONE} -${colors.BLUE} |${colors.NONE} ${colors.RED},-----^${colors.NONE} -${colors.BLUE}2 |${colors.NONE} ${colors.RED}| whiz bang boom${colors.NONE} -${colors.BLUE}3 |${colors.NONE} ${colors.RED}| zip zap${colors.NONE} zop -${colors.BLUE} |${colors.NONE} ${colors.RED}'-------^${colors.NONE} -${colors.BLUE} '${colors.NONE}""")); +${colors.blue} ,${colors.none} +${colors.blue}1 |${colors.none} foo ${colors.red}bar baz${colors.none} +${colors.blue} |${colors.none} ${colors.red},-----^${colors.none} +${colors.blue}2 |${colors.none} ${colors.red}| whiz bang boom${colors.none} +${colors.blue}3 |${colors.none} ${colors.red}| zip zap${colors.none} zop +${colors.blue} |${colors.none} ${colors.red}'-------^${colors.none} +${colors.blue} '${colors.none}""")); }); test("colorizes a multiline span that highlights full lines", () { expect(file.span(0, 39).highlight(color: true), equals(""" -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} ${colors.RED}/ foo bar baz${colors.NONE} -${colors.BLUE}2 |${colors.NONE} ${colors.RED}| whiz bang boom${colors.NONE} -${colors.BLUE}3 |${colors.NONE} ${colors.RED}\\ zip zap zop${colors.NONE} -${colors.BLUE} '${colors.NONE}""")); +${colors.blue} ,${colors.none} +${colors.blue}1 |${colors.none} ${colors.red}/ foo bar baz${colors.none} +${colors.blue}2 |${colors.none} ${colors.red}| whiz bang boom${colors.none} +${colors.blue}3 |${colors.none} ${colors.red}\\ zip zap zop${colors.none} +${colors.blue} '${colors.none}""")); }); }); diff --git a/pkgs/source_span/test/location_test.dart b/pkgs/source_span/test/location_test.dart index 90329362f..c0e9c0786 100644 --- a/pkgs/source_span/test/location_test.dart +++ b/pkgs/source_span/test/location_test.dart @@ -2,11 +2,11 @@ // 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:test/test.dart'; import 'package:source_span/source_span.dart'; +import 'package:test/test.dart'; -main() { - var location; +void main() { + SourceLocation location; setUp(() { location = SourceLocation(15, line: 2, column: 6, sourceUrl: "foo.dart"); }); @@ -48,19 +48,19 @@ main() { }); test('gracefully handles a missing source URL', () { - var location = SourceLocation(15, line: 2, column: 6); + final location = SourceLocation(15, line: 2, column: 6); expect(location.toolString, equals('unknown source:3:7')); }); }); test("distance returns the absolute distance between locations", () { - var other = SourceLocation(10, sourceUrl: "foo.dart"); + final other = SourceLocation(10, sourceUrl: "foo.dart"); expect(location.distance(other), equals(5)); expect(other.distance(location), equals(5)); }); test("pointSpan returns an empty span at location", () { - var span = location.pointSpan(); + final span = location.pointSpan(); expect(span.start, equals(location)); expect(span.end, equals(location)); expect(span.text, isEmpty); @@ -68,7 +68,7 @@ main() { group("compareTo()", () { test("sorts by offset", () { - var other = SourceLocation(20, sourceUrl: "foo.dart"); + final other = SourceLocation(20, sourceUrl: "foo.dart"); expect(location.compareTo(other), lessThan(0)); expect(other.compareTo(location), greaterThan(0)); }); @@ -80,17 +80,17 @@ main() { group("equality", () { test("two locations with the same offset and source are equal", () { - var other = SourceLocation(15, sourceUrl: "foo.dart"); + final other = SourceLocation(15, sourceUrl: "foo.dart"); expect(location, equals(other)); }); test("a different offset isn't equal", () { - var other = SourceLocation(10, sourceUrl: "foo.dart"); + final other = SourceLocation(10, sourceUrl: "foo.dart"); expect(location, isNot(equals(other))); }); test("a different source isn't equal", () { - var other = SourceLocation(15, sourceUrl: "bar.dart"); + final other = SourceLocation(15, sourceUrl: "bar.dart"); expect(location, isNot(equals(other))); }); }); diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 6a18b4293..d53e1e0d4 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -8,7 +8,7 @@ import 'package:term_glyph/term_glyph.dart' as glyph; import 'package:source_span/source_span.dart'; import 'package:source_span/src/colors.dart' as colors; -main() { +void main() { bool oldAscii; setUpAll(() { oldAscii = glyph.ascii; @@ -19,7 +19,7 @@ main() { glyph.ascii = oldAscii; }); - var span; + SourceSpan span; setUp(() { span = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); @@ -28,42 +28,42 @@ main() { group('errors', () { group('for new SourceSpan()', () { test('source URLs must match', () { - var start = SourceLocation(0, sourceUrl: "foo.dart"); - var end = SourceLocation(1, sourceUrl: "bar.dart"); + final start = SourceLocation(0, sourceUrl: "foo.dart"); + final end = SourceLocation(1, sourceUrl: "bar.dart"); expect(() => SourceSpan(start, end, "_"), throwsArgumentError); }); test('end must come after start', () { - var start = SourceLocation(1); - var end = SourceLocation(0); + final start = SourceLocation(1); + final end = SourceLocation(0); expect(() => SourceSpan(start, end, "_"), throwsArgumentError); }); test('text must be the right length', () { - var start = SourceLocation(0); - var end = SourceLocation(1); + final start = SourceLocation(0); + final end = SourceLocation(1); expect(() => SourceSpan(start, end, "abc"), throwsArgumentError); }); }); group('for new SourceSpanWithContext()', () { test('context must contain text', () { - var start = SourceLocation(2); - var end = SourceLocation(5); + final start = SourceLocation(2); + final end = SourceLocation(5); expect(() => SourceSpanWithContext(start, end, "abc", "--axc--"), throwsArgumentError); }); test('text starts at start.column in context', () { - var start = SourceLocation(3); - var end = SourceLocation(5); + final start = SourceLocation(3); + final end = SourceLocation(5); expect(() => SourceSpanWithContext(start, end, "abc", "--abc--"), throwsArgumentError); }); test('text starts at start.column of line in multi-line context', () { - var start = SourceLocation(4, line: 55, column: 3); - var end = SourceLocation(7, line: 55, column: 6); + final start = SourceLocation(4, line: 55, column: 3); + final end = SourceLocation(7, line: 55, column: 6); expect(() => SourceSpanWithContext(start, end, "abc", "\n--abc--"), throwsArgumentError); expect(() => SourceSpanWithContext(start, end, "abc", "\n----abc--"), @@ -77,10 +77,10 @@ main() { }); test('text can occur multiple times in context', () { - var start1 = SourceLocation(4, line: 55, column: 2); - var end1 = SourceLocation(7, line: 55, column: 5); - var start2 = SourceLocation(4, line: 55, column: 8); - var end2 = SourceLocation(7, line: 55, column: 11); + final start1 = SourceLocation(4, line: 55, column: 2); + final end1 = SourceLocation(7, line: 55, column: 5); + final start2 = SourceLocation(4, line: 55, column: 8); + final end2 = SourceLocation(7, line: 55, column: 11); SourceSpanWithContext(start1, end1, "abc", "--abc---abc--\n"); SourceSpanWithContext(start1, end1, "abc", "--abc--abc--\n"); SourceSpanWithContext(start2, end2, "abc", "--abc---abc--\n"); @@ -96,14 +96,14 @@ main() { group('for union()', () { test('source URLs must match', () { - var other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), + final other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), SourceLocation(13, sourceUrl: "bar.dart"), "_"); expect(() => span.union(other), throwsArgumentError); }); test('spans may not be disjoint', () { - var other = SourceSpan(SourceLocation(13, sourceUrl: 'foo.dart'), + final other = SourceSpan(SourceLocation(13, sourceUrl: 'foo.dart'), SourceLocation(14, sourceUrl: 'foo.dart'), "_"); expect(() => span.union(other), throwsArgumentError); @@ -111,7 +111,7 @@ main() { }); test('for compareTo() source URLs must match', () { - var other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), + final other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), SourceLocation(13, sourceUrl: "bar.dart"), "_"); expect(() => span.compareTo(other), throwsArgumentError); @@ -127,54 +127,54 @@ main() { group("union()", () { test("works with a preceding adjacent span", () { - var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); - var result = span.union(other); + final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); expect(result.text, equals("hey, foo bar")); }); test("works with a preceding overlapping span", () { - var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), SourceLocation(8, sourceUrl: "foo.dart"), "hey, foo"); - var result = span.union(other); + final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); expect(result.text, equals("hey, foo bar")); }); test("works with a following adjacent span", () { - var other = SourceSpan(SourceLocation(12, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(12, sourceUrl: "foo.dart"), SourceLocation(16, sourceUrl: "foo.dart"), " baz"); - var result = span.union(other); + final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); expect(result.text, equals("foo bar baz")); }); test("works with a following overlapping span", () { - var other = SourceSpan(SourceLocation(9, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(9, sourceUrl: "foo.dart"), SourceLocation(16, sourceUrl: "foo.dart"), "bar baz"); - var result = span.union(other); + final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); expect(result.text, equals("foo bar baz")); }); test("works with an internal overlapping span", () { - var other = SourceSpan(SourceLocation(7, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(7, sourceUrl: "foo.dart"), SourceLocation(10, sourceUrl: "foo.dart"), "o b"); expect(span.union(other), equals(span)); }); test("works with an external overlapping span", () { - var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), SourceLocation(16, sourceUrl: "foo.dart"), "hey, foo bar baz"); expect(span.union(other), equals(other)); @@ -192,7 +192,7 @@ line 1, column 6 of foo.dart: oh no }); test("gracefully handles a missing source URL", () { - var span = SourceSpan(SourceLocation(5), SourceLocation(12), "foo bar"); + final span = SourceSpan(SourceLocation(5), SourceLocation(12), "foo bar"); expect(span.message("oh no"), equalsIgnoringWhitespace(""" line 1, column 6: oh no @@ -203,7 +203,7 @@ line 1, column 6: oh no }); test("gracefully handles empty text", () { - var span = SourceSpan(SourceLocation(5), SourceLocation(5), ""); + final span = SourceSpan(SourceLocation(5), SourceLocation(5), ""); expect(span.message("oh no"), equals("line 1, column 6: oh no")); }); @@ -220,40 +220,40 @@ line 1, column 6 of foo.dart: oh no test("colorizes if color is true", () { expect(span.message("oh no", color: true), equals(""" line 1, column 6 of foo.dart: oh no -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} ${colors.RED}foo bar${colors.NONE} -${colors.BLUE} |${colors.NONE} ${colors.RED}^^^^^^^${colors.NONE} -${colors.BLUE} '${colors.NONE}""")); +${colors.blue} ,${colors.none} +${colors.blue}1 |${colors.none} ${colors.red}foo bar${colors.none} +${colors.blue} |${colors.none} ${colors.red}^^^^^^^${colors.none} +${colors.blue} '${colors.none}""")); }); test("uses the given color if it's passed", () { - expect(span.message("oh no", color: colors.YELLOW), equals(""" + expect(span.message("oh no", color: colors.yellow), equals(""" line 1, column 6 of foo.dart: oh no -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} ${colors.YELLOW}foo bar${colors.NONE} -${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^^^^^${colors.NONE} -${colors.BLUE} '${colors.NONE}""")); +${colors.blue} ,${colors.none} +${colors.blue}1 |${colors.none} ${colors.yellow}foo bar${colors.none} +${colors.blue} |${colors.none} ${colors.yellow}^^^^^^^${colors.none} +${colors.blue} '${colors.none}""")); }); test("with context, underlines the right column", () { - var spanWithContext = SourceSpanWithContext( + final spanWithContext = SourceSpanWithContext( SourceLocation(5, sourceUrl: "foo.dart"), SourceLocation(12, sourceUrl: "foo.dart"), "foo bar", "-----foo bar-----"); - expect(spanWithContext.message("oh no", color: colors.YELLOW), equals(""" + expect(spanWithContext.message("oh no", color: colors.yellow), equals(""" line 1, column 6 of foo.dart: oh no -${colors.BLUE} ,${colors.NONE} -${colors.BLUE}1 |${colors.NONE} -----${colors.YELLOW}foo bar${colors.NONE}----- -${colors.BLUE} |${colors.NONE} ${colors.YELLOW}^^^^^^^${colors.NONE} -${colors.BLUE} '${colors.NONE}""")); +${colors.blue} ,${colors.none} +${colors.blue}1 |${colors.none} -----${colors.yellow}foo bar${colors.none}----- +${colors.blue} |${colors.none} ${colors.yellow}^^^^^^^${colors.none} +${colors.blue} '${colors.none}""")); }); }); group("compareTo()", () { test("sorts by start location first", () { - var other = SourceSpan(SourceLocation(6, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(6, sourceUrl: "foo.dart"), SourceLocation(14, sourceUrl: "foo.dart"), "oo bar b"); expect(span.compareTo(other), lessThan(0)); @@ -261,7 +261,7 @@ ${colors.BLUE} '${colors.NONE}""")); }); test("sorts by length second", () { - var other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), SourceLocation(14, sourceUrl: "foo.dart"), "foo bar b"); expect(span.compareTo(other), lessThan(0)); @@ -275,28 +275,28 @@ ${colors.BLUE} '${colors.NONE}""")); group("equality", () { test("two spans with the same locations are equal", () { - var other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); expect(span, equals(other)); }); test("a different start isn't equal", () { - var other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), SourceLocation(12, sourceUrl: "foo.dart"), "hey, foo bar"); expect(span, isNot(equals(other))); }); test("a different end isn't equal", () { - var other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), + final other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), SourceLocation(16, sourceUrl: "foo.dart"), "foo bar baz"); expect(span, isNot(equals(other))); }); test("a different source URL isn't equal", () { - var other = SourceSpan(SourceLocation(5, sourceUrl: "bar.dart"), + final other = SourceSpan(SourceLocation(5, sourceUrl: "bar.dart"), SourceLocation(12, sourceUrl: "bar.dart"), "foo bar"); expect(span, isNot(equals(other))); diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index a8146e33b..a4a372eec 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -5,18 +5,18 @@ import 'package:test/test.dart'; import 'package:source_span/src/utils.dart'; -main() { +void main() { group('find line start', () { test('skip entries in wrong column', () { - var context = '0_bb\n1_bbb\n2b____\n3bbb\n'; - var index = findLineStart(context, 'b', 1); + final context = '0_bb\n1_bbb\n2b____\n3bbb\n'; + 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', () { - var context = '0123\n56789\nabcdefgh\n'; - var index = findLineStart(context, '', 5); + final context = '0123\n56789\nabcdefgh\n'; + final index = findLineStart(context, '', 5); expect(index, 5); expect(context[index], '5'); }); @@ -33,25 +33,25 @@ main() { }); test('empty text in empty context', () { - var index = findLineStart('', '', 0); + final index = findLineStart('', '', 0); expect(index, 0); }); test('found on the first line', () { - var context = '0\n2\n45\n'; - var index = findLineStart(context, '0', 0); + final context = '0\n2\n45\n'; + final index = findLineStart(context, '0', 0); expect(index, 0); }); test('finds text that starts with a newline', () { - var context = '0\n2\n45\n'; - var index = findLineStart(context, '\n2', 1); + final context = '0\n2\n45\n'; + final index = findLineStart(context, '\n2', 1); expect(index, 0); }); test('not found', () { - var context = '0\n2\n45\n'; - var index = findLineStart(context, '0', 1); + final context = '0\n2\n45\n'; + final index = findLineStart(context, '0', 1); expect(index, isNull); }); }); From 35ff0992f8092ef0336947796e514f2a34a655de Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 14 Nov 2019 11:02:45 -0800 Subject: [PATCH 311/657] Revert "Be more efficient with String.fromCharCodes (dart-lang/source_span#44)" (dart-lang/source_span#46) This reverts commit ff838908bd75a6b3c1d8cebdb42b7b96f06e9c42. This caused an unknown issue in rare cases with the test package. --- pkgs/source_span/lib/src/file.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 97a2f6534..717a4d432 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -214,7 +214,7 @@ class SourceFile { /// /// If [end] isn't passed, it defaults to the end of the file. String getText(int start, [int end]) => - String.fromCharCodes(_decodedChars, start, end); + String.fromCharCodes(_decodedChars.sublist(start, end)); } /// A [SourceLocation] within a [SourceFile]. From be210223a8cd9a4ba808cbb85456cd83fea0044b Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 14 Nov 2019 13:23:26 -0800 Subject: [PATCH 312/657] Enforce and fix prefer_single_quotes (dart-lang/source_span#47) We will soon be enforcing this with `package:pedantic`. --- pkgs/source_span/analysis_options.yaml | 2 +- pkgs/source_span/lib/src/file.dart | 50 ++--- pkgs/source_span/lib/src/location.dart | 12 +- pkgs/source_span/lib/src/location_mixin.dart | 6 +- pkgs/source_span/lib/src/span_mixin.dart | 6 +- pkgs/source_span/test/file_test.dart | 210 +++++++++--------- pkgs/source_span/test/highlight_test.dart | 212 +++++++++---------- pkgs/source_span/test/span_test.dart | 176 +++++++-------- 8 files changed, 337 insertions(+), 337 deletions(-) diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index f28d5a1f1..929d6fa97 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -67,7 +67,7 @@ linter: - prefer_is_empty - prefer_is_not_empty - prefer_null_aware_operators - #- prefer_single_quotes + - prefer_single_quotes - prefer_typing_uninitialized_variables - recursive_getters - slash_for_doc_comments diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 717a4d432..a03a875a5 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -52,7 +52,7 @@ class SourceFile { /// This constructor is deprecated. /// /// Use [new SourceFile.fromString] instead. - @Deprecated("Will be removed in 2.0.0") + @Deprecated('Will be removed in 2.0.0') SourceFile(String text, {url}) : this.decoded(text.runes, url: url); /// Creates a new source file from [text]. @@ -98,10 +98,10 @@ class SourceFile { /// Gets the 0-based line corresponding to [offset]. int getLine(int offset) { if (offset < 0) { - throw RangeError("Offset may not be negative, was $offset."); + throw RangeError('Offset may not be negative, was $offset.'); } else if (offset > length) { - throw RangeError("Offset $offset must not be greater than the number " - "of characters in the file, $length."); + throw RangeError('Offset $offset must not be greater than the number ' + 'of characters in the file, $length.'); } if (offset < _lineStarts.first) return -1; @@ -163,24 +163,24 @@ class SourceFile { /// is used to more efficiently compute the column. int getColumn(int offset, {int line}) { if (offset < 0) { - throw RangeError("Offset may not be negative, was $offset."); + throw RangeError('Offset may not be negative, was $offset.'); } else if (offset > length) { - throw RangeError("Offset $offset must be not be greater than the " - "number of characters in the file, $length."); + throw RangeError('Offset $offset must be not be greater than the ' + 'number of characters in the file, $length.'); } if (line == null) { line = getLine(offset); } else if (line < 0) { - throw RangeError("Line may not be negative, was $line."); + throw RangeError('Line may not be negative, was $line.'); } else if (line >= lines) { - throw RangeError("Line $line must be less than the number of " - "lines in the file, $lines."); + throw RangeError('Line $line must be less than the number of ' + 'lines in the file, $lines.'); } final lineStart = _lineStarts[line]; if (lineStart > offset) { - throw RangeError("Line $line comes after offset $offset."); + throw RangeError('Line $line comes after offset $offset.'); } return offset - lineStart; @@ -193,12 +193,12 @@ class SourceFile { column ??= 0; if (line < 0) { - throw RangeError("Line may not be negative, was $line."); + throw RangeError('Line may not be negative, was $line.'); } else if (line >= lines) { - throw RangeError("Line $line must be less than the number of " - "lines in the file, $lines."); + throw RangeError('Line $line must be less than the number of ' + 'lines in the file, $lines.'); } else if (column < 0) { - throw RangeError("Column may not be negative, was $column."); + throw RangeError('Column may not be negative, was $column.'); } final result = _lineStarts[line] + column; @@ -241,10 +241,10 @@ class FileLocation extends SourceLocationMixin implements SourceLocation { FileLocation._(this.file, this.offset) { if (offset < 0) { - throw RangeError("Offset may not be negative, was $offset."); + throw RangeError('Offset may not be negative, was $offset.'); } else if (offset > file.length) { - throw RangeError("Offset $offset must not be greater than the number " - "of characters in the file, ${file.length}."); + throw RangeError('Offset $offset must not be greater than the number ' + 'of characters in the file, ${file.length}.'); } } @@ -328,7 +328,7 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { // ...unless this is a point span, in which case we want to include the // next line (or the empty string if this is the end of the file). return endLine == file.lines - 1 - ? "" + ? '' : file.getText( file.getOffset(endLine), file.getOffset(endLine + 1)); } @@ -351,10 +351,10 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { if (_end < _start) { throw ArgumentError('End $_end must come after start $_start.'); } else if (_end > file.length) { - throw RangeError("End $_end must not be greater than the number " - "of characters in the file, ${file.length}."); + throw RangeError('End $_end must not be greater than the number ' + 'of characters in the file, ${file.length}.'); } else if (_start < 0) { - throw RangeError("Start may not be negative, was $_start."); + throw RangeError('Start may not be negative, was $_start.'); } } @@ -375,11 +375,11 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { if (other is _FileSpan) { if (_start > other._end || other._start > _end) { - throw ArgumentError("Spans $this and $other are disjoint."); + throw ArgumentError('Spans $this and $other are disjoint.'); } } else { if (_start > other.end.offset || other.start.offset > _end) { - throw ArgumentError("Spans $this and $other are disjoint."); + throw ArgumentError('Spans $this and $other are disjoint.'); } } @@ -409,7 +409,7 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { @override FileSpan expand(FileSpan other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"$sourceUrl\" and " + throw ArgumentError('Source URLs \"$sourceUrl\" and ' " \"${other.sourceUrl}\" don't match."); } diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index c03c98c51..4f69df5b8 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -48,11 +48,11 @@ class SourceLocation implements Comparable { line = line == null ? 0 : line, column = column == null ? offset : column { if (offset < 0) { - throw RangeError("Offset may not be negative, was $offset."); + throw RangeError('Offset may not be negative, was $offset.'); } else if (line != null && line < 0) { - throw RangeError("Line may not be negative, was $line."); + throw RangeError('Line may not be negative, was $line.'); } else if (column != null && column < 0) { - throw RangeError("Column may not be negative, was $column."); + throw RangeError('Column may not be negative, was $column.'); } } @@ -61,14 +61,14 @@ class SourceLocation implements Comparable { /// This always returns a non-negative value. int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"$sourceUrl\" and " + throw ArgumentError('Source URLs \"$sourceUrl\" and ' "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); } /// Returns a span that covers only a single point: this location. - SourceSpan pointSpan() => SourceSpan(this, this, ""); + SourceSpan pointSpan() => SourceSpan(this, this, ''); /// Compares two locations. /// @@ -76,7 +76,7 @@ class SourceLocation implements Comparable { @override int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"$sourceUrl\" and " + throw ArgumentError('Source URLs \"$sourceUrl\" and ' "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index bd773ae76..bbb73b49a 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -23,19 +23,19 @@ abstract class SourceLocationMixin implements SourceLocation { @override int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"$sourceUrl\" and " + throw ArgumentError('Source URLs \"$sourceUrl\" and ' "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); } @override - SourceSpan pointSpan() => SourceSpan(this, this, ""); + SourceSpan pointSpan() => SourceSpan(this, this, ''); @override int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"$sourceUrl\" and " + throw ArgumentError('Source URLs \"$sourceUrl\" and ' "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 89606114a..55eae94a9 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -31,7 +31,7 @@ abstract class SourceSpanMixin implements SourceSpan { @override SourceSpan union(SourceSpan other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError("Source URLs \"$sourceUrl\" and " + throw ArgumentError('Source URLs \"$sourceUrl\" and ' " \"${other.sourceUrl}\" don't match."); } @@ -41,7 +41,7 @@ abstract class SourceSpanMixin implements SourceSpan { final endSpan = end == this.end ? this : other; if (beginSpan.end.compareTo(endSpan.start) < 0) { - throw ArgumentError("Spans $this and $other are disjoint."); + throw ArgumentError('Spans $this and $other are disjoint.'); } final text = beginSpan.text + @@ -68,7 +68,7 @@ abstract class SourceSpanMixin implements SourceSpan { @override String highlight({color}) { - if (this is! SourceSpanWithContext && length == 0) return ""; + if (this is! SourceSpanWithContext && length == 0) return ''; return Highlighter(this, color: color).highlight(); } diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 2cfe2d4e7..499f8ef41 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -8,236 +8,236 @@ import 'package:source_span/source_span.dart'; void main() { SourceFile file; setUp(() { - file = SourceFile.fromString(""" + file = SourceFile.fromString(''' foo bar baz whiz bang boom -zip zap zop""", url: "foo.dart"); +zip zap zop''', url: 'foo.dart'); }); - group("errors", () { - group("for span()", () { - test("end must come after start", () { + group('errors', () { + group('for span()', () { + test('end must come after start', () { expect(() => file.span(10, 5), throwsArgumentError); }); - test("start may not be negative", () { + test('start may not be negative', () { expect(() => file.span(-1, 5), throwsRangeError); }); - test("end may not be outside the file", () { + test('end may not be outside the file', () { expect(() => file.span(10, 100), throwsRangeError); }); }); - group("for location()", () { - test("offset may not be negative", () { + group('for location()', () { + test('offset may not be negative', () { expect(() => file.location(-1), throwsRangeError); }); - test("offset may not be outside the file", () { + test('offset may not be outside the file', () { expect(() => file.location(100), throwsRangeError); }); }); - group("for getLine()", () { - test("offset may not be negative", () { + group('for getLine()', () { + test('offset may not be negative', () { expect(() => file.getLine(-1), throwsRangeError); }); - test("offset may not be outside the file", () { + test('offset may not be outside the file', () { expect(() => file.getLine(100), throwsRangeError); }); }); - group("for getColumn()", () { - test("offset may not be negative", () { + group('for getColumn()', () { + test('offset may not be negative', () { expect(() => file.getColumn(-1), throwsRangeError); }); - test("offset may not be outside the file", () { + test('offset may not be outside the file', () { expect(() => file.getColumn(100), throwsRangeError); }); - test("line may not be negative", () { + test('line may not be negative', () { expect(() => file.getColumn(1, line: -1), throwsRangeError); }); - test("line may not be outside the file", () { + test('line may not be outside the file', () { expect(() => file.getColumn(1, line: 100), throwsRangeError); }); - test("line must be accurate", () { + test('line must be accurate', () { expect(() => file.getColumn(1, line: 1), throwsRangeError); }); }); - group("getOffset()", () { - test("line may not be negative", () { + group('getOffset()', () { + test('line may not be negative', () { expect(() => file.getOffset(-1), throwsRangeError); }); - test("column may not be negative", () { + test('column may not be negative', () { expect(() => file.getOffset(1, -1), throwsRangeError); }); - test("line may not be outside the file", () { + test('line may not be outside the file', () { expect(() => file.getOffset(100), throwsRangeError); }); - test("column may not be outside the file", () { + test('column may not be outside the file', () { expect(() => file.getOffset(2, 100), throwsRangeError); }); - test("column may not be outside the line", () { + test('column may not be outside the line', () { expect(() => file.getOffset(1, 20), throwsRangeError); }); }); - group("for getText()", () { - test("end must come after start", () { + group('for getText()', () { + test('end must come after start', () { expect(() => file.getText(10, 5), throwsArgumentError); }); - test("start may not be negative", () { + test('start may not be negative', () { expect(() => file.getText(-1, 5), throwsRangeError); }); - test("end may not be outside the file", () { + test('end may not be outside the file', () { expect(() => file.getText(10, 100), throwsRangeError); }); }); - group("for span().union()", () { - test("source URLs must match", () { - final other = SourceSpan(SourceLocation(10), SourceLocation(11), "_"); + group('for span().union()', () { + test('source URLs must match', () { + final other = SourceSpan(SourceLocation(10), SourceLocation(11), '_'); expect(() => file.span(9, 10).union(other), throwsArgumentError); }); - test("spans may not be disjoint", () { + test('spans may not be disjoint', () { expect(() => file.span(9, 10).union(file.span(11, 12)), throwsArgumentError); }); }); - test("for span().expand() source URLs must match", () { - final other = SourceFile.fromString(""" + test('for span().expand() source URLs must match', () { + final other = SourceFile.fromString(''' foo bar baz whiz bang boom -zip zap zop""", url: "bar.dart").span(10, 11); +zip zap zop''', url: 'bar.dart').span(10, 11); expect(() => file.span(9, 10).expand(other), throwsArgumentError); }); }); test('fields work correctly', () { - expect(file.url, equals(Uri.parse("foo.dart"))); + expect(file.url, equals(Uri.parse('foo.dart'))); expect(file.lines, equals(3)); expect(file.length, equals(38)); }); - group("new SourceFile()", () { - test("handles CRLF correctly", () { - expect(SourceFile.fromString("foo\r\nbar").getLine(6), equals(1)); + group('new SourceFile()', () { + test('handles CRLF correctly', () { + expect(SourceFile.fromString('foo\r\nbar').getLine(6), equals(1)); }); - test("handles a lone CR correctly", () { - expect(SourceFile.fromString("foo\rbar").getLine(5), equals(1)); + test('handles a lone CR correctly', () { + expect(SourceFile.fromString('foo\rbar').getLine(5), equals(1)); }); }); - group("span()", () { - test("returns a span between the given offsets", () { + group('span()', () { + test('returns a span between the given offsets', () { final span = file.span(5, 10); expect(span.start, equals(file.location(5))); expect(span.end, equals(file.location(10))); }); - test("end defaults to the end of the file", () { + test('end defaults to the end of the file', () { final span = file.span(5); expect(span.start, equals(file.location(5))); expect(span.end, equals(file.location(file.length))); }); }); - group("getLine()", () { - test("works for a middle character on the line", () { + group('getLine()', () { + test('works for a middle character on the line', () { expect(file.getLine(15), equals(1)); }); - test("works for the first character of a line", () { + test('works for the first character of a line', () { expect(file.getLine(12), equals(1)); }); - test("works for a newline character", () { + test('works for a newline character', () { expect(file.getLine(11), equals(0)); }); - test("works for the last offset", () { + test('works for the last offset', () { expect(file.getLine(file.length), equals(2)); }); }); - group("getColumn()", () { - test("works for a middle character on the line", () { + group('getColumn()', () { + test('works for a middle character on the line', () { expect(file.getColumn(15), equals(3)); }); - test("works for the first character of a line", () { + test('works for the first character of a line', () { expect(file.getColumn(12), equals(0)); }); - test("works for a newline character", () { + test('works for a newline character', () { expect(file.getColumn(11), equals(11)); }); - test("works when line is passed as well", () { + test('works when line is passed as well', () { expect(file.getColumn(12, line: 1), equals(0)); }); - test("works for the last offset", () { + test('works for the last offset', () { expect(file.getColumn(file.length), equals(11)); }); }); - group("getOffset()", () { - test("works for a middle character on the line", () { + group('getOffset()', () { + test('works for a middle character on the line', () { expect(file.getOffset(1, 3), equals(15)); }); - test("works for the first character of a line", () { + test('works for the first character of a line', () { expect(file.getOffset(1), equals(12)); }); - test("works for a newline character", () { + test('works for a newline character', () { expect(file.getOffset(0, 11), equals(11)); }); - test("works for the last offset", () { + test('works for the last offset', () { expect(file.getOffset(2, 11), equals(file.length)); }); }); - group("getText()", () { - test("returns a substring of the source", () { - expect(file.getText(8, 15), equals("baz\nwhi")); + group('getText()', () { + test('returns a substring of the source', () { + expect(file.getText(8, 15), equals('baz\nwhi')); }); - test("end defaults to the end of the file", () { - expect(file.getText(20), equals("g boom\nzip zap zop")); + test('end defaults to the end of the file', () { + expect(file.getText(20), equals('g boom\nzip zap zop')); }); }); - group("FileLocation", () { - test("reports the correct line number", () { + group('FileLocation', () { + test('reports the correct line number', () { expect(file.location(15).line, equals(1)); }); - test("reports the correct column number", () { + test('reports the correct column number', () { expect(file.location(15).column, equals(3)); }); - test("pointSpan() returns a FileSpan", () { + test('pointSpan() returns a FileSpan', () { final location = file.location(15); final span = location.pointSpan(); expect(span, isA()); @@ -247,46 +247,46 @@ zip zap zop""", url: "bar.dart").span(10, 11); }); }); - group("FileSpan", () { - test("text returns a substring of the source", () { - expect(file.span(8, 15).text, equals("baz\nwhi")); + group('FileSpan', () { + test('text returns a substring of the source', () { + expect(file.span(8, 15).text, equals('baz\nwhi')); }); - test("text includes the last char when end is defaulted to EOF", () { - expect(file.span(29).text, equals("p zap zop")); + test('text includes the last char when end is defaulted to EOF', () { + expect(file.span(29).text, equals('p zap zop')); }); - group("context", () { + group('context', () { test("contains the span's text", () { final span = file.span(8, 15); expect(span.context.contains(span.text), isTrue); expect(span.context, equals('foo bar baz\nwhiz bang boom\n')); }); - test("contains the previous line for a point span at the end of a line", + test('contains the previous line for a point span at the end of a line', () { final span = file.span(25, 25); expect(span.context, equals('whiz bang boom\n')); }); - test("contains the next line for a point span at the beginning of a line", + test('contains the next line for a point span at the beginning of a line', () { final span = file.span(12, 12); expect(span.context, equals('whiz bang boom\n')); }); - group("for a point span at the end of a file", () { - test("without a newline, contains the last line", () { + group('for a point span at the end of a file', () { + test('without a newline, contains the last line', () { final span = file.span(file.length, file.length); expect(span.context, equals('zip zap zop')); }); - test("with a newline, contains an empty line", () { - file = SourceFile.fromString(""" + test('with a newline, contains an empty line', () { + file = SourceFile.fromString(''' foo bar baz whiz bang boom zip zap zop -""", url: "foo.dart"); +''', url: 'foo.dart'); final span = file.span(file.length, file.length); expect(span.context, isEmpty); @@ -294,92 +294,92 @@ zip zap zop }); }); - group("union()", () { + group('union()', () { FileSpan span; setUp(() { span = file.span(5, 12); }); - test("works with a preceding adjacent span", () { + test('works with a preceding adjacent span', () { final other = file.span(0, 5); final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); - expect(result.text, equals("foo bar baz\n")); + expect(result.text, equals('foo bar baz\n')); }); - test("works with a preceding overlapping span", () { + test('works with a preceding overlapping span', () { final other = file.span(0, 8); final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); - expect(result.text, equals("foo bar baz\n")); + expect(result.text, equals('foo bar baz\n')); }); - test("works with a following adjacent span", () { + test('works with a following adjacent span', () { final other = file.span(12, 16); final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); - expect(result.text, equals("ar baz\nwhiz")); + expect(result.text, equals('ar baz\nwhiz')); }); - test("works with a following overlapping span", () { + test('works with a following overlapping span', () { final other = file.span(9, 16); final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); - expect(result.text, equals("ar baz\nwhiz")); + expect(result.text, equals('ar baz\nwhiz')); }); - test("works with an internal overlapping span", () { + test('works with an internal overlapping span', () { final other = file.span(7, 10); expect(span.union(other), equals(span)); }); - test("works with an external overlapping span", () { + test('works with an external overlapping span', () { final other = file.span(0, 16); expect(span.union(other), equals(other)); }); - test("returns a FileSpan for a FileSpan input", () { + test('returns a FileSpan for a FileSpan input', () { expect(span.union(file.span(0, 5)), isA()); }); - test("returns a base SourceSpan for a SourceSpan input", () { - final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), - SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); + test('returns a base SourceSpan for a SourceSpan input', () { + final other = SourceSpan(SourceLocation(0, sourceUrl: 'foo.dart'), + SourceLocation(5, sourceUrl: 'foo.dart'), 'hey, '); final result = span.union(other); expect(result, isNot(isA())); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); - expect(result.text, equals("hey, ar baz\n")); + expect(result.text, equals('hey, ar baz\n')); }); }); - group("expand()", () { + group('expand()', () { FileSpan span; setUp(() { span = file.span(5, 12); }); - test("works with a preceding nonadjacent span", () { + test('works with a preceding nonadjacent span', () { final other = file.span(0, 3); final result = span.expand(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); - expect(result.text, equals("foo bar baz\n")); + expect(result.text, equals('foo bar baz\n')); }); - test("works with a preceding overlapping span", () { + test('works with a preceding overlapping span', () { final other = file.span(0, 8); final result = span.expand(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); - expect(result.text, equals("foo bar baz\n")); + expect(result.text, equals('foo bar baz\n')); }); - test("works with a following nonadjacent span", () { + test('works with a following nonadjacent span', () { final other = file.span(14, 16); final result = span.expand(other); expect(result.start, equals(span.start)); diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 33719bc4a..9d95b21ef 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -22,14 +22,14 @@ void main() { SourceFile file; setUp(() { - file = SourceFile.fromString(""" + file = SourceFile.fromString(''' foo bar baz whiz bang boom zip zap zop -"""); +'''); }); - test("points to the span in the source", () { + test('points to the span in the source', () { expect(file.span(4, 7).highlight(), equals(""" , 1 | foo bar baz @@ -37,8 +37,8 @@ zip zap zop '""")); }); - test("gracefully handles a missing source URL", () { - final span = SourceFile.fromString("foo bar baz").span(4, 7); + test('gracefully handles a missing source URL', () { + final span = SourceFile.fromString('foo bar baz').span(4, 7); expect(span.highlight(), equals(""" , 1 | foo bar baz @@ -46,8 +46,8 @@ zip zap zop '""")); }); - group("highlights a point span", () { - test("in the middle of a line", () { + group('highlights a point span', () { + test('in the middle of a line', () { expect(file.location(4).pointSpan().highlight(), equals(""" , 1 | foo bar baz @@ -55,7 +55,7 @@ zip zap zop '""")); }); - test("at the beginning of the file", () { + test('at the beginning of the file', () { expect(file.location(0).pointSpan().highlight(), equals(""" , 1 | foo bar baz @@ -63,7 +63,7 @@ zip zap zop '""")); }); - test("at the beginning of a line", () { + test('at the beginning of a line', () { expect(file.location(12).pointSpan().highlight(), equals(""" , 2 | whiz bang boom @@ -71,7 +71,7 @@ zip zap zop '""")); }); - test("at the end of a line", () { + test('at the end of a line', () { expect(file.location(11).pointSpan().highlight(), equals(""" , 1 | foo bar baz @@ -79,7 +79,7 @@ zip zap zop '""")); }); - test("at the end of the file", () { + test('at the end of the file', () { expect(file.location(38).pointSpan().highlight(), equals(""" , 3 | zip zap zop @@ -87,7 +87,7 @@ zip zap zop '""")); }); - test("after the end of the file", () { + test('after the end of the file', () { expect(file.location(39).pointSpan().highlight(), equals(""" , 4 | @@ -95,8 +95,8 @@ zip zap zop '""")); }); - test("at the end of the file with no trailing newline", () { - file = SourceFile.fromString("zip zap zop"); + test('at the end of the file with no trailing newline', () { + file = SourceFile.fromString('zip zap zop'); expect(file.location(10).pointSpan().highlight(), equals(""" , 1 | zip zap zop @@ -104,8 +104,8 @@ zip zap zop '""")); }); - test("after the end of the file with no trailing newline", () { - file = SourceFile.fromString("zip zap zop"); + test('after the end of the file with no trailing newline', () { + file = SourceFile.fromString('zip zap zop'); expect(file.location(11).pointSpan().highlight(), equals(""" , 1 | zip zap zop @@ -113,8 +113,8 @@ zip zap zop '""")); }); - test("in an empty file", () { - expect(SourceFile.fromString("").location(0).pointSpan().highlight(), + test('in an empty file', () { + expect(SourceFile.fromString('').location(0).pointSpan().highlight(), equals(""" , 1 | @@ -122,8 +122,8 @@ zip zap zop '""")); }); - test("on an empty line", () { - final file = SourceFile.fromString("foo\n\nbar"); + test('on an empty line', () { + final file = SourceFile.fromString('foo\n\nbar'); expect(file.location(4).pointSpan().highlight(), equals(""" , 2 | @@ -132,25 +132,25 @@ zip zap zop }); }); - test("highlights a single-line file without a newline", () { - expect(SourceFile.fromString("foo bar").span(0, 7).highlight(), equals(""" + test('highlights a single-line file without a newline', () { + expect(SourceFile.fromString('foo bar').span(0, 7).highlight(), equals(""" , 1 | foo bar | ^^^^^^^ '""")); }); - test("highlights a single empty line", () { + test('highlights a single empty line', () { expect( - SourceFile.fromString("foo\n\nbar").span(4, 5).highlight(), equals(""" + SourceFile.fromString('foo\n\nbar').span(4, 5).highlight(), equals(""" , 2 | | ^ '""")); }); - group("with a multiline span", () { - test("highlights the middle of the first and last lines", () { + group('with a multiline span', () { + test('highlights the middle of the first and last lines', () { expect(file.span(4, 34).highlight(), equals(""" , 1 | foo bar baz @@ -161,7 +161,7 @@ zip zap zop '""")); }); - test("works when it begins at the end of a line", () { + test('works when it begins at the end of a line', () { expect(file.span(11, 34).highlight(), equals(""" , 1 | foo bar baz @@ -172,7 +172,7 @@ zip zap zop '""")); }); - test("works when it ends at the beginning of a line", () { + test('works when it ends at the beginning of a line', () { expect(file.span(4, 28).highlight(), equals(""" , 1 | foo bar baz @@ -183,7 +183,7 @@ zip zap zop '""")); }); - test("highlights the full first line", () { + test('highlights the full first line', () { expect(file.span(0, 34).highlight(), equals(""" , 1 | / foo bar baz @@ -194,11 +194,11 @@ zip zap zop }); test("highlights the full first line even if it's indented", () { - final file = SourceFile.fromString(""" + final file = SourceFile.fromString(''' foo bar baz whiz bang boom zip zap zop -"""); +'''); expect(file.span(2, 38).highlight(), equals(""" , @@ -210,11 +210,11 @@ zip zap zop }); test("highlights the full first line if it's empty", () { - final file = SourceFile.fromString(""" + final file = SourceFile.fromString(''' foo bar -"""); +'''); expect(file.span(4, 9).highlight(), equals(""" , @@ -223,7 +223,7 @@ bar '""")); }); - test("highlights the full last line", () { + test('highlights the full last line', () { expect(file.span(4, 27).highlight(), equals(""" , 1 | foo bar baz @@ -232,7 +232,7 @@ bar '""")); }); - test("highlights the full last line with no trailing newline", () { + test('highlights the full last line with no trailing newline', () { expect(file.span(4, 26).highlight(), equals(""" , 1 | foo bar baz @@ -241,12 +241,12 @@ bar '""")); }); - test("highlights the full last line with a trailing Windows newline", () { - final file = SourceFile.fromString(""" + test('highlights the full last line with a trailing Windows newline', () { + final file = SourceFile.fromString(''' foo bar baz\r whiz bang boom\r zip zap zop\r -"""); +'''); expect(file.span(4, 29).highlight(), equals(""" , @@ -256,7 +256,7 @@ zip zap zop\r '""")); }); - test("highlights the full last line at the end of the file", () { + test('highlights the full last line at the end of the file', () { expect(file.span(4, 39).highlight(), equals(""" , 1 | foo bar baz @@ -267,12 +267,12 @@ zip zap zop\r }); test( - "highlights the full last line at the end of the file with no trailing " - "newline", () { - final file = SourceFile.fromString(""" + 'highlights the full last line at the end of the file with no trailing ' + 'newline', () { + final file = SourceFile.fromString(''' foo bar baz whiz bang boom -zip zap zop"""); +zip zap zop'''); expect(file.span(4, 38).highlight(), equals(""" , @@ -284,11 +284,11 @@ zip zap zop"""); }); test("highlights the full last line if it's empty", () { - final file = SourceFile.fromString(""" + final file = SourceFile.fromString(''' foo bar -"""); +'''); expect(file.span(0, 5).highlight(), equals(""" , @@ -297,8 +297,8 @@ bar '""")); }); - test("highlights multiple empty lines", () { - final file = SourceFile.fromString("foo\n\n\n\nbar"); + test('highlights multiple empty lines', () { + final file = SourceFile.fromString('foo\n\n\n\nbar'); expect(file.span(4, 7).highlight(), equals(""" , 2 | / @@ -308,8 +308,8 @@ bar }); // Regression test for #32 - test("highlights the end of a line and an empty line", () { - final file = SourceFile.fromString("foo\n\n"); + test('highlights the end of a line and an empty line', () { + final file = SourceFile.fromString('foo\n\n'); expect(file.span(3, 5).highlight(), equals(""" , 1 | foo @@ -319,10 +319,10 @@ bar }); }); - group("prints tabs as spaces", () { - group("in a single-line span", () { - test("before the highlighted section", () { - final span = SourceFile.fromString("foo\tbar baz").span(4, 7); + group('prints tabs as spaces', () { + group('in a single-line span', () { + test('before the highlighted section', () { + final span = SourceFile.fromString('foo\tbar baz').span(4, 7); expect(span.highlight(), equals(""" , @@ -331,8 +331,8 @@ bar '""")); }); - test("within the highlighted section", () { - final span = SourceFile.fromString("foo bar\tbaz bang").span(4, 11); + test('within the highlighted section', () { + final span = SourceFile.fromString('foo bar\tbaz bang').span(4, 11); expect(span.highlight(), equals(""" , @@ -341,8 +341,8 @@ bar '""")); }); - test("after the highlighted section", () { - final span = SourceFile.fromString("foo bar\tbaz").span(4, 7); + test('after the highlighted section', () { + final span = SourceFile.fromString('foo bar\tbaz').span(4, 7); expect(span.highlight(), equals(""" , @@ -352,12 +352,12 @@ bar }); }); - group("in a multi-line span", () { - test("before the highlighted section", () { - final span = SourceFile.fromString(""" + group('in a multi-line span', () { + test('before the highlighted section', () { + final span = SourceFile.fromString(''' foo\tbar baz whiz bang boom -""").span(4, 21); +''').span(4, 21); expect(span.highlight(), equals(""" , @@ -368,11 +368,11 @@ whiz bang boom '""")); }); - test("within the first highlighted line", () { - final span = SourceFile.fromString(""" + test('within the first highlighted line', () { + final span = SourceFile.fromString(''' foo bar\tbaz whiz bang boom -""").span(4, 21); +''').span(4, 21); expect(span.highlight(), equals(""" , @@ -383,12 +383,12 @@ whiz bang boom '""")); }); - test("within a middle highlighted line", () { - final span = SourceFile.fromString(""" + test('within a middle highlighted line', () { + final span = SourceFile.fromString(''' foo bar baz whiz\tbang boom zip zap zop -""").span(4, 34); +''').span(4, 34); expect(span.highlight(), equals(""" , @@ -400,11 +400,11 @@ zip zap zop '""")); }); - test("within the last highlighted line", () { - final span = SourceFile.fromString(""" + test('within the last highlighted line', () { + final span = SourceFile.fromString(''' foo bar baz whiz\tbang boom -""").span(4, 21); +''').span(4, 21); expect(span.highlight(), equals(""" , @@ -415,11 +415,11 @@ whiz\tbang boom '""")); }); - test("after the highlighted section", () { - final span = SourceFile.fromString(""" + test('after the highlighted section', () { + final span = SourceFile.fromString(''' foo bar baz whiz bang\tboom -""").span(4, 21); +''').span(4, 21); expect(span.highlight(), equals(""" , @@ -432,13 +432,13 @@ whiz bang\tboom }); }); - group("supports lines of preceding and following context for a span", () { - test("within a single line", () { + group('supports lines of preceding and following context for a span', () { + test('within a single line', () { final span = SourceSpanWithContext( - SourceLocation(20, line: 2, column: 5, sourceUrl: "foo.dart"), - SourceLocation(27, line: 2, column: 12, sourceUrl: "foo.dart"), - "foo bar", - "previous\nlines\n-----foo bar-----\nfollowing line\n"); + SourceLocation(20, line: 2, column: 5, sourceUrl: 'foo.dart'), + SourceLocation(27, line: 2, column: 12, sourceUrl: 'foo.dart'), + 'foo bar', + 'previous\nlines\n-----foo bar-----\nfollowing line\n'); expect(span.highlight(), equals(""" , @@ -450,12 +450,12 @@ whiz bang\tboom '""")); }); - test("covering a full line", () { + test('covering a full line', () { final span = SourceSpanWithContext( - SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), - SourceLocation(33, line: 3, column: 0, sourceUrl: "foo.dart"), - "-----foo bar-----\n", - "previous\nlines\n-----foo bar-----\nfollowing line\n"); + SourceLocation(15, line: 2, column: 0, sourceUrl: 'foo.dart'), + SourceLocation(33, line: 3, column: 0, sourceUrl: 'foo.dart'), + '-----foo bar-----\n', + 'previous\nlines\n-----foo bar-----\nfollowing line\n'); expect(span.highlight(), equals(""" , @@ -467,12 +467,12 @@ whiz bang\tboom '""")); }); - test("covering multiple full lines", () { + test('covering multiple full lines', () { final span = SourceSpanWithContext( - SourceLocation(15, line: 2, column: 0, sourceUrl: "foo.dart"), - SourceLocation(23, line: 4, column: 0, sourceUrl: "foo.dart"), - "foo\nbar\n", - "previous\nlines\nfoo\nbar\nfollowing line\n"); + SourceLocation(15, line: 2, column: 0, sourceUrl: 'foo.dart'), + SourceLocation(23, line: 4, column: 0, sourceUrl: 'foo.dart'), + 'foo\nbar\n', + 'previous\nlines\nfoo\nbar\nfollowing line\n'); expect(span.highlight(), equals(""" , @@ -485,7 +485,7 @@ whiz bang\tboom }); }); - group("colors", () { + group('colors', () { test("doesn't colorize if color is false", () { expect(file.span(4, 7).highlight(color: false), equals(""" , @@ -494,47 +494,47 @@ whiz bang\tboom '""")); }); - test("colorizes if color is true", () { - expect(file.span(4, 7).highlight(color: true), equals(""" + test('colorizes if color is true', () { + expect(file.span(4, 7).highlight(color: true), equals(''' ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} foo ${colors.red}bar${colors.none} baz ${colors.blue} |${colors.none} ${colors.red}^^^${colors.none} -${colors.blue} '${colors.none}""")); +${colors.blue} '${colors.none}''')); }); test("uses the given color if it's passed", () { - expect(file.span(4, 7).highlight(color: colors.yellow), equals(""" + expect(file.span(4, 7).highlight(color: colors.yellow), equals(''' ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} foo ${colors.yellow}bar${colors.none} baz ${colors.blue} |${colors.none} ${colors.yellow}^^^${colors.none} -${colors.blue} '${colors.none}""")); +${colors.blue} '${colors.none}''')); }); - test("colorizes a multiline span", () { - expect(file.span(4, 34).highlight(color: true), equals(""" + test('colorizes a multiline span', () { + expect(file.span(4, 34).highlight(color: true), equals(''' ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} foo ${colors.red}bar baz${colors.none} ${colors.blue} |${colors.none} ${colors.red},-----^${colors.none} ${colors.blue}2 |${colors.none} ${colors.red}| whiz bang boom${colors.none} ${colors.blue}3 |${colors.none} ${colors.red}| zip zap${colors.none} zop ${colors.blue} |${colors.none} ${colors.red}'-------^${colors.none} -${colors.blue} '${colors.none}""")); +${colors.blue} '${colors.none}''')); }); - test("colorizes a multiline span that highlights full lines", () { - expect(file.span(0, 39).highlight(color: true), equals(""" + test('colorizes a multiline span that highlights full lines', () { + expect(file.span(0, 39).highlight(color: true), equals(''' ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} ${colors.red}/ foo bar baz${colors.none} ${colors.blue}2 |${colors.none} ${colors.red}| whiz bang boom${colors.none} ${colors.blue}3 |${colors.none} ${colors.red}\\ zip zap zop${colors.none} -${colors.blue} '${colors.none}""")); +${colors.blue} '${colors.none}''')); }); }); - group("line numbers have appropriate padding", () { - test("with line number 9", () { + group('line numbers have appropriate padding', () { + test('with line number 9', () { expect( - SourceFile.fromString("\n" * 8 + "foo bar baz\n") + SourceFile.fromString('\n' * 8 + 'foo bar baz\n') .span(8, 11) .highlight(), equals(""" @@ -544,9 +544,9 @@ ${colors.blue} '${colors.none}""")); '""")); }); - test("with line number 10", () { + test('with line number 10', () { expect( - SourceFile.fromString("\n" * 9 + "foo bar baz\n") + SourceFile.fromString('\n' * 9 + 'foo bar baz\n') .span(9, 12) .highlight(), equals(""" diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index d53e1e0d4..1ac9d35ef 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -21,28 +21,28 @@ void main() { SourceSpan span; setUp(() { - span = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), - SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); + span = SourceSpan(SourceLocation(5, sourceUrl: 'foo.dart'), + SourceLocation(12, sourceUrl: 'foo.dart'), 'foo bar'); }); group('errors', () { group('for new SourceSpan()', () { test('source URLs must match', () { - final start = SourceLocation(0, sourceUrl: "foo.dart"); - final end = SourceLocation(1, sourceUrl: "bar.dart"); - expect(() => SourceSpan(start, end, "_"), throwsArgumentError); + final start = SourceLocation(0, sourceUrl: 'foo.dart'); + final end = SourceLocation(1, sourceUrl: 'bar.dart'); + expect(() => SourceSpan(start, end, '_'), throwsArgumentError); }); test('end must come after start', () { final start = SourceLocation(1); final end = SourceLocation(0); - expect(() => SourceSpan(start, end, "_"), throwsArgumentError); + expect(() => SourceSpan(start, end, '_'), throwsArgumentError); }); test('text must be the right length', () { final start = SourceLocation(0); final end = SourceLocation(1); - expect(() => SourceSpan(start, end, "abc"), throwsArgumentError); + expect(() => SourceSpan(start, end, 'abc'), throwsArgumentError); }); }); @@ -50,30 +50,30 @@ void main() { test('context must contain text', () { final start = SourceLocation(2); final end = SourceLocation(5); - expect(() => SourceSpanWithContext(start, end, "abc", "--axc--"), + expect(() => SourceSpanWithContext(start, end, 'abc', '--axc--'), throwsArgumentError); }); test('text starts at start.column in context', () { final start = SourceLocation(3); final end = SourceLocation(5); - expect(() => SourceSpanWithContext(start, end, "abc", "--abc--"), + expect(() => SourceSpanWithContext(start, end, 'abc', '--abc--'), throwsArgumentError); }); test('text starts at start.column of line in multi-line context', () { final start = SourceLocation(4, line: 55, column: 3); final end = SourceLocation(7, line: 55, column: 6); - expect(() => SourceSpanWithContext(start, end, "abc", "\n--abc--"), + expect(() => SourceSpanWithContext(start, end, 'abc', '\n--abc--'), throwsArgumentError); - expect(() => SourceSpanWithContext(start, end, "abc", "\n----abc--"), + expect(() => SourceSpanWithContext(start, end, 'abc', '\n----abc--'), throwsArgumentError); - expect(() => SourceSpanWithContext(start, end, "abc", "\n\n--abc--"), + expect(() => SourceSpanWithContext(start, end, 'abc', '\n\n--abc--'), throwsArgumentError); // However, these are valid: - SourceSpanWithContext(start, end, "abc", "\n---abc--"); - SourceSpanWithContext(start, end, "abc", "\n\n---abc--"); + SourceSpanWithContext(start, end, 'abc', '\n---abc--'); + SourceSpanWithContext(start, end, 'abc', '\n\n---abc--'); }); test('text can occur multiple times in context', () { @@ -81,109 +81,109 @@ void main() { final end1 = SourceLocation(7, line: 55, column: 5); final start2 = SourceLocation(4, line: 55, column: 8); final end2 = SourceLocation(7, line: 55, column: 11); - SourceSpanWithContext(start1, end1, "abc", "--abc---abc--\n"); - SourceSpanWithContext(start1, end1, "abc", "--abc--abc--\n"); - SourceSpanWithContext(start2, end2, "abc", "--abc---abc--\n"); - SourceSpanWithContext(start2, end2, "abc", "---abc--abc--\n"); + SourceSpanWithContext(start1, end1, 'abc', '--abc---abc--\n'); + SourceSpanWithContext(start1, end1, 'abc', '--abc--abc--\n'); + SourceSpanWithContext(start2, end2, 'abc', '--abc---abc--\n'); + SourceSpanWithContext(start2, end2, 'abc', '---abc--abc--\n'); expect( - () => SourceSpanWithContext(start1, end1, "abc", "---abc--abc--\n"), + () => SourceSpanWithContext(start1, end1, 'abc', '---abc--abc--\n'), throwsArgumentError); expect( - () => SourceSpanWithContext(start2, end2, "abc", "--abc--abc--\n"), + () => SourceSpanWithContext(start2, end2, 'abc', '--abc--abc--\n'), throwsArgumentError); }); }); group('for union()', () { test('source URLs must match', () { - final other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), - SourceLocation(13, sourceUrl: "bar.dart"), "_"); + final other = SourceSpan(SourceLocation(12, sourceUrl: 'bar.dart'), + SourceLocation(13, sourceUrl: 'bar.dart'), '_'); expect(() => span.union(other), throwsArgumentError); }); test('spans may not be disjoint', () { final other = SourceSpan(SourceLocation(13, sourceUrl: 'foo.dart'), - SourceLocation(14, sourceUrl: 'foo.dart'), "_"); + SourceLocation(14, sourceUrl: 'foo.dart'), '_'); expect(() => span.union(other), throwsArgumentError); }); }); test('for compareTo() source URLs must match', () { - final other = SourceSpan(SourceLocation(12, sourceUrl: "bar.dart"), - SourceLocation(13, sourceUrl: "bar.dart"), "_"); + final other = SourceSpan(SourceLocation(12, sourceUrl: 'bar.dart'), + SourceLocation(13, sourceUrl: 'bar.dart'), '_'); expect(() => span.compareTo(other), throwsArgumentError); }); }); test('fields work correctly', () { - expect(span.start, equals(SourceLocation(5, sourceUrl: "foo.dart"))); - expect(span.end, equals(SourceLocation(12, sourceUrl: "foo.dart"))); - expect(span.sourceUrl, equals(Uri.parse("foo.dart"))); + expect(span.start, equals(SourceLocation(5, sourceUrl: 'foo.dart'))); + expect(span.end, equals(SourceLocation(12, sourceUrl: 'foo.dart'))); + expect(span.sourceUrl, equals(Uri.parse('foo.dart'))); expect(span.length, equals(7)); }); - group("union()", () { - test("works with a preceding adjacent span", () { - final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), - SourceLocation(5, sourceUrl: "foo.dart"), "hey, "); + group('union()', () { + test('works with a preceding adjacent span', () { + final other = SourceSpan(SourceLocation(0, sourceUrl: 'foo.dart'), + SourceLocation(5, sourceUrl: 'foo.dart'), 'hey, '); final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); - expect(result.text, equals("hey, foo bar")); + expect(result.text, equals('hey, foo bar')); }); - test("works with a preceding overlapping span", () { - final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), - SourceLocation(8, sourceUrl: "foo.dart"), "hey, foo"); + test('works with a preceding overlapping span', () { + final other = SourceSpan(SourceLocation(0, sourceUrl: 'foo.dart'), + SourceLocation(8, sourceUrl: 'foo.dart'), 'hey, foo'); final result = span.union(other); expect(result.start, equals(other.start)); expect(result.end, equals(span.end)); - expect(result.text, equals("hey, foo bar")); + expect(result.text, equals('hey, foo bar')); }); - test("works with a following adjacent span", () { - final other = SourceSpan(SourceLocation(12, sourceUrl: "foo.dart"), - SourceLocation(16, sourceUrl: "foo.dart"), " baz"); + test('works with a following adjacent span', () { + final other = SourceSpan(SourceLocation(12, sourceUrl: 'foo.dart'), + SourceLocation(16, sourceUrl: 'foo.dart'), ' baz'); final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); - expect(result.text, equals("foo bar baz")); + expect(result.text, equals('foo bar baz')); }); - test("works with a following overlapping span", () { - final other = SourceSpan(SourceLocation(9, sourceUrl: "foo.dart"), - SourceLocation(16, sourceUrl: "foo.dart"), "bar baz"); + test('works with a following overlapping span', () { + final other = SourceSpan(SourceLocation(9, sourceUrl: 'foo.dart'), + SourceLocation(16, sourceUrl: 'foo.dart'), 'bar baz'); final result = span.union(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); - expect(result.text, equals("foo bar baz")); + expect(result.text, equals('foo bar baz')); }); - test("works with an internal overlapping span", () { - final other = SourceSpan(SourceLocation(7, sourceUrl: "foo.dart"), - SourceLocation(10, sourceUrl: "foo.dart"), "o b"); + test('works with an internal overlapping span', () { + final other = SourceSpan(SourceLocation(7, sourceUrl: 'foo.dart'), + SourceLocation(10, sourceUrl: 'foo.dart'), 'o b'); expect(span.union(other), equals(span)); }); - test("works with an external overlapping span", () { - final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), - SourceLocation(16, sourceUrl: "foo.dart"), "hey, foo bar baz"); + test('works with an external overlapping span', () { + final other = SourceSpan(SourceLocation(0, sourceUrl: 'foo.dart'), + SourceLocation(16, sourceUrl: 'foo.dart'), 'hey, foo bar baz'); expect(span.union(other), equals(other)); }); }); - group("message()", () { - test("prints the text being described", () { - expect(span.message("oh no"), equals(""" + group('message()', () { + test('prints the text being described', () { + expect(span.message('oh no'), equals(""" line 1, column 6 of foo.dart: oh no , 1 | foo bar @@ -191,10 +191,10 @@ line 1, column 6 of foo.dart: oh no '""")); }); - test("gracefully handles a missing source URL", () { - final span = SourceSpan(SourceLocation(5), SourceLocation(12), "foo bar"); + test('gracefully handles a missing source URL', () { + final span = SourceSpan(SourceLocation(5), SourceLocation(12), 'foo bar'); - expect(span.message("oh no"), equalsIgnoringWhitespace(""" + expect(span.message('oh no'), equalsIgnoringWhitespace(""" line 1, column 6: oh no , 1 | foo bar @@ -202,14 +202,14 @@ line 1, column 6: oh no '""")); }); - test("gracefully handles empty text", () { - final span = SourceSpan(SourceLocation(5), SourceLocation(5), ""); + test('gracefully handles empty text', () { + final span = SourceSpan(SourceLocation(5), SourceLocation(5), ''); - expect(span.message("oh no"), equals("line 1, column 6: oh no")); + expect(span.message('oh no'), equals('line 1, column 6: oh no')); }); test("doesn't colorize if color is false", () { - expect(span.message("oh no", color: false), equals(""" + expect(span.message('oh no', color: false), equals(""" line 1, column 6 of foo.dart: oh no , 1 | foo bar @@ -217,8 +217,8 @@ line 1, column 6 of foo.dart: oh no '""")); }); - test("colorizes if color is true", () { - expect(span.message("oh no", color: true), equals(""" + test('colorizes if color is true', () { + expect(span.message('oh no', color: true), equals(""" line 1, column 6 of foo.dart: oh no ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} ${colors.red}foo bar${colors.none} @@ -227,7 +227,7 @@ ${colors.blue} '${colors.none}""")); }); test("uses the given color if it's passed", () { - expect(span.message("oh no", color: colors.yellow), equals(""" + expect(span.message('oh no', color: colors.yellow), equals(""" line 1, column 6 of foo.dart: oh no ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} ${colors.yellow}foo bar${colors.none} @@ -235,14 +235,14 @@ ${colors.blue} |${colors.none} ${colors.yellow}^^^^^^^${colors.none} ${colors.blue} '${colors.none}""")); }); - test("with context, underlines the right column", () { + test('with context, underlines the right column', () { final spanWithContext = SourceSpanWithContext( - SourceLocation(5, sourceUrl: "foo.dart"), - SourceLocation(12, sourceUrl: "foo.dart"), - "foo bar", - "-----foo bar-----"); + SourceLocation(5, sourceUrl: 'foo.dart'), + SourceLocation(12, sourceUrl: 'foo.dart'), + 'foo bar', + '-----foo bar-----'); - expect(spanWithContext.message("oh no", color: colors.yellow), equals(""" + expect(spanWithContext.message('oh no', color: colors.yellow), equals(""" line 1, column 6 of foo.dart: oh no ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} -----${colors.yellow}foo bar${colors.none}----- @@ -251,53 +251,53 @@ ${colors.blue} '${colors.none}""")); }); }); - group("compareTo()", () { - test("sorts by start location first", () { - final other = SourceSpan(SourceLocation(6, sourceUrl: "foo.dart"), - SourceLocation(14, sourceUrl: "foo.dart"), "oo bar b"); + group('compareTo()', () { + test('sorts by start location first', () { + final other = SourceSpan(SourceLocation(6, sourceUrl: 'foo.dart'), + SourceLocation(14, sourceUrl: 'foo.dart'), 'oo bar b'); expect(span.compareTo(other), lessThan(0)); expect(other.compareTo(span), greaterThan(0)); }); - test("sorts by length second", () { - final other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), - SourceLocation(14, sourceUrl: "foo.dart"), "foo bar b"); + test('sorts by length second', () { + final other = SourceSpan(SourceLocation(5, sourceUrl: 'foo.dart'), + SourceLocation(14, sourceUrl: 'foo.dart'), 'foo bar b'); expect(span.compareTo(other), lessThan(0)); expect(other.compareTo(span), greaterThan(0)); }); - test("considers equal spans equal", () { + test('considers equal spans equal', () { expect(span.compareTo(span), equals(0)); }); }); - group("equality", () { - test("two spans with the same locations are equal", () { - final other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), - SourceLocation(12, sourceUrl: "foo.dart"), "foo bar"); + group('equality', () { + test('two spans with the same locations are equal', () { + final other = SourceSpan(SourceLocation(5, sourceUrl: 'foo.dart'), + SourceLocation(12, sourceUrl: 'foo.dart'), 'foo bar'); expect(span, equals(other)); }); test("a different start isn't equal", () { - final other = SourceSpan(SourceLocation(0, sourceUrl: "foo.dart"), - SourceLocation(12, sourceUrl: "foo.dart"), "hey, foo bar"); + final other = SourceSpan(SourceLocation(0, sourceUrl: 'foo.dart'), + SourceLocation(12, sourceUrl: 'foo.dart'), 'hey, foo bar'); expect(span, isNot(equals(other))); }); test("a different end isn't equal", () { - final other = SourceSpan(SourceLocation(5, sourceUrl: "foo.dart"), - SourceLocation(16, sourceUrl: "foo.dart"), "foo bar baz"); + final other = SourceSpan(SourceLocation(5, sourceUrl: 'foo.dart'), + SourceLocation(16, sourceUrl: 'foo.dart'), 'foo bar baz'); expect(span, isNot(equals(other))); }); test("a different source URL isn't equal", () { - final other = SourceSpan(SourceLocation(5, sourceUrl: "bar.dart"), - SourceLocation(12, sourceUrl: "bar.dart"), "foo bar"); + final other = SourceSpan(SourceLocation(5, sourceUrl: 'bar.dart'), + SourceLocation(12, sourceUrl: 'bar.dart'), 'foo bar'); expect(span, isNot(equals(other))); }); From b41607b1d496b158819cb2141764bc91d24665c0 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Fri, 22 Nov 2019 15:57:23 -0800 Subject: [PATCH 313/657] Fix remaining prefer_single_quotes and fail travis on lints (dart-lang/source_span#48) Missed saving some files in my editor in https://github.com/dart-lang/source_span/pull/47 The travis config was not set to fail for lints. --- pkgs/source_span/.travis.yml | 3 +- pkgs/source_span/lib/source_span.dart | 14 ++--- pkgs/source_span/lib/src/highlighter.dart | 58 ++++++++++---------- pkgs/source_span/lib/src/span.dart | 2 +- pkgs/source_span/lib/src/span_exception.dart | 2 +- pkgs/source_span/lib/src/utils.dart | 2 +- pkgs/source_span/test/file_test.dart | 10 ++-- pkgs/source_span/test/location_test.dart | 28 +++++----- 8 files changed, 60 insertions(+), 59 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index ace10ab04..edb90e60b 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -13,7 +13,8 @@ matrix: - dart: dev dart_task: dartfmt - dart: dev - dart_task: dartanalyzer + dart_task: + dartanalyzer: --fatal-warnings --fatal-infos . # Only building master means that we don't run two builds for each pull request. branches: diff --git a/pkgs/source_span/lib/source_span.dart b/pkgs/source_span/lib/source_span.dart index 6ed10a0e6..534a3a7aa 100644 --- a/pkgs/source_span/lib/source_span.dart +++ b/pkgs/source_span/lib/source_span.dart @@ -2,10 +2,10 @@ // 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. -export "src/file.dart"; -export "src/location.dart"; -export "src/location_mixin.dart"; -export "src/span.dart"; -export "src/span_exception.dart"; -export "src/span_mixin.dart"; -export "src/span_with_context.dart"; +export 'src/file.dart'; +export 'src/location.dart'; +export 'src/location_mixin.dart'; +export 'src/span.dart'; +export 'src/span_exception.dart'; +export 'src/span_mixin.dart'; +export 'src/span_with_context.dart'; diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 94bc85771..f3af75f7e 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -90,7 +90,7 @@ class Highlighter { /// newlines. static SourceSpanWithContext _normalizeNewlines(SourceSpanWithContext span) { final text = span.text; - if (!text.contains("\r\n")) return span; + if (!text.contains('\r\n')) return span; var endOffset = span.end.offset; for (var i = 0; i < text.length - 1; i++) { @@ -105,8 +105,8 @@ class Highlighter { sourceUrl: span.sourceUrl, line: span.end.line, column: span.end.column), - text.replaceAll("\r\n", "\n"), - span.context.replaceAll("\r\n", "\n")); + text.replaceAll('\r\n', '\n'), + span.context.replaceAll('\r\n', '\n')); } /// Normalizes [span] to remove a trailing newline from `span.context`. @@ -115,17 +115,17 @@ class Highlighter { /// the trailing newline used to be. static SourceSpanWithContext _normalizeTrailingNewline( SourceSpanWithContext span) { - if (!span.context.endsWith("\n")) return span; + if (!span.context.endsWith('\n')) return span; // If there's a full blank line on the end of [span.context], it's probably // significant, so we shouldn't trim it. - if (span.text.endsWith("\n\n")) return span; + if (span.text.endsWith('\n\n')) return span; final context = span.context.substring(0, span.context.length - 1); var text = span.text; var start = span.start; var end = span.end; - if (span.text.endsWith("\n") && _isTextAtEndOfContext(span)) { + if (span.text.endsWith('\n') && _isTextAtEndOfContext(span)) { text = span.text.substring(0, span.text.length - 1); end = SourceLocation(span.end.offset - 1, sourceUrl: span.sourceUrl, @@ -163,9 +163,9 @@ class Highlighter { if (text.codeUnitAt(text.length - 1) == $lf) { return text.length == 1 ? 0 - : text.length - text.lastIndexOf("\n", text.length - 2) - 1; + : text.length - text.lastIndexOf('\n', text.length - 2) - 1; } else { - return text.length - text.lastIndexOf("\n") - 1; + return text.length - text.lastIndexOf('\n') - 1; } } @@ -202,11 +202,11 @@ class Highlighter { // [findLineStart] is guaranteed to return a position immediately after a // newline. Including that newline would add an extra empty line to the // end of [lines]. - final lines = context.substring(0, lineStart - 1).split("\n"); + final lines = context.substring(0, lineStart - 1).split('\n'); var lineNumber = _span.start.line - lines.length; for (var line in lines) { _writeSidebar(line: lineNumber); - _buffer.write(" " * _paddingAfterSidebar); + _buffer.write(' ' * _paddingAfterSidebar); _writeText(line); _buffer.writeln(); lineNumber++; @@ -214,7 +214,7 @@ class Highlighter { context = context.substring(lineStart); } - final lines = context.split("\n"); + final lines = context.split('\n'); final lastLineIndex = _span.end.line - _span.start.line; if (lines.last.isEmpty && lines.length > lastLineIndex + 1) { @@ -247,16 +247,16 @@ class Highlighter { // If the span covers the entire first line other than initial whitespace, // don't bother pointing out exactly where it begins. if (_multiline && _isOnlyWhitespace(textBefore)) { - _buffer.write(" "); + _buffer.write(' '); _colorize(() { - _buffer..write(glyph.glyphOrAscii("┌", "/"))..write(" "); + _buffer..write(glyph.glyphOrAscii('┌', '/'))..write(' '); _writeText(line); }); _buffer.writeln(); return; } - _buffer.write(" " * _paddingAfterSidebar); + _buffer.write(' ' * _paddingAfterSidebar); _writeText(textBefore); final textInside = line.substring(startColumn, endColumn); _colorize(() => _writeText(textInside)); @@ -274,17 +274,17 @@ class Highlighter { // single-line span, and a pointer to the beginning of a multi-line span. _writeSidebar(); if (_multiline) { - _buffer.write(" "); + _buffer.write(' '); _colorize(() { _buffer ..write(glyph.topLeftCorner) ..write(glyph.horizontalLine * (startColumn + 1)) - ..write("^"); + ..write('^'); }); } else { - _buffer.write(" " * (startColumn + 1)); + _buffer.write(' ' * (startColumn + 1)); _colorize( - () => _buffer.write("^" * math.max(endColumn - startColumn, 1))); + () => _buffer.write('^' * math.max(endColumn - startColumn, 1))); } _buffer.writeln(); } @@ -298,9 +298,9 @@ class Highlighter { for (var line in lines) { _writeSidebar(line: lineNumber); - _buffer.write(" "); + _buffer.write(' '); _colorize(() { - _buffer..write(glyph.verticalLine)..write(" "); + _buffer..write(glyph.verticalLine)..write(' '); _writeText(line); }); _buffer.writeln(); @@ -320,19 +320,19 @@ class Highlighter { // If the span covers the entire last line, don't bother pointing out // exactly where it ends. if (_multiline && endColumn == line.length) { - _buffer.write(" "); + _buffer.write(' '); _colorize(() { - _buffer..write(glyph.glyphOrAscii("└", "\\"))..write(" "); + _buffer..write(glyph.glyphOrAscii('└', '\\'))..write(' '); _writeText(line); }); _buffer.writeln(); return; } - _buffer.write(" "); + _buffer.write(' '); final textInside = line.substring(0, endColumn); _colorize(() { - _buffer..write(glyph.verticalLine)..write(" "); + _buffer..write(glyph.verticalLine)..write(' '); _writeText(textInside); }); _writeText(line.substring(endColumn)); @@ -346,12 +346,12 @@ class Highlighter { // Write the highlight for the final line, which is an arrow pointing to the // end of the span. _writeSidebar(); - _buffer.write(" "); + _buffer.write(' '); _colorize(() { _buffer ..write(glyph.bottomLeftCorner) ..write(glyph.horizontalLine * endColumn) - ..write("^"); + ..write('^'); }); _buffer.writeln(); } @@ -362,7 +362,7 @@ class Highlighter { var lineNumber = _span.end.line + 1; for (var line in lines) { _writeSidebar(line: lineNumber); - _buffer.write(" " * _paddingAfterSidebar); + _buffer.write(' ' * _paddingAfterSidebar); _writeText(line); _buffer.writeln(); lineNumber++; @@ -374,7 +374,7 @@ class Highlighter { void _writeText(String text) { for (var char in text.codeUnits) { if (char == $tab) { - _buffer.write(" " * _spacesPerTab); + _buffer.write(' ' * _spacesPerTab); } else { _buffer.writeCharCode(char); } @@ -390,7 +390,7 @@ class Highlighter { // numbers to human-friendly 1-indexed line numbers. _buffer.write((line + 1).toString().padRight(_paddingBeforeSidebar)); } else { - _buffer.write(" " * _paddingBeforeSidebar); + _buffer.write(' ' * _paddingBeforeSidebar); } _buffer.write(end ?? glyph.verticalLine); }, color: colors.blue); diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 87ce846b0..48dfae73f 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -96,7 +96,7 @@ class SourceSpanBase extends SourceSpanMixin { SourceSpanBase(this.start, this.end, this.text) { if (end.sourceUrl != start.sourceUrl) { - throw ArgumentError("Source URLs \"${start.sourceUrl}\" and " + throw ArgumentError('Source URLs \"${start.sourceUrl}\" and ' " \"${end.sourceUrl}\" don't match."); } else if (end.offset < start.offset) { throw ArgumentError('End $end must come after start $start.'); diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index 2ce0f1a5a..02c897452 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -30,7 +30,7 @@ class SourceSpanException implements Exception { @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)}'; } } diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 33791debd..63ff01cb8 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -31,7 +31,7 @@ int findLineStart(String context, String text, int column) { if (text.isEmpty) { var beginningOfLine = 0; while (true) { - final index = context.indexOf("\n", beginningOfLine); + final index = context.indexOf('\n', beginningOfLine); if (index == -1) { return context.length - beginningOfLine >= column ? beginningOfLine diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 499f8ef41..91922006d 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -384,23 +384,23 @@ zip zap zop final result = span.expand(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); - expect(result.text, equals("ar baz\nwhiz")); + expect(result.text, equals('ar baz\nwhiz')); }); - test("works with a following overlapping span", () { + test('works with a following overlapping span', () { final other = file.span(9, 16); final result = span.expand(other); expect(result.start, equals(span.start)); expect(result.end, equals(other.end)); - expect(result.text, equals("ar baz\nwhiz")); + expect(result.text, equals('ar baz\nwhiz')); }); - test("works with an internal overlapping span", () { + test('works with an internal overlapping span', () { final other = file.span(7, 10); expect(span.expand(other), equals(span)); }); - test("works with an external overlapping span", () { + test('works with an external overlapping span', () { final other = file.span(0, 16); expect(span.expand(other), equals(other)); }); diff --git a/pkgs/source_span/test/location_test.dart b/pkgs/source_span/test/location_test.dart index c0e9c0786..c22a148c0 100644 --- a/pkgs/source_span/test/location_test.dart +++ b/pkgs/source_span/test/location_test.dart @@ -8,7 +8,7 @@ import 'package:test/test.dart'; void main() { SourceLocation location; setUp(() { - location = SourceLocation(15, line: 2, column: 6, sourceUrl: "foo.dart"); + location = SourceLocation(15, line: 2, column: 6, sourceUrl: 'foo.dart'); }); group('errors', () { @@ -36,7 +36,7 @@ void main() { }); test('fields work correctly', () { - expect(location.sourceUrl, equals(Uri.parse("foo.dart"))); + expect(location.sourceUrl, equals(Uri.parse('foo.dart'))); expect(location.offset, equals(15)); expect(location.line, equals(2)); expect(location.column, equals(6)); @@ -53,44 +53,44 @@ void main() { }); }); - test("distance returns the absolute distance between locations", () { - final other = SourceLocation(10, sourceUrl: "foo.dart"); + test('distance returns the absolute distance between locations', () { + final other = SourceLocation(10, sourceUrl: 'foo.dart'); expect(location.distance(other), equals(5)); expect(other.distance(location), equals(5)); }); - test("pointSpan returns an empty span at location", () { + test('pointSpan returns an empty span at location', () { final span = location.pointSpan(); expect(span.start, equals(location)); expect(span.end, equals(location)); expect(span.text, isEmpty); }); - group("compareTo()", () { - test("sorts by offset", () { - final other = SourceLocation(20, sourceUrl: "foo.dart"); + group('compareTo()', () { + test('sorts by offset', () { + final other = SourceLocation(20, sourceUrl: 'foo.dart'); expect(location.compareTo(other), lessThan(0)); expect(other.compareTo(location), greaterThan(0)); }); - test("considers equal locations equal", () { + test('considers equal locations equal', () { expect(location.compareTo(location), equals(0)); }); }); - group("equality", () { - test("two locations with the same offset and source are equal", () { - final other = SourceLocation(15, sourceUrl: "foo.dart"); + group('equality', () { + test('two locations with the same offset and source are equal', () { + final other = SourceLocation(15, sourceUrl: 'foo.dart'); expect(location, equals(other)); }); test("a different offset isn't equal", () { - final other = SourceLocation(10, sourceUrl: "foo.dart"); + final other = SourceLocation(10, sourceUrl: 'foo.dart'); expect(location, isNot(equals(other))); }); test("a different source isn't equal", () { - final other = SourceLocation(15, sourceUrl: "bar.dart"); + final other = SourceLocation(15, sourceUrl: 'bar.dart'); expect(location, isNot(equals(other))); }); }); From 373d878aa33cc49964a406d55ebbc4234a42492b Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 4 Dec 2019 16:34:42 -0800 Subject: [PATCH 314/657] Enable comment_references lint (dart-lang/source_span#50) Change the markdown link style in a few places to work around a bug with the analyzer where links that are split across lines are not recognized correctly. --- pkgs/source_span/analysis_options.yaml | 3 +-- pkgs/source_span/lib/src/highlighter.dart | 5 +++-- pkgs/source_span/lib/src/span.dart | 10 ++++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index 929d6fa97..a94bb5062 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -27,8 +27,7 @@ linter: - camel_case_types - cancel_subscriptions - cascade_invocations - # Enable once https://github.com/dart-lang/sdk/issues/31761 is fixed - #- comment_references + - comment_references - constant_identifier_names - control_flow_in_finally - directives_ordering diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index f3af75f7e..3ebe0df0c 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -48,12 +48,13 @@ class Highlighter { /// when [highlight] is called. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, - /// it indicates an [ANSI terminal color - /// escape](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) that should + /// it indicates an [ANSI terminal color escape][] that should /// be used to highlight the span's text (for example, `"\u001b[31m"` will /// color red). If it's `true`, it indicates that the text should be /// highlighted using the default color. If it's `false` or `null`, it /// indicates that the text shouldn't be highlighted. + /// + /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors factory Highlighter(SourceSpan span, {color}) { if (color == true) color = colors.red; if (color == false) color = null; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 48dfae73f..f329e372d 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -52,8 +52,7 @@ abstract class SourceSpan implements Comparable { /// Formats [message] in a human-friendly way associated with this span. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, - /// it indicates an [ANSI terminal color - /// escape](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) that should + /// it indicates an [ANSI terminal color escape][] that should /// be used to highlight the span's text (for example, `"\u001b[31m"` will /// color red). If it's `true`, it indicates that the text should be /// highlighted using the default color. If it's `false` or `null`, it @@ -62,6 +61,8 @@ abstract class SourceSpan implements Comparable { /// This uses the full range of Unicode characters to highlight the source /// span if [glyph.ascii] is `false` (the default), but only uses ASCII /// characters if it's `true`. + /// + /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors String message(String message, {color}); /// Prints the text associated with this span in a user-friendly way. @@ -71,8 +72,7 @@ abstract class SourceSpan implements Comparable { /// isn't a [SourceSpanWithContext], returns an empty string. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, - /// it indicates an [ANSI terminal color - /// escape](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) that should + /// it indicates an [ANSI terminal color escape][] that should /// be used to highlight the span's text (for example, `"\u001b[31m"` will /// color red). If it's `true`, it indicates that the text should be /// highlighted using the default color. If it's `false` or `null`, it @@ -81,6 +81,8 @@ abstract class SourceSpan implements Comparable { /// This uses the full range of Unicode characters to highlight the source /// span if [glyph.ascii] is `false` (the default), but only uses ASCII /// characters if it's `true`. + /// + /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors String highlight({color}); } From 1aaeb5a83e08c505694128839e8698a24b7c00b0 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 5 Dec 2019 11:36:57 -0800 Subject: [PATCH 315/657] Fix newly enforced package:pedantic lints (dart-lang/source_span#51) - prefer_if_null_operators --- pkgs/source_span/lib/src/location.dart | 6 +++--- pkgs/source_span/lib/src/location_mixin.dart | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 4f69df5b8..93942f05f 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -32,7 +32,7 @@ class SourceLocation implements Comparable { /// /// This prints 1-based lines and columns. String get toolString { - final source = sourceUrl == null ? 'unknown source' : sourceUrl; + final source = sourceUrl ?? 'unknown source'; return '$source:${line + 1}:${column + 1}'; } @@ -45,8 +45,8 @@ class SourceLocation implements Comparable { SourceLocation(this.offset, {sourceUrl, int line, int column}) : sourceUrl = sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri, - line = line == null ? 0 : line, - column = column == null ? offset : column { + line = line ?? 0, + column = column ?? offset { if (offset < 0) { throw RangeError('Offset may not be negative, was $offset.'); } else if (line != null && line < 0) { diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index bbb73b49a..a54e363d0 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -16,7 +16,7 @@ import 'span.dart'; abstract class SourceLocationMixin implements SourceLocation { @override String get toolString { - final source = sourceUrl == null ? 'unknown source' : sourceUrl; + final source = sourceUrl ?? 'unknown source'; return '$source:${line + 1}:${column + 1}'; } From 5b1b9835308b69b8ee18d2e08bfa8ac8fd585521 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Mon, 9 Dec 2019 15:59:31 -0800 Subject: [PATCH 316/657] Fix newly enforced package:pedantic lints (dart-lang/pool#34) - prefer_single_quotes --- pkgs/pool/lib/pool.dart | 12 +++---- pkgs/pool/test/pool_test.dart | 66 +++++++++++++++++------------------ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 12dd5e1b0..d8565411a 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -97,7 +97,7 @@ class Pool { /// until one of them is released. Future request() { if (isClosed) { - throw StateError("request() may not be called on a closed Pool."); + throw StateError('request() may not be called on a closed Pool.'); } if (_allocatedResources < _maxAllocatedResources) { @@ -119,7 +119,7 @@ class Pool { /// The return value of [callback] is piped to the returned Future. Future withResource(FutureOr Function() callback) async { if (isClosed) { - throw StateError("withResource() may not be called on a closed Pool."); + throw StateError('withResource() may not be called on a closed Pool.'); } var resource = await request(); @@ -324,8 +324,8 @@ class Pool { for (var completer in _requestedResources) { completer.completeError( TimeoutException( - "Pool deadlock: all resources have been " - "allocated for too long.", + 'Pool deadlock: all resources have been ' + 'allocated for too long.', _timeout), Chain.current()); } @@ -350,7 +350,7 @@ class PoolResource { /// no longer allocated, and that a new [PoolResource] may be allocated. void release() { if (_released) { - throw StateError("A PoolResource may only be released once."); + throw StateError('A PoolResource may only be released once.'); } _released = true; _pool._onResourceReleased(); @@ -370,7 +370,7 @@ class PoolResource { /// may be complete, but it could still emit asynchronous errors. void allowRelease(Function() onRelease) { if (_released) { - throw StateError("A PoolResource may only be released once."); + throw StateError('A PoolResource may only be released once.'); } _released = true; _pool._onResourceReleaseAllowed(onRelease); diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 77ef13d42..091cd5513 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -11,15 +11,15 @@ import 'package:stack_trace/stack_trace.dart'; import 'package:test/test.dart'; void main() { - group("request()", () { - test("resources can be requested freely up to the limit", () { + group('request()', () { + test('resources can be requested freely up to the limit', () { var pool = Pool(50); for (var i = 0; i < 50; i++) { expect(pool.request(), completes); } }); - test("resources block past the limit", () { + test('resources block past the limit', () { FakeAsync().run((async) { var pool = Pool(50); for (var i = 0; i < 50; i++) { @@ -31,7 +31,7 @@ void main() { }); }); - test("a blocked resource is allocated when another is released", () { + test('a blocked resource is allocated when another is released', () { FakeAsync().run((async) { var pool = Pool(50); for (var i = 0; i < 49; i++) { @@ -52,15 +52,15 @@ void main() { }); }); - group("withResource()", () { - test("can be called freely up to the limit", () { + group('withResource()', () { + test('can be called freely up to the limit', () { var pool = Pool(50); for (var i = 0; i < 50; i++) { pool.withResource(expectAsync0(() => Completer().future)); } }); - test("blocks the callback past the limit", () { + test('blocks the callback past the limit', () { FakeAsync().run((async) { var pool = Pool(50); for (var i = 0; i < 50; i++) { @@ -72,7 +72,7 @@ void main() { }); }); - test("a blocked resource is allocated when another is released", () { + test('a blocked resource is allocated when another is released', () { FakeAsync().run((async) { var pool = Pool(50); for (var i = 0; i < 49; i++) { @@ -99,14 +99,14 @@ void main() { }); // Regression test for #3. - test("can be called immediately before close()", () async { + test('can be called immediately before close()', () async { var pool = Pool(1); unawaited(pool.withResource(expectAsync0(() {}))); await pool.close(); }); }); - group("with a timeout", () { + group('with a timeout', () { test("doesn't time out if there are no pending requests", () { FakeAsync().run((async) { var pool = Pool(50, timeout: const Duration(seconds: 5)); @@ -118,7 +118,7 @@ void main() { }); }); - test("resets the timer if a resource is returned", () { + test('resets the timer if a resource is returned', () { FakeAsync().run((async) { var pool = Pool(50, timeout: const Duration(seconds: 5)); for (var i = 0; i < 49; i++) { @@ -139,7 +139,7 @@ void main() { }); }); - test("resets the timer if a resource is requested", () { + test('resets the timer if a resource is requested', () { FakeAsync().run((async) { var pool = Pool(50, timeout: const Duration(seconds: 5)); for (var i = 0; i < 50; i++) { @@ -155,7 +155,7 @@ void main() { }); }); - test("times out if nothing happens", () { + test('times out if nothing happens', () { FakeAsync().run((async) { var pool = Pool(50, timeout: const Duration(seconds: 5)); for (var i = 0; i < 50; i++) { @@ -168,8 +168,8 @@ void main() { }); }); - group("allowRelease()", () { - test("runs the callback once the resource limit is exceeded", () async { + group('allowRelease()', () { + test('runs the callback once the resource limit is exceeded', () async { var pool = Pool(50); for (var i = 0; i < 49; i++) { expect(pool.request(), completes); @@ -186,7 +186,7 @@ void main() { expect(onReleaseCalled, isTrue); }); - test("runs the callback immediately if there are blocked requests", + test('runs the callback immediately if there are blocked requests', () async { var pool = Pool(1); var resource = await pool.request(); @@ -200,7 +200,7 @@ void main() { expect(onReleaseCalled, isTrue); }); - test("blocks the request until the callback completes", () async { + test('blocks the request until the callback completes', () async { var pool = Pool(1); var resource = await pool.request(); @@ -217,7 +217,7 @@ void main() { expect(requestComplete, isTrue); }); - test("completes requests in request order regardless of callback order", + test('completes requests in request order regardless of callback order', () async { var pool = Pool(2); var resource1 = await pool.request(); @@ -262,7 +262,7 @@ void main() { expect(request2Complete, isTrue); }); - test("runs onRequest in the zone it was created", () async { + test('runs onRequest in the zone it was created', () async { var pool = Pool(1); var resource = await pool.request(); @@ -290,14 +290,14 @@ void main() { await Future.delayed(Duration.zero); }); - group("close()", () { - test("disallows request() and withResource()", () { + group('close()', () { + test('disallows request() and withResource()', () { var pool = Pool(1)..close(); expect(pool.request, throwsStateError); expect(() => pool.withResource(() {}), throwsStateError); }); - test("pending requests are fulfilled", () async { + test('pending requests are fulfilled', () async { var pool = Pool(1); var resource1 = await pool.request(); expect( @@ -310,7 +310,7 @@ void main() { resource1.release(); }); - test("pending requests are fulfilled with allowRelease", () async { + test('pending requests are fulfilled with allowRelease', () async { var pool = Pool(1); var resource1 = await pool.request(); @@ -359,7 +359,7 @@ void main() { resource3.release(); }); - test("active onReleases complete as usual", () async { + test('active onReleases complete as usual', () async { var pool = Pool(1); var resource = await pool.request(); @@ -380,7 +380,7 @@ void main() { completer.complete(); }); - test("inactive onReleases fire", () async { + test('inactive onReleases fire', () async { var pool = Pool(2); var resource1 = await pool.request(); var resource2 = await pool.request(); @@ -404,7 +404,7 @@ void main() { completer2.complete(); }); - test("new allowReleases fire immediately", () async { + test('new allowReleases fire immediately', () async { var pool = Pool(1); var resource = await pool.request(); @@ -422,18 +422,18 @@ void main() { completer.complete(); }); - test("an onRelease error is piped to the return value", () async { + test('an onRelease error is piped to the return value', () async { var pool = Pool(1); var resource = await pool.request(); var completer = Completer(); resource.allowRelease(() => completer.future); - expect(pool.done, throwsA("oh no!")); - expect(pool.close(), throwsA("oh no!")); + expect(pool.done, throwsA('oh no!')); + expect(pool.close(), throwsA('oh no!')); await Future.delayed(Duration.zero); - completer.completeError("oh no!"); + completer.completeError('oh no!'); }); }); @@ -719,7 +719,7 @@ void main() { }); }); - test("throw error when pool limit <= 0", () { + test('throw error when pool limit <= 0', () { expect(() => Pool(-1), throwsArgumentError); expect(() => Pool(0), throwsArgumentError); }); @@ -731,7 +731,7 @@ void main() { void Function() expectNoAsync() { var stack = Trace.current(1); return () => registerException( - TestFailure("Expected function not to be called."), stack); + TestFailure('Expected function not to be called.'), stack); } /// A matcher for Futures that asserts that they don't complete. @@ -742,6 +742,6 @@ Matcher get doesNotComplete => predicate((future) { var stack = Trace.current(1); future.then((_) => registerException( - TestFailure("Expected future not to complete."), stack)); + TestFailure('Expected future not to complete.'), stack)); return true; }); From cb144c756d65e04783e365c912e0653319975ca4 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Mon, 9 Dec 2019 17:41:12 -0800 Subject: [PATCH 317/657] Run dartfmt --fix (dart-lang/source_maps#35) - Drop optional new. - Use `=` over `:` for named parameter default values. --- pkgs/source_maps/lib/builder.dart | 11 +- pkgs/source_maps/lib/parser.dart | 112 +++++++++--------- pkgs/source_maps/lib/printer.dart | 26 ++-- pkgs/source_maps/lib/refactor.dart | 8 +- pkgs/source_maps/lib/src/source_map_span.dart | 6 +- pkgs/source_maps/lib/src/vlq.dart | 8 +- pkgs/source_maps/pubspec.yaml | 4 +- pkgs/source_maps/test/builder_test.dart | 4 +- pkgs/source_maps/test/common.dart | 14 +-- pkgs/source_maps/test/end2end_test.dart | 16 +-- pkgs/source_maps/test/parser_test.dart | 87 +++++++------- pkgs/source_maps/test/printer_test.dart | 20 ++-- pkgs/source_maps/test/refactor_test.dart | 12 +- 13 files changed, 159 insertions(+), 169 deletions(-) diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 0769d5052..67b48501d 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -22,10 +22,9 @@ class SourceMapBuilder { void addFromOffset(SourceLocation source, SourceFile targetFile, int targetOffset, String identifier) { if (targetFile == null) { - throw new ArgumentError('targetFile cannot be null'); + throw ArgumentError('targetFile cannot be null'); } - _entries - .add(new Entry(source, targetFile.location(targetOffset), identifier)); + _entries.add(Entry(source, targetFile.location(targetOffset), identifier)); } /// Adds an entry mapping [target] to [source]. @@ -40,18 +39,18 @@ class SourceMapBuilder { } var name = isIdentifier ? source.text : null; - _entries.add(new Entry(source.start, target.start, name)); + _entries.add(Entry(source.start, target.start, name)); } /// Adds an entry mapping [target] to [source]. void addLocation( SourceLocation source, SourceLocation target, String identifier) { - _entries.add(new Entry(source, target, identifier)); + _entries.add(Entry(source, target, identifier)); } /// Encodes all mappings added to this builder as a json map. Map build(String fileUrl) { - return new SingleMapping.fromEntries(this._entries, fileUrl).toJson(); + return SingleMapping.fromEntries(this._entries, fileUrl).toJson(); } /// Encodes all mappings added to this builder as a json string. diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 7fe45654f..755674e83 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -43,7 +43,7 @@ Mapping parseExtended(String jsonMap, {Map otherMaps, mapUrl}) => Mapping parseJsonExtended(/*List|Map*/ json, {Map otherMaps, mapUrl}) { if (json is List) { - return new MappingBundle.fromJson(json, mapUrl: mapUrl); + return MappingBundle.fromJson(json, mapUrl: mapUrl); } return parseJson(json as Map); } @@ -55,7 +55,7 @@ Mapping parseJsonExtended(/*List|Map*/ json, /// map will be interpreted as relative to this URL when generating spans. Mapping parseJson(Map map, {Map otherMaps, mapUrl}) { if (map['version'] != 3) { - throw new ArgumentError('unexpected source map version: ${map["version"]}. ' + throw ArgumentError('unexpected source map version: ${map["version"]}. ' 'Only version 3 is supported.'); } @@ -63,13 +63,13 @@ Mapping parseJson(Map map, {Map otherMaps, mapUrl}) { if (map.containsKey('mappings') || map.containsKey('sources') || map.containsKey('names')) { - throw new FormatException('map containing "sections" ' + throw FormatException('map containing "sections" ' 'cannot contain "mappings", "sources", or "names".'); } - return new MultiSectionMapping.fromJson(map['sections'], otherMaps, + return MultiSectionMapping.fromJson(map['sections'], otherMaps, mapUrl: mapUrl); } - return new SingleMapping.fromJson(map, mapUrl: mapUrl); + return SingleMapping.fromJson(map, mapUrl: mapUrl); } /// A mapping parsed out of a source map. @@ -107,13 +107,13 @@ class MultiSectionMapping extends Mapping { {mapUrl}) { for (var section in sections) { var offset = section['offset']; - if (offset == null) throw new FormatException('section missing offset'); + if (offset == null) throw FormatException('section missing offset'); var line = section['offset']['line']; - if (line == null) throw new FormatException('offset missing line'); + if (line == null) throw FormatException('offset missing line'); var column = section['offset']['column']; - if (column == null) throw new FormatException('offset missing column'); + if (column == null) throw FormatException('offset missing column'); _lineStart.add(line); _columnStart.add(column); @@ -122,10 +122,10 @@ class MultiSectionMapping extends Mapping { var map = section['map']; if (url != null && map != null) { - throw new FormatException("section can't use both url and map entries"); + throw FormatException("section can't use both url and map entries"); } else if (url != null) { if (otherMaps == null || otherMaps[url] == null) { - throw new FormatException( + throw FormatException( 'section contains refers to $url, but no map was ' 'given for it. Make sure a map is passed in "otherMaps"'); } @@ -133,11 +133,11 @@ class MultiSectionMapping extends Mapping { } else if (map != null) { _maps.add(parseJson(map, otherMaps: otherMaps, mapUrl: mapUrl)); } else { - throw new FormatException('section missing url or map'); + throw FormatException('section missing url or map'); } } if (_lineStart.length == 0) { - throw new FormatException('expected at least one section'); + throw FormatException('expected at least one section'); } } @@ -160,7 +160,7 @@ class MultiSectionMapping extends Mapping { } String toString() { - var buff = new StringBuffer("$runtimeType : ["); + var buff = StringBuffer("$runtimeType : ["); for (int i = 0; i < _lineStart.length; i++) { buff ..write('(') @@ -197,7 +197,7 @@ class MappingBundle extends Mapping { List toJson() => _mappings.values.map((v) => v.toJson()).toList(); String toString() { - var buff = new StringBuffer(); + var buff = StringBuffer(); for (var map in _mappings.values) { buff.write(map.toString()); } @@ -209,7 +209,7 @@ class MappingBundle extends Mapping { SourceMapSpan spanFor(int line, int column, {Map files, String uri}) { if (uri == null) { - throw new ArgumentError.notNull('uri'); + throw ArgumentError.notNull('uri'); } // Find the longest suffix of the uri that matches the sourcemap @@ -243,9 +243,9 @@ class MappingBundle extends Mapping { // of the input line and column to minimize the chances that two different // line and column locations are mapped to the same offset. var offset = line * 1000000 + column; - var location = new SourceLocation(offset, + var location = SourceLocation(offset, line: line, column: column, sourceUrl: Uri.parse(uri)); - return new SourceMapSpan(location, location, ""); + return SourceMapSpan(location, location, ""); } } @@ -287,7 +287,7 @@ class SingleMapping extends Mapping { factory SingleMapping.fromEntries(Iterable entries, [String fileUrl]) { // The entries needs to be sorted by the target offsets. - var sourceEntries = new List.from(entries)..sort(); + var sourceEntries = List.from(entries)..sort(); var lines = []; // Indices associated with file urls that will be part of the source map. We @@ -307,11 +307,11 @@ class SingleMapping extends Mapping { if (lineNum == null || sourceEntry.target.line > lineNum) { lineNum = sourceEntry.target.line; targetEntries = []; - lines.add(new TargetLineEntry(lineNum, targetEntries)); + lines.add(TargetLineEntry(lineNum, targetEntries)); } if (sourceEntry.source == null) { - targetEntries.add(new TargetEntry(sourceEntry.target.column)); + targetEntries.add(TargetEntry(sourceEntry.target.column)); } else { var sourceUrl = sourceEntry.source.sourceUrl; var urlId = urls.putIfAbsent( @@ -325,34 +325,30 @@ class SingleMapping extends Mapping { var srcNameId = sourceEntry.identifierName == null ? null : names.putIfAbsent(sourceEntry.identifierName, () => names.length); - targetEntries.add(new TargetEntry(sourceEntry.target.column, urlId, + targetEntries.add(TargetEntry(sourceEntry.target.column, urlId, sourceEntry.source.line, sourceEntry.source.column, srcNameId)); } } - return new SingleMapping._( - fileUrl, - urls.values.map((i) => files[i]).toList(), - urls.keys.toList(), - names.keys.toList(), - lines); + return SingleMapping._(fileUrl, urls.values.map((i) => files[i]).toList(), + urls.keys.toList(), names.keys.toList(), lines); } SingleMapping.fromJson(Map map, {mapUrl}) : targetUrl = map['file'], - urls = new List.from(map['sources']), - names = new List.from(map['names']), - files = new List(map['sources'].length), + urls = List.from(map['sources']), + names = List.from(map['names']), + files = List(map['sources'].length), sourceRoot = map['sourceRoot'], lines = [], _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl, extensions = {} { var sourcesContent = map['sourcesContent'] == null ? const [] - : new List.from(map['sourcesContent']); + : List.from(map['sourcesContent']); for (var i = 0; i < urls.length && i < sourcesContent.length; i++) { var source = sourcesContent[i]; if (source == null) continue; - files[i] = new SourceFile.fromString(source, url: urls[i]); + files[i] = SourceFile.fromString(source, url: urls[i]); } int line = 0; @@ -361,13 +357,13 @@ class SingleMapping extends Mapping { int srcLine = 0; int srcColumn = 0; int srcNameId = 0; - var tokenizer = new _MappingTokenizer(map['mappings']); + var tokenizer = _MappingTokenizer(map['mappings']); var entries = []; while (tokenizer.hasTokens) { if (tokenizer.nextKind.isNewLine) { if (!entries.isEmpty) { - lines.add(new TargetLineEntry(line, entries)); + lines.add(TargetLineEntry(line, entries)); entries = []; } line++; @@ -390,11 +386,11 @@ class SingleMapping extends Mapping { if (tokenizer.nextKind.isNewSegment) throw _segmentError(0, line); column += tokenizer._consumeValue(); if (!tokenizer.nextKind.isValue) { - entries.add(new TargetEntry(column)); + entries.add(TargetEntry(column)); } else { srcUrlId += tokenizer._consumeValue(); if (srcUrlId >= urls.length) { - throw new StateError( + throw StateError( 'Invalid source url id. $targetUrl, $line, $srcUrlId'); } if (!tokenizer.nextKind.isValue) throw _segmentError(2, line); @@ -402,21 +398,20 @@ class SingleMapping extends Mapping { if (!tokenizer.nextKind.isValue) throw _segmentError(3, line); srcColumn += tokenizer._consumeValue(); if (!tokenizer.nextKind.isValue) { - entries.add(new TargetEntry(column, srcUrlId, srcLine, srcColumn)); + entries.add(TargetEntry(column, srcUrlId, srcLine, srcColumn)); } else { srcNameId += tokenizer._consumeValue(); if (srcNameId >= names.length) { - throw new StateError( - 'Invalid name id: $targetUrl, $line, $srcNameId'); + throw StateError('Invalid name id: $targetUrl, $line, $srcNameId'); } entries.add( - new TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId)); + TargetEntry(column, srcUrlId, srcLine, srcColumn, srcNameId)); } } if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment(); } if (!entries.isEmpty) { - lines.add(new TargetLineEntry(line, entries)); + lines.add(TargetLineEntry(line, entries)); } map.forEach((name, value) { @@ -428,8 +423,8 @@ class SingleMapping extends Mapping { /// /// If [sourcesContent] is `true`, this includes the source file contents from /// [files] in the map if possible. - Map toJson({bool includeSourceContents: false}) { - var buff = new StringBuffer(); + Map toJson({bool includeSourceContents = false}) { + var buff = StringBuffer(); var line = 0; var column = 0; var srcLine = 0; @@ -492,7 +487,7 @@ class SingleMapping extends Mapping { } _segmentError(int seen, int line) => - new StateError('Invalid entry in sourcemap, expected 1, 4, or 5' + StateError('Invalid entry in sourcemap, expected 1, 4, or 5' ' values, but got $seen.\ntargeturl: $targetUrl, line: $line'); /// Returns [TargetLineEntry] which includes the location in the target [line] @@ -529,29 +524,28 @@ class SingleMapping extends Mapping { var start = file.getOffset(entry.sourceLine, entry.sourceColumn); if (entry.sourceNameId != null) { var text = names[entry.sourceNameId]; - return new SourceMapFileSpan( - files[url].span(start, start + text.length), + return SourceMapFileSpan(files[url].span(start, start + text.length), isIdentifier: true); } else { - return new SourceMapFileSpan(files[url].location(start).pointSpan()); + return SourceMapFileSpan(files[url].location(start).pointSpan()); } } else { - var start = new SourceLocation(0, + var start = SourceLocation(0, sourceUrl: _mapUrl == null ? url : _mapUrl.resolve(url), line: entry.sourceLine, column: entry.sourceColumn); // Offset and other context is not available. if (entry.sourceNameId != null) { - return new SourceMapSpan.identifier(start, names[entry.sourceNameId]); + return SourceMapSpan.identifier(start, names[entry.sourceNameId]); } else { - return new SourceMapSpan(start, start, ''); + return SourceMapSpan(start, start, ''); } } } String toString() { - return (new StringBuffer("$runtimeType : [") + return (StringBuffer("$runtimeType : [") ..write('targetUrl: ') ..write(targetUrl) ..write(', sourceRoot: ') @@ -567,7 +561,7 @@ class SingleMapping extends Mapping { } String get debugString { - var buff = new StringBuffer(); + var buff = StringBuffer(); for (var lineEntry in lines) { var line = lineEntry.line; for (var entry in lineEntry.entries) { @@ -624,7 +618,7 @@ class TargetEntry { '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; } -/** A character iterator over a string that can peek one character ahead. */ +/// A character iterator over a string that can peek one character ahead. class _MappingTokenizer implements Iterator { final String _internal; final int _length; @@ -660,7 +654,7 @@ class _MappingTokenizer implements Iterator { // Print the state of the iterator, with colors indicating the current // position. String toString() { - var buff = new StringBuffer(); + var buff = StringBuffer(); for (int i = 0; i < index; i++) { buff.write(_internal[i]); } @@ -676,15 +670,15 @@ class _MappingTokenizer implements Iterator { } class _TokenKind { - static const _TokenKind LINE = const _TokenKind(isNewLine: true); - static const _TokenKind SEGMENT = const _TokenKind(isNewSegment: true); - static const _TokenKind EOF = const _TokenKind(isEof: true); - static const _TokenKind VALUE = const _TokenKind(); + static const _TokenKind LINE = _TokenKind(isNewLine: true); + static const _TokenKind SEGMENT = _TokenKind(isNewSegment: true); + static const _TokenKind EOF = _TokenKind(isEof: true); + static const _TokenKind VALUE = _TokenKind(); final bool isNewLine; final bool isNewSegment; final bool isEof; bool get isValue => !isNewLine && !isNewSegment && !isEof; const _TokenKind( - {this.isNewLine: false, this.isNewSegment: false, this.isEof: false}); + {this.isNewLine = false, this.isNewSegment = false, this.isEof = false}); } diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 6187dba81..beadbdd4e 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -17,8 +17,8 @@ const int _CR = 13; /// maps locations. class Printer { final String filename; - final StringBuffer _buff = new StringBuffer(); - final SourceMapBuilder _maps = new SourceMapBuilder(); + final StringBuffer _buff = StringBuffer(); + final SourceMapBuilder _maps = SourceMapBuilder(); String get text => _buff.toString(); String get map => _maps.toJson(filename); @@ -38,7 +38,7 @@ class Printer { /// adds a source map location on each new line, projecting that every new /// line in the target file (printed here) corresponds to a new line in the /// source file. - void add(String str, {projectMarks: false}) { + void add(String str, {projectMarks = false}) { var chars = str.runes.toList(); var length = chars.length; for (int i = 0; i < length; i++) { @@ -52,7 +52,7 @@ class Printer { var file = (_loc as FileLocation).file; mark(file.location(file.getOffset(_loc.line + 1))); } else { - mark(new SourceLocation(0, + mark(SourceLocation(0, sourceUrl: _loc.sourceUrl, line: _loc.line + 1, column: 0)); } } @@ -84,10 +84,8 @@ class Printer { loc = mark.start; if (mark is SourceMapSpan && mark.isIdentifier) identifier = mark.text; } - _maps.addLocation( - loc, - new SourceLocation(_buff.length, line: _line, column: _column), - identifier); + _maps.addLocation(loc, + SourceLocation(_buff.length, line: _line, column: _column), identifier); _loc = loc; } } @@ -113,7 +111,7 @@ class NestedPrinter implements NestedItem { /// Item used to indicate that the following item is copied from the original /// source code, and hence we should preserve source-maps on every new line. - static final _ORIGINAL = new Object(); + static final _ORIGINAL = Object(); NestedPrinter([this.indent = 0]); @@ -133,7 +131,7 @@ class NestedPrinter implements NestedItem { /// Setting [isOriginal] will make this printer propagate source map locations /// on every line-break. void add(object, - {SourceLocation location, SourceSpan span, bool isOriginal: false}) { + {SourceLocation location, SourceSpan span, bool isOriginal = false}) { if (object is! String || location != null || span != null || isOriginal) { _flush(); assert(location == null || span == null); @@ -180,7 +178,7 @@ class NestedPrinter implements NestedItem { /// Appends a string merging it with any previous strings, if possible. void _appendString(String s) { - if (_buff == null) _buff = new StringBuffer(); + if (_buff == null) _buff = StringBuffer(); _buff.write(s); } @@ -200,7 +198,7 @@ class NestedPrinter implements NestedItem { /// printer, including source map location tokens. String toString() { _flush(); - return (new StringBuffer()..writeAll(_items)).toString(); + return (StringBuffer()..writeAll(_items)).toString(); } /// [Printer] used during the last call to [build], if any. @@ -216,7 +214,7 @@ class NestedPrinter implements NestedItem { /// calling this function, you can use [text] and [map] to retrieve the /// geenrated code and source map information, respectively. void build(String filename) { - writeTo(printer = new Printer(filename)); + writeTo(printer = Printer(filename)); } /// Implements the [NestedItem] interface. @@ -237,7 +235,7 @@ class NestedPrinter implements NestedItem { // every new-line. propagate = true; } else { - throw new UnsupportedError('Unknown item type: $item'); + throw UnsupportedError('Unknown item type: $item'); } } } diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index d6b129a29..34eabf816 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -30,7 +30,7 @@ class TextEditTransaction { /// with the [replacement]. [replacement] can be either a string or a /// [NestedPrinter]. void edit(int begin, int end, replacement) { - _edits.add(new _TextEdit(begin, end, replacement)); + _edits.add(_TextEdit(begin, end, replacement)); } /// Create a source map [SourceLocation] for [offset]. @@ -45,7 +45,7 @@ class TextEditTransaction { /// Throws [UnsupportedError] if the edits were overlapping. If no edits were /// made, the printer simply contains the original string. NestedPrinter commit() { - var printer = new NestedPrinter(); + var printer = NestedPrinter(); if (_edits.length == 0) { return printer..add(original, location: _loc(0), isOriginal: true); } @@ -56,7 +56,7 @@ class TextEditTransaction { int consumed = 0; for (var edit in _edits) { if (consumed > edit.begin) { - var sb = new StringBuffer(); + var sb = StringBuffer(); sb ..write(file.location(edit.begin).toolString) ..write(': overlapping edits. Insert at offset ') @@ -65,7 +65,7 @@ class TextEditTransaction { ..write(consumed) ..write(' input characters. List of edits:'); for (var e in _edits) sb..write('\n ')..write(e); - throw new UnsupportedError(sb.toString()); + throw UnsupportedError(sb.toString()); } // Add characters from the original string between this edit and the last diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index 37107e1c7..ba67027d5 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -17,7 +17,7 @@ class SourceMapSpan extends SourceSpanBase { final bool isIdentifier; SourceMapSpan(SourceLocation start, SourceLocation end, String text, - {this.isIdentifier: false}) + {this.isIdentifier = false}) : super(start, end, text); /// Creates a [SourceMapSpan] for an identifier with value [text] starting at @@ -27,7 +27,7 @@ class SourceMapSpan extends SourceSpanBase { SourceMapSpan.identifier(SourceLocation start, String text) : this( start, - new SourceLocation(start.offset + text.length, + SourceLocation(start.offset + text.length, sourceUrl: start.sourceUrl, line: start.line, column: start.column + text.length), @@ -48,7 +48,7 @@ class SourceMapFileSpan implements SourceMapSpan, FileSpan { Uri get sourceUrl => _inner.sourceUrl; int get length => _inner.length; - SourceMapFileSpan(this._inner, {this.isIdentifier: false}); + SourceMapFileSpan(this._inner, {this.isIdentifier = false}); int compareTo(SourceSpan other) => _inner.compareTo(other); String highlight({color}) => _inner.highlight(color: color); diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index 0c54dbf66..ebae139fd 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -40,7 +40,7 @@ final int MIN_INT32 = -pow(2, 31); /// Creates the VLQ encoding of [value] as a sequence of characters Iterable encodeVlq(int value) { if (value < MIN_INT32 || value > MAX_INT32) { - throw new ArgumentError('expected 32 bit int, got: $value'); + throw ArgumentError('expected 32 bit int, got: $value'); } var res = []; int signBit = 0; @@ -69,10 +69,10 @@ int decodeVlq(Iterator chars) { bool stop = false; int shift = 0; while (!stop) { - if (!chars.moveNext()) throw new StateError('incomplete VLQ value'); + if (!chars.moveNext()) throw StateError('incomplete VLQ value'); var char = chars.current; if (!_digits.containsKey(char)) { - throw new FormatException('invalid character in VLQ encoding: $char'); + throw FormatException('invalid character in VLQ encoding: $char'); } var digit = _digits[char]; stop = (digit & VLQ_CONTINUATION_BIT) == 0; @@ -95,7 +95,7 @@ int decodeVlq(Iterator chars) { // TODO(sigmund): can we detect this earlier? if (result < MIN_INT32 || result > MAX_INT32) { - throw new FormatException( + throw FormatException( 'expected an encoded 32 bit int, but we got: $result'); } return result; diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 0a35df6e0..cf7976605 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,12 +1,12 @@ name: source_maps -version: 0.10.8 +version: 0.10.9-dev description: Library to programmatically manipulate source map files. author: Dart Team homepage: http://github.com/dart-lang/source_maps environment: - sdk: '>=2.0.0-dev.17.0 <3.0.0' + sdk: '>=2.0.0 <3.0.0' dependencies: source_span: ^1.3.0 diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index 1e2efdd5c..0b2a96512 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -11,7 +11,7 @@ import 'common.dart'; main() { test('builder - with span', () { - var map = (new SourceMapBuilder() + var map = (SourceMapBuilder() ..addSpan(inputVar1, outputVar1) ..addSpan(inputFunction, outputFunction) ..addSpan(inputVar2, outputVar2) @@ -21,7 +21,7 @@ main() { }); test('builder - with location', () { - var str = (new SourceMapBuilder() + var str = (SourceMapBuilder() ..addLocation(inputVar1.start, outputVar1.start, 'longVar1') ..addLocation(inputFunction.start, outputFunction.start, 'longName') ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index 01ffdada6..8217c0e22 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -19,11 +19,11 @@ int longName(int longVar2) { return longVar1 + longVar2; } '''; -var input = new SourceFile(INPUT, url: 'input.dart'); +var input = SourceFile(INPUT, url: 'input.dart'); /// A span in the input file SourceMapSpan ispan(int start, int end, [bool isIdentifier = false]) => - new SourceMapFileSpan(input.span(start, end), isIdentifier: isIdentifier); + SourceMapFileSpan(input.span(start, end), isIdentifier: isIdentifier); SourceMapSpan inputVar1 = ispan(30, 38, true); SourceMapSpan inputFunction = ispan(74, 82, true); @@ -40,11 +40,11 @@ const String OUTPUT = ''' var x = 3; f(y) => x + y; '''; -var output = new SourceFile(OUTPUT, url: 'output.dart'); +var output = SourceFile(OUTPUT, url: 'output.dart'); /// A span in the output file SourceMapSpan ospan(int start, int end, [bool isIdentifier = false]) => - new SourceMapFileSpan(output.span(start, end), isIdentifier: isIdentifier); + SourceMapFileSpan(output.span(start, end), isIdentifier: isIdentifier); SourceMapSpan outputVar1 = ospan(4, 5, true); SourceMapSpan outputFunction = ospan(11, 12, true); @@ -62,11 +62,11 @@ SourceMapSpan outputExpr = ospan(19, 24); /// /// This mapping is stored in the tests so we can independently test the builder /// and parser algorithms without relying entirely on end2end tests. -const Map EXPECTED_MAP = const { +const Map EXPECTED_MAP = { 'version': 3, 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const ['longVar1', 'longName', 'longVar2'], + 'sources': ['input.dart'], + 'names': ['longVar1', 'longName', 'longVar2'], 'mappings': 'IACIA;AAGAC,EAAaC,MACR', 'file': 'output.dart' }; diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 1082c979b..5d6016538 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -29,7 +29,7 @@ main() { }); test('build + parse', () { - var map = (new SourceMapBuilder() + var map = (SourceMapBuilder() ..addSpan(inputVar1, outputVar1) ..addSpan(inputFunction, outputFunction) ..addSpan(inputVar2, outputVar2) @@ -43,7 +43,7 @@ main() { }); test('build + parse - no symbols', () { - var map = (new SourceMapBuilder() + var map = (SourceMapBuilder() ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) ..addSpan(inputVar2NoSymbol, outputVar2NoSymbol) @@ -57,7 +57,7 @@ main() { }); test('build + parse, repeated entries', () { - var map = (new SourceMapBuilder() + var map = (SourceMapBuilder() ..addSpan(inputVar1, outputVar1) ..addSpan(inputVar1, outputVar1) ..addSpan(inputFunction, outputFunction) @@ -75,7 +75,7 @@ main() { }); test('build + parse - no symbols, repeated entries', () { - var map = (new SourceMapBuilder() + var map = (SourceMapBuilder() ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) ..addSpan(inputVar1NoSymbol, outputVar1NoSymbol) ..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol) @@ -92,7 +92,7 @@ main() { }); test('build + parse with file', () { - var json = (new SourceMapBuilder() + var json = (SourceMapBuilder() ..addSpan(inputVar1, outputVar1) ..addSpan(inputFunction, outputFunction) ..addSpan(inputVar2, outputVar2) @@ -107,8 +107,8 @@ main() { test('printer projecting marks + parse', () { var out = INPUT.replaceAll('long', '_s'); - var file = new SourceFile(out, url: 'output2.dart'); - var printer = new Printer('output2.dart'); + var file = SourceFile(out, url: 'output2.dart'); + var printer = Printer('output2.dart'); printer.mark(ispan(0, 0)); var segments = INPUT.split('long'); @@ -135,7 +135,7 @@ main() { checkHelper(SourceMapSpan inputSpan, int adjustment) { var start = inputSpan.start.offset - adjustment; var end = (inputSpan.end.offset - adjustment) - 2; - var span = new SourceMapFileSpan(file.span(start, end), + var span = SourceMapFileSpan(file.span(start, end), isIdentifier: inputSpan.isIdentifier); check(span, mapping, inputSpan, true); } diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 390184292..d6a8ac12d 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -10,61 +10,61 @@ import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; import 'common.dart'; -const Map MAP_WITH_NO_SOURCE_LOCATION = const { +const Map MAP_WITH_NO_SOURCE_LOCATION = { 'version': 3, 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const [], + 'sources': ['input.dart'], + 'names': [], 'mappings': 'A', 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION = const { +const Map MAP_WITH_SOURCE_LOCATION = { 'version': 3, 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const [], + 'sources': ['input.dart'], + 'names': [], 'mappings': 'AAAA', 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME = const { +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME = { 'version': 3, 'sourceRoot': '', - 'sources': const ['input.dart'], - 'names': const ['var'], + 'sources': ['input.dart'], + 'names': ['var'], 'mappings': 'AAAAA', 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_1 = const { +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_1 = { 'version': 3, 'sourceRoot': 'pkg/', - 'sources': const ['input1.dart'], - 'names': const ['var1'], + 'sources': ['input1.dart'], + 'names': ['var1'], 'mappings': 'AAAAA', 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_2 = const { +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_2 = { 'version': 3, 'sourceRoot': 'pkg/', - 'sources': const ['input2.dart'], - 'names': const ['var2'], + 'sources': ['input2.dart'], + 'names': ['var2'], 'mappings': 'AAAAA', 'file': 'output2.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_3 = const { +const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_3 = { 'version': 3, 'sourceRoot': 'pkg/', - 'sources': const ['input3.dart'], - 'names': const ['var3'], + 'sources': ['input3.dart'], + 'names': ['var3'], 'mappings': 'AAAAA', 'file': '3/output.dart' }; -const List SOURCE_MAP_BUNDLE = const [ +const List SOURCE_MAP_BUNDLE = [ MAP_WITH_SOURCE_LOCATION_AND_NAME_1, MAP_WITH_SOURCE_LOCATION_AND_NAME_2, MAP_WITH_SOURCE_LOCATION_AND_NAME_3, @@ -135,14 +135,14 @@ main() { }); test('parse with source root', () { - var inputMap = new Map.from(MAP_WITH_SOURCE_LOCATION); + var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = '/pkg/'; var mapping = parseJson(inputMap) as SingleMapping; expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse("/pkg/input.dart")); expect( mapping .spanForLocation( - new SourceLocation(0, sourceUrl: Uri.parse("ignored.dart"))) + SourceLocation(0, sourceUrl: Uri.parse("ignored.dart"))) .sourceUrl, Uri.parse("/pkg/input.dart")); @@ -155,7 +155,7 @@ main() { }); test('parse with map URL', () { - var inputMap = new Map.from(MAP_WITH_SOURCE_LOCATION); + var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = 'pkg/'; var mapping = parseJson(inputMap, mapUrl: "file:///path/to/map"); expect(mapping.spanFor(0, 0).sourceUrl, @@ -169,20 +169,20 @@ main() { test('simple', () { expect( mapping - .spanForLocation(new SourceLocation(0, - sourceUrl: new Uri.file('/path/to/output.dart'))) + .spanForLocation(SourceLocation(0, + sourceUrl: Uri.file('/path/to/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect( mapping - .spanForLocation(new SourceLocation(0, - sourceUrl: new Uri.file('/path/to/output2.dart'))) + .spanForLocation(SourceLocation(0, + sourceUrl: Uri.file('/path/to/output2.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); expect( mapping - .spanForLocation(new SourceLocation(0, - sourceUrl: new Uri.file('/path/to/3/output.dart'))) + .spanForLocation(SourceLocation(0, + sourceUrl: Uri.file('/path/to/3/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input3.dart")); @@ -200,19 +200,19 @@ main() { test('package uris', () { expect( mapping - .spanForLocation(new SourceLocation(0, + .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:1/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect( mapping - .spanForLocation(new SourceLocation(0, + .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:2/output2.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); expect( mapping - .spanForLocation(new SourceLocation(0, + .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:3/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input3.dart")); @@ -263,7 +263,7 @@ main() { }); test('build bundle incrementally', () { - var mapping = new MappingBundle(); + var mapping = MappingBundle(); mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_1, mapUrl: "file:///path/to/map")); @@ -291,19 +291,19 @@ main() { test('different paths', () { expect( mapping - .spanForLocation(new SourceLocation(0, + .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input1.dart")); expect( mapping - .spanForLocation(new SourceLocation(0, + .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/output2.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input2.dart")); expect( mapping - .spanForLocation(new SourceLocation(0, + .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/3/output.dart'))) .sourceUrl, Uri.parse("file:///path/to/pkg/input3.dart")); @@ -343,7 +343,7 @@ main() { }); test('parse extensions', () { - var map = new Map.from(EXPECTED_MAP); + var map = Map.from(EXPECTED_MAP); map["x_foo"] = "a"; map["x_bar"] = [3]; SingleMapping mapping = parseJson(map); @@ -355,16 +355,15 @@ main() { group("source files", () { group("from fromEntries()", () { test("are null for non-FileLocations", () { - var mapping = new SingleMapping.fromEntries([ - new Entry(new SourceLocation(10, line: 1, column: 8), - outputVar1.start, null) + var mapping = SingleMapping.fromEntries([ + Entry(SourceLocation(10, line: 1, column: 8), outputVar1.start, null) ]); expect(mapping.files, equals([null])); }); test("use a file location's file", () { - var mapping = new SingleMapping.fromEntries( - [new Entry(inputVar1.start, outputVar1.start, null)]); + var mapping = SingleMapping.fromEntries( + [Entry(inputVar1.start, outputVar1.start, null)]); expect(mapping.files, equals([input])); }); }); @@ -377,14 +376,14 @@ main() { }); test("with null sourcesContent values", () { - var map = new Map.from(EXPECTED_MAP); + var map = Map.from(EXPECTED_MAP); map["sourcesContent"] = [null]; var mapping = parseJson(map) as SingleMapping; expect(mapping.files, equals([null])); }); test("with a too-short sourcesContent", () { - var map = new Map.from(EXPECTED_MAP); + var map = Map.from(EXPECTED_MAP); map["sourcesContent"] = []; var mapping = parseJson(map) as SingleMapping; expect(mapping.files, equals([null])); @@ -392,7 +391,7 @@ main() { }); test("are parsed from sourcesContent", () { - var map = new Map.from(EXPECTED_MAP); + var map = Map.from(EXPECTED_MAP); map["sourcesContent"] = ["hello, world!"]; var mapping = parseJson(map) as SingleMapping; diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index 32db69565..a2479073a 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -12,7 +12,7 @@ import 'common.dart'; main() { test('printer', () { - var printer = new Printer('output.dart'); + var printer = Printer('output.dart'); printer ..add('var ') ..mark(inputVar1) @@ -29,7 +29,7 @@ main() { test('printer projecting marks', () { var out = INPUT.replaceAll('long', '_s'); - var printer = new Printer('output2.dart'); + var printer = Printer('output2.dart'); var segments = INPUT.split('long'); expect(segments.length, 6); @@ -56,12 +56,12 @@ main() { expect(printer.map.split(';').length, 8); asFixed(SourceMapSpan s) => - new SourceMapSpan(s.start, s.end, s.text, isIdentifier: s.isIdentifier); + SourceMapSpan(s.start, s.end, s.text, isIdentifier: s.isIdentifier); // The result is the same if we use fixed positions - var printer2 = new Printer('output2.dart'); + var printer2 = Printer('output2.dart'); printer2 - ..mark(new SourceLocation(0, sourceUrl: 'input.dart').pointSpan()) + ..mark(SourceLocation(0, sourceUrl: 'input.dart').pointSpan()) ..add(segments[0], projectMarks: true) ..mark(asFixed(inputVar1)) ..add('_s') @@ -84,7 +84,7 @@ main() { group('nested printer', () { test('simple use', () { - var printer = new NestedPrinter(); + var printer = NestedPrinter(); printer ..add('var ') ..add('x = 3;\n', span: inputVar1) @@ -97,12 +97,12 @@ main() { }); test('nested use', () { - var printer = new NestedPrinter(); + var printer = NestedPrinter(); printer ..add('var ') - ..add(new NestedPrinter()..add('x = 3;\n', span: inputVar1)) + ..add(NestedPrinter()..add('x = 3;\n', span: inputVar1)) ..add('f(', span: inputFunction) - ..add(new NestedPrinter()..add('y) => ', span: inputVar2)) + ..add(NestedPrinter()..add('y) => ', span: inputVar2)) ..add('x + y;\n', span: inputExpr) ..build('output.dart'); expect(printer.text, OUTPUT); @@ -113,7 +113,7 @@ main() { var out = INPUT.replaceAll('long', '_s'); var lines = INPUT.trim().split('\n'); expect(lines.length, 7); - var printer = new NestedPrinter(); + var printer = NestedPrinter(); for (int i = 0; i < lines.length; i++) { if (i == 5) printer.indent++; printer.addLine(lines[i].replaceAll('long', '_s').trim()); diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 857d30dce..ba2ddc955 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -17,10 +17,10 @@ main() { group('conflict detection', () { var original = "0123456789abcdefghij"; - var file = new SourceFile(original); + var file = SourceFile(original); test('no conflict, in order', () { - var txn = new TextEditTransaction(original, file); + var txn = TextEditTransaction(original, file); txn.edit(2, 4, '.'); txn.edit(5, 5, '|'); txn.edit(6, 6, '-'); @@ -29,7 +29,7 @@ main() { }); test('no conflict, out of order', () { - var txn = new TextEditTransaction(original, file); + var txn = TextEditTransaction(original, file); txn.edit(2, 4, '.'); txn.edit(5, 5, '|'); @@ -41,7 +41,7 @@ main() { }); test('conflict', () { - var txn = new TextEditTransaction(original, file); + var txn = TextEditTransaction(original, file); txn.edit(2, 4, '.'); txn.edit(3, 3, '-'); expect( @@ -54,8 +54,8 @@ main() { test('generated source maps', () { var original = "0123456789\n0*23456789\n01*3456789\nabcdefghij\nabcd*fghij\n"; - var file = new SourceFile(original); - var txn = new TextEditTransaction(original, file); + var file = SourceFile(original); + var txn = TextEditTransaction(original, file); txn.edit(27, 29, '__\n '); txn.edit(34, 35, '___'); var printer = (txn.commit()..build('')); From d92d0de2861d4dfc1bd016c5e489ecf8cf9b0f45 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Mon, 9 Dec 2019 17:59:46 -0800 Subject: [PATCH 318/657] Migrate for deprecations from other packages (dart-lang/source_maps#36) --- pkgs/source_maps/test/common.dart | 4 ++-- pkgs/source_maps/test/end2end_test.dart | 2 +- pkgs/source_maps/test/parser_test.dart | 4 ++-- pkgs/source_maps/test/refactor_test.dart | 4 ++-- pkgs/source_maps/test/vlq_test.dart | 16 ++++++++-------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index 8217c0e22..ef119ec22 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -19,7 +19,7 @@ int longName(int longVar2) { return longVar1 + longVar2; } '''; -var input = SourceFile(INPUT, url: 'input.dart'); +var input = SourceFile.fromString(INPUT, url: 'input.dart'); /// A span in the input file SourceMapSpan ispan(int start, int end, [bool isIdentifier = false]) => @@ -40,7 +40,7 @@ const String OUTPUT = ''' var x = 3; f(y) => x + y; '''; -var output = SourceFile(OUTPUT, url: 'output.dart'); +var output = SourceFile.fromString(OUTPUT, url: 'output.dart'); /// A span in the output file SourceMapSpan ospan(int start, int end, [bool isIdentifier = false]) => diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 5d6016538..28c662556 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -107,7 +107,7 @@ main() { test('printer projecting marks + parse', () { var out = INPUT.replaceAll('long', '_s'); - var file = SourceFile(out, url: 'output2.dart'); + var file = SourceFile.fromString(out, url: 'output2.dart'); var printer = Printer('output2.dart'); printer.mark(ispan(0, 0)); diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index d6a8ac12d..6b2f5573f 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -238,7 +238,7 @@ main() { }); test('missing path', () { - expect(() => mapping.spanFor(0, 0), throws); + expect(() => mapping.spanFor(0, 0), throwsA(anything)); }); test('incomplete paths', () { @@ -336,7 +336,7 @@ main() { expect(mapping.toJson(), equals(expected)); } // Invalid for this case - expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throws); + expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throwsA(anything)); var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE) as MappingBundle; expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index ba2ddc955..552081ae9 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -17,7 +17,7 @@ main() { group('conflict detection', () { var original = "0123456789abcdefghij"; - var file = SourceFile(original); + var file = SourceFile.fromString(original); test('no conflict, in order', () { var txn = TextEditTransaction(original, file); @@ -54,7 +54,7 @@ main() { test('generated source maps', () { var original = "0123456789\n0*23456789\n01*3456789\nabcdefghij\nabcd*fghij\n"; - var file = SourceFile(original); + var file = SourceFile.fromString(original); var txn = TextEditTransaction(original, file); txn.edit(27, 29, '__\n '); txn.edit(34, 35, '___'); diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index 30b6d4529..f97989f2b 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -37,17 +37,17 @@ main() { expect(encodeVlq(min_int).join(''), 'hgggggE'); expect(decodeVlq('hgggggE'.split('').iterator), min_int); - expect(() => encodeVlq(max_int + 1), throws); - expect(() => encodeVlq(max_int + 2), throws); - expect(() => encodeVlq(min_int - 1), throws); - expect(() => encodeVlq(min_int - 2), throws); + expect(() => encodeVlq(max_int + 1), throwsA(anything)); + expect(() => encodeVlq(max_int + 2), throwsA(anything)); + expect(() => encodeVlq(min_int - 1), throwsA(anything)); + expect(() => encodeVlq(min_int - 2), throwsA(anything)); // if we allowed more than 32 bits, these would be the expected encodings // for the large numbers above. - expect(() => decodeVlq('ggggggE'.split('').iterator), throws); - expect(() => decodeVlq('igggggE'.split('').iterator), throws); - expect(() => decodeVlq('jgggggE'.split('').iterator), throws); - expect(() => decodeVlq('lgggggE'.split('').iterator), throws); + expect(() => decodeVlq('ggggggE'.split('').iterator), throwsA(anything)); + expect(() => decodeVlq('igggggE'.split('').iterator), throwsA(anything)); + expect(() => decodeVlq('jgggggE'.split('').iterator), throwsA(anything)); + expect(() => decodeVlq('lgggggE'.split('').iterator), throwsA(anything)); }, // This test uses integers so large they overflow in JS. testOn: "dart-vm"); From 949aaedc7c5bac357548eb60ca4a3ad60ed094a6 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 11 Dec 2019 17:15:14 -0800 Subject: [PATCH 319/657] Enforce and fix package:pedantic lints (dart-lang/source_maps#37) Add an `analysis_options.yaml` which includes `package:pedantic` config. Fix existing lints: - always_declare_return_types - annotate_overrides - avoid_init_to_null - curly_braces_in_flow_control_structures - empty_constructor_bodies - omit_local_variable_types - prefer_conditional_assignment - prefer_final_fields - prefer_if_null_operators - prefer_is_empty - prefer_is_not_empty - prefer_single_quotes - unnecessary_this - use_function_type_syntax_for_parameters --- pkgs/source_maps/analysis_options.yaml | 1 + pkgs/source_maps/lib/builder.dart | 9 +- pkgs/source_maps/lib/parser.dart | 71 ++++--- pkgs/source_maps/lib/printer.dart | 22 ++- pkgs/source_maps/lib/refactor.dart | 22 ++- pkgs/source_maps/lib/source_maps.dart | 8 +- pkgs/source_maps/lib/src/source_map_span.dart | 16 +- pkgs/source_maps/lib/src/utils.dart | 8 +- pkgs/source_maps/lib/src/vlq.dart | 14 +- pkgs/source_maps/test/builder_test.dart | 2 +- pkgs/source_maps/test/common.dart | 2 +- pkgs/source_maps/test/end2end_test.dart | 4 +- pkgs/source_maps/test/parser_test.dart | 176 +++++++++--------- pkgs/source_maps/test/printer_test.dart | 6 +- pkgs/source_maps/test/refactor_test.dart | 140 +++++++------- pkgs/source_maps/test/utils_test.dart | 12 +- pkgs/source_maps/test/vlq_test.dart | 8 +- 17 files changed, 278 insertions(+), 243 deletions(-) create mode 100644 pkgs/source_maps/analysis_options.yaml diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml new file mode 100644 index 000000000..108d1058a --- /dev/null +++ b/pkgs/source_maps/analysis_options.yaml @@ -0,0 +1 @@ +include: package:pedantic/analysis_options.yaml diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 67b48501d..5574f0df0 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -34,9 +34,7 @@ class SourceMapBuilder { /// identifier whose value will be stored in the source map. [isIdenfier] /// takes precedence over [target]'s `isIdentifier` value. void addSpan(SourceSpan source, SourceSpan target, {bool isIdentifier}) { - if (isIdentifier == null) { - isIdentifier = source is SourceMapSpan ? source.isIdentifier : false; - } + isIdentifier ??= source is SourceMapSpan ? source.isIdentifier : false; var name = isIdentifier ? source.text : null; _entries.add(Entry(source.start, target.start, name)); @@ -50,7 +48,7 @@ class SourceMapBuilder { /// Encodes all mappings added to this builder as a json map. Map build(String fileUrl) { - return SingleMapping.fromEntries(this._entries, fileUrl).toJson(); + return SingleMapping.fromEntries(_entries, fileUrl).toJson(); } /// Encodes all mappings added to this builder as a json string. @@ -75,8 +73,9 @@ class Entry implements Comparable { /// location in the target file. We sort primarily by the target offset /// because source map files are encoded by printing each mapping in order as /// they appear in the target file. + @override int compareTo(Entry other) { - int res = target.compareTo(other.target); + var res = target.compareTo(other.target); if (res != 0) return res; res = source.sourceUrl .toString() diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 755674e83..c15ff2a11 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -136,32 +136,34 @@ class MultiSectionMapping extends Mapping { throw FormatException('section missing url or map'); } } - if (_lineStart.length == 0) { + if (_lineStart.isEmpty) { throw FormatException('expected at least one section'); } } int _indexFor(line, column) { - for (int i = 0; i < _lineStart.length; i++) { + for (var i = 0; i < _lineStart.length; i++) { if (line < _lineStart[i]) return i - 1; if (line == _lineStart[i] && column < _columnStart[i]) return i - 1; } return _lineStart.length - 1; } + @override SourceMapSpan spanFor(int line, int column, {Map files, String uri}) { // TODO(jacobr): perhaps verify that targetUrl matches the actual uri // or at least ends in the same file name. - int index = _indexFor(line, column); + var index = _indexFor(line, column); return _maps[index].spanFor( line - _lineStart[index], column - _columnStart[index], files: files); } + @override String toString() { - var buff = StringBuffer("$runtimeType : ["); - for (int i = 0; i < _lineStart.length; i++) { + var buff = StringBuffer('$runtimeType : ['); + for (var i = 0; i < _lineStart.length; i++) { buff ..write('(') ..write(_lineStart[i]) @@ -177,9 +179,9 @@ class MultiSectionMapping extends Mapping { } class MappingBundle extends Mapping { - Map _mappings = {}; + final Map _mappings = {}; - MappingBundle() {} + MappingBundle(); MappingBundle.fromJson(List json, {String mapUrl}) { for (var map in json) { @@ -187,7 +189,7 @@ class MappingBundle extends Mapping { } } - addMapping(SingleMapping mapping) { + void addMapping(SingleMapping mapping) { // TODO(jacobr): verify that targetUrl is valid uri instead of a windows // path. _mappings[mapping.targetUrl] = mapping; @@ -196,6 +198,7 @@ class MappingBundle extends Mapping { /// Encodes the Mapping mappings as a json map. List toJson() => _mappings.values.map((v) => v.toJson()).toList(); + @override String toString() { var buff = StringBuffer(); for (var map in _mappings.values) { @@ -206,6 +209,7 @@ class MappingBundle extends Mapping { bool containsMapping(String url) => _mappings.containsKey(url); + @override SourceMapSpan spanFor(int line, int column, {Map files, String uri}) { if (uri == null) { @@ -223,7 +227,7 @@ class MappingBundle extends Mapping { // urls as "package:package_name" would be one path segment when we want // "package" and "package_name" to be sepearate path segments. - bool onBoundary = true; + var onBoundary = true; var separatorCodeUnits = ['/'.codeUnitAt(0), ':'.codeUnitAt(0)]; for (var i = 0; i < uri.length; ++i) { if (onBoundary) { @@ -245,7 +249,7 @@ class MappingBundle extends Mapping { var offset = line * 1000000 + column; var location = SourceLocation(offset, line: line, column: column, sourceUrl: Uri.parse(uri)); - return SourceMapSpan(location, location, ""); + return SourceMapSpan(location, location, ''); } } @@ -351,18 +355,18 @@ class SingleMapping extends Mapping { files[i] = SourceFile.fromString(source, url: urls[i]); } - int line = 0; - int column = 0; - int srcUrlId = 0; - int srcLine = 0; - int srcColumn = 0; - int srcNameId = 0; + var line = 0; + var column = 0; + var srcUrlId = 0; + var srcLine = 0; + var srcColumn = 0; + var srcNameId = 0; var tokenizer = _MappingTokenizer(map['mappings']); var entries = []; while (tokenizer.hasTokens) { if (tokenizer.nextKind.isNewLine) { - if (!entries.isEmpty) { + if (entries.isNotEmpty) { lines.add(TargetLineEntry(line, entries)); entries = []; } @@ -410,12 +414,12 @@ class SingleMapping extends Mapping { } if (tokenizer.nextKind.isNewSegment) tokenizer._consumeNewSegment(); } - if (!entries.isEmpty) { + if (entries.isNotEmpty) { lines.add(TargetLineEntry(line, entries)); } map.forEach((name, value) { - if (name.startsWith("x_")) extensions[name] = value; + if (name.startsWith('x_')) extensions[name] = value; }); } @@ -434,9 +438,9 @@ class SingleMapping extends Mapping { var first = true; for (var entry in lines) { - int nextLine = entry.line; + var nextLine = entry.line; if (nextLine > line) { - for (int i = line; i < nextLine; ++i) { + for (var i = line; i < nextLine; ++i) { buff.write(';'); } line = nextLine; @@ -464,7 +468,7 @@ class SingleMapping extends Mapping { var result = { 'version': 3, - 'sourceRoot': sourceRoot == null ? '' : sourceRoot, + 'sourceRoot': sourceRoot ?? '', 'sources': urls, 'names': names, 'mappings': buff.toString() @@ -486,7 +490,7 @@ class SingleMapping extends Mapping { return newValue; } - _segmentError(int seen, int line) => + StateError _segmentError(int seen, int line) => StateError('Invalid entry in sourcemap, expected 1, 4, or 5' ' values, but got $seen.\ntargeturl: $targetUrl, line: $line'); @@ -494,7 +498,7 @@ class SingleMapping extends Mapping { /// number. In particular, the resulting entry is the last entry whose line /// number is lower or equal to [line]. TargetLineEntry _findLine(int line) { - int index = binarySearch(lines, (e) => e.line > line); + var index = binarySearch(lines, (e) => e.line > line); return (index <= 0) ? null : lines[index - 1]; } @@ -504,13 +508,14 @@ class SingleMapping extends Mapping { /// [lineEntry] corresponds to a line prior to [line], then the result will be /// the very last entry on that line. TargetEntry _findColumn(int line, int column, TargetLineEntry lineEntry) { - if (lineEntry == null || lineEntry.entries.length == 0) return null; + if (lineEntry == null || lineEntry.entries.isEmpty) return null; if (lineEntry.line != line) return lineEntry.entries.last; var entries = lineEntry.entries; - int index = binarySearch(entries, (e) => e.column > column); + var index = binarySearch(entries, (e) => e.column > column); return (index <= 0) ? null : entries[index - 1]; } + @override SourceMapSpan spanFor(int line, int column, {Map files, String uri}) { var entry = _findColumn(line, column, _findLine(line)); @@ -544,8 +549,9 @@ class SingleMapping extends Mapping { } } + @override String toString() { - return (StringBuffer("$runtimeType : [") + return (StringBuffer('$runtimeType : [') ..write('targetUrl: ') ..write(targetUrl) ..write(', sourceRoot: ') @@ -597,6 +603,7 @@ class TargetLineEntry { List entries; TargetLineEntry(this.line, this.entries); + @override String toString() => '$runtimeType: $line $entries'; } @@ -614,6 +621,7 @@ class TargetEntry { this.sourceColumn, this.sourceNameId]); + @override String toString() => '$runtimeType: ' '($column, $sourceUrlId, $sourceLine, $sourceColumn, $sourceNameId)'; } @@ -628,7 +636,9 @@ class _MappingTokenizer implements Iterator { _length = internal.length; // Iterator API is used by decodeVlq to consume VLQ entries. + @override bool moveNext() => ++index < _length; + @override String get current => (index >= 0 && index < _length) ? _internal[index] : null; @@ -653,15 +663,16 @@ class _MappingTokenizer implements Iterator { // Print the state of the iterator, with colors indicating the current // position. + @override String toString() { var buff = StringBuffer(); - for (int i = 0; i < index; i++) { + for (var i = 0; i < index; i++) { buff.write(_internal[i]); } buff.write(''); - buff.write(current == null ? '' : current); + buff.write(current ?? ''); buff.write(''); - for (int i = index + 1; i < _internal.length; i++) { + for (var i = index + 1; i < _internal.length; i++) { buff.write(_internal[i]); } buff.write(' ($index)'); diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index beadbdd4e..24eec6429 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -41,7 +41,7 @@ class Printer { void add(String str, {projectMarks = false}) { var chars = str.runes.toList(); var length = chars.length; - for (int i = 0; i < length; i++) { + for (var i = 0; i < length; i++) { var c = chars[i]; if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) { // Return not followed by line-feed is treated as a new line. @@ -66,7 +66,9 @@ class Printer { /// Append a [total] number of spaces in the target file. Typically used for /// formatting indentation. void addSpaces(int total) { - for (int i = 0; i < total; i++) _buff.write(' '); + for (var i = 0; i < total; i++) { + _buff.write(' '); + } _column += total; } @@ -76,8 +78,8 @@ class Printer { /// this also records the name of the identifier in the source map /// information. void mark(mark) { - var loc; - var identifier = null; + SourceLocation loc; + String identifier; if (mark is SourceLocation) { loc = mark; } else if (mark is SourceSpan) { @@ -101,7 +103,7 @@ class NestedPrinter implements NestedItem { /// Items recoded by this printer, which can be [String] literals, /// [NestedItem]s, and source map information like [SourceLocation] and /// [SourceSpan]. - List _items = []; + final _items = []; /// Internal buffer to merge consecutive strings added to this printer. StringBuffer _buff; @@ -178,7 +180,7 @@ class NestedPrinter implements NestedItem { /// Appends a string merging it with any previous strings, if possible. void _appendString(String s) { - if (_buff == null) _buff = StringBuffer(); + _buff ??= StringBuffer(); _buff.write(s); } @@ -191,11 +193,14 @@ class NestedPrinter implements NestedItem { } void _indent(int indent) { - for (int i = 0; i < indent; i++) _appendString(' '); + for (var i = 0; i < indent; i++) { + _appendString(' '); + } } /// Returns a string representation of all the contents appended to this /// printer, including source map location tokens. + @override String toString() { _flush(); return (StringBuffer()..writeAll(_items)).toString(); @@ -218,9 +223,10 @@ class NestedPrinter implements NestedItem { } /// Implements the [NestedItem] interface. + @override void writeTo(Printer printer) { _flush(); - bool propagate = false; + var propagate = false; for (var item in _items) { if (item is NestedItem) { item.writeTo(printer); diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 34eabf816..32daf326c 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -24,7 +24,7 @@ class TextEditTransaction { /// Creates a new transaction. TextEditTransaction(this.original, this.file); - bool get hasEdits => _edits.length > 0; + bool get hasEdits => _edits.isNotEmpty; /// Edit the original text, replacing text on the range [begin] and [end] /// with the [replacement]. [replacement] can be either a string or a @@ -46,14 +46,14 @@ class TextEditTransaction { /// made, the printer simply contains the original string. NestedPrinter commit() { var printer = NestedPrinter(); - if (_edits.length == 0) { + if (_edits.isEmpty) { return printer..add(original, location: _loc(0), isOriginal: true); } // Sort edits by start location. _edits.sort(); - int consumed = 0; + var consumed = 0; for (var edit in _edits) { if (consumed > edit.begin) { var sb = StringBuffer(); @@ -64,7 +64,9 @@ class TextEditTransaction { ..write(' but have consumed ') ..write(consumed) ..write(' input characters. List of edits:'); - for (var e in _edits) sb..write('\n ')..write(e); + for (var e in _edits) { + sb..write('\n ')..write(e); + } throw UnsupportedError(sb.toString()); } @@ -95,10 +97,12 @@ class _TextEdit implements Comparable<_TextEdit> { int get length => end - begin; + @override String toString() => '(Edit @ $begin,$end: "$replace")'; + @override int compareTo(_TextEdit other) { - int diff = begin - other.begin; + var diff = begin - other.begin; if (diff != 0) return diff; return end - other.end; } @@ -107,8 +111,8 @@ class _TextEdit implements Comparable<_TextEdit> { /// Returns all whitespace characters at the start of [charOffset]'s line. String guessIndent(String code, int charOffset) { // Find the beginning of the line - int lineStart = 0; - for (int i = charOffset - 1; i >= 0; i--) { + var lineStart = 0; + for (var i = charOffset - 1; i >= 0; i--) { var c = code.codeUnitAt(i); if (c == _LF || c == _CR) { lineStart = i + 1; @@ -117,8 +121,8 @@ String guessIndent(String code, int charOffset) { } // Grab all the whitespace - int whitespaceEnd = code.length; - for (int i = lineStart; i < code.length; i++) { + var whitespaceEnd = code.length; + for (var i = lineStart; i < code.length; i++) { var c = code.codeUnitAt(i); if (c != _SPACE && c != _TAB) { whitespaceEnd = i; diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 953190341..e77ac5967 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -37,8 +37,8 @@ /// [pkg]: http://pub.dartlang.org/packages/source_maps library source_maps; -export "builder.dart"; -export "parser.dart"; -export "printer.dart"; -export "refactor.dart"; +export 'builder.dart'; +export 'parser.dart'; +export 'printer.dart'; +export 'refactor.dart'; export 'src/source_map_span.dart'; diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index ba67027d5..b8f1152f7 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -38,24 +38,38 @@ class SourceMapSpan extends SourceSpanBase { /// A wrapper aruond a [FileSpan] that implements [SourceMapSpan]. class SourceMapFileSpan implements SourceMapSpan, FileSpan { final FileSpan _inner; + @override final bool isIdentifier; + @override SourceFile get file => _inner.file; + @override FileLocation get start => _inner.start; + @override FileLocation get end => _inner.end; + @override String get text => _inner.text; + @override String get context => _inner.context; + @override Uri get sourceUrl => _inner.sourceUrl; + @override int get length => _inner.length; SourceMapFileSpan(this._inner, {this.isIdentifier = false}); + @override int compareTo(SourceSpan other) => _inner.compareTo(other); + @override String highlight({color}) => _inner.highlight(color: color); + @override SourceSpan union(SourceSpan other) => _inner.union(other); + @override FileSpan expand(FileSpan other) => _inner.expand(other); + @override String message(String message, {color}) => _inner.message(message, color: color); + @override String toString() => - _inner.toString().replaceAll("FileSpan", "SourceMapFileSpan"); + _inner.toString().replaceAll('FileSpan', 'SourceMapFileSpan'); } diff --git a/pkgs/source_maps/lib/src/utils.dart b/pkgs/source_maps/lib/src/utils.dart index 78f098e70..f9870d2f3 100644 --- a/pkgs/source_maps/lib/src/utils.dart +++ b/pkgs/source_maps/lib/src/utils.dart @@ -10,13 +10,13 @@ library source_maps.utils; /// and all items after `n` match too. The result is -1 when there are no /// items, 0 when all items match, and list.length when none does. // TODO(sigmund): remove this function after dartbug.com/5624 is fixed. -int binarySearch(List list, bool matches(item)) { - if (list.length == 0) return -1; +int binarySearch(List list, bool Function(dynamic) matches) { + if (list.isEmpty) return -1; if (matches(list.first)) return 0; if (!matches(list.last)) return list.length; - int min = 0; - int max = list.length - 1; + var min = 0; + var max = list.length - 1; while (min < max) { var half = min + ((max - min) ~/ 2); if (matches(list[half])) { diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index ebae139fd..de3ab27e9 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -28,7 +28,7 @@ const String BASE64_DIGITS = final Map _digits = () { var map = {}; - for (int i = 0; i < 64; i++) { + for (var i = 0; i < 64; i++) { map[BASE64_DIGITS[i]] = i; } return map; @@ -43,14 +43,14 @@ Iterable encodeVlq(int value) { throw ArgumentError('expected 32 bit int, got: $value'); } var res = []; - int signBit = 0; + var signBit = 0; if (value < 0) { signBit = 1; value = -value; } value = (value << 1) | signBit; do { - int digit = value & VLQ_BASE_MASK; + var digit = value & VLQ_BASE_MASK; value >>= VLQ_BASE_SHIFT; if (value > 0) { digit |= VLQ_CONTINUATION_BIT; @@ -65,9 +65,9 @@ Iterable encodeVlq(int value) { /// iterator is advanced until a stop character is found (a character without /// the [VLQ_CONTINUATION_BIT]). int decodeVlq(Iterator chars) { - int result = 0; - bool stop = false; - int shift = 0; + var result = 0; + var stop = false; + var shift = 0; while (!stop) { if (!chars.moveNext()) throw StateError('incomplete VLQ value'); var char = chars.current; @@ -89,7 +89,7 @@ int decodeVlq(Iterator chars) { // 5 (101 binary) becomes -2 // 6 (110 binary) becomes 3 // 7 (111 binary) becomes -3 - bool negate = (result & 1) == 1; + var negate = (result & 1) == 1; result = result >> 1; result = negate ? -result : result; diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index 0b2a96512..fddf46c88 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -9,7 +9,7 @@ import 'package:test/test.dart'; import 'package:source_maps/source_maps.dart'; import 'common.dart'; -main() { +void main() { test('builder - with span', () { var map = (SourceMapBuilder() ..addSpan(inputVar1, outputVar1) diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index ef119ec22..c0bed6810 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -71,7 +71,7 @@ const Map EXPECTED_MAP = { 'file': 'output.dart' }; -check(SourceSpan outputSpan, Mapping mapping, SourceMapSpan inputSpan, +void check(SourceSpan outputSpan, Mapping mapping, SourceMapSpan inputSpan, bool realOffsets) { var line = outputSpan.start.line; var column = outputSpan.start.column; diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 28c662556..954339fbd 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -9,7 +9,7 @@ import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; import 'common.dart'; -main() { +void main() { test('end-to-end setup', () { expect(inputVar1.text, 'longVar1'); expect(inputFunction.text, 'longName'); @@ -132,7 +132,7 @@ main() { expect(printer.text, out); var mapping = parse(printer.map); - checkHelper(SourceMapSpan inputSpan, int adjustment) { + void checkHelper(SourceMapSpan inputSpan, int adjustment) { var start = inputSpan.start.offset - adjustment; var end = (inputSpan.end.offset - adjustment) - 2; var span = SourceMapFileSpan(file.span(start, end), diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 6b2f5573f..275efd30a 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -70,7 +70,7 @@ const List SOURCE_MAP_BUNDLE = [ MAP_WITH_SOURCE_LOCATION_AND_NAME_3, ]; -main() { +void main() { test('parse', () { var mapping = parseJson(EXPECTED_MAP); check(outputVar1, mapping, inputVar1, false); @@ -99,7 +99,7 @@ main() { SingleMapping map = parse(jsonEncode(MAP_WITH_NO_SOURCE_LOCATION)); expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); - TargetEntry entry = map.lines.first.entries.first; + var entry = map.lines.first.entries.first; expect(entry.column, 0); expect(entry.sourceUrlId, null); @@ -112,7 +112,7 @@ main() { SingleMapping map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION)); expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); - TargetEntry entry = map.lines.first.entries.first; + var entry = map.lines.first.entries.first; expect(entry.column, 0); expect(entry.sourceUrlId, 0); @@ -125,7 +125,7 @@ main() { SingleMapping map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_NAME)); expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); - TargetEntry entry = map.lines.first.entries.first; + var entry = map.lines.first.entries.first; expect(entry.sourceUrlId, 0); expect(entry.sourceUrlId, 0); @@ -138,18 +138,18 @@ main() { var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = '/pkg/'; var mapping = parseJson(inputMap) as SingleMapping; - expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse("/pkg/input.dart")); + expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse('/pkg/input.dart')); expect( mapping .spanForLocation( - SourceLocation(0, sourceUrl: Uri.parse("ignored.dart"))) + SourceLocation(0, sourceUrl: Uri.parse('ignored.dart'))) .sourceUrl, - Uri.parse("/pkg/input.dart")); + Uri.parse('/pkg/input.dart')); var newSourceRoot = '/new/'; mapping.sourceRoot = newSourceRoot; - inputMap["sourceRoot"] = newSourceRoot; + inputMap['sourceRoot'] = newSourceRoot; expect(mapping.toJson(), equals(inputMap)); }); @@ -157,14 +157,14 @@ main() { test('parse with map URL', () { var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = 'pkg/'; - var mapping = parseJson(inputMap, mapUrl: "file:///path/to/map"); + var mapping = parseJson(inputMap, mapUrl: 'file:///path/to/map'); expect(mapping.spanFor(0, 0).sourceUrl, - Uri.parse("file:///path/to/pkg/input.dart")); + Uri.parse('file:///path/to/pkg/input.dart')); }); group('parse with bundle', () { var mapping = - parseJsonExtended(SOURCE_MAP_BUNDLE, mapUrl: "file:///path/to/map"); + parseJsonExtended(SOURCE_MAP_BUNDLE, mapUrl: 'file:///path/to/map'); test('simple', () { expect( @@ -172,29 +172,29 @@ main() { .spanForLocation(SourceLocation(0, sourceUrl: Uri.file('/path/to/output.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); + Uri.parse('file:///path/to/pkg/input1.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.file('/path/to/output2.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); + Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.file('/path/to/3/output.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + Uri.parse('file:///path/to/pkg/input3.dart')); expect( - mapping.spanFor(0, 0, uri: "file:///path/to/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); + mapping.spanFor(0, 0, uri: 'file:///path/to/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input1.dart')); expect( - mapping.spanFor(0, 0, uri: "file:///path/to/output2.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); + mapping.spanFor(0, 0, uri: 'file:///path/to/output2.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input2.dart')); expect( - mapping.spanFor(0, 0, uri: "file:///path/to/3/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + mapping.spanFor(0, 0, uri: 'file:///path/to/3/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input3.dart')); }); test('package uris', () { @@ -203,36 +203,36 @@ main() { .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:1/output.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); + Uri.parse('file:///path/to/pkg/input1.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:2/output2.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); + Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:3/output.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); - - expect(mapping.spanFor(0, 0, uri: "package:1/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); - expect(mapping.spanFor(0, 0, uri: "package:2/output2.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); - expect(mapping.spanFor(0, 0, uri: "package:3/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + Uri.parse('file:///path/to/pkg/input3.dart')); + + expect(mapping.spanFor(0, 0, uri: 'package:1/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input1.dart')); + expect(mapping.spanFor(0, 0, uri: 'package:2/output2.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input2.dart')); + expect(mapping.spanFor(0, 0, uri: 'package:3/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input3.dart')); }); test('unmapped path', () { - var span = mapping.spanFor(0, 0, uri: "unmapped_output.dart"); - expect(span.sourceUrl, Uri.parse("unmapped_output.dart")); + var span = mapping.spanFor(0, 0, uri: 'unmapped_output.dart'); + expect(span.sourceUrl, Uri.parse('unmapped_output.dart')); expect(span.start.line, equals(0)); expect(span.start.column, equals(0)); - span = mapping.spanFor(10, 5, uri: "unmapped_output.dart"); - expect(span.sourceUrl, Uri.parse("unmapped_output.dart")); + span = mapping.spanFor(10, 5, uri: 'unmapped_output.dart'); + expect(span.sourceUrl, Uri.parse('unmapped_output.dart')); expect(span.start.line, equals(10)); expect(span.start.column, equals(5)); }); @@ -242,47 +242,47 @@ main() { }); test('incomplete paths', () { - expect(mapping.spanFor(0, 0, uri: "output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); - expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); - expect(mapping.spanFor(0, 0, uri: "3/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + expect(mapping.spanFor(0, 0, uri: 'output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input1.dart')); + expect(mapping.spanFor(0, 0, uri: 'output2.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input2.dart')); + expect(mapping.spanFor(0, 0, uri: '3/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input3.dart')); }); test('parseExtended', () { var mapping = parseExtended(jsonEncode(SOURCE_MAP_BUNDLE), - mapUrl: "file:///path/to/map"); - - expect(mapping.spanFor(0, 0, uri: "output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); - expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); - expect(mapping.spanFor(0, 0, uri: "3/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + mapUrl: 'file:///path/to/map'); + + expect(mapping.spanFor(0, 0, uri: 'output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input1.dart')); + expect(mapping.spanFor(0, 0, uri: 'output2.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input2.dart')); + expect(mapping.spanFor(0, 0, uri: '3/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input3.dart')); }); test('build bundle incrementally', () { var mapping = MappingBundle(); mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_1, - mapUrl: "file:///path/to/map")); - expect(mapping.spanFor(0, 0, uri: "output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); + mapUrl: 'file:///path/to/map')); + expect(mapping.spanFor(0, 0, uri: 'output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input1.dart')); - expect(mapping.containsMapping("output2.dart"), isFalse); + expect(mapping.containsMapping('output2.dart'), isFalse); mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_2, - mapUrl: "file:///path/to/map")); - expect(mapping.containsMapping("output2.dart"), isTrue); - expect(mapping.spanFor(0, 0, uri: "output2.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); + mapUrl: 'file:///path/to/map')); + expect(mapping.containsMapping('output2.dart'), isTrue); + expect(mapping.spanFor(0, 0, uri: 'output2.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input2.dart')); - expect(mapping.containsMapping("3/output.dart"), isFalse); + expect(mapping.containsMapping('3/output.dart'), isFalse); mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_3, - mapUrl: "file:///path/to/map")); - expect(mapping.containsMapping("3/output.dart"), isTrue); - expect(mapping.spanFor(0, 0, uri: "3/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + mapUrl: 'file:///path/to/map')); + expect(mapping.containsMapping('3/output.dart'), isTrue); + expect(mapping.spanFor(0, 0, uri: '3/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input3.dart')); }); // Test that the source map can handle cases where the uri passed in is @@ -294,31 +294,31 @@ main() { .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/output.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); + Uri.parse('file:///path/to/pkg/input1.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/output2.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); + Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/3/output.dart'))) .sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + Uri.parse('file:///path/to/pkg/input3.dart')); expect( - mapping.spanFor(0, 0, uri: "http://localhost/output.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input1.dart")); + mapping.spanFor(0, 0, uri: 'http://localhost/output.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input1.dart')); expect( - mapping.spanFor(0, 0, uri: "http://localhost/output2.dart").sourceUrl, - Uri.parse("file:///path/to/pkg/input2.dart")); + mapping.spanFor(0, 0, uri: 'http://localhost/output2.dart').sourceUrl, + Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping - .spanFor(0, 0, uri: "http://localhost/3/output.dart") + .spanFor(0, 0, uri: 'http://localhost/3/output.dart') .sourceUrl, - Uri.parse("file:///path/to/pkg/input3.dart")); + Uri.parse('file:///path/to/pkg/input3.dart')); }); }); @@ -344,17 +344,17 @@ main() { test('parse extensions', () { var map = Map.from(EXPECTED_MAP); - map["x_foo"] = "a"; - map["x_bar"] = [3]; + map['x_foo'] = 'a'; + map['x_bar'] = [3]; SingleMapping mapping = parseJson(map); expect(mapping.toJson(), equals(map)); - expect(mapping.extensions["x_foo"], equals("a")); - expect(mapping.extensions["x_bar"].first, equals(3)); + expect(mapping.extensions['x_foo'], equals('a')); + expect(mapping.extensions['x_bar'].first, equals(3)); }); - group("source files", () { - group("from fromEntries()", () { - test("are null for non-FileLocations", () { + group('source files', () { + group('from fromEntries()', () { + test('are null for non-FileLocations', () { var mapping = SingleMapping.fromEntries([ Entry(SourceLocation(10, line: 1, column: 8), outputVar1.start, null) ]); @@ -368,36 +368,36 @@ main() { }); }); - group("from parse()", () { - group("are null", () { - test("with no sourcesContent field", () { + group('from parse()', () { + group('are null', () { + test('with no sourcesContent field', () { var mapping = parseJson(EXPECTED_MAP) as SingleMapping; expect(mapping.files, equals([null])); }); - test("with null sourcesContent values", () { + test('with null sourcesContent values', () { var map = Map.from(EXPECTED_MAP); - map["sourcesContent"] = [null]; + map['sourcesContent'] = [null]; var mapping = parseJson(map) as SingleMapping; expect(mapping.files, equals([null])); }); - test("with a too-short sourcesContent", () { + test('with a too-short sourcesContent', () { var map = Map.from(EXPECTED_MAP); - map["sourcesContent"] = []; + map['sourcesContent'] = []; var mapping = parseJson(map) as SingleMapping; expect(mapping.files, equals([null])); }); }); - test("are parsed from sourcesContent", () { + test('are parsed from sourcesContent', () { var map = Map.from(EXPECTED_MAP); - map["sourcesContent"] = ["hello, world!"]; + map['sourcesContent'] = ['hello, world!']; var mapping = parseJson(map) as SingleMapping; var file = mapping.files[0]; - expect(file.url, equals(Uri.parse("input.dart"))); - expect(file.getText(0), equals("hello, world!")); + expect(file.url, equals(Uri.parse('input.dart'))); + expect(file.getText(0), equals('hello, world!')); }); }); }); diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index a2479073a..fc7991359 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -10,7 +10,7 @@ import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; import 'common.dart'; -main() { +void main() { test('printer', () { var printer = Printer('output.dart'); printer @@ -55,7 +55,7 @@ main() { // 8 new lines in the source map: expect(printer.map.split(';').length, 8); - asFixed(SourceMapSpan s) => + SourceMapSpan asFixed(SourceMapSpan s) => SourceMapSpan(s.start, s.end, s.text, isIdentifier: s.isIdentifier); // The result is the same if we use fixed positions @@ -114,7 +114,7 @@ main() { var lines = INPUT.trim().split('\n'); expect(lines.length, 7); var printer = NestedPrinter(); - for (int i = 0; i < lines.length; i++) { + for (var i = 0; i < lines.length; i++) { if (i == 5) printer.indent++; printer.addLine(lines[i].replaceAll('long', '_s').trim()); if (i == 5) printer.indent--; diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 552081ae9..36b934a8d 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -10,13 +10,13 @@ import 'package:source_maps/parser.dart' show parse, Mapping; import 'package:source_span/source_span.dart'; import 'package:term_glyph/term_glyph.dart' as term_glyph; -main() { +void main() { setUpAll(() { term_glyph.ascii = true; }); group('conflict detection', () { - var original = "0123456789abcdefghij"; + var original = '0123456789abcdefghij'; var file = SourceFile.fromString(original); test('no conflict, in order', () { @@ -25,7 +25,7 @@ main() { txn.edit(5, 5, '|'); txn.edit(6, 6, '-'); txn.edit(6, 7, '_'); - expect((txn.commit()..build('')).text, "01.4|5-_789abcdefghij"); + expect((txn.commit()..build('')).text, '01.4|5-_789abcdefghij'); }); test('no conflict, out of order', () { @@ -37,7 +37,7 @@ main() { // that don't remove any of the original code. txn.edit(6, 7, '_'); txn.edit(6, 6, '-'); - expect((txn.commit()..build('')).text, "01.4|5-_789abcdefghij"); + expect((txn.commit()..build('')).text, '01.4|5-_789abcdefghij'); }); test('conflict', () { @@ -53,7 +53,7 @@ main() { test('generated source maps', () { var original = - "0123456789\n0*23456789\n01*3456789\nabcdefghij\nabcd*fghij\n"; + '0123456789\n0*23456789\n01*3456789\nabcdefghij\nabcd*fghij\n'; var file = SourceFile.fromString(original); var txn = TextEditTransaction(original, file); txn.edit(27, 29, '__\n '); @@ -62,70 +62,70 @@ main() { var output = printer.text; var map = parse(printer.map); expect(output, - "0123456789\n0*23456789\n01*34__\n 789\na___cdefghij\nabcd*fghij\n"); + '0123456789\n0*23456789\n01*34__\n 789\na___cdefghij\nabcd*fghij\n'); // Line 1 and 2 are unmodified: mapping any column returns the beginning // of the corresponding line: expect( _span(1, 1, map, file), - "line 1, column 1: \n" - " ,\n" - "1 | 0123456789\n" - " | ^\n" + 'line 1, column 1: \n' + ' ,\n' + '1 | 0123456789\n' + ' | ^\n' " '"); expect( _span(1, 5, map, file), - "line 1, column 1: \n" - " ,\n" - "1 | 0123456789\n" - " | ^\n" + 'line 1, column 1: \n' + ' ,\n' + '1 | 0123456789\n' + ' | ^\n' " '"); expect( _span(2, 1, map, file), - "line 2, column 1: \n" - " ,\n" - "2 | 0*23456789\n" - " | ^\n" + 'line 2, column 1: \n' + ' ,\n' + '2 | 0*23456789\n' + ' | ^\n' " '"); expect( _span(2, 8, map, file), - "line 2, column 1: \n" - " ,\n" - "2 | 0*23456789\n" - " | ^\n" + 'line 2, column 1: \n' + ' ,\n' + '2 | 0*23456789\n' + ' | ^\n' " '"); // Line 3 is modified part way: mappings before the edits have the right // mapping, after the edits the mapping is null. expect( _span(3, 1, map, file), - "line 3, column 1: \n" - " ,\n" - "3 | 01*3456789\n" - " | ^\n" + 'line 3, column 1: \n' + ' ,\n' + '3 | 01*3456789\n' + ' | ^\n' " '"); expect( _span(3, 5, map, file), - "line 3, column 1: \n" - " ,\n" - "3 | 01*3456789\n" - " | ^\n" + 'line 3, column 1: \n' + ' ,\n' + '3 | 01*3456789\n' + ' | ^\n' " '"); // Start of edits map to beginning of the edit secion: expect( _span(3, 6, map, file), - "line 3, column 6: \n" - " ,\n" - "3 | 01*3456789\n" - " | ^\n" + 'line 3, column 6: \n' + ' ,\n' + '3 | 01*3456789\n' + ' | ^\n' " '"); expect( _span(3, 7, map, file), - "line 3, column 6: \n" - " ,\n" - "3 | 01*3456789\n" - " | ^\n" + 'line 3, column 6: \n' + ' ,\n' + '3 | 01*3456789\n' + ' | ^\n' " '"); // Lines added have no mapping (they should inherit the last mapping), @@ -133,66 +133,66 @@ main() { expect(_span(4, 1, map, file), isNull); expect( _span(4, 5, map, file), - "line 3, column 8: \n" - " ,\n" - "3 | 01*3456789\n" - " | ^\n" + 'line 3, column 8: \n' + ' ,\n' + '3 | 01*3456789\n' + ' | ^\n' " '"); // Subsequent lines are still mapped correctly: // a (in a___cd...) expect( _span(5, 1, map, file), - "line 4, column 1: \n" - " ,\n" - "4 | abcdefghij\n" - " | ^\n" + 'line 4, column 1: \n' + ' ,\n' + '4 | abcdefghij\n' + ' | ^\n' " '"); // _ (in a___cd...) expect( _span(5, 2, map, file), - "line 4, column 2: \n" - " ,\n" - "4 | abcdefghij\n" - " | ^\n" + 'line 4, column 2: \n' + ' ,\n' + '4 | abcdefghij\n' + ' | ^\n' " '"); // _ (in a___cd...) expect( _span(5, 3, map, file), - "line 4, column 2: \n" - " ,\n" - "4 | abcdefghij\n" - " | ^\n" + 'line 4, column 2: \n' + ' ,\n' + '4 | abcdefghij\n' + ' | ^\n' " '"); // _ (in a___cd...) expect( _span(5, 4, map, file), - "line 4, column 2: \n" - " ,\n" - "4 | abcdefghij\n" - " | ^\n" + 'line 4, column 2: \n' + ' ,\n' + '4 | abcdefghij\n' + ' | ^\n' " '"); // c (in a___cd...) expect( _span(5, 5, map, file), - "line 4, column 3: \n" - " ,\n" - "4 | abcdefghij\n" - " | ^\n" + 'line 4, column 3: \n' + ' ,\n' + '4 | abcdefghij\n' + ' | ^\n' " '"); expect( _span(6, 1, map, file), - "line 5, column 1: \n" - " ,\n" - "5 | abcd*fghij\n" - " | ^\n" + 'line 5, column 1: \n' + ' ,\n' + '5 | abcd*fghij\n' + ' | ^\n' " '"); expect( _span(6, 8, map, file), - "line 5, column 1: \n" - " ,\n" - "5 | abcd*fghij\n" - " | ^\n" + 'line 5, column 1: \n' + ' ,\n' + '5 | abcd*fghij\n' + ' | ^\n' " '"); }); } diff --git a/pkgs/source_maps/test/utils_test.dart b/pkgs/source_maps/test/utils_test.dart index 6790082aa..3064d6b22 100644 --- a/pkgs/source_maps/test/utils_test.dart +++ b/pkgs/source_maps/test/utils_test.dart @@ -8,7 +8,7 @@ library test.utils_test; import 'package:test/test.dart'; import 'package:source_maps/src/utils.dart'; -main() { +void main() { group('binary search', () { test('empty', () { expect(binarySearch([], (x) => true), -1); @@ -30,12 +30,12 @@ main() { }); test('compare with linear search', () { - for (int size = 0; size < 100; size++) { + for (var size = 0; size < 100; size++) { var list = []; - for (int i = 0; i < size; i++) { + for (var i = 0; i < size; i++) { list.add(i); } - for (int pos = 0; pos <= size; pos++) { + for (var pos = 0; pos <= size; pos++) { expect(binarySearch(list, (x) => x >= pos), _linearSearch(list, (x) => x >= pos)); } @@ -44,9 +44,9 @@ main() { }); } -_linearSearch(list, predicate) { +int _linearSearch(list, predicate) { if (list.length == 0) return -1; - for (int i = 0; i < list.length; i++) { + for (var i = 0; i < list.length; i++) { if (predicate(list[i])) return i; } return list.length; diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index f97989f2b..6021519dd 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -8,7 +8,7 @@ import 'dart:math'; import 'package:test/test.dart'; import 'package:source_maps/src/vlq.dart'; -main() { +void main() { test('encode and decode - simple values', () { expect(encodeVlq(1).join(''), 'C'); expect(encodeVlq(2).join(''), 'E'); @@ -21,7 +21,7 @@ main() { }); test('encode and decode', () { - for (int i = -10000; i < 10000; i++) { + for (var i = -10000; i < 10000; i++) { _checkEncodeDecode(i); } }); @@ -50,10 +50,10 @@ main() { expect(() => decodeVlq('lgggggE'.split('').iterator), throwsA(anything)); }, // This test uses integers so large they overflow in JS. - testOn: "dart-vm"); + testOn: 'dart-vm'); } -_checkEncodeDecode(int value) { +void _checkEncodeDecode(int value) { var encoded = encodeVlq(value); expect(decodeVlq(encoded.iterator), value); expect(decodeVlq(encoded.join('').split('').iterator), value); From fe4d2e4f339582570525b5776f62030ee0ffd915 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 18 Dec 2019 17:54:39 -0800 Subject: [PATCH 320/657] Fix new pedantic lints, disallow implicit casts (dart-lang/pub_semver#40) - annotate_overrides - prefer_single_quotes There is a minor breaking change in `VersionConstraint.unionOf` if any callers were passing a custom subtype of `VersionConstraint` and _also_ always had a constraint with `.isAny` of `true`. There are no known remaining callers of this API and it should be removed - allowing a technically breaking change that no one will hit allows us to have nice static types within the method. --- pkgs/pub_semver/analysis_options.yaml | 6 +- pkgs/pub_semver/lib/src/patterns.dart | 4 +- pkgs/pub_semver/lib/src/version.dart | 41 ++-- .../lib/src/version_constraint.dart | 29 +-- pkgs/pub_semver/lib/src/version_range.dart | 17 +- pkgs/pub_semver/lib/src/version_union.dart | 22 +- pkgs/pub_semver/test/utils.dart | 3 + .../test/version_constraint_test.dart | 16 +- pkgs/pub_semver/test/version_range_test.dart | 214 +++++++++--------- pkgs/pub_semver/test/version_test.dart | 16 +- pkgs/pub_semver/test/version_union_test.dart | 34 +-- 11 files changed, 224 insertions(+), 178 deletions(-) diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index c970ea7aa..248e8c6d7 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -1,7 +1,9 @@ include: package:pedantic/analysis_options.yaml + analyzer: -# strong-mode: -# implicit-casts: false + strong-mode: + implicit-casts: false + linter: rules: - always_declare_return_types diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart index 8829447fa..d5f189711 100644 --- a/pkgs/pub_semver/lib/src/patterns.dart +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -13,7 +13,7 @@ final completeVersion = RegExp('${startVersion.pattern}\$'); /// Parses a comparison operator ("<", ">", "<=", or ">=") at the beginning of /// a string. -final startComparison = RegExp(r"^[<>]=?"); +final startComparison = RegExp(r'^[<>]=?'); /// The "compatible with" operator. -const compatibleWithChar = "^"; +const compatibleWithChar = '^'; diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 031af5201..eb38409dc 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -83,9 +83,13 @@ class Version implements VersionConstraint, VersionRange { /// of the parsed version. final String _text; + @override Version get min => this; + @override Version get max => this; + @override bool get includeMin => true; + @override bool get includeMax => true; Version._(this.major, this.minor, this.patch, String preRelease, String build, @@ -99,9 +103,9 @@ class Version implements VersionConstraint, VersionRange { /// Creates a new [Version] object. factory Version(int major, int minor, int patch, {String pre, String build}) { - var text = "$major.$minor.$patch"; - if (pre != null) text += "-$pre"; - if (build != null) text += "+$build"; + var text = '$major.$minor.$patch'; + if (pre != null) text += '-$pre'; + if (build != null) text += '+$build'; return Version._(major, minor, patch, pre, build, text); } @@ -157,15 +161,16 @@ class Version implements VersionConstraint, VersionRange { }).toList(); } - bool operator ==(other) { - if (other is! Version) return false; - return major == other.major && - minor == other.minor && - patch == other.patch && - _equality.equals(preRelease, other.preRelease) && - _equality.equals(build, other.build); - } + @override + bool operator ==(Object other) => + other is Version && + major == other.major && + minor == other.minor && + patch == other.patch && + _equality.equals(preRelease, other.preRelease) && + _equality.equals(build, other.build); + @override int get hashCode => major ^ minor ^ @@ -178,7 +183,9 @@ class Version implements VersionConstraint, VersionRange { bool operator <=(Version other) => compareTo(other) <= 0; bool operator >=(Version other) => compareTo(other) >= 0; + @override bool get isAny => false; + @override bool get isEmpty => false; /// Whether or not this is a pre-release version. @@ -237,7 +244,7 @@ class Version implements VersionConstraint, VersionRange { } /// Returns the first possible pre-release of this version. - Version get firstPreRelease => Version(major, minor, patch, pre: "0"); + Version get firstPreRelease => Version(major, minor, patch, pre: '0'); /// Returns whether this is the first possible pre-release of its version. bool get isFirstPreRelease => preRelease.length == 1 && preRelease.first == 0; @@ -247,15 +254,20 @@ class Version implements VersionConstraint, VersionRange { Version _incrementPatch() => Version(major, minor, patch + 1); /// Tests if [other] matches this version exactly. + @override bool allows(Version other) => this == other; + @override bool allowsAll(VersionConstraint other) => other.isEmpty || other == this; + @override bool allowsAny(VersionConstraint other) => other.allows(this); + @override VersionConstraint intersect(VersionConstraint other) => other.allows(this) ? this : VersionConstraint.empty; + @override VersionConstraint union(VersionConstraint other) { if (other.allows(this)) return other; @@ -282,9 +294,11 @@ class Version implements VersionConstraint, VersionRange { return VersionConstraint.unionOf([this, other]); } + @override VersionConstraint difference(VersionConstraint other) => other.allows(this) ? VersionConstraint.empty : this; + @override int compareTo(VersionRange other) { if (other is Version) { if (major != other.major) return major.compareTo(other.major); @@ -307,6 +321,7 @@ class Version implements VersionConstraint, VersionRange { } } + @override String toString() => _text; /// Compares a dot-separated component of two versions. @@ -338,7 +353,7 @@ class Version implements VersionConstraint, VersionRange { return 1; } else { // Compare two strings. - return aPart.compareTo(bPart); + return (aPart as String).compareTo(bPart as String); } } } diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 6dfd396f5..ac39b6b18 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -54,7 +54,7 @@ abstract class VersionConstraint { skipWhitespace(); // Handle the "any" constraint. - if (text == "any") return any; + if (text == 'any') return any; // Try to parse and consume a version number. Version matchVersion() { @@ -190,7 +190,7 @@ abstract class VersionConstraint { Iterable constraints) { var constraint = VersionRange(); for (var other in constraints) { - constraint = constraint.intersect(other); + constraint = constraint.intersect(other) as VersionRange; } return constraint; } @@ -201,9 +201,10 @@ abstract class VersionConstraint { /// [constraints] is empty, this returns a constraint that allows no versions. factory VersionConstraint.unionOf(Iterable constraints) { var flattened = constraints.expand((constraint) { - if (constraint.isEmpty) return []; + if (constraint.isEmpty) return []; if (constraint is VersionUnion) return constraint.ranges; - return [constraint]; + if (constraint is VersionRange) return [constraint]; + throw ArgumentError('Unknown VersionConstraint type $constraint.'); }).toList(); if (flattened.isEmpty) return VersionConstraint.empty; @@ -212,14 +213,6 @@ abstract class VersionConstraint { return VersionConstraint.any; } - // Only allow Versions and VersionRanges here so we can more easily reason - // about everything in [flattened]. _EmptyVersions and VersionUnions are - // filtered out above. - for (var constraint in flattened) { - if (constraint is VersionRange) continue; - throw ArgumentError('Unknown VersionConstraint type $constraint.'); - } - flattened.sort(); var merged = []; @@ -230,7 +223,8 @@ abstract class VersionConstraint { !areAdjacent(merged.last, constraint))) { merged.add(constraint); } else { - merged[merged.length - 1] = merged.last.union(constraint); + merged[merged.length - 1] = + merged.last.union(constraint) as VersionRange; } } @@ -271,21 +265,30 @@ abstract class VersionConstraint { class _EmptyVersion implements VersionConstraint { const _EmptyVersion(); + @override bool get isEmpty => true; + @override bool get isAny => false; + @override bool allows(Version other) => false; + @override bool allowsAll(VersionConstraint other) => other.isEmpty; + @override bool allowsAny(VersionConstraint other) => false; + @override VersionConstraint intersect(VersionConstraint other) => this; + @override VersionConstraint union(VersionConstraint other) => other; + @override VersionConstraint difference(VersionConstraint other) => this; + @override String toString() => ''; } diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 8ac79dab8..2c4088426 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -84,6 +84,7 @@ class VersionRange implements Comparable, VersionConstraint { VersionRange._(this.min, this.max, this.includeMin, this.includeMax); + @override bool operator ==(other) { if (other is! VersionRange) return false; @@ -93,17 +94,21 @@ class VersionRange implements Comparable, VersionConstraint { includeMax == other.includeMax; } + @override int get hashCode => min.hashCode ^ (max.hashCode * 3) ^ (includeMin.hashCode * 5) ^ (includeMax.hashCode * 7); + @override bool get isEmpty => false; + @override bool get isAny => min == null && max == null; /// Tests if [other] falls within this version range. + @override bool allows(Version other) { if (min != null) { if (other < min) return false; @@ -118,6 +123,7 @@ class VersionRange implements Comparable, VersionConstraint { return true; } + @override bool allowsAll(VersionConstraint other) { if (other.isEmpty) return true; if (other is Version) return allows(other); @@ -133,6 +139,7 @@ class VersionRange implements Comparable, VersionConstraint { throw ArgumentError('Unknown VersionConstraint type $other.'); } + @override bool allowsAny(VersionConstraint other) { if (other.isEmpty) return false; if (other is Version) return allows(other); @@ -148,6 +155,7 @@ class VersionRange implements Comparable, VersionConstraint { throw ArgumentError('Unknown VersionConstraint type $other.'); } + @override VersionConstraint intersect(VersionConstraint other) { if (other.isEmpty) return other; if (other is VersionUnion) return other.intersect(this); @@ -206,6 +214,7 @@ class VersionRange implements Comparable, VersionConstraint { throw ArgumentError('Unknown VersionConstraint type $other.'); } + @override VersionConstraint union(VersionConstraint other) { if (other is Version) { if (allows(other)) return this; @@ -271,6 +280,7 @@ class VersionRange implements Comparable, VersionConstraint { return VersionConstraint.unionOf([this, other]); } + @override VersionConstraint difference(VersionConstraint other) { if (other.isEmpty) return this; @@ -383,6 +393,7 @@ class VersionRange implements Comparable, VersionConstraint { throw ArgumentError('Unknown VersionConstraint type $other.'); } + @override int compareTo(VersionRange other) { if (min == null) { if (other.min == null) return _compareMax(other); @@ -413,6 +424,7 @@ class VersionRange implements Comparable, VersionConstraint { return 0; } + @override String toString() { var buffer = StringBuffer(); @@ -429,7 +441,7 @@ class VersionRange implements Comparable, VersionConstraint { if (max.isFirstPreRelease) { // Since `"<$max"` would parse the same as `"<$max-0"`, we just emit // `<$max` to avoid confusing "-0" suffixes. - buffer.write("${max.major}.${max.minor}.${max.patch}"); + buffer.write('${max.major}.${max.minor}.${max.patch}'); } else { buffer.write(max); @@ -439,7 +451,7 @@ class VersionRange implements Comparable, VersionConstraint { min.isPreRelease && equalsWithoutPreRelease(min, max); if (!max.isPreRelease && max.build.isEmpty && !minIsPreReleaseOfMax) { - buffer.write("-∞"); + buffer.write('-∞'); } } } @@ -454,5 +466,6 @@ class CompatibleWithVersionRange extends VersionRange { CompatibleWithVersionRange(Version version) : super._(version, version.nextBreaking.firstPreRelease, true, false); + @override String toString() => '^$min'; } diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index b774163ef..8a235220c 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -25,8 +25,10 @@ class VersionUnion implements VersionConstraint { /// those constraints that they don't match. final List ranges; + @override bool get isEmpty => false; + @override bool get isAny => false; /// Creates a union from a list of ranges with no pre-processing. @@ -37,9 +39,11 @@ class VersionUnion implements VersionConstraint { /// VersionConstraint.unionOf] instead. VersionUnion.fromRanges(this.ranges); + @override bool allows(Version version) => ranges.any((constraint) => constraint.allows(version)); + @override bool allowsAll(VersionConstraint other) { var ourRanges = ranges.iterator; var theirRanges = _rangesFor(other).iterator; @@ -61,6 +65,7 @@ class VersionUnion implements VersionConstraint { return theirRanges.current == null; } + @override bool allowsAny(VersionConstraint other) { var ourRanges = ranges.iterator; var theirRanges = _rangesFor(other).iterator; @@ -86,6 +91,7 @@ class VersionUnion implements VersionConstraint { return false; } + @override VersionConstraint intersect(VersionConstraint other) { var ourRanges = ranges.iterator; var theirRanges = _rangesFor(other).iterator; @@ -98,7 +104,7 @@ class VersionUnion implements VersionConstraint { while (ourRanges.current != null && theirRanges.current != null) { var intersection = ourRanges.current.intersect(theirRanges.current); - if (!intersection.isEmpty) newRanges.add(intersection); + if (!intersection.isEmpty) newRanges.add(intersection as VersionRange); // Move the constraint with the lower max value forward. This ensures that // we keep both lists in sync as much as possible, and that large ranges @@ -116,6 +122,7 @@ class VersionUnion implements VersionConstraint { return VersionUnion.fromRanges(newRanges); } + @override VersionConstraint difference(VersionConstraint other) { var ourRanges = ranges.iterator; var theirRanges = _rangesFor(other).iterator; @@ -200,15 +207,18 @@ class VersionUnion implements VersionConstraint { throw ArgumentError('Unknown VersionConstraint type $constraint.'); } + @override VersionConstraint union(VersionConstraint other) => VersionConstraint.unionOf([this, other]); - bool operator ==(other) { - if (other is! VersionUnion) return false; - return const ListEquality().equals(ranges, other.ranges); - } + @override + bool operator ==(Object other) => + other is VersionUnion && + const ListEquality().equals(ranges, other.ranges); + @override int get hashCode => const ListEquality().hash(ranges); - String toString() => ranges.join(" or "); + @override + String toString() => ranges.join(' or '); } diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index a0fd684c1..eb3358a98 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -34,16 +34,19 @@ class _VersionConstraintMatcher implements Matcher { _VersionConstraintMatcher(this._expected, this._allow); + @override bool matches(item, Map matchState) => (item is VersionConstraint) && _expected.every((version) => item.allows(version) == _allow); + @override Description describe(Description description) { description.addAll(' ${_allow ? "allows" : "does not allow"} versions ', ', ', '', _expected); return description; } + @override Description describeMismatch( item, Description mismatchDescription, Map matchState, bool verbose) { if (item is! VersionConstraint) { diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index 1e48391ee..c9d8e611b 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -152,14 +152,14 @@ void main() { test('throws FormatException on a bad string', () { var bad = [ - "", " ", // Empty string. - "foo", // Bad text. - ">foo", // Bad text after operator. - "^foo", // Bad text after "^". - "1.0.0 foo", "1.0.0foo", // Bad text after version. - "anything", // Bad text after "any". - "<>1.0.0", // Multiple operators. - "1.0.0<" // Trailing operator. + '', ' ', // Empty string. + 'foo', // Bad text. + '>foo', // Bad text after operator. + '^foo', // Bad text after "^". + '1.0.0 foo', '1.0.0foo', // Bad text after version. + 'anything', // Bad text after "any". + '<>1.0.0', // Multiple operators. + '1.0.0<' // Trailing operator. ]; for (var text in bad) { diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index cfd66d975..bf280c23c 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -19,22 +19,22 @@ void main() { group("doesn't make the max a pre-release if", () { test("it's already a pre-release", () { - expect(VersionRange(max: Version.parse("1.2.4-pre")).max, - equals(Version.parse("1.2.4-pre"))); + expect(VersionRange(max: Version.parse('1.2.4-pre')).max, + equals(Version.parse('1.2.4-pre'))); }); - test("includeMax is true", () { + test('includeMax is true', () { expect(VersionRange(max: v124, includeMax: true).max, equals(v124)); }); - test("min is a prerelease of max", () { - expect(VersionRange(min: Version.parse("1.2.4-pre"), max: v124).max, + test('min is a prerelease of max', () { + expect(VersionRange(min: Version.parse('1.2.4-pre'), max: v124).max, equals(v124)); }); - test("max has a build identifier", () { - expect(VersionRange(max: Version.parse("1.2.4+1")).max, - equals(Version.parse("1.2.4+1"))); + test('max has a build identifier', () { + expect(VersionRange(max: Version.parse('1.2.4+1')).max, + equals(Version.parse('1.2.4+1'))); }); }); @@ -472,71 +472,71 @@ void main() { VersionRange(min: v123, max: v124).intersect(v114).isEmpty, isTrue); }); - test("with a range with a pre-release min, returns an empty constraint", + test('with a range with a pre-release min, returns an empty constraint', () { expect( VersionRange(max: v200) - .intersect(VersionConstraint.parse(">=2.0.0-dev")), + .intersect(VersionConstraint.parse('>=2.0.0-dev')), equals(VersionConstraint.empty)); }); - test("with a range with a pre-release max, returns the original", () { + test('with a range with a pre-release max, returns the original', () { expect( VersionRange(max: v200) - .intersect(VersionConstraint.parse("<2.0.0-dev")), + .intersect(VersionConstraint.parse('<2.0.0-dev')), equals(VersionRange(max: v200))); }); - group("with includeMaxPreRelease", () { + group('with includeMaxPreRelease', () { test('preserves includeMaxPreRelease if the max version is included', () { expect( includeMaxPreReleaseRange - .intersect(VersionConstraint.parse("<1.0.0")), - equals(VersionConstraint.parse("<1.0.0"))); + .intersect(VersionConstraint.parse('<1.0.0')), + equals(VersionConstraint.parse('<1.0.0'))); expect( includeMaxPreReleaseRange - .intersect(VersionConstraint.parse("<2.0.0")), - equals(VersionConstraint.parse("<2.0.0"))); + .intersect(VersionConstraint.parse('<2.0.0')), + equals(VersionConstraint.parse('<2.0.0'))); expect(includeMaxPreReleaseRange.intersect(includeMaxPreReleaseRange), equals(includeMaxPreReleaseRange)); expect( includeMaxPreReleaseRange - .intersect(VersionConstraint.parse("<3.0.0")), + .intersect(VersionConstraint.parse('<3.0.0')), equals(includeMaxPreReleaseRange)); expect( includeMaxPreReleaseRange - .intersect(VersionConstraint.parse(">1.1.4")), + .intersect(VersionConstraint.parse('>1.1.4')), equals(VersionRange( min: v114, max: v200, alwaysIncludeMaxPreRelease: true))); }); test( - "and a range with a pre-release min, returns " - "an intersection", () { + 'and a range with a pre-release min, returns ' + 'an intersection', () { expect( includeMaxPreReleaseRange - .intersect(VersionConstraint.parse(">=2.0.0-dev")), - equals(VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); + .intersect(VersionConstraint.parse('>=2.0.0-dev')), + equals(VersionConstraint.parse('>=2.0.0-dev <2.0.0'))); }); test( - "and a range with a pre-release max, returns " - "the narrower constraint", () { + 'and a range with a pre-release max, returns ' + 'the narrower constraint', () { expect( includeMaxPreReleaseRange - .intersect(VersionConstraint.parse("<2.0.0-dev")), - equals(VersionConstraint.parse("<2.0.0-dev"))); + .intersect(VersionConstraint.parse('<2.0.0-dev')), + equals(VersionConstraint.parse('<2.0.0-dev'))); }); }); }); group('union()', () { - test("with a version returns the range if it contains the version", () { + test('with a version returns the range if it contains the version', () { var range = VersionRange(min: v114, max: v124); expect(range.union(v123), equals(range)); }); - test("with a version on the edge of the range, expands the range", () { + test('with a version on the edge of the range, expands the range', () { expect( VersionRange(min: v114, max: v124, alwaysIncludeMaxPreRelease: true) .union(v124), @@ -546,7 +546,7 @@ void main() { }); test( - "with a version allows both the range and the version if the range " + 'with a version allows both the range and the version if the range ' "doesn't contain the version", () { var result = VersionRange(min: v003, max: v114).union(v124); expect(result, allows(v010)); @@ -554,7 +554,7 @@ void main() { expect(result, allows(v124)); }); - test("returns a VersionUnion for a disjoint range", () { + test('returns a VersionUnion for a disjoint range', () { var result = VersionRange(min: v003, max: v114) .union(VersionRange(min: v130, max: v200)); expect(result, allows(v080)); @@ -562,7 +562,7 @@ void main() { expect(result, allows(v140)); }); - test("considers open ranges disjoint", () { + test('considers open ranges disjoint', () { var result = VersionRange(min: v003, max: v114) .union(VersionRange(min: v114, max: v200)); expect(result, allows(v080)); @@ -576,13 +576,13 @@ void main() { expect(result, allows(v140)); }); - test("returns a merged range for an overlapping range", () { + test('returns a merged range for an overlapping range', () { var result = VersionRange(min: v003, max: v114) .union(VersionRange(min: v080, max: v200)); expect(result, equals(VersionRange(min: v003, max: v200))); }); - test("considers closed ranges overlapping", () { + test('considers closed ranges overlapping', () { var result = VersionRange(min: v003, max: v114, includeMax: true) .union(VersionRange(min: v114, max: v200)); expect(result, equals(VersionRange(min: v003, max: v200))); @@ -601,7 +601,7 @@ void main() { expect(result, equals(VersionRange(min: v003, max: v200))); }); - test("includes edges if either range does", () { + test('includes edges if either range does', () { var result = VersionRange(min: v003, max: v114, includeMin: true) .union(VersionRange(min: v003, max: v114, includeMax: true)); expect( @@ -610,69 +610,69 @@ void main() { min: v003, max: v114, includeMin: true, includeMax: true))); }); - test("with a range with a pre-release min, returns a constraint with a gap", + test('with a range with a pre-release min, returns a constraint with a gap', () { var result = - VersionRange(max: v200).union(VersionConstraint.parse(">=2.0.0-dev")); + VersionRange(max: v200).union(VersionConstraint.parse('>=2.0.0-dev')); expect(result, allows(v140)); - expect(result, doesNotAllow(Version.parse("2.0.0-alpha"))); - expect(result, allows(Version.parse("2.0.0-dev"))); - expect(result, allows(Version.parse("2.0.0-dev.1"))); - expect(result, allows(Version.parse("2.0.0"))); + expect(result, doesNotAllow(Version.parse('2.0.0-alpha'))); + expect(result, allows(Version.parse('2.0.0-dev'))); + expect(result, allows(Version.parse('2.0.0-dev.1'))); + expect(result, allows(Version.parse('2.0.0'))); }); - test("with a range with a pre-release max, returns the larger constraint", + test('with a range with a pre-release max, returns the larger constraint', () { expect( - VersionRange(max: v200).union(VersionConstraint.parse("<2.0.0-dev")), - equals(VersionConstraint.parse("<2.0.0-dev"))); + VersionRange(max: v200).union(VersionConstraint.parse('<2.0.0-dev')), + equals(VersionConstraint.parse('<2.0.0-dev'))); }); - group("with includeMaxPreRelease", () { + group('with includeMaxPreRelease', () { test('adds includeMaxPreRelease if the max version is included', () { expect( - includeMaxPreReleaseRange.union(VersionConstraint.parse("<1.0.0")), + includeMaxPreReleaseRange.union(VersionConstraint.parse('<1.0.0')), equals(includeMaxPreReleaseRange)); expect(includeMaxPreReleaseRange.union(includeMaxPreReleaseRange), equals(includeMaxPreReleaseRange)); expect( - includeMaxPreReleaseRange.union(VersionConstraint.parse("<2.0.0")), + includeMaxPreReleaseRange.union(VersionConstraint.parse('<2.0.0')), equals(includeMaxPreReleaseRange)); expect( - includeMaxPreReleaseRange.union(VersionConstraint.parse("<3.0.0")), - equals(VersionConstraint.parse("<3.0.0"))); + includeMaxPreReleaseRange.union(VersionConstraint.parse('<3.0.0')), + equals(VersionConstraint.parse('<3.0.0'))); }); - test("and a range with a pre-release min, returns any", () { + test('and a range with a pre-release min, returns any', () { expect( includeMaxPreReleaseRange - .union(VersionConstraint.parse(">=2.0.0-dev")), + .union(VersionConstraint.parse('>=2.0.0-dev')), equals(VersionConstraint.any)); }); - test("and a range with a pre-release max, returns the original", () { + test('and a range with a pre-release max, returns the original', () { expect( includeMaxPreReleaseRange - .union(VersionConstraint.parse("<2.0.0-dev")), + .union(VersionConstraint.parse('<2.0.0-dev')), equals(includeMaxPreReleaseRange)); }); }); }); group('difference()', () { - test("with an empty range returns the original range", () { + test('with an empty range returns the original range', () { expect( VersionRange(min: v003, max: v114) .difference(VersionConstraint.empty), equals(VersionRange(min: v003, max: v114))); }); - test("with a version outside the range returns the original range", () { + test('with a version outside the range returns the original range', () { expect(VersionRange(min: v003, max: v114).difference(v200), equals(VersionRange(min: v003, max: v114))); }); - test("with a version in the range splits the range", () { + test('with a version in the range splits the range', () { expect( VersionRange(min: v003, max: v114).difference(v072), equals(VersionConstraint.unionOf([ @@ -682,43 +682,43 @@ void main() { ]))); }); - test("with the max version makes the max exclusive", () { + test('with the max version makes the max exclusive', () { expect( VersionRange(min: v003, max: v114, includeMax: true).difference(v114), equals(VersionRange( min: v003, max: v114, alwaysIncludeMaxPreRelease: true))); }); - test("with the min version makes the min exclusive", () { + test('with the min version makes the min exclusive', () { expect( VersionRange(min: v003, max: v114, includeMin: true).difference(v003), equals(VersionRange(min: v003, max: v114))); }); - test("with a disjoint range returns the original", () { + test('with a disjoint range returns the original', () { expect( VersionRange(min: v003, max: v114) .difference(VersionRange(min: v123, max: v140)), equals(VersionRange(min: v003, max: v114))); }); - test("with an adjacent range returns the original", () { + test('with an adjacent range returns the original', () { expect( VersionRange(min: v003, max: v114, includeMax: true) .difference(VersionRange(min: v114, max: v140)), equals(VersionRange(min: v003, max: v114, includeMax: true))); }); - test("with a range at the beginning cuts off the beginning of the range", + test('with a range at the beginning cuts off the beginning of the range', () { expect( VersionRange(min: v080, max: v130) .difference(VersionRange(min: v010, max: v114)), - equals(VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); + equals(VersionConstraint.parse('>=1.1.4-0 <1.3.0'))); expect( VersionRange(min: v080, max: v130) .difference(VersionRange(max: v114)), - equals(VersionConstraint.parse(">=1.1.4-0 <1.3.0"))); + equals(VersionConstraint.parse('>=1.1.4-0 <1.3.0'))); expect( VersionRange(min: v080, max: v130) .difference(VersionRange(min: v010, max: v114, includeMax: true)), @@ -730,10 +730,10 @@ void main() { expect( VersionRange(min: v080, max: v130, includeMax: true) .difference(VersionRange(min: v080, max: v130)), - equals(VersionConstraint.parse(">=1.3.0-0 <=1.3.0"))); + equals(VersionConstraint.parse('>=1.3.0-0 <=1.3.0'))); }); - test("with a range at the end cuts off the end of the range", () { + test('with a range at the end cuts off the end of the range', () { expect( VersionRange(min: v080, max: v130) .difference(VersionRange(min: v114, max: v140)), @@ -758,17 +758,17 @@ void main() { equals(v080)); }); - test("with a range in the middle cuts the range in half", () { + test('with a range in the middle cuts the range in half', () { expect( VersionRange(min: v003, max: v130) .difference(VersionRange(min: v072, max: v114)), equals(VersionConstraint.unionOf([ VersionRange(min: v003, max: v072, includeMax: true), - VersionConstraint.parse(">=1.1.4-0 <1.3.0") + VersionConstraint.parse('>=1.1.4-0 <1.3.0') ]))); }); - test("with a totally covering range returns empty", () { + test('with a totally covering range returns empty', () { expect( VersionRange(min: v114, max: v200) .difference(VersionRange(min: v072, max: v300)), @@ -786,24 +786,24 @@ void main() { test( "with a version union that doesn't cover the range, returns the " - "original", () { + 'original', () { expect( VersionRange(min: v114, max: v140) .difference(VersionConstraint.unionOf([v010, v200])), equals(VersionRange(min: v114, max: v140))); }); - test("with a version union that intersects the ends, chops them off", () { + test('with a version union that intersects the ends, chops them off', () { expect( VersionRange(min: v114, max: v140).difference( VersionConstraint.unionOf([ VersionRange(min: v080, max: v123), VersionRange(min: v130, max: v200) ])), - equals(VersionConstraint.parse(">=1.2.3-0 <=1.3.0"))); + equals(VersionConstraint.parse('>=1.2.3-0 <=1.3.0'))); }); - test("with a version union that intersects the middle, chops it up", () { + test('with a version union that intersects the middle, chops it up', () { expect( VersionRange(min: v114, max: v140) .difference(VersionConstraint.unionOf([v123, v124, v130])), @@ -818,42 +818,42 @@ void main() { ]))); }); - test("with a version union that covers the whole range, returns empty", () { + test('with a version union that covers the whole range, returns empty', () { expect( VersionRange(min: v114, max: v140).difference( VersionConstraint.unionOf([v003, VersionRange(min: v010)])), equals(VersionConstraint.empty)); }); - test("with a range with a pre-release min, returns the original", () { + test('with a range with a pre-release min, returns the original', () { expect( VersionRange(max: v200) - .difference(VersionConstraint.parse(">=2.0.0-dev")), + .difference(VersionConstraint.parse('>=2.0.0-dev')), equals(VersionRange(max: v200))); }); - test("with a range with a pre-release max, returns null", () { + test('with a range with a pre-release max, returns null', () { expect( VersionRange(max: v200) - .difference(VersionConstraint.parse("<2.0.0-dev")), + .difference(VersionConstraint.parse('<2.0.0-dev')), equals(VersionConstraint.empty)); }); - group("with includeMaxPreRelease", () { - group("for the minuend", () { - test("preserves includeMaxPreRelease if the max version is included", + group('with includeMaxPreRelease', () { + group('for the minuend', () { + test('preserves includeMaxPreRelease if the max version is included', () { expect( includeMaxPreReleaseRange - .difference(VersionConstraint.parse("<1.0.0")), + .difference(VersionConstraint.parse('<1.0.0')), equals(VersionRange( - min: Version.parse("1.0.0-0"), + min: Version.parse('1.0.0-0'), max: v200, includeMin: true, alwaysIncludeMaxPreRelease: true))); expect( includeMaxPreReleaseRange - .difference(VersionConstraint.parse("<2.0.0")), + .difference(VersionConstraint.parse('<2.0.0')), equals(VersionRange( min: v200.firstPreRelease, max: v200, @@ -864,50 +864,50 @@ void main() { equals(VersionConstraint.empty)); expect( includeMaxPreReleaseRange - .difference(VersionConstraint.parse("<3.0.0")), + .difference(VersionConstraint.parse('<3.0.0')), equals(VersionConstraint.empty)); }); - test("with a range with a pre-release min, adjusts the max", () { + test('with a range with a pre-release min, adjusts the max', () { expect( includeMaxPreReleaseRange - .difference(VersionConstraint.parse(">=2.0.0-dev")), - equals(VersionConstraint.parse("<2.0.0-dev"))); + .difference(VersionConstraint.parse('>=2.0.0-dev')), + equals(VersionConstraint.parse('<2.0.0-dev'))); }); - test("with a range with a pre-release max, adjusts the min", () { + test('with a range with a pre-release max, adjusts the min', () { expect( includeMaxPreReleaseRange - .difference(VersionConstraint.parse("<2.0.0-dev")), - equals(VersionConstraint.parse(">=2.0.0-dev <2.0.0"))); + .difference(VersionConstraint.parse('<2.0.0-dev')), + equals(VersionConstraint.parse('>=2.0.0-dev <2.0.0'))); }); }); - group("for the subtrahend", () { + group('for the subtrahend', () { group("doesn't create a pre-release minimum", () { - test("when cutting off the bottom", () { + test('when cutting off the bottom', () { expect( - VersionConstraint.parse("<3.0.0") + VersionConstraint.parse('<3.0.0') .difference(includeMaxPreReleaseRange), equals(VersionRange(min: v200, max: v300, includeMin: true))); }); - test("with splitting down the middle", () { + test('with splitting down the middle', () { expect( - VersionConstraint.parse("<4.0.0").difference(VersionRange( + VersionConstraint.parse('<4.0.0').difference(VersionRange( min: v200, max: v300, includeMin: true, alwaysIncludeMaxPreRelease: true)), equals(VersionConstraint.unionOf([ VersionRange(max: v200, alwaysIncludeMaxPreRelease: true), - VersionConstraint.parse(">=3.0.0 <4.0.0") + VersionConstraint.parse('>=3.0.0 <4.0.0') ]))); }); - test("can leave a single version", () { + test('can leave a single version', () { expect( - VersionConstraint.parse("<=2.0.0") + VersionConstraint.parse('<=2.0.0') .difference(includeMaxPreReleaseRange), equals(v200)); }); @@ -922,7 +922,7 @@ void main() { }); group('compareTo()', () { - test("orders by minimum first", () { + test('orders by minimum first', () { _expectComparesSmaller(VersionRange(min: v003, max: v080), VersionRange(min: v010, max: v072)); _expectComparesSmaller(VersionRange(min: v003, max: v080), @@ -931,36 +931,36 @@ void main() { VersionRange(min: v010, max: v114)); }); - test("orders by maximum second", () { + test('orders by maximum second', () { _expectComparesSmaller(VersionRange(min: v003, max: v010), VersionRange(min: v003, max: v072)); }); - test("includeMin comes before !includeMin", () { + test('includeMin comes before !includeMin', () { _expectComparesSmaller( VersionRange(min: v003, max: v080, includeMin: true), VersionRange(min: v003, max: v080, includeMin: false)); }); - test("includeMax comes after !includeMax", () { + test('includeMax comes after !includeMax', () { _expectComparesSmaller( VersionRange(min: v003, max: v080, includeMax: false), VersionRange(min: v003, max: v080, includeMax: true)); }); - test("includeMaxPreRelease comes after !includeMaxPreRelease", () { + test('includeMaxPreRelease comes after !includeMaxPreRelease', () { _expectComparesSmaller( VersionRange(max: v200), includeMaxPreReleaseRange); }); - test("no minimum comes before small minimum", () { + test('no minimum comes before small minimum', () { _expectComparesSmaller( VersionRange(max: v010), VersionRange(min: v003, max: v010)); _expectComparesSmaller(VersionRange(max: v010, includeMin: true), VersionRange(min: v003, max: v010)); }); - test("no maximium comes after large maximum", () { + test('no maximium comes after large maximum', () { _expectComparesSmaller( VersionRange(min: v003, max: v300), VersionRange(min: v003)); _expectComparesSmaller(VersionRange(min: v003, max: v300), @@ -971,7 +971,7 @@ void main() { void _expectComparesSmaller(VersionRange smaller, VersionRange larger) { expect(smaller.compareTo(larger), lessThan(0), - reason: "expected $smaller to sort below $larger"); + reason: 'expected $smaller to sort below $larger'); expect(larger.compareTo(smaller), greaterThan(0), - reason: "expected $larger to sort above $smaller"); + reason: 'expected $larger to sort above $smaller'); } diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 634148bcc..df0d25b14 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -167,11 +167,11 @@ void main() { }); group('union()', () { - test("with the same version returns the version", () { + test('with the same version returns the version', () { expect(v123.union(v123), equals(v123)); }); - test("with a different version returns a version that matches both", () { + test('with a different version returns a version that matches both', () { var result = v123.union(v080); expect(result, allows(v123)); expect(result, allows(v080)); @@ -180,12 +180,12 @@ void main() { expect(result, doesNotAllow(v114)); }); - test("with a range returns the range if it contains the version", () { + test('with a range returns the range if it contains the version', () { var range = VersionRange(min: v114, max: v124); expect(v123.union(range), equals(range)); }); - test("with a range with the version on the edge, expands the range", () { + test('with a range with the version on the edge, expands the range', () { expect( v124.union(VersionRange( min: v114, max: v124, alwaysIncludeMaxPreRelease: true)), @@ -199,7 +199,7 @@ void main() { }); test( - "with a range allows both the range and the version if the range " + 'with a range allows both the range and the version if the range ' "doesn't contain the version", () { var result = v123.union(VersionRange(min: v003, max: v114)); expect(result, allows(v123)); @@ -208,15 +208,15 @@ void main() { }); group('difference()', () { - test("with the same version returns an empty constraint", () { + test('with the same version returns an empty constraint', () { expect(v123.difference(v123), isEmpty); }); - test("with a different version returns the original version", () { + test('with a different version returns the original version', () { expect(v123.difference(v080), equals(v123)); }); - test("returns an empty constraint with a range that contains the version", + test('returns an empty constraint with a range that contains the version', () { expect(v123.difference(VersionRange(min: v114, max: v124)), isEmpty); }); diff --git a/pkgs/pub_semver/test/version_union_test.dart b/pkgs/pub_semver/test/version_union_test.dart index 11a5ecd73..89f9a8553 100644 --- a/pkgs/pub_semver/test/version_union_test.dart +++ b/pkgs/pub_semver/test/version_union_test.dart @@ -82,7 +82,7 @@ void main() { ]))); }); - test("merges overlapping ranges", () { + test('merges overlapping ranges', () { expect( VersionConstraint.unionOf([ VersionRange(min: v003, max: v072), @@ -96,7 +96,7 @@ void main() { ]))); }); - test("merges adjacent ranges", () { + test('merges adjacent ranges', () { expect( VersionConstraint.unionOf([ VersionRange(min: v003, max: v072, includeMax: true), @@ -128,7 +128,7 @@ void main() { isNot(equals(VersionRange(min: v003, max: v080)))); }); - test("merges version numbers into ranges", () { + test('merges version numbers into ranges', () { expect( VersionConstraint.unionOf([ VersionRange(min: v003, max: v072), @@ -142,7 +142,7 @@ void main() { ]))); }); - test("merges adjacent version numbers into ranges", () { + test('merges adjacent version numbers into ranges', () { expect( VersionConstraint.unionOf([ VersionRange( @@ -319,7 +319,7 @@ void main() { isTrue); }); - test("returns false if no constraint matches", () { + test('returns false if no constraint matches', () { expect( union.allowsAny(VersionConstraint.unionOf([ v003, @@ -331,8 +331,8 @@ void main() { }); }); - group("intersect()", () { - test("with an overlapping version, returns that version", () { + group('intersect()', () { + test('with an overlapping version, returns that version', () { expect( VersionConstraint.unionOf([ VersionRange(min: v010, max: v080), @@ -341,7 +341,7 @@ void main() { equals(v072)); }); - test("with a non-overlapping version, returns an empty constraint", () { + test('with a non-overlapping version, returns an empty constraint', () { expect( VersionConstraint.unionOf([ VersionRange(min: v010, max: v080), @@ -350,7 +350,7 @@ void main() { isEmpty); }); - test("with an overlapping range, returns that range", () { + test('with an overlapping range, returns that range', () { var range = VersionRange(min: v072, max: v080); expect( VersionConstraint.unionOf([ @@ -360,7 +360,7 @@ void main() { equals(range)); }); - test("with a non-overlapping range, returns an empty constraint", () { + test('with a non-overlapping range, returns an empty constraint', () { expect( VersionConstraint.unionOf([ VersionRange(min: v010, max: v080), @@ -369,7 +369,7 @@ void main() { isEmpty); }); - test("with a parially-overlapping range, returns the overlapping parts", + test('with a parially-overlapping range, returns the overlapping parts', () { expect( VersionConstraint.unionOf([ @@ -382,13 +382,13 @@ void main() { ]))); }); - group("for a union,", () { + group('for a union,', () { var union = VersionConstraint.unionOf([ VersionRange(min: v003, max: v080), VersionRange(min: v123, max: v130) ]); - test("returns the overlapping parts", () { + test('returns the overlapping parts', () { expect( union.intersect(VersionConstraint.unionOf([ v010, @@ -415,7 +415,7 @@ void main() { }); }); - group("difference()", () { + group('difference()', () { test("ignores ranges that don't intersect", () { expect( VersionConstraint.unionOf([ @@ -432,7 +432,7 @@ void main() { ]))); }); - test("removes overlapping portions", () { + test('removes overlapping portions', () { expect( VersionConstraint.unionOf([ VersionRange(min: v010, max: v080), @@ -446,7 +446,7 @@ void main() { ]))); }); - test("removes multiple portions from the same range", () { + test('removes multiple portions from the same range', () { expect( VersionConstraint.unionOf([ VersionRange(min: v010, max: v114), @@ -462,7 +462,7 @@ void main() { ]))); }); - test("removes the same range from multiple ranges", () { + test('removes the same range from multiple ranges', () { expect( VersionConstraint.unionOf([ VersionRange(min: v010, max: v072), From c0466fe4af21b652c54dcb1d6eea2777de5c8670 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 20 Dec 2019 14:50:27 +0100 Subject: [PATCH 321/657] Version 2.0.0 supporting package_config.json (dart-lang/package_config#56) Giving it the package name package_config_2 to avoid conflict with the existing package_config which is used by the `test` package. This is the initial version. It will be updated to allow overlapping packages, as long as no file in the package URI root can be considered as belonging to a different package. --- pkgs/package_config/CHANGELOG.md | 3 + pkgs/package_config/CONTRIBUTING.md | 2 +- pkgs/package_config/LICENSE | 2 +- pkgs/package_config/lib/discovery.dart | 230 -------- .../lib/discovery_analysis.dart | 167 ------ pkgs/package_config/lib/package_config.dart | 141 +++++ pkgs/package_config/lib/packages.dart | 94 ---- pkgs/package_config/lib/packages_file.dart | 232 -------- pkgs/package_config/lib/src/discovery.dart | 132 +++++ pkgs/package_config/lib/src/errors.dart | 24 + .../lib/src/package_config.dart | 176 ++++++ .../lib/src/package_config_impl.dart | 181 +++++++ .../lib/src/package_config_json.dart | 327 ++++++++++++ .../package_config/lib/src/packages_file.dart | 150 ++++++ .../package_config/lib/src/packages_impl.dart | 127 ----- .../lib/src/packages_io_impl.dart | 45 -- pkgs/package_config/lib/src/util.dart | 251 ++++++++- pkgs/package_config/pubspec.yaml | 8 +- pkgs/package_config/test/all.dart | 17 - .../test/discovery_analysis_test.dart | 126 ----- pkgs/package_config/test/discovery_test.dart | 485 +++++++---------- .../test/discovery_uri_test.dart | 256 +++++++++ pkgs/package_config/test/parse_test.dart | 503 ++++++++++-------- .../package_config/test/parse_write_test.dart | 132 ----- pkgs/package_config/test/src/util.dart | 109 ++++ 25 files changed, 2223 insertions(+), 1697 deletions(-) delete mode 100644 pkgs/package_config/lib/discovery.dart delete mode 100644 pkgs/package_config/lib/discovery_analysis.dart create mode 100644 pkgs/package_config/lib/package_config.dart delete mode 100644 pkgs/package_config/lib/packages.dart delete mode 100644 pkgs/package_config/lib/packages_file.dart create mode 100644 pkgs/package_config/lib/src/discovery.dart create mode 100644 pkgs/package_config/lib/src/errors.dart create mode 100644 pkgs/package_config/lib/src/package_config.dart create mode 100644 pkgs/package_config/lib/src/package_config_impl.dart create mode 100644 pkgs/package_config/lib/src/package_config_json.dart create mode 100644 pkgs/package_config/lib/src/packages_file.dart delete mode 100644 pkgs/package_config/lib/src/packages_impl.dart delete mode 100644 pkgs/package_config/lib/src/packages_io_impl.dart delete mode 100644 pkgs/package_config/test/all.dart delete mode 100644 pkgs/package_config/test/discovery_analysis_test.dart create mode 100644 pkgs/package_config/test/discovery_uri_test.dart delete mode 100644 pkgs/package_config/test/parse_write_test.dart create mode 100644 pkgs/package_config/test/src/util.dart diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 50f1ede5a..84384fc21 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,6 @@ +## 2.0.0 + - Based on new JSON file format with more content. + ## 1.2.0 - Added support for writing default-package entries. - Fixed bug when writing `Uri`s containing a fragment. diff --git a/pkgs/package_config/CONTRIBUTING.md b/pkgs/package_config/CONTRIBUTING.md index 6f5e0ea67..8423ff94f 100644 --- a/pkgs/package_config/CONTRIBUTING.md +++ b/pkgs/package_config/CONTRIBUTING.md @@ -23,7 +23,7 @@ All submissions, including submissions by project members, require review. ### File headers All files in the project must start with the following header. - // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file + // Copyright (c) 2019, 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. diff --git a/pkgs/package_config/LICENSE b/pkgs/package_config/LICENSE index de31e1a0a..f75d7c237 100644 --- a/pkgs/package_config/LICENSE +++ b/pkgs/package_config/LICENSE @@ -1,4 +1,4 @@ -Copyright 2015, the Dart project authors. All rights reserved. +Copyright 2019, the Dart project authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart deleted file mode 100644 index 57584b682..000000000 --- a/pkgs/package_config/lib/discovery.dart +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) 2015, 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. - -library package_config.discovery; - -import "dart:async"; -import "dart:io"; -import "dart:typed_data" show Uint8List; - -import "package:path/path.dart" as path; - -import "packages.dart"; -import "packages_file.dart" as pkgfile show parse; -import "src/packages_impl.dart"; -import "src/packages_io_impl.dart"; - -/// Reads a package resolution file and creates a [Packages] object from it. -/// -/// The [packagesFile] must exist and be loadable. -/// Currently that means the URI must have a `file`, `http` or `https` scheme, -/// and that the file can be loaded and its contents parsed correctly. -/// -/// If the [loader] is provided, it is used to fetch non-`file` URIs, and -/// it can support other schemes or set up more complex HTTP requests. -/// -/// This function can be used to load an explicitly configured package -/// resolution file, for example one specified using a `--packages` -/// command-line parameter. -Future loadPackagesFile(Uri packagesFile, - {Future> loader(Uri uri)}) async { - Packages parseBytes(List bytes) { - Map packageMap = pkgfile.parse(bytes, packagesFile); - return new MapPackages(packageMap); - } - - if (packagesFile.scheme == "file") { - File file = new File.fromUri(packagesFile); - return parseBytes(await file.readAsBytes()); - } - if (loader == null) { - return parseBytes(await _httpGet(packagesFile)); - } - return parseBytes(await loader(packagesFile)); -} - -/// Create a [Packages] object for a package directory. -/// -/// The [packagesDir] URI should refer to a directory. -/// Package names are resolved as relative to sub-directories of the -/// package directory. -/// -/// This function can be used for explicitly configured package directories, -/// for example one specified using a `--package-root` comand-line parameter. -Packages getPackagesDirectory(Uri packagesDir) { - if (packagesDir.scheme == "file") { - Directory directory = new Directory.fromUri(packagesDir); - return new FilePackagesDirectoryPackages(directory); - } - if (!packagesDir.path.endsWith('/')) { - packagesDir = packagesDir.replace(path: packagesDir.path + '/'); - } - return new NonFilePackagesDirectoryPackages(packagesDir); -} - -/// Discover the package configuration for a Dart script. -/// -/// The [baseUri] points to either the Dart script or its directory. -/// A package resolution strategy is found by going through the following steps, -/// and stopping when something is found. -/// -/// * Check if a `.packages` file exists in the same directory. -/// * If `baseUri`'s scheme is not `file`, then assume a `packages` directory -/// in the same directory, and resolve packages relative to that. -/// * If `baseUri`'s scheme *is* `file`: -/// * Check if a `packages` directory exists. -/// * Otherwise check each successive parent directory of `baseUri` for a -/// `.packages` file. -/// -/// If any of these tests succeed, a `Packages` class is returned. -/// Returns the constant [noPackages] if no resolution strategy is found. -/// -/// This function currently only supports `file`, `http` and `https` URIs. -/// It needs to be able to load a `.packages` file from the URI, so only -/// recognized schemes are accepted. -/// -/// To support other schemes, or more complex HTTP requests, -/// an optional [loader] function can be supplied. -/// It's called to load the `.packages` file for a non-`file` scheme. -/// The loader function returns the *contents* of the file -/// identified by the URI it's given. -/// The content should be a UTF-8 encoded `.packages` file, and must return an -/// error future if loading fails for any reason. -Future findPackages(Uri baseUri, - {Future> loader(Uri unsupportedUri)}) { - if (baseUri.scheme == "file") { - return new Future.sync(() => findPackagesFromFile(baseUri)); - } else if (loader != null) { - return findPackagesFromNonFile(baseUri, loader: loader); - } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { - return findPackagesFromNonFile(baseUri, loader: _httpGet); - } else { - return new Future.value(Packages.noPackages); - } -} - -/// Find the location of the package resolution file/directory for a Dart file. -/// -/// Checks for a `.packages` file in the [workingDirectory]. -/// If not found, checks for a `packages` directory in the same directory. -/// If still not found, starts checking parent directories for -/// `.packages` until reaching the root directory. -/// -/// Returns a [File] object of a `.packages` file if one is found, or a -/// [Directory] object for the `packages/` directory if that is found. -FileSystemEntity _findPackagesFile(String workingDirectory) { - var dir = new Directory(workingDirectory); - if (!dir.isAbsolute) dir = dir.absolute; - if (!dir.existsSync()) { - throw new ArgumentError.value( - workingDirectory, "workingDirectory", "Directory does not exist."); - } - File checkForConfigFile(Directory directory) { - assert(directory.isAbsolute); - var file = new File(path.join(directory.path, ".packages")); - if (file.existsSync()) return file; - return null; - } - - // Check for $cwd/.packages - var packagesCfgFile = checkForConfigFile(dir); - if (packagesCfgFile != null) return packagesCfgFile; - // Check for $cwd/packages/ - var packagesDir = new Directory(path.join(dir.path, "packages")); - if (packagesDir.existsSync()) return packagesDir; - // Check for cwd(/..)+/.packages - var parentDir = dir.parent; - while (parentDir.path != dir.path) { - packagesCfgFile = checkForConfigFile(parentDir); - if (packagesCfgFile != null) break; - dir = parentDir; - parentDir = dir.parent; - } - return packagesCfgFile; -} - -/// Finds a package resolution strategy for a local Dart script. -/// -/// The [fileBaseUri] points to either a Dart script or the directory of the -/// script. The `fileBaseUri` must be a `file:` URI. -/// -/// This function first tries to locate a `.packages` file in the `fileBaseUri` -/// directory. If that is not found, it instead checks for the presence of -/// a `packages/` directory in the same place. -/// If that also fails, it starts checking parent directories for a `.packages` -/// file, and stops if it finds it. -/// Otherwise it gives up and returns [Packages.noPackages]. -Packages findPackagesFromFile(Uri fileBaseUri) { - Uri baseDirectoryUri = fileBaseUri; - if (!fileBaseUri.path.endsWith('/')) { - baseDirectoryUri = baseDirectoryUri.resolve("."); - } - String baseDirectoryPath = baseDirectoryUri.toFilePath(); - FileSystemEntity location = _findPackagesFile(baseDirectoryPath); - if (location == null) return Packages.noPackages; - if (location is File) { - List fileBytes = location.readAsBytesSync(); - Map map = - pkgfile.parse(fileBytes, new Uri.file(location.path)); - return new MapPackages(map); - } - assert(location is Directory); - return new FilePackagesDirectoryPackages(location); -} - -/// Finds a package resolution strategy for a Dart script. -/// -/// The [nonFileUri] points to either a Dart script or the directory of the -/// script. -/// The [nonFileUri] should not be a `file:` URI since the algorithm for -/// finding a package resolution strategy is more elaborate for `file:` URIs. -/// In that case, use [findPackagesFromFile]. -/// -/// This function first tries to locate a `.packages` file in the [nonFileUri] -/// directory. If that is not found, it instead assumes a `packages/` directory -/// in the same place. -/// -/// By default, this function only works for `http:` and `https:` URIs. -/// To support other schemes, a loader must be provided, which is used to -/// try to load the `.packages` file. The loader should return the contents -/// of the requested `.packages` file as bytes, which will be assumed to be -/// UTF-8 encoded. -Future findPackagesFromNonFile(Uri nonFileUri, - {Future> loader(Uri name)}) async { - if (loader == null) loader = _httpGet; - Uri packagesFileUri = nonFileUri.resolve(".packages"); - - try { - List fileBytes = await loader(packagesFileUri); - Map map = pkgfile.parse(fileBytes, packagesFileUri); - return new MapPackages(map); - } catch (_) { - // Didn't manage to load ".packages". Assume a "packages/" directory. - Uri packagesDirectoryUri = nonFileUri.resolve("packages/"); - return new NonFilePackagesDirectoryPackages(packagesDirectoryUri); - } -} - -/// Fetches a file over http. -Future> _httpGet(Uri uri) async { - HttpClient client = new HttpClient(); - HttpClientRequest request = await client.getUrl(uri); - HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.ok) { - throw new HttpException('${response.statusCode} ${response.reasonPhrase}', - uri: uri); - } - List> splitContent = await response.toList(); - int totalLength = 0; - for (var list in splitContent) { - totalLength += list.length; - } - Uint8List result = new Uint8List(totalLength); - int offset = 0; - for (List contentPart in splitContent) { - result.setRange(offset, offset + contentPart.length, contentPart); - offset += contentPart.length; - } - return result; -} diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart deleted file mode 100644 index d623303c8..000000000 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2015, 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. - -/// Analyse a directory structure and find packages resolvers for each -/// sub-directory. -/// -/// The resolvers are generally the same that would be found by using -/// the `discovery.dart` library on each sub-directory in turn, -/// but more efficiently and with some heuristics for directories that -/// wouldn't otherwise have a package resolution strategy, or that are -/// determined to be "package directories" themselves. -library package_config.discovery_analysis; - -import "dart:collection" show HashMap; -import "dart:io" show File, Directory; - -import "package:path/path.dart" as path; - -import "packages.dart"; -import "packages_file.dart" as pkgfile; -import "src/packages_impl.dart"; -import "src/packages_io_impl.dart"; - -/// Associates a [Packages] package resolution strategy with a directory. -/// -/// The package resolution applies to the directory and any sub-directory -/// that doesn't have its own overriding child [PackageContext]. -abstract class PackageContext { - /// The directory that introduced the [packages] resolver. - Directory get directory; - - /// A [Packages] resolver that applies to the directory. - /// - /// Introduced either by a `.packages` file or a `packages/` directory. - Packages get packages; - - /// Child contexts that apply to sub-directories of [directory]. - List get children; - - /// Look up the [PackageContext] that applies to a specific directory. - /// - /// The directory must be inside [directory]. - PackageContext operator [](Directory directory); - - /// A map from directory to package resolver. - /// - /// Has an entry for this package context and for each child context - /// contained in this one. - Map asMap(); - - /// Analyze [directory] and sub-directories for package resolution strategies. - /// - /// Returns a mapping from sub-directories to [Packages] objects. - /// - /// The analysis assumes that there are no `.packages` files in a parent - /// directory of `directory`. If there is, its corresponding `Packages` object - /// should be provided as `root`. - static PackageContext findAll(Directory directory, - {Packages root: Packages.noPackages}) { - if (!directory.existsSync()) { - throw ArgumentError("Directory not found: $directory"); - } - var contexts = []; - void findRoots(Directory directory) { - Packages packages; - List oldContexts; - File packagesFile = File(path.join(directory.path, ".packages")); - if (packagesFile.existsSync()) { - packages = _loadPackagesFile(packagesFile); - oldContexts = contexts; - contexts = []; - } else { - Directory packagesDir = - Directory(path.join(directory.path, "packages")); - if (packagesDir.existsSync()) { - packages = FilePackagesDirectoryPackages(packagesDir); - oldContexts = contexts; - contexts = []; - } - } - for (var entry in directory.listSync()) { - if (entry is Directory) { - if (packages == null || !entry.path.endsWith("/packages")) { - findRoots(entry); - } - } - } - if (packages != null) { - oldContexts.add(_PackageContext(directory, packages, contexts)); - contexts = oldContexts; - } - } - - findRoots(directory); - // If the root is not itself context root, add a the wrapper context. - if (contexts.length == 1 && contexts[0].directory == directory) { - return contexts[0]; - } - return _PackageContext(directory, root, contexts); - } -} - -class _PackageContext implements PackageContext { - final Directory directory; - final Packages packages; - final List children; - _PackageContext(this.directory, this.packages, List children) - : children = List.unmodifiable(children); - - Map asMap() { - var result = HashMap(); - recurse(_PackageContext current) { - result[current.directory] = current.packages; - for (var child in current.children) { - recurse(child); - } - } - - recurse(this); - return result; - } - - PackageContext operator [](Directory directory) { - String path = directory.path; - if (!path.startsWith(this.directory.path)) { - throw ArgumentError("Not inside $path: $directory"); - } - _PackageContext current = this; - // The current path is know to agree with directory until deltaIndex. - int deltaIndex = current.directory.path.length; - List children = current.children; - int i = 0; - while (i < children.length) { - // TODO(lrn): Sort children and use binary search. - _PackageContext child = children[i]; - String childPath = child.directory.path; - if (_stringsAgree(path, childPath, deltaIndex, childPath.length)) { - deltaIndex = childPath.length; - if (deltaIndex == path.length) { - return child; - } - current = child; - children = current.children; - i = 0; - continue; - } - i++; - } - return current; - } - - static bool _stringsAgree(String a, String b, int start, int end) { - if (a.length < end || b.length < end) return false; - for (int i = start; i < end; i++) { - if (a.codeUnitAt(i) != b.codeUnitAt(i)) return false; - } - return true; - } -} - -Packages _loadPackagesFile(File file) { - var uri = Uri.file(file.path); - var bytes = file.readAsBytesSync(); - var map = pkgfile.parse(bytes, uri); - return MapPackages(map); -} diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart new file mode 100644 index 000000000..4d6f346d7 --- /dev/null +++ b/pkgs/package_config/lib/package_config.dart @@ -0,0 +1,141 @@ +// Copyright (c) 2019, 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. + +/// A package configuration is a way to assign file paths to package URIs, +/// and vice-versa, +library package_config.package_config; + +import "dart:io" show File, Directory; +import "dart:typed_data" show Uint8List; +import "src/discovery.dart" as discover; +import "src/package_config.dart"; +import "src/package_config_json.dart"; + +export "src/package_config.dart" show PackageConfig, Package; +export "src/errors.dart" show PackageConfigError; + +/// Reads a specific package configuration file. +/// +/// The file must exist and be readable. +/// It must be either a valid `package_config.json` file +/// or a valid `.packages` file. +/// It is considered a `package_config.json` file if its first character +/// is a `{`. +/// +/// If the file is a `.packages` file, also checks if there is a +/// `.dart_tool/package_config.json` file next to the original file, +/// and if so, loads that instead. +Future loadPackageConfig(File file) => readAnyConfigFile(file); + +/// Reads a specific package configuration URI. +/// +/// The file of the URI must exist and be readable. +/// It must be either a valid `package_config.json` file +/// or a valid `.packages` file. +/// It is considered a `package_config.json` file if its first +/// non-whitespace character is a `{`. +/// +/// If the file is a `.packages` file, first checks if there is a +/// `.dart_tool/package_config.json` file next to the original file, +/// and if so, loads that instead. +/// The [file] *must not* be a `package:` URI. +/// +/// If [loader] is provided, URIs are loaded using that function. +/// The future returned by the loader must complete with a [Uint8List] +/// containing the entire file content, +/// or with `null` if the file does not exist. +/// The loader may throw at its own discretion, for situations where +/// it determines that an error might be need user attention, +/// but it is always allowed to return `null`. +/// This function makes no attempt to catch such errors. +/// +/// If no [loader] is supplied, a default loader is used which +/// only accepts `file:`, `http:` and `https:` URIs, +/// and which uses the platform file system and HTTP requests to +/// fetch file content. The default loader never throws because +/// of an I/O issue, as long as the location URIs are valid. +/// As such, it does not distinguish between a file not existing, +/// and it being temporarily locked or unreachable. +Future loadPackageConfigUri(Uri file, + {Future loader(Uri uri) /*?*/}) => + readAnyConfigFileUri(file, loader); + +/// Finds a package configuration relative to [directory]. +/// +/// If [directory] contains a package configuration, +/// either a `.dart_tool/package_config.json` file or, +/// if not, a `.packages`, then that file is loaded. +/// +/// If no file is found in the current directory, +/// then the parent directories are checked recursively, +/// all the way to the root directory, to check if those contains +/// a package configuration. +/// If [recurse] is set to [false], this parent directory check is not +/// performed. +/// +/// Returns `null` if no configuration file is found. +Future findPackageConfig(Directory directory, + {bool recurse = true}) => + discover.findPackageConfig(directory, recurse); + +/// Finds a package configuration relative to [location]. +/// +/// If [location] contains a package configuration, +/// either a `.dart_tool/package_config.json` file or, +/// if not, a `.packages`, then that file is loaded. +/// The [location] URI *must not* be a `package:` URI. +/// It should be a hierarchical URI which is supported +/// by [loader]. +/// +/// If no file is found in the current directory, +/// then the parent directories are checked recursively, +/// all the way to the root directory, to check if those contains +/// a package configuration. +/// If [recurse] is set to [false], this parent directory check is not +/// performed. +/// +/// If [loader] is provided, URIs are loaded using that function. +/// The future returned by the loader must complete with a [Uint8List] +/// containing the entire file content, +/// or with `null` if the file does not exist. +/// The loader may throw at its own discretion, for situations where +/// it determines that an error might be need user attention, +/// but it is always allowed to return `null`. +/// This function makes no attempt to catch such errors. +/// +/// If no [loader] is supplied, a default loader is used which +/// only accepts `file:`, `http:` and `https:` URIs, +/// and which uses the platform file system and HTTP requests to +/// fetch file content. The default loader never throws because +/// of an I/O issue, as long as the location URIs are valid. +/// As such, it does not distinguish between a file not existing, +/// and it being temporarily locked or unreachable. +/// +/// Returns `null` if no configuration file is found. +Future findPackageConfigUri(Uri location, + {bool recurse = true, Future loader(Uri uri)}) => + discover.findPackageConfigUri(location, loader, recurse); + +/// Writes a package configuration to the provided directory. +/// +/// Writes `.dart_tool/package_config.json` relative to [directory]. +/// If the `.dart_tool/` directory does not exist, it is created. +/// If it cannot be created, this operation fails. +/// +/// If [extraData] contains any entries, they are added to the JSON +/// written to the `package_config.json` file. Entries with the names +/// `"configVersion"` or `"packages"` are ignored, all other entries +/// are added verbatim. +/// This is intended for, e.g., the +/// `"generator"`, `"generated"` and `"generatorVersion"` +/// properties. +/// +/// Also writes a `.packages` file in [directory]. +/// This will stop happening eventually as the `.packages` file becomes +/// discontinued. +/// A comment is generated if `[PackageConfig.extraData]` contains a +/// `"generator"` entry. +Future savePackageConfig( + PackageConfig configuration, Directory directory) => + writePackageConfigJson(configuration, directory); diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart deleted file mode 100644 index 886fbc83c..000000000 --- a/pkgs/package_config/lib/packages.dart +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2015, 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. - -library package_config.packages; - -import "src/packages_impl.dart"; - -/// A package resolution strategy. -/// -/// Allows converting a `package:` URI to a different kind of URI. -/// -/// May also allow listing the available packages and converting -/// to a `Map` that gives the base location of each available -/// package. In some cases there is no way to find the available packages, -/// in which case [packages] and [asMap] will throw if used. -/// One such case is if the packages are resolved relative to a -/// `packages/` directory available over HTTP. -abstract class Packages { - /// A [Packages] resolver containing no packages. - /// - /// This constant object is returned by [find] above if no - /// package resolution strategy is found. - static const Packages noPackages = const NoPackages(); - - /// Resolve a package URI into a non-package URI. - /// - /// Translates a `package:` URI, according to the package resolution - /// strategy, into a URI that can be loaded. - /// By default, only `file`, `http` and `https` URIs are returned. - /// Custom `Packages` objects may return other URIs. - /// - /// If resolution fails because a package with the requested package name - /// is not available, the [notFound] function is called. - /// If no `notFound` function is provided, it defaults to throwing an error. - /// - /// The [packageUri] must be a valid package URI. - Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}); - - /// Return the names of the available packages. - /// - /// Returns an iterable that allows iterating the names of available packages. - /// - /// Some `Packages` objects are unable to find the package names, - /// and getting `packages` from such a `Packages` object will throw. - Iterable get packages; - - /// Retrieve metadata associated with a package. - /// - /// Metadata have string keys and values, and are looked up by key. - /// - /// Returns `null` if the argument is not a valid package name, - /// or if the package is not one of the packages configured by - /// this packages object, or if the package does not have associated - /// metadata with the provided [key]. - /// - /// Not all `Packages` objects can support metadata. - /// Those will always return `null`. - String packageMetadata(String packageName, String key); - - /// Retrieve metadata associated with a library. - /// - /// If [libraryUri] is a `package:` URI, the returned value - /// is the same that would be returned by [packageMetadata] with - /// the package's name and the same key. - /// - /// If [libraryUri] is not a `package:` URI, and this [Packages] - /// object has a [defaultPackageName], then the [key] is looked - /// up on the default package instead. - /// - /// Otherwise the result is `null`. - String libraryMetadata(Uri libraryUri, String key); - - /// Return the names-to-base-URI mapping of the available packages. - /// - /// Returns a map from package name to a base URI. - /// The [resolve] method will resolve a package URI with a specific package - /// name to a path extending the base URI that this map gives for that - /// package name. - /// - /// Some `Packages` objects are unable to find the package names, - /// and calling `asMap` on such a `Packages` object will throw. - Map asMap(); - - /// The name of the "default package". - /// - /// A default package is a package that *non-package* libraries - /// may be considered part of for some purposes. - /// - /// The value is `null` if there is no default package. - /// Not all implementations of [Packages] supports a default package, - /// and will always have a `null` value for those. - String get defaultPackageName; -} diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart deleted file mode 100644 index 1c35d5b21..000000000 --- a/pkgs/package_config/lib/packages_file.dart +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2015, 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. - -library package_config.packages_file; - -import "package:charcode/ascii.dart"; - -import "src/util.dart" show isValidPackageName; - -/// Parses a `.packages` file into a map from package name to base URI. -/// -/// The [source] is the byte content of a `.packages` file, assumed to be -/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII, -/// so Latin-1 or Windows-1252 encoding will also work fine. -/// -/// If the file content is available as a string, its [String.codeUnits] can -/// be used as the `source` argument of this function. -/// -/// The [baseLocation] is used as a base URI to resolve all relative -/// URI references against. -/// If the content was read from a file, `baseLocation` should be the -/// location of that file. -/// -/// If [allowDefaultPackage] is set to true, an entry with an empty package name -/// is accepted. This entry does not correspond to a package, but instead -/// represents a *default package* which non-package libraries may be considered -/// part of in some cases. The value of that entry must be a valid package name. -/// -/// Returns a simple mapping from package name to package location. -/// If default package is allowed, the map maps the empty string to the default package's name. -Map parse(List source, Uri baseLocation, - {bool allowDefaultPackage = false}) { - int index = 0; - Map result = {}; - while (index < source.length) { - bool isComment = false; - int start = index; - int separatorIndex = -1; - int end = source.length; - int char = source[index++]; - if (char == $cr || char == $lf) { - continue; - } - if (char == $colon) { - if (!allowDefaultPackage) { - throw FormatException("Missing package name", source, index - 1); - } - separatorIndex = index - 1; - } - isComment = char == $hash; - while (index < source.length) { - char = source[index++]; - if (char == $colon && separatorIndex < 0) { - separatorIndex = index - 1; - } else if (char == $cr || char == $lf) { - end = index - 1; - break; - } - } - if (isComment) continue; - if (separatorIndex < 0) { - throw FormatException("No ':' on line", source, index - 1); - } - var packageName = new String.fromCharCodes(source, start, separatorIndex); - if (packageName.isEmpty - ? !allowDefaultPackage - : !isValidPackageName(packageName)) { - throw FormatException("Not a valid package name", packageName, 0); - } - var packageValue = - new String.fromCharCodes(source, separatorIndex + 1, end); - Uri packageLocation; - if (packageName.isEmpty) { - if (!isValidPackageName(packageValue)) { - throw FormatException( - "Default package entry value is not a valid package name"); - } - packageLocation = Uri(path: packageValue); - } else { - packageLocation = baseLocation.resolve(packageValue); - if (!packageLocation.path.endsWith('/')) { - packageLocation = - packageLocation.replace(path: packageLocation.path + "/"); - } - } - if (result.containsKey(packageName)) { - if (packageName.isEmpty) { - throw FormatException( - "More than one default package entry", source, start); - } - throw FormatException("Same package name occured twice", source, start); - } - result[packageName] = packageLocation; - } - return result; -} - -/// Writes the mapping to a [StringSink]. -/// -/// If [comment] is provided, the output will contain this comment -/// with `# ` in front of each line. -/// Lines are defined as ending in line feed (`'\n'`). If the final -/// line of the comment doesn't end in a line feed, one will be added. -/// -/// If [baseUri] is provided, package locations will be made relative -/// to the base URI, if possible, before writing. -/// -/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an -/// empty string mapping to the _default package name_. -/// -/// All the keys of [packageMapping] must be valid package names, -/// and the values must be URIs that do not have the `package:` scheme. -void write(StringSink output, Map packageMapping, - {Uri baseUri, String comment, bool allowDefaultPackage = false}) { - ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage'); - - if (baseUri != null && !baseUri.isAbsolute) { - throw new ArgumentError.value(baseUri, "baseUri", "Must be absolute"); - } - - if (comment != null) { - var lines = comment.split('\n'); - if (lines.last.isEmpty) lines.removeLast(); - for (var commentLine in lines) { - output.write('# '); - output.writeln(commentLine); - } - } else { - output.write("# generated by package:package_config at "); - output.write(new DateTime.now()); - output.writeln(); - } - - packageMapping.forEach((String packageName, Uri uri) { - // If [packageName] is empty then [uri] is the _default package name_. - if (allowDefaultPackage && packageName.isEmpty) { - final defaultPackageName = uri.toString(); - if (!isValidPackageName(defaultPackageName)) { - throw ArgumentError.value( - defaultPackageName, - 'defaultPackageName', - '"$defaultPackageName" is not a valid package name', - ); - } - output.write(':'); - output.write(defaultPackageName); - output.writeln(); - return; - } - // Validate packageName. - if (!isValidPackageName(packageName)) { - throw new ArgumentError('"$packageName" is not a valid package name'); - } - if (uri.scheme == "package") { - throw new ArgumentError.value( - "Package location must not be a package: URI", uri.toString()); - } - output.write(packageName); - output.write(':'); - // If baseUri provided, make uri relative. - if (baseUri != null) { - uri = _relativize(uri, baseUri); - } - if (!uri.path.endsWith('/')) { - uri = uri.replace(path: uri.path + '/'); - } - output.write(uri); - output.writeln(); - }); -} - -/// Attempts to return a relative URI for [uri]. -/// -/// The result URI satisfies `baseUri.resolveUri(result) == uri`, -/// but may be relative. -/// The `baseUri` must be absolute. -Uri _relativize(Uri uri, Uri baseUri) { - assert(baseUri.isAbsolute); - if (uri.hasQuery || uri.hasFragment) { - uri = new Uri( - scheme: uri.scheme, - userInfo: uri.hasAuthority ? uri.userInfo : null, - host: uri.hasAuthority ? uri.host : null, - port: uri.hasAuthority ? uri.port : null, - path: uri.path); - } - - // Already relative. We assume the caller knows what they are doing. - if (!uri.isAbsolute) return uri; - - if (baseUri.scheme != uri.scheme) { - return uri; - } - - // If authority differs, we could remove the scheme, but it's not worth it. - if (uri.hasAuthority != baseUri.hasAuthority) return uri; - if (uri.hasAuthority) { - if (uri.userInfo != baseUri.userInfo || - uri.host.toLowerCase() != baseUri.host.toLowerCase() || - uri.port != baseUri.port) { - return uri; - } - } - - baseUri = baseUri.normalizePath(); - List base = baseUri.pathSegments.toList(); - if (base.isNotEmpty) { - base = new List.from(base)..removeLast(); - } - uri = uri.normalizePath(); - List target = uri.pathSegments.toList(); - if (target.isNotEmpty && target.last.isEmpty) target.removeLast(); - int index = 0; - while (index < base.length && index < target.length) { - if (base[index] != target[index]) { - break; - } - index++; - } - if (index == base.length) { - if (index == target.length) { - return new Uri(path: "./"); - } - return new Uri(path: target.skip(index).join('/')); - } else if (index > 0) { - return new Uri( - path: '../' * (base.length - index) + target.skip(index).join('/')); - } else { - return uri; - } -} diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart new file mode 100644 index 000000000..6b0fc8f0d --- /dev/null +++ b/pkgs/package_config/lib/src/discovery.dart @@ -0,0 +1,132 @@ +// Copyright (c) 2019, 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 "dart:io"; +import 'dart:typed_data'; + +import "package:path/path.dart" as path; + +import "errors.dart"; +import "package_config_impl.dart"; +import "package_config_json.dart"; +import "packages_file.dart" as packages_file; +import "util.dart" show defaultLoader; + +final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json"); +final Uri dotPackagesPath = Uri(path: ".packages"); +final Uri currentPath = Uri(path: "."); +final Uri parentPath = Uri(path: ".."); + +/// Discover the package configuration for a Dart script. +/// +/// The [baseDirectory] points to the directory of the Dart script. +/// A package resolution strategy is found by going through the following steps, +/// and stopping when something is found. +/// +/// * Check if a `.dart_tool/package_config.json` file exists in the directory. +/// * Check if a `.packages` file exists in the directory. +/// * Repeat these checks for the parent directories until reaching the +/// root directory if [recursive] is true. +/// +/// If any of these tests succeed, a `PackageConfig` class is returned. +/// Returns `null` if no configuration was found. If a configuration +/// is needed, then the caller can supply [PackageConfig.empty]. +Future findPackageConfig( + Directory baseDirectory, bool recursive) async { + var directory = baseDirectory; + if (!directory.isAbsolute) directory = directory.absolute; + if (!await directory.exists()) { + return null; + } + do { + // Check for $cwd/.packages + var packageConfig = await findPackagConfigInDirectory(directory); + if (packageConfig != null) return packageConfig; + if (!recursive) break; + // Check in parent directories. + var parentDirectory = directory.parent; + if (parentDirectory.path == directory.path) break; + directory = parentDirectory; + } while (true); + return null; +} + +/// Similar to [findPackageConfig] but based on a URI. +Future findPackageConfigUri(Uri location, + Future loader(Uri uri) /*?*/, bool recursive) async { + if (location.isScheme("package")) { + throw PackageConfigArgumentError( + location, "location", "Must not be a package: URI"); + } + if (loader == null) { + if (location.isScheme("file")) { + return findPackageConfig( + Directory.fromUri(location.resolveUri(currentPath)), recursive); + } + loader = defaultLoader; + } + if (!location.path.endsWith("/")) location = location.resolveUri(currentPath); + while (true) { + var file = location.resolveUri(packageConfigJsonPath); + var bytes = await loader(file); + if (bytes != null) { + return parsePackageConfigBytes(bytes, file); + } + file = location.resolveUri(dotPackagesPath); + bytes = await loader(file); + if (bytes != null) { + return packages_file.parse(bytes, file); + } + if (!recursive) break; + var parent = location.resolveUri(parentPath); + if (parent == location) break; + location = parent; + } + return null; +} + +/// Finds a `.packages` or `.dart_tool/package_config.json` file in [directory]. +/// +/// Loads the file, if it is there, and returns the resulting [PackageConfig]. +/// Returns `null` if the file isn't there. +/// Throws [FormatException] if a file is there but is not valid. +/// +/// If [extraData] is supplied and the `package_config.json` contains extra +/// entries in the top JSON object, those extra entries are stored into +/// [extraData]. +Future findPackagConfigInDirectory( + Directory directory) async { + var packageConfigFile = await checkForPackageConfigJsonFile(directory); + if (packageConfigFile != null) { + return await readPackageConfigJsonFile(packageConfigFile); + } + packageConfigFile = await checkForDotPackagesFile(directory); + if (packageConfigFile != null) { + return await readDotPackagesFile(packageConfigFile); + } + return null; +} + +Future /*?*/ checkForPackageConfigJsonFile(Directory directory) async { + assert(directory.isAbsolute); + var file = + File(path.join(directory.path, ".dart_tool", "package_config.json")); + if (await file.exists()) return file; + return null; +} + +Future checkForDotPackagesFile(Directory directory) async { + var file = File(path.join(directory.path, ".packages")); + if (await file.exists()) return file; + return null; +} + +Future _loadFile(File file) async { + Uint8List bytes; + try { + return await file.readAsBytes(); + } catch (_) { + return null; + } +} diff --git a/pkgs/package_config/lib/src/errors.dart b/pkgs/package_config/lib/src/errors.dart new file mode 100644 index 000000000..6c31ccea1 --- /dev/null +++ b/pkgs/package_config/lib/src/errors.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2019, 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. + +/// General superclass of most errors and exceptions thrown by this package. +/// +/// Only covers errors thrown while parsing package configuration files. +/// Programming errors and I/O exceptions are not covered. +abstract class PackageConfigError { + PackageConfigError._(); +} + +class PackageConfigArgumentError extends ArgumentError + implements PackageConfigError { + PackageConfigArgumentError(Object /*?*/ value, String name, String message) + : super.value(value, name, message); +} + +class PackageConfigFormatException extends FormatException + implements PackageConfigError { + PackageConfigFormatException(String message, Object /*?*/ value, + [int /*?*/ index]) + : super(message, value, index); +} diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart new file mode 100644 index 000000000..f7b96b8a5 --- /dev/null +++ b/pkgs/package_config/lib/src/package_config.dart @@ -0,0 +1,176 @@ +// Copyright (c) 2019, 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_config_impl.dart"; + +/// A package configuration. +/// +/// Associates configuration data to packages and files in packages. +/// +/// More members may be added to this class in the future, +/// so classes outside of this package must not implement [PackageConfig] +/// or any subclass of it. +abstract class PackageConfig { + /// The largest configuration version currently recognized. + static const int maxVersion = 2; + + /// An empty package configuration. + /// + /// A package configuration with no available packages. + /// Is used as a default value where a package configuration + /// is expected, but none have been specified or found. + static const PackageConfig empty = const SimplePackageConfig.empty(); + + /// Creats a package configuration with the provided available [packages]. + /// + /// The packages must be valid packages (valid package name, valid + /// absolute directory URIs, valid language version, if any), + /// and there must not be two packages with the same name or with + /// overlapping root directories. + /// + /// If supplied, the [extraData] will be available as the + /// [PackageConfig.extraData] of the created configuration. + /// + /// The version of the resulting configuration is always [maxVersion]. + factory PackageConfig(Iterable packages, {dynamic extraData}) => + SimplePackageConfig(maxVersion, packages); + + /// The configuration version number. + /// + /// Currently this is 1 or 2, where + /// * Version one is the `.packages` file format and + /// * Version two is the first `package_config.json` format. + /// + /// Instances of this class supports both, and the version + /// is only useful for detecting which kind of file the configuration + /// was read from. + int get version; + + /// All the available packages of this configuration. + /// + /// No two of these packages have the same name, + /// and no two [Package.root] directories overlap. + Iterable get packages; + + /// Look up a package by name. + /// + /// Returns the [Package] fron [packages] with [packageName] as + /// [Package.name]. Returns `null` if the package is not available in the + /// current configuration. + Package /*?*/ operator [](String packageName); + + /// Provides the associated package for a specific [file] (or directory). + /// + /// Returns a [Package] which contains the [file]'s path, if any. + /// That is, the [Package.rootUri] directory is a parent directory + /// of the [file]'s location. + /// + /// Returns `null` if the file does not belong to any package. + Package /*?*/ packageOf(Uri file); + + /// Resolves a `package:` URI to a non-package URI + /// + /// The [packageUri] must be a valid package URI. That means: + /// * A URI with `package` as scheme, + /// * with no authority part (`package://...`), + /// * with a path starting with a valid package name followed by a slash, and + /// * with no query or fragment part. + /// + /// Throws an [ArgumentError] (which also implements [PackageConfigError]) + /// if the package URI is not valid. + /// + /// Returns `null` if the package name of [packageUri] is not available + /// in this package configuration. + /// Returns the remaining path of the package URI resolved relative to the + /// [Package.packageUriRoot] of the corresponding package. + Uri /*?*/ resolve(Uri packageUri); + + /// The package URI which resolves to [nonPackageUri]. + /// + /// The [nonPackageUri] must not have any query or fragment part, + /// and it must not have `package` as scheme. + /// Throws an [ArgumentError] (which also implements [PackageConfigError]) + /// if the non-package URI is not valid. + /// + /// Returns a package URI which [resolve] will convert to [nonPackageUri], + /// if any such URI exists. Returns `null` if no such package URI exists. + Uri /*?*/ toPackageUri(Uri nonPackageUri); + + /// Extra data associated with the package configuration. + /// + /// The data may be in any format, depending on who introduced it. + /// The standard `packjage_config.json` file storage will only store + /// JSON-like list/map data structures. + dynamic get extraData; +} + +/// Configuration data for a single package. +abstract class Package { + /// Creates a package with the provided properties. + /// + /// The [name] must be a valid package name. + /// The [root] must be an absolute directory URI, meaning an absolute URI + /// with no query or fragment path and a path starting and ending with `/`. + /// The [packageUriRoot], if provided, must be either an absolute + /// directory URI or a relative URI reference which is then resolved + /// relative to [root]. It must then also be a subdirectory of [root], + /// or the same directory. + /// If [languageVersion] is supplied, it must be a valid Dart language + /// version, which means two decimal integer literals separated by a `.`, + /// where the integer literals have no leading zeros unless they are + /// a single zero digit. + /// If [extraData] is supplied, it will be available as the + /// [Package.extraData] of the created package. + factory Package(String name, Uri root, + {Uri /*?*/ packageUriRoot, + String /*?*/ languageVersion, + dynamic extraData}) => + SimplePackage(name, root, packageUriRoot, languageVersion, extraData); + + /// The package-name of the package. + String get name; + + /// The location of the root of the package. + /// + /// Is always an absolute URI with no query or fragment parts, + /// and with a path ending in `/`. + /// + /// All files in the [rootUri] directory are considered + /// part of the package for purposes where that that matters. + Uri get root; + + /// The root of the files available through `package:` URIs. + /// + /// A `package:` URI with [name] as the package name is + /// resolved relative to this location. + /// + /// Is always an absolute URI with no query or fragment part + /// with a path ending in `/`, + /// and with a location which is a subdirectory + /// of the [root], or the same as the [root]. + Uri get packageUriRoot; + + /// The default language version associated with this package. + /// + /// Each package may have a default language version associated, + /// which is the language version used to parse and compile + /// Dart files in the package. + /// A package version is always of the form: + /// + /// * A numeral consisting of one or more decimal digits, + /// with no leading zero unless the entire numeral is a single zero digit. + /// * Followed by a `.` character. + /// * Followed by another numeral of the same form. + /// + /// There is no whitespace allowed around the numerals. + /// Valid version numbers include `2.5`, `3.0`, and `1234.5678`. + String /*?*/ get languageVersion; + + /// Extra data associated with the specific package. + /// + /// The data may be in any format, depending on who introduced it. + /// The standard `packjage_config.json` file storage will only store + /// JSON-like list/map data structures. + dynamic get extraData; +} diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart new file mode 100644 index 000000000..0bbe18f5b --- /dev/null +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -0,0 +1,181 @@ +// Copyright (c) 2019, 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 'errors.dart'; +import "package_config.dart"; +export "package_config.dart"; +import "util.dart"; + +class SimplePackageConfig implements PackageConfig { + final int version; + final Map _packages; + final dynamic extraData; + + SimplePackageConfig(int version, Iterable packages, [this.extraData]) + : version = _validateVersion(version), + _packages = _validatePackages(packages); + + SimplePackageConfig._( + int version, Iterable packages, this.extraData) + : version = _validateVersion(version), + _packages = {for (var package in packages) package.name: package}; + + /// Creates empty configuration. + /// + /// The empty configuration can be used in cases where no configuration is + /// found, but code expects a non-null configuration. + const SimplePackageConfig.empty() + : version = 1, + _packages = const {}, + extraData = null; + + static int _validateVersion(int version) { + if (version < 0 || version > PackageConfig.maxVersion) { + throw PackageConfigArgumentError(version, "version", + "Must be in the range 1 to ${PackageConfig.maxVersion}"); + } + return version; + } + + static Map _validatePackages(Iterable packages) { + Map result = {}; + for (var package in packages) { + if (package is! SimplePackage) { + // SimplePackage validates these properties. + try { + _validatePackageData(package.name, package.root, + package.packageUriRoot, package.languageVersion); + } catch (e) { + throw PackageConfigArgumentError( + packages, "packages", "Package ${package.name}: ${e.message}"); + } + } + var name = package.name; + if (result.containsKey(name)) { + throw PackageConfigArgumentError( + name, "packages", "Duplicate package name"); + } + result[name] = package; + } + + // Check that no root URI is a prefix of another. + if (result.length > 1) { + // Uris cache their toString, so this is not as bad as it looks. + var rootUris = [...result.values] + ..sort((a, b) => a.root.toString().compareTo(b.root.toString())); + var prev = rootUris[0]; + var prevRoot = prev.root.toString(); + for (int i = 1; i < rootUris.length; i++) { + var next = rootUris[i]; + var nextRoot = next.root.toString(); + // If one string is a prefix of another, + // the former sorts just before the latter. + if (nextRoot.startsWith(prevRoot)) { + throw PackageConfigArgumentError( + packages, + "packages", + "Package ${next.name} root overlaps " + "package ${prev.name} root.\n" + "${prev.name} root: $prevRoot\n" + "${next.name} root: $nextRoot\n"); + } + prev = next; + } + } + return result; + } + + Iterable get packages => _packages.values; + + Package /*?*/ operator [](String packageName) => _packages[packageName]; + + /// Provides the associated package for a specific [file] (or directory). + /// + /// Returns a [Package] which contains the [file]'s path. + /// That is, the [Package.rootUri] directory is a parent directory + /// of the [file]'s location. + /// Returns `null` if the file does not belong to any package. + Package /*?*/ packageOf(Uri file) { + String path = file.toString(); + for (var package in _packages.values) { + var rootPath = package.root.toString(); + if (path.startsWith(rootPath)) return package; + } + return null; + } + + Uri /*?*/ resolve(Uri packageUri) { + String packageName = checkValidPackageUri(packageUri, "packageUri"); + return _packages[packageName]?.packageUriRoot?.resolveUri( + Uri(path: packageUri.path.substring(packageName.length + 1))); + } + + Uri /*?*/ toPackageUri(Uri nonPackageUri) { + if (nonPackageUri.isScheme("package")) { + throw PackageConfigArgumentError( + nonPackageUri, "nonPackageUri", "Must not be a package URI"); + } + if (nonPackageUri.hasQuery || nonPackageUri.hasFragment) { + throw PackageConfigArgumentError(nonPackageUri, "nonPackageUri", + "Must not have query or fragment part"); + } + for (var package in _packages.values) { + var root = package.packageUriRoot; + if (isUriPrefix(root, nonPackageUri)) { + var rest = nonPackageUri.toString().substring(root.toString().length); + return Uri(scheme: "package", path: "${package.name}/$rest"); + } + } + return null; + } +} + +/// Configuration data for a single package. +class SimplePackage implements Package { + final String name; + final Uri root; + final Uri packageUriRoot; + final String /*?*/ languageVersion; + final dynamic extraData; + + SimplePackage._(this.name, this.root, this.packageUriRoot, + this.languageVersion, this.extraData); + + factory SimplePackage(String name, Uri root, Uri packageUriRoot, + String /*?*/ languageVersion, dynamic extraData) { + _validatePackageData(name, root, packageUriRoot, languageVersion); + return SimplePackage._( + name, root, packageUriRoot, languageVersion, extraData); + } +} + +void _validatePackageData( + String name, Uri root, Uri packageUriRoot, String /*?*/ languageVersion) { + if (!isValidPackageName(name)) { + throw PackageConfigArgumentError(name, "name", "Not a valid package name"); + } + if (!isAbsoluteDirectoryUri(root)) { + throw PackageConfigArgumentError( + "$root", + "root", + "Not an absolute URI with no query or fragment " + "with a path ending in /"); + } + if (!isAbsoluteDirectoryUri(packageUriRoot)) { + throw PackageConfigArgumentError( + packageUriRoot, + "packageUriRoot", + "Not an absolute URI with no query or fragment " + "with a path ending in /"); + } + if (!isUriPrefix(root, packageUriRoot)) { + throw PackageConfigArgumentError(packageUriRoot, "packageUriRoot", + "The package URI root is not below the package root"); + } + if (languageVersion != null && + checkValidVersionNumber(languageVersion) >= 0) { + throw PackageConfigArgumentError( + languageVersion, "languageVersion", "Invalid language version format"); + } +} diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart new file mode 100644 index 000000000..8a6014cad --- /dev/null +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -0,0 +1,327 @@ +// Copyright (c) 2019, 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 "dart:convert"; +import "dart:io"; +import "dart:typed_data"; + +import 'package:charcode/ascii.dart'; +import "package:path/path.dart" as path; + +import "discovery.dart" show packageConfigJsonPath; +import "errors.dart"; +import "package_config_impl.dart"; +import "packages_file.dart" as packages_file; +import "util.dart"; + +const String _configVersionKey = "configVersion"; +const String _packagesKey = "packages"; +const List _topNames = [_configVersionKey, _packagesKey]; +const String _nameKey = "name"; +const String _rootUriKey = "rootUri"; +const String _packageUriKey = "packageUri"; +const String _languageVersionKey = "languageVersion"; +const List _packageNames = [ + _nameKey, + _rootUriKey, + _packageUriKey, + _languageVersionKey +]; + +const String _generatedKey = "generated"; +const String _generatorKey = "generator"; +const String _generatorVersionKey = "generatorVersion"; + +/// Reads a package configuration file. +/// +/// Detects whether the [file] is a version one `.packages` file or +/// a version two `package_config.json` file. +/// +/// If the [file] is a `.packages` file, first checks whether there is an +/// adjacent `.dart_tool/package_config.json` file, and if so, +/// reads that instead. +/// +/// The file must exist and be a normal file. +Future readAnyConfigFile(File file) async { + var bytes = await file.readAsBytes(); + int firstChar = firstNonWhitespaceChar(bytes); + if (firstChar != $lbrace) { + // Definitely not a JSON object, probably a .packages. + var alternateFile = File(path.join( + path.dirname(file.path), ".dart_tool", "package_config.json")); + if (!alternateFile.existsSync()) { + return packages_file.parse(bytes, file.uri); + } + file = alternateFile; + bytes = await alternateFile.readAsBytes(); + } + return parsePackageConfigBytes(bytes, file.uri); +} + +/// Like [readAnyConfigFile] but uses a URI and an optional loader. +Future readAnyConfigFileUri( + Uri file, Future loader(Uri uri) /*?*/) async { + if (file.isScheme("package")) { + throw PackageConfigArgumentError( + file, "file", "Must not be a package: URI"); + } + if (loader == null) { + if (file.isScheme("file")) return readAnyConfigFile(File.fromUri(file)); + loader = defaultLoader; + } + var bytes = await loader(file); + if (bytes == null) { + throw PackageConfigArgumentError( + file.toString(), "file", "File cannot be read"); + } + int firstChar = firstNonWhitespaceChar(bytes); + if (firstChar != $lbrace) { + // Definitely not a JSON object, probably a .packages. + var alternateFile = file.resolveUri(packageConfigJsonPath); + var alternateBytes = await loader(alternateFile); + if (alternateBytes == null) { + return packages_file.parse(bytes, file); + } + bytes = alternateBytes; + file = alternateFile; + } + return parsePackageConfigBytes(bytes, file); +} + +Future readPackageConfigJsonFile(File file) async { + Uint8List bytes; + try { + bytes = await file.readAsBytes(); + } catch (_) { + return null; + } + return parsePackageConfigBytes(bytes, file.uri); +} + +Future readDotPackagesFile(File file) async { + Uint8List bytes; + try { + bytes = await file.readAsBytes(); + } catch (_) { + return null; + } + return packages_file.parse(bytes, file.uri); +} + +PackageConfig parsePackageConfigBytes(Uint8List bytes, Uri file) { + // TODO(lrn): Make this simpler. Maybe parse directly from bytes. + return parsePackageConfigJson(json.fuse(utf8).decode(bytes), file); +} + +/// Creates a [PackageConfig] from a parsed JSON-like object structure. +/// +/// The [json] argument must be a JSON object (`Map`) +/// containing a `"configVersion"` entry with an integer value in the range +/// 1 to [PackageConfig.maxVersion], +/// and with a `"packages"` entry which is a JSON array (`List`) +/// containing JSON objects which each has the following properties: +/// +/// * `"name"`: The package name as a string. +/// * `"rootUri"`: The root of the package as a URI stored as a string. +/// * `"packageUri"`: Optionally the root of for `package:` URI resolution +/// for the package, as a relative URI below the root URI +/// stored as a string. +/// * `"languageVersion"`: Optionally a language version string which is a +/// an integer numeral, a decimal point (`.`) and another integer numeral, +/// where the integer numeral cannot have a sign, and can only have a +/// leading zero if the entire numeral is a single zero. +/// +/// All other properties are stored in [extraData]. +/// +/// The [baseLocation] is used as base URI to resolve the "rootUri" +/// URI referencestring. +PackageConfig parsePackageConfigJson(dynamic json, Uri baseLocation) { + if (!baseLocation.hasScheme || baseLocation.isScheme("package")) { + throw PackageConfigArgumentError(baseLocation.toString(), "baseLocation", + "Must be an absolute non-package: URI"); + } + + if (!baseLocation.path.endsWith("/")) { + baseLocation = baseLocation.resolveUri(Uri(path: ".")); + } + + String typeName() { + if (0 is T) return "int"; + if ("" is T) return "string"; + if (const [] is T) return "array"; + return "object"; + } + + T checkType(dynamic value, String name, [String /*?*/ packageName]) { + if (value is T) return value; + // The only types we are called with are [int], [String], [List] + // and Map. Recognize which to give a better error message. + var message = + "$name${packageName != null ? " of package $packageName" : ""}" + " is not a JSON ${typeName()}"; + throw PackageConfigFormatException(message, value); + } + + Package parsePackage(Map entry) { + String /*?*/ name; + String /*?*/ rootUri; + String /*?*/ packageUri; + String /*?*/ languageVersion; + Map /*?*/ extraData; + entry.forEach((key, value) { + switch (key) { + case _nameKey: + name = checkType(value, _nameKey); + break; + case _rootUriKey: + rootUri = checkType(value, _rootUriKey, name); + break; + case _packageUriKey: + packageUri = checkType(value, _packageUriKey, name); + break; + case _languageVersionKey: + languageVersion = checkType(value, _languageVersionKey, name); + break; + default: + (extraData ??= {})[key] = value; + break; + } + }); + if (name == null) { + throw PackageConfigFormatException("Missing name entry", entry); + } + if (rootUri == null) { + throw PackageConfigFormatException("Missing rootUri entry", entry); + } + Uri root = baseLocation.resolve(rootUri); + Uri /*?*/ packageRoot = root; + if (packageUri != null) packageRoot = root.resolve(packageUri); + try { + return SimplePackage(name, root, packageRoot, languageVersion, extraData); + } on ArgumentError catch (e) { + throw PackageConfigFormatException(e.message, e.invalidValue); + } + } + + var map = checkType>(json, "value"); + Map /*?*/ extraData = null; + List /*?*/ packageList; + int /*?*/ configVersion; + map.forEach((key, value) { + switch (key) { + case _configVersionKey: + configVersion = checkType(value, _configVersionKey); + break; + case _packagesKey: + var packageArray = checkType>(value, _packagesKey); + var packages = []; + for (var package in packageArray) { + packages.add(parsePackage( + checkType>(package, "package entry"))); + } + packageList = packages; + break; + default: + (extraData ??= {})[key] = value; + break; + } + }); + if (configVersion == null) { + throw PackageConfigFormatException("Missing configVersion entry", json); + } + if (packageList == null) + throw PackageConfigFormatException("Missing packages list", json); + try { + return SimplePackageConfig(configVersion, packageList, extraData); + } on ArgumentError catch (e) { + throw PackageConfigFormatException(e.message, e.invalidValue); + } +} + +Future writePackageConfigJson( + PackageConfig config, Directory targetDirectory) async { + // Write .dart_tool/package_config.json first. + var file = File( + path.join(targetDirectory.path, ".dart_tool", "package_config.json")); + var baseUri = file.uri; + var extraData = config.extraData; + var data = { + _configVersionKey: PackageConfig.maxVersion, + _packagesKey: [ + for (var package in config.packages) + { + _nameKey: package.name, + _rootUriKey: relativizeUri(package.root, baseUri), + if (package.root != package.packageUriRoot) + _packageUriKey: relativizeUri(package.packageUriRoot, package.root), + if (package.languageVersion != null) + _languageVersionKey: package.languageVersion, + ...?_extractExtraData(package.extraData, _packageNames), + } + ], + ...?_extractExtraData(config.extraData, _topNames), + }; + + // Write .packages too. + String /*?*/ comment; + if (extraData != null) { + String /*?*/ generator = extraData[_generatorKey]; + if (generator != null) { + String /*?*/ generated = extraData[_generatedKey]; + String /*?*/ generatorVersion = extraData[_generatorVersionKey]; + comment = "Generated by $generator" + "${generatorVersion != null ? " $generatorVersion" : ""}" + "${generated != null ? " on $generated" : ""}."; + } + } + file = File(path.join(targetDirectory.path, ".packages")); + baseUri = file.uri; + var buffer = StringBuffer(); + packages_file.write(buffer, config, baseUri: baseUri, comment: comment); + + await Future.wait([ + file.writeAsString(JsonEncoder.withIndent(" ").convert(data)), + file.writeAsString(buffer.toString()), + ]); +} + +/// If "extraData" is a JSON map, then return it, otherwise return null. +/// +/// If the value contains any of the [reservedNames] for the current context, +/// entries with that name in the extra data are dropped. +Map /*?*/ _extractExtraData( + dynamic data, Iterable reservedNames) { + if (data is Map) { + if (data.isEmpty) return null; + for (var name in reservedNames) { + if (data.containsKey(name)) { + data = { + for (var key in data.keys) + if (!reservedNames.contains(key)) key: data[key] + }; + if (data.isEmpty) return null; + for (var value in data.values) { + if (!_validateJson(value)) return null; + } + } + } + return data; + } + return null; +} + +/// Checks that the object is a valid JSON-like data structure. +bool _validateJson(dynamic object) { + if (object == null || object == true || object == false) return true; + if (object is num || object is String) return true; + if (object is List) { + for (var element in object) if (!_validateJson(element)) return false; + return true; + } + if (object is Map) { + for (var value in object.values) if (!_validateJson(value)) return false; + return true; + } + return false; +} diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart new file mode 100644 index 000000000..ac57b4f15 --- /dev/null +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -0,0 +1,150 @@ +// Copyright (c) 2019, 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_config_impl.dart"; +import "package:charcode/ascii.dart"; + +import "util.dart" show isValidPackageName, relativizeUri; +import "errors.dart"; + +/// Parses a `.packages` file into a [PackageConfig]. +/// +/// The [source] is the byte content of a `.packages` file, assumed to be +/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII, +/// so Latin-1 or Windows-1252 encoding will also work fine. +/// +/// If the file content is available as a string, its [String.codeUnits] can +/// be used as the `source` argument of this function. +/// +/// The [baseLocation] is used as a base URI to resolve all relative +/// URI references against. +/// If the content was read from a file, `baseLocation` should be the +/// location of that file. +/// +/// Returns a simple package configuration where each package's +/// [Package.packageUriRoot] is the same as its [Package.root] +/// and it has no [Package.languageVersion]. +PackageConfig parse(List source, Uri baseLocation) { + if (baseLocation.isScheme("package")) { + throw PackageConfigArgumentError( + baseLocation, "baseLocation", "Must not be a package: URI"); + } + int index = 0; + List packages = []; + Set packageNames = {}; + while (index < source.length) { + bool isComment = false; + int start = index; + int separatorIndex = -1; + int end = source.length; + int char = source[index++]; + if (char == $cr || char == $lf) { + continue; + } + if (char == $colon) { + throw PackageConfigFormatException( + "Missing package name", source, index - 1); + } + isComment = char == $hash; + while (index < source.length) { + char = source[index++]; + if (char == $colon && separatorIndex < 0) { + separatorIndex = index - 1; + } else if (char == $cr || char == $lf) { + end = index - 1; + break; + } + } + if (isComment) continue; + if (separatorIndex < 0) { + throw PackageConfigFormatException("No ':' on line", source, index - 1); + } + var packageName = String.fromCharCodes(source, start, separatorIndex); + if (!isValidPackageName(packageName)) { + throw PackageConfigFormatException( + "Not a valid package name", packageName, 0); + } + var packageValue = String.fromCharCodes(source, separatorIndex + 1, end); + Uri packageLocation = baseLocation.resolve(packageValue); + if (packageLocation.isScheme("package")) { + throw PackageConfigFormatException( + "Package URI as location for package", source, separatorIndex + 1); + } + if (packageLocation.hasQuery || packageLocation.hasFragment) { + throw PackageConfigFormatException( + "Location URI must not have query or fragment", source, start); + } + if (!packageLocation.path.endsWith('/')) { + packageLocation = + packageLocation.replace(path: packageLocation.path + "/"); + } + if (packageNames.contains(packageName)) { + throw PackageConfigFormatException( + "Same package name occured more than once", source, start); + } + packages.add(SimplePackage( + packageName, packageLocation, packageLocation, null, null)); + packageNames.add(packageName); + } + return SimplePackageConfig(1, packages, null); +} + +/// Writes the configuration to a [StringSink]. +/// +/// If [comment] is provided, the output will contain this comment +/// with `# ` in front of each line. +/// Lines are defined as ending in line feed (`'\n'`). If the final +/// line of the comment doesn't end in a line feed, one will be added. +/// +/// If [baseUri] is provided, package locations will be made relative +/// to the base URI, if possible, before writing. +/// +/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an +/// empty string mapping to the _default package name_. +/// +/// All the keys of [packageMapping] must be valid package names, +/// and the values must be URIs that do not have the `package:` scheme. +void write(StringSink output, PackageConfig config, + {Uri baseUri, String comment}) { + if (baseUri != null && !baseUri.isAbsolute) { + throw PackageConfigArgumentError(baseUri, "baseUri", "Must be absolute"); + } + + if (comment != null) { + var lines = comment.split('\n'); + if (lines.last.isEmpty) lines.removeLast(); + for (var commentLine in lines) { + output.write('# '); + output.writeln(commentLine); + } + } else { + output.write("# generated by package:package_config at "); + output.write(DateTime.now()); + output.writeln(); + } + for (var package in config.packages) { + var packageName = package.name; + var uri = package.packageUriRoot; + // Validate packageName. + if (!isValidPackageName(packageName)) { + throw PackageConfigArgumentError( + config, "config", '"$packageName" is not a valid package name'); + } + if (uri.scheme == "package") { + throw PackageConfigArgumentError( + config, "config", "Package location must not be a package URI: $uri"); + } + output.write(packageName); + output.write(':'); + // If baseUri provided, make uri relative. + if (baseUri != null) { + uri = relativizeUri(uri, baseUri); + } + if (!uri.path.endsWith('/')) { + uri = uri.replace(path: uri.path + '/'); + } + output.write(uri); + output.writeln(); + } +} diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart deleted file mode 100644 index 817002f1e..000000000 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2015, 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. - -/// Implementations of [Packages] that may be used in either server or browser -/// based applications. For implementations that can only run in the browser, -/// see [package_config.packages_io_impl]. -library package_config.packages_impl; - -import "dart:collection" show UnmodifiableMapView; - -import "../packages.dart"; -import "util.dart" show checkValidPackageUri; - -/// A [Packages] null-object. -class NoPackages implements Packages { - const NoPackages(); - - Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { - String packageName = checkValidPackageUri(packageUri); - if (notFound != null) return notFound(packageUri); - throw new ArgumentError.value( - packageUri, "packageUri", 'No package named "$packageName"'); - } - - Iterable get packages => new Iterable.empty(); - - Map asMap() => const {}; - - String get defaultPackageName => null; - - String packageMetadata(String packageName, String key) => null; - - String libraryMetadata(Uri libraryUri, String key) => null; -} - -/// Base class for [Packages] implementations. -/// -/// This class implements the [resolve] method in terms of a private -/// member -abstract class PackagesBase implements Packages { - Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { - packageUri = packageUri.normalizePath(); - String packageName = checkValidPackageUri(packageUri); - Uri packageBase = getBase(packageName); - if (packageBase == null) { - if (notFound != null) return notFound(packageUri); - throw new ArgumentError.value( - packageUri, "packageUri", 'No package named "$packageName"'); - } - String packagePath = packageUri.path.substring(packageName.length + 1); - return packageBase.resolve(packagePath); - } - - /// Find a base location for a package name. - /// - /// Returns `null` if no package exists with that name, and that can be - /// determined. - Uri getBase(String packageName); - - String get defaultPackageName => null; - - String packageMetadata(String packageName, String key) => null; - - String libraryMetadata(Uri libraryUri, String key) => null; -} - -/// A [Packages] implementation based on an existing map. -class MapPackages extends PackagesBase { - final Map _mapping; - MapPackages(this._mapping); - - Uri getBase(String packageName) => - packageName.isEmpty ? null : _mapping[packageName]; - - Iterable get packages => _mapping.keys; - - Map asMap() => new UnmodifiableMapView(_mapping); - - String get defaultPackageName => _mapping[""]?.toString(); - - String packageMetadata(String packageName, String key) { - if (packageName.isEmpty) return null; - Uri uri = _mapping[packageName]; - if (uri == null || !uri.hasFragment) return null; - // This can be optimized, either by caching the map or by - // parsing incrementally instead of parsing the entire fragment. - return Uri.splitQueryString(uri.fragment)[key]; - } - - String libraryMetadata(Uri libraryUri, String key) { - if (libraryUri.isScheme("package")) { - return packageMetadata(libraryUri.pathSegments.first, key); - } - var defaultPackageNameUri = _mapping[""]; - if (defaultPackageNameUri != null) { - return packageMetadata(defaultPackageNameUri.toString(), key); - } - return null; - } -} - -/// A [Packages] implementation based on a remote (e.g., HTTP) directory. -/// -/// There is no way to detect which packages exist short of trying to use -/// them. You can't necessarily check whether a directory exists, -/// except by checking for a know file in the directory. -class NonFilePackagesDirectoryPackages extends PackagesBase { - final Uri _packageBase; - NonFilePackagesDirectoryPackages(this._packageBase); - - Uri getBase(String packageName) => _packageBase.resolve("$packageName/"); - - Error _failListingPackages() { - return new UnsupportedError( - "Cannot list packages for a ${_packageBase.scheme}: " - "based package root"); - } - - Iterable get packages { - throw _failListingPackages(); - } - - Map asMap() { - throw _failListingPackages(); - } -} diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart deleted file mode 100644 index 9eba9ce44..000000000 --- a/pkgs/package_config/lib/src/packages_io_impl.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2015, 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. - -/// Implementations of [Packages] that can only be used in server based -/// applications. -library package_config.packages_io_impl; - -import "dart:collection" show UnmodifiableMapView; -import "dart:io" show Directory; - -import "package:path/path.dart" as path; - -import "packages_impl.dart"; - -/// A [Packages] implementation based on a local directory. -class FilePackagesDirectoryPackages extends PackagesBase { - final Directory _packageDir; - final Map _packageToBaseUriMap = {}; - - FilePackagesDirectoryPackages(this._packageDir); - - Uri getBase(String packageName) { - return _packageToBaseUriMap.putIfAbsent(packageName, () { - return new Uri.file(path.join(_packageDir.path, packageName, '.')); - }); - } - - Iterable _listPackageNames() { - return _packageDir - .listSync() - .where((e) => e is Directory) - .map((e) => path.basename(e.path)); - } - - Iterable get packages => _listPackageNames(); - - Map asMap() { - var result = {}; - for (var packageName in _listPackageNames()) { - result[packageName] = getBase(packageName); - } - return new UnmodifiableMapView(result); - } -} diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index f1e1afd0a..25d7b89e4 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -1,12 +1,17 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2019, 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 methods used by more than one library in the package. library package_config.util; +import 'dart:io'; +import 'dart:typed_data'; + import "package:charcode/ascii.dart"; +import "errors.dart"; + // All ASCII characters that are valid in a package name, with space // for all the invalid ones (including space). const String _validPackageNameCharacters = @@ -15,7 +20,7 @@ const String _validPackageNameCharacters = /// Tests whether something is a valid Dart package name. bool isValidPackageName(String string) { - return _findInvalidCharacter(string) < 0; + return checkPackageName(string) < 0; } /// Check if a string is a valid package name. @@ -26,7 +31,7 @@ bool isValidPackageName(String string) { /// Returns `-1` if the string is valid. /// Otherwise returns the index of the first invalid character, /// or `string.length` if the string contains no non-'.' character. -int _findInvalidCharacter(String string) { +int checkPackageName(String string) { // Becomes non-zero if any non-'.' character is encountered. int nonDot = 0; for (int i = 0; i < string.length; i++) { @@ -40,47 +45,46 @@ int _findInvalidCharacter(String string) { return -1; } -/// Validate that a Uri is a valid package:URI. -String checkValidPackageUri(Uri packageUri) { +/// Validate that a [Uri] is a valid `package:` URI. +String checkValidPackageUri(Uri packageUri, String name) { if (packageUri.scheme != "package") { - throw new ArgumentError.value( - packageUri, "packageUri", "Not a package: URI"); + throw PackageConfigArgumentError(packageUri, name, "Not a package: URI"); } if (packageUri.hasAuthority) { - throw new ArgumentError.value( - packageUri, "packageUri", "Package URIs must not have a host part"); + throw PackageConfigArgumentError( + packageUri, name, "Package URIs must not have a host part"); } if (packageUri.hasQuery) { // A query makes no sense if resolved to a file: URI. - throw new ArgumentError.value( - packageUri, "packageUri", "Package URIs must not have a query part"); + throw PackageConfigArgumentError( + packageUri, name, "Package URIs must not have a query part"); } if (packageUri.hasFragment) { // We could leave the fragment after the URL when resolving, // but it would be odd if "package:foo/foo.dart#1" and // "package:foo/foo.dart#2" were considered different libraries. // Keep the syntax open in case we ever get multiple libraries in one file. - throw new ArgumentError.value( - packageUri, "packageUri", "Package URIs must not have a fragment part"); + throw PackageConfigArgumentError( + packageUri, name, "Package URIs must not have a fragment part"); } if (packageUri.path.startsWith('/')) { - throw new ArgumentError.value( - packageUri, "packageUri", "Package URIs must not start with a '/'"); + throw PackageConfigArgumentError( + packageUri, name, "Package URIs must not start with a '/'"); } int firstSlash = packageUri.path.indexOf('/'); if (firstSlash == -1) { - throw new ArgumentError.value(packageUri, "packageUri", + throw PackageConfigArgumentError(packageUri, name, "Package URIs must start with the package name followed by a '/'"); } String packageName = packageUri.path.substring(0, firstSlash); - int badIndex = _findInvalidCharacter(packageName); + int badIndex = checkPackageName(packageName); if (badIndex >= 0) { if (packageName.isEmpty) { - throw new ArgumentError.value( - packageUri, "packageUri", "Package names mus be non-empty"); + throw PackageConfigArgumentError( + packageUri, name, "Package names mus be non-empty"); } if (badIndex == packageName.length) { - throw new ArgumentError.value(packageUri, "packageUri", + throw PackageConfigArgumentError(packageUri, name, "Package names must contain at least one non-'.' character"); } assert(badIndex < packageName.length); @@ -90,8 +94,211 @@ String checkValidPackageUri(Uri packageUri) { // Printable character. badChar = "'${packageName[badIndex]}' ($badChar)"; } - throw new ArgumentError.value( - packageUri, "packageUri", "Package names must not contain $badChar"); + throw PackageConfigArgumentError( + packageUri, name, "Package names must not contain $badChar"); } return packageName; } + +/// Checks whether [version] is a valid Dart language version string. +/// +/// The format is (as RegExp) `^(0|[1-9]\d+)\.(0|[1-9]\d+)$`. +/// +/// Returns the position of the first invalid character, or -1 if +/// the string is valid. +/// If the string is terminated early, the result is the length of the string. +int checkValidVersionNumber(String version) { + if (version == null) { + return 0; + } + int index = 0; + int dotsSeen = 0; + outer: + for (;;) { + // Check for numeral. + if (index == version.length) return index; + int char = version.codeUnitAt(index++); + int digit = char ^ 0x30; + if (digit != 0) { + if (digit < 9) { + while (index < version.length) { + char = version.codeUnitAt(index++); + digit = char ^ 0x30; + if (digit < 9) continue; + if (char == 0x2e /*.*/) { + if (dotsSeen > 0) return index - 1; + dotsSeen = 1; + continue outer; + } + return index - 1; + } + if (dotsSeen > 0) return -1; + return index; + } + return index - 1; + } + // Leading zero means numeral is over. + if (index >= version.length) { + if (dotsSeen > 0) return -1; + return index; + } + if (dotsSeen > 0) return index; + char = version.codeUnitAt(index++); + if (char != 0x2e /*.*/) return index - 1; + } +} + +/// Checks whether URI is just an absolute directory. +/// +/// * It must have a scheme. +/// * It must not have a query or fragment. +/// * The path must start and end with `/`. +bool isAbsoluteDirectoryUri(Uri uri) { + if (uri.hasQuery) return false; + if (uri.hasFragment) return false; + if (!uri.hasScheme) return false; + var path = uri.path; + if (!path.startsWith("/")) return false; + if (!path.endsWith("/")) return false; + return true; +} + +/// Whether the former URI is a prefix of the latter. +bool isUriPrefix(Uri prefix, Uri path) { + assert(!prefix.hasFragment); + assert(!prefix.hasQuery); + assert(!path.hasQuery); + assert(!path.hasFragment); + assert(prefix.path.endsWith('/')); + return path.toString().startsWith(prefix.toString()); +} + +/// Finds the first non-JSON-whitespace character in a file. +/// +/// Used to heuristically detect whether a file is a JSON file or an .ini file. +int firstNonWhitespaceChar(List bytes) { + for (int i = 0; i < bytes.length; i++) { + var char = bytes[i]; + if (char != 0x20 && char != 0x09 && char != 0x0a && char != 0x0d) { + return char; + } + } + return -1; +} + +/// Attempts to return a relative path-only URI for [uri]. +/// +/// First removes any query or fragment part from [uri]. +/// +/// If [uri] is already relative (has no scheme), it's returned as-is. +/// If that is not desired, the caller can pass `baseUri.resolveUri(uri)` +/// as the [uri] instead. +/// +/// If the [uri] has a scheme or authority part which differs from +/// the [baseUri], or if there is no overlap in the paths of the +/// two URIs at all, the [uri] is returned as-is. +/// +/// Otherwise the result is a path-only URI which satsifies +/// `baseUri.resolveUri(result) == uri`, +/// +/// The `baseUri` must be absolute. +Uri relativizeUri(Uri uri, Uri baseUri) { + assert(baseUri.isAbsolute); + if (uri.hasQuery || uri.hasFragment) { + uri = Uri( + scheme: uri.scheme, + userInfo: uri.hasAuthority ? uri.userInfo : null, + host: uri.hasAuthority ? uri.host : null, + port: uri.hasAuthority ? uri.port : null, + path: uri.path); + } + + // Already relative. We assume the caller knows what they are doing. + if (!uri.isAbsolute) return uri; + + if (baseUri.scheme != uri.scheme) { + return uri; + } + + // If authority differs, we could remove the scheme, but it's not worth it. + if (uri.hasAuthority != baseUri.hasAuthority) return uri; + if (uri.hasAuthority) { + if (uri.userInfo != baseUri.userInfo || + uri.host.toLowerCase() != baseUri.host.toLowerCase() || + uri.port != baseUri.port) { + return uri; + } + } + + baseUri = baseUri.normalizePath(); + List base = [...baseUri.pathSegments]; + if (base.isNotEmpty) base.removeLast(); + uri = uri.normalizePath(); + List target = [...uri.pathSegments]; + if (target.isNotEmpty && target.last.isEmpty) target.removeLast(); + int index = 0; + while (index < base.length && index < target.length) { + if (base[index] != target[index]) { + break; + } + index++; + } + if (index == base.length) { + if (index == target.length) { + return Uri(path: "./"); + } + return Uri(path: target.skip(index).join('/')); + } else if (index > 0) { + var buffer = StringBuffer(); + for (int n = base.length - index; n > 0; --n) { + buffer.write("../"); + } + buffer.writeAll(target.skip(index), "/"); + return Uri(path: buffer.toString()); + } else { + return uri; + } +} + +Future defaultLoader(Uri uri) async { + if (uri.isScheme("file")) { + var file = File.fromUri(uri); + try { + return file.readAsBytes(); + } catch (_) { + return null; + } + } + if (uri.isScheme("http") || uri.isScheme("https")) { + return _httpGet(uri); + } + throw UnsupportedError("Default URI unsupported scheme: $uri"); +} + +Future _httpGet(Uri uri) async { + assert(uri.isScheme("http") || uri.isScheme("https")); + HttpClient client = new HttpClient(); + HttpClientRequest request = await client.getUrl(uri); + HttpClientResponse response = await request.close(); + if (response.statusCode != HttpStatus.ok) { + return null; + } + List> splitContent = await response.toList(); + int totalLength = 0; + if (splitContent.length == 1) { + var part = splitContent[0]; + if (part is Uint8List) { + return part; + } + } + for (var list in splitContent) { + totalLength += list.length; + } + Uint8List result = new Uint8List(totalLength); + int offset = 0; + for (Uint8List contentPart in splitContent) { + result.setRange(offset, offset + contentPart.length, contentPart); + offset += contentPart.length; + } + return result; +} diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 72d299bf2..0cd7ddc52 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,11 +1,11 @@ -name: package_config -version: 1.2.0 -description: Support for working with Package Resolution config files. +name: package_config_2 +version: 2.0.0 +description: Support for working with Package Configuration files. author: Dart Team homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=2.0.0-dev <3.0.0' + sdk: '>=2.5.0-dev <3.0.0' dependencies: charcode: ^1.1.0 diff --git a/pkgs/package_config/test/all.dart b/pkgs/package_config/test/all.dart deleted file mode 100644 index 78e6cffd1..000000000 --- a/pkgs/package_config/test/all.dart +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2015, 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:test/test.dart"; - -import "discovery_analysis_test.dart" as discovery_analysis; -import "discovery_test.dart" as discovery; -import "parse_test.dart" as parse; -import "parse_write_test.dart" as parse_write; - -main() { - group("parse:", parse.main); - group("discovery:", discovery.main); - group("discovery-analysis:", discovery_analysis.main); - group("parse/write:", parse_write.main); -} diff --git a/pkgs/package_config/test/discovery_analysis_test.dart b/pkgs/package_config/test/discovery_analysis_test.dart deleted file mode 100644 index e43245468..000000000 --- a/pkgs/package_config/test/discovery_analysis_test.dart +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2015, 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. - -library package_config.discovery_analysis_test; - -import "dart:async"; -import "dart:io"; - -import "package:package_config/discovery_analysis.dart"; -import "package:package_config/packages.dart"; -import "package:path/path.dart" as path; -import "package:test/test.dart"; - -main() { - fileTest("basic", { - ".packages": packagesFile, - "foo": {".packages": packagesFile}, - "bar": { - "packages": {"foo": {}, "bar": {}, "baz": {}} - }, - "baz": {} - }, (Directory directory) { - var dirUri = new Uri.directory(directory.path); - PackageContext ctx = PackageContext.findAll(directory); - PackageContext root = ctx[directory]; - expect(root, same(ctx)); - validatePackagesFile(root.packages, dirUri); - var fooDir = sub(directory, "foo"); - PackageContext foo = ctx[fooDir]; - expect(identical(root, foo), isFalse); - validatePackagesFile(foo.packages, dirUri.resolve("foo/")); - var barDir = sub(directory, "bar"); - PackageContext bar = ctx[sub(directory, "bar")]; - validatePackagesDir(bar.packages, dirUri.resolve("bar/")); - PackageContext barbar = ctx[sub(barDir, "bar")]; - expect(barbar, same(bar)); // inherited. - PackageContext baz = ctx[sub(directory, "baz")]; - expect(baz, same(root)); // inherited. - - var map = ctx.asMap(); - expect(map.keys.map((dir) => dir.path), - unorderedEquals([directory.path, fooDir.path, barDir.path])); - return null; - }); -} - -Directory sub(Directory parent, String dirName) { - return new Directory(path.join(parent.path, dirName)); -} - -const packagesFile = """ -# A comment -foo:file:///dart/packages/foo/ -bar:http://example.com/dart/packages/bar/ -baz:packages/baz/ -"""; - -void validatePackagesFile(Packages resolver, Uri location) { - expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); -} - -void validatePackagesDir(Packages resolver, Uri location) { - // Expect three packages: foo, bar and baz - expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(location.resolve("packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(location.resolve("packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - if (location.scheme == "file") { - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); - } else { - expect(() => resolver.packages, throwsUnsupportedError); - } -} - -Uri pkg(String packageName, String packagePath) { - var path; - if (packagePath.startsWith('/')) { - path = "$packageName$packagePath"; - } else { - path = "$packageName/$packagePath"; - } - return new Uri(scheme: "package", path: path); -} - -/// Create a directory structure from [description] and run [fileTest]. -/// -/// Description is a map, each key is a file entry. If the value is a map, -/// it's a sub-dir, otherwise it's a file and the value is the content -/// as a string. -void fileTest( - String name, Map description, Future fileTest(Directory directory)) { - group("file-test", () { - Directory tempDir = Directory.systemTemp.createTempSync("file-test"); - setUp(() { - _createFiles(tempDir, description); - }); - tearDown(() { - tempDir.deleteSync(recursive: true); - }); - test(name, () => fileTest(tempDir)); - }); -} - -void _createFiles(Directory target, Map description) { - description.forEach((name, content) { - if (content is Map) { - Directory subDir = new Directory(path.join(target.path, name)); - subDir.createSync(); - _createFiles(subDir, content); - } else { - File file = new File(path.join(target.path, name)); - file.writeAsStringSync(content, flush: true); - } - }); -} diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 282427289..5db24a100 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -1,327 +1,250 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2019, 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. library package_config.discovery_test; -import "dart:async"; import "dart:io"; import "package:test/test.dart"; -import "package:package_config/packages.dart"; -import "package:package_config/discovery.dart"; -import "package:path/path.dart" as path; +import "package:package_config_2/package_config.dart"; + +import "src/util.dart"; const packagesFile = """ # A comment foo:file:///dart/packages/foo/ -bar:http://example.com/dart/packages/bar/ +bar:/dart/packages/bar/ baz:packages/baz/ """; -void validatePackagesFile(Packages resolver, Uri location) { - expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); +const packageConfigFile = """ +{ + "configVersion": 2, + "packages": [ + { + "name": "foo", + "rootUri": "file:///dart/packages/foo/" + }, + { + "name": "bar", + "rootUri": "/dart/packages/bar/" + }, + { + "name": "baz", + "rootUri": "../packages/baz/" + } + ], + "extra": [42] } +"""; -void validatePackagesDir(Packages resolver, Uri location) { - // Expect three packages: foo, bar and baz +void validatePackagesFile(PackageConfig resolver, Directory directory) { expect(resolver, isNotNull); expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(location.resolve("packages/foo/bar/baz"))); + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(location.resolve("packages/bar/baz/qux"))); + equals(Uri.parse("file:///dart/packages/bar/baz/qux"))); expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - if (location.scheme == "file") { - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); - } else { - expect(() => resolver.packages, throwsUnsupportedError); - } -} - -Uri pkg(String packageName, String packagePath) { - var path; - if (packagePath.startsWith('/')) { - path = "$packageName$packagePath"; - } else { - path = "$packageName/$packagePath"; - } - return new Uri(scheme: "package", path: path); + equals(Uri.directory(directory.path).resolve("packages/baz/qux/foo"))); + expect([for (var p in resolver.packages) p.name], + unorderedEquals(["foo", "bar", "baz"])); } main() { - generalTest(".packages", { - ".packages": packagesFile, - "script.dart": "main(){}", - "packages": {"shouldNotBeFound": {}} - }, (Uri location) async { - Packages resolver; - resolver = await findPackages(location); - validatePackagesFile(resolver, location); - resolver = await findPackages(location.resolve("script.dart")); - validatePackagesFile(resolver, location); - var specificDiscovery = (location.scheme == "file") - ? findPackagesFromFile - : findPackagesFromNonFile; - resolver = await specificDiscovery(location); - validatePackagesFile(resolver, location); - resolver = await specificDiscovery(location.resolve("script.dart")); - validatePackagesFile(resolver, location); - }); - - generalTest("packages/", { - "packages": {"foo": {}, "bar": {}, "baz": {}}, - "script.dart": "main(){}" - }, (Uri location) async { - Packages resolver; - bool isFile = (location.scheme == "file"); - resolver = await findPackages(location); - validatePackagesDir(resolver, location); - resolver = await findPackages(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - var specificDiscovery = - isFile ? findPackagesFromFile : findPackagesFromNonFile; - resolver = await specificDiscovery(location); - validatePackagesDir(resolver, location); - resolver = await specificDiscovery(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - }); - - generalTest("underscore packages", { - "packages": {"_foo": {}} - }, (Uri location) async { - Packages resolver = await findPackages(location); - expect(resolver.resolve(pkg("_foo", "foo.dart")), - equals(location.resolve("packages/_foo/foo.dart"))); - }); - - fileTest(".packages recursive", { - ".packages": packagesFile, - "subdir": {"script.dart": "main(){}"} - }, (Uri location) async { - Packages resolver; - resolver = await findPackages(location.resolve("subdir/")); - validatePackagesFile(resolver, location); - resolver = await findPackages(location.resolve("subdir/script.dart")); - validatePackagesFile(resolver, location); - resolver = await findPackagesFromFile(location.resolve("subdir/")); - validatePackagesFile(resolver, location); - resolver = - await findPackagesFromFile(location.resolve("subdir/script.dart")); - validatePackagesFile(resolver, location); - }); + group("findPackages", () { + // Finds package_config.json if there. + fileTest("package_config.json", { + ".packages": "invalid .packages file", + "script.dart": "main(){}", + "packages": {"shouldNotBeFound": {}}, + ".dart_tool": { + "package_config.json": packageConfigFile, + } + }, (Directory directory) async { + PackageConfig config = await findPackageConfig(directory); + expect(config.version, 2); // Found package_config.json file. + validatePackagesFile(config, directory); + }); - httpTest(".packages not recursive", { - ".packages": packagesFile, - "subdir": {"script.dart": "main(){}"} - }, (Uri location) async { - Packages resolver; - var subdir = location.resolve("subdir/"); - resolver = await findPackages(subdir); - validatePackagesDir(resolver, subdir); - resolver = await findPackages(subdir.resolve("script.dart")); - validatePackagesDir(resolver, subdir); - resolver = await findPackagesFromNonFile(subdir); - validatePackagesDir(resolver, subdir); - resolver = await findPackagesFromNonFile(subdir.resolve("script.dart")); - validatePackagesDir(resolver, subdir); - }); + // Finds .packages if no package_config.json. + fileTest(".packages", { + ".packages": packagesFile, + "script.dart": "main(){}", + "packages": {"shouldNotBeFound": {}} + }, (Directory directory) async { + PackageConfig config = await findPackageConfig(directory); + expect(config.version, 1); // Found .packages file. + validatePackagesFile(config, directory); + }); - fileTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { - // A file: location with no .packages or packages returns - // Packages.noPackages. - Packages resolver; - resolver = await findPackages(location); - expect(resolver, same(Packages.noPackages)); - resolver = await findPackages(location.resolve("script.dart")); - expect(resolver, same(Packages.noPackages)); - resolver = findPackagesFromFile(location); - expect(resolver, same(Packages.noPackages)); - resolver = findPackagesFromFile(location.resolve("script.dart")); - expect(resolver, same(Packages.noPackages)); - }); + // Finds package_config.json in super-directory. + fileTest("package_config.json recursive", { + ".packages": packagesFile, + ".dart_tool": { + "package_config.json": packageConfigFile, + }, + "subdir": { + "script.dart": "main(){}", + } + }, (Directory directory) async { + PackageConfig config = + await findPackageConfig(subdir(directory, "subdir/")); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); - httpTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { - // A non-file: location with no .packages or packages/: - // Assumes a packages dir exists, and resolves relative to that. - Packages resolver; - resolver = await findPackages(location); - validatePackagesDir(resolver, location); - resolver = await findPackages(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - }); + // Finds .packages in super-directory. + fileTest(".packages recursive", { + ".packages": packagesFile, + "subdir": {"script.dart": "main(){}"} + }, (Directory directory) async { + PackageConfig config; + config = await findPackageConfig(subdir(directory, "subdir/")); + expect(config.version, 1); + validatePackagesFile(config, directory); + }); - test(".packages w/ loader", () async { - Uri location = Uri.parse("krutch://example.com/path/"); - Future> loader(Uri file) async { - if (file.path.endsWith(".packages")) { - return packagesFile.codeUnits; + // Does not find a packages/ directory, and returns null if nothing found. + fileTest("package directory packages not supported", { + "packages": { + "foo": {}, } - throw "not found"; - } - - // A non-file: location with no .packages or packages/: - // Assumes a packages dir exists, and resolves relative to that. - Packages resolver; - resolver = await findPackages(location, loader: loader); - validatePackagesFile(resolver, location); - resolver = - await findPackages(location.resolve("script.dart"), loader: loader); - validatePackagesFile(resolver, location); - resolver = await findPackagesFromNonFile(location, loader: loader); - validatePackagesFile(resolver, location); - resolver = await findPackagesFromNonFile(location.resolve("script.dart"), - loader: loader); - validatePackagesFile(resolver, location); - }); + }, (Directory directory) async { + PackageConfig config = await findPackageConfig(directory); + expect(config, null); + }); - test("no packages w/ loader", () async { - Uri location = Uri.parse("krutch://example.com/path/"); - Future> loader(Uri file) async { - throw "not found"; - } + fileTest("invalid .packages", { + ".packages": "not a .packages file", + }, (Directory directory) { + expect(() => findPackageConfig(directory), + throwsA(TypeMatcher())); + }); - // A non-file: location with no .packages or packages/: - // Assumes a packages dir exists, and resolves relative to that. - Packages resolver; - resolver = await findPackages(location, loader: loader); - validatePackagesDir(resolver, location); - resolver = - await findPackages(location.resolve("script.dart"), loader: loader); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location, loader: loader); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location.resolve("script.dart"), - loader: loader); - validatePackagesDir(resolver, location); - }); + fileTest("invalid .packages as JSON", { + ".packages": packageConfigFile, + }, (Directory directory) { + expect(() => findPackageConfig(directory), + throwsA(TypeMatcher())); + }); - generalTest("loadPackagesFile", {".packages": packagesFile}, - (Uri directory) async { - Uri file = directory.resolve(".packages"); - Packages resolver = await loadPackagesFile(file); - validatePackagesFile(resolver, file); - }); + fileTest("invalid .packages", { + ".dart_tool": { + "package_config.json": "not a JSON file", + } + }, (Directory directory) { + expect(() => findPackageConfig(directory), + throwsA(TypeMatcher())); + }); - generalTest( - "loadPackagesFile non-default name", {"pheldagriff": packagesFile}, - (Uri directory) async { - Uri file = directory.resolve("pheldagriff"); - Packages resolver = await loadPackagesFile(file); - validatePackagesFile(resolver, file); + fileTest("invalid .packages as INI", { + ".dart_tool": { + "package_config.json": packagesFile, + } + }, (Directory directory) { + expect(() => findPackageConfig(directory), + throwsA(TypeMatcher())); + }); }); - test("loadPackagesFile w/ loader", () async { - Future> loader(Uri uri) async => packagesFile.codeUnits; - Uri file = Uri.parse("krutz://example.com/.packages"); - Packages resolver = await loadPackagesFile(file, loader: loader); - validatePackagesFile(resolver, file); - }); + group("loadPackageConfig", () { + // Load a specific files + group("package_config.json", () { + var files = { + ".packages": packagesFile, + ".dart_tool": { + "package_config.json": packageConfigFile, + }, + }; + fileTest("directly", files, (Directory directory) async { + File file = + dirFile(subdir(directory, ".dart_tool"), "package_config.json"); + PackageConfig config = await loadPackageConfig(file); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + fileTest("indirectly through .packages", files, + (Directory directory) async { + File file = dirFile(directory, ".packages"); + PackageConfig config = await loadPackageConfig(file); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + }); - generalTest("loadPackagesFile not found", {}, (Uri directory) async { - Uri file = directory.resolve(".packages"); - expect( - loadPackagesFile(file), - throwsA(anyOf(new TypeMatcher(), - new TypeMatcher()))); - }); + fileTest("package_config.json non-default name", { + ".packages": packagesFile, + "subdir": { + "pheldagriff": packageConfigFile, + }, + }, (Directory directory) async { + File file = dirFile(directory, "subdir/pheldagriff"); + PackageConfig config = await loadPackageConfig(file); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); - generalTest("loadPackagesFile syntax error", {".packages": "syntax error"}, - (Uri directory) async { - Uri file = directory.resolve(".packages"); - expect(loadPackagesFile(file), throwsFormatException); - }); + fileTest("package_config.json named .packages", { + "subdir": { + ".packages": packageConfigFile, + }, + }, (Directory directory) async { + File file = dirFile(directory, "subdir/.packages"); + PackageConfig config = await loadPackageConfig(file); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); - generalTest("getPackagesDir", { - "packages": {"foo": {}, "bar": {}, "baz": {}} - }, (Uri directory) async { - Uri packages = directory.resolve("packages/"); - Packages resolver = getPackagesDirectory(packages); - Uri resolved = resolver.resolve(pkg("foo", "flip/flop")); - expect(resolved, packages.resolve("foo/flip/flop")); - }); -} + fileTest(".packages", { + ".packages": packagesFile, + }, (Directory directory) async { + File file = dirFile(directory, ".packages"); + PackageConfig config = await loadPackageConfig(file); + expect(config.version, 1); + validatePackagesFile(config, directory); + }); -/// Create a directory structure from [description] and run [fileTest]. -/// -/// Description is a map, each key is a file entry. If the value is a map, -/// it's a sub-dir, otherwise it's a file and the value is the content -/// as a string. -void fileTest(String name, Map description, Future fileTest(Uri directory)) { - group("file-test", () { - Directory tempDir = Directory.systemTemp.createTempSync("file-test"); - setUp(() { - _createFiles(tempDir, description); + fileTest(".packages non-default name", { + "pheldagriff": packagesFile, + }, (Directory directory) async { + File file = dirFile(directory, "pheldagriff"); + PackageConfig config = await loadPackageConfig(file); + expect(config.version, 1); + validatePackagesFile(config, directory); }); - tearDown(() { - tempDir.deleteSync(recursive: true); + + fileTest("no config found", {}, (Directory directory) { + File file = dirFile(directory, "anyname"); + expect(() => loadPackageConfig(file), + throwsA(TypeMatcher())); }); - test(name, () => fileTest(new Uri.file(path.join(tempDir.path, ".")))); - }); -} -/// HTTP-server the directory structure from [description] and run [htpTest]. -/// -/// Description is a map, each key is a file entry. If the value is a map, -/// it's a sub-dir, otherwise it's a file and the value is the content -/// as a string. -void httpTest(String name, Map description, Future httpTest(Uri directory)) { - group("http-test", () { - var serverSub; - var uri; - setUp(() { - return HttpServer.bind(InternetAddress.loopbackIPv4, 0).then((server) { - uri = new Uri( - scheme: "http", host: "127.0.0.1", port: server.port, path: "/"); - serverSub = server.listen((HttpRequest request) { - // No error handling. - var path = request.uri.path; - if (path.startsWith('/')) path = path.substring(1); - if (path.endsWith('/')) path = path.substring(0, path.length - 1); - var parts = path.split('/'); - dynamic fileOrDir = description; - for (int i = 0; i < parts.length; i++) { - fileOrDir = fileOrDir[parts[i]]; - if (fileOrDir == null) { - request.response.statusCode = 404; - request.response.close(); - return; - } - } - request.response.write(fileOrDir); - request.response.close(); - }); - }); + fileTest("specified file syntax error", { + "anyname": "syntax error", + }, (Directory directory) { + File file = dirFile(directory, "anyname"); + expect(() => loadPackageConfig(file), throwsFormatException); }); - tearDown(() => serverSub.cancel()); - test(name, () => httpTest(uri)); - }); -} -void generalTest(String name, Map description, Future action(Uri location)) { - fileTest(name, description, action); - httpTest(name, description, action); -} + // Find package_config.json in subdir even if initial file syntax error. + fileTest("specified file syntax error", { + "anyname": "syntax error", + ".dart_tool": { + "package_config.json": packageConfigFile, + }, + }, (Directory directory) async { + File file = dirFile(directory, "anyname"); + PackageConfig config = await loadPackageConfig(file); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); -void _createFiles(Directory target, Map description) { - description.forEach((name, content) { - if (content is Map) { - Directory subDir = new Directory(path.join(target.path, name)); - subDir.createSync(); - _createFiles(subDir, content); - } else { - File file = new File(path.join(target.path, name)); - file.writeAsStringSync(content, flush: true); - } + // A file starting with `{` is a package_config.json file. + fileTest("file syntax error with {", { + ".packages": "{syntax error", + }, (Directory directory) { + File file = dirFile(directory, ".packages"); + expect(() => loadPackageConfig(file), throwsFormatException); + }); }); } diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart new file mode 100644 index 000000000..414a43add --- /dev/null +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -0,0 +1,256 @@ +// Copyright (c) 2019, 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. + +library package_config.discovery_test; + +import "dart:io"; +import "package:test/test.dart"; +import "package:package_config_2/package_config.dart"; + +import "src/util.dart"; + +const packagesFile = """ +# A comment +foo:file:///dart/packages/foo/ +bar:/dart/packages/bar/ +baz:packages/baz/ +"""; + +const packageConfigFile = """ +{ + "configVersion": 2, + "packages": [ + { + "name": "foo", + "rootUri": "file:///dart/packages/foo/" + }, + { + "name": "bar", + "rootUri": "/dart/packages/bar/" + }, + { + "name": "baz", + "rootUri": "../packages/baz/" + } + ], + "extra": [42] +} +"""; + +void validatePackagesFile(PackageConfig resolver, Uri directory) { + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(directory.resolve("/dart/packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(directory.resolve("packages/baz/qux/foo"))); + expect([for (var p in resolver.packages) p.name], + unorderedEquals(["foo", "bar", "baz"])); +} + +main() { + group("findPackages", () { + // Finds package_config.json if there. + loaderTest("package_config.json", { + ".packages": "invalid .packages file", + "script.dart": "main(){}", + "packages": {"shouldNotBeFound": {}}, + ".dart_tool": { + "package_config.json": packageConfigFile, + } + }, (Uri directory, loader) async { + PackageConfig config = + await findPackageConfigUri(directory, loader: loader); + expect(config.version, 2); // Found package_config.json file. + validatePackagesFile(config, directory); + }); + + // Finds .packages if no package_config.json. + loaderTest(".packages", { + ".packages": packagesFile, + "script.dart": "main(){}", + "packages": {"shouldNotBeFound": {}} + }, (Uri directory, loader) async { + PackageConfig config = + await findPackageConfigUri(directory, loader: loader); + expect(config.version, 1); // Found .packages file. + validatePackagesFile(config, directory); + }); + + // Finds package_config.json in super-directory. + loaderTest("package_config.json recursive", { + ".packages": packagesFile, + ".dart_tool": { + "package_config.json": packageConfigFile, + }, + "subdir": { + "script.dart": "main(){}", + } + }, (Uri directory, loader) async { + PackageConfig config = await findPackageConfigUri( + directory.resolve("subdir/"), + loader: loader); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + + // Finds .packages in super-directory. + loaderTest(".packages recursive", { + ".packages": packagesFile, + "subdir": {"script.dart": "main(){}"} + }, (Uri directory, loader) async { + PackageConfig config; + config = await findPackageConfigUri(directory.resolve("subdir/"), + loader: loader); + expect(config.version, 1); + validatePackagesFile(config, directory); + }); + + // Does not find a packages/ directory, and returns null if nothing found. + loaderTest("package directory packages not supported", { + "packages": { + "foo": {}, + } + }, (Uri directory, loader) async { + PackageConfig config = + await findPackageConfigUri(directory, loader: loader); + expect(config, null); + }); + + loaderTest("invalid .packages", { + ".packages": "not a .packages file", + }, (Uri directory, loader) { + expect(() => findPackageConfigUri(directory, loader: loader), + throwsA(TypeMatcher())); + }); + + loaderTest("invalid .packages as JSON", { + ".packages": packageConfigFile, + }, (Uri directory, loader) { + expect(() => findPackageConfigUri(directory, loader: loader), + throwsA(TypeMatcher())); + }); + + loaderTest("invalid .packages", { + ".dart_tool": { + "package_config.json": "not a JSON file", + } + }, (Uri directory, loader) { + expect(() => findPackageConfigUri(directory, loader: loader), + throwsA(TypeMatcher())); + }); + + loaderTest("invalid .packages as INI", { + ".dart_tool": { + "package_config.json": packagesFile, + } + }, (Uri directory, loader) { + expect(() => findPackageConfigUri(directory, loader: loader), + throwsA(TypeMatcher())); + }); + }); + + group("loadPackageConfig", () { + // Load a specific files + group("package_config.json", () { + var files = { + ".packages": packagesFile, + ".dart_tool": { + "package_config.json": packageConfigFile, + }, + }; + loaderTest("directly", files, (Uri directory, loader) async { + Uri file = directory.resolve(".dart_tool/package_config.json"); + PackageConfig config = await loadPackageConfigUri(file, loader: loader); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + loaderTest("indirectly through .packages", files, + (Uri directory, loader) async { + Uri file = directory.resolve(".packages"); + PackageConfig config = await loadPackageConfigUri(file, loader: loader); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + }); + + loaderTest("package_config.json non-default name", { + ".packages": packagesFile, + "subdir": { + "pheldagriff": packageConfigFile, + }, + }, (Uri directory, loader) async { + Uri file = directory.resolve("subdir/pheldagriff"); + PackageConfig config = await loadPackageConfigUri(file, loader: loader); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + + loaderTest("package_config.json named .packages", { + "subdir": { + ".packages": packageConfigFile, + }, + }, (Uri directory, loader) async { + Uri file = directory.resolve("subdir/.packages"); + PackageConfig config = await loadPackageConfigUri(file, loader: loader); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + + loaderTest(".packages", { + ".packages": packagesFile, + }, (Uri directory, loader) async { + Uri file = directory.resolve(".packages"); + PackageConfig config = await loadPackageConfigUri(file, loader: loader); + expect(config.version, 1); + validatePackagesFile(config, directory); + }); + + loaderTest(".packages non-default name", { + "pheldagriff": packagesFile, + }, (Uri directory, loader) async { + Uri file = directory.resolve("pheldagriff"); + PackageConfig config = await loadPackageConfigUri(file, loader: loader); + expect(config.version, 1); + validatePackagesFile(config, directory); + }); + + loaderTest("no config found", {}, (Uri directory, loader) { + Uri file = directory.resolve("anyname"); + expect(() => loadPackageConfigUri(file, loader: loader), + throwsArgumentError); + }); + + loaderTest("specified file syntax error", { + "anyname": "syntax error", + }, (Uri directory, loader) { + Uri file = directory.resolve("anyname"); + expect(() => loadPackageConfigUri(file, loader: loader), + throwsFormatException); + }); + + // Find package_config.json in subdir even if initial file syntax error. + loaderTest("specified file syntax error", { + "anyname": "syntax error", + ".dart_tool": { + "package_config.json": packageConfigFile, + }, + }, (Uri directory, loader) async { + Uri file = directory.resolve("anyname"); + PackageConfig config = await loadPackageConfigUri(file, loader: loader); + expect(config.version, 2); + validatePackagesFile(config, directory); + }); + + // A file starting with `{` is a package_config.json file. + loaderTest("file syntax error with {", { + ".packages": "{syntax error", + }, (Uri directory, loader) { + Uri file = directory.resolve(".packages"); + expect(() => loadPackageConfigUri(file, loader: loader), + throwsFormatException); + }); + }); +} diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index b9b1bb510..235f49381 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -1,245 +1,312 @@ -// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2019, 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. -library package_config.parse_test; +import "dart:io"; +import "dart:convert"; -import "package:package_config/packages.dart"; -import "package:package_config/packages_file.dart" show parse; -import "package:package_config/src/packages_impl.dart"; import "package:test/test.dart"; -main() { - var base = Uri.parse("file:///one/two/three/packages.map"); - test("empty", () { - var packages = doParse(emptySample, base); - expect(packages.asMap(), isEmpty); - }); - test("comment only", () { - var packages = doParse(commentOnlySample, base); - expect(packages.asMap(), isEmpty); - }); - test("empty lines only", () { - var packages = doParse(emptyLinesSample, base); - expect(packages.asMap(), isEmpty); - }); - - test("empty lines only", () { - var packages = doParse(emptyLinesSample, base); - expect(packages.asMap(), isEmpty); - }); - - test("single", () { - var packages = doParse(singleRelativeSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("single no slash", () { - var packages = doParse(singleRelativeSampleNoSlash, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("single no newline", () { - var packages = doParse(singleRelativeSampleNoNewline, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("single absolute authority", () { - var packages = doParse(singleAbsoluteSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(Uri.parse("http://example.com/some/where/bar/baz.dart"))); - }); - - test("single empty path", () { - var packages = doParse(singleEmptyPathSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.replace(path: "${base.path}/bar/baz.dart"))); - }); +import "package:package_config_2/src/packages_file.dart" as packages; +import "package:package_config_2/src/package_config_json.dart"; +import "src/util.dart"; - test("single absolute path", () { - var packages = doParse(singleAbsolutePathSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.replace(path: "/test/bar/baz.dart"))); - }); +void main() { + group(".packages", () { + test("valid", () { + var packagesFile = "# Generated by pub yadda yadda\n" + "foo:file:///foo/lib/\n" + "bar:/bar/lib/\n" + "baz:lib/\n"; + var result = packages.parse( + utf8.encode(packagesFile), Uri.parse("file:///tmp/file.dart")); + expect(result.version, 1); + expect({for (var p in result.packages) p.name}, {"foo", "bar", "baz"}); + expect(result.resolve(pkg("foo", "foo.dart")), + Uri.parse("file:///foo/lib/foo.dart")); + expect(result.resolve(pkg("bar", "bar.dart")), + Uri.parse("file:///bar/lib/bar.dart")); + expect(result.resolve(pkg("baz", "baz.dart")), + Uri.parse("file:///tmp/lib/baz.dart")); - test("multiple", () { - var packages = doParse(multiRelativeSample, base); - expect(packages.packages.toList()..sort(), equals(["bar", "foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - expect(packages.resolve(Uri.parse("package:bar/foo/baz.dart")), - equals(base.resolve("../test2/").resolve("foo/baz.dart"))); - }); + var foo = result["foo"]; + expect(foo, isNotNull); + expect(foo.root, Uri.parse("file:///foo/lib/")); + expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); + expect(foo.languageVersion, null); + }); - test("dot-dot 1", () { - var packages = doParse(singleRelativeSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/qux/../bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); + test("valid empty", () { + var packagesFile = "# Generated by pub yadda yadda\n"; + var result = + packages.parse(utf8.encode(packagesFile), Uri.file("/tmp/file.dart")); + expect(result.version, 1); + expect({for (var p in result.packages) p.name}, {}); + }); - test("all valid chars can be used in URI segment", () { - var packages = doParse(allValidCharsSample, base); - expect(packages.packages.toList(), equals([allValidChars])); - expect(packages.resolve(Uri.parse("package:$allValidChars/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); + group("invalid", () { + var baseFile = Uri.file("/tmp/file.dart"); + testThrows(String name, String content) { + test(name, () { + expect(() => packages.parse(utf8.encode(content), baseFile), + throwsA(TypeMatcher())); + }); + } - test("no invalid chars accepted", () { - var map = {}; - for (int i = 0; i < allValidChars.length; i++) { - map[allValidChars.codeUnitAt(i)] = true; - } - for (int i = 0; i <= 255; i++) { - if (map[i] == true) continue; - var char = new String.fromCharCode(i); - expect(() => doParse("x${char}x:x", null), - anyOf(throwsNoSuchMethodError, throwsFormatException)); - } + testThrows("repeated package name", "foo:lib/\nfoo:lib\n"); + testThrows("no colon", "foo\n"); + testThrows("empty package name", ":lib/\n"); + testThrows("dot only package name", ".:lib/\n"); + testThrows("dot only package name", "..:lib/\n"); + testThrows("invalid package name character", "f\\o:lib/\n"); + testThrows("package URI", "foo:package:bar/lib/"); + testThrows("location with query", "f\\o:lib/?\n"); + testThrows("location with fragment", "f\\o:lib/#\n"); + }); }); - test("no escapes", () { - expect(() => doParse("x%41x:x", base), throwsFormatException); - }); + group("package_config.json", () { + test("valid", () { + var packageConfigFile = """ + { + "configVersion": 2, + "packages": [ + { + "name": "foo", + "rootUri": "file:///foo/", + "packageUri": "lib/", + "languageVersion": "2.5", + "nonstandard": true + }, + { + "name": "bar", + "rootUri": "/bar/", + "packageUri": "lib/", + "languageVersion": "100.100" + }, + { + "name": "baz", + "rootUri": "../", + "packageUri": "lib/" + } + ], + "generator": "pub", + "other": [42] + } + """; + var config = parsePackageConfigBytes(utf8.encode(packageConfigFile), + Uri.parse("file:///tmp/.dart_tool/file.dart")); + expect(config.version, 2); + expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"}); - test("same name twice", () { - expect( - () => doParse(singleRelativeSample * 2, base), throwsFormatException); - }); + expect(config.resolve(pkg("foo", "foo.dart")), + Uri.parse("file:///foo/lib/foo.dart")); + expect(config.resolve(pkg("bar", "bar.dart")), + Uri.parse("file:///bar/lib/bar.dart")); + expect(config.resolve(pkg("baz", "baz.dart")), + Uri.parse("file:///tmp/lib/baz.dart")); - test("disallow default package", () { - expect(() => doParse(":foo", base, allowDefaultPackage: false), - throwsFormatException); - }); + var foo = config["foo"]; + expect(foo, isNotNull); + expect(foo.root, Uri.parse("file:///foo/")); + expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); + expect(foo.languageVersion, "2.5"); + expect(foo.extraData, {"nonstandard": true}); - test("allow default package", () { - var packages = doParse(":foo", base, allowDefaultPackage: true); - expect(packages.defaultPackageName, "foo"); - }); + var bar = config["bar"]; + expect(bar, isNotNull); + expect(bar.root, Uri.parse("file:///bar/")); + expect(bar.packageUriRoot, Uri.parse("file:///bar/lib/")); + expect(bar.languageVersion, "100.100"); + expect(bar.extraData, null); - test("allow default package name with dot", () { - var packages = doParse(":foo.bar", base, allowDefaultPackage: true); - expect(packages.defaultPackageName, "foo.bar"); - }); + var baz = config["baz"]; + expect(baz, isNotNull); + expect(baz.root, Uri.parse("file:///tmp/")); + expect(baz.packageUriRoot, Uri.parse("file:///tmp/lib/")); + expect(baz.languageVersion, null); - test("not two default packages", () { - expect(() => doParse(":foo\n:bar", base, allowDefaultPackage: true), - throwsFormatException); - }); + expect(config.extraData, { + "generator": "pub", + "other": [42] + }); + }); - test("default package invalid package name", () { - // Not a valid *package name*. - expect(() => doParse(":foo/bar", base, allowDefaultPackage: true), - throwsFormatException); - }); + test("valid other order", () { + // The ordering in the file is not important. + var packageConfigFile = """ + { + "generator": "pub", + "other": [42], + "packages": [ + { + "languageVersion": "2.5", + "packageUri": "lib/", + "rootUri": "file:///foo/", + "name": "foo" + }, + { + "packageUri": "lib/", + "languageVersion": "100.100", + "rootUri": "/bar/", + "name": "bar" + }, + { + "packageUri": "lib/", + "name": "baz", + "rootUri": "../" + } + ], + "configVersion": 2 + } + """; + var config = parsePackageConfigBytes(utf8.encode(packageConfigFile), + Uri.parse("file:///tmp/.dart_tool/file.dart")); + expect(config.version, 2); + expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"}); - group("metadata", () { - var packages = doParse( - ":foo\n" - "foo:foo#metafoo=1\n" - "bar:bar#metabar=2\n" - "baz:baz\n" - "qux:qux#metaqux1=3&metaqux2=4\n", - base, - allowDefaultPackage: true); - test("non-existing", () { - // non-package name. - expect(packages.packageMetadata("///", "f"), null); - expect(packages.packageMetadata("", "f"), null); - // unconfigured package name. - expect(packages.packageMetadata("absent", "f"), null); - // package name without that metadata - expect(packages.packageMetadata("foo", "notfoo"), null); - }); - test("lookup", () { - expect(packages.packageMetadata("foo", "metafoo"), "1"); - expect(packages.packageMetadata("bar", "metabar"), "2"); - expect(packages.packageMetadata("qux", "metaqux1"), "3"); - expect(packages.packageMetadata("qux", "metaqux2"), "4"); + expect(config.resolve(pkg("foo", "foo.dart")), + Uri.parse("file:///foo/lib/foo.dart")); + expect(config.resolve(pkg("bar", "bar.dart")), + Uri.parse("file:///bar/lib/bar.dart")); + expect(config.resolve(pkg("baz", "baz.dart")), + Uri.parse("file:///tmp/lib/baz.dart")); + expect(config.extraData, { + "generator": "pub", + "other": [42] + }); }); - test("by library URI", () { - expect( - packages.libraryMetadata( - Uri.parse("package:foo/index.dart"), "metafoo"), - "1"); - expect( - packages.libraryMetadata( - Uri.parse("package:bar/index.dart"), "metabar"), - "2"); - expect( - packages.libraryMetadata( - Uri.parse("package:qux/index.dart"), "metaqux1"), - "3"); - expect( - packages.libraryMetadata( - Uri.parse("package:qux/index.dart"), "metaqux2"), - "4"); + + // Check that a few minimal configurations are valid. + // These form the basis of invalid tests below. + var cfg = '"configVersion":2'; + var pkgs = '"packages":[]'; + var name = '"name":"foo"'; + var root = '"rootUri":"/foo/"'; + test("minimal", () { + var config = parsePackageConfigBytes(utf8.encode("{$cfg,$pkgs}"), + Uri.parse("file:///tmp/.dart_tool/file.dart")); + expect(config.version, 2); + expect(config.packages, isEmpty); }); - test("by default package", () { - expect( - packages.libraryMetadata( - Uri.parse("file:///whatever.dart"), "metafoo"), - "1"); + test("minimal package", () { + // A package must have a name and a rootUri, the remaining properties + // are optional. + var config = parsePackageConfigBytes( + utf8.encode('{$cfg,"packages":[{$name,$root}]}'), + Uri.parse("file:///tmp/.dart_tool/file.dart")); + expect(config.version, 2); + expect(config.packages.first.name, "foo"); }); - }); - for (String invalidSample in invalid) { - test("invalid '$invalidSample'", () { - var result; - try { - result = doParse(invalidSample, base); - } on FormatException { - // expected - return; + group("invalid", () { + testThrows(String name, String source) { + test(name, () { + expect( + () => parsePackageConfigBytes(utf8.encode(source), + Uri.parse("file:///tmp/.dart_tool/file.dart")), + throwsA(TypeMatcher())); + }); } - fail("Resolved to $result"); - }); - } -} -Packages doParse(String sample, Uri baseUri, - {bool allowDefaultPackage = false}) { - Map map = parse(sample.codeUnits, baseUri, - allowDefaultPackage: allowDefaultPackage); - return new MapPackages(map); -} + testThrows("comment", '# comment\n {$cfg,$pkgs}'); + testThrows(".packages file", 'foo:/foo\n'); + testThrows("no configVersion", '{$pkgs}'); + testThrows("no packages", '{$cfg}'); + group("config version:", () { + testThrows("null", '{"configVersion":null,$pkgs}'); + testThrows("string", '{"configVersion":"2",$pkgs}'); + testThrows("array", '{"configVersion":[2],$pkgs}'); + }); + group("packages:", () { + testThrows("null", '{$cfg,"packages":null}'); + testThrows("string", '{$cfg,"packages":"foo"}'); + testThrows("object", '{$cfg,"packages":{}}'); + }); + group("packages entry:", () { + testThrows("null", '{$cfg,"packages":[null]}'); + testThrows("string", '{$cfg,"packages":["foo"]}'); + testThrows("array", '{$cfg,"packages":[[]]}'); + }); + group("package", () { + testThrows("no name", '{$cfg,"packages":[{$root}]}'); + group("name:", () { + testThrows("null", '{$cfg,"packages":[{"name":null,$root}]}'); + testThrows("num", '{$cfg,"packages":[{"name":1,$root}]}'); + testThrows("object", '{$cfg,"packages":[{"name":{},$root}]}'); + testThrows("empty", '{$cfg,"packages":[{"name":"",$root}]}'); + testThrows("one-dot", '{$cfg,"packages":[{"name":".",$root}]}'); + testThrows("two-dot", '{$cfg,"packages":[{"name":"..",$root}]}'); + testThrows( + "invalid char '\\'", '{$cfg,"packages":[{"name":"\\",$root}]}'); + testThrows( + "invalid char ':'", '{$cfg,"packages":[{"name":":",$root}]}'); + testThrows( + "invalid char ' '", '{$cfg,"packages":[{"name":" ",$root}]}'); + }); -// Valid samples. -var emptySample = ""; -var commentOnlySample = "# comment only\n"; -var emptyLinesSample = "\n\n\r\n"; -var singleRelativeSample = "foo:../test/\n"; -var singleRelativeSampleNoSlash = "foo:../test\n"; -var singleRelativeSampleNoNewline = "foo:../test/"; -var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; -var singleEmptyPathSample = "foo:\n"; -var singleAbsolutePathSample = "foo:/test/\n"; -var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; -// All valid path segment characters in an URI. -var allValidChars = r"!$&'()*+,-.0123456789;=" - r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; - -var allValidCharsSample = "${allValidChars}:../test/\n"; - -// Invalid samples. -var invalid = [ - ":baz.dart", // empty. - "foobar=baz.dart", // no colon (but an equals, which is not the same) - ".:../test/", // dot segment - "..:../test/", // dot-dot segment - "...:../test/", // dot-dot-dot segment - "foo/bar:../test/", // slash in name - "/foo:../test/", // slash at start of name - "?:../test/", // invalid characters. - "[:../test/", // invalid characters. - "x#:../test/", // invalid characters. -]; + testThrows("no root", '{$cfg,"packages":[{$name}]}'); + group("root:", () { + testThrows("null", '{$cfg,"packages":[{$name,"rootUri":null}]}'); + testThrows("num", '{$cfg,"packages":[{$name,"rootUri":1}]}'); + testThrows("object", '{$cfg,"packages":[{$name,"rootUri":{}}]}'); + testThrows("fragment", '{$cfg,"packages":[{$name,"rootUri":"x/#"}]}'); + testThrows("query", '{$cfg,"packages":[{$name,"rootUri":"x/?"}]}'); + testThrows("package-URI", + '{$cfg,"packages":[{$name,"rootUri":"package:x/x/"}]}'); + }); + group("package-URI root:", () { + testThrows( + "null", '{$cfg,"packages":[{$name,$root,"packageUri":null}]}'); + testThrows("num", '{$cfg,"packages":[{$name,$root,"packageUri":1}]}'); + testThrows( + "object", '{$cfg,"packages":[{$name,$root,"packageUri":{}}]}'); + testThrows("fragment", + '{$cfg,"packages":[{$name,$root,"packageUri":"x/#"}]}'); + testThrows( + "query", '{$cfg,"packages":[{$name,$root,"packageUri":"x/?"}]}'); + testThrows("package: URI", + '{$cfg,"packages":[{$name,$root,"packageUri":"package:x/x/"}]}'); + testThrows("not inside root", + '{$cfg,"packages":[{$name,$root,"packageUri":"../other/"}]}'); + }); + group("language version", () { + testThrows("null", + '{$cfg,"packages":[{$name,$root,"languageVersion":null}]}'); + testThrows( + "num", '{$cfg,"packages":[{$name,$root,"languageVersion":1}]}'); + testThrows("object", + '{$cfg,"packages":[{$name,$root,"languageVersion":{}}]}'); + testThrows("empty", + '{$cfg,"packages":[{$name,$root,"languageVersion":""}]}'); + testThrows("non number.number", + '{$cfg,"packages":[{$name,$root,"languageVersion":"x.1"}]}'); + testThrows("number.non number", + '{$cfg,"packages":[{$name,$root,"languageVersion":"1.x"}]}'); + testThrows("non number", + '{$cfg,"packages":[{$name,$root,"languageVersion":"x"}]}'); + testThrows("one number", + '{$cfg,"packages":[{$name,$root,"languageVersion":"1"}]}'); + testThrows("three numbers", + '{$cfg,"packages":[{$name,$root,"languageVersion":"1.2.3"}]}'); + testThrows("leading zero first", + '{$cfg,"packages":[{$name,$root,"languageVersion":"01.1"}]}'); + testThrows("leading zero second", + '{$cfg,"packages":[{$name,$root,"languageVersion":"1.01"}]}'); + testThrows("trailing-", + '{$cfg,"packages":[{$name,$root,"languageVersion":"1.1-1"}]}'); + testThrows("trailing+", + '{$cfg,"packages":[{$name,$root,"languageVersion":"1.1+1"}]}'); + }); + }); + testThrows("duplicate package name", + '{$cfg,"packages":[{$name,$root},{$name,"rootUri":"/other/"}]}'); + testThrows("same roots", + '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); + testThrows( + "overlapping roots", + '{$cfg,"packages":[{$name,$root},' + '{"name":"bar","rootUri":"/foo/sub/"}]}'); + }); + }); +} diff --git a/pkgs/package_config/test/parse_write_test.dart b/pkgs/package_config/test/parse_write_test.dart deleted file mode 100644 index 415b479e9..000000000 --- a/pkgs/package_config/test/parse_write_test.dart +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) 2015, 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. - -library package_config.parse_write_test; - -import "dart:convert" show utf8; -import "package:package_config/packages_file.dart"; -import "package:test/test.dart"; - -main() { - testBase(baseDirString) { - var baseDir = Uri.parse(baseDirString); - group("${baseDir.scheme} base", () { - Uri packagesFile = baseDir.resolve(".packages"); - - roundTripTest(String name, Map map) { - group(name, () { - test("write with no baseUri", () { - var content = writeToString(map).codeUnits; - var resultMap = parse(content, packagesFile); - expect(resultMap, map); - }); - - test("write with base directory", () { - var content = writeToString(map, baseUri: baseDir).codeUnits; - var resultMap = parse(content, packagesFile); - expect(resultMap, map); - }); - - test("write with base .packages file", () { - var content = writeToString(map, baseUri: packagesFile).codeUnits; - var resultMap = parse(content, packagesFile); - expect(resultMap, map); - }); - - test("write with defaultPackageName", () { - var content = writeToString( - {'': Uri.parse('my_pkg')}..addAll(map), - allowDefaultPackage: true, - ).codeUnits; - var resultMap = parse( - content, - packagesFile, - allowDefaultPackage: true, - ); - expect(resultMap[''].toString(), 'my_pkg'); - expect( - resultMap, - {'': Uri.parse('my_pkg')}..addAll(map), - ); - }); - - test("write with defaultPackageName (utf8)", () { - var content = utf8.encode(writeToString( - {'': Uri.parse('my_pkg')}..addAll(map), - allowDefaultPackage: true, - )); - var resultMap = parse( - content, - packagesFile, - allowDefaultPackage: true, - ); - expect(resultMap[''].toString(), 'my_pkg'); - expect( - resultMap, - {'': Uri.parse('my_pkg')}..addAll(map), - ); - }); - }); - } - - var lowerDir = baseDir.resolve("path3/path4/"); - var higherDir = baseDir.resolve("../"); - var parallelDir = baseDir.resolve("../path3/"); - var rootDir = baseDir.resolve("/"); - var fileDir = Uri.parse("file:///path1/part2/"); - var httpDir = Uri.parse("http://example.com/path1/path2/"); - var otherDir = Uri.parse("other:/path1/path2/"); - - roundTripTest("empty", {}); - roundTripTest("lower directory", {"foo": lowerDir}); - roundTripTest("higher directory", {"foo": higherDir}); - roundTripTest("parallel directory", {"foo": parallelDir}); - roundTripTest("same directory", {"foo": baseDir}); - roundTripTest("root directory", {"foo": rootDir}); - roundTripTest("file directory", {"foo": fileDir}); - roundTripTest("http directory", {"foo": httpDir}); - roundTripTest("other scheme directory", {"foo": otherDir}); - roundTripTest("multiple same-type directories", - {"foo": lowerDir, "bar": higherDir, "baz": parallelDir}); - roundTripTest("multiple scheme directories", - {"foo": fileDir, "bar": httpDir, "baz": otherDir}); - roundTripTest("multiple scheme directories and mutliple same type", { - "foo": fileDir, - "bar": httpDir, - "baz": otherDir, - "qux": lowerDir, - "hip": higherDir, - "dep": parallelDir - }); - }); - } - - testBase("file:///base1/base2/"); - testBase("http://example.com/base1/base2/"); - testBase("other:/base1/base2/"); - - // Check that writing adds the comment. - test("write preserves comment", () { - var comment = "comment line 1\ncomment line 2\ncomment line 3"; - var result = writeToString({}, comment: comment); - // Comment with "# " before each line and "\n" after last. - var expectedComment = - "# comment line 1\n# comment line 2\n# comment line 3\n"; - expect(result, startsWith(expectedComment)); - }); -} - -String writeToString( - Map map, { - Uri baseUri, - String comment, - bool allowDefaultPackage = false, -}) { - var buffer = new StringBuffer(); - write(buffer, map, - baseUri: baseUri, - comment: comment, - allowDefaultPackage: allowDefaultPackage); - return buffer.toString(); -} diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart new file mode 100644 index 000000000..ec4e5e8bc --- /dev/null +++ b/pkgs/package_config/test/src/util.dart @@ -0,0 +1,109 @@ +// Copyright (c) 2019, 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 'dart:convert'; +import "dart:io"; +import 'dart:typed_data'; + +import "package:path/path.dart" as path; +import "package:test/test.dart"; + +/// Creates a directory structure from [description] and runs [fileTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a subdirectory, otherwise it's a file and the value is the content +/// as a string. +/// Introduces a group to hold the [setUp]/[tearDown] logic. +void fileTest(String name, Map description, + void fileTest(Directory directory)) { + group("file-test", () { + Directory tempDir = Directory.systemTemp.createTempSync("pkgcfgtest"); + setUp(() { + _createFiles(tempDir, description); + }); + tearDown(() { + tempDir.deleteSync(recursive: true); + }); + test(name, () => fileTest(tempDir)); + }); +} + +/// Creates a set of files under a new temporary directory. +/// Returns the temporary directory. +/// +/// The [description] is a map from file names to content. +/// If the content is again a map, it represents a subdirectory +/// with the content as description. +/// Otherwise the content should be a string, +/// which is written to the file as UTF-8. +Directory createTestFiles(Map description) { + var target = Directory.systemTemp.createTempSync("pkgcfgtest"); + _createFiles(target, description); + return target; +} + +// Creates temporary files in the target directory. +void _createFiles(Directory target, Map description) { + description.forEach((name, content) { + var entryName = path.join(target.path, "$name"); + if (content is Map) { + _createFiles(Directory(entryName)..createSync(), content); + } else { + File(entryName).writeAsStringSync(content, flush: true); + } + }); +} + +/// Creates a [Directory] for a subdirectory of [parent]. +Directory subdir(Directory parent, String dirName) => + Directory(path.joinAll([parent.path, ...dirName.split("/")])); + +/// Creates a [File] for an entry in the [directory] directory. +File dirFile(Directory directory, String fileName) => + File(path.join(directory.path, fileName)); + +/// Creates a package: URI. +Uri pkg(String packageName, String packagePath) { + var path = + "$packageName${packagePath.startsWith('/') ? "" : "/"}$packagePath"; + return new Uri(scheme: "package", path: path); +} + +// Remove if not used. +String configFromPackages(List> packages) => """ +{ + "configVersion": 2, + "packages": [ +${packages.map((nu) => """ + { + "name": "${nu[0]}", + "rootUri": "${nu[1]}" + }""").join(",\n")} + ] +} +"""; + +/// Mimics a directory structure of [description] and runs [fileTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a subdirectory, otherwise it's a file and the value is the content +/// as a string. +void loaderTest(String name, Map description, + void loaderTest(Uri root, Future loader(Uri uri))) { + Uri root = Uri(scheme: "test", path: "/"); + Future loader(Uri uri) async { + var path = uri.path; + if (!uri.isScheme("test") || !path.startsWith("/")) return null; + var parts = path.split("/"); + dynamic value = description; + for (int i = 1; i < parts.length; i++) { + if (value is! Map) return null; + value = value[parts[i]]; + } + if (value is String) return utf8.encode(value); + return null; + } + + test(name, () => loaderTest(root, loader)); +} From 9ff0d68b4eee3b2b6326f07ced0664bd7a2c97c3 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 14 Jan 2020 19:48:42 -0800 Subject: [PATCH 322/657] Add support for highlighting multiple spans at once (dart-lang/source_span#49) This makes it possible for applications to provide additional context in their span-based messages. Like the existing highlight format, it's heavily inspired by [Rust's error messages][]. [Rust's error messages]: https://blog.rust-lang.org/images/2016-08-09-Errors/new_errors.png For maximal backwards-compatibility, this doesn't change the formatting of any single-span highlights and it uses extension methods rather than adding new methods to existing classes. --- pkgs/source_span/.travis.yml | 2 +- pkgs/source_span/CHANGELOG.md | 8 + pkgs/source_span/analysis_options.yaml | 13 +- pkgs/source_span/lib/src/highlighter.dart | 802 ++++++++++++------ pkgs/source_span/lib/src/span.dart | 72 ++ pkgs/source_span/lib/src/span_exception.dart | 69 +- pkgs/source_span/lib/src/utils.dart | 38 + pkgs/source_span/pubspec.yaml | 6 +- pkgs/source_span/test/highlight_test.dart | 64 +- .../test/multiple_highlight_test.dart | 281 ++++++ pkgs/source_span/test/span_test.dart | 2 +- 11 files changed, 1061 insertions(+), 296 deletions(-) create mode 100644 pkgs/source_span/test/multiple_highlight_test.dart diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index edb90e60b..9738ed50e 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -2,7 +2,7 @@ language: dart dart: - dev - - 2.1.0 + - 2.6.0 dart_task: - test: --platform vm,chrome diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 0dfe483b6..014cc4c63 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,11 @@ +# 1.6.0 + +* Add support for highlighting multiple source spans at once, providing more + context for span-based messages. This is exposed through the new APIs + `SourceSpan.highlightMultiple()` and `SourceSpan.messageMultiple()` (both + extension methods), `MultiSourceSpanException`, and + `MultiSourceSpanFormatException`. + # 1.5.6 * Fix padding around line numbers that are powers of 10 in diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index a94bb5062..0ce791169 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -2,6 +2,9 @@ include: package:pedantic/analysis_options.yaml analyzer: strong-mode: implicit-casts: false + errors: + # TODO(natebosch): fix and re-enable. + prefer_single_quotes: ignore linter: rules: - always_declare_return_types @@ -26,7 +29,8 @@ linter: - await_only_futures - camel_case_types - cancel_subscriptions - - cascade_invocations + # TODO(natebosch): fix and re-enable. + #- cascade_invocations - comment_references - constant_identifier_names - control_flow_in_finally @@ -59,14 +63,15 @@ linter: - prefer_contains - prefer_equal_for_default_values - prefer_final_fields - - prefer_final_locals + # TODO(natebosch): fix and re-enable. + #- prefer_final_locals - prefer_generic_function_type_aliases - prefer_initializing_formals - - prefer_interpolation_to_compose_strings + # TODO(natebosch): fix and re-enable. + #- prefer_interpolation_to_compose_strings - prefer_is_empty - prefer_is_not_empty - prefer_null_aware_operators - - prefer_single_quotes - prefer_typing_uninitialized_variables - recursive_getters - slash_for_doc_comments diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 3ebe0df0c..feb5594d5 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -5,6 +5,9 @@ import 'dart:math' as math; 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; import 'colors.dart' as colors; @@ -15,25 +18,26 @@ import 'utils.dart'; /// A class for writing a chunk of text with a particular span highlighted. class Highlighter { - /// The span to highlight. - final SourceSpanWithContext _span; + /// The lines to display, including context around the highlighted spans. + final List<_Line> _lines; - /// The color to highlight [_span] within its context, or `null` if the span - /// should not be colored. - final String _color; + /// The color to highlight the primary [_Highlight] within its context, or + /// `null` if it should not be colored. + final String _primaryColor; - /// Whether [_span] covers multiple lines. - final bool _multiline; + /// The color to highlight the secondary [_Highlight]s within their context, + /// or `null` if they should not be colored. + final String _secondaryColor; /// The number of characters before the bar in the sidebar. final int _paddingBeforeSidebar; - // The number of characters between the bar in the sidebar and the text - // being highlighted. - int get _paddingAfterSidebar => - // This is just a space for a single-line span, but for a multi-line span - // needs to accommodate " | ". - _multiline ? 3 : 1; + /// The maximum number of multiline spans that cover any part of a single + /// line in [_lines]. + final int _maxMultilineSpans; + + /// Whether [_lines] includes lines from multiple different files. + final bool _multipleFiles; /// The buffer to which to write the result. final _buffer = StringBuffer(); @@ -44,28 +48,478 @@ class Highlighter { /// alignment. static const _spacesPerTab = 4; - /// Creates a [Highlighter] that will return a message associated with [span] - /// when [highlight] is called. + /// Creates a [Highlighter] that will return a string highlighting [span] + /// within the text of its file when [highlight] is called. /// /// [color] may either be a [String], a [bool], or `null`. If it's a string, - /// it indicates an [ANSI terminal color escape][] that should - /// be used to highlight the span's text (for example, `"\u001b[31m"` will - /// color red). If it's `true`, it indicates that the text should be - /// highlighted using the default color. If it's `false` or `null`, it - /// indicates that the text shouldn't be highlighted. + /// it indicates an [ANSI terminal color escape][] that should be used to + /// highlight [span]'s text (for example, `"\u001b[31m"` will color red). If + /// it's `true`, it indicates that the text should be highlighted using the + /// default color. If it's `false` or `null`, it indicates that no color + /// should be used. + /// + /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors + Highlighter(SourceSpan span, {color}) + : this._(_collateLines([_Highlight(span, primary: true)]), () { + if (color == true) return colors.red; + if (color == false) return null; + return color as String; + }(), null); + + /// Creates a [Highlighter] that will return a string highlighting + /// [primarySpan] as well as all the spans in [secondarySpans] within the text + /// of their file when [highlight] is called. + /// + /// Each span has an associated label that will be written alongside it. For + /// [primarySpan] this message is [primaryLabel], and for [secondarySpans] the + /// labels are the map values. + /// + /// If [color] is `true`, this will use [ANSI terminal color escapes][] to + /// highlight the text. The [primarySpan] will be highlighted with + /// [primaryColor] (which defaults to red), and the [secondarySpans] will be + /// highlighted with [secondaryColor] (which defaults to blue). These + /// arguments are ignored if [color] is `false`. /// /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors - factory Highlighter(SourceSpan span, {color}) { - if (color == true) color = colors.red; - if (color == false) color = null; + Highlighter.multiple(SourceSpan primarySpan, String primaryLabel, + Map secondarySpans, + {bool color = false, String primaryColor, String secondaryColor}) + : this._( + _collateLines([ + _Highlight(primarySpan, label: primaryLabel, primary: true), + for (var entry in secondarySpans.entries) + _Highlight(entry.key, label: entry.value) + ]), + color ? (primaryColor ?? colors.red) : null, + color ? (secondaryColor ?? colors.blue) : null); + + Highlighter._(this._lines, this._primaryColor, this._secondaryColor) + : _paddingBeforeSidebar = 1 + + math.max( + // In a purely mathematical world, floor(log10(n)) would give the + // number of digits in n, but floating point errors render that + // unreliable in practice. + (_lines.last.number + 1).toString().length, + // If [_lines] aren't contiguous, we'll write "..." in place of a + // line number. + _contiguous(_lines) ? 0 : 3), + _maxMultilineSpans = _lines + .map((line) => line.highlights + .where((highlight) => isMultiline(highlight.span)) + .length) + .reduce(math.max), + _multipleFiles = !isAllTheSame(_lines.map((line) => line.url)); + + /// Returns whether [lines] contains any adjacent lines from the same source + /// file that aren't adjacent in the original file. + static bool _contiguous(List<_Line> lines) { + for (var i = 0; i < lines.length - 1; i++) { + var thisLine = lines[i]; + var nextLine = lines[i + 1]; + if (thisLine.number + 1 != nextLine.number && + thisLine.url == nextLine.url) { + return false; + } + } + return true; + } + + /// 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) { + var highlightsByUrl = + groupBy(highlights, (highlight) => highlight.span.sourceUrl); + for (var list in highlightsByUrl.values) { + list.sort((highlight1, highlight2) => + highlight1.span.compareTo(highlight2.span)); + } + + return highlightsByUrl.values.expand((highlightsForFile) { + // First, create a list of all the lines in the current file that we have + // context for along with their line numbers. + var lines = <_Line>[]; + for (var highlight in highlightsForFile) { + var context = highlight.span.context; + // If [highlight.span.context] contains lines prior to the one + // [highlight.span.text] appears on, write those first. + var lineStart = findLineStart( + context, highlight.span.text, highlight.span.start.column); + assert(lineStart != null); // enforced by [_normalizeContext] + + var linesBeforeSpan = + '\n'.allMatches(context.substring(0, lineStart)).length; + + var url = highlight.span.sourceUrl; + var lineNumber = highlight.span.start.line - linesBeforeSpan; + for (var line in context.split('\n')) { + // Only add a line if it hasn't already been added for a previous span. + if (lines.isEmpty || lineNumber > lines.last.number) { + lines.add(_Line(line, lineNumber, url)); + } + lineNumber++; + } + } + + // Next, associate each line with each highlights that covers it. + var activeHighlights = <_Highlight>[]; + var highlightIndex = 0; + for (var line in lines) { + activeHighlights.removeWhere((highlight) => + highlight.span.sourceUrl != line.url || + highlight.span.end.line < line.number); + + var oldHighlightLength = activeHighlights.length; + for (var highlight in highlightsForFile.skip(highlightIndex)) { + if (highlight.span.start.line > line.number) break; + if (highlight.span.sourceUrl != line.url) break; + activeHighlights.add(highlight); + } + highlightIndex += activeHighlights.length - oldHighlightLength; + + line.highlights.addAll(activeHighlights); + } + + return lines; + }).toList(); + } + + /// Returns the highlighted span text. + /// + /// This method should only be called once. + String highlight() { + _writeFileStart(_lines.first.url); + + // 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. + var highlightsByColumn = List<_Highlight>(_maxMultilineSpans); + + for (var i = 0; i < _lines.length; i++) { + var line = _lines[i]; + if (i > 0) { + var lastLine = _lines[i - 1]; + if (lastLine.url != line.url) { + _writeSidebar(end: glyph.upEnd); + _buffer.writeln(); + _writeFileStart(line.url); + } else if (lastLine.number + 1 != line.number) { + _writeSidebar(text: '...'); + _buffer.writeln(); + } + } + + // If a highlight covers the entire first line other than initial + // whitespace, don't bother pointing out exactly where it begins. Iterate + // in reverse so that longer highlights (which are sorted after shorter + // highlights) appear further out, leading to fewer crossed lines. + for (var highlight in line.highlights.reversed) { + if (isMultiline(highlight.span) && + highlight.span.start.line == line.number && + _isOnlyWhitespace( + line.text.substring(0, highlight.span.start.column))) { + replaceFirstNull(highlightsByColumn, highlight); + } + } + + _writeSidebar(line: line.number); + _buffer.write(' '); + _writeMultilineHighlights(line, highlightsByColumn); + if (highlightsByColumn.isNotEmpty) _buffer.write(' '); + + var primary = line.highlights + .firstWhere((highlight) => highlight.isPrimary, orElse: () => null); + if (primary != null) { + _writeHighlightedText( + line.text, + primary.span.start.line == line.number + ? primary.span.start.column + : 0, + primary.span.end.line == line.number + ? primary.span.end.column + : line.text.length, + color: _primaryColor); + } else { + _writeText(line.text); + } + _buffer.writeln(); + + // Always write the primary span's indicator first so that it's right next + // to the highlighted text. + if (primary != null) _writeIndicator(line, primary, highlightsByColumn); + for (var highlight in line.highlights) { + if (highlight.isPrimary) continue; + _writeIndicator(line, highlight, highlightsByColumn); + } + } + + _writeSidebar(end: glyph.upEnd); + return _buffer.toString(); + } + + /// Writes the beginning of the file highlight for the file with the given + /// [url]. + void _writeFileStart(Uri url) { + if (!_multipleFiles || url == null) { + _writeSidebar(end: glyph.downEnd); + } else { + _writeSidebar(end: glyph.topLeftCorner); + _colorize(() => _buffer.write("${glyph.horizontalLine * 2}>"), + color: colors.blue); + _buffer.write(" ${p.prettyUri(url)}"); + } + _buffer.writeln(); + } + + /// Writes the post-sidebar highlight bars for [line] according to + /// [highlightsByColumn]. + /// + /// If [current] is passed, it's the highlight for which an indicator is being + /// 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}) { + // 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; + + var currentColor = current == null + ? null + : current.isPrimary ? _primaryColor : _secondaryColor; + var foundCurrent = false; + for (var highlight in highlightsByColumn) { + var startLine = highlight?.span?.start?.line; + var endLine = highlight?.span?.end?.line; + if (current != null && highlight == current) { + foundCurrent = true; + assert(startLine == line.number || endLine == line.number); + _colorize(() { + _buffer.write(startLine == line.number + ? glyph.topLeftCorner + : glyph.bottomLeftCorner); + }, color: currentColor); + } else if (foundCurrent) { + _colorize(() { + _buffer.write(highlight == null ? glyph.horizontalLine : glyph.cross); + }, color: currentColor); + } else if (highlight == null) { + if (openedOnThisLine) { + _colorize(() => _buffer.write(glyph.horizontalLine), + color: openedOnThisLineColor); + } else { + _buffer.write(' '); + } + } else { + _colorize(() { + var vertical = openedOnThisLine ? glyph.cross : glyph.verticalLine; + if (current != null) { + _buffer.write(vertical); + } else if (startLine == line.number) { + _colorize(() { + _buffer + .write(glyph.glyphOrAscii(openedOnThisLine ? '┬' : '┌', '/')); + }, color: openedOnThisLineColor); + openedOnThisLine = true; + openedOnThisLineColor ??= + highlight.isPrimary ? _primaryColor : _secondaryColor; + } else if (endLine == line.number && + highlight.span.end.column == line.text.length) { + _buffer.write(highlight.label == null + ? glyph.glyphOrAscii('└', '\\') + : vertical); + } else { + _colorize(() { + _buffer.write(vertical); + }, color: openedOnThisLineColor); + } + }, color: highlight.isPrimary ? _primaryColor : _secondaryColor); + } + } + } + + // 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}) { + _writeText(text.substring(0, startColumn)); + _colorize(() => _writeText(text.substring(startColumn, endColumn)), + color: color); + _writeText(text.substring(endColumn, text.length)); + } + + /// Writes an indicator for where [highlight] starts, ends, or both below + /// [line]. + /// + /// This may either add or remove [highlight] from [highlightsByColumn]. + void _writeIndicator( + _Line line, _Highlight highlight, List<_Highlight> highlightsByColumn) { + var color = highlight.isPrimary ? _primaryColor : _secondaryColor; + if (!isMultiline(highlight.span)) { + _writeSidebar(); + _buffer.write(' '); + _writeMultilineHighlights(line, highlightsByColumn, current: highlight); + if (highlightsByColumn.isNotEmpty) _buffer.write(' '); + + _colorize(() { + _writeUnderline(line, highlight.span, + highlight.isPrimary ? "^" : glyph.horizontalLineBold); + _writeLabel(highlight.label); + }, color: color); + _buffer.writeln(); + } else if (highlight.span.start.line == line.number) { + if (highlightsByColumn.contains(highlight)) return; + replaceFirstNull(highlightsByColumn, highlight); + + _writeSidebar(); + _buffer.write(' '); + _writeMultilineHighlights(line, highlightsByColumn, current: highlight); + _colorize(() => _writeArrow(line, highlight.span.start.column), + color: color); + _buffer.writeln(); + } else if (highlight.span.end.line == line.number) { + var coversWholeLine = highlight.span.end.column == line.text.length; + if (coversWholeLine && highlight.label == null) { + replaceWithNull(highlightsByColumn, highlight); + return; + } + + _writeSidebar(); + _buffer.write(' '); + _writeMultilineHighlights(line, highlightsByColumn, current: highlight); + + _colorize(() { + if (coversWholeLine) { + _buffer.write(glyph.horizontalLine * 3); + } else { + _writeArrow(line, math.max(highlight.span.end.column - 1, 0), + beginning: false); + } + _writeLabel(highlight.label); + }, color: color); + _buffer.writeln(); + replaceWithNull(highlightsByColumn, highlight); + } + } + + /// Underlines the portion of [line] covered by [span] with repeated instances + /// of [character]. + void _writeUnderline(_Line line, SourceSpan span, String character) { + assert(!isMultiline(span)); + assert(line.text.contains(span.text)); + + var startColumn = span.start.column; + var endColumn = span.end.column; + + // Adjust the start and end columns to account for any tabs that were + // converted to spaces. + var tabsBefore = _countTabs(line.text.substring(0, startColumn)); + var tabsInside = _countTabs(line.text.substring(startColumn, endColumn)); + startColumn += tabsBefore * (_spacesPerTab - 1); + endColumn += (tabsBefore + tabsInside) * (_spacesPerTab - 1); + + _buffer.write(" " * startColumn); + _buffer.write(character * math.max(endColumn - startColumn, 1)); + } + + /// Write an arrow pointing to column [column] in [line]. + /// + /// If the arrow points to a tab character, this will point to the beginning + /// of the tab if [beginning] is `true` and the end if it's `false`. + void _writeArrow(_Line line, int column, {bool beginning = true}) { + var tabs = _countTabs(line.text.substring(0, column + (beginning ? 0 : 1))); + _buffer + ..write(glyph.horizontalLine * (1 + column + tabs * (_spacesPerTab - 1))) + ..write("^"); + } + + /// Writes a space followed by [label] if [label] isn't `null`. + void _writeLabel(String label) { + if (label != null) _buffer.write(" $label"); + } + + /// Writes a snippet from the source text, converting hard tab characters into + /// plain indentation. + void _writeText(String text) { + for (var char in text.codeUnits) { + if (char == $tab) { + _buffer.write(' ' * _spacesPerTab); + } else { + _buffer.writeCharCode(char); + } + } + } - var newSpan = _normalizeContext(span); - newSpan = _normalizeNewlines(newSpan); - newSpan = _normalizeTrailingNewline(newSpan); - newSpan = _normalizeEndOfLine(newSpan); + // Writes a sidebar to [buffer] that includes [line] as the line number if + // given and writes [end] at the end (defaults to [glyphs.verticalLine]). + // + // 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}) { + assert(line == null || text == null); + + // Add 1 to line to convert from computer-friendly 0-indexed line numbers to + // human-friendly 1-indexed line numbers. + if (line != null) text = (line + 1).toString(); + _colorize(() { + _buffer.write((text ?? '').padRight(_paddingBeforeSidebar)); + _buffer.write(end ?? glyph.verticalLine); + }, color: colors.blue); + } - return Highlighter._(newSpan, color as String); + /// Returns the number of hard tabs in [text]. + int _countTabs(String text) { + var count = 0; + for (var char in text.codeUnits) { + if (char == $tab) count++; + } + return count; + } + + /// Returns whether [text] contains only space or tab characters. + bool _isOnlyWhitespace(String text) { + for (var char in text.codeUnits) { + if (char != $space && char != $tab) return false; + } + return true; + } + + /// 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}) { + if (_primaryColor != null && color != null) _buffer.write(color); + callback(); + if (_primaryColor != null && color != null) _buffer.write(colors.none); } +} + +/// Information about how to highlight a single section of a source file. +class _Highlight { + /// The section of the source file to highlight. + /// + /// This is normalized to make it easier for [Highlighter] to work with. + final SourceSpanWithContext span; + + /// Whether this is the primary span in the highlight. + /// + /// The primary span is highlighted with a different character and colored + /// differently than non-primary spans. + final bool isPrimary; + + /// The label to include inline when highlighting [span]. + /// + /// This helps distinguish clarify what each highlight means when multiple are + /// used in the same message. + final String label; + + _Highlight(SourceSpan span, {this.label, bool primary = false}) + : span = (() { + var newSpan = _normalizeContext(span); + newSpan = _normalizeNewlines(newSpan); + newSpan = _normalizeTrailingNewline(newSpan); + return _normalizeEndOfLine(newSpan); + })(), + isPrimary = primary; /// Normalizes [span] to ensure that it's a [SourceSpanWithContext] whose /// context actually contains its text at the expected column. @@ -128,11 +582,15 @@ class Highlighter { var end = span.end; if (span.text.endsWith('\n') && _isTextAtEndOfContext(span)) { text = span.text.substring(0, span.text.length - 1); - end = SourceLocation(span.end.offset - 1, - sourceUrl: span.sourceUrl, - line: span.end.line - 1, - column: _lastLineLength(text)); - start = span.start.offset == span.end.offset ? end : span.start; + if (text.isEmpty) { + end = start; + } else { + end = SourceLocation(span.end.offset - 1, + sourceUrl: span.sourceUrl, + line: span.end.line - 1, + column: _lastLineLength(context)); + start = span.start.offset == span.end.offset ? end : span.start; + } } return SourceSpanWithContext(start, end, text, context); } @@ -150,18 +608,21 @@ class Highlighter { SourceLocation(span.end.offset - 1, sourceUrl: span.sourceUrl, line: span.end.line - 1, - column: _lastLineLength(text)), + column: text.length - text.lastIndexOf('\n') - 1), text, - span.context); + // If the context also ends with a newline, it's possible that we don't + // have the full context for that line, so we shouldn't print it at all. + span.context.endsWith("\n") + ? span.context.substring(0, span.context.length - 1) + : span.context); } /// Returns the length of the last line in [text], whether or not it ends in a /// newline. static int _lastLineLength(String text) { - if (text.isEmpty) return 0; - - // The "- 1" here avoids counting the newline itself. - if (text.codeUnitAt(text.length - 1) == $lf) { + if (text.isEmpty) { + return 0; + } else if (text.codeUnitAt(text.length - 1) == $lf) { return text.length == 1 ? 0 : text.length - text.lastIndexOf('\n', text.length - 2) - 1; @@ -177,250 +638,35 @@ class Highlighter { span.length == span.context.length; - Highlighter._(this._span, this._color) - : _multiline = _span.start.line != _span.end.line, - // In a purely mathematical world, floor(log10(n)) would give the number of - // digits in n, but floating point errors render that unreliable in - // practice. - _paddingBeforeSidebar = (_span.end.line + 1).toString().length + 1; - - /// Returns the highlighted span text. - /// - /// This method should only be called once. - String highlight() { - _writeSidebar(end: glyph.downEnd); - _buffer.writeln(); - - // If [_span.context] contains lines prior to the one [_span.text] appears - // on, write those first. - final lineStart = - findLineStart(_span.context, _span.text, _span.start.column); - assert(lineStart != null); // enforced by [_normalizeContext] - - var context = _span.context; - if (lineStart > 0) { - // Take a substring to one character *before* [lineStart] because - // [findLineStart] is guaranteed to return a position immediately after a - // newline. Including that newline would add an extra empty line to the - // end of [lines]. - final lines = context.substring(0, lineStart - 1).split('\n'); - var lineNumber = _span.start.line - lines.length; - for (var line in lines) { - _writeSidebar(line: lineNumber); - _buffer.write(' ' * _paddingAfterSidebar); - _writeText(line); - _buffer.writeln(); - lineNumber++; - } - context = context.substring(lineStart); - } - - final lines = context.split('\n'); - - final lastLineIndex = _span.end.line - _span.start.line; - if (lines.last.isEmpty && lines.length > lastLineIndex + 1) { - // Trim a trailing newline so we don't add an empty line to the end of the - // highlight. - lines.removeLast(); - } - - _writeFirstLine(lines.first); - if (_multiline) { - _writeIntermediateLines(lines.skip(1).take(lastLineIndex - 1)); - _writeLastLine(lines[lastLineIndex]); - } - _writeTrailingLines(lines.skip(lastLineIndex + 1)); - - _writeSidebar(end: glyph.upEnd); - - return _buffer.toString(); - } - - // Writes the first (and possibly only) line highlighted by the span. - void _writeFirstLine(String line) { - _writeSidebar(line: _span.start.line); - - var startColumn = math.min(_span.start.column, line.length); - var endColumn = math.min( - startColumn + _span.end.offset - _span.start.offset, line.length); - final textBefore = line.substring(0, startColumn); - - // If the span covers the entire first line other than initial whitespace, - // don't bother pointing out exactly where it begins. - if (_multiline && _isOnlyWhitespace(textBefore)) { - _buffer.write(' '); - _colorize(() { - _buffer..write(glyph.glyphOrAscii('┌', '/'))..write(' '); - _writeText(line); - }); - _buffer.writeln(); - return; - } - - _buffer.write(' ' * _paddingAfterSidebar); - _writeText(textBefore); - final textInside = line.substring(startColumn, endColumn); - _colorize(() => _writeText(textInside)); - _writeText(line.substring(endColumn)); - _buffer.writeln(); - - // Adjust the start and end column to account for any tabs that were - // converted to spaces. - final tabsBefore = _countTabs(textBefore); - final tabsInside = _countTabs(textInside); - startColumn = startColumn + tabsBefore * (_spacesPerTab - 1); - endColumn = endColumn + (tabsBefore + tabsInside) * (_spacesPerTab - 1); - - // Write the highlight for the first line. This is a series of carets for a - // single-line span, and a pointer to the beginning of a multi-line span. - _writeSidebar(); - if (_multiline) { - _buffer.write(' '); - _colorize(() { - _buffer - ..write(glyph.topLeftCorner) - ..write(glyph.horizontalLine * (startColumn + 1)) - ..write('^'); - }); - } else { - _buffer.write(' ' * (startColumn + 1)); - _colorize( - () => _buffer.write('^' * math.max(endColumn - startColumn, 1))); - } - _buffer.writeln(); - } - - /// Writes the lines between the first and last lines highlighted by the span. - void _writeIntermediateLines(Iterable lines) { - assert(_multiline); - - // +1 because the first line was already written. - var lineNumber = _span.start.line + 1; - for (var line in lines) { - _writeSidebar(line: lineNumber); - - _buffer.write(' '); - _colorize(() { - _buffer..write(glyph.verticalLine)..write(' '); - _writeText(line); - }); - _buffer.writeln(); - - lineNumber++; - } - } - - // Writes the last line highlighted by the span. - void _writeLastLine(String line) { - assert(_multiline); - - _writeSidebar(line: _span.end.line); - - var endColumn = math.min(_span.end.column, line.length); - - // If the span covers the entire last line, don't bother pointing out - // exactly where it ends. - if (_multiline && endColumn == line.length) { - _buffer.write(' '); - _colorize(() { - _buffer..write(glyph.glyphOrAscii('└', '\\'))..write(' '); - _writeText(line); - }); - _buffer.writeln(); - return; - } - - _buffer.write(' '); - final textInside = line.substring(0, endColumn); - _colorize(() { - _buffer..write(glyph.verticalLine)..write(' '); - _writeText(textInside); - }); - _writeText(line.substring(endColumn)); - _buffer.writeln(); - - // Adjust the end column to account for any tabs that were converted to - // spaces. - final tabsInside = _countTabs(textInside); - endColumn = endColumn + tabsInside * (_spacesPerTab - 1); - - // Write the highlight for the final line, which is an arrow pointing to the - // end of the span. - _writeSidebar(); - _buffer.write(' '); - _colorize(() { - _buffer - ..write(glyph.bottomLeftCorner) - ..write(glyph.horizontalLine * endColumn) - ..write('^'); - }); - _buffer.writeln(); + @override + String toString() { + var buffer = StringBuffer(); + if (isPrimary) buffer.write("primary "); + buffer.write("${span.start.line}:${span.start.column}-" + "${span.end.line}:${span.end.column}"); + if (label != null) buffer.write(" ($label)"); + return buffer.toString(); } +} - /// Writes lines that appear in the context string but come after the span. - void _writeTrailingLines(Iterable lines) { - // +1 because this comes after any lines covered by the span. - var lineNumber = _span.end.line + 1; - for (var line in lines) { - _writeSidebar(line: lineNumber); - _buffer.write(' ' * _paddingAfterSidebar); - _writeText(line); - _buffer.writeln(); - lineNumber++; - } - } +/// A single line of the source file being highlighted. +class _Line { + /// The text of the line, not including the trailing newline. + final String text; - /// Writes a snippet from the source text, converting hard tab characters into - /// plain indentation. - void _writeText(String text) { - for (var char in text.codeUnits) { - if (char == $tab) { - _buffer.write(' ' * _spacesPerTab); - } else { - _buffer.writeCharCode(char); - } - } - } + /// The 0-based line number in the source file. + final int number; - // Writes a sidebar to [buffer] that includes [line] as the line number if - // given and writes [end] at the end (defaults to [glyphs.verticalLine]). - void _writeSidebar({int line, String end}) { - _colorize(() { - if (line != null) { - // Add 1 to line to convert from computer-friendly 0-indexed line - // numbers to human-friendly 1-indexed line numbers. - _buffer.write((line + 1).toString().padRight(_paddingBeforeSidebar)); - } else { - _buffer.write(' ' * _paddingBeforeSidebar); - } - _buffer.write(end ?? glyph.verticalLine); - }, color: colors.blue); - } + /// The URL of the source file in which this line appears. + final Uri url; - /// Returns the number of hard tabs in [text]. - int _countTabs(String text) { - var count = 0; - for (var char in text.codeUnits) { - if (char == $tab) count++; - } - return count; - } + /// All highlights that cover any portion of this line, in source span order. + /// + /// This is populated after the initial line is created. + final highlights = <_Highlight>[]; - /// Returns whether [text] contains only space or tab characters. - bool _isOnlyWhitespace(String text) { - for (var char in text.codeUnits) { - if (char != $space && char != $tab) return false; - } - return true; - } + _Line(this.text, this.number, this.url); - /// Colors all text written to [_buffer] during [callback], if colorization is - /// enabled. - /// - /// If [color] is passed, it's used as the color; otherwise, [_color] is used. - void _colorize(void Function() callback, {String color}) { - if (_color != null) _buffer.write(color ?? _color); - callback(); - if (_color != null) _buffer.write(colors.none); - } + @override + String toString() => '$number: "$text" (${highlights.join(', ')})'; } diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index f329e372d..51e81ab80 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -2,8 +2,11 @@ // 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:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; +import 'file.dart'; +import 'highlighter.dart'; import 'location.dart'; import 'span_mixin.dart'; import 'span_with_context.dart'; @@ -108,3 +111,72 @@ class SourceSpanBase extends SourceSpanMixin { } } } + +// TODO(#52): Move these to instance methods in the next breaking release. +/// Extension methods on the base [SourceSpan] API. +extension SourceSpanExtension on SourceSpan { + /// Like [SourceSpan.message], but also highlights [secondarySpans] to provide + /// the user with additional context. + /// + /// Each span takes a label ([label] for this span, and the values of the + /// [secondarySpans] map for the secondary spans) that's used to indicate to + /// the user what that particular span represents. + /// + /// If [color] is `true`, [ANSI terminal color escapes][] are used to color + /// the resulting string. By default this span is colored red and the + /// secondary spans are colored blue, but that can be customized by passing + /// ANSI escape strings to [primaryColor] or [secondaryColor]. + /// + /// [ANSI terminal color escapes]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors + /// + /// Each span in [secondarySpans] must refer to the same document as this + /// span. Throws an [ArgumentError] if any secondary span has a different + /// source URL than this span. + /// + /// Note that while this will work with plain [SourceSpan]s, it will produce + /// much more useful output with [SourceSpanWithContext]s (including + /// [FileSpan]s). + String messageMultiple( + String message, String label, Map secondarySpans, + {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)}'); + buffer + ..writeln(': $message') + ..write(highlightMultiple(label, secondarySpans, + color: color, + primaryColor: primaryColor, + secondaryColor: secondaryColor)); + return buffer.toString(); + } + + /// Like [SourceSpan.highlight], but also highlights [secondarySpans] to + /// provide the user with additional context. + /// + /// Each span takes a label ([label] for this span, and the values of the + /// [secondarySpans] map for the secondary spans) that's used to indicate to + /// the user what that particular span represents. + /// + /// If [color] is `true`, [ANSI terminal color escapes][] are used to color + /// the resulting string. By default this span is colored red and the + /// secondary spans are colored blue, but that can be customized by passing + /// ANSI escape strings to [primaryColor] or [secondaryColor]. + /// + /// [ANSI terminal color escapes]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors + /// + /// Each span in [secondarySpans] must refer to the same document as this + /// span. Throws an [ArgumentError] if any secondary span has a different + /// source URL than this span. + /// + /// Note that while this will work with plain [SourceSpan]s, it will produce + /// much more useful output with [SourceSpanWithContext]s (including + /// [FileSpan]s). + String highlightMultiple(String label, Map secondarySpans, + {bool color = false, String primaryColor, String secondaryColor}) => + Highlighter.multiple(this, label, secondarySpans, + color: color, + primaryColor: primaryColor, + secondaryColor: secondaryColor) + .highlight(); +} diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index 02c897452..5b33d06ec 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -37,7 +37,6 @@ class SourceSpanException implements Exception { /// A [SourceSpanException] that's also a [FormatException]. class SourceSpanFormatException extends SourceSpanException implements FormatException { - // This is a getter so that subclasses can override it. @override final dynamic source; @@ -47,3 +46,71 @@ class SourceSpanFormatException extends SourceSpanException SourceSpanFormatException(String message, SourceSpan span, [this.source]) : super(message, span); } + +/// A [SourceSpanException] that also highlights some secondary spans to provide +/// the user with extra context. +/// +/// Each span has a label ([primaryLabel] for the primary, and the values of the +/// [secondarySpans] map for the secondary spans) that's used to indicate to the +/// user what that particular span represents. +class MultiSourceSpanException extends SourceSpanException { + /// A label to attach to [span] that provides additional information and helps + /// distinguish it from [secondarySpans]. + final String primaryLabel; + + /// A map whose keys are secondary spans that should be highlighted. + /// + /// Each span's value is a label to attach to that span that provides + /// additional information and helps distinguish it from [secondarySpans]. + final Map secondarySpans; + + MultiSourceSpanException(String message, SourceSpan span, this.primaryLabel, + Map secondarySpans) + : secondarySpans = Map.unmodifiable(secondarySpans), + super(message, span); + + /// Returns a string representation of `this`. + /// + /// [color] may either be a [String], a [bool], or `null`. If it's a string, + /// it indicates an ANSI terminal color escape that should be used to + /// highlight the primary span's text. If it's `true`, it indicates that the + /// text should be highlighted using the default color. If it's `false` or + /// `null`, it indicates that the text shouldn't be highlighted. + /// + /// If [color] is `true` or a string, [secondaryColor] is used to highlight + /// [secondarySpans]. + @override + String toString({color, String secondaryColor}) { + if (span == null) return message; + + var useColor = false; + String primaryColor; + if (color is String) { + useColor = true; + primaryColor = color; + } else if (color == true) { + useColor = true; + } + + return "Error on " + + span.messageMultiple(message, primaryLabel, secondarySpans, + color: useColor, + primaryColor: primaryColor, + secondaryColor: secondaryColor); + } +} + +/// A [MultiSourceSpanException] that's also a [FormatException]. +class MultiSourceSpanFormatException extends MultiSourceSpanException + implements FormatException { + @override + final dynamic source; + + @override + int get offset => span?.start?.offset; + + MultiSourceSpanFormatException(String message, SourceSpan span, + String primaryLabel, Map secondarySpans, + [this.source]) + : super(message, span, primaryLabel, secondarySpans); +} diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 63ff01cb8..12b15b382 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -2,6 +2,8 @@ // 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 'span.dart'; + /// Returns the minimum of [obj1] and [obj2] according to /// [Comparable.compareTo]. T min(T obj1, T obj2) => @@ -12,6 +14,42 @@ T min(T obj1, T obj2) => T max(T obj1, T obj2) => obj1.compareTo(obj2) > 0 ? obj1 : obj2; +/// Returns whether all elements of [iter] are the same value, according to +/// `==`. +/// +/// Assumes [iter] doesn't contain any `null` values. +bool isAllTheSame(Iterable iter) { + Object lastValue; + for (var value in iter) { + if (lastValue == null) { + lastValue = value; + } else if (value != lastValue) { + return false; + } + } + return true; +} + +/// Returns whether [span] covers multiple lines. +bool isMultiline(SourceSpan span) => span.start.line != span.end.line; + +/// Sets the first `null` element of [list] to [element]. +void replaceFirstNull(List list, E element) { + var 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(List list, E element) { + var index = list.indexOf(element); + if (index < 0) { + throw ArgumentError("$list contains no elements matching $element."); + } + + list[index] = null; +} + /// Returns the number of instances of [codeUnit] in [string]. int countCodeUnits(String string, int codeUnit) { var count = 0; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 71e10f60a..2054423d5 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,15 +1,17 @@ name: source_span -version: 1.5.6-dev +version: 1.6.0 description: A library for identifying source spans and locations. author: Dart Team homepage: https://github.com/dart-lang/source_span environment: - sdk: '>=2.1.0 <3.0.0' + sdk: '>=2.6.0 <3.0.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 diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 9d95b21ef..6313108e1 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -140,6 +140,14 @@ zip zap zop '""")); }); + test('highlights text including a trailing newline', () { + expect(file.span(8, 12).highlight(), equals(""" + , +1 | foo bar baz + | ^^^ + '""")); + }); + test('highlights a single empty line', () { expect( SourceFile.fromString('foo\n\nbar').span(4, 5).highlight(), equals(""" @@ -149,6 +157,14 @@ zip zap zop '""")); }); + test('highlights a trailing newline', () { + expect(file.span(11, 12).highlight(), equals(""" + , +1 | foo bar baz + | ^ + '""")); + }); + group('with a multiline span', () { test('highlights the middle of the first and last lines', () { expect(file.span(4, 34).highlight(), equals(""" @@ -383,6 +399,21 @@ whiz bang boom '""")); }); + test('at the beginning of the first highlighted line', () { + final span = SourceFile.fromString(''' +foo bar\tbaz +whiz bang boom +''').span(7, 21); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ,--------^ +2 | | whiz bang boom + | '---------^ + '""")); + }); + test('within a middle highlighted line', () { final span = SourceFile.fromString(''' foo bar baz @@ -415,6 +446,21 @@ whiz\tbang boom '""")); }); + test('at the end of the last highlighted line', () { + final span = SourceFile.fromString(''' +foo bar baz +whiz\tbang boom +''').span(4, 17); + + expect(span.highlight(), equals(""" + , +1 | foo bar baz + | ,-----^ +2 | | whiz bang boom + | '--------^ + '""")); + }); + test('after the highlighted section', () { final span = SourceFile.fromString(''' foo bar baz @@ -498,7 +544,7 @@ whiz bang\tboom expect(file.span(4, 7).highlight(color: true), equals(''' ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} foo ${colors.red}bar${colors.none} baz -${colors.blue} |${colors.none} ${colors.red}^^^${colors.none} +${colors.blue} |${colors.none} ${colors.red} ^^^${colors.none} ${colors.blue} '${colors.none}''')); }); @@ -506,7 +552,7 @@ ${colors.blue} '${colors.none}''')); expect(file.span(4, 7).highlight(color: colors.yellow), equals(''' ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} foo ${colors.yellow}bar${colors.none} baz -${colors.blue} |${colors.none} ${colors.yellow}^^^${colors.none} +${colors.blue} |${colors.none} ${colors.yellow} ^^^${colors.none} ${colors.blue} '${colors.none}''')); }); @@ -514,19 +560,19 @@ ${colors.blue} '${colors.none}''')); expect(file.span(4, 34).highlight(color: true), equals(''' ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} foo ${colors.red}bar baz${colors.none} -${colors.blue} |${colors.none} ${colors.red},-----^${colors.none} -${colors.blue}2 |${colors.none} ${colors.red}| whiz bang boom${colors.none} -${colors.blue}3 |${colors.none} ${colors.red}| zip zap${colors.none} zop -${colors.blue} |${colors.none} ${colors.red}'-------^${colors.none} +${colors.blue} |${colors.none} ${colors.red},${colors.none}${colors.red}-----^${colors.none} +${colors.blue}2 |${colors.none} ${colors.red}|${colors.none} ${colors.red}whiz bang boom${colors.none} +${colors.blue}3 |${colors.none} ${colors.red}|${colors.none} ${colors.red}zip zap${colors.none} zop +${colors.blue} |${colors.none} ${colors.red}'${colors.none}${colors.red}-------^${colors.none} ${colors.blue} '${colors.none}''')); }); test('colorizes a multiline span that highlights full lines', () { expect(file.span(0, 39).highlight(color: true), equals(''' ${colors.blue} ,${colors.none} -${colors.blue}1 |${colors.none} ${colors.red}/ foo bar baz${colors.none} -${colors.blue}2 |${colors.none} ${colors.red}| whiz bang boom${colors.none} -${colors.blue}3 |${colors.none} ${colors.red}\\ zip zap zop${colors.none} +${colors.blue}1 |${colors.none} ${colors.red}/${colors.none} ${colors.red}foo bar baz${colors.none} +${colors.blue}2 |${colors.none} ${colors.red}|${colors.none} ${colors.red}whiz bang boom${colors.none} +${colors.blue}3 |${colors.none} ${colors.red}\\${colors.none} ${colors.red}zip zap zop${colors.none} ${colors.blue} '${colors.none}''')); }); }); diff --git a/pkgs/source_span/test/multiple_highlight_test.dart b/pkgs/source_span/test/multiple_highlight_test.dart new file mode 100644 index 000000000..f0cceedef --- /dev/null +++ b/pkgs/source_span/test/multiple_highlight_test.dart @@ -0,0 +1,281 @@ +// Copyright (c) 2019, 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:source_span/source_span.dart'; +import 'package:term_glyph/term_glyph.dart' as glyph; +import 'package:test/test.dart'; + +void main() { + bool oldAscii; + setUpAll(() { + oldAscii = glyph.ascii; + glyph.ascii = true; + }); + + tearDownAll(() { + glyph.ascii = oldAscii; + }); + + SourceFile file; + setUp(() { + file = SourceFile.fromString(''' +foo bar baz +whiz bang boom +zip zap zop +fwee fwoo fwip +argle bargle boo +gibble bibble bop +''', url: "file1.txt"); + }); + + test("highlights spans on separate lines", () { + expect( + file.span(17, 21).highlightMultiple( + "one", {file.span(31, 34): "two", file.span(4, 7): "three"}), + equals(""" + , +1 | foo bar baz + | === three +2 | whiz bang boom + | ^^^^ one +3 | zip zap zop + | === two + '""")); + }); + + test("highlights spans on the same line", () { + expect( + file.span(17, 21).highlightMultiple( + "one", {file.span(22, 26): "two", file.span(12, 16): "three"}), + equals(""" + , +2 | whiz bang boom + | ^^^^ one + | ==== three + | ==== two + '""")); + }); + + test("highlights overlapping spans on the same line", () { + expect( + file.span(17, 21).highlightMultiple( + "one", {file.span(20, 26): "two", file.span(12, 18): "three"}), + equals(""" + , +2 | whiz bang boom + | ^^^^ one + | ====== three + | ====== two + '""")); + }); + + test("highlights multiple multiline spans", () { + expect( + file.span(27, 54).highlightMultiple( + "one", {file.span(54, 89): "two", file.span(0, 27): "three"}), + equals(""" + , +1 | / foo bar baz +2 | | whiz bang boom + | '--- three +3 | / zip zap zop +4 | | fwee fwoo fwip + | '--- one +5 | / argle bargle boo +6 | | gibble bibble bop + | '--- two + '""")); + }); + + test("highlights multiple overlapping multiline spans", () { + expect( + file.span(12, 70).highlightMultiple( + "one", {file.span(54, 89): "two", file.span(0, 27): "three"}), + equals(""" + , +1 | /- foo bar baz +2 | |/ whiz bang boom + | '+--- three +3 | | zip zap zop +4 | | fwee fwoo fwip +5 | /+ argle bargle boo + | |'--- one +6 | | gibble bibble bop + | '---- two + '""")); + }); + + test("highlights many layers of overlaps", () { + expect( + file.span(0, 54).highlightMultiple("one", { + file.span(12, 77): "two", + file.span(27, 84): "three", + file.span(39, 88): "four" + }), + equals(""" + , +1 | /--- foo bar baz +2 | |/-- whiz bang boom +3 | ||/- zip zap zop +4 | |||/ fwee fwoo fwip + | '+++--- one +5 | ||| argle bargle boo +6 | ||| gibble bibble bop + | '++------^ two + | '+-------------^ three + | '--- four + '""")); + }); + + group("highlights a multiline span that's a subset", () { + test("with no first or last line overlap", () { + expect( + file + .span(27, 53) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | /- whiz bang boom +3 | |/ zip zap zop +4 | || fwee fwoo fwip + | |'--- inner +5 | | argle bargle boo + | '---- outer + '""")); + }); + + test("overlapping the whole first line", () { + expect( + file + .span(12, 53) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | // whiz bang boom +3 | || zip zap zop +4 | || fwee fwoo fwip + | |'--- inner +5 | | argle bargle boo + | '---- outer + '""")); + }); + + test("overlapping part of first line", () { + expect( + file + .span(17, 53) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | /- whiz bang boom + | |,------^ +3 | || zip zap zop +4 | || fwee fwoo fwip + | |'--- inner +5 | | argle bargle boo + | '---- outer + '""")); + }); + + test("overlapping the whole last line", () { + expect( + file + .span(27, 70) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | /- whiz bang boom +3 | |/ zip zap zop +4 | || fwee fwoo fwip +5 | || argle bargle boo + | |'--- inner + | '---- outer + '""")); + }); + + test("overlapping part of the last line", () { + expect( + file + .span(27, 66) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | /- whiz bang boom +3 | |/ zip zap zop +4 | || fwee fwoo fwip +5 | || argle bargle boo + | |'------------^ inner + | '---- outer + '""")); + }); + }); + + group("a single-line span in a multiline span", () { + test("on the first line", () { + expect( + file + .span(17, 21) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | / whiz bang boom + | | ^^^^ inner +3 | | zip zap zop +4 | | fwee fwoo fwip +5 | | argle bargle boo + | '--- outer + '""")); + }); + + test("in the middle", () { + expect( + file + .span(31, 34) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | / whiz bang boom +3 | | zip zap zop + | | ^^^ inner +4 | | fwee fwoo fwip +5 | | argle bargle boo + | '--- outer + '""")); + }); + + test("on the last line", () { + expect( + file + .span(60, 66) + .highlightMultiple("inner", {file.span(12, 70): "outer"}), + equals(""" + , +2 | / whiz bang boom +3 | | zip zap zop +4 | | fwee fwoo fwip +5 | | argle bargle boo + | | ^^^^^^ inner + | '--- outer + '""")); + }); + }); + + test("highlights multiple files with their URLs", () { + var file2 = SourceFile.fromString(''' +quibble bibble boop +''', url: "file2.txt"); + + expect( + file.span(31, 34).highlightMultiple("one", {file2.span(8, 14): "two"}), + equals(""" + ,--> file1.txt +3 | zip zap zop + | ^^^ one + ' + ,--> file2.txt +1 | quibble bibble boop + | ====== two + '""")); + }); +} diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 1ac9d35ef..f44b02fdd 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -246,7 +246,7 @@ ${colors.blue} '${colors.none}""")); line 1, column 6 of foo.dart: oh no ${colors.blue} ,${colors.none} ${colors.blue}1 |${colors.none} -----${colors.yellow}foo bar${colors.none}----- -${colors.blue} |${colors.none} ${colors.yellow}^^^^^^^${colors.none} +${colors.blue} |${colors.none} ${colors.yellow} ^^^^^^^${colors.none} ${colors.blue} '${colors.none}""")); }); }); From 303dd9fa615a762b7f5145c817d6508a3f66ae55 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 22 Jan 2020 10:58:08 -0800 Subject: [PATCH 323/657] Fix a number of doc comments Enable corresponding lint --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/analysis_options.yaml | 4 ++++ pkgs/source_maps/lib/builder.dart | 2 +- pkgs/source_maps/lib/parser.dart | 11 ++++++----- pkgs/source_maps/lib/printer.dart | 2 +- pkgs/source_maps/lib/refactor.dart | 6 +++--- pkgs/source_maps/lib/source_maps.dart | 22 +++++----------------- pkgs/source_maps/lib/src/vlq.dart | 3 +-- 8 files changed, 25 insertions(+), 29 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index af62d9460..73bbed05e 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.9-dev + +* Fix a number of document comment issues. + ## 0.10.8 * Preserve source-map extensions in `SingleMapping`. Extensions are keys in the diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml index 108d1058a..4f9dfb038 100644 --- a/pkgs/source_maps/analysis_options.yaml +++ b/pkgs/source_maps/analysis_options.yaml @@ -1 +1,5 @@ include: package:pedantic/analysis_options.yaml + +linter: + rules: + - comment_references diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 5574f0df0..e6b8d82ee 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -31,7 +31,7 @@ class SourceMapBuilder { /// /// If [isIdentifier] is true or if [target] is a [SourceMapSpan] with /// `isIdentifier` set to true, this entry is considered to represent an - /// identifier whose value will be stored in the source map. [isIdenfier] + /// identifier whose value will be stored in the source map. [isIdentifier] /// takes precedence over [target]'s `isIdentifier` value. void addSpan(SourceSpan source, SourceSpan target, {bool isIdentifier}) { isIdentifier ??= source is SourceMapSpan ? source.isIdentifier : false; diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index c15ff2a11..124ef6dc4 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -264,9 +264,10 @@ class SingleMapping extends Mapping { /// The [SourceFile]s to which the entries in [lines] refer. /// /// This is in the same order as [urls]. If this was constructed using - /// [fromEntries], this contains files from any [FileLocation]s used to build - /// the mapping. If it was parsed from JSON, it contains files for any sources - /// whose contents were provided via the `"sourcesContent"` field. + /// [SingleMapping.fromEntries], this contains files from any [FileLocation]s + /// used to build the mapping. If it was parsed from JSON, it contains files + /// for any sources whose contents were provided via the `"sourcesContent"` + /// field. /// /// Files whose contents aren't available are `null`. final List files; @@ -425,8 +426,8 @@ class SingleMapping extends Mapping { /// Encodes the Mapping mappings as a json map. /// - /// If [sourcesContent] is `true`, this includes the source file contents from - /// [files] in the map if possible. + /// If [includeSourceContents] is `true`, this includes the source file + /// contents from [files] in the map if possible. Map toJson({bool includeSourceContents = false}) { var buff = StringBuffer(); var line = 0; diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 24eec6429..d79d2cb03 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -160,7 +160,7 @@ class NestedPrinter implements NestedItem { /// separately and will not include any the indentation set here. /// /// The [location] and [span] parameters indicate the corresponding source map - /// location of [object] in the original input. Only one, [location] or + /// location of [line] in the original input. Only one, [location] or /// [span], should be provided at a time. void addLine(String line, {SourceLocation location, SourceSpan span}) { if (location != null || span != null) { diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 32daf326c..5e117e8ac 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -38,9 +38,9 @@ class TextEditTransaction { file != null ? file.location(offset) : null; /// Applies all pending [edit]s and returns a [NestedPrinter] containing the - /// rewritten string and source map information. [filename] is given to the - /// underlying printer to indicate the name of the generated file that will - /// contains the source map information. + /// rewritten string and source map information. [file]`.location` is given to + /// the underlying printer to indicate the name of the generated file that + /// will contains the source map information. /// /// Throws [UnsupportedError] if the edits were overlapping. If no edits were /// made, the printer simply contains the original string. diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index e77ac5967..0d171788b 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -18,25 +18,13 @@ /// object. For example: /// var mapping = parse(json); /// mapping.spanFor(outputSpan1.line, outputSpan1.column) -/// -/// ## Getting the code ## -/// -/// This library is distributed as a [pub][] package. To install this package, -/// add the following to your `pubspec.yaml` file: -/// -/// dependencies: -/// source_maps: any -/// -/// After you run `pub install`, you should be able to access this library by -/// importing `package:source_maps/source_maps.dart`. -/// -/// For more information, see the -/// [source_maps package on pub.dartlang.org][pkg]. -/// -/// [pub]: http://pub.dartlang.org -/// [pkg]: http://pub.dartlang.org/packages/source_maps library source_maps; +import 'package:source_span/source_span.dart'; + +import 'parser.dart'; +import 'builder.dart'; + export 'builder.dart'; export 'parser.dart'; export 'printer.dart'; diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index de3ab27e9..d4e29a1c3 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -9,8 +9,7 @@ /// encodes a 5-bit value (0-31) and a continuation bit. Signed values can be /// represented by using the least significant bit of the value as the sign bit. /// -/// For more details see the source map [version 3 documentation][spec]. -/// [spec]: https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit +/// For more details see the source map [version 3 documentation](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?usp=sharing). library source_maps.src.vlq; import 'dart:math'; From 27129d3a37067071492a3d0bb08f026645d38a30 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 22 Jan 2020 12:10:17 -0800 Subject: [PATCH 324/657] Drop author from pubspec (dart-lang/source_maps#39) --- pkgs/source_maps/pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index cf7976605..3c42700b8 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -2,7 +2,6 @@ name: source_maps version: 0.10.9-dev description: Library to programmatically manipulate source map files. -author: Dart Team homepage: http://github.com/dart-lang/source_maps environment: From 4ce9a76ad19d034d8ea5a75ad2f0f95d5c2bf4d9 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 22 Jan 2020 15:09:31 -0800 Subject: [PATCH 325/657] Re-enable lint disabled in the last PR (dart-lang/source_span#53) Some of these were lints that had been enabled while the review was ongoing, some were lints that had been around a while but ignored. Drop author field from pubspec --- pkgs/source_span/CHANGELOG.md | 2 + pkgs/source_span/analysis_options.yaml | 12 +-- pkgs/source_span/lib/src/highlighter.dart | 79 ++++++++++--------- pkgs/source_span/lib/src/span_exception.dart | 11 +-- pkgs/source_span/lib/src/utils.dart | 8 +- pkgs/source_span/pubspec.yaml | 3 +- .../test/multiple_highlight_test.dart | 74 ++++++++--------- 7 files changed, 94 insertions(+), 95 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 014cc4c63..c24535b24 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.6.1-dev + # 1.6.0 * Add support for highlighting multiple source spans at once, providing more diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index 0ce791169..ab5a4f209 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -2,9 +2,6 @@ include: package:pedantic/analysis_options.yaml analyzer: strong-mode: implicit-casts: false - errors: - # TODO(natebosch): fix and re-enable. - prefer_single_quotes: ignore linter: rules: - always_declare_return_types @@ -29,8 +26,7 @@ linter: - await_only_futures - camel_case_types - cancel_subscriptions - # TODO(natebosch): fix and re-enable. - #- cascade_invocations + - cascade_invocations - comment_references - constant_identifier_names - control_flow_in_finally @@ -63,12 +59,10 @@ linter: - prefer_contains - prefer_equal_for_default_values - prefer_final_fields - # TODO(natebosch): fix and re-enable. - #- prefer_final_locals + - prefer_final_locals - prefer_generic_function_type_aliases - prefer_initializing_formals - # TODO(natebosch): fix and re-enable. - #- prefer_interpolation_to_compose_strings + - prefer_interpolation_to_compose_strings - prefer_is_empty - prefer_is_not_empty - prefer_null_aware_operators diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index feb5594d5..cef6f79dd 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -114,8 +114,8 @@ class Highlighter { /// file that aren't adjacent in the original file. static bool _contiguous(List<_Line> lines) { for (var i = 0; i < lines.length - 1; i++) { - var thisLine = lines[i]; - var nextLine = lines[i + 1]; + final thisLine = lines[i]; + final nextLine = lines[i + 1]; if (thisLine.number + 1 != nextLine.number && thisLine.url == nextLine.url) { return false; @@ -127,7 +127,7 @@ class Highlighter { /// 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) { - var highlightsByUrl = + final highlightsByUrl = groupBy(highlights, (highlight) => highlight.span.sourceUrl); for (var list in highlightsByUrl.values) { list.sort((highlight1, highlight2) => @@ -137,19 +137,19 @@ class Highlighter { return highlightsByUrl.values.expand((highlightsForFile) { // First, create a list of all the lines in the current file that we have // context for along with their line numbers. - var lines = <_Line>[]; + final lines = <_Line>[]; for (var highlight in highlightsForFile) { - var context = highlight.span.context; + final context = highlight.span.context; // If [highlight.span.context] contains lines prior to the one // [highlight.span.text] appears on, write those first. - var lineStart = findLineStart( + final lineStart = findLineStart( context, highlight.span.text, highlight.span.start.column); assert(lineStart != null); // enforced by [_normalizeContext] - var linesBeforeSpan = + final linesBeforeSpan = '\n'.allMatches(context.substring(0, lineStart)).length; - var url = highlight.span.sourceUrl; + final url = highlight.span.sourceUrl; var lineNumber = highlight.span.start.line - linesBeforeSpan; for (var line in context.split('\n')) { // Only add a line if it hasn't already been added for a previous span. @@ -161,14 +161,14 @@ class Highlighter { } // Next, associate each line with each highlights that covers it. - var activeHighlights = <_Highlight>[]; + final activeHighlights = <_Highlight>[]; var highlightIndex = 0; for (var line in lines) { activeHighlights.removeWhere((highlight) => highlight.span.sourceUrl != line.url || highlight.span.end.line < line.number); - var oldHighlightLength = activeHighlights.length; + final oldHighlightLength = activeHighlights.length; for (var highlight in highlightsForFile.skip(highlightIndex)) { if (highlight.span.start.line > line.number) break; if (highlight.span.sourceUrl != line.url) break; @@ -192,12 +192,12 @@ class Highlighter { // 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. - var highlightsByColumn = List<_Highlight>(_maxMultilineSpans); + final highlightsByColumn = List<_Highlight>(_maxMultilineSpans); for (var i = 0; i < _lines.length; i++) { - var line = _lines[i]; + final line = _lines[i]; if (i > 0) { - var lastLine = _lines[i - 1]; + final lastLine = _lines[i - 1]; if (lastLine.url != line.url) { _writeSidebar(end: glyph.upEnd); _buffer.writeln(); @@ -226,7 +226,7 @@ class Highlighter { _writeMultilineHighlights(line, highlightsByColumn); if (highlightsByColumn.isNotEmpty) _buffer.write(' '); - var primary = line.highlights + final primary = line.highlights .firstWhere((highlight) => highlight.isPrimary, orElse: () => null); if (primary != null) { _writeHighlightedText( @@ -263,9 +263,9 @@ class Highlighter { _writeSidebar(end: glyph.downEnd); } else { _writeSidebar(end: glyph.topLeftCorner); - _colorize(() => _buffer.write("${glyph.horizontalLine * 2}>"), + _colorize(() => _buffer.write('${glyph.horizontalLine * 2}>'), color: colors.blue); - _buffer.write(" ${p.prettyUri(url)}"); + _buffer.write(' ${p.prettyUri(url)}'); } _buffer.writeln(); } @@ -284,13 +284,13 @@ class Highlighter { var openedOnThisLine = false; String openedOnThisLineColor; - var currentColor = current == null + final currentColor = current == null ? null : current.isPrimary ? _primaryColor : _secondaryColor; var foundCurrent = false; for (var highlight in highlightsByColumn) { - var startLine = highlight?.span?.start?.line; - var 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); @@ -312,7 +312,7 @@ class Highlighter { } } else { _colorize(() { - var vertical = openedOnThisLine ? glyph.cross : glyph.verticalLine; + final vertical = openedOnThisLine ? glyph.cross : glyph.verticalLine; if (current != null) { _buffer.write(vertical); } else if (startLine == line.number) { @@ -354,7 +354,7 @@ class Highlighter { /// This may either add or remove [highlight] from [highlightsByColumn]. void _writeIndicator( _Line line, _Highlight highlight, List<_Highlight> highlightsByColumn) { - var color = highlight.isPrimary ? _primaryColor : _secondaryColor; + final color = highlight.isPrimary ? _primaryColor : _secondaryColor; if (!isMultiline(highlight.span)) { _writeSidebar(); _buffer.write(' '); @@ -363,7 +363,7 @@ class Highlighter { _colorize(() { _writeUnderline(line, highlight.span, - highlight.isPrimary ? "^" : glyph.horizontalLineBold); + highlight.isPrimary ? '^' : glyph.horizontalLineBold); _writeLabel(highlight.label); }, color: color); _buffer.writeln(); @@ -378,7 +378,7 @@ class Highlighter { color: color); _buffer.writeln(); } else if (highlight.span.end.line == line.number) { - var coversWholeLine = highlight.span.end.column == line.text.length; + final coversWholeLine = highlight.span.end.column == line.text.length; if (coversWholeLine && highlight.label == null) { replaceWithNull(highlightsByColumn, highlight); return; @@ -413,13 +413,14 @@ class Highlighter { // Adjust the start and end columns to account for any tabs that were // converted to spaces. - var tabsBefore = _countTabs(line.text.substring(0, startColumn)); - var tabsInside = _countTabs(line.text.substring(startColumn, endColumn)); + final tabsBefore = _countTabs(line.text.substring(0, startColumn)); + final tabsInside = _countTabs(line.text.substring(startColumn, endColumn)); startColumn += tabsBefore * (_spacesPerTab - 1); endColumn += (tabsBefore + tabsInside) * (_spacesPerTab - 1); - _buffer.write(" " * startColumn); - _buffer.write(character * math.max(endColumn - startColumn, 1)); + _buffer + ..write(' ' * startColumn) + ..write(character * math.max(endColumn - startColumn, 1)); } /// Write an arrow pointing to column [column] in [line]. @@ -427,15 +428,16 @@ class Highlighter { /// If the arrow points to a tab character, this will point to the beginning /// of the tab if [beginning] is `true` and the end if it's `false`. void _writeArrow(_Line line, int column, {bool beginning = true}) { - var tabs = _countTabs(line.text.substring(0, column + (beginning ? 0 : 1))); + final tabs = + _countTabs(line.text.substring(0, column + (beginning ? 0 : 1))); _buffer ..write(glyph.horizontalLine * (1 + column + tabs * (_spacesPerTab - 1))) - ..write("^"); + ..write('^'); } /// Writes a space followed by [label] if [label] isn't `null`. void _writeLabel(String label) { - if (label != null) _buffer.write(" $label"); + if (label != null) _buffer.write(' $label'); } /// Writes a snippet from the source text, converting hard tab characters into @@ -462,8 +464,9 @@ class Highlighter { // human-friendly 1-indexed line numbers. if (line != null) text = (line + 1).toString(); _colorize(() { - _buffer.write((text ?? '').padRight(_paddingBeforeSidebar)); - _buffer.write(end ?? glyph.verticalLine); + _buffer + ..write((text ?? '').padRight(_paddingBeforeSidebar)) + ..write(end ?? glyph.verticalLine); }, color: colors.blue); } @@ -612,7 +615,7 @@ class _Highlight { text, // If the context also ends with a newline, it's possible that we don't // have the full context for that line, so we shouldn't print it at all. - span.context.endsWith("\n") + span.context.endsWith('\n') ? span.context.substring(0, span.context.length - 1) : span.context); } @@ -640,11 +643,11 @@ class _Highlight { @override String toString() { - var buffer = StringBuffer(); - if (isPrimary) buffer.write("primary "); - buffer.write("${span.start.line}:${span.start.column}-" - "${span.end.line}:${span.end.column}"); - if (label != null) buffer.write(" ($label)"); + final buffer = StringBuffer(); + if (isPrimary) buffer.write('primary '); + buffer.write('${span.start.line}:${span.start.column}-' + '${span.end.line}:${span.end.column}'); + if (label != null) buffer.write(' ($label)'); return buffer.toString(); } } diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index 5b33d06ec..32aaa4eae 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -92,11 +92,12 @@ class MultiSourceSpanException extends SourceSpanException { useColor = true; } - return "Error on " + - span.messageMultiple(message, primaryLabel, secondarySpans, - color: useColor, - primaryColor: primaryColor, - secondaryColor: secondaryColor); + final formatted = span.messageMultiple( + message, primaryLabel, secondarySpans, + color: useColor, + primaryColor: primaryColor, + secondaryColor: secondaryColor); + return 'Error on $formatted'; } } diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 12b15b382..5cb5e90e7 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -35,16 +35,16 @@ bool isMultiline(SourceSpan span) => span.start.line != span.end.line; /// Sets the first `null` element of [list] to [element]. void replaceFirstNull(List list, E element) { - var index = list.indexOf(null); - if (index < 0) throw ArgumentError("$list contains no null elements."); + 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(List list, E element) { - var index = list.indexOf(element); + final index = list.indexOf(element); if (index < 0) { - throw ArgumentError("$list contains no elements matching $element."); + throw ArgumentError('$list contains no elements matching $element.'); } list[index] = null; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 2054423d5..fce212461 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,8 +1,7 @@ name: source_span -version: 1.6.0 +version: 1.6.1-dev description: A library for identifying source spans and locations. -author: Dart Team homepage: https://github.com/dart-lang/source_span environment: diff --git a/pkgs/source_span/test/multiple_highlight_test.dart b/pkgs/source_span/test/multiple_highlight_test.dart index f0cceedef..d9d1b30c8 100644 --- a/pkgs/source_span/test/multiple_highlight_test.dart +++ b/pkgs/source_span/test/multiple_highlight_test.dart @@ -26,13 +26,13 @@ zip zap zop fwee fwoo fwip argle bargle boo gibble bibble bop -''', url: "file1.txt"); +''', url: 'file1.txt'); }); - test("highlights spans on separate lines", () { + test('highlights spans on separate lines', () { expect( file.span(17, 21).highlightMultiple( - "one", {file.span(31, 34): "two", file.span(4, 7): "three"}), + 'one', {file.span(31, 34): 'two', file.span(4, 7): 'three'}), equals(""" , 1 | foo bar baz @@ -44,10 +44,10 @@ gibble bibble bop '""")); }); - test("highlights spans on the same line", () { + test('highlights spans on the same line', () { expect( file.span(17, 21).highlightMultiple( - "one", {file.span(22, 26): "two", file.span(12, 16): "three"}), + 'one', {file.span(22, 26): 'two', file.span(12, 16): 'three'}), equals(""" , 2 | whiz bang boom @@ -57,10 +57,10 @@ gibble bibble bop '""")); }); - test("highlights overlapping spans on the same line", () { + test('highlights overlapping spans on the same line', () { expect( file.span(17, 21).highlightMultiple( - "one", {file.span(20, 26): "two", file.span(12, 18): "three"}), + 'one', {file.span(20, 26): 'two', file.span(12, 18): 'three'}), equals(""" , 2 | whiz bang boom @@ -70,10 +70,10 @@ gibble bibble bop '""")); }); - test("highlights multiple multiline spans", () { + test('highlights multiple multiline spans', () { expect( file.span(27, 54).highlightMultiple( - "one", {file.span(54, 89): "two", file.span(0, 27): "three"}), + 'one', {file.span(54, 89): 'two', file.span(0, 27): 'three'}), equals(""" , 1 | / foo bar baz @@ -88,10 +88,10 @@ gibble bibble bop '""")); }); - test("highlights multiple overlapping multiline spans", () { + test('highlights multiple overlapping multiline spans', () { expect( file.span(12, 70).highlightMultiple( - "one", {file.span(54, 89): "two", file.span(0, 27): "three"}), + 'one', {file.span(54, 89): 'two', file.span(0, 27): 'three'}), equals(""" , 1 | /- foo bar baz @@ -106,12 +106,12 @@ gibble bibble bop '""")); }); - test("highlights many layers of overlaps", () { + test('highlights many layers of overlaps', () { expect( - file.span(0, 54).highlightMultiple("one", { - file.span(12, 77): "two", - file.span(27, 84): "three", - file.span(39, 88): "four" + file.span(0, 54).highlightMultiple('one', { + file.span(12, 77): 'two', + file.span(27, 84): 'three', + file.span(39, 88): 'four' }), equals(""" , @@ -129,11 +129,11 @@ gibble bibble bop }); group("highlights a multiline span that's a subset", () { - test("with no first or last line overlap", () { + test('with no first or last line overlap', () { expect( file .span(27, 53) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | /- whiz bang boom @@ -145,11 +145,11 @@ gibble bibble bop '""")); }); - test("overlapping the whole first line", () { + test('overlapping the whole first line', () { expect( file .span(12, 53) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | // whiz bang boom @@ -161,11 +161,11 @@ gibble bibble bop '""")); }); - test("overlapping part of first line", () { + test('overlapping part of first line', () { expect( file .span(17, 53) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | /- whiz bang boom @@ -178,11 +178,11 @@ gibble bibble bop '""")); }); - test("overlapping the whole last line", () { + test('overlapping the whole last line', () { expect( file .span(27, 70) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | /- whiz bang boom @@ -194,11 +194,11 @@ gibble bibble bop '""")); }); - test("overlapping part of the last line", () { + test('overlapping part of the last line', () { expect( file .span(27, 66) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | /- whiz bang boom @@ -211,12 +211,12 @@ gibble bibble bop }); }); - group("a single-line span in a multiline span", () { - test("on the first line", () { + group('a single-line span in a multiline span', () { + test('on the first line', () { expect( file .span(17, 21) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | / whiz bang boom @@ -228,11 +228,11 @@ gibble bibble bop '""")); }); - test("in the middle", () { + test('in the middle', () { expect( file .span(31, 34) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | / whiz bang boom @@ -244,11 +244,11 @@ gibble bibble bop '""")); }); - test("on the last line", () { + test('on the last line', () { expect( file .span(60, 66) - .highlightMultiple("inner", {file.span(12, 70): "outer"}), + .highlightMultiple('inner', {file.span(12, 70): 'outer'}), equals(""" , 2 | / whiz bang boom @@ -261,13 +261,13 @@ gibble bibble bop }); }); - test("highlights multiple files with their URLs", () { - var file2 = SourceFile.fromString(''' + test('highlights multiple files with their URLs', () { + final file2 = SourceFile.fromString(''' quibble bibble boop -''', url: "file2.txt"); +''', url: 'file2.txt'); expect( - file.span(31, 34).highlightMultiple("one", {file2.span(8, 14): "two"}), + file.span(31, 34).highlightMultiple('one', {file2.span(8, 14): 'two'}), equals(""" ,--> file1.txt 3 | zip zap zop From 7620e6b877ec39ebc0afb7ad1d3d9dea4ab635c5 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Mon, 27 Jan 2020 12:50:59 +0100 Subject: [PATCH 326/657] Further tweaks on the API. (dart-lang/package_config#57) * Allow nested packages. --- pkgs/package_config/lib/package_config.dart | 38 +-- pkgs/package_config/lib/src/discovery.dart | 16 +- .../lib/src/package_config_impl.dart | 251 ++++++++++++++---- .../lib/src/package_config_json.dart | 56 ++-- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/discovery_test.dart | 7 + .../test/discovery_uri_test.dart | 1 - pkgs/package_config/test/parse_test.dart | 47 +++- 8 files changed, 309 insertions(+), 109 deletions(-) diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index 4d6f346d7..77e8d61bf 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -23,10 +23,16 @@ export "src/errors.dart" show PackageConfigError; /// It is considered a `package_config.json` file if its first character /// is a `{`. /// -/// If the file is a `.packages` file, also checks if there is a -/// `.dart_tool/package_config.json` file next to the original file, +/// If the file is a `.packages` file and [preferNewest] is true, the default, +/// also checks if there is a `.dart_tool/package_config.json` file next to the original file, /// and if so, loads that instead. -Future loadPackageConfig(File file) => readAnyConfigFile(file); +/// If [preferNewest] is set to false, a directly specified `.packages` file +/// is loaded even if there is an available `package_config.json` file. +/// The caller can determine this from the [PackageConfig.version] +/// being 1 and look for a `package_config.json` file themselves. +Future loadPackageConfig(File file, + {bool preferNewest = true}) => + readAnyConfigFile(file, preferNewest); /// Reads a specific package configuration URI. /// @@ -36,19 +42,24 @@ Future loadPackageConfig(File file) => readAnyConfigFile(file); /// It is considered a `package_config.json` file if its first /// non-whitespace character is a `{`. /// -/// If the file is a `.packages` file, first checks if there is a -/// `.dart_tool/package_config.json` file next to the original file, -/// and if so, loads that instead. +/// If [preferNewest] is true, the default, and the file is a `.packages` file, +/// first checks if there is a `.dart_tool/package_config.json` file +/// next to the original file, and if so, loads that instead. /// The [file] *must not* be a `package:` URI. +/// If [preferNewest] is set to false, a directly specified `.packages` file +/// is loaded even if there is an available `package_config.json` file. +/// The caller can determine this from the [PackageConfig.version] +/// being 1 and look for a `package_config.json` file themselves. /// /// If [loader] is provided, URIs are loaded using that function. /// The future returned by the loader must complete with a [Uint8List] -/// containing the entire file content, +/// containing the entire file content encoded as UTF-8, /// or with `null` if the file does not exist. /// The loader may throw at its own discretion, for situations where /// it determines that an error might be need user attention, /// but it is always allowed to return `null`. /// This function makes no attempt to catch such errors. +/// As such, it may throw any error that [loader] throws. /// /// If no [loader] is supplied, a default loader is used which /// only accepts `file:`, `http:` and `https:` URIs, @@ -58,8 +69,9 @@ Future loadPackageConfig(File file) => readAnyConfigFile(file); /// As such, it does not distinguish between a file not existing, /// and it being temporarily locked or unreachable. Future loadPackageConfigUri(Uri file, - {Future loader(Uri uri) /*?*/}) => - readAnyConfigFileUri(file, loader); + {Future loader(Uri uri) /*?*/, + bool preferNewest = true}) => + readAnyConfigFileUri(file, loader, preferNewest); /// Finds a package configuration relative to [directory]. /// @@ -123,14 +135,6 @@ Future findPackageConfigUri(Uri location, /// If the `.dart_tool/` directory does not exist, it is created. /// If it cannot be created, this operation fails. /// -/// If [extraData] contains any entries, they are added to the JSON -/// written to the `package_config.json` file. Entries with the names -/// `"configVersion"` or `"packages"` are ignored, all other entries -/// are added verbatim. -/// This is intended for, e.g., the -/// `"generator"`, `"generated"` and `"generatorVersion"` -/// properties. -/// /// Also writes a `.packages` file in [directory]. /// This will stop happening eventually as the `.packages` file becomes /// discontinued. diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index 6b0fc8f0d..5ad6ac54e 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -5,7 +5,7 @@ import "dart:io"; import 'dart:typed_data'; -import "package:path/path.dart" as path; +import "package:path/path.dart" as p; import "errors.dart"; import "package_config_impl.dart"; @@ -110,23 +110,13 @@ Future findPackagConfigInDirectory( Future /*?*/ checkForPackageConfigJsonFile(Directory directory) async { assert(directory.isAbsolute); - var file = - File(path.join(directory.path, ".dart_tool", "package_config.json")); + var file = File(p.join(directory.path, ".dart_tool", "package_config.json")); if (await file.exists()) return file; return null; } Future checkForDotPackagesFile(Directory directory) async { - var file = File(path.join(directory.path, ".packages")); + var file = File(p.join(directory.path, ".packages")); if (await file.exists()) return file; return null; } - -Future _loadFile(File file) async { - Uint8List bytes; - try { - return await file.readAsBytes(); - } catch (_) { - return null; - } -} diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 0bbe18f5b..62579610c 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -4,22 +4,26 @@ import 'errors.dart'; import "package_config.dart"; -export "package_config.dart"; import "util.dart"; +export "package_config.dart"; + class SimplePackageConfig implements PackageConfig { final int version; final Map _packages; + final PackageTree _packageTree; final dynamic extraData; - SimplePackageConfig(int version, Iterable packages, [this.extraData]) - : version = _validateVersion(version), - _packages = _validatePackages(packages); + SimplePackageConfig(int version, Iterable packages, + [dynamic extraData]) + : this._(_validateVersion(version), packages, + [...packages]..sort(_compareRoot), extraData); - SimplePackageConfig._( - int version, Iterable packages, this.extraData) - : version = _validateVersion(version), - _packages = {for (var package in packages) package.name: package}; + /// Expects a list of [packages] sorted on root path. + SimplePackageConfig._(this.version, Iterable originalPackages, + List packages, this.extraData) + : _packageTree = _validatePackages(originalPackages, packages), + _packages = {for (var p in packages) p.name: p}; /// Creates empty configuration. /// @@ -27,6 +31,7 @@ class SimplePackageConfig implements PackageConfig { /// found, but code expects a non-null configuration. const SimplePackageConfig.empty() : version = 1, + _packageTree = const EmptyPackageTree(), _packages = const {}, extraData = null; @@ -38,18 +43,28 @@ class SimplePackageConfig implements PackageConfig { return version; } - static Map _validatePackages(Iterable packages) { + static PackageTree _validatePackages( + Iterable originalPackages, List packages) { + // Assumes packages are sorted. Map result = {}; - for (var package in packages) { - if (package is! SimplePackage) { + var tree = MutablePackageTree(); + SimplePackage package; + for (var originalPackage in packages) { + if (originalPackage is! SimplePackage) { // SimplePackage validates these properties. try { - _validatePackageData(package.name, package.root, - package.packageUriRoot, package.languageVersion); + package = SimplePackage( + originalPackage.name, + originalPackage.root, + originalPackage.packageUriRoot, + originalPackage.languageVersion, + originalPackage.extraData); } catch (e) { throw PackageConfigArgumentError( packages, "packages", "Package ${package.name}: ${e.message}"); } + } else { + package = originalPackage; } var name = package.name; if (result.containsKey(name)) { @@ -57,33 +72,31 @@ class SimplePackageConfig implements PackageConfig { name, "packages", "Duplicate package name"); } result[name] = package; - } - - // Check that no root URI is a prefix of another. - if (result.length > 1) { - // Uris cache their toString, so this is not as bad as it looks. - var rootUris = [...result.values] - ..sort((a, b) => a.root.toString().compareTo(b.root.toString())); - var prev = rootUris[0]; - var prevRoot = prev.root.toString(); - for (int i = 1; i < rootUris.length; i++) { - var next = rootUris[i]; - var nextRoot = next.root.toString(); - // If one string is a prefix of another, - // the former sorts just before the latter. - if (nextRoot.startsWith(prevRoot)) { + try { + tree.add(0, package); + } on ConflictException catch (e) { + // There is a conflict with an existing package. + var existingPackage = e.existingPackage; + if (e.isRootConflict) { throw PackageConfigArgumentError( - packages, + originalPackages, "packages", - "Package ${next.name} root overlaps " - "package ${prev.name} root.\n" - "${prev.name} root: $prevRoot\n" - "${next.name} root: $nextRoot\n"); + "Packages ${package.name} and ${existingPackage.name}" + "have the same root directory: ${package.root}.\n"); } - prev = next; + assert(e.isPackageRootConflict); + // Or package is inside the package URI root of the existing package. + throw PackageConfigArgumentError( + originalPackages, + "packages", + "Package ${package.name} is inside the package URI root of " + "package ${existingPackage.name}.\n" + "${existingPackage.name} URI root: " + "${existingPackage.packageUriRoot}\n" + "${package.name} root: ${package.root}\n"); } } - return result; + return tree; } Iterable get packages => _packages.values; @@ -96,14 +109,7 @@ class SimplePackageConfig implements PackageConfig { /// That is, the [Package.rootUri] directory is a parent directory /// of the [file]'s location. /// Returns `null` if the file does not belong to any package. - Package /*?*/ packageOf(Uri file) { - String path = file.toString(); - for (var package in _packages.values) { - var rootPath = package.root.toString(); - if (path.startsWith(rootPath)) return package; - } - return null; - } + Package /*?*/ packageOf(Uri file) => _packageTree.packageOf(file); Uri /*?*/ resolve(Uri packageUri) { String packageName = checkValidPackageUri(packageUri, "packageUri"); @@ -120,12 +126,15 @@ class SimplePackageConfig implements PackageConfig { throw PackageConfigArgumentError(nonPackageUri, "nonPackageUri", "Must not have query or fragment part"); } - for (var package in _packages.values) { - var root = package.packageUriRoot; - if (isUriPrefix(root, nonPackageUri)) { - var rest = nonPackageUri.toString().substring(root.toString().length); - return Uri(scheme: "package", path: "${package.name}/$rest"); - } + // Find package that file belongs to. + var package = _packageTree.packageOf(nonPackageUri); + if (package == null) return null; + // Check if it is inside the package URI root. + var path = nonPackageUri.toString(); + var root = package.packageUriRoot.toString(); + if (_beginsWith(package.root.toString().length, root, path)) { + var rest = path.substring(root.length); + return Uri(scheme: "package", path: "${package.name}/$rest"); } return null; } @@ -142,6 +151,9 @@ class SimplePackage implements Package { SimplePackage._(this.name, this.root, this.packageUriRoot, this.languageVersion, this.extraData); + /// Creates a [SimplePackage] with the provided content. + /// + /// The provided arguments must be valid. factory SimplePackage(String name, Uri root, Uri packageUriRoot, String /*?*/ languageVersion, dynamic extraData) { _validatePackageData(name, root, packageUriRoot, languageVersion); @@ -179,3 +191,144 @@ void _validatePackageData( languageVersion, "languageVersion", "Invalid language version format"); } } + +abstract class PackageTree { + SimplePackage /*?*/ packageOf(Uri file); +} + +/// Packages of a package configuration ordered by root path. +/// +/// A package is said to be inside another package if the root path URI of +/// the latter is a prefix of the root path URI of the former. +/// No two packages of a package may have the same root path, so this +/// path prefix ordering defines a tree-like partial ordering on packages +/// of a configuration. +/// +/// The package tree contains an ordered mapping of unrelated packages +/// (represented by their name) to their immediately nested packages' names. +class MutablePackageTree implements PackageTree { + final List packages = []; + Map /*?*/ _packageChildren; + + /// Tries to (add) `package` to the tree. + /// + /// Throws [ConflictException] if the added package conflicts with an + /// existing package. + /// It conflicts if it has the same root path, or if the new package + /// contains the existing package's package root. + void add(int start, SimplePackage package) { + var path = package.root.toString(); + for (var childPackage in packages) { + var childPath = childPackage.root.toString(); + assert(childPath.length > start); + assert(path.startsWith(childPath.substring(0, start))); + if (_beginsWith(start, childPath, path)) { + var childPathLength = childPath.length; + if (path.length == childPathLength) { + throw ConflictException.root(package, childPackage); + } + var childPackageRoot = childPackage.packageUriRoot.toString(); + if (_beginsWith(childPathLength, childPackageRoot, path)) { + throw ConflictException.packageRoot(package, childPackage); + } + _treeOf(childPackage).add(childPathLength, package); + return; + } + } + packages.add(package); + } + + SimplePackage /*?*/ packageOf(Uri file) { + return findPackageOf(0, file.toString()); + } + + /// Finds package containing [path] in this tree. + /// + /// Returns `null` if no such package is found. + /// + /// Assumes the first [start] characters of path agrees with all + /// the packages at this level of the tree. + SimplePackage /*?*/ findPackageOf(int start, String path) { + for (var childPackage in packages) { + var childPath = childPackage.root.toString(); + if (_beginsWith(start, childPath, path)) { + // The [package] is inside [childPackage]. + var childPathLength = childPath.length; + if (path.length == childPathLength) return childPackage; + var uriRoot = childPackage.packageUriRoot.toString(); + // Is [package] is inside the URI root of [childPackage]. + if (uriRoot.length == childPathLength || + _beginsWith(childPathLength, uriRoot, path)) { + return childPackage; + } + // Otherwise add [package] as child of [childPackage]. + // TODO(lrn): When NNBD comes, convert to: + // return _packageChildren?[childPackage.name] + // ?.packageOf(childPathLength, path) ?? childPackage; + if (_packageChildren == null) return childPackage; + var childTree = _packageChildren[childPackage.name]; + if (childTree == null) return childPackage; + return childTree.findPackageOf(childPathLength, path) ?? childPackage; + } + } + return null; + } + + /// Returns the [PackageTree] of the children of [package]. + /// + /// Ensures that the object is allocated if necessary. + MutablePackageTree _treeOf(SimplePackage package) { + var children = _packageChildren ??= {}; + return children[package.name] ??= MutablePackageTree(); + } +} + +class EmptyPackageTree implements PackageTree { + const EmptyPackageTree(); + + SimplePackage packageOf(Uri file) => null; +} + +/// Checks whether [longerPath] begins with [parentPath]. +/// +/// Skips checking the [start] first characters which are assumed to +/// already have been matched. +bool _beginsWith(int start, String parentPath, String longerPath) { + if (longerPath.length < parentPath.length) return false; + for (int i = start; i < parentPath.length; i++) { + if (longerPath.codeUnitAt(i) != parentPath.codeUnitAt(i)) return false; + } + return true; +} + +/// Conflict between packages added to the same configuration. +/// +/// The [package] conflicts with [existingPackage] if it has +/// the same root path ([isRootConflict]) or the package URI root path +/// of [existingPackage] is inside the root path of [package] +/// ([isPackageRootConflict]). +class ConflictException { + /// The existing package that [package] conflicts with. + final SimplePackage existingPackage; + + /// The package that could not be added without a conflict. + final SimplePackage package; + + /// Whether the conflict is with the package URI root of [existingPackage]. + final bool isPackageRootConflict; + + /// Creates a root conflict between [package] and [existingPackage]. + ConflictException.root(this.package, this.existingPackage) + : isPackageRootConflict = false; + + /// Creates a package root conflict between [package] and [existingPackage]. + ConflictException.packageRoot(this.package, this.existingPackage) + : isPackageRootConflict = true; + + /// WHether the conflict is with the root URI of [existingPackage]. + bool get isRootConflict => !isPackageRootConflict; +} + +/// Used for sorting packages by root path. +int _compareRoot(Package p1, Package p2) => + p1.root.toString().compareTo(p2.root.toString()); diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index 8a6014cad..8108102bd 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -7,7 +7,7 @@ import "dart:io"; import "dart:typed_data"; import 'package:charcode/ascii.dart'; -import "package:path/path.dart" as path; +import "package:path/path.dart" as p; import "discovery.dart" show packageConfigJsonPath; import "errors.dart"; @@ -38,36 +38,42 @@ const String _generatorVersionKey = "generatorVersion"; /// Detects whether the [file] is a version one `.packages` file or /// a version two `package_config.json` file. /// -/// If the [file] is a `.packages` file, first checks whether there is an -/// adjacent `.dart_tool/package_config.json` file, and if so, -/// reads that instead. +/// If the [file] is a `.packages` file and [preferNewest] is true, +/// first checks whether there is an adjacent `.dart_tool/package_config.json` +/// file, and if so, reads that instead. +/// If [preferNewset] is false, the specified file is loaded even if it is +/// a `.packages` file and there is an available `package_config.json` file. /// /// The file must exist and be a normal file. -Future readAnyConfigFile(File file) async { +Future readAnyConfigFile(File file, bool preferNewest) async { var bytes = await file.readAsBytes(); int firstChar = firstNonWhitespaceChar(bytes); if (firstChar != $lbrace) { // Definitely not a JSON object, probably a .packages. - var alternateFile = File(path.join( - path.dirname(file.path), ".dart_tool", "package_config.json")); - if (!alternateFile.existsSync()) { - return packages_file.parse(bytes, file.uri); + if (preferNewest) { + var alternateFile = File( + p.join(p.dirname(file.path), ".dart_tool", "package_config.json")); + if (alternateFile.existsSync()) { + return parsePackageConfigBytes( + await alternateFile.readAsBytes(), alternateFile.uri); + } } - file = alternateFile; - bytes = await alternateFile.readAsBytes(); + return packages_file.parse(bytes, file.uri); } return parsePackageConfigBytes(bytes, file.uri); } /// Like [readAnyConfigFile] but uses a URI and an optional loader. -Future readAnyConfigFileUri( - Uri file, Future loader(Uri uri) /*?*/) async { +Future readAnyConfigFileUri(Uri file, + Future loader(Uri uri) /*?*/, bool preferNewest) async { if (file.isScheme("package")) { throw PackageConfigArgumentError( file, "file", "Must not be a package: URI"); } if (loader == null) { - if (file.isScheme("file")) return readAnyConfigFile(File.fromUri(file)); + if (file.isScheme("file")) { + return readAnyConfigFile(File.fromUri(file), preferNewest); + } loader = defaultLoader; } var bytes = await loader(file); @@ -78,13 +84,15 @@ Future readAnyConfigFileUri( int firstChar = firstNonWhitespaceChar(bytes); if (firstChar != $lbrace) { // Definitely not a JSON object, probably a .packages. - var alternateFile = file.resolveUri(packageConfigJsonPath); - var alternateBytes = await loader(alternateFile); - if (alternateBytes == null) { - return packages_file.parse(bytes, file); + if (preferNewest) { + // Check if there is a package_config.json file. + var alternateFile = file.resolveUri(packageConfigJsonPath); + var alternateBytes = await loader(alternateFile); + if (alternateBytes != null) { + return parsePackageConfigBytes(alternateBytes, alternateFile); + } } - bytes = alternateBytes; - file = alternateFile; + return packages_file.parse(bytes, file); } return parsePackageConfigBytes(bytes, file); } @@ -242,8 +250,8 @@ PackageConfig parsePackageConfigJson(dynamic json, Uri baseLocation) { Future writePackageConfigJson( PackageConfig config, Directory targetDirectory) async { // Write .dart_tool/package_config.json first. - var file = File( - path.join(targetDirectory.path, ".dart_tool", "package_config.json")); + var file = + File(p.join(targetDirectory.path, ".dart_tool", "package_config.json")); var baseUri = file.uri; var extraData = config.extraData; var data = { @@ -275,7 +283,7 @@ Future writePackageConfigJson( "${generated != null ? " on $generated" : ""}."; } } - file = File(path.join(targetDirectory.path, ".packages")); + file = File(p.join(targetDirectory.path, ".packages")); baseUri = file.uri; var buffer = StringBuffer(); packages_file.write(buffer, config, baseUri: baseUri, comment: comment); @@ -313,7 +321,7 @@ Map /*?*/ _extractExtraData( /// Checks that the object is a valid JSON-like data structure. bool _validateJson(dynamic object) { - if (object == null || object == true || object == false) return true; + if (object == null || true == object || false == object) return true; if (object is num || object is String) return true; if (object is List) { for (var element in object) if (!_validateJson(element)) return false; diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 0cd7ddc52..781dc32a8 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -5,7 +5,7 @@ author: Dart Team homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=2.5.0-dev <3.0.0' + sdk: '>=2.7.0 <3.0.0' dependencies: charcode: ^1.1.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 5db24a100..4dd1504e1 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -170,6 +170,13 @@ main() { expect(config.version, 2); validatePackagesFile(config, directory); }); + fileTest("prefer .packages", files, (Directory directory) async { + File file = dirFile(directory, ".packages"); + PackageConfig config = + await loadPackageConfig(file, preferNewest: false); + expect(config.version, 1); + validatePackagesFile(config, directory); + }); }); fileTest("package_config.json non-default name", { diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 414a43add..9558f585e 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -4,7 +4,6 @@ library package_config.discovery_test; -import "dart:io"; import "package:test/test.dart"; import "package:package_config_2/package_config.dart"; diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 235f49381..a07ef1d61 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -2,7 +2,6 @@ // 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 "dart:io"; import "dart:convert"; import "package:test/test.dart"; @@ -199,9 +198,43 @@ void main() { expect(config.packages.first.name, "foo"); }); + test("nested packages", () { + var configBytes = utf8.encode(json.encode({ + "configVersion": 2, + "packages": [ + {"name": "foo", "rootUri": "/foo/", "packageUri": "lib/"}, + {"name": "bar", "rootUri": "/foo/bar/", "packageUri": "lib/"}, + {"name": "baz", "rootUri": "/foo/bar/baz/", "packageUri": "lib/"}, + {"name": "qux", "rootUri": "/foo/qux/", "packageUri": "lib/"}, + ] + })); + var config = parsePackageConfigBytes( + configBytes, Uri.parse("file:///tmp/.dart_tool/file.dart")); + expect(config.version, 2); + expect(config.packageOf(Uri.parse("file:///foo/lala/lala.dart")).name, + "foo"); + expect( + config.packageOf(Uri.parse("file:///foo/bar/lala.dart")).name, "bar"); + expect(config.packageOf(Uri.parse("file:///foo/bar/baz/lala.dart")).name, + "baz"); + expect( + config.packageOf(Uri.parse("file:///foo/qux/lala.dart")).name, "qux"); + expect(config.toPackageUri(Uri.parse("file:///foo/lib/diz")), + Uri.parse("package:foo/diz")); + expect(config.toPackageUri(Uri.parse("file:///foo/bar/lib/diz")), + Uri.parse("package:bar/diz")); + expect(config.toPackageUri(Uri.parse("file:///foo/bar/baz/lib/diz")), + Uri.parse("package:baz/diz")); + expect(config.toPackageUri(Uri.parse("file:///foo/qux/lib/diz")), + Uri.parse("package:qux/diz")); + }); + group("invalid", () { testThrows(String name, String source) { test(name, () { + if (name == "inside lib") { + print(name); + } expect( () => parsePackageConfigBytes(utf8.encode(source), Uri.parse("file:///tmp/.dart_tool/file.dart")), @@ -304,9 +337,15 @@ void main() { testThrows("same roots", '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); testThrows( - "overlapping roots", - '{$cfg,"packages":[{$name,$root},' - '{"name":"bar","rootUri":"/foo/sub/"}]}'); + // The roots of foo and bar are the same. + "same roots", + '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); + testThrows( + // The root of bar is inside the package root of foo. + "inside lib", + '{$cfg,"packages":[' + '{"name":"foo","rootUri":"/foo/","packageUri":"lib/"},' + '{"name":"bar","rootUri":"/foo/lib/qux/"}]}'); }); }); } From db13ed8bf9e2ad1700ef155249d5e8bac2c8b453 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Mon, 27 Jan 2020 13:07:43 +0100 Subject: [PATCH 327/657] Prepare release of package_config 2.0.0. --- pkgs/package_config/README.md | 8 +++++--- pkgs/package_config/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 942822002..9ab7f38a3 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -1,8 +1,10 @@ # package_config -Support for working with **Package Resolution Configuration** files as described -in this [DEP](https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md), -under review [here](https://github.com/dart-lang/dart_enhancement_proposals/issues/5). +Support for working with **Package Configuration** files as described +in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). + +This package is also available as `package_config_2`, which can be used by packages +which transitively depend on a version of package_config with a version <2.0.0. [![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 781dc32a8..66aeb7858 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,4 +1,4 @@ -name: package_config_2 +name: package_config version: 2.0.0 description: Support for working with Package Configuration files. author: Dart Team From 9bb0203bb07039889f2df85f045382692d7ffe88 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Mon, 27 Jan 2020 13:07:43 +0100 Subject: [PATCH 328/657] Prepare release of package_config 2.0.0. --- pkgs/package_config/README.md | 5 +++-- pkgs/package_config/test/discovery_test.dart | 2 +- pkgs/package_config/test/discovery_uri_test.dart | 2 +- pkgs/package_config/test/parse_test.dart | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 9ab7f38a3..073a1c7e0 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -3,8 +3,9 @@ Support for working with **Package Configuration** files as described in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). -This package is also available as `package_config_2`, which can be used by packages -which transitively depend on a version of package_config with a version <2.0.0. +This version of the `package_config` package is also available as `package_config_2`, +which can be used by packages which transitively depend on a version of `package_config` +with a version <2.0.0. [![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 4dd1504e1..3256187d2 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -6,7 +6,7 @@ library package_config.discovery_test; import "dart:io"; import "package:test/test.dart"; -import "package:package_config_2/package_config.dart"; +import "package:package_config/package_config.dart"; import "src/util.dart"; diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 9558f585e..8ad428ac0 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -5,7 +5,7 @@ library package_config.discovery_test; import "package:test/test.dart"; -import "package:package_config_2/package_config.dart"; +import "package:package_config/package_config.dart"; import "src/util.dart"; diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index a07ef1d61..3d1a20e4a 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -6,8 +6,8 @@ import "dart:convert"; import "package:test/test.dart"; -import "package:package_config_2/src/packages_file.dart" as packages; -import "package:package_config_2/src/package_config_json.dart"; +import "package:package_config/src/packages_file.dart" as packages; +import "package:package_config/src/package_config_json.dart"; import "src/util.dart"; void main() { From ace073c02a863dce77e998dc1b9393f3d28bb5a2 Mon Sep 17 00:00:00 2001 From: Scott Hyndman Date: Thu, 6 Feb 2020 17:21:08 -0600 Subject: [PATCH 329/657] Replace use of int.parse with int.tryParse (dart-lang/pub_semver#43) By replacing `int.parse` with `int.tryParse`, exceptions will no longer be thrown if the version part is a non-integer. This avoids triggering the debugger if set to break on "All Exceptions". Fixes dart-lang/pub_semver#42 --- pkgs/pub_semver/lib/src/version.dart | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index eb38409dc..e769dcd64 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -152,12 +152,8 @@ class Version implements VersionConstraint, VersionRange { /// Identifiers that are numeric are converted to numbers. static List _splitParts(String text) { return text.split('.').map((part) { - try { - return int.parse(part); - } on FormatException { - // Not a number. - return part; - } + // Return an integer part if possible, otherwise return the string as-is + return int.tryParse(part) ?? part; }).toList(); } From 173173868aa030ef6431cdc82ffe823ce77649f8 Mon Sep 17 00:00:00 2001 From: Tod Bachman Date: Mon, 10 Feb 2020 17:04:07 -0700 Subject: [PATCH 330/657] Handle null names field when parsing source map files (dart-lang/source_maps#40) The field is required by the spec, but we can be more lenient. --- pkgs/source_maps/lib/parser.dart | 2 +- pkgs/source_maps/test/parser_test.dart | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 124ef6dc4..e3044aa31 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -341,7 +341,7 @@ class SingleMapping extends Mapping { SingleMapping.fromJson(Map map, {mapUrl}) : targetUrl = map['file'], urls = List.from(map['sources']), - names = List.from(map['names']), + names = List.from(map['names'] ?? []), files = List(map['sources'].length), sourceRoot = map['sourceRoot'], lines = [], diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 275efd30a..45ac52db2 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -28,6 +28,14 @@ const Map MAP_WITH_SOURCE_LOCATION = { 'file': 'output.dart' }; +const Map MAP_WITH_SOURCE_LOCATION_AND_MISSING_NAMES = { + 'version': 3, + 'sourceRoot': '', + 'sources': ['input.dart'], + 'mappings': 'AAAA', + 'file': 'output.dart' +}; + const Map MAP_WITH_SOURCE_LOCATION_AND_NAME = { 'version': 3, 'sourceRoot': '', @@ -121,6 +129,20 @@ void main() { expect(entry.sourceNameId, null); }); + test('parse with source location and missing names entry', () { + SingleMapping map = + parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_MISSING_NAMES)); + expect(map.lines.length, 1); + expect(map.lines.first.entries.length, 1); + var entry = map.lines.first.entries.first; + + expect(entry.column, 0); + expect(entry.sourceUrlId, 0); + expect(entry.sourceColumn, 0); + expect(entry.sourceLine, 0); + expect(entry.sourceNameId, null); + }); + test('parse with source location and name', () { SingleMapping map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_NAME)); expect(map.lines.length, 1); From 86f3c5245a3aac86783819a35153b20c80fe0557 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Tue, 11 Feb 2020 09:34:11 +0100 Subject: [PATCH 331/657] Make error handling optionally more permissive. (dart-lang/package_config#58) * Make error handling optionally more permissive. * Make the LanguageVersion be an object, not a string. * Make it version 3.0.0-dev --- pkgs/package_config/CHANGELOG.md | 19 +- pkgs/package_config/README.md | 6 +- pkgs/package_config/lib/package_config.dart | 49 ++- pkgs/package_config/lib/src/discovery.dart | 48 +-- pkgs/package_config/lib/src/errors.dart | 57 +-- .../lib/src/package_config.dart | 122 ++++++- .../lib/src/package_config_impl.dart | 331 +++++++++++++----- .../lib/src/package_config_json.dart | 194 +++++++--- .../package_config/lib/src/packages_file.dart | 91 +++-- pkgs/package_config/lib/src/util.dart | 118 ++++--- pkgs/package_config/pubspec.yaml | 6 +- pkgs/package_config/test/discovery_test.dart | 119 +++++-- .../test/discovery_uri_test.dart | 43 ++- pkgs/package_config/test/parse_test.dart | 63 ++-- pkgs/package_config/test/src/util.dart | 8 +- 15 files changed, 917 insertions(+), 357 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 84384fc21..317184075 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,9 +1,22 @@ +## 3.0.0 + +- Make the language version be represented as a `LanguageVersion` class + instead of a string. +- Made error handling interceptable. Passing an `onError` handler + makes the parsers attempt to do a best-effort error correction after + detecting an error. +- Do not require root URIs to have paths starting with `/`. That + only makes sense for `file` or `http`, and they enforce it anyway. +- Fixed bug in language version validation not accepting the digit `9`. + ## 2.0.0 - - Based on new JSON file format with more content. + +- Based on new JSON file format with more content. ## 1.2.0 - - Added support for writing default-package entries. - - Fixed bug when writing `Uri`s containing a fragment. + +- Added support for writing default-package entries. +- Fixed bug when writing `Uri`s containing a fragment. ## 1.1.0 diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 073a1c7e0..45791aaf3 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -3,11 +3,7 @@ Support for working with **Package Configuration** files as described in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). -This version of the `package_config` package is also available as `package_config_2`, -which can be used by packages which transitively depend on a version of `package_config` -with a version <2.0.0. - -[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) +[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) ## Features and bugs diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index 77e8d61bf..98b31f1f9 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -8,11 +8,14 @@ library package_config.package_config; import "dart:io" show File, Directory; import "dart:typed_data" show Uint8List; + import "src/discovery.dart" as discover; +import "src/errors.dart" show throwError; import "src/package_config.dart"; import "src/package_config_json.dart"; -export "src/package_config.dart" show PackageConfig, Package; +export "src/package_config.dart" + show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion; export "src/errors.dart" show PackageConfigError; /// Reads a specific package configuration file. @@ -30,9 +33,15 @@ export "src/errors.dart" show PackageConfigError; /// is loaded even if there is an available `package_config.json` file. /// The caller can determine this from the [PackageConfig.version] /// being 1 and look for a `package_config.json` file themselves. +/// +/// If [onError] is provided, the configuration file parsing will report errors +/// by calling that function, and then try to recover. +/// The returned package configuration is a *best effort* attempt to create +/// a valid configuration from the invalid configuration file. +/// If no [onError] is provided, errors are thrown immediately. Future loadPackageConfig(File file, - {bool preferNewest = true}) => - readAnyConfigFile(file, preferNewest); + {bool preferNewest = true, void onError(Object error)}) => + readAnyConfigFile(file, preferNewest, onError ?? throwError); /// Reads a specific package configuration URI. /// @@ -68,10 +77,17 @@ Future loadPackageConfig(File file, /// of an I/O issue, as long as the location URIs are valid. /// As such, it does not distinguish between a file not existing, /// and it being temporarily locked or unreachable. +/// +/// If [onError] is provided, the configuration file parsing will report errors +/// by calling that function, and then try to recover. +/// The returned package configuration is a *best effort* attempt to create +/// a valid configuration from the invalid configuration file. +/// If no [onError] is provided, errors are thrown immediately. Future loadPackageConfigUri(Uri file, {Future loader(Uri uri) /*?*/, - bool preferNewest = true}) => - readAnyConfigFileUri(file, loader, preferNewest); + bool preferNewest = true, + void onError(Object error)}) => + readAnyConfigFileUri(file, loader, onError ?? throwError, preferNewest); /// Finds a package configuration relative to [directory]. /// @@ -86,10 +102,16 @@ Future loadPackageConfigUri(Uri file, /// If [recurse] is set to [false], this parent directory check is not /// performed. /// +/// If [onError] is provided, the configuration file parsing will report errors +/// by calling that function, and then try to recover. +/// The returned package configuration is a *best effort* attempt to create +/// a valid configuration from the invalid configuration file. +/// If no [onError] is provided, errors are thrown immediately. +/// /// Returns `null` if no configuration file is found. Future findPackageConfig(Directory directory, - {bool recurse = true}) => - discover.findPackageConfig(directory, recurse); + {bool recurse = true, void onError(Object error)}) => + discover.findPackageConfig(directory, recurse, onError ?? throwError); /// Finds a package configuration relative to [location]. /// @@ -124,10 +146,19 @@ Future findPackageConfig(Directory directory, /// As such, it does not distinguish between a file not existing, /// and it being temporarily locked or unreachable. /// +/// If [onError] is provided, the configuration file parsing will report errors +/// by calling that function, and then try to recover. +/// The returned package configuration is a *best effort* attempt to create +/// a valid configuration from the invalid configuration file. +/// If no [onError] is provided, errors are thrown immediately. +/// /// Returns `null` if no configuration file is found. Future findPackageConfigUri(Uri location, - {bool recurse = true, Future loader(Uri uri)}) => - discover.findPackageConfigUri(location, loader, recurse); + {bool recurse = true, + Future loader(Uri uri), + void onError(Object error)}) => + discover.findPackageConfigUri( + location, loader, onError ?? throwError, recurse); /// Writes a package configuration to the provided directory. /// diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index 5ad6ac54e..14033ed35 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -5,13 +5,11 @@ import "dart:io"; import 'dart:typed_data'; -import "package:path/path.dart" as p; - import "errors.dart"; import "package_config_impl.dart"; import "package_config_json.dart"; import "packages_file.dart" as packages_file; -import "util.dart" show defaultLoader; +import "util.dart" show defaultLoader, pathJoin; final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json"); final Uri dotPackagesPath = Uri(path: ".packages"); @@ -33,7 +31,7 @@ final Uri parentPath = Uri(path: ".."); /// Returns `null` if no configuration was found. If a configuration /// is needed, then the caller can supply [PackageConfig.empty]. Future findPackageConfig( - Directory baseDirectory, bool recursive) async { + Directory baseDirectory, bool recursive, void onError(Object error)) async { var directory = baseDirectory; if (!directory.isAbsolute) directory = directory.absolute; if (!await directory.exists()) { @@ -41,7 +39,7 @@ Future findPackageConfig( } do { // Check for $cwd/.packages - var packageConfig = await findPackagConfigInDirectory(directory); + var packageConfig = await findPackagConfigInDirectory(directory, onError); if (packageConfig != null) return packageConfig; if (!recursive) break; // Check in parent directories. @@ -53,16 +51,22 @@ Future findPackageConfig( } /// Similar to [findPackageConfig] but based on a URI. -Future findPackageConfigUri(Uri location, - Future loader(Uri uri) /*?*/, bool recursive) async { +Future findPackageConfigUri( + Uri location, + Future loader(Uri uri) /*?*/, + void onError(Object error) /*?*/, + bool recursive) async { if (location.isScheme("package")) { - throw PackageConfigArgumentError( - location, "location", "Must not be a package: URI"); + onError(PackageConfigArgumentError( + location, "location", "Must not be a package: URI")); + return null; } if (loader == null) { if (location.isScheme("file")) { return findPackageConfig( - Directory.fromUri(location.resolveUri(currentPath)), recursive); + Directory.fromUri(location.resolveUri(currentPath)), + recursive, + onError); } loader = defaultLoader; } @@ -71,12 +75,12 @@ Future findPackageConfigUri(Uri location, var file = location.resolveUri(packageConfigJsonPath); var bytes = await loader(file); if (bytes != null) { - return parsePackageConfigBytes(bytes, file); + return parsePackageConfigBytes(bytes, file, onError); } file = location.resolveUri(dotPackagesPath); bytes = await loader(file); if (bytes != null) { - return packages_file.parse(bytes, file); + return packages_file.parse(bytes, file, onError); } if (!recursive) break; var parent = location.resolveUri(parentPath); @@ -90,33 +94,35 @@ Future findPackageConfigUri(Uri location, /// /// Loads the file, if it is there, and returns the resulting [PackageConfig]. /// Returns `null` if the file isn't there. -/// Throws [FormatException] if a file is there but is not valid. +/// Reports a [FormatException] if a file is there but the content is not valid. +/// If the file exists, but fails to be read, the file system error is reported. /// -/// If [extraData] is supplied and the `package_config.json` contains extra -/// entries in the top JSON object, those extra entries are stored into -/// [extraData]. +/// If [onError] is supplied, parsing errors are reported using that, and +/// a best-effort attempt is made to return a package configuration. +/// This may be the empty package configuration. Future findPackagConfigInDirectory( - Directory directory) async { + Directory directory, void onError(Object error)) async { var packageConfigFile = await checkForPackageConfigJsonFile(directory); if (packageConfigFile != null) { - return await readPackageConfigJsonFile(packageConfigFile); + return await readPackageConfigJsonFile(packageConfigFile, onError); } packageConfigFile = await checkForDotPackagesFile(directory); if (packageConfigFile != null) { - return await readDotPackagesFile(packageConfigFile); + return await readDotPackagesFile(packageConfigFile, onError); } return null; } Future /*?*/ checkForPackageConfigJsonFile(Directory directory) async { assert(directory.isAbsolute); - var file = File(p.join(directory.path, ".dart_tool", "package_config.json")); + var file = + File(pathJoin(directory.path, ".dart_tool", "package_config.json")); if (await file.exists()) return file; return null; } Future checkForDotPackagesFile(Directory directory) async { - var file = File(p.join(directory.path, ".packages")); + var file = File(pathJoin(directory.path, ".packages")); if (await file.exists()) return file; return null; } diff --git a/pkgs/package_config/lib/src/errors.dart b/pkgs/package_config/lib/src/errors.dart index 6c31ccea1..c9736177c 100644 --- a/pkgs/package_config/lib/src/errors.dart +++ b/pkgs/package_config/lib/src/errors.dart @@ -1,24 +1,33 @@ -// Copyright (c) 2019, 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. - -/// General superclass of most errors and exceptions thrown by this package. -/// -/// Only covers errors thrown while parsing package configuration files. -/// Programming errors and I/O exceptions are not covered. -abstract class PackageConfigError { - PackageConfigError._(); -} - -class PackageConfigArgumentError extends ArgumentError - implements PackageConfigError { - PackageConfigArgumentError(Object /*?*/ value, String name, String message) - : super.value(value, name, message); -} - -class PackageConfigFormatException extends FormatException - implements PackageConfigError { - PackageConfigFormatException(String message, Object /*?*/ value, - [int /*?*/ index]) - : super(message, value, index); -} +// Copyright (c) 2019, 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. + +/// General superclass of most errors and exceptions thrown by this package. +/// +/// Only covers errors thrown while parsing package configuration files. +/// Programming errors and I/O exceptions are not covered. +abstract class PackageConfigError { + PackageConfigError._(); +} + +class PackageConfigArgumentError extends ArgumentError + implements PackageConfigError { + PackageConfigArgumentError(Object /*?*/ value, String name, String message) + : super.value(value, name, message); + + PackageConfigArgumentError.from(ArgumentError error) + : super.value(error.invalidValue, error.name, error.message); +} + +class PackageConfigFormatException extends FormatException + implements PackageConfigError { + PackageConfigFormatException(String message, Object /*?*/ source, + [int /*?*/ offset]) + : super(message, source, offset); + + PackageConfigFormatException.from(FormatException exception) + : super(exception.message, exception.source, exception.offset); +} + +/// The default `onError` handler. +void /*Never*/ throwError(Object error) => throw error; diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index f7b96b8a5..08c4a9691 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -2,6 +2,7 @@ // 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 'errors.dart'; import "package_config_impl.dart"; /// A package configuration. @@ -34,7 +35,7 @@ abstract class PackageConfig { /// /// The version of the resulting configuration is always [maxVersion]. factory PackageConfig(Iterable packages, {dynamic extraData}) => - SimplePackageConfig(maxVersion, packages); + SimplePackageConfig(maxVersion, packages, extraData); /// The configuration version number. /// @@ -124,9 +125,10 @@ abstract class Package { /// [Package.extraData] of the created package. factory Package(String name, Uri root, {Uri /*?*/ packageUriRoot, - String /*?*/ languageVersion, + LanguageVersion /*?*/ languageVersion, dynamic extraData}) => - SimplePackage(name, root, packageUriRoot, languageVersion, extraData); + SimplePackage.validate( + name, root, packageUriRoot, languageVersion, extraData, throwError); /// The package-name of the package. String get name; @@ -156,16 +158,9 @@ abstract class Package { /// Each package may have a default language version associated, /// which is the language version used to parse and compile /// Dart files in the package. - /// A package version is always of the form: - /// - /// * A numeral consisting of one or more decimal digits, - /// with no leading zero unless the entire numeral is a single zero digit. - /// * Followed by a `.` character. - /// * Followed by another numeral of the same form. - /// - /// There is no whitespace allowed around the numerals. - /// Valid version numbers include `2.5`, `3.0`, and `1234.5678`. - String /*?*/ get languageVersion; + /// A package version is defined by two non-negative numbers, + /// the *major* and *minor* version numbers. + LanguageVersion /*?*/ get languageVersion; /// Extra data associated with the specific package. /// @@ -174,3 +169,104 @@ abstract class Package { /// JSON-like list/map data structures. dynamic get extraData; } + +/// A language version. +/// +/// A language version is represented by two non-negative integers, +/// the [major] and [minor] version numbers. +/// +/// If errors during parsing are handled using an `onError` handler, +/// then an *invalid* language version may be represented by an +/// [InvalidLanguageVersion] object. +abstract class LanguageVersion implements Comparable { + /// The maximal value allowed by [major] and [minor] values; + static const int maxValue = 0x7FFFFFFF; + factory LanguageVersion(int major, int minor) { + RangeError.checkValueInInterval(major, 0, maxValue, "major"); + RangeError.checkValueInInterval(minor, 0, maxValue, "major"); + return SimpleLanguageVersion(major, minor, null); + } + + /// Parses a language version string. + /// + /// A valid language version string has the form + /// + /// > *decimalNumber* `.` *decimalNumber* + /// + /// where a *decimalNumber* is a non-empty sequence of decimal digits + /// with no unnecessary leading zeros (the decimal number only starts + /// with a zero digit if that digit is the entire number). + /// No spaces are allowed in the string. + /// + /// If the [source] is valid then it is parsed into a valid + /// [LanguageVersion] object. + /// If not, then the [onError] is called with a [FormatException]. + /// If [onError] is not supplied, it defaults to throwing the exception. + /// If the call does not throw, then an [InvalidLanguageVersion] is returned + /// containing the original [source]. + static LanguageVersion parse(String source, {void onError(Object error)}) => + parseLanguageVersion(source, onError ?? throwError); + + /// The major language version. + /// + /// A non-negative integer less than 231. + /// + /// The value is negative for objects representing *invalid* language + /// versions ([InvalidLanguageVersion]). + int get major; + + /// The minor language version. + /// + /// A non-negative integer less than 231. + /// + /// The value is negative for objects representing *invalid* language + /// versions ([InvalidLanguageVersion]). + int get minor; + + /// Compares language versions. + /// + /// Two language versions are considered equal if they have the + /// same major and minor version numbers. + /// + /// A language version is greater then another if the former's major version + /// is greater than the latter's major version, or if they have + /// the same major version and the former's minor version is greater than + /// the latter's. + int compareTo(LanguageVersion other); + + /// Valid language versions with the same [major] and [minor] values are + /// equal. + /// + /// Invalid language versions ([InvalidLanguageVersion]) are not equal to + /// any other object. + bool operator ==(Object other); + + int get hashCode; + + /// A string representation of the language version. + /// + /// A valid language version is represented as + /// `"${version.major}.${version.minor}"`. + String toString(); +} + +/// An *invalid* language version. +/// +/// Stored in a [Package] when the orginal language version string +/// was invalid and a `onError` handler was passed to the parser +/// which did not throw on an error. +abstract class InvalidLanguageVersion implements LanguageVersion { + /// The value -1 for an invalid language version. + int get major; + + /// The value -1 for an invalid language version. + int get minor; + + /// An invalid language version is only equal to itself. + bool operator ==(Object other); + + int get hashCode; + + /// The original invalid version string. + String toString(); +} diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 62579610c..39633fe4b 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -14,16 +14,18 @@ class SimplePackageConfig implements PackageConfig { final PackageTree _packageTree; final dynamic extraData; - SimplePackageConfig(int version, Iterable packages, - [dynamic extraData]) - : this._(_validateVersion(version), packages, - [...packages]..sort(_compareRoot), extraData); + factory SimplePackageConfig(int version, Iterable packages, + [dynamic extraData, void onError(Object error)]) { + onError ??= throwError; + var validVersion = _validateVersion(version, onError); + var sortedPackages = [...packages]..sort(_compareRoot); + var packageTree = _validatePackages(packages, sortedPackages, onError); + return SimplePackageConfig._(validVersion, packageTree, + {for (var p in packageTree.allPackages) p.name: p}, extraData); + } - /// Expects a list of [packages] sorted on root path. - SimplePackageConfig._(this.version, Iterable originalPackages, - List packages, this.extraData) - : _packageTree = _validatePackages(originalPackages, packages), - _packages = {for (var p in packages) p.name: p}; + SimplePackageConfig._( + this.version, this._packageTree, this._packages, this.extraData); /// Creates empty configuration. /// @@ -35,66 +37,78 @@ class SimplePackageConfig implements PackageConfig { _packages = const {}, extraData = null; - static int _validateVersion(int version) { + static int _validateVersion(int version, void onError(Object error)) { if (version < 0 || version > PackageConfig.maxVersion) { - throw PackageConfigArgumentError(version, "version", - "Must be in the range 1 to ${PackageConfig.maxVersion}"); + onError(PackageConfigArgumentError(version, "version", + "Must be in the range 1 to ${PackageConfig.maxVersion}")); + return 2; // The minimal version supporting a SimplePackageConfig. } return version; } - static PackageTree _validatePackages( - Iterable originalPackages, List packages) { - // Assumes packages are sorted. - Map result = {}; + static PackageTree _validatePackages(Iterable originalPackages, + List packages, void onError(Object error)) { + var packageNames = {}; var tree = MutablePackageTree(); - SimplePackage package; for (var originalPackage in packages) { + if (originalPackage == null) { + onError(ArgumentError.notNull("element of packages")); + continue; + } + SimplePackage package; if (originalPackage is! SimplePackage) { // SimplePackage validates these properties. - try { - package = SimplePackage( - originalPackage.name, - originalPackage.root, - originalPackage.packageUriRoot, - originalPackage.languageVersion, - originalPackage.extraData); - } catch (e) { - throw PackageConfigArgumentError( - packages, "packages", "Package ${package.name}: ${e.message}"); - } + package = SimplePackage.validate( + originalPackage.name, + originalPackage.root, + originalPackage.packageUriRoot, + originalPackage.languageVersion, + originalPackage.extraData, (error) { + if (error is PackageConfigArgumentError) { + onError(PackageConfigArgumentError(packages, "packages", + "Package ${package.name}: ${error.message}")); + } else { + onError(error); + } + }); + if (package == null) continue; } else { package = originalPackage; } var name = package.name; - if (result.containsKey(name)) { - throw PackageConfigArgumentError( - name, "packages", "Duplicate package name"); + if (packageNames.contains(name)) { + onError(PackageConfigArgumentError( + name, "packages", "Duplicate package name")); + continue; } - result[name] = package; - try { - tree.add(0, package); - } on ConflictException catch (e) { - // There is a conflict with an existing package. - var existingPackage = e.existingPackage; - if (e.isRootConflict) { - throw PackageConfigArgumentError( - originalPackages, - "packages", - "Packages ${package.name} and ${existingPackage.name}" - "have the same root directory: ${package.root}.\n"); + packageNames.add(name); + tree.add(0, package, (error) { + if (error is ConflictException) { + // There is a conflict with an existing package. + var existingPackage = error.existingPackage; + if (error.isRootConflict) { + onError(PackageConfigArgumentError( + originalPackages, + "packages", + "Packages ${package.name} and ${existingPackage.name}" + "have the same root directory: ${package.root}.\n")); + } else { + assert(error.isPackageRootConflict); + // Package is inside the package URI root of the existing package. + onError(PackageConfigArgumentError( + originalPackages, + "packages", + "Package ${package.name} is inside the package URI root of " + "package ${existingPackage.name}.\n" + "${existingPackage.name} URI root: " + "${existingPackage.packageUriRoot}\n" + "${package.name} root: ${package.root}\n")); + } + } else { + // Any other error. + onError(error); } - assert(e.isPackageRootConflict); - // Or package is inside the package URI root of the existing package. - throw PackageConfigArgumentError( - originalPackages, - "packages", - "Package ${package.name} is inside the package URI root of " - "package ${existingPackage.name}.\n" - "${existingPackage.name} URI root: " - "${existingPackage.packageUriRoot}\n" - "${package.name} root: ${package.root}\n"); - } + }); } return tree; } @@ -145,7 +159,7 @@ class SimplePackage implements Package { final String name; final Uri root; final Uri packageUriRoot; - final String /*?*/ languageVersion; + final LanguageVersion /*?*/ languageVersion; final dynamic extraData; SimplePackage._(this.name, this.root, this.packageUriRoot, @@ -154,45 +168,175 @@ class SimplePackage implements Package { /// Creates a [SimplePackage] with the provided content. /// /// The provided arguments must be valid. - factory SimplePackage(String name, Uri root, Uri packageUriRoot, - String /*?*/ languageVersion, dynamic extraData) { - _validatePackageData(name, root, packageUriRoot, languageVersion); + /// + /// If the arguments are invalid then the error is reported by + /// calling [onError], then the erroneous entry is ignored. + /// + /// If [onError] is provided, the user is expected to be able to handle + /// errors themselves. An invalid [languageVersion] string + /// will be replaced with the string `"invalid"`. This allows + /// users to detect the difference between an absent version and + /// an invalid one. + /// + /// Returns `null` if the input is invalid and an approximately valid package + /// cannot be salvaged from the input. + static SimplePackage /*?*/ validate( + String name, + Uri root, + Uri packageUriRoot, + LanguageVersion /*?*/ languageVersion, + dynamic extraData, + void onError(Object error)) { + bool fatalError = false; + var invalidIndex = checkPackageName(name); + if (invalidIndex >= 0) { + onError(PackageConfigFormatException( + "Not a valid package name", name, invalidIndex)); + fatalError = true; + } + if (root.isScheme("package")) { + onError(PackageConfigArgumentError( + "$root", "root", "Must not be a package URI")); + fatalError = true; + } else if (!isAbsoluteDirectoryUri(root)) { + onError(PackageConfigArgumentError( + "$root", + "root", + "In package $name: Not an absolute URI with no query or fragment " + "with a path ending in /")); + // Try to recover. If the URI has a scheme, + // then ensure that the path ends with `/`. + if (!root.hasScheme) { + fatalError = true; + } else if (!root.path.endsWith("/")) { + root = root.replace(path: root.path + "/"); + } + } + if (!fatalError) { + if (!isAbsoluteDirectoryUri(packageUriRoot)) { + onError(PackageConfigArgumentError( + packageUriRoot, + "packageUriRoot", + "In package $name: Not an absolute URI with no query or fragment " + "with a path ending in /")); + packageUriRoot = root; + } else if (!isUriPrefix(root, packageUriRoot)) { + onError(PackageConfigArgumentError(packageUriRoot, "packageUriRoot", + "The package URI root is not below the package root")); + packageUriRoot = root; + } + } + if (fatalError) return null; return SimplePackage._( name, root, packageUriRoot, languageVersion, extraData); } } -void _validatePackageData( - String name, Uri root, Uri packageUriRoot, String /*?*/ languageVersion) { - if (!isValidPackageName(name)) { - throw PackageConfigArgumentError(name, "name", "Not a valid package name"); +/// Checks whether [version] is a valid Dart language version string. +/// +/// The format is (as RegExp) `^(0|[1-9]\d+)\.(0|[1-9]\d+)$`. +/// +/// Reports a format exception on [onError] if not, or if the numbers +/// are too large (at most 32-bit signed integers). +LanguageVersion parseLanguageVersion( + String source, void onError(Object error)) { + var index = 0; + // Reads a positive decimal numeral. Returns the value of the numeral, + // or a negative number in case of an error. + // Starts at [index] and increments the index to the position after + // the numeral. + // It is an error if the numeral value is greater than 0x7FFFFFFFF. + // It is a recoverable error if the numeral starts with leading zeros. + int readNumeral() { + const maxValue = 0x7FFFFFFF; + if (index == source.length) { + onError(PackageConfigFormatException("Missing number", source, index)); + return -1; + } + var start = index; + + var char = source.codeUnitAt(index); + var digit = char ^ 0x30; + if (digit > 9) { + onError(PackageConfigFormatException("Missing number", source, index)); + return -1; + } + var firstDigit = digit; + var value = 0; + do { + value = value * 10 + digit; + if (value > maxValue) { + onError( + PackageConfigFormatException("Number too large", source, start)); + return -1; + } + index++; + if (index == source.length) break; + char = source.codeUnitAt(index); + digit = char ^ 0x30; + } while (digit <= 9); + if (firstDigit == 0 && index > start + 1) { + onError(PackageConfigFormatException( + "Leading zero not allowed", source, start)); + } + return value; + } + + var major = readNumeral(); + if (major < 0) { + return SimpleInvalidLanguageVersion(source); } - if (!isAbsoluteDirectoryUri(root)) { - throw PackageConfigArgumentError( - "$root", - "root", - "Not an absolute URI with no query or fragment " - "with a path ending in /"); + if (index == source.length || source.codeUnitAt(index) != $dot) { + onError(PackageConfigFormatException("Missing '.'", source, index)); + return SimpleInvalidLanguageVersion(source); } - if (!isAbsoluteDirectoryUri(packageUriRoot)) { - throw PackageConfigArgumentError( - packageUriRoot, - "packageUriRoot", - "Not an absolute URI with no query or fragment " - "with a path ending in /"); + index++; + var minor = readNumeral(); + if (minor < 0) { + return SimpleInvalidLanguageVersion(source); } - if (!isUriPrefix(root, packageUriRoot)) { - throw PackageConfigArgumentError(packageUriRoot, "packageUriRoot", - "The package URI root is not below the package root"); + if (index != source.length) { + onError(PackageConfigFormatException( + "Unexpected trailing character", source, index)); + return SimpleInvalidLanguageVersion(source); } - if (languageVersion != null && - checkValidVersionNumber(languageVersion) >= 0) { - throw PackageConfigArgumentError( - languageVersion, "languageVersion", "Invalid language version format"); + return SimpleLanguageVersion(major, minor, source); +} + +abstract class _SimpleLanguageVersionBase implements LanguageVersion { + int compareTo(LanguageVersion other) { + int result = major.compareTo(other.major); + if (result != 0) return result; + return minor.compareTo(other.minor); } } +class SimpleLanguageVersion extends _SimpleLanguageVersionBase { + final int major; + final int minor; + String /*?*/ _source; + SimpleLanguageVersion(this.major, this.minor, this._source); + + bool operator ==(Object other) => + other is LanguageVersion && major == other.major && minor == other.minor; + + int get hashCode => (major * 17 ^ minor * 37) & 0x3FFFFFFF; + + String toString() => _source ??= "$major.$minor"; +} + +class SimpleInvalidLanguageVersion extends _SimpleLanguageVersionBase + implements InvalidLanguageVersion { + final String _source; + SimpleInvalidLanguageVersion(this._source); + int get major => -1; + int get minor => -1; + + String toString() => _source; +} + abstract class PackageTree { + Iterable get allPackages; SimplePackage /*?*/ packageOf(Uri file); } @@ -210,13 +354,24 @@ class MutablePackageTree implements PackageTree { final List packages = []; Map /*?*/ _packageChildren; + Iterable get allPackages sync* { + for (var package in packages) yield package; + if (_packageChildren != null) { + for (var tree in _packageChildren.values) yield* tree.allPackages; + } + } + /// Tries to (add) `package` to the tree. /// - /// Throws [ConflictException] if the added package conflicts with an + /// Reports a [ConflictException] if the added package conflicts with an /// existing package. /// It conflicts if it has the same root path, or if the new package /// contains the existing package's package root. - void add(int start, SimplePackage package) { + /// + /// If a conflict is detected between [package] and a previous package, + /// then [onError] is called with a [ConflictException] object + /// and the [package] is not added to the tree. + void add(int start, SimplePackage package, void onError(Object error)) { var path = package.root.toString(); for (var childPackage in packages) { var childPath = childPackage.root.toString(); @@ -225,13 +380,15 @@ class MutablePackageTree implements PackageTree { if (_beginsWith(start, childPath, path)) { var childPathLength = childPath.length; if (path.length == childPathLength) { - throw ConflictException.root(package, childPackage); + onError(ConflictException.root(package, childPackage)); + return; } var childPackageRoot = childPackage.packageUriRoot.toString(); if (_beginsWith(childPathLength, childPackageRoot, path)) { - throw ConflictException.packageRoot(package, childPackage); + onError(ConflictException.packageRoot(package, childPackage)); + return; } - _treeOf(childPackage).add(childPathLength, package); + _treeOf(childPackage).add(childPathLength, package, onError); return; } } @@ -286,6 +443,8 @@ class MutablePackageTree implements PackageTree { class EmptyPackageTree implements PackageTree { const EmptyPackageTree(); + Iterable get allPackages => const Iterable.empty(); + SimplePackage packageOf(Uri file) => null; } diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index 8108102bd..f56c91271 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -6,9 +6,6 @@ import "dart:convert"; import "dart:io"; import "dart:typed_data"; -import 'package:charcode/ascii.dart'; -import "package:path/path.dart" as p; - import "discovery.dart" show packageConfigJsonPath; import "errors.dart"; import "package_config_impl.dart"; @@ -45,41 +42,66 @@ const String _generatorVersionKey = "generatorVersion"; /// a `.packages` file and there is an available `package_config.json` file. /// /// The file must exist and be a normal file. -Future readAnyConfigFile(File file, bool preferNewest) async { - var bytes = await file.readAsBytes(); +Future readAnyConfigFile( + File file, bool preferNewest, void onError(Object error)) async { + Uint8List bytes; + try { + bytes = await file.readAsBytes(); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } int firstChar = firstNonWhitespaceChar(bytes); if (firstChar != $lbrace) { // Definitely not a JSON object, probably a .packages. if (preferNewest) { var alternateFile = File( - p.join(p.dirname(file.path), ".dart_tool", "package_config.json")); + pathJoin(dirName(file.path), ".dart_tool", "package_config.json")); if (alternateFile.existsSync()) { - return parsePackageConfigBytes( - await alternateFile.readAsBytes(), alternateFile.uri); + Uint8List /*?*/ bytes; + try { + bytes = await alternateFile.readAsBytes(); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } + if (bytes != null) { + return parsePackageConfigBytes(bytes, alternateFile.uri, onError); + } } } - return packages_file.parse(bytes, file.uri); + return packages_file.parse(bytes, file.uri, onError); } - return parsePackageConfigBytes(bytes, file.uri); + return parsePackageConfigBytes(bytes, file.uri, onError); } /// Like [readAnyConfigFile] but uses a URI and an optional loader. -Future readAnyConfigFileUri(Uri file, - Future loader(Uri uri) /*?*/, bool preferNewest) async { +Future readAnyConfigFileUri( + Uri file, + Future loader(Uri uri) /*?*/, + void onError(Object error), + bool preferNewest) async { if (file.isScheme("package")) { throw PackageConfigArgumentError( file, "file", "Must not be a package: URI"); } if (loader == null) { if (file.isScheme("file")) { - return readAnyConfigFile(File.fromUri(file), preferNewest); + return readAnyConfigFile(File.fromUri(file), preferNewest, onError); } loader = defaultLoader; } - var bytes = await loader(file); + Uint8List bytes; + try { + bytes = await loader(file); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } if (bytes == null) { - throw PackageConfigArgumentError( - file.toString(), "file", "File cannot be read"); + onError(PackageConfigArgumentError( + file.toString(), "file", "File cannot be read")); + return const SimplePackageConfig.empty(); } int firstChar = firstNonWhitespaceChar(bytes); if (firstChar != $lbrace) { @@ -87,39 +109,59 @@ Future readAnyConfigFileUri(Uri file, if (preferNewest) { // Check if there is a package_config.json file. var alternateFile = file.resolveUri(packageConfigJsonPath); - var alternateBytes = await loader(alternateFile); + Uint8List alternateBytes; + try { + alternateBytes = await loader(alternateFile); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } if (alternateBytes != null) { - return parsePackageConfigBytes(alternateBytes, alternateFile); + return parsePackageConfigBytes(alternateBytes, alternateFile, onError); } } - return packages_file.parse(bytes, file); + return packages_file.parse(bytes, file, onError); } - return parsePackageConfigBytes(bytes, file); + return parsePackageConfigBytes(bytes, file, onError); } -Future readPackageConfigJsonFile(File file) async { +Future readPackageConfigJsonFile( + File file, void onError(Object error)) async { Uint8List bytes; try { bytes = await file.readAsBytes(); - } catch (_) { - return null; + } catch (error) { + onError(error); + return const SimplePackageConfig.empty(); } - return parsePackageConfigBytes(bytes, file.uri); + return parsePackageConfigBytes(bytes, file.uri, onError); } -Future readDotPackagesFile(File file) async { +Future readDotPackagesFile( + File file, void onError(Object error)) async { Uint8List bytes; try { bytes = await file.readAsBytes(); - } catch (_) { - return null; + } catch (error) { + onError(error); + return const SimplePackageConfig.empty(); } - return packages_file.parse(bytes, file.uri); + return packages_file.parse(bytes, file.uri, onError); } -PackageConfig parsePackageConfigBytes(Uint8List bytes, Uri file) { +final _jsonUtf8Decoder = json.fuse(utf8).decoder; + +PackageConfig parsePackageConfigBytes( + Uint8List bytes, Uri file, void onError(Object error)) { // TODO(lrn): Make this simpler. Maybe parse directly from bytes. - return parsePackageConfigJson(json.fuse(utf8).decode(bytes), file); + var jsonObject; + try { + jsonObject = _jsonUtf8Decoder.convert(bytes); + } on FormatException catch (e) { + onError(PackageConfigFormatException(e.message, e.source, e.offset)); + return const SimplePackageConfig.empty(); + } + return parsePackageConfigJson(jsonObject, file, onError); } /// Creates a [PackageConfig] from a parsed JSON-like object structure. @@ -144,7 +186,8 @@ PackageConfig parsePackageConfigBytes(Uint8List bytes, Uri file) { /// /// The [baseLocation] is used as base URI to resolve the "rootUri" /// URI referencestring. -PackageConfig parsePackageConfigJson(dynamic json, Uri baseLocation) { +PackageConfig parsePackageConfigJson( + dynamic json, Uri baseLocation, void onError(Object error)) { if (!baseLocation.hasScheme || baseLocation.isScheme("package")) { throw PackageConfigArgumentError(baseLocation.toString(), "baseLocation", "Must be an absolute non-package: URI"); @@ -168,27 +211,34 @@ PackageConfig parsePackageConfigJson(dynamic json, Uri baseLocation) { var message = "$name${packageName != null ? " of package $packageName" : ""}" " is not a JSON ${typeName()}"; - throw PackageConfigFormatException(message, value); + onError(PackageConfigFormatException(message, value)); + return null; } - Package parsePackage(Map entry) { + Package /*?*/ parsePackage(Map entry) { String /*?*/ name; String /*?*/ rootUri; String /*?*/ packageUri; String /*?*/ languageVersion; Map /*?*/ extraData; + bool hasName = false; + bool hasRoot = false; + bool hasVersion = false; entry.forEach((key, value) { switch (key) { case _nameKey: + hasName = true; name = checkType(value, _nameKey); break; case _rootUriKey: + hasRoot = true; rootUri = checkType(value, _rootUriKey, name); break; case _packageUriKey: packageUri = checkType(value, _packageUriKey, name); break; case _languageVersionKey: + hasVersion = true; languageVersion = checkType(value, _languageVersionKey, name); break; default: @@ -196,37 +246,61 @@ PackageConfig parsePackageConfigJson(dynamic json, Uri baseLocation) { break; } }); - if (name == null) { - throw PackageConfigFormatException("Missing name entry", entry); + if (!hasName) { + onError(PackageConfigFormatException("Missing name entry", entry)); } - if (rootUri == null) { - throw PackageConfigFormatException("Missing rootUri entry", entry); + if (!hasRoot) { + onError(PackageConfigFormatException("Missing rootUri entry", entry)); } + if (name == null || rootUri == null) return null; Uri root = baseLocation.resolve(rootUri); - Uri /*?*/ packageRoot = root; + if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/"); + Uri packageRoot = root; if (packageUri != null) packageRoot = root.resolve(packageUri); - try { - return SimplePackage(name, root, packageRoot, languageVersion, extraData); - } on ArgumentError catch (e) { - throw PackageConfigFormatException(e.message, e.invalidValue); + if (!packageRoot.path.endsWith("/")) { + packageRoot = packageRoot.replace(path: packageRoot.path + "/"); + } + + LanguageVersion /*?*/ version; + if (languageVersion != null) { + version = parseLanguageVersion(languageVersion, onError); + } else if (hasVersion) { + version = SimpleInvalidLanguageVersion("invalid"); } + + return SimplePackage.validate(name, root, packageRoot, version, extraData, + (error) { + if (error is ArgumentError) { + onError( + PackageConfigFormatException(error.message, error.invalidValue)); + } else { + onError(error); + } + }); } var map = checkType>(json, "value"); + if (map == null) return const SimplePackageConfig.empty(); Map /*?*/ extraData = null; List /*?*/ packageList; int /*?*/ configVersion; map.forEach((key, value) { switch (key) { case _configVersionKey: - configVersion = checkType(value, _configVersionKey); + configVersion = checkType(value, _configVersionKey) ?? 2; break; case _packagesKey: - var packageArray = checkType>(value, _packagesKey); + var packageArray = checkType>(value, _packagesKey) ?? []; var packages = []; for (var package in packageArray) { - packages.add(parsePackage( - checkType>(package, "package entry"))); + var packageMap = + checkType>(package, "package entry"); + if (packageMap != null) { + var entry = parsePackage(packageMap); + if (entry != null) { + packages.add(entry); + } + } } packageList = packages; break; @@ -236,22 +310,27 @@ PackageConfig parsePackageConfigJson(dynamic json, Uri baseLocation) { } }); if (configVersion == null) { - throw PackageConfigFormatException("Missing configVersion entry", json); + onError(PackageConfigFormatException("Missing configVersion entry", json)); + configVersion = 2; } - if (packageList == null) - throw PackageConfigFormatException("Missing packages list", json); - try { - return SimplePackageConfig(configVersion, packageList, extraData); - } on ArgumentError catch (e) { - throw PackageConfigFormatException(e.message, e.invalidValue); + if (packageList == null) { + onError(PackageConfigFormatException("Missing packages list", json)); + packageList = []; } + return SimplePackageConfig(configVersion, packageList, extraData, (error) { + if (error is ArgumentError) { + onError(PackageConfigFormatException(error.message, error.invalidValue)); + } else { + onError(error); + } + }); } Future writePackageConfigJson( PackageConfig config, Directory targetDirectory) async { // Write .dart_tool/package_config.json first. var file = - File(p.join(targetDirectory.path, ".dart_tool", "package_config.json")); + File(pathJoin(targetDirectory.path, ".dart_tool", "package_config.json")); var baseUri = file.uri; var extraData = config.extraData; var data = { @@ -263,8 +342,9 @@ Future writePackageConfigJson( _rootUriKey: relativizeUri(package.root, baseUri), if (package.root != package.packageUriRoot) _packageUriKey: relativizeUri(package.packageUriRoot, package.root), - if (package.languageVersion != null) - _languageVersionKey: package.languageVersion, + if (package.languageVersion != null && + package.languageVersion is! InvalidLanguageVersion) + _languageVersionKey: package.languageVersion.toString(), ...?_extractExtraData(package.extraData, _packageNames), } ], @@ -283,7 +363,7 @@ Future writePackageConfigJson( "${generated != null ? " on $generated" : ""}."; } } - file = File(p.join(targetDirectory.path, ".packages")); + file = File(pathJoin(targetDirectory.path, ".packages")); baseUri = file.uri; var buffer = StringBuffer(); packages_file.write(buffer, config, baseUri: baseUri, comment: comment); diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index ac57b4f15..475a782a2 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -3,9 +3,8 @@ // BSD-style license that can be found in the LICENSE file. import "package_config_impl.dart"; -import "package:charcode/ascii.dart"; -import "util.dart" show isValidPackageName, relativizeUri; +import "util.dart"; import "errors.dart"; /// Parses a `.packages` file into a [PackageConfig]. @@ -25,16 +24,18 @@ import "errors.dart"; /// Returns a simple package configuration where each package's /// [Package.packageUriRoot] is the same as its [Package.root] /// and it has no [Package.languageVersion]. -PackageConfig parse(List source, Uri baseLocation) { +PackageConfig parse( + List source, Uri baseLocation, void onError(Object error)) { if (baseLocation.isScheme("package")) { - throw PackageConfigArgumentError( - baseLocation, "baseLocation", "Must not be a package: URI"); + onError(PackageConfigArgumentError( + baseLocation, "baseLocation", "Must not be a package: URI")); + return PackageConfig.empty; } int index = 0; List packages = []; Set packageNames = {}; while (index < source.length) { - bool isComment = false; + bool ignoreLine = false; int start = index; int separatorIndex = -1; int end = source.length; @@ -43,10 +44,14 @@ PackageConfig parse(List source, Uri baseLocation) { continue; } if (char == $colon) { - throw PackageConfigFormatException( - "Missing package name", source, index - 1); + onError(PackageConfigFormatException( + "Missing package name", source, index - 1)); + ignoreLine = true; // Ignore if package name is invalid. + } else { + ignoreLine = char == $hash; // Ignore if comment. } - isComment = char == $hash; + int queryStart = -1; + int fragmentStart = -1; while (index < source.length) { char = source[index++]; if (char == $colon && separatorIndex < 0) { @@ -54,40 +59,70 @@ PackageConfig parse(List source, Uri baseLocation) { } else if (char == $cr || char == $lf) { end = index - 1; break; + } else if (char == $question && queryStart < 0 && fragmentStart < 0) { + queryStart = index - 1; + } else if (char == $hash && fragmentStart < 0) { + fragmentStart = index - 1; } } - if (isComment) continue; + if (ignoreLine) continue; if (separatorIndex < 0) { - throw PackageConfigFormatException("No ':' on line", source, index - 1); + onError( + PackageConfigFormatException("No ':' on line", source, index - 1)); + continue; } var packageName = String.fromCharCodes(source, start, separatorIndex); - if (!isValidPackageName(packageName)) { - throw PackageConfigFormatException( - "Not a valid package name", packageName, 0); + int invalidIndex = checkPackageName(packageName); + if (invalidIndex >= 0) { + onError(PackageConfigFormatException( + "Not a valid package name", source, start + invalidIndex)); + continue; + } + if (queryStart >= 0) { + onError(PackageConfigFormatException( + "Location URI must not have query", source, queryStart)); + end = queryStart; + } else if (fragmentStart >= 0) { + onError(PackageConfigFormatException( + "Location URI must not have fragment", source, fragmentStart)); + end = fragmentStart; } var packageValue = String.fromCharCodes(source, separatorIndex + 1, end); - Uri packageLocation = baseLocation.resolve(packageValue); - if (packageLocation.isScheme("package")) { - throw PackageConfigFormatException( - "Package URI as location for package", source, separatorIndex + 1); + Uri packageLocation; + try { + packageLocation = baseLocation.resolve(packageValue); + } on FormatException catch (e) { + onError(PackageConfigFormatException.from(e)); + continue; } - if (packageLocation.hasQuery || packageLocation.hasFragment) { - throw PackageConfigFormatException( - "Location URI must not have query or fragment", source, start); + if (packageLocation.isScheme("package")) { + onError(PackageConfigFormatException( + "Package URI as location for package", source, separatorIndex + 1)); + continue; } if (!packageLocation.path.endsWith('/')) { packageLocation = packageLocation.replace(path: packageLocation.path + "/"); } if (packageNames.contains(packageName)) { - throw PackageConfigFormatException( - "Same package name occured more than once", source, start); + onError(PackageConfigFormatException( + "Same package name occured more than once", source, start)); + continue; + } + var package = SimplePackage.validate( + packageName, packageLocation, packageLocation, null, null, (error) { + if (error is ArgumentError) { + onError(PackageConfigFormatException(error.message, source)); + } else { + onError(error); + } + }); + if (package != null) { + packages.add(package); + packageNames.add(packageName); } - packages.add(SimplePackage( - packageName, packageLocation, packageLocation, null, null)); - packageNames.add(packageName); } - return SimplePackageConfig(1, packages, null); + return SimplePackageConfig(1, packages, null, onError); } /// Writes the configuration to a [StringSink]. @@ -137,7 +172,7 @@ void write(StringSink output, PackageConfig config, } output.write(packageName); output.write(':'); - // If baseUri provided, make uri relative. + // If baseUri is provided, make the URI relative to baseUri. if (baseUri != null) { uri = relativizeUri(uri, baseUri); } diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 25d7b89e4..2609a2f8a 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -8,8 +8,6 @@ library package_config.util; import 'dart:io'; import 'dart:typed_data'; -import "package:charcode/ascii.dart"; - import "errors.dart"; // All ASCII characters that are valid in a package name, with space @@ -46,6 +44,11 @@ int checkPackageName(String string) { } /// Validate that a [Uri] is a valid `package:` URI. +/// +/// Used to validate user input. +/// +/// Returns the package name extracted from the package URI, +/// which is the path segment between `package:` and the first `/`. String checkValidPackageUri(Uri packageUri, String name) { if (packageUri.scheme != "package") { throw PackageConfigArgumentError(packageUri, name, "Not a package: URI"); @@ -100,65 +103,16 @@ String checkValidPackageUri(Uri packageUri, String name) { return packageName; } -/// Checks whether [version] is a valid Dart language version string. -/// -/// The format is (as RegExp) `^(0|[1-9]\d+)\.(0|[1-9]\d+)$`. -/// -/// Returns the position of the first invalid character, or -1 if -/// the string is valid. -/// If the string is terminated early, the result is the length of the string. -int checkValidVersionNumber(String version) { - if (version == null) { - return 0; - } - int index = 0; - int dotsSeen = 0; - outer: - for (;;) { - // Check for numeral. - if (index == version.length) return index; - int char = version.codeUnitAt(index++); - int digit = char ^ 0x30; - if (digit != 0) { - if (digit < 9) { - while (index < version.length) { - char = version.codeUnitAt(index++); - digit = char ^ 0x30; - if (digit < 9) continue; - if (char == 0x2e /*.*/) { - if (dotsSeen > 0) return index - 1; - dotsSeen = 1; - continue outer; - } - return index - 1; - } - if (dotsSeen > 0) return -1; - return index; - } - return index - 1; - } - // Leading zero means numeral is over. - if (index >= version.length) { - if (dotsSeen > 0) return -1; - return index; - } - if (dotsSeen > 0) return index; - char = version.codeUnitAt(index++); - if (char != 0x2e /*.*/) return index - 1; - } -} - /// Checks whether URI is just an absolute directory. /// /// * It must have a scheme. /// * It must not have a query or fragment. -/// * The path must start and end with `/`. +/// * The path must end with `/`. bool isAbsoluteDirectoryUri(Uri uri) { if (uri.hasQuery) return false; if (uri.hasFragment) return false; if (!uri.hasScheme) return false; var path = uri.path; - if (!path.startsWith("/")) return false; if (!path.endsWith("/")) return false; return true; } @@ -302,3 +256,63 @@ Future _httpGet(Uri uri) async { } return result; } + +/// The file name of a path. +/// +/// The file name is everything after the last occurrence of +/// [Platform.pathSeparator]. +String fileName(String path) { + var separator = Platform.pathSeparator; + int lastSeparator = path.lastIndexOf(separator); + if (lastSeparator < 0) return path; + return path.substring(lastSeparator + separator.length); +} + +/// The file name of a path. +/// +/// The file name is everything before the last occurrence of +/// [Platform.pathSeparator]. +String dirName(String path) { + var separator = Platform.pathSeparator; + int lastSeparator = path.lastIndexOf(separator); + if (lastSeparator < 0) return ""; + return path.substring(0, lastSeparator); +} + +/// Join path parts with the [Platform.pathSeparator]. +String pathJoin(String part1, String part2, [String part3]) { + var separator = Platform.pathSeparator; + if (part3 == null) { + return "$part1$separator$part2"; + } + return "$part1$separator$part2$separator$part3"; +} + +/// Join an unknown number of path parts with [Platform.pathSeparator]. +String pathJoinAll(Iterable parts) => + parts.join(Platform.pathSeparator); + +// Character constants used by this package. +/// "Line feed" control character. +const int $lf = 0x0a; + +/// "Carriage return" control character. +const int $cr = 0x0d; + +/// Space character. +const int $space = 0x20; + +/// Character `#`. +const int $hash = 0x23; + +/// Character `.`. +const int $dot = 0x2e; + +/// Character `:`. +const int $colon = 0x3a; + +/// Character `?`. +const int $question = 0x3f; + +/// Character `{`. +const int $lbrace = 0x7b; diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 66aeb7858..7f47d2e2c 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.0 +version: 3.0.0-dev description: Support for working with Package Configuration files. author: Dart Team homepage: https://github.com/dart-lang/package_config @@ -7,9 +7,5 @@ homepage: https://github.com/dart-lang/package_config environment: sdk: '>=2.7.0 <3.0.0' -dependencies: - charcode: ^1.1.0 - path: ^1.0.0 - dev_dependencies: test: ^1.3.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 3256187d2..23efc6741 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -114,36 +114,92 @@ main() { expect(config, null); }); - fileTest("invalid .packages", { - ".packages": "not a .packages file", - }, (Directory directory) { - expect(() => findPackageConfig(directory), - throwsA(TypeMatcher())); - }); + group("throws", () { + fileTest("invalid .packages", { + ".packages": "not a .packages file", + }, (Directory directory) { + expect(findPackageConfig(directory), + throwsA(TypeMatcher())); + }); - fileTest("invalid .packages as JSON", { - ".packages": packageConfigFile, - }, (Directory directory) { - expect(() => findPackageConfig(directory), - throwsA(TypeMatcher())); - }); + fileTest("invalid .packages as JSON", { + ".packages": packageConfigFile, + }, (Directory directory) { + expect(findPackageConfig(directory), + throwsA(TypeMatcher())); + }); - fileTest("invalid .packages", { - ".dart_tool": { - "package_config.json": "not a JSON file", - } - }, (Directory directory) { - expect(() => findPackageConfig(directory), - throwsA(TypeMatcher())); + fileTest("invalid .packages", { + ".dart_tool": { + "package_config.json": "not a JSON file", + } + }, (Directory directory) { + expect(findPackageConfig(directory), + throwsA(TypeMatcher())); + }); + + fileTest("invalid .packages as INI", { + ".dart_tool": { + "package_config.json": packagesFile, + } + }, (Directory directory) { + expect(findPackageConfig(directory), + throwsA(TypeMatcher())); + }); }); - fileTest("invalid .packages as INI", { - ".dart_tool": { - "package_config.json": packagesFile, - } - }, (Directory directory) { - expect(() => findPackageConfig(directory), - throwsA(TypeMatcher())); + group("handles error", () { + fileTest("invalid .packages", { + ".packages": "not a .packages file", + }, (Directory directory) async { + bool hadError = false; + await findPackageConfig(directory, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); + }); + + fileTest("invalid .packages as JSON", { + ".packages": packageConfigFile, + }, (Directory directory) async { + bool hadError = false; + await findPackageConfig(directory, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); + }); + + fileTest("invalid package_config not JSON", { + ".dart_tool": { + "package_config.json": "not a JSON file", + } + }, (Directory directory) async { + bool hadError = false; + await findPackageConfig(directory, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); + }); + + fileTest("invalid package config as INI", { + ".dart_tool": { + "package_config.json": packagesFile, + } + }, (Directory directory) async { + bool hadError = false; + await findPackageConfig(directory, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); + }); }); }); @@ -226,6 +282,17 @@ main() { throwsA(TypeMatcher())); }); + fileTest("no config found, handled", {}, (Directory directory) async { + File file = dirFile(directory, "anyname"); + bool hadError = false; + await loadPackageConfig(file, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); + }); + fileTest("specified file syntax error", { "anyname": "syntax error", }, (Directory directory) { diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 8ad428ac0..081ec608f 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -4,6 +4,8 @@ library package_config.discovery_test; +import 'dart:io'; + import "package:test/test.dart"; import "package:package_config/package_config.dart"; @@ -219,7 +221,20 @@ main() { loaderTest("no config found", {}, (Uri directory, loader) { Uri file = directory.resolve("anyname"); expect(() => loadPackageConfigUri(file, loader: loader), - throwsArgumentError); + throwsA(isA())); + }); + + loaderTest("no config found, handle error", {}, + (Uri directory, loader) async { + Uri file = directory.resolve("anyname"); + bool hadError = false; + await loadPackageConfigUri(file, + loader: loader, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); }); loaderTest("specified file syntax error", { @@ -230,6 +245,20 @@ main() { throwsFormatException); }); + loaderTest("specified file syntax error", { + "anyname": "syntax error", + }, (Uri directory, loader) async { + Uri file = directory.resolve("anyname"); + bool hadError = false; + await loadPackageConfigUri(file, + loader: loader, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); + }); + // Find package_config.json in subdir even if initial file syntax error. loaderTest("specified file syntax error", { "anyname": "syntax error", @@ -246,10 +275,16 @@ main() { // A file starting with `{` is a package_config.json file. loaderTest("file syntax error with {", { ".packages": "{syntax error", - }, (Uri directory, loader) { + }, (Uri directory, loader) async { Uri file = directory.resolve(".packages"); - expect(() => loadPackageConfigUri(file, loader: loader), - throwsFormatException); + var hadError = false; + await loadPackageConfigUri(file, + loader: loader, + onError: expectAsync1((error) { + hadError = true; + expect(error, isA()); + }, max: -1)); + expect(hadError, true); }); }); } diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 3d1a20e4a..d9430953c 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -6,10 +6,13 @@ import "dart:convert"; import "package:test/test.dart"; +import "package:package_config/package_config.dart"; import "package:package_config/src/packages_file.dart" as packages; import "package:package_config/src/package_config_json.dart"; import "src/util.dart"; +void throwError(Object error) => throw error; + void main() { group(".packages", () { test("valid", () { @@ -17,8 +20,8 @@ void main() { "foo:file:///foo/lib/\n" "bar:/bar/lib/\n" "baz:lib/\n"; - var result = packages.parse( - utf8.encode(packagesFile), Uri.parse("file:///tmp/file.dart")); + var result = packages.parse(utf8.encode(packagesFile), + Uri.parse("file:///tmp/file.dart"), throwError); expect(result.version, 1); expect({for (var p in result.packages) p.name}, {"foo", "bar", "baz"}); expect(result.resolve(pkg("foo", "foo.dart")), @@ -37,8 +40,8 @@ void main() { test("valid empty", () { var packagesFile = "# Generated by pub yadda yadda\n"; - var result = - packages.parse(utf8.encode(packagesFile), Uri.file("/tmp/file.dart")); + var result = packages.parse( + utf8.encode(packagesFile), Uri.file("/tmp/file.dart"), throwError); expect(result.version, 1); expect({for (var p in result.packages) p.name}, {}); }); @@ -47,9 +50,18 @@ void main() { var baseFile = Uri.file("/tmp/file.dart"); testThrows(String name, String content) { test(name, () { - expect(() => packages.parse(utf8.encode(content), baseFile), + expect( + () => packages.parse(utf8.encode(content), baseFile, throwError), throwsA(TypeMatcher())); }); + test(name + ", handle error", () { + bool hadError = false; + packages.parse(utf8.encode(content), baseFile, (error) { + hadError = true; + expect(error, isA()); + }); + expect(hadError, true); + }); } testThrows("repeated package name", "foo:lib/\nfoo:lib\n"); @@ -81,12 +93,17 @@ void main() { "name": "bar", "rootUri": "/bar/", "packageUri": "lib/", - "languageVersion": "100.100" + "languageVersion": "9999.9999" }, { "name": "baz", "rootUri": "../", "packageUri": "lib/" + }, + { + "name": "noslash", + "rootUri": "../noslash", + "packageUri": "lib" } ], "generator": "pub", @@ -94,9 +111,10 @@ void main() { } """; var config = parsePackageConfigBytes(utf8.encode(packageConfigFile), - Uri.parse("file:///tmp/.dart_tool/file.dart")); + Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); expect(config.version, 2); - expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"}); + expect({for (var p in config.packages) p.name}, + {"foo", "bar", "baz", "noslash"}); expect(config.resolve(pkg("foo", "foo.dart")), Uri.parse("file:///foo/lib/foo.dart")); @@ -109,14 +127,14 @@ void main() { expect(foo, isNotNull); expect(foo.root, Uri.parse("file:///foo/")); expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); - expect(foo.languageVersion, "2.5"); + expect(foo.languageVersion, LanguageVersion(2, 5)); expect(foo.extraData, {"nonstandard": true}); var bar = config["bar"]; expect(bar, isNotNull); expect(bar.root, Uri.parse("file:///bar/")); expect(bar.packageUriRoot, Uri.parse("file:///bar/lib/")); - expect(bar.languageVersion, "100.100"); + expect(bar.languageVersion, LanguageVersion(9999, 9999)); expect(bar.extraData, null); var baz = config["baz"]; @@ -125,6 +143,13 @@ void main() { expect(baz.packageUriRoot, Uri.parse("file:///tmp/lib/")); expect(baz.languageVersion, null); + // No slash after root or package root. One is inserted. + var noslash = config["noslash"]; + expect(noslash, isNotNull); + expect(noslash.root, Uri.parse("file:///tmp/noslash/")); + expect(noslash.packageUriRoot, Uri.parse("file:///tmp/noslash/lib/")); + expect(noslash.languageVersion, null); + expect(config.extraData, { "generator": "pub", "other": [42] @@ -146,7 +171,7 @@ void main() { }, { "packageUri": "lib/", - "languageVersion": "100.100", + "languageVersion": "9999.9999", "rootUri": "/bar/", "name": "bar" }, @@ -160,7 +185,7 @@ void main() { } """; var config = parsePackageConfigBytes(utf8.encode(packageConfigFile), - Uri.parse("file:///tmp/.dart_tool/file.dart")); + Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); expect(config.version, 2); expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"}); @@ -184,7 +209,7 @@ void main() { var root = '"rootUri":"/foo/"'; test("minimal", () { var config = parsePackageConfigBytes(utf8.encode("{$cfg,$pkgs}"), - Uri.parse("file:///tmp/.dart_tool/file.dart")); + Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); expect(config.version, 2); expect(config.packages, isEmpty); }); @@ -193,7 +218,8 @@ void main() { // are optional. var config = parsePackageConfigBytes( utf8.encode('{$cfg,"packages":[{$name,$root}]}'), - Uri.parse("file:///tmp/.dart_tool/file.dart")); + Uri.parse("file:///tmp/.dart_tool/file.dart"), + throwError); expect(config.version, 2); expect(config.packages.first.name, "foo"); }); @@ -208,8 +234,8 @@ void main() { {"name": "qux", "rootUri": "/foo/qux/", "packageUri": "lib/"}, ] })); - var config = parsePackageConfigBytes( - configBytes, Uri.parse("file:///tmp/.dart_tool/file.dart")); + var config = parsePackageConfigBytes(configBytes, + Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); expect(config.version, 2); expect(config.packageOf(Uri.parse("file:///foo/lala/lala.dart")).name, "foo"); @@ -232,12 +258,9 @@ void main() { group("invalid", () { testThrows(String name, String source) { test(name, () { - if (name == "inside lib") { - print(name); - } expect( () => parsePackageConfigBytes(utf8.encode(source), - Uri.parse("file:///tmp/.dart_tool/file.dart")), + Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError), throwsA(TypeMatcher())); }); } diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart index ec4e5e8bc..95670bdbb 100644 --- a/pkgs/package_config/test/src/util.dart +++ b/pkgs/package_config/test/src/util.dart @@ -6,8 +6,8 @@ import 'dart:convert'; import "dart:io"; import 'dart:typed_data'; -import "package:path/path.dart" as path; import "package:test/test.dart"; +import "package:package_config/src/util.dart"; /// Creates a directory structure from [description] and runs [fileTest]. /// @@ -46,7 +46,7 @@ Directory createTestFiles(Map description) { // Creates temporary files in the target directory. void _createFiles(Directory target, Map description) { description.forEach((name, content) { - var entryName = path.join(target.path, "$name"); + var entryName = pathJoin(target.path, "$name"); if (content is Map) { _createFiles(Directory(entryName)..createSync(), content); } else { @@ -57,11 +57,11 @@ void _createFiles(Directory target, Map description) { /// Creates a [Directory] for a subdirectory of [parent]. Directory subdir(Directory parent, String dirName) => - Directory(path.joinAll([parent.path, ...dirName.split("/")])); + Directory(pathJoinAll([parent.path, ...dirName.split("/")])); /// Creates a [File] for an entry in the [directory] directory. File dirFile(Directory directory, String fileName) => - File(path.join(directory.path, fileName)); + File(pathJoin(directory.path, fileName)); /// Creates a package: URI. Uri pkg(String packageName, String packagePath) { From 917abca9660d8e75ffda2cb5f2f3e0d0648fef4c Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Tue, 11 Feb 2020 14:28:07 +0100 Subject: [PATCH 332/657] Fix doc and bug in util.dart --- pkgs/package_config/lib/src/util.dart | 34 ++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 2609a2f8a..f39027d00 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -260,7 +260,8 @@ Future _httpGet(Uri uri) async { /// The file name of a path. /// /// The file name is everything after the last occurrence of -/// [Platform.pathSeparator]. +/// [Platform.pathSeparator], or the entire string if no +/// path separator occurs in the string. String fileName(String path) { var separator = Platform.pathSeparator; int lastSeparator = path.lastIndexOf(separator); @@ -268,10 +269,11 @@ String fileName(String path) { return path.substring(lastSeparator + separator.length); } -/// The file name of a path. +/// The directory name of a path. /// -/// The file name is everything before the last occurrence of -/// [Platform.pathSeparator]. +/// The directory name is everything before the last occurrence of +/// [Platform.pathSeparator], or the empty string if no +/// path separator occurs in the string. String dirName(String path) { var separator = Platform.pathSeparator; int lastSeparator = path.lastIndexOf(separator); @@ -280,17 +282,33 @@ String dirName(String path) { } /// Join path parts with the [Platform.pathSeparator]. +/// +/// If a part ends with a path separator, then no extra separator is +/// inserted. String pathJoin(String part1, String part2, [String part3]) { var separator = Platform.pathSeparator; + String separator1 = part1.endsWith(separator) ? "" : separator; if (part3 == null) { - return "$part1$separator$part2"; + return "$part1$separator1$part2"; } - return "$part1$separator$part2$separator$part3"; + String separator2 = part2.endsWith(separator) ? "" : separator; + return "$part1$separator1$part2$separator2$part3"; } /// Join an unknown number of path parts with [Platform.pathSeparator]. -String pathJoinAll(Iterable parts) => - parts.join(Platform.pathSeparator); +/// +/// If a part ends with a path separator, then no extra separator is +/// inserted. +String pathJoinAll(Iterable parts) { + var buffer = StringBuffer(); + String separator = ""; + for (var part in parts) { + buffer..write(separator)..write(part); + separator = + part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator; + } + return buffer.toString(); +} // Character constants used by this package. /// "Line feed" control character. From 1c3193eb96a374e66a4abeb248433cc7610a1cfd Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 11 Feb 2020 08:52:01 -0800 Subject: [PATCH 333/657] pubspec: remove author, update homepage URL --- pkgs/pub_semver/pubspec.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index b92d2f66c..1297883d1 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -4,8 +4,7 @@ version: 1.4.3-dev description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. -author: Dart Team -homepage: http://github.com/dart-lang/pub_semver +homepage: https://github.com/dart-lang/pub_semver environment: sdk: '>=2.0.0 <3.0.0' From c3c9fdd5b8fd6aa4ee9dad802059012460a62b3c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 11 Feb 2020 08:58:44 -0800 Subject: [PATCH 334/657] Add example, prepare for 1.4.3 ship --- pkgs/pub_semver/example/example.dart | 17 +++++++++++++++++ pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 pkgs/pub_semver/example/example.dart diff --git a/pkgs/pub_semver/example/example.dart b/pkgs/pub_semver/example/example.dart new file mode 100644 index 000000000..890343c93 --- /dev/null +++ b/pkgs/pub_semver/example/example.dart @@ -0,0 +1,17 @@ +// 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:pub_semver/pub_semver.dart'; + +void main() { + final range = VersionConstraint.parse('^2.0.0'); + + for (var version in [ + Version.parse('1.2.3-pre'), + Version.parse('2.0.0+123'), + Version.parse('3.0.0-dev'), + ]) { + print('$version ${version.isPreRelease} ${range.allows(version)}'); + } +} diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 1297883d1..e2ac3b078 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.4.3-dev +version: 1.4.3 description: >- Versions and version constraints implementing pub's versioning policy. This From 87e2ef4a3bc7e2b158944c5c986445be7d97da20 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 11 Feb 2020 11:26:46 -0800 Subject: [PATCH 335/657] Fix homepage URL (dart-lang/source_maps#43) --- pkgs/source_maps/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 3c42700b8..f2db1eb32 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -2,7 +2,7 @@ name: source_maps version: 0.10.9-dev description: Library to programmatically manipulate source map files. -homepage: http://github.com/dart-lang/source_maps +homepage: https://github.com/dart-lang/source_maps environment: sdk: '>=2.0.0 <3.0.0' From e03b48d57938d47f28f22953c06b3b0902af5776 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 11 Feb 2020 11:26:55 -0800 Subject: [PATCH 336/657] Remove an unnecessary test expectation (dart-lang/source_maps#42) This expect is testing language implementation which is not necessary to do in this package. --- pkgs/source_maps/test/parser_test.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 45ac52db2..1b73f13cb 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -357,8 +357,6 @@ void main() { mapping = parseJsonExtended(expected); expect(mapping.toJson(), equals(expected)); } - // Invalid for this case - expect(() => parseJson(SOURCE_MAP_BUNDLE as dynamic), throwsA(anything)); var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE) as MappingBundle; expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); From 9bf652983ef2fd4888c5879bfa49c1479df791dd Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 11 Feb 2020 11:27:07 -0800 Subject: [PATCH 337/657] Prepare to publish (dart-lang/source_maps#41) Add a changelog entry for the `names` field change, drop `-dev`. --- pkgs/source_maps/CHANGELOG.md | 3 ++- pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 73bbed05e..321c37140 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,6 +1,7 @@ -## 0.10.9-dev +## 0.10.9 * Fix a number of document comment issues. +* Allow parsing source map files with a missing `names` field. ## 0.10.8 diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index f2db1eb32..871c40acc 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.9-dev +version: 0.10.9 description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps From 0117f2517cb08173b4712f0eb937c629e111c02e Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Fri, 21 Feb 2020 09:36:22 +0100 Subject: [PATCH 338/657] Support the new package_config.json file format. Add support for new format. Retains, but deprecates, the existing functionality. A later 2.0 release will remove support for the old file format. --- pkgs/package_config/CHANGELOG.md | 16 +- pkgs/package_config/README.md | 13 + pkgs/package_config/analysis_options.yaml | 11 + pkgs/package_config/lib/discovery.dart | 227 ++++++++++++ .../lib/discovery_analysis.dart | 167 +++++++++ pkgs/package_config/lib/package_config.dart | 10 +- .../lib/package_config_types.dart | 11 + pkgs/package_config/lib/packages.dart | 96 +++++ pkgs/package_config/lib/packages_file.dart | 232 +++++++++++++ pkgs/package_config/lib/src/discovery.dart | 2 + .../lib/src/package_config.dart | 109 +++++- .../lib/src/package_config_impl.dart | 64 +++- .../lib/src/package_config_io.dart | 155 +++++++++ .../lib/src/package_config_json.dart | 220 ++++-------- .../package_config/lib/src/packages_file.dart | 22 +- .../package_config/lib/src/packages_impl.dart | 128 +++++++ .../lib/src/packages_io_impl.dart | 46 +++ pkgs/package_config/lib/src/util.dart | 49 +-- pkgs/package_config/pubspec.yaml | 6 +- pkgs/package_config/test/discovery_test.dart | 64 ++-- .../test/discovery_uri_test.dart | 60 ++-- pkgs/package_config/test/legacy/all.dart | 20 ++ .../test/legacy/discovery_analysis_test.dart | 127 +++++++ .../test/legacy/discovery_test.dart | 328 ++++++++++++++++++ .../test/legacy/parse_test.dart | 246 +++++++++++++ .../test/legacy/parse_write_test.dart | 133 +++++++ pkgs/package_config/test/parse_test.dart | 85 ++++- pkgs/package_config/test/src/util.dart | 8 +- 28 files changed, 2340 insertions(+), 315 deletions(-) create mode 100644 pkgs/package_config/analysis_options.yaml create mode 100644 pkgs/package_config/lib/discovery.dart create mode 100644 pkgs/package_config/lib/discovery_analysis.dart create mode 100644 pkgs/package_config/lib/package_config_types.dart create mode 100644 pkgs/package_config/lib/packages.dart create mode 100644 pkgs/package_config/lib/packages_file.dart create mode 100644 pkgs/package_config/lib/src/package_config_io.dart create mode 100644 pkgs/package_config/lib/src/packages_impl.dart create mode 100644 pkgs/package_config/lib/src/packages_io_impl.dart create mode 100644 pkgs/package_config/test/legacy/all.dart create mode 100644 pkgs/package_config/test/legacy/discovery_analysis_test.dart create mode 100644 pkgs/package_config/test/legacy/discovery_test.dart create mode 100644 pkgs/package_config/test/legacy/parse_test.dart create mode 100644 pkgs/package_config/test/legacy/parse_write_test.dart diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 317184075..c6caf4d6e 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,17 +1,9 @@ -## 3.0.0 - -- Make the language version be represented as a `LanguageVersion` class - instead of a string. -- Made error handling interceptable. Passing an `onError` handler - makes the parsers attempt to do a best-effort error correction after - detecting an error. -- Do not require root URIs to have paths starting with `/`. That - only makes sense for `file` or `http`, and they enforce it anyway. -- Fixed bug in language version validation not accepting the digit `9`. - -## 2.0.0 +## 1.9.0 - Based on new JSON file format with more content. +- This version includes all the new functionality intended for a 2.0.0 + version, as well as the, now deprecated, version 1 functionality. + When we release 2.0.0, the deprectated functionality will be removed. ## 1.2.0 diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 45791aaf3..ec51f6ea7 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -3,6 +3,19 @@ Support for working with **Package Configuration** files as described in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). +The primary libraries are +* `package_config.dart`: + Defines the `PackageConfig` class and other types needed to use + package configurations. + +* `package_config_discovery.dart`: + Provides functions for reading configurations from files, + and writing them back out. + +The package includes deprecated backwards compatible functionality to +work with the `.packages` file. This functionality will not be maintained, +and will be removed in a future version of this package. + [![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) ## Features and bugs diff --git a/pkgs/package_config/analysis_options.yaml b/pkgs/package_config/analysis_options.yaml new file mode 100644 index 000000000..82c00e5c8 --- /dev/null +++ b/pkgs/package_config/analysis_options.yaml @@ -0,0 +1,11 @@ +# 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. + +include: package:pedantic/analysis_options.yaml +analyzer: + errors: + annotate_overrides: ignore + curly_braces_in_flow_control_structures: ignore + prefer_single_quotes: ignore + use_function_type_syntax_for_parameters: ignore diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart new file mode 100644 index 000000000..a2f53c0e6 --- /dev/null +++ b/pkgs/package_config/lib/discovery.dart @@ -0,0 +1,227 @@ +// Copyright (c) 2015, 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. + +@Deprecated("Use the package_config.json based API") +library package_config.discovery; + +import "dart:async"; +import "dart:io"; +import "dart:typed_data" show Uint8List; + +import "package:path/path.dart" as path; + +import "packages.dart"; +import "packages_file.dart" as pkgfile show parse; +import "src/packages_impl.dart"; +import "src/packages_io_impl.dart"; + +/// Reads a package resolution file and creates a [Packages] object from it. +/// +/// The [packagesFile] must exist and be loadable. +/// Currently that means the URI must have a `file`, `http` or `https` scheme, +/// and that the file can be loaded and its contents parsed correctly. +/// +/// If the [loader] is provided, it is used to fetch non-`file` URIs, and +/// it can support other schemes or set up more complex HTTP requests. +/// +/// This function can be used to load an explicitly configured package +/// resolution file, for example one specified using a `--packages` +/// command-line parameter. +Future loadPackagesFile(Uri packagesFile, + {Future> loader(Uri uri)}) async { + Packages parseBytes(List bytes) { + return MapPackages(pkgfile.parse(bytes, packagesFile)); + } + + if (packagesFile.scheme == "file") { + return parseBytes(await File.fromUri(packagesFile).readAsBytes()); + } + if (loader == null) { + return parseBytes(await _httpGet(packagesFile)); + } + return parseBytes(await loader(packagesFile)); +} + +/// Create a [Packages] object for a package directory. +/// +/// The [packagesDir] URI should refer to a directory. +/// Package names are resolved as relative to sub-directories of the +/// package directory. +/// +/// This function can be used for explicitly configured package directories, +/// for example one specified using a `--package-root` comand-line parameter. +Packages getPackagesDirectory(Uri packagesDir) { + if (packagesDir.scheme == "file") { + return FilePackagesDirectoryPackages(Directory.fromUri(packagesDir)); + } + if (!packagesDir.path.endsWith('/')) { + packagesDir = packagesDir.replace(path: packagesDir.path + '/'); + } + return NonFilePackagesDirectoryPackages(packagesDir); +} + +/// Discover the package configuration for a Dart script. +/// +/// The [baseUri] points to either the Dart script or its directory. +/// A package resolution strategy is found by going through the following steps, +/// and stopping when something is found. +/// +/// * Check if a `.packages` file exists in the same directory. +/// * If `baseUri`'s scheme is not `file`, then assume a `packages` directory +/// in the same directory, and resolve packages relative to that. +/// * If `baseUri`'s scheme *is* `file`: +/// * Check if a `packages` directory exists. +/// * Otherwise check each successive parent directory of `baseUri` for a +/// `.packages` file. +/// +/// If any of these tests succeed, a `Packages` class is returned. +/// Returns the constant [noPackages] if no resolution strategy is found. +/// +/// This function currently only supports `file`, `http` and `https` URIs. +/// It needs to be able to load a `.packages` file from the URI, so only +/// recognized schemes are accepted. +/// +/// To support other schemes, or more complex HTTP requests, +/// an optional [loader] function can be supplied. +/// It's called to load the `.packages` file for a non-`file` scheme. +/// The loader function returns the *contents* of the file +/// identified by the URI it's given. +/// The content should be a UTF-8 encoded `.packages` file, and must return an +/// error future if loading fails for any reason. +Future findPackages(Uri baseUri, + {Future> loader(Uri unsupportedUri)}) { + if (baseUri.scheme == "file") { + return Future.sync(() => findPackagesFromFile(baseUri)); + } else if (loader != null) { + return findPackagesFromNonFile(baseUri, loader: loader); + } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { + return findPackagesFromNonFile(baseUri, loader: _httpGet); + } else { + return Future.value(Packages.noPackages); + } +} + +/// Find the location of the package resolution file/directory for a Dart file. +/// +/// Checks for a `.packages` file in the [workingDirectory]. +/// If not found, checks for a `packages` directory in the same directory. +/// If still not found, starts checking parent directories for +/// `.packages` until reaching the root directory. +/// +/// Returns a [File] object of a `.packages` file if one is found, or a +/// [Directory] object for the `packages/` directory if that is found. +FileSystemEntity _findPackagesFile(String workingDirectory) { + var dir = Directory(workingDirectory); + if (!dir.isAbsolute) dir = dir.absolute; + if (!dir.existsSync()) { + throw ArgumentError.value( + workingDirectory, "workingDirectory", "Directory does not exist."); + } + File checkForConfigFile(Directory directory) { + assert(directory.isAbsolute); + var file = File(path.join(directory.path, ".packages")); + if (file.existsSync()) return file; + return null; + } + + // Check for $cwd/.packages + var packagesCfgFile = checkForConfigFile(dir); + if (packagesCfgFile != null) return packagesCfgFile; + // Check for $cwd/packages/ + var packagesDir = Directory(path.join(dir.path, "packages")); + if (packagesDir.existsSync()) return packagesDir; + // Check for cwd(/..)+/.packages + var parentDir = dir.parent; + while (parentDir.path != dir.path) { + packagesCfgFile = checkForConfigFile(parentDir); + if (packagesCfgFile != null) break; + dir = parentDir; + parentDir = dir.parent; + } + return packagesCfgFile; +} + +/// Finds a package resolution strategy for a local Dart script. +/// +/// The [fileBaseUri] points to either a Dart script or the directory of the +/// script. The `fileBaseUri` must be a `file:` URI. +/// +/// This function first tries to locate a `.packages` file in the `fileBaseUri` +/// directory. If that is not found, it instead checks for the presence of +/// a `packages/` directory in the same place. +/// If that also fails, it starts checking parent directories for a `.packages` +/// file, and stops if it finds it. +/// Otherwise it gives up and returns [Packages.noPackages]. +Packages findPackagesFromFile(Uri fileBaseUri) { + var baseDirectoryUri = fileBaseUri; + if (!fileBaseUri.path.endsWith('/')) { + baseDirectoryUri = baseDirectoryUri.resolve("."); + } + var baseDirectoryPath = baseDirectoryUri.toFilePath(); + var location = _findPackagesFile(baseDirectoryPath); + if (location == null) return Packages.noPackages; + if (location is File) { + var fileBytes = location.readAsBytesSync(); + var map = pkgfile.parse(fileBytes, Uri.file(location.path)); + return MapPackages(map); + } + assert(location is Directory); + return FilePackagesDirectoryPackages(location); +} + +/// Finds a package resolution strategy for a Dart script. +/// +/// The [nonFileUri] points to either a Dart script or the directory of the +/// script. +/// The [nonFileUri] should not be a `file:` URI since the algorithm for +/// finding a package resolution strategy is more elaborate for `file:` URIs. +/// In that case, use [findPackagesFromFile]. +/// +/// This function first tries to locate a `.packages` file in the [nonFileUri] +/// directory. If that is not found, it instead assumes a `packages/` directory +/// in the same place. +/// +/// By default, this function only works for `http:` and `https:` URIs. +/// To support other schemes, a loader must be provided, which is used to +/// try to load the `.packages` file. The loader should return the contents +/// of the requested `.packages` file as bytes, which will be assumed to be +/// UTF-8 encoded. +Future findPackagesFromNonFile(Uri nonFileUri, + {Future> loader(Uri name)}) async { + loader ??= _httpGet; + var packagesFileUri = nonFileUri.resolve(".packages"); + + try { + var fileBytes = await loader(packagesFileUri); + var map = pkgfile.parse(fileBytes, packagesFileUri); + return MapPackages(map); + } catch (_) { + // Didn't manage to load ".packages". Assume a "packages/" directory. + var packagesDirectoryUri = nonFileUri.resolve("packages/"); + return NonFilePackagesDirectoryPackages(packagesDirectoryUri); + } +} + +/// Fetches a file over http. +Future> _httpGet(Uri uri) async { + var client = HttpClient(); + var request = await client.getUrl(uri); + var response = await request.close(); + if (response.statusCode != HttpStatus.ok) { + throw HttpException('${response.statusCode} ${response.reasonPhrase}', + uri: uri); + } + var splitContent = await response.toList(); + var totalLength = 0; + for (var list in splitContent) { + totalLength += list.length; + } + var result = Uint8List(totalLength); + var offset = 0; + for (var contentPart in splitContent) { + result.setRange(offset, offset + contentPart.length, contentPart); + offset += contentPart.length; + } + return result; +} diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart new file mode 100644 index 000000000..2af07292e --- /dev/null +++ b/pkgs/package_config/lib/discovery_analysis.dart @@ -0,0 +1,167 @@ +// Copyright (c) 2015, 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. + +/// Analyse a directory structure and find packages resolvers for each +/// sub-directory. +/// +/// The resolvers are generally the same that would be found by using +/// the `discovery.dart` library on each sub-directory in turn, +/// but more efficiently and with some heuristics for directories that +/// wouldn't otherwise have a package resolution strategy, or that are +/// determined to be "package directories" themselves. +@Deprecated("Use the package_config.json based API") +library package_config.discovery_analysis; + +import "dart:collection" show HashMap; +import "dart:io" show File, Directory; + +import "package:path/path.dart" as path; + +import "packages.dart"; +import "packages_file.dart" as pkgfile; +import "src/packages_impl.dart"; +import "src/packages_io_impl.dart"; + +/// Associates a [Packages] package resolution strategy with a directory. +/// +/// The package resolution applies to the directory and any sub-directory +/// that doesn't have its own overriding child [PackageContext]. +abstract class PackageContext { + /// The directory that introduced the [packages] resolver. + Directory get directory; + + /// A [Packages] resolver that applies to the directory. + /// + /// Introduced either by a `.packages` file or a `packages/` directory. + Packages get packages; + + /// Child contexts that apply to sub-directories of [directory]. + List get children; + + /// Look up the [PackageContext] that applies to a specific directory. + /// + /// The directory must be inside [directory]. + PackageContext operator [](Directory directory); + + /// A map from directory to package resolver. + /// + /// Has an entry for this package context and for each child context + /// contained in this one. + Map asMap(); + + /// Analyze [directory] and sub-directories for package resolution strategies. + /// + /// Returns a mapping from sub-directories to [Packages] objects. + /// + /// The analysis assumes that there are no `.packages` files in a parent + /// directory of `directory`. If there is, its corresponding `Packages` object + /// should be provided as `root`. + static PackageContext findAll(Directory directory, + {Packages root = Packages.noPackages}) { + if (!directory.existsSync()) { + throw ArgumentError("Directory not found: $directory"); + } + var contexts = []; + void findRoots(Directory directory) { + Packages packages; + List oldContexts; + var packagesFile = File(path.join(directory.path, ".packages")); + if (packagesFile.existsSync()) { + packages = _loadPackagesFile(packagesFile); + oldContexts = contexts; + contexts = []; + } else { + var packagesDir = Directory(path.join(directory.path, "packages")); + if (packagesDir.existsSync()) { + packages = FilePackagesDirectoryPackages(packagesDir); + oldContexts = contexts; + contexts = []; + } + } + for (var entry in directory.listSync()) { + if (entry is Directory) { + if (packages == null || !entry.path.endsWith("/packages")) { + findRoots(entry); + } + } + } + if (packages != null) { + oldContexts.add(_PackageContext(directory, packages, contexts)); + contexts = oldContexts; + } + } + + findRoots(directory); + // If the root is not itself context root, add a the wrapper context. + if (contexts.length == 1 && contexts[0].directory == directory) { + return contexts[0]; + } + return _PackageContext(directory, root, contexts); + } +} + +class _PackageContext implements PackageContext { + final Directory directory; + final Packages packages; + final List children; + _PackageContext(this.directory, this.packages, List children) + : children = List.unmodifiable(children); + + Map asMap() { + var result = HashMap(); + void recurse(_PackageContext current) { + result[current.directory] = current.packages; + for (var child in current.children) { + recurse(child); + } + } + + recurse(this); + return result; + } + + PackageContext operator [](Directory directory) { + var path = directory.path; + if (!path.startsWith(this.directory.path)) { + throw ArgumentError("Not inside $path: $directory"); + } + var current = this; + // The current path is know to agree with directory until deltaIndex. + var deltaIndex = current.directory.path.length; + List children = current.children; + var i = 0; + while (i < children.length) { + // TODO(lrn): Sort children and use binary search. + _PackageContext child = children[i]; + var childPath = child.directory.path; + if (_stringsAgree(path, childPath, deltaIndex, childPath.length)) { + deltaIndex = childPath.length; + if (deltaIndex == path.length) { + return child; + } + current = child; + children = current.children; + i = 0; + continue; + } + i++; + } + return current; + } + + static bool _stringsAgree(String a, String b, int start, int end) { + if (a.length < end || b.length < end) return false; + for (var i = start; i < end; i++) { + if (a.codeUnitAt(i) != b.codeUnitAt(i)) return false; + } + return true; + } +} + +Packages _loadPackagesFile(File file) { + var uri = Uri.file(file.path); + var bytes = file.readAsBytesSync(); + var map = pkgfile.parse(bytes, uri); + return MapPackages(map); +} diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index 98b31f1f9..bca865d70 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -4,7 +4,7 @@ /// A package configuration is a way to assign file paths to package URIs, /// and vice-versa, -library package_config.package_config; +library package_config.package_config_discovery; import "dart:io" show File, Directory; import "dart:typed_data" show Uint8List; @@ -12,11 +12,9 @@ import "dart:typed_data" show Uint8List; import "src/discovery.dart" as discover; import "src/errors.dart" show throwError; import "src/package_config.dart"; -import "src/package_config_json.dart"; +import "src/package_config_io.dart"; -export "src/package_config.dart" - show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion; -export "src/errors.dart" show PackageConfigError; +export "package_config_types.dart"; /// Reads a specific package configuration file. /// @@ -173,4 +171,4 @@ Future findPackageConfigUri(Uri location, /// `"generator"` entry. Future savePackageConfig( PackageConfig configuration, Directory directory) => - writePackageConfigJson(configuration, directory); + writePackageConfigJsonFile(configuration, directory); diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart new file mode 100644 index 000000000..f0637b11b --- /dev/null +++ b/pkgs/package_config/lib/package_config_types.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2019, 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. + +/// A package configuration is a way to assign file paths to package URIs, +/// and vice-versa, +library package_config.package_config; + +export "src/package_config.dart" + show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion; +export "src/errors.dart" show PackageConfigError; diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart new file mode 100644 index 000000000..203f32fdb --- /dev/null +++ b/pkgs/package_config/lib/packages.dart @@ -0,0 +1,96 @@ +// Copyright (c) 2015, 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. + +@Deprecated("Use the package_config.json based API") +library package_config.packages; + +import "src/packages_impl.dart"; + +/// A package resolution strategy. +/// +/// Allows converting a `package:` URI to a different kind of URI. +/// +/// May also allow listing the available packages and converting +/// to a `Map` that gives the base location of each available +/// package. In some cases there is no way to find the available packages, +/// in which case [packages] and [asMap] will throw if used. +/// One such case is if the packages are resolved relative to a +/// `packages/` directory available over HTTP. +@Deprecated("Use the package_config.json based API") +abstract class Packages { + /// A [Packages] resolver containing no packages. + /// + /// This constant object is returned by [find] above if no + /// package resolution strategy is found. + static const Packages noPackages = NoPackages(); + + /// Resolve a package URI into a non-package URI. + /// + /// Translates a `package:` URI, according to the package resolution + /// strategy, into a URI that can be loaded. + /// By default, only `file`, `http` and `https` URIs are returned. + /// Custom `Packages` objects may return other URIs. + /// + /// If resolution fails because a package with the requested package name + /// is not available, the [notFound] function is called. + /// If no `notFound` function is provided, it defaults to throwing an error. + /// + /// The [packageUri] must be a valid package URI. + Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}); + + /// Return the names of the available packages. + /// + /// Returns an iterable that allows iterating the names of available packages. + /// + /// Some `Packages` objects are unable to find the package names, + /// and getting `packages` from such a `Packages` object will throw. + Iterable get packages; + + /// Retrieve metadata associated with a package. + /// + /// Metadata have string keys and values, and are looked up by key. + /// + /// Returns `null` if the argument is not a valid package name, + /// or if the package is not one of the packages configured by + /// this packages object, or if the package does not have associated + /// metadata with the provided [key]. + /// + /// Not all `Packages` objects can support metadata. + /// Those will always return `null`. + String packageMetadata(String packageName, String key); + + /// Retrieve metadata associated with a library. + /// + /// If [libraryUri] is a `package:` URI, the returned value + /// is the same that would be returned by [packageMetadata] with + /// the package's name and the same key. + /// + /// If [libraryUri] is not a `package:` URI, and this [Packages] + /// object has a [defaultPackageName], then the [key] is looked + /// up on the default package instead. + /// + /// Otherwise the result is `null`. + String libraryMetadata(Uri libraryUri, String key); + + /// Return the names-to-base-URI mapping of the available packages. + /// + /// Returns a map from package name to a base URI. + /// The [resolve] method will resolve a package URI with a specific package + /// name to a path extending the base URI that this map gives for that + /// package name. + /// + /// Some `Packages` objects are unable to find the package names, + /// and calling `asMap` on such a `Packages` object will throw. + Map asMap(); + + /// The name of the "default package". + /// + /// A default package is a package that *non-package* libraries + /// may be considered part of for some purposes. + /// + /// The value is `null` if there is no default package. + /// Not all implementations of [Packages] supports a default package, + /// and will always have a `null` value for those. + String get defaultPackageName; +} diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart new file mode 100644 index 000000000..ef0b0b3ca --- /dev/null +++ b/pkgs/package_config/lib/packages_file.dart @@ -0,0 +1,232 @@ +// Copyright (c) 2015, 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. + +@Deprecated("Use the package_config.json based API") +library package_config.packages_file; + +import "package:charcode/ascii.dart"; + +import "src/util.dart" show isValidPackageName; + +/// Parses a `.packages` file into a map from package name to base URI. +/// +/// The [source] is the byte content of a `.packages` file, assumed to be +/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII, +/// so Latin-1 or Windows-1252 encoding will also work fine. +/// +/// If the file content is available as a string, its [String.codeUnits] can +/// be used as the `source` argument of this function. +/// +/// The [baseLocation] is used as a base URI to resolve all relative +/// URI references against. +/// If the content was read from a file, `baseLocation` should be the +/// location of that file. +/// +/// If [allowDefaultPackage] is set to true, an entry with an empty package name +/// is accepted. This entry does not correspond to a package, but instead +/// represents a *default package* which non-package libraries may be considered +/// part of in some cases. The value of that entry must be a valid package name. +/// +/// Returns a simple mapping from package name to package location. +/// If default package is allowed, the map maps the empty string to the default package's name. +Map parse(List source, Uri baseLocation, + {bool allowDefaultPackage = false}) { + var index = 0; + var result = {}; + while (index < source.length) { + var isComment = false; + var start = index; + var separatorIndex = -1; + var end = source.length; + var char = source[index++]; + if (char == $cr || char == $lf) { + continue; + } + if (char == $colon) { + if (!allowDefaultPackage) { + throw FormatException("Missing package name", source, index - 1); + } + separatorIndex = index - 1; + } + isComment = char == $hash; + while (index < source.length) { + char = source[index++]; + if (char == $colon && separatorIndex < 0) { + separatorIndex = index - 1; + } else if (char == $cr || char == $lf) { + end = index - 1; + break; + } + } + if (isComment) continue; + if (separatorIndex < 0) { + throw FormatException("No ':' on line", source, index - 1); + } + var packageName = String.fromCharCodes(source, start, separatorIndex); + if (packageName.isEmpty + ? !allowDefaultPackage + : !isValidPackageName(packageName)) { + throw FormatException("Not a valid package name", packageName, 0); + } + var packageValue = String.fromCharCodes(source, separatorIndex + 1, end); + Uri packageLocation; + if (packageName.isEmpty) { + if (!isValidPackageName(packageValue)) { + throw FormatException( + "Default package entry value is not a valid package name"); + } + packageLocation = Uri(path: packageValue); + } else { + packageLocation = baseLocation.resolve(packageValue); + if (!packageLocation.path.endsWith('/')) { + packageLocation = + packageLocation.replace(path: packageLocation.path + "/"); + } + } + if (result.containsKey(packageName)) { + if (packageName.isEmpty) { + throw FormatException( + "More than one default package entry", source, start); + } + throw FormatException("Same package name occured twice", source, start); + } + result[packageName] = packageLocation; + } + return result; +} + +/// Writes the mapping to a [StringSink]. +/// +/// If [comment] is provided, the output will contain this comment +/// with `# ` in front of each line. +/// Lines are defined as ending in line feed (`'\n'`). If the final +/// line of the comment doesn't end in a line feed, one will be added. +/// +/// If [baseUri] is provided, package locations will be made relative +/// to the base URI, if possible, before writing. +/// +/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an +/// empty string mapping to the _default package name_. +/// +/// All the keys of [packageMapping] must be valid package names, +/// and the values must be URIs that do not have the `package:` scheme. +void write(StringSink output, Map packageMapping, + {Uri baseUri, String comment, bool allowDefaultPackage = false}) { + ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage'); + + if (baseUri != null && !baseUri.isAbsolute) { + throw ArgumentError.value(baseUri, "baseUri", "Must be absolute"); + } + + if (comment != null) { + var lines = comment.split('\n'); + if (lines.last.isEmpty) lines.removeLast(); + for (var commentLine in lines) { + output.write('# '); + output.writeln(commentLine); + } + } else { + output.write("# generated by package:package_config at "); + output.write(DateTime.now()); + output.writeln(); + } + + packageMapping.forEach((String packageName, Uri uri) { + // If [packageName] is empty then [uri] is the _default package name_. + if (allowDefaultPackage && packageName.isEmpty) { + final defaultPackageName = uri.toString(); + if (!isValidPackageName(defaultPackageName)) { + throw ArgumentError.value( + defaultPackageName, + 'defaultPackageName', + '"$defaultPackageName" is not a valid package name', + ); + } + output.write(':'); + output.write(defaultPackageName); + output.writeln(); + return; + } + // Validate packageName. + if (!isValidPackageName(packageName)) { + throw ArgumentError('"$packageName" is not a valid package name'); + } + if (uri.scheme == "package") { + throw ArgumentError.value( + "Package location must not be a package: URI", uri.toString()); + } + output.write(packageName); + output.write(':'); + // If baseUri provided, make uri relative. + if (baseUri != null) { + uri = _relativize(uri, baseUri); + } + if (!uri.path.endsWith('/')) { + uri = uri.replace(path: uri.path + '/'); + } + output.write(uri); + output.writeln(); + }); +} + +/// Attempts to return a relative URI for [uri]. +/// +/// The result URI satisfies `baseUri.resolveUri(result) == uri`, +/// but may be relative. +/// The `baseUri` must be absolute. +Uri _relativize(Uri uri, Uri baseUri) { + assert(baseUri.isAbsolute); + if (uri.hasQuery || uri.hasFragment) { + uri = Uri( + scheme: uri.scheme, + userInfo: uri.hasAuthority ? uri.userInfo : null, + host: uri.hasAuthority ? uri.host : null, + port: uri.hasAuthority ? uri.port : null, + path: uri.path); + } + + // Already relative. We assume the caller knows what they are doing. + if (!uri.isAbsolute) return uri; + + if (baseUri.scheme != uri.scheme) { + return uri; + } + + // If authority differs, we could remove the scheme, but it's not worth it. + if (uri.hasAuthority != baseUri.hasAuthority) return uri; + if (uri.hasAuthority) { + if (uri.userInfo != baseUri.userInfo || + uri.host.toLowerCase() != baseUri.host.toLowerCase() || + uri.port != baseUri.port) { + return uri; + } + } + + baseUri = baseUri.normalizePath(); + var base = baseUri.pathSegments.toList(); + if (base.isNotEmpty) { + base = List.from(base)..removeLast(); + } + uri = uri.normalizePath(); + var target = uri.pathSegments.toList(); + if (target.isNotEmpty && target.last.isEmpty) target.removeLast(); + var index = 0; + while (index < base.length && index < target.length) { + if (base[index] != target[index]) { + break; + } + index++; + } + if (index == base.length) { + if (index == target.length) { + return Uri(path: "./"); + } + return Uri(path: target.skip(index).join('/')); + } else if (index > 0) { + return Uri( + path: '../' * (base.length - index) + target.skip(index).join('/')); + } else { + return uri; + } +} diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index 14033ed35..5d3172f26 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -5,6 +5,8 @@ import "dart:io"; import 'dart:typed_data'; +import 'package_config_io.dart'; + import "errors.dart"; import "package_config_impl.dart"; import "package_config_json.dart"; diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 08c4a9691..364df75b1 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -2,8 +2,11 @@ // 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 'dart:typed_data'; + import 'errors.dart'; import "package_config_impl.dart"; +import 'package_config_json.dart'; /// A package configuration. /// @@ -21,14 +24,27 @@ abstract class PackageConfig { /// A package configuration with no available packages. /// Is used as a default value where a package configuration /// is expected, but none have been specified or found. - static const PackageConfig empty = const SimplePackageConfig.empty(); + static const PackageConfig empty = SimplePackageConfig.empty(); /// Creats a package configuration with the provided available [packages]. /// /// The packages must be valid packages (valid package name, valid /// absolute directory URIs, valid language version, if any), - /// and there must not be two packages with the same name or with - /// overlapping root directories. + /// and there must not be two packages with the same name. + /// + /// The package's root ([Package.rootUri]) and package-root + /// ([Package.packageUriRoot]) paths must satisfy a number of constraints + /// We say that one path (which we know ends with a `/` charater) + /// is inside another path, if the latter path is a prefix of the former path, + /// including the two paths being the same. + /// + /// * No package's root must be the same as another package's root. + /// * The package-root of a package must be inside the pacakge's root. + /// * If one package's package-root is inside another package's root, + /// then the latter package's package root must not be inside the former + /// package's root. (No getting between a package and its package root!) + /// This also disallows a package's root being the same as another + /// package's package root. /// /// If supplied, the [extraData] will be available as the /// [PackageConfig.extraData] of the created configuration. @@ -37,6 +53,93 @@ abstract class PackageConfig { factory PackageConfig(Iterable packages, {dynamic extraData}) => SimplePackageConfig(maxVersion, packages, extraData); + /// Parses a package configuration file. + /// + /// The [bytes] must be an UTF-8 encoded JSON object + /// containing a valid package configuration. + /// + /// The [baseUri] is used as the base for resolving relative + /// URI references in the configuration file. If the configuration + /// has been read from a file, the [baseUri] can be the URI of that + /// file, or of the directory it occurs in. + /// + /// If [onError] is provided, errors found during parsing or building + /// the configuration are reported by calling [onError] instead of + /// throwing, and parser makes a *best effort* attempt to continue + /// despite the error. The input must still be valid JSON. + /// The result may be a [PackageConfig.empty] if there is no way to + /// extract useful information from the bytes. + static PackageConfig parseBytes(Uint8List bytes, Uri baseUri, + {void onError(Object error)}) => + parsePackageConfigBytes(bytes, baseUri, onError ?? throwError); + + /// Parses a package configuration file. + /// + /// The [configuration] must be a JSON object + /// containing a valid package configuration. + /// + /// The [baseUri] is used as the base for resolving relative + /// URI references in the configuration file. If the configuration + /// has been read from a file, the [baseUri] can be the URI of that + /// file, or of the directory it occurs in. + /// + /// If [onError] is provided, errors found during parsing or building + /// the configuration are reported by calling [onError] instead of + /// throwing, and parser makes a *best effort* attempt to continue + /// despite the error. The input must still be valid JSON. + /// The result may be a [PackageConfig.empty] if there is no way to + /// extract useful information from the bytes. + static PackageConfig parseString(String configuration, Uri baseUri, + {void onError(Object error)}) => + parsePackageConfigString(configuration, baseUri, onError ?? throwError); + + /// Parses the JSON data of a package configuration file. + /// + /// The [configuration] must be a JSON-like Dart data structure, + /// like the one provided by parsing JSON text using `dart:convert`, + /// containing a valid package configuration. + /// + /// The [baseUri] is used as the base for resolving relative + /// URI references in the configuration file. If the configuration + /// has been read from a file, the [baseUri] can be the URI of that + /// file, or of the directory it occurs in. + /// + /// If [onError] is provided, errors found during parsing or building + /// the configuration are reported by calling [onError] instead of + /// throwing, and parser makes a *best effort* attempt to continue + /// despite the error. The input must still be valid JSON. + /// The result may be a [PackageConfig.empty] if there is no way to + /// extract useful information from the bytes. + static PackageConfig parseJson(dynamic jsonData, Uri baseUri, + {void onError(Object error)}) => + parsePackageConfigJson(jsonData, baseUri, onError ?? throwError); + + /// Writes a configuration file for this configuration on [output]. + /// + /// If [baseUri] is provided, URI references in the generated file + /// will be made relative to [baseUri] where possible. + static void writeBytes(PackageConfig configuration, Sink output, + [Uri /*?*/ baseUri]) { + writePackageConfigJsonUtf8(configuration, baseUri, output); + } + + /// Writes a configuration JSON text for this configuration on [output]. + /// + /// If [baseUri] is provided, URI references in the generated file + /// will be made relative to [baseUri] where possible. + static void writeString(PackageConfig configuration, StringSink output, + [Uri /*?*/ baseUri]) { + writePackageConfigJsonString(configuration, baseUri, output); + } + + /// Converts a configuration to a JSON-like data structure. + /// + /// If [baseUri] is provided, URI references in the generated data + /// will be made relative to [baseUri] where possible. + static Map toJson(PackageConfig configuration, + [Uri /*?*/ baseUri]) => + packageConfigToJson(configuration, baseUri); + /// The configuration version number. /// /// Currently this is 1 or 2, where diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 39633fe4b..f68a9ea75 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -8,6 +8,8 @@ import "util.dart"; export "package_config.dart"; +// Implementations of the main data types exposed by the API of this package. + class SimplePackageConfig implements PackageConfig { final int version; final Map _packages; @@ -90,7 +92,7 @@ class SimplePackageConfig implements PackageConfig { onError(PackageConfigArgumentError( originalPackages, "packages", - "Packages ${package.name} and ${existingPackage.name}" + "Packages ${package.name} and ${existingPackage.name} " "have the same root directory: ${package.root}.\n")); } else { assert(error.isPackageRootConflict); @@ -126,7 +128,7 @@ class SimplePackageConfig implements PackageConfig { Package /*?*/ packageOf(Uri file) => _packageTree.packageOf(file); Uri /*?*/ resolve(Uri packageUri) { - String packageName = checkValidPackageUri(packageUri, "packageUri"); + var packageName = checkValidPackageUri(packageUri, "packageUri"); return _packages[packageName]?.packageUriRoot?.resolveUri( Uri(path: packageUri.path.substring(packageName.length + 1))); } @@ -187,7 +189,7 @@ class SimplePackage implements Package { LanguageVersion /*?*/ languageVersion, dynamic extraData, void onError(Object error)) { - bool fatalError = false; + var fatalError = false; var invalidIndex = checkPackageName(name); if (invalidIndex >= 0) { onError(PackageConfigFormatException( @@ -305,7 +307,7 @@ LanguageVersion parseLanguageVersion( abstract class _SimpleLanguageVersionBase implements LanguageVersion { int compareTo(LanguageVersion other) { - int result = major.compareTo(other.major); + var result = major.compareTo(other.major); if (result != 0) return result; return minor.compareTo(other.minor); } @@ -342,16 +344,32 @@ abstract class PackageTree { /// Packages of a package configuration ordered by root path. /// +/// A package has a root path and a package root path, where the latter +/// contains the files exposed by `package:` URIs. +/// /// A package is said to be inside another package if the root path URI of /// the latter is a prefix of the root path URI of the former. +/// /// No two packages of a package may have the same root path, so this /// path prefix ordering defines a tree-like partial ordering on packages /// of a configuration. /// +/// The package root path of a package must not be inside another package's +/// root path. +/// Entire other packages are allowed inside a package's root or +/// package root path. +/// /// The package tree contains an ordered mapping of unrelated packages /// (represented by their name) to their immediately nested packages' names. class MutablePackageTree implements PackageTree { + /// A list of packages that are not nested inside each other. final List packages = []; + + /// The tree of the immediately nested packages inside each package. + /// + /// Indexed by [Package.name]. + /// If a package has no nested packages (which is most often the case), + /// there is no tree object associated with it. Map /*?*/ _packageChildren; Iterable get allPackages sync* { @@ -365,30 +383,38 @@ class MutablePackageTree implements PackageTree { /// /// Reports a [ConflictException] if the added package conflicts with an /// existing package. - /// It conflicts if it has the same root path, or if the new package - /// contains the existing package's package root. + /// It conflicts if its root or package root is the same as another + /// package's root or package root, or is between the two. /// /// If a conflict is detected between [package] and a previous package, /// then [onError] is called with a [ConflictException] object /// and the [package] is not added to the tree. + /// + /// The packages are added in order of their root path. + /// It is never necessary to insert a node between two existing levels. void add(int start, SimplePackage package, void onError(Object error)) { var path = package.root.toString(); - for (var childPackage in packages) { - var childPath = childPackage.root.toString(); - assert(childPath.length > start); - assert(path.startsWith(childPath.substring(0, start))); - if (_beginsWith(start, childPath, path)) { - var childPathLength = childPath.length; - if (path.length == childPathLength) { - onError(ConflictException.root(package, childPackage)); + for (var treePackage in packages) { + // Check is package is inside treePackage. + var treePackagePath = treePackage.root.toString(); + assert(treePackagePath.length > start); + assert(path.startsWith(treePackagePath.substring(0, start))); + if (_beginsWith(start, treePackagePath, path)) { + // Package *is* inside treePackage. + var treePackagePathLength = treePackagePath.length; + if (path.length == treePackagePathLength) { + // Has same root. Do not add package. + onError(ConflictException.root(package, treePackage)); return; } - var childPackageRoot = childPackage.packageUriRoot.toString(); - if (_beginsWith(childPathLength, childPackageRoot, path)) { - onError(ConflictException.packageRoot(package, childPackage)); + var treePackageUriRoot = treePackage.packageUriRoot.toString(); + if (_beginsWith(treePackagePathLength, path, treePackageUriRoot)) { + // The treePackage's package root is inside package, which is inside + // the treePackage. This is not allowed. + onError(ConflictException.packageRoot(package, treePackage)); return; } - _treeOf(childPackage).add(childPathLength, package, onError); + _treeOf(treePackage).add(treePackagePathLength, package, onError); return; } } @@ -454,7 +480,7 @@ class EmptyPackageTree implements PackageTree { /// already have been matched. bool _beginsWith(int start, String parentPath, String longerPath) { if (longerPath.length < parentPath.length) return false; - for (int i = start; i < parentPath.length; i++) { + for (var i = start; i < parentPath.length; i++) { if (longerPath.codeUnitAt(i) != parentPath.codeUnitAt(i)) return false; } return true; diff --git a/pkgs/package_config/lib/src/package_config_io.dart b/pkgs/package_config/lib/src/package_config_io.dart new file mode 100644 index 000000000..d59972f9a --- /dev/null +++ b/pkgs/package_config/lib/src/package_config_io.dart @@ -0,0 +1,155 @@ +// Copyright (c) 2019, 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. + +// dart:io dependent functionality for reading and writing configuration files. + +import "dart:convert"; +import "dart:io"; +import "dart:typed_data"; + +import "discovery.dart" show packageConfigJsonPath; +import "errors.dart"; +import "package_config_impl.dart"; +import "package_config_json.dart"; +import "packages_file.dart" as packages_file; +import "util.dart"; + +/// Reads a package configuration file. +/// +/// Detects whether the [file] is a version one `.packages` file or +/// a version two `package_config.json` file. +/// +/// If the [file] is a `.packages` file and [preferNewest] is true, +/// first checks whether there is an adjacent `.dart_tool/package_config.json` +/// file, and if so, reads that instead. +/// If [preferNewset] is false, the specified file is loaded even if it is +/// a `.packages` file and there is an available `package_config.json` file. +/// +/// The file must exist and be a normal file. +Future readAnyConfigFile( + File file, bool preferNewest, void onError(Object error)) async { + Uint8List bytes; + try { + bytes = await file.readAsBytes(); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } + var firstChar = firstNonWhitespaceChar(bytes); + if (firstChar != $lbrace) { + // Definitely not a JSON object, probably a .packages. + if (preferNewest) { + var alternateFile = File( + pathJoin(dirName(file.path), ".dart_tool", "package_config.json")); + if (alternateFile.existsSync()) { + Uint8List /*?*/ bytes; + try { + bytes = await alternateFile.readAsBytes(); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } + if (bytes != null) { + return parsePackageConfigBytes(bytes, alternateFile.uri, onError); + } + } + } + return packages_file.parse(bytes, file.uri, onError); + } + return parsePackageConfigBytes(bytes, file.uri, onError); +} + +/// Like [readAnyConfigFile] but uses a URI and an optional loader. +Future readAnyConfigFileUri( + Uri file, + Future loader(Uri uri) /*?*/, + void onError(Object error), + bool preferNewest) async { + if (file.isScheme("package")) { + throw PackageConfigArgumentError( + file, "file", "Must not be a package: URI"); + } + if (loader == null) { + if (file.isScheme("file")) { + return readAnyConfigFile(File.fromUri(file), preferNewest, onError); + } + loader = defaultLoader; + } + Uint8List bytes; + try { + bytes = await loader(file); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } + if (bytes == null) { + onError(PackageConfigArgumentError( + file.toString(), "file", "File cannot be read")); + return const SimplePackageConfig.empty(); + } + var firstChar = firstNonWhitespaceChar(bytes); + if (firstChar != $lbrace) { + // Definitely not a JSON object, probably a .packages. + if (preferNewest) { + // Check if there is a package_config.json file. + var alternateFile = file.resolveUri(packageConfigJsonPath); + Uint8List alternateBytes; + try { + alternateBytes = await loader(alternateFile); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } + if (alternateBytes != null) { + return parsePackageConfigBytes(alternateBytes, alternateFile, onError); + } + } + return packages_file.parse(bytes, file, onError); + } + return parsePackageConfigBytes(bytes, file, onError); +} + +Future readPackageConfigJsonFile( + File file, void onError(Object error)) async { + Uint8List bytes; + try { + bytes = await file.readAsBytes(); + } catch (error) { + onError(error); + return const SimplePackageConfig.empty(); + } + return parsePackageConfigBytes(bytes, file.uri, onError); +} + +Future readDotPackagesFile( + File file, void onError(Object error)) async { + Uint8List bytes; + try { + bytes = await file.readAsBytes(); + } catch (error) { + onError(error); + return const SimplePackageConfig.empty(); + } + return packages_file.parse(bytes, file.uri, onError); +} + +Future writePackageConfigJsonFile( + PackageConfig config, Directory targetDirectory) async { + // Write .dart_tool/package_config.json first. + var file = + File(pathJoin(targetDirectory.path, ".dart_tool", "package_config.json")); + var baseUri = file.uri; + var sink = file.openWrite(encoding: utf8); + writePackageConfigJsonUtf8(config, baseUri, sink); + var doneJson = sink.close(); + + // Write .packages too. + file = File(pathJoin(targetDirectory.path, ".packages")); + baseUri = file.uri; + sink = file.openWrite(encoding: utf8); + writeDotPackages(config, baseUri, sink); + var donePackages = sink.close(); + + await Future.wait([doneJson, donePackages]); +} diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index f56c91271..b9b34165b 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -2,11 +2,11 @@ // 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. +// Parsing and serialization of package configurations. + import "dart:convert"; -import "dart:io"; import "dart:typed_data"; -import "discovery.dart" show packageConfigJsonPath; import "errors.dart"; import "package_config_impl.dart"; import "packages_file.dart" as packages_file; @@ -30,125 +30,6 @@ const String _generatedKey = "generated"; const String _generatorKey = "generator"; const String _generatorVersionKey = "generatorVersion"; -/// Reads a package configuration file. -/// -/// Detects whether the [file] is a version one `.packages` file or -/// a version two `package_config.json` file. -/// -/// If the [file] is a `.packages` file and [preferNewest] is true, -/// first checks whether there is an adjacent `.dart_tool/package_config.json` -/// file, and if so, reads that instead. -/// If [preferNewset] is false, the specified file is loaded even if it is -/// a `.packages` file and there is an available `package_config.json` file. -/// -/// The file must exist and be a normal file. -Future readAnyConfigFile( - File file, bool preferNewest, void onError(Object error)) async { - Uint8List bytes; - try { - bytes = await file.readAsBytes(); - } catch (e) { - onError(e); - return const SimplePackageConfig.empty(); - } - int firstChar = firstNonWhitespaceChar(bytes); - if (firstChar != $lbrace) { - // Definitely not a JSON object, probably a .packages. - if (preferNewest) { - var alternateFile = File( - pathJoin(dirName(file.path), ".dart_tool", "package_config.json")); - if (alternateFile.existsSync()) { - Uint8List /*?*/ bytes; - try { - bytes = await alternateFile.readAsBytes(); - } catch (e) { - onError(e); - return const SimplePackageConfig.empty(); - } - if (bytes != null) { - return parsePackageConfigBytes(bytes, alternateFile.uri, onError); - } - } - } - return packages_file.parse(bytes, file.uri, onError); - } - return parsePackageConfigBytes(bytes, file.uri, onError); -} - -/// Like [readAnyConfigFile] but uses a URI and an optional loader. -Future readAnyConfigFileUri( - Uri file, - Future loader(Uri uri) /*?*/, - void onError(Object error), - bool preferNewest) async { - if (file.isScheme("package")) { - throw PackageConfigArgumentError( - file, "file", "Must not be a package: URI"); - } - if (loader == null) { - if (file.isScheme("file")) { - return readAnyConfigFile(File.fromUri(file), preferNewest, onError); - } - loader = defaultLoader; - } - Uint8List bytes; - try { - bytes = await loader(file); - } catch (e) { - onError(e); - return const SimplePackageConfig.empty(); - } - if (bytes == null) { - onError(PackageConfigArgumentError( - file.toString(), "file", "File cannot be read")); - return const SimplePackageConfig.empty(); - } - int firstChar = firstNonWhitespaceChar(bytes); - if (firstChar != $lbrace) { - // Definitely not a JSON object, probably a .packages. - if (preferNewest) { - // Check if there is a package_config.json file. - var alternateFile = file.resolveUri(packageConfigJsonPath); - Uint8List alternateBytes; - try { - alternateBytes = await loader(alternateFile); - } catch (e) { - onError(e); - return const SimplePackageConfig.empty(); - } - if (alternateBytes != null) { - return parsePackageConfigBytes(alternateBytes, alternateFile, onError); - } - } - return packages_file.parse(bytes, file, onError); - } - return parsePackageConfigBytes(bytes, file, onError); -} - -Future readPackageConfigJsonFile( - File file, void onError(Object error)) async { - Uint8List bytes; - try { - bytes = await file.readAsBytes(); - } catch (error) { - onError(error); - return const SimplePackageConfig.empty(); - } - return parsePackageConfigBytes(bytes, file.uri, onError); -} - -Future readDotPackagesFile( - File file, void onError(Object error)) async { - Uint8List bytes; - try { - bytes = await file.readAsBytes(); - } catch (error) { - onError(error); - return const SimplePackageConfig.empty(); - } - return packages_file.parse(bytes, file.uri, onError); -} - final _jsonUtf8Decoder = json.fuse(utf8).decoder; PackageConfig parsePackageConfigBytes( @@ -164,6 +45,18 @@ PackageConfig parsePackageConfigBytes( return parsePackageConfigJson(jsonObject, file, onError); } +PackageConfig parsePackageConfigString( + String source, Uri file, void onError(Object error)) { + var jsonObject; + try { + jsonObject = jsonDecode(source); + } on FormatException catch (e) { + onError(PackageConfigFormatException(e.message, e.source, e.offset)); + return const SimplePackageConfig.empty(); + } + return parsePackageConfigJson(jsonObject, file, onError); +} + /// Creates a [PackageConfig] from a parsed JSON-like object structure. /// /// The [json] argument must be a JSON object (`Map`) @@ -221,9 +114,9 @@ PackageConfig parsePackageConfigJson( String /*?*/ packageUri; String /*?*/ languageVersion; Map /*?*/ extraData; - bool hasName = false; - bool hasRoot = false; - bool hasVersion = false; + var hasName = false; + var hasRoot = false; + var hasVersion = false; entry.forEach((key, value) { switch (key) { case _nameKey: @@ -253,9 +146,9 @@ PackageConfig parsePackageConfigJson( onError(PackageConfigFormatException("Missing rootUri entry", entry)); } if (name == null || rootUri == null) return null; - Uri root = baseLocation.resolve(rootUri); + var root = baseLocation.resolve(rootUri); if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/"); - Uri packageRoot = root; + var packageRoot = root; if (packageUri != null) packageRoot = root.resolve(packageUri); if (!packageRoot.path.endsWith("/")) { packageRoot = packageRoot.replace(path: packageRoot.path + "/"); @@ -281,7 +174,7 @@ PackageConfig parsePackageConfigJson( var map = checkType>(json, "value"); if (map == null) return const SimplePackageConfig.empty(); - Map /*?*/ extraData = null; + Map /*?*/ extraData; List /*?*/ packageList; int /*?*/ configVersion; map.forEach((key, value) { @@ -326,31 +219,45 @@ PackageConfig parsePackageConfigJson( }); } -Future writePackageConfigJson( - PackageConfig config, Directory targetDirectory) async { - // Write .dart_tool/package_config.json first. - var file = - File(pathJoin(targetDirectory.path, ".dart_tool", "package_config.json")); - var baseUri = file.uri; - var extraData = config.extraData; - var data = { - _configVersionKey: PackageConfig.maxVersion, - _packagesKey: [ - for (var package in config.packages) - { - _nameKey: package.name, - _rootUriKey: relativizeUri(package.root, baseUri), - if (package.root != package.packageUriRoot) - _packageUriKey: relativizeUri(package.packageUriRoot, package.root), - if (package.languageVersion != null && - package.languageVersion is! InvalidLanguageVersion) - _languageVersionKey: package.languageVersion.toString(), - ...?_extractExtraData(package.extraData, _packageNames), - } - ], - ...?_extractExtraData(config.extraData, _topNames), - }; +final _jsonUtf8Encoder = JsonUtf8Encoder(" "); + +void writePackageConfigJsonUtf8( + PackageConfig config, Uri baseUri, Sink> output) { + // Can be optimized. + var data = packageConfigToJson(config, baseUri); + output.add(_jsonUtf8Encoder.convert(data) as Uint8List); +} + +void writePackageConfigJsonString( + PackageConfig config, Uri baseUri, StringSink output) { + // Can be optimized. + var data = packageConfigToJson(config, baseUri); + output.write(JsonEncoder.withIndent(" ").convert(data) as Uint8List); +} +Map packageConfigToJson(PackageConfig config, Uri baseUri) => + { + ...?_extractExtraData(config.extraData, _topNames), + _configVersionKey: PackageConfig.maxVersion, + _packagesKey: [ + for (var package in config.packages) + { + _nameKey: package.name, + _rootUriKey: relativizeUri(package.root, baseUri).toString(), + if (package.root != package.packageUriRoot) + _packageUriKey: + relativizeUri(package.packageUriRoot, package.root) + .toString(), + if (package.languageVersion != null && + package.languageVersion is! InvalidLanguageVersion) + _languageVersionKey: package.languageVersion.toString(), + ...?_extractExtraData(package.extraData, _packageNames), + } + ], + }; + +void writeDotPackages(PackageConfig config, Uri baseUri, StringSink output) { + var extraData = config.extraData; // Write .packages too. String /*?*/ comment; if (extraData != null) { @@ -363,15 +270,8 @@ Future writePackageConfigJson( "${generated != null ? " on $generated" : ""}."; } } - file = File(pathJoin(targetDirectory.path, ".packages")); - baseUri = file.uri; - var buffer = StringBuffer(); - packages_file.write(buffer, config, baseUri: baseUri, comment: comment); - - await Future.wait([ - file.writeAsString(JsonEncoder.withIndent(" ").convert(data)), - file.writeAsString(buffer.toString()), - ]); + packages_file.write(output, config, baseUri: baseUri, comment: comment); + return; } /// If "extraData" is a JSON map, then return it, otherwise return null. diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index 475a782a2..e65e7e8a6 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -31,15 +31,15 @@ PackageConfig parse( baseLocation, "baseLocation", "Must not be a package: URI")); return PackageConfig.empty; } - int index = 0; - List packages = []; - Set packageNames = {}; + var index = 0; + var packages = []; + var packageNames = {}; while (index < source.length) { - bool ignoreLine = false; - int start = index; - int separatorIndex = -1; - int end = source.length; - int char = source[index++]; + var ignoreLine = false; + var start = index; + var separatorIndex = -1; + var end = source.length; + var char = source[index++]; if (char == $cr || char == $lf) { continue; } @@ -50,8 +50,8 @@ PackageConfig parse( } else { ignoreLine = char == $hash; // Ignore if comment. } - int queryStart = -1; - int fragmentStart = -1; + var queryStart = -1; + var fragmentStart = -1; while (index < source.length) { char = source[index++]; if (char == $colon && separatorIndex < 0) { @@ -72,7 +72,7 @@ PackageConfig parse( continue; } var packageName = String.fromCharCodes(source, start, separatorIndex); - int invalidIndex = checkPackageName(packageName); + var invalidIndex = checkPackageName(packageName); if (invalidIndex >= 0) { onError(PackageConfigFormatException( "Not a valid package name", source, start + invalidIndex)); diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart new file mode 100644 index 000000000..19f103922 --- /dev/null +++ b/pkgs/package_config/lib/src/packages_impl.dart @@ -0,0 +1,128 @@ +// Copyright (c) 2015, 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. + +/// Implementations of [Packages] that may be used in either server or browser +/// based applications. For implementations that can only run in the browser, +/// see [package_config.packages_io_impl]. +@Deprecated("Use the package_config.json based API") +library package_config.packages_impl; + +import "dart:collection" show UnmodifiableMapView; + +import "../packages.dart"; +import "util.dart" show checkValidPackageUri; + +/// A [Packages] null-object. +class NoPackages implements Packages { + const NoPackages(); + + Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { + var packageName = checkValidPackageUri(packageUri, "packageUri"); + if (notFound != null) return notFound(packageUri); + throw ArgumentError.value( + packageUri, "packageUri", 'No package named "$packageName"'); + } + + Iterable get packages => Iterable.empty(); + + Map asMap() => const {}; + + String get defaultPackageName => null; + + String packageMetadata(String packageName, String key) => null; + + String libraryMetadata(Uri libraryUri, String key) => null; +} + +/// Base class for [Packages] implementations. +/// +/// This class implements the [resolve] method in terms of a private +/// member +abstract class PackagesBase implements Packages { + Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { + packageUri = packageUri.normalizePath(); + var packageName = checkValidPackageUri(packageUri, "packageUri"); + var packageBase = getBase(packageName); + if (packageBase == null) { + if (notFound != null) return notFound(packageUri); + throw ArgumentError.value( + packageUri, "packageUri", 'No package named "$packageName"'); + } + var packagePath = packageUri.path.substring(packageName.length + 1); + return packageBase.resolve(packagePath); + } + + /// Find a base location for a package name. + /// + /// Returns `null` if no package exists with that name, and that can be + /// determined. + Uri getBase(String packageName); + + String get defaultPackageName => null; + + String packageMetadata(String packageName, String key) => null; + + String libraryMetadata(Uri libraryUri, String key) => null; +} + +/// A [Packages] implementation based on an existing map. +class MapPackages extends PackagesBase { + final Map _mapping; + MapPackages(this._mapping); + + Uri getBase(String packageName) => + packageName.isEmpty ? null : _mapping[packageName]; + + Iterable get packages => _mapping.keys; + + Map asMap() => UnmodifiableMapView(_mapping); + + String get defaultPackageName => _mapping[""]?.toString(); + + String packageMetadata(String packageName, String key) { + if (packageName.isEmpty) return null; + var uri = _mapping[packageName]; + if (uri == null || !uri.hasFragment) return null; + // This can be optimized, either by caching the map or by + // parsing incrementally instead of parsing the entire fragment. + return Uri.splitQueryString(uri.fragment)[key]; + } + + String libraryMetadata(Uri libraryUri, String key) { + if (libraryUri.isScheme("package")) { + return packageMetadata(libraryUri.pathSegments.first, key); + } + var defaultPackageNameUri = _mapping[""]; + if (defaultPackageNameUri != null) { + return packageMetadata(defaultPackageNameUri.toString(), key); + } + return null; + } +} + +/// A [Packages] implementation based on a remote (e.g., HTTP) directory. +/// +/// There is no way to detect which packages exist short of trying to use +/// them. You can't necessarily check whether a directory exists, +/// except by checking for a know file in the directory. +class NonFilePackagesDirectoryPackages extends PackagesBase { + final Uri _packageBase; + NonFilePackagesDirectoryPackages(this._packageBase); + + Uri getBase(String packageName) => _packageBase.resolve("$packageName/"); + + Error _failListingPackages() { + return UnsupportedError( + "Cannot list packages for a ${_packageBase.scheme}: " + "based package root"); + } + + Iterable get packages { + throw _failListingPackages(); + } + + Map asMap() { + throw _failListingPackages(); + } +} diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart new file mode 100644 index 000000000..b2277e7e0 --- /dev/null +++ b/pkgs/package_config/lib/src/packages_io_impl.dart @@ -0,0 +1,46 @@ +// Copyright (c) 2015, 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. + +/// Implementations of [Packages] that can only be used in server based +/// applications. +@Deprecated("Use the package_config.json based API") +library package_config.packages_io_impl; + +import "dart:collection" show UnmodifiableMapView; +import "dart:io" show Directory; + +import "packages_impl.dart"; + +import "util.dart"; + +/// A [Packages] implementation based on a local directory. +class FilePackagesDirectoryPackages extends PackagesBase { + final Directory _packageDir; + final Map _packageToBaseUriMap = {}; + + FilePackagesDirectoryPackages(this._packageDir); + + Uri getBase(String packageName) { + return _packageToBaseUriMap.putIfAbsent(packageName, () { + return Uri.file(pathJoin(_packageDir.path, packageName, '.')); + }); + } + + Iterable _listPackageNames() { + return _packageDir + .listSync() + .whereType() + .map((e) => fileName(e.path)); + } + + Iterable get packages => _listPackageNames(); + + Map asMap() { + var result = {}; + for (var packageName in _listPackageNames()) { + result[packageName] = getBase(packageName); + } + return UnmodifiableMapView(result); + } +} diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index f39027d00..548f61d98 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -31,8 +31,8 @@ bool isValidPackageName(String string) { /// or `string.length` if the string contains no non-'.' character. int checkPackageName(String string) { // Becomes non-zero if any non-'.' character is encountered. - int nonDot = 0; - for (int i = 0; i < string.length; i++) { + var nonDot = 0; + for (var i = 0; i < string.length; i++) { var c = string.codeUnitAt(i); if (c > 0x7f || _validPackageNameCharacters.codeUnitAt(c) <= $space) { return i; @@ -74,13 +74,13 @@ String checkValidPackageUri(Uri packageUri, String name) { throw PackageConfigArgumentError( packageUri, name, "Package URIs must not start with a '/'"); } - int firstSlash = packageUri.path.indexOf('/'); + var firstSlash = packageUri.path.indexOf('/'); if (firstSlash == -1) { throw PackageConfigArgumentError(packageUri, name, "Package URIs must start with the package name followed by a '/'"); } - String packageName = packageUri.path.substring(0, firstSlash); - int badIndex = checkPackageName(packageName); + var packageName = packageUri.path.substring(0, firstSlash); + var badIndex = checkPackageName(packageName); if (badIndex >= 0) { if (packageName.isEmpty) { throw PackageConfigArgumentError( @@ -91,7 +91,7 @@ String checkValidPackageUri(Uri packageUri, String name) { "Package names must contain at least one non-'.' character"); } assert(badIndex < packageName.length); - int badCharCode = packageName.codeUnitAt(badIndex); + var badCharCode = packageName.codeUnitAt(badIndex); var badChar = "U+" + badCharCode.toRadixString(16).padLeft(4, '0'); if (badCharCode >= 0x20 && badCharCode <= 0x7e) { // Printable character. @@ -131,7 +131,7 @@ bool isUriPrefix(Uri prefix, Uri path) { /// /// Used to heuristically detect whether a file is a JSON file or an .ini file. int firstNonWhitespaceChar(List bytes) { - for (int i = 0; i < bytes.length; i++) { + for (var i = 0; i < bytes.length; i++) { var char = bytes[i]; if (char != 0x20 && char != 0x09 && char != 0x0a && char != 0x0d) { return char; @@ -156,7 +156,8 @@ int firstNonWhitespaceChar(List bytes) { /// `baseUri.resolveUri(result) == uri`, /// /// The `baseUri` must be absolute. -Uri relativizeUri(Uri uri, Uri baseUri) { +Uri relativizeUri(Uri uri, Uri /*?*/ baseUri) { + if (baseUri == null) return uri; assert(baseUri.isAbsolute); if (uri.hasQuery || uri.hasFragment) { uri = Uri( @@ -185,12 +186,12 @@ Uri relativizeUri(Uri uri, Uri baseUri) { } baseUri = baseUri.normalizePath(); - List base = [...baseUri.pathSegments]; + var base = [...baseUri.pathSegments]; if (base.isNotEmpty) base.removeLast(); uri = uri.normalizePath(); - List target = [...uri.pathSegments]; + var target = [...uri.pathSegments]; if (target.isNotEmpty && target.last.isEmpty) target.removeLast(); - int index = 0; + var index = 0; while (index < base.length && index < target.length) { if (base[index] != target[index]) { break; @@ -204,7 +205,7 @@ Uri relativizeUri(Uri uri, Uri baseUri) { return Uri(path: target.skip(index).join('/')); } else if (index > 0) { var buffer = StringBuffer(); - for (int n = base.length - index; n > 0; --n) { + for (var n = base.length - index; n > 0; --n) { buffer.write("../"); } buffer.writeAll(target.skip(index), "/"); @@ -231,14 +232,14 @@ Future defaultLoader(Uri uri) async { Future _httpGet(Uri uri) async { assert(uri.isScheme("http") || uri.isScheme("https")); - HttpClient client = new HttpClient(); - HttpClientRequest request = await client.getUrl(uri); - HttpClientResponse response = await request.close(); + var client = HttpClient(); + var request = await client.getUrl(uri); + var response = await request.close(); if (response.statusCode != HttpStatus.ok) { return null; } - List> splitContent = await response.toList(); - int totalLength = 0; + var splitContent = await response.toList(); + var totalLength = 0; if (splitContent.length == 1) { var part = splitContent[0]; if (part is Uint8List) { @@ -248,8 +249,8 @@ Future _httpGet(Uri uri) async { for (var list in splitContent) { totalLength += list.length; } - Uint8List result = new Uint8List(totalLength); - int offset = 0; + var result = Uint8List(totalLength); + var offset = 0; for (Uint8List contentPart in splitContent) { result.setRange(offset, offset + contentPart.length, contentPart); offset += contentPart.length; @@ -264,7 +265,7 @@ Future _httpGet(Uri uri) async { /// path separator occurs in the string. String fileName(String path) { var separator = Platform.pathSeparator; - int lastSeparator = path.lastIndexOf(separator); + var lastSeparator = path.lastIndexOf(separator); if (lastSeparator < 0) return path; return path.substring(lastSeparator + separator.length); } @@ -276,7 +277,7 @@ String fileName(String path) { /// path separator occurs in the string. String dirName(String path) { var separator = Platform.pathSeparator; - int lastSeparator = path.lastIndexOf(separator); + var lastSeparator = path.lastIndexOf(separator); if (lastSeparator < 0) return ""; return path.substring(0, lastSeparator); } @@ -287,11 +288,11 @@ String dirName(String path) { /// inserted. String pathJoin(String part1, String part2, [String part3]) { var separator = Platform.pathSeparator; - String separator1 = part1.endsWith(separator) ? "" : separator; + var separator1 = part1.endsWith(separator) ? "" : separator; if (part3 == null) { return "$part1$separator1$part2"; } - String separator2 = part2.endsWith(separator) ? "" : separator; + var separator2 = part2.endsWith(separator) ? "" : separator; return "$part1$separator1$part2$separator2$part3"; } @@ -301,7 +302,7 @@ String pathJoin(String part1, String part2, [String part3]) { /// inserted. String pathJoinAll(Iterable parts) { var buffer = StringBuffer(); - String separator = ""; + var separator = ""; for (var part in parts) { buffer..write(separator)..write(part); separator = diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 7f47d2e2c..20a39c767 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 3.0.0-dev +version: 1.9.0-dev description: Support for working with Package Configuration files. author: Dart Team homepage: https://github.com/dart-lang/package_config @@ -8,4 +8,6 @@ environment: sdk: '>=2.7.0 <3.0.0' dev_dependencies: - test: ^1.3.0 + test: ^1.6.4 + matcher: ^0.12.5 + pedantic: 1.8.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 23efc6741..e4c93a592 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -50,7 +50,7 @@ void validatePackagesFile(PackageConfig resolver, Directory directory) { unorderedEquals(["foo", "bar", "baz"])); } -main() { +void main() { group("findPackages", () { // Finds package_config.json if there. fileTest("package_config.json", { @@ -61,7 +61,7 @@ main() { "package_config.json": packageConfigFile, } }, (Directory directory) async { - PackageConfig config = await findPackageConfig(directory); + var config = await findPackageConfig(directory); expect(config.version, 2); // Found package_config.json file. validatePackagesFile(config, directory); }); @@ -72,7 +72,7 @@ main() { "script.dart": "main(){}", "packages": {"shouldNotBeFound": {}} }, (Directory directory) async { - PackageConfig config = await findPackageConfig(directory); + var config = await findPackageConfig(directory); expect(config.version, 1); // Found .packages file. validatePackagesFile(config, directory); }); @@ -87,8 +87,7 @@ main() { "script.dart": "main(){}", } }, (Directory directory) async { - PackageConfig config = - await findPackageConfig(subdir(directory, "subdir/")); + var config = await findPackageConfig(subdir(directory, "subdir/")); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -98,7 +97,7 @@ main() { ".packages": packagesFile, "subdir": {"script.dart": "main(){}"} }, (Directory directory) async { - PackageConfig config; + var config; config = await findPackageConfig(subdir(directory, "subdir/")); expect(config.version, 1); validatePackagesFile(config, directory); @@ -110,7 +109,7 @@ main() { "foo": {}, } }, (Directory directory) async { - PackageConfig config = await findPackageConfig(directory); + var config = await findPackageConfig(directory); expect(config, null); }); @@ -152,7 +151,7 @@ main() { fileTest("invalid .packages", { ".packages": "not a .packages file", }, (Directory directory) async { - bool hadError = false; + var hadError = false; await findPackageConfig(directory, onError: expectAsync1((error) { hadError = true; @@ -164,7 +163,7 @@ main() { fileTest("invalid .packages as JSON", { ".packages": packageConfigFile, }, (Directory directory) async { - bool hadError = false; + var hadError = false; await findPackageConfig(directory, onError: expectAsync1((error) { hadError = true; @@ -178,7 +177,7 @@ main() { "package_config.json": "not a JSON file", } }, (Directory directory) async { - bool hadError = false; + var hadError = false; await findPackageConfig(directory, onError: expectAsync1((error) { hadError = true; @@ -192,7 +191,7 @@ main() { "package_config.json": packagesFile, } }, (Directory directory) async { - bool hadError = false; + var hadError = false; await findPackageConfig(directory, onError: expectAsync1((error) { hadError = true; @@ -213,23 +212,22 @@ main() { }, }; fileTest("directly", files, (Directory directory) async { - File file = + var file = dirFile(subdir(directory, ".dart_tool"), "package_config.json"); - PackageConfig config = await loadPackageConfig(file); + var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); fileTest("indirectly through .packages", files, (Directory directory) async { - File file = dirFile(directory, ".packages"); - PackageConfig config = await loadPackageConfig(file); + var file = dirFile(directory, ".packages"); + var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); fileTest("prefer .packages", files, (Directory directory) async { - File file = dirFile(directory, ".packages"); - PackageConfig config = - await loadPackageConfig(file, preferNewest: false); + var file = dirFile(directory, ".packages"); + var config = await loadPackageConfig(file, preferNewest: false); expect(config.version, 1); validatePackagesFile(config, directory); }); @@ -241,8 +239,8 @@ main() { "pheldagriff": packageConfigFile, }, }, (Directory directory) async { - File file = dirFile(directory, "subdir/pheldagriff"); - PackageConfig config = await loadPackageConfig(file); + var file = dirFile(directory, "subdir/pheldagriff"); + var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -252,8 +250,8 @@ main() { ".packages": packageConfigFile, }, }, (Directory directory) async { - File file = dirFile(directory, "subdir/.packages"); - PackageConfig config = await loadPackageConfig(file); + var file = dirFile(directory, "subdir/.packages"); + var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -261,8 +259,8 @@ main() { fileTest(".packages", { ".packages": packagesFile, }, (Directory directory) async { - File file = dirFile(directory, ".packages"); - PackageConfig config = await loadPackageConfig(file); + var file = dirFile(directory, ".packages"); + var config = await loadPackageConfig(file); expect(config.version, 1); validatePackagesFile(config, directory); }); @@ -270,21 +268,21 @@ main() { fileTest(".packages non-default name", { "pheldagriff": packagesFile, }, (Directory directory) async { - File file = dirFile(directory, "pheldagriff"); - PackageConfig config = await loadPackageConfig(file); + var file = dirFile(directory, "pheldagriff"); + var config = await loadPackageConfig(file); expect(config.version, 1); validatePackagesFile(config, directory); }); fileTest("no config found", {}, (Directory directory) { - File file = dirFile(directory, "anyname"); + var file = dirFile(directory, "anyname"); expect(() => loadPackageConfig(file), throwsA(TypeMatcher())); }); fileTest("no config found, handled", {}, (Directory directory) async { - File file = dirFile(directory, "anyname"); - bool hadError = false; + var file = dirFile(directory, "anyname"); + var hadError = false; await loadPackageConfig(file, onError: expectAsync1((error) { hadError = true; @@ -296,7 +294,7 @@ main() { fileTest("specified file syntax error", { "anyname": "syntax error", }, (Directory directory) { - File file = dirFile(directory, "anyname"); + var file = dirFile(directory, "anyname"); expect(() => loadPackageConfig(file), throwsFormatException); }); @@ -307,8 +305,8 @@ main() { "package_config.json": packageConfigFile, }, }, (Directory directory) async { - File file = dirFile(directory, "anyname"); - PackageConfig config = await loadPackageConfig(file); + var file = dirFile(directory, "anyname"); + var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -317,7 +315,7 @@ main() { fileTest("file syntax error with {", { ".packages": "{syntax error", }, (Directory directory) { - File file = dirFile(directory, ".packages"); + var file = dirFile(directory, ".packages"); expect(() => loadPackageConfig(file), throwsFormatException); }); }); diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 081ec608f..109693c4c 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -4,8 +4,6 @@ library package_config.discovery_test; -import 'dart:io'; - import "package:test/test.dart"; import "package:package_config/package_config.dart"; @@ -51,7 +49,7 @@ void validatePackagesFile(PackageConfig resolver, Uri directory) { unorderedEquals(["foo", "bar", "baz"])); } -main() { +void main() { group("findPackages", () { // Finds package_config.json if there. loaderTest("package_config.json", { @@ -62,8 +60,7 @@ main() { "package_config.json": packageConfigFile, } }, (Uri directory, loader) async { - PackageConfig config = - await findPackageConfigUri(directory, loader: loader); + var config = await findPackageConfigUri(directory, loader: loader); expect(config.version, 2); // Found package_config.json file. validatePackagesFile(config, directory); }); @@ -74,8 +71,7 @@ main() { "script.dart": "main(){}", "packages": {"shouldNotBeFound": {}} }, (Uri directory, loader) async { - PackageConfig config = - await findPackageConfigUri(directory, loader: loader); + var config = await findPackageConfigUri(directory, loader: loader); expect(config.version, 1); // Found .packages file. validatePackagesFile(config, directory); }); @@ -90,8 +86,7 @@ main() { "script.dart": "main(){}", } }, (Uri directory, loader) async { - PackageConfig config = await findPackageConfigUri( - directory.resolve("subdir/"), + var config = await findPackageConfigUri(directory.resolve("subdir/"), loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); @@ -102,7 +97,7 @@ main() { ".packages": packagesFile, "subdir": {"script.dart": "main(){}"} }, (Uri directory, loader) async { - PackageConfig config; + var config; config = await findPackageConfigUri(directory.resolve("subdir/"), loader: loader); expect(config.version, 1); @@ -115,8 +110,7 @@ main() { "foo": {}, } }, (Uri directory, loader) async { - PackageConfig config = - await findPackageConfigUri(directory, loader: loader); + var config = await findPackageConfigUri(directory, loader: loader); expect(config, null); }); @@ -163,15 +157,15 @@ main() { }, }; loaderTest("directly", files, (Uri directory, loader) async { - Uri file = directory.resolve(".dart_tool/package_config.json"); - PackageConfig config = await loadPackageConfigUri(file, loader: loader); + var file = directory.resolve(".dart_tool/package_config.json"); + var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); loaderTest("indirectly through .packages", files, (Uri directory, loader) async { - Uri file = directory.resolve(".packages"); - PackageConfig config = await loadPackageConfigUri(file, loader: loader); + var file = directory.resolve(".packages"); + var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -183,8 +177,8 @@ main() { "pheldagriff": packageConfigFile, }, }, (Uri directory, loader) async { - Uri file = directory.resolve("subdir/pheldagriff"); - PackageConfig config = await loadPackageConfigUri(file, loader: loader); + var file = directory.resolve("subdir/pheldagriff"); + var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -194,8 +188,8 @@ main() { ".packages": packageConfigFile, }, }, (Uri directory, loader) async { - Uri file = directory.resolve("subdir/.packages"); - PackageConfig config = await loadPackageConfigUri(file, loader: loader); + var file = directory.resolve("subdir/.packages"); + var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -203,8 +197,8 @@ main() { loaderTest(".packages", { ".packages": packagesFile, }, (Uri directory, loader) async { - Uri file = directory.resolve(".packages"); - PackageConfig config = await loadPackageConfigUri(file, loader: loader); + var file = directory.resolve(".packages"); + var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 1); validatePackagesFile(config, directory); }); @@ -212,22 +206,22 @@ main() { loaderTest(".packages non-default name", { "pheldagriff": packagesFile, }, (Uri directory, loader) async { - Uri file = directory.resolve("pheldagriff"); - PackageConfig config = await loadPackageConfigUri(file, loader: loader); + var file = directory.resolve("pheldagriff"); + var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 1); validatePackagesFile(config, directory); }); loaderTest("no config found", {}, (Uri directory, loader) { - Uri file = directory.resolve("anyname"); + var file = directory.resolve("anyname"); expect(() => loadPackageConfigUri(file, loader: loader), throwsA(isA())); }); loaderTest("no config found, handle error", {}, (Uri directory, loader) async { - Uri file = directory.resolve("anyname"); - bool hadError = false; + var file = directory.resolve("anyname"); + var hadError = false; await loadPackageConfigUri(file, loader: loader, onError: expectAsync1((error) { @@ -240,7 +234,7 @@ main() { loaderTest("specified file syntax error", { "anyname": "syntax error", }, (Uri directory, loader) { - Uri file = directory.resolve("anyname"); + var file = directory.resolve("anyname"); expect(() => loadPackageConfigUri(file, loader: loader), throwsFormatException); }); @@ -248,8 +242,8 @@ main() { loaderTest("specified file syntax error", { "anyname": "syntax error", }, (Uri directory, loader) async { - Uri file = directory.resolve("anyname"); - bool hadError = false; + var file = directory.resolve("anyname"); + var hadError = false; await loadPackageConfigUri(file, loader: loader, onError: expectAsync1((error) { @@ -266,8 +260,8 @@ main() { "package_config.json": packageConfigFile, }, }, (Uri directory, loader) async { - Uri file = directory.resolve("anyname"); - PackageConfig config = await loadPackageConfigUri(file, loader: loader); + var file = directory.resolve("anyname"); + var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); @@ -276,7 +270,7 @@ main() { loaderTest("file syntax error with {", { ".packages": "{syntax error", }, (Uri directory, loader) async { - Uri file = directory.resolve(".packages"); + var file = directory.resolve(".packages"); var hadError = false; await loadPackageConfigUri(file, loader: loader, diff --git a/pkgs/package_config/test/legacy/all.dart b/pkgs/package_config/test/legacy/all.dart new file mode 100644 index 000000000..22e2e4f9e --- /dev/null +++ b/pkgs/package_config/test/legacy/all.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2015, 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. + +@deprecated +library package_config.all_test; + +import "package:test/test.dart"; + +import "discovery_analysis_test.dart" as discovery_analysis; +import "discovery_test.dart" as discovery; +import "parse_test.dart" as parse; +import "parse_write_test.dart" as parse_write; + +void main() { + group("parse:", parse.main); + group("discovery:", discovery.main); + group("discovery-analysis:", discovery_analysis.main); + group("parse/write:", parse_write.main); +} diff --git a/pkgs/package_config/test/legacy/discovery_analysis_test.dart b/pkgs/package_config/test/legacy/discovery_analysis_test.dart new file mode 100644 index 000000000..7d08f7b92 --- /dev/null +++ b/pkgs/package_config/test/legacy/discovery_analysis_test.dart @@ -0,0 +1,127 @@ +// Copyright (c) 2015, 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. + +@deprecated +library package_config.discovery_analysis_test; + +import "dart:async"; +import "dart:io"; + +import "package:package_config/discovery_analysis.dart"; +import "package:package_config/packages.dart"; +import "package:path/path.dart" as path; +import "package:test/test.dart"; + +void main() { + fileTest("basic", { + ".packages": packagesFile, + "foo": {".packages": packagesFile}, + "bar": { + "packages": {"foo": {}, "bar": {}, "baz": {}} + }, + "baz": {} + }, (Directory directory) { + var dirUri = Uri.directory(directory.path); + var ctx = PackageContext.findAll(directory); + var root = ctx[directory]; + expect(root, same(ctx)); + validatePackagesFile(root.packages, dirUri); + var fooDir = sub(directory, "foo"); + var foo = ctx[fooDir]; + expect(identical(root, foo), isFalse); + validatePackagesFile(foo.packages, dirUri.resolve("foo/")); + var barDir = sub(directory, "bar"); + var bar = ctx[sub(directory, "bar")]; + validatePackagesDir(bar.packages, dirUri.resolve("bar/")); + var barbar = ctx[sub(barDir, "bar")]; + expect(barbar, same(bar)); // inherited. + var baz = ctx[sub(directory, "baz")]; + expect(baz, same(root)); // inherited. + + var map = ctx.asMap(); + expect(map.keys.map((dir) => dir.path), + unorderedEquals([directory.path, fooDir.path, barDir.path])); + return null; + }); +} + +Directory sub(Directory parent, String dirName) { + return Directory(path.join(parent.path, dirName)); +} + +const packagesFile = """ +# A comment +foo:file:///dart/packages/foo/ +bar:http://example.com/dart/packages/bar/ +baz:packages/baz/ +"""; + +void validatePackagesFile(Packages resolver, Uri location) { + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); +} + +void validatePackagesDir(Packages resolver, Uri location) { + // Expect three packages: foo, bar and baz + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(location.resolve("packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(location.resolve("packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + if (location.scheme == "file") { + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); + } else { + expect(() => resolver.packages, throwsUnsupportedError); + } +} + +Uri pkg(String packageName, String packagePath) { + var path; + if (packagePath.startsWith('/')) { + path = "$packageName$packagePath"; + } else { + path = "$packageName/$packagePath"; + } + return Uri(scheme: "package", path: path); +} + +/// Create a directory structure from [description] and run [fileTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a sub-dir, otherwise it's a file and the value is the content +/// as a string. +void fileTest( + String name, Map description, Future fileTest(Directory directory)) { + group("file-test", () { + var tempDir = Directory.systemTemp.createTempSync("file-test"); + setUp(() { + _createFiles(tempDir, description); + }); + tearDown(() { + tempDir.deleteSync(recursive: true); + }); + test(name, () => fileTest(tempDir)); + }); +} + +void _createFiles(Directory target, Map description) { + description.forEach((name, content) { + if (content is Map) { + var subDir = Directory(path.join(target.path, name)); + subDir.createSync(); + _createFiles(subDir, content); + } else { + var file = File(path.join(target.path, name)); + file.writeAsStringSync(content, flush: true); + } + }); +} diff --git a/pkgs/package_config/test/legacy/discovery_test.dart b/pkgs/package_config/test/legacy/discovery_test.dart new file mode 100644 index 000000000..684abcb4a --- /dev/null +++ b/pkgs/package_config/test/legacy/discovery_test.dart @@ -0,0 +1,328 @@ +// Copyright (c) 2015, 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. + +@deprecated +library package_config.discovery_test; + +import "dart:async"; +import "dart:io"; +import "package:test/test.dart"; +import "package:package_config/packages.dart"; +import "package:package_config/discovery.dart"; +import "package:path/path.dart" as path; + +const packagesFile = """ +# A comment +foo:file:///dart/packages/foo/ +bar:http://example.com/dart/packages/bar/ +baz:packages/baz/ +"""; + +void validatePackagesFile(Packages resolver, Uri location) { + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); +} + +void validatePackagesDir(Packages resolver, Uri location) { + // Expect three packages: foo, bar and baz + expect(resolver, isNotNull); + expect(resolver.resolve(pkg("foo", "bar/baz")), + equals(location.resolve("packages/foo/bar/baz"))); + expect(resolver.resolve(pkg("bar", "baz/qux")), + equals(location.resolve("packages/bar/baz/qux"))); + expect(resolver.resolve(pkg("baz", "qux/foo")), + equals(location.resolve("packages/baz/qux/foo"))); + if (location.scheme == "file") { + expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); + } else { + expect(() => resolver.packages, throwsUnsupportedError); + } +} + +Uri pkg(String packageName, String packagePath) { + var path; + if (packagePath.startsWith('/')) { + path = "$packageName$packagePath"; + } else { + path = "$packageName/$packagePath"; + } + return Uri(scheme: "package", path: path); +} + +void main() { + generalTest(".packages", { + ".packages": packagesFile, + "script.dart": "main(){}", + "packages": {"shouldNotBeFound": {}} + }, (Uri location) async { + Packages resolver; + resolver = await findPackages(location); + validatePackagesFile(resolver, location); + resolver = await findPackages(location.resolve("script.dart")); + validatePackagesFile(resolver, location); + var specificDiscovery = (location.scheme == "file") + ? findPackagesFromFile + : findPackagesFromNonFile; + resolver = await specificDiscovery(location); + validatePackagesFile(resolver, location); + resolver = await specificDiscovery(location.resolve("script.dart")); + validatePackagesFile(resolver, location); + }); + + generalTest("packages/", { + "packages": {"foo": {}, "bar": {}, "baz": {}}, + "script.dart": "main(){}" + }, (Uri location) async { + Packages resolver; + var isFile = (location.scheme == "file"); + resolver = await findPackages(location); + validatePackagesDir(resolver, location); + resolver = await findPackages(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + var specificDiscovery = + isFile ? findPackagesFromFile : findPackagesFromNonFile; + resolver = await specificDiscovery(location); + validatePackagesDir(resolver, location); + resolver = await specificDiscovery(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + }); + + generalTest("underscore packages", { + "packages": {"_foo": {}} + }, (Uri location) async { + var resolver = await findPackages(location); + expect(resolver.resolve(pkg("_foo", "foo.dart")), + equals(location.resolve("packages/_foo/foo.dart"))); + }); + + fileTest(".packages recursive", { + ".packages": packagesFile, + "subdir": {"script.dart": "main(){}"} + }, (Uri location) async { + Packages resolver; + resolver = await findPackages(location.resolve("subdir/")); + validatePackagesFile(resolver, location); + resolver = await findPackages(location.resolve("subdir/script.dart")); + validatePackagesFile(resolver, location); + resolver = await findPackagesFromFile(location.resolve("subdir/")); + validatePackagesFile(resolver, location); + resolver = + await findPackagesFromFile(location.resolve("subdir/script.dart")); + validatePackagesFile(resolver, location); + }); + + httpTest(".packages not recursive", { + ".packages": packagesFile, + "subdir": {"script.dart": "main(){}"} + }, (Uri location) async { + Packages resolver; + var subdir = location.resolve("subdir/"); + resolver = await findPackages(subdir); + validatePackagesDir(resolver, subdir); + resolver = await findPackages(subdir.resolve("script.dart")); + validatePackagesDir(resolver, subdir); + resolver = await findPackagesFromNonFile(subdir); + validatePackagesDir(resolver, subdir); + resolver = await findPackagesFromNonFile(subdir.resolve("script.dart")); + validatePackagesDir(resolver, subdir); + }); + + fileTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { + // A file: location with no .packages or packages returns + // Packages.noPackages. + Packages resolver; + resolver = await findPackages(location); + expect(resolver, same(Packages.noPackages)); + resolver = await findPackages(location.resolve("script.dart")); + expect(resolver, same(Packages.noPackages)); + resolver = findPackagesFromFile(location); + expect(resolver, same(Packages.noPackages)); + resolver = findPackagesFromFile(location.resolve("script.dart")); + expect(resolver, same(Packages.noPackages)); + }); + + httpTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { + // A non-file: location with no .packages or packages/: + // Assumes a packages dir exists, and resolves relative to that. + Packages resolver; + resolver = await findPackages(location); + validatePackagesDir(resolver, location); + resolver = await findPackages(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location.resolve("script.dart")); + validatePackagesDir(resolver, location); + }); + + test(".packages w/ loader", () async { + var location = Uri.parse("krutch://example.com/path/"); + Future> loader(Uri file) async { + if (file.path.endsWith(".packages")) { + return packagesFile.codeUnits; + } + throw "not found"; + } + + // A non-file: location with no .packages or packages/: + // Assumes a packages dir exists, and resolves relative to that. + Packages resolver; + resolver = await findPackages(location, loader: loader); + validatePackagesFile(resolver, location); + resolver = + await findPackages(location.resolve("script.dart"), loader: loader); + validatePackagesFile(resolver, location); + resolver = await findPackagesFromNonFile(location, loader: loader); + validatePackagesFile(resolver, location); + resolver = await findPackagesFromNonFile(location.resolve("script.dart"), + loader: loader); + validatePackagesFile(resolver, location); + }); + + test("no packages w/ loader", () async { + var location = Uri.parse("krutch://example.com/path/"); + Future> loader(Uri file) async { + throw "not found"; + } + + // A non-file: location with no .packages or packages/: + // Assumes a packages dir exists, and resolves relative to that. + Packages resolver; + resolver = await findPackages(location, loader: loader); + validatePackagesDir(resolver, location); + resolver = + await findPackages(location.resolve("script.dart"), loader: loader); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location, loader: loader); + validatePackagesDir(resolver, location); + resolver = await findPackagesFromNonFile(location.resolve("script.dart"), + loader: loader); + validatePackagesDir(resolver, location); + }); + + generalTest("loadPackagesFile", {".packages": packagesFile}, + (Uri directory) async { + var file = directory.resolve(".packages"); + var resolver = await loadPackagesFile(file); + validatePackagesFile(resolver, file); + }); + + generalTest( + "loadPackagesFile non-default name", {"pheldagriff": packagesFile}, + (Uri directory) async { + var file = directory.resolve("pheldagriff"); + var resolver = await loadPackagesFile(file); + validatePackagesFile(resolver, file); + }); + + test("loadPackagesFile w/ loader", () async { + Future> loader(Uri uri) async => packagesFile.codeUnits; + var file = Uri.parse("krutz://example.com/.packages"); + var resolver = await loadPackagesFile(file, loader: loader); + validatePackagesFile(resolver, file); + }); + + generalTest("loadPackagesFile not found", {}, (Uri directory) async { + var file = directory.resolve(".packages"); + expect( + loadPackagesFile(file), + throwsA(anyOf( + TypeMatcher(), TypeMatcher()))); + }); + + generalTest("loadPackagesFile syntax error", {".packages": "syntax error"}, + (Uri directory) async { + var file = directory.resolve(".packages"); + expect(loadPackagesFile(file), throwsFormatException); + }); + + generalTest("getPackagesDir", { + "packages": {"foo": {}, "bar": {}, "baz": {}} + }, (Uri directory) async { + var packages = directory.resolve("packages/"); + var resolver = getPackagesDirectory(packages); + var resolved = resolver.resolve(pkg("foo", "flip/flop")); + expect(resolved, packages.resolve("foo/flip/flop")); + }); +} + +/// Create a directory structure from [description] and run [fileTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a sub-dir, otherwise it's a file and the value is the content +/// as a string. +void fileTest(String name, Map description, Future fileTest(Uri directory)) { + group("file-test", () { + var tempDir = Directory.systemTemp.createTempSync("file-test"); + setUp(() { + _createFiles(tempDir, description); + }); + tearDown(() { + tempDir.deleteSync(recursive: true); + }); + test(name, () => fileTest(Uri.file(path.join(tempDir.path, ".")))); + }); +} + +/// HTTP-server the directory structure from [description] and run [htpTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a sub-dir, otherwise it's a file and the value is the content +/// as a string. +void httpTest(String name, Map description, Future httpTest(Uri directory)) { + group("http-test", () { + var serverSub; + var uri; + setUp(() { + return HttpServer.bind(InternetAddress.loopbackIPv4, 0).then((server) { + uri = Uri( + scheme: "http", host: "127.0.0.1", port: server.port, path: "/"); + serverSub = server.listen((HttpRequest request) { + // No error handling. + var path = request.uri.path; + if (path.startsWith('/')) path = path.substring(1); + if (path.endsWith('/')) path = path.substring(0, path.length - 1); + var parts = path.split('/'); + dynamic fileOrDir = description; + for (var i = 0; i < parts.length; i++) { + fileOrDir = fileOrDir[parts[i]]; + if (fileOrDir == null) { + request.response.statusCode = 404; + request.response.close(); + return; + } + } + request.response.write(fileOrDir); + request.response.close(); + }); + }); + }); + tearDown(() => serverSub.cancel()); + test(name, () => httpTest(uri)); + }); +} + +void generalTest(String name, Map description, Future action(Uri location)) { + fileTest(name, description, action); + httpTest(name, description, action); +} + +void _createFiles(Directory target, Map description) { + description.forEach((name, content) { + if (content is Map) { + var subDir = Directory(path.join(target.path, name)); + subDir.createSync(); + _createFiles(subDir, content); + } else { + var file = File(path.join(target.path, name)); + file.writeAsStringSync(content, flush: true); + } + }); +} diff --git a/pkgs/package_config/test/legacy/parse_test.dart b/pkgs/package_config/test/legacy/parse_test.dart new file mode 100644 index 000000000..b9cf1f8fd --- /dev/null +++ b/pkgs/package_config/test/legacy/parse_test.dart @@ -0,0 +1,246 @@ +// Copyright (c) 2015, 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. + +@deprecated +library package_config.parse_test; + +import "package:package_config/packages.dart"; +import "package:package_config/packages_file.dart" show parse; +import "package:package_config/src/packages_impl.dart"; +import "package:test/test.dart"; + +void main() { + var base = Uri.parse("file:///one/two/three/packages.map"); + test("empty", () { + var packages = doParse(emptySample, base); + expect(packages.asMap(), isEmpty); + }); + test("comment only", () { + var packages = doParse(commentOnlySample, base); + expect(packages.asMap(), isEmpty); + }); + test("empty lines only", () { + var packages = doParse(emptyLinesSample, base); + expect(packages.asMap(), isEmpty); + }); + + test("empty lines only", () { + var packages = doParse(emptyLinesSample, base); + expect(packages.asMap(), isEmpty); + }); + + test("single", () { + var packages = doParse(singleRelativeSample, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("single no slash", () { + var packages = doParse(singleRelativeSampleNoSlash, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("single no newline", () { + var packages = doParse(singleRelativeSampleNoNewline, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("single absolute authority", () { + var packages = doParse(singleAbsoluteSample, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(Uri.parse("http://example.com/some/where/bar/baz.dart"))); + }); + + test("single empty path", () { + var packages = doParse(singleEmptyPathSample, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.replace(path: "${base.path}/bar/baz.dart"))); + }); + + test("single absolute path", () { + var packages = doParse(singleAbsolutePathSample, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.replace(path: "/test/bar/baz.dart"))); + }); + + test("multiple", () { + var packages = doParse(multiRelativeSample, base); + expect(packages.packages.toList()..sort(), equals(["bar", "foo"])); + expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + expect(packages.resolve(Uri.parse("package:bar/foo/baz.dart")), + equals(base.resolve("../test2/").resolve("foo/baz.dart"))); + }); + + test("dot-dot 1", () { + var packages = doParse(singleRelativeSample, base); + expect(packages.packages.toList(), equals(["foo"])); + expect(packages.resolve(Uri.parse("package:foo/qux/../bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("all valid chars can be used in URI segment", () { + var packages = doParse(allValidCharsSample, base); + expect(packages.packages.toList(), equals([allValidChars])); + expect(packages.resolve(Uri.parse("package:$allValidChars/bar/baz.dart")), + equals(base.resolve("../test/").resolve("bar/baz.dart"))); + }); + + test("no invalid chars accepted", () { + var map = {}; + for (var i = 0; i < allValidChars.length; i++) { + map[allValidChars.codeUnitAt(i)] = true; + } + for (var i = 0; i <= 255; i++) { + if (map[i] == true) continue; + var char = String.fromCharCode(i); + expect(() => doParse("x${char}x:x", null), + anyOf(throwsNoSuchMethodError, throwsFormatException)); + } + }); + + test("no escapes", () { + expect(() => doParse("x%41x:x", base), throwsFormatException); + }); + + test("same name twice", () { + expect( + () => doParse(singleRelativeSample * 2, base), throwsFormatException); + }); + + test("disallow default package", () { + expect(() => doParse(":foo", base, allowDefaultPackage: false), + throwsFormatException); + }); + + test("allow default package", () { + var packages = doParse(":foo", base, allowDefaultPackage: true); + expect(packages.defaultPackageName, "foo"); + }); + + test("allow default package name with dot", () { + var packages = doParse(":foo.bar", base, allowDefaultPackage: true); + expect(packages.defaultPackageName, "foo.bar"); + }); + + test("not two default packages", () { + expect(() => doParse(":foo\n:bar", base, allowDefaultPackage: true), + throwsFormatException); + }); + + test("default package invalid package name", () { + // Not a valid *package name*. + expect(() => doParse(":foo/bar", base, allowDefaultPackage: true), + throwsFormatException); + }); + + group("metadata", () { + var packages = doParse( + ":foo\n" + "foo:foo#metafoo=1\n" + "bar:bar#metabar=2\n" + "baz:baz\n" + "qux:qux#metaqux1=3&metaqux2=4\n", + base, + allowDefaultPackage: true); + test("non-existing", () { + // non-package name. + expect(packages.packageMetadata("///", "f"), null); + expect(packages.packageMetadata("", "f"), null); + // unconfigured package name. + expect(packages.packageMetadata("absent", "f"), null); + // package name without that metadata + expect(packages.packageMetadata("foo", "notfoo"), null); + }); + test("lookup", () { + expect(packages.packageMetadata("foo", "metafoo"), "1"); + expect(packages.packageMetadata("bar", "metabar"), "2"); + expect(packages.packageMetadata("qux", "metaqux1"), "3"); + expect(packages.packageMetadata("qux", "metaqux2"), "4"); + }); + test("by library URI", () { + expect( + packages.libraryMetadata( + Uri.parse("package:foo/index.dart"), "metafoo"), + "1"); + expect( + packages.libraryMetadata( + Uri.parse("package:bar/index.dart"), "metabar"), + "2"); + expect( + packages.libraryMetadata( + Uri.parse("package:qux/index.dart"), "metaqux1"), + "3"); + expect( + packages.libraryMetadata( + Uri.parse("package:qux/index.dart"), "metaqux2"), + "4"); + }); + test("by default package", () { + expect( + packages.libraryMetadata( + Uri.parse("file:///whatever.dart"), "metafoo"), + "1"); + }); + }); + + for (var invalidSample in invalid) { + test("invalid '$invalidSample'", () { + var result; + try { + result = doParse(invalidSample, base); + } on FormatException { + // expected + return; + } + fail("Resolved to $result"); + }); + } +} + +Packages doParse(String sample, Uri baseUri, + {bool allowDefaultPackage = false}) { + var map = parse(sample.codeUnits, baseUri, + allowDefaultPackage: allowDefaultPackage); + return MapPackages(map); +} + +// Valid samples. +var emptySample = ""; +var commentOnlySample = "# comment only\n"; +var emptyLinesSample = "\n\n\r\n"; +var singleRelativeSample = "foo:../test/\n"; +var singleRelativeSampleNoSlash = "foo:../test\n"; +var singleRelativeSampleNoNewline = "foo:../test/"; +var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; +var singleEmptyPathSample = "foo:\n"; +var singleAbsolutePathSample = "foo:/test/\n"; +var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; +// All valid path segment characters in an URI. +var allValidChars = r"!$&'()*+,-.0123456789;=" + r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; + +var allValidCharsSample = "${allValidChars}:../test/\n"; + +// Invalid samples. +var invalid = [ + ":baz.dart", // empty. + "foobar=baz.dart", // no colon (but an equals, which is not the same) + ".:../test/", // dot segment + "..:../test/", // dot-dot segment + "...:../test/", // dot-dot-dot segment + "foo/bar:../test/", // slash in name + "/foo:../test/", // slash at start of name + "?:../test/", // invalid characters. + "[:../test/", // invalid characters. + "x#:../test/", // invalid characters. +]; diff --git a/pkgs/package_config/test/legacy/parse_write_test.dart b/pkgs/package_config/test/legacy/parse_write_test.dart new file mode 100644 index 000000000..a51ced1ba --- /dev/null +++ b/pkgs/package_config/test/legacy/parse_write_test.dart @@ -0,0 +1,133 @@ +// Copyright (c) 2015, 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. + +@deprecated +library package_config.parse_write_test; + +import "dart:convert" show utf8; +import "package:package_config/packages_file.dart"; +import "package:test/test.dart"; + +void main() { + void testBase(baseDirString) { + var baseDir = Uri.parse(baseDirString); + group("${baseDir.scheme} base", () { + var packagesFile = baseDir.resolve(".packages"); + + void roundTripTest(String name, Map map) { + group(name, () { + test("write with no baseUri", () { + var content = writeToString(map).codeUnits; + var resultMap = parse(content, packagesFile); + expect(resultMap, map); + }); + + test("write with base directory", () { + var content = writeToString(map, baseUri: baseDir).codeUnits; + var resultMap = parse(content, packagesFile); + expect(resultMap, map); + }); + + test("write with base .packages file", () { + var content = writeToString(map, baseUri: packagesFile).codeUnits; + var resultMap = parse(content, packagesFile); + expect(resultMap, map); + }); + + test("write with defaultPackageName", () { + var content = writeToString( + {'': Uri.parse('my_pkg')}..addAll(map), + allowDefaultPackage: true, + ).codeUnits; + var resultMap = parse( + content, + packagesFile, + allowDefaultPackage: true, + ); + expect(resultMap[''].toString(), 'my_pkg'); + expect( + resultMap, + {'': Uri.parse('my_pkg')}..addAll(map), + ); + }); + + test("write with defaultPackageName (utf8)", () { + var content = utf8.encode(writeToString( + {'': Uri.parse('my_pkg')}..addAll(map), + allowDefaultPackage: true, + )); + var resultMap = parse( + content, + packagesFile, + allowDefaultPackage: true, + ); + expect(resultMap[''].toString(), 'my_pkg'); + expect( + resultMap, + {'': Uri.parse('my_pkg')}..addAll(map), + ); + }); + }); + } + + var lowerDir = baseDir.resolve("path3/path4/"); + var higherDir = baseDir.resolve("../"); + var parallelDir = baseDir.resolve("../path3/"); + var rootDir = baseDir.resolve("/"); + var fileDir = Uri.parse("file:///path1/part2/"); + var httpDir = Uri.parse("http://example.com/path1/path2/"); + var otherDir = Uri.parse("other:/path1/path2/"); + + roundTripTest("empty", {}); + roundTripTest("lower directory", {"foo": lowerDir}); + roundTripTest("higher directory", {"foo": higherDir}); + roundTripTest("parallel directory", {"foo": parallelDir}); + roundTripTest("same directory", {"foo": baseDir}); + roundTripTest("root directory", {"foo": rootDir}); + roundTripTest("file directory", {"foo": fileDir}); + roundTripTest("http directory", {"foo": httpDir}); + roundTripTest("other scheme directory", {"foo": otherDir}); + roundTripTest("multiple same-type directories", + {"foo": lowerDir, "bar": higherDir, "baz": parallelDir}); + roundTripTest("multiple scheme directories", + {"foo": fileDir, "bar": httpDir, "baz": otherDir}); + roundTripTest("multiple scheme directories and mutliple same type", { + "foo": fileDir, + "bar": httpDir, + "baz": otherDir, + "qux": lowerDir, + "hip": higherDir, + "dep": parallelDir + }); + }); + } + + testBase("file:///base1/base2/"); + testBase("http://example.com/base1/base2/"); + testBase("other:/base1/base2/"); + + // Check that writing adds the comment. + test("write preserves comment", () { + var comment = "comment line 1\ncomment line 2\ncomment line 3"; + var result = writeToString({}, comment: comment); + // Comment with "# " before each line and "\n" after last. + var expectedComment = + "# comment line 1\n# comment line 2\n# comment line 3\n"; + expect(result, startsWith(expectedComment)); + }); +} + +String writeToString( + Map map, { + Uri baseUri, + String comment, + bool allowDefaultPackage = false, +}) { + var buffer = StringBuffer(); + write(buffer, map, + baseUri: baseUri, + comment: comment, + allowDefaultPackage: allowDefaultPackage); + return buffer.toString(); +} diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index d9430953c..367b64384 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -3,10 +3,11 @@ // BSD-style license that can be found in the LICENSE file. import "dart:convert"; +import 'dart:typed_data'; import "package:test/test.dart"; -import "package:package_config/package_config.dart"; +import "package:package_config/package_config_types.dart"; import "package:package_config/src/packages_file.dart" as packages; import "package:package_config/src/package_config_json.dart"; import "src/util.dart"; @@ -48,14 +49,14 @@ void main() { group("invalid", () { var baseFile = Uri.file("/tmp/file.dart"); - testThrows(String name, String content) { + void testThrows(String name, String content) { test(name, () { expect( () => packages.parse(utf8.encode(content), baseFile, throwError), throwsA(TypeMatcher())); }); test(name + ", handle error", () { - bool hadError = false; + var hadError = false; packages.parse(utf8.encode(content), baseFile, (error) { hadError = true; expect(error, isA()); @@ -256,7 +257,7 @@ void main() { }); group("invalid", () { - testThrows(String name, String source) { + void testThrows(String name, String source) { test(name, () { expect( () => parsePackageConfigBytes(utf8.encode(source), @@ -364,11 +365,79 @@ void main() { "same roots", '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); testThrows( - // The root of bar is inside the package root of foo. - "inside lib", + // The root of bar is inside the root of foo, + // but the package root of foo is inside the root of bar. + "between root and lib", '{$cfg,"packages":[' - '{"name":"foo","rootUri":"/foo/","packageUri":"lib/"},' - '{"name":"bar","rootUri":"/foo/lib/qux/"}]}'); + '{"name":"foo","rootUri":"/foo/","packageUri":"bar/lib/"},' + '{"name":"bar","rootUri":"/foo/bar/"},"packageUri":"baz/lib"]}'); }); }); + + group("factories", () { + void testConfig(String name, PackageConfig config, PackageConfig expected) { + group(name, () { + test("structure", () { + expect(config.version, expected.version); + var expectedPackages = {for (var p in expected.packages) p.name}; + var actualPackages = {for (var p in config.packages) p.name}; + expect(actualPackages, expectedPackages); + }); + for (var package in config.packages) { + var name = package.name; + test("package $name", () { + var expectedPackage = expected[name]; + expect(expectedPackage, isNotNull); + expect(package.root, expectedPackage.root, reason: "root"); + expect(package.packageUriRoot, expectedPackage.packageUriRoot, + reason: "package root"); + expect(package.languageVersion, expectedPackage.languageVersion, + reason: "languageVersion"); + }); + } + }); + } + + var configText = """ + {"configVersion": 2, "packages": [ + { + "name": "foo", + "rootUri": "foo/", + "packageUri": "bar/", + "languageVersion": "1.2" + } + ]} + """; + var baseUri = Uri.parse("file:///start/"); + var config = PackageConfig([ + Package("foo", Uri.parse("file:///start/foo/"), + packageUriRoot: Uri.parse("file:///start/foo/bar/"), + languageVersion: LanguageVersion(1, 2)) + ]); + testConfig( + "string", PackageConfig.parseString(configText, baseUri), config); + testConfig( + "bytes", + PackageConfig.parseBytes( + Uint8List.fromList(configText.codeUnits), baseUri), + config); + testConfig("json", PackageConfig.parseJson(jsonDecode(configText), baseUri), + config); + + baseUri = Uri.parse("file:///start2/"); + config = PackageConfig([ + Package("foo", Uri.parse("file:///start2/foo/"), + packageUriRoot: Uri.parse("file:///start2/foo/bar/"), + languageVersion: LanguageVersion(1, 2)) + ]); + testConfig( + "string2", PackageConfig.parseString(configText, baseUri), config); + testConfig( + "bytes2", + PackageConfig.parseBytes( + Uint8List.fromList(configText.codeUnits), baseUri), + config); + testConfig("json2", + PackageConfig.parseJson(jsonDecode(configText), baseUri), config); + }); } diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart index 95670bdbb..2b91b2130 100644 --- a/pkgs/package_config/test/src/util.dart +++ b/pkgs/package_config/test/src/util.dart @@ -18,7 +18,7 @@ import "package:package_config/src/util.dart"; void fileTest(String name, Map description, void fileTest(Directory directory)) { group("file-test", () { - Directory tempDir = Directory.systemTemp.createTempSync("pkgcfgtest"); + var tempDir = Directory.systemTemp.createTempSync("pkgcfgtest"); setUp(() { _createFiles(tempDir, description); }); @@ -67,7 +67,7 @@ File dirFile(Directory directory, String fileName) => Uri pkg(String packageName, String packagePath) { var path = "$packageName${packagePath.startsWith('/') ? "" : "/"}$packagePath"; - return new Uri(scheme: "package", path: path); + return Uri(scheme: "package", path: path); } // Remove if not used. @@ -91,13 +91,13 @@ ${packages.map((nu) => """ /// as a string. void loaderTest(String name, Map description, void loaderTest(Uri root, Future loader(Uri uri))) { - Uri root = Uri(scheme: "test", path: "/"); + var root = Uri(scheme: "test", path: "/"); Future loader(Uri uri) async { var path = uri.path; if (!uri.isScheme("test") || !path.startsWith("/")) return null; var parts = path.split("/"); dynamic value = description; - for (int i = 1; i < parts.length; i++) { + for (var i = 1; i < parts.length; i++) { if (value is! Map) return null; value = value[parts[i]]; } From af58162f9d26235eed94104c4a7c2c522ac68b1c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Feb 2020 00:09:03 -0800 Subject: [PATCH 339/657] Tweak readme (dart-lang/package_config#69) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Tweak readme Remove gratuitous title Move badges to top, as is tradition * Update README.md Remove issue/feature request blurb – this is automatically done on the pub site! --- pkgs/package_config/README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index ec51f6ea7..5a76a7ab1 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -1,4 +1,5 @@ -# package_config +[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) +[![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) Support for working with **Package Configuration** files as described in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). @@ -15,11 +16,3 @@ The primary libraries are The package includes deprecated backwards compatible functionality to work with the `.packages` file. This functionality will not be maintained, and will be removed in a future version of this package. - -[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) - -## Features and bugs - -Please file feature requests and bugs at the [issue tracker][tracker]. - -[tracker]: https://github.com/dart-lang/package_config/issues From b69e8ac948775b58bffe2f119eb1e88ce754cc56 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 26 Feb 2020 09:10:03 +0100 Subject: [PATCH 340/657] Remove 1.2.0 from changelog. That version was never released. --- pkgs/package_config/CHANGELOG.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index c6caf4d6e..a86d1a54f 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -5,11 +5,6 @@ version, as well as the, now deprecated, version 1 functionality. When we release 2.0.0, the deprectated functionality will be removed. -## 1.2.0 - -- Added support for writing default-package entries. -- Fixed bug when writing `Uri`s containing a fragment. - ## 1.1.0 - Allow parsing files with default-package entries and metadata. From 267c75ab3c875d335cf294a10de340713a62ac4a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Feb 2020 08:50:41 -0800 Subject: [PATCH 341/657] Remove pubspec author, fix URL in readme (dart-lang/package_config#71) --- pkgs/package_config/README.md | 2 +- pkgs/package_config/pubspec.yaml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 5a76a7ab1..b47a6825b 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -1,5 +1,5 @@ [![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) -[![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dartlang.org/packages/package_config) +[![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config) Support for working with **Package Configuration** files as described in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 20a39c767..0eaeeda93 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,7 +1,6 @@ name: package_config version: 1.9.0-dev description: Support for working with Package Configuration files. -author: Dart Team homepage: https://github.com/dart-lang/package_config environment: From 45477a6a7d1f62d4c4f97efa0e45bc685321e530 Mon Sep 17 00:00:00 2001 From: Lasse Nielsen Date: Wed, 26 Feb 2020 19:18:52 +0000 Subject: [PATCH 342/657] Add missing dependency on package:path. --- pkgs/package_config/pubspec.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 0eaeeda93..c37dda616 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -6,6 +6,9 @@ homepage: https://github.com/dart-lang/package_config environment: sdk: '>=2.7.0 <3.0.0' +dependencies: + path: ^1.6.4 + dev_dependencies: test: ^1.6.4 matcher: ^0.12.5 From 48ab5081081ff91362dde900a1f0cbea9138e150 Mon Sep 17 00:00:00 2001 From: Lasse Nielsen Date: Wed, 26 Feb 2020 19:23:20 +0000 Subject: [PATCH 343/657] Add another missing dependency. --- pkgs/package_config/pubspec.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index c37dda616..651dbec28 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -8,6 +8,7 @@ environment: dependencies: path: ^1.6.4 + charcode: ^1.1.0 dev_dependencies: test: ^1.6.4 From 6c4b1492ffbdea9becd3acf41b3b43e2ff06962b Mon Sep 17 00:00:00 2001 From: Lasse Nielsen Date: Wed, 26 Feb 2020 19:31:03 +0000 Subject: [PATCH 344/657] Set version to 1.9.0 (no -dev) for release. --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 651dbec28..abaddd9e9 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.9.0-dev +version: 1.9.0 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config From 6d7290406dd7f7416212eeb4361405b0b2d1f32a Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 26 Feb 2020 14:30:43 -0800 Subject: [PATCH 345/657] move io utils to their own library, release 1.9.1 (dart-lang/package_config#74) --- pkgs/package_config/.travis.yml | 5 + pkgs/package_config/CHANGELOG.md | 5 + pkgs/package_config/lib/src/discovery.dart | 2 +- .../lib/src/package_config_io.dart | 1 + .../lib/src/packages_io_impl.dart | 2 +- pkgs/package_config/lib/src/util.dart | 99 ---------------- pkgs/package_config/lib/src/util_io.dart | 106 ++++++++++++++++++ pkgs/package_config/pubspec.yaml | 5 +- pkgs/package_config/test/discovery_test.dart | 2 + .../test/discovery_uri_test.dart | 1 + .../test/legacy/discovery_analysis_test.dart | 1 + .../test/legacy/discovery_test.dart | 1 + pkgs/package_config/test/src/util.dart | 56 --------- pkgs/package_config/test/src/util_io.dart | 62 ++++++++++ 14 files changed, 190 insertions(+), 158 deletions(-) create mode 100644 pkgs/package_config/lib/src/util_io.dart create mode 100644 pkgs/package_config/test/src/util_io.dart diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml index 655bf3dc1..09fc296c2 100644 --- a/pkgs/package_config/.travis.yml +++ b/pkgs/package_config/.travis.yml @@ -7,6 +7,11 @@ dart_task: - dartfmt - dartanalyzer: --fatal-warnings . +matrix: + include: + - dart: dev + script: pub run build_runner test -- -p chrome + # Only building master means that we don't run two builds for each pull request. branches: only: [master] diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index a86d1a54f..1cd45d007 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.9.1 + +- Remove accidental transitive import of `dart:io` from entrypoints that are + supposed to be cross-platform compatible. + ## 1.9.0 - Based on new JSON file format with more content. diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index 5d3172f26..8ac6a0128 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -11,7 +11,7 @@ import "errors.dart"; import "package_config_impl.dart"; import "package_config_json.dart"; import "packages_file.dart" as packages_file; -import "util.dart" show defaultLoader, pathJoin; +import "util_io.dart" show defaultLoader, pathJoin; final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json"); final Uri dotPackagesPath = Uri(path: ".packages"); diff --git a/pkgs/package_config/lib/src/package_config_io.dart b/pkgs/package_config/lib/src/package_config_io.dart index d59972f9a..954be6b1e 100644 --- a/pkgs/package_config/lib/src/package_config_io.dart +++ b/pkgs/package_config/lib/src/package_config_io.dart @@ -14,6 +14,7 @@ import "package_config_impl.dart"; import "package_config_json.dart"; import "packages_file.dart" as packages_file; import "util.dart"; +import "util_io.dart"; /// Reads a package configuration file. /// diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart index b2277e7e0..c623f4d5d 100644 --- a/pkgs/package_config/lib/src/packages_io_impl.dart +++ b/pkgs/package_config/lib/src/packages_io_impl.dart @@ -12,7 +12,7 @@ import "dart:io" show Directory; import "packages_impl.dart"; -import "util.dart"; +import "util_io.dart"; /// A [Packages] implementation based on a local directory. class FilePackagesDirectoryPackages extends PackagesBase { diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 548f61d98..50b140fa0 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -5,9 +5,6 @@ /// Utility methods used by more than one library in the package. library package_config.util; -import 'dart:io'; -import 'dart:typed_data'; - import "errors.dart"; // All ASCII characters that are valid in a package name, with space @@ -215,102 +212,6 @@ Uri relativizeUri(Uri uri, Uri /*?*/ baseUri) { } } -Future defaultLoader(Uri uri) async { - if (uri.isScheme("file")) { - var file = File.fromUri(uri); - try { - return file.readAsBytes(); - } catch (_) { - return null; - } - } - if (uri.isScheme("http") || uri.isScheme("https")) { - return _httpGet(uri); - } - throw UnsupportedError("Default URI unsupported scheme: $uri"); -} - -Future _httpGet(Uri uri) async { - assert(uri.isScheme("http") || uri.isScheme("https")); - var client = HttpClient(); - var request = await client.getUrl(uri); - var response = await request.close(); - if (response.statusCode != HttpStatus.ok) { - return null; - } - var splitContent = await response.toList(); - var totalLength = 0; - if (splitContent.length == 1) { - var part = splitContent[0]; - if (part is Uint8List) { - return part; - } - } - for (var list in splitContent) { - totalLength += list.length; - } - var result = Uint8List(totalLength); - var offset = 0; - for (Uint8List contentPart in splitContent) { - result.setRange(offset, offset + contentPart.length, contentPart); - offset += contentPart.length; - } - return result; -} - -/// The file name of a path. -/// -/// The file name is everything after the last occurrence of -/// [Platform.pathSeparator], or the entire string if no -/// path separator occurs in the string. -String fileName(String path) { - var separator = Platform.pathSeparator; - var lastSeparator = path.lastIndexOf(separator); - if (lastSeparator < 0) return path; - return path.substring(lastSeparator + separator.length); -} - -/// The directory name of a path. -/// -/// The directory name is everything before the last occurrence of -/// [Platform.pathSeparator], or the empty string if no -/// path separator occurs in the string. -String dirName(String path) { - var separator = Platform.pathSeparator; - var lastSeparator = path.lastIndexOf(separator); - if (lastSeparator < 0) return ""; - return path.substring(0, lastSeparator); -} - -/// Join path parts with the [Platform.pathSeparator]. -/// -/// If a part ends with a path separator, then no extra separator is -/// inserted. -String pathJoin(String part1, String part2, [String part3]) { - var separator = Platform.pathSeparator; - var separator1 = part1.endsWith(separator) ? "" : separator; - if (part3 == null) { - return "$part1$separator1$part2"; - } - var separator2 = part2.endsWith(separator) ? "" : separator; - return "$part1$separator1$part2$separator2$part3"; -} - -/// Join an unknown number of path parts with [Platform.pathSeparator]. -/// -/// If a part ends with a path separator, then no extra separator is -/// inserted. -String pathJoinAll(Iterable parts) { - var buffer = StringBuffer(); - var separator = ""; - for (var part in parts) { - buffer..write(separator)..write(part); - separator = - part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator; - } - return buffer.toString(); -} - // Character constants used by this package. /// "Line feed" control character. const int $lf = 0x0a; diff --git a/pkgs/package_config/lib/src/util_io.dart b/pkgs/package_config/lib/src/util_io.dart new file mode 100644 index 000000000..7f21a8dcd --- /dev/null +++ b/pkgs/package_config/lib/src/util_io.dart @@ -0,0 +1,106 @@ +// 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. + +/// Utility methods requiring dart:io and used by more than one library in the +/// package. +library package_config.util_io; + +import 'dart:io'; +import 'dart:typed_data'; + +Future defaultLoader(Uri uri) async { + if (uri.isScheme("file")) { + var file = File.fromUri(uri); + try { + return file.readAsBytes(); + } catch (_) { + return null; + } + } + if (uri.isScheme("http") || uri.isScheme("https")) { + return _httpGet(uri); + } + throw UnsupportedError("Default URI unsupported scheme: $uri"); +} + +Future _httpGet(Uri uri) async { + assert(uri.isScheme("http") || uri.isScheme("https")); + var client = HttpClient(); + var request = await client.getUrl(uri); + var response = await request.close(); + if (response.statusCode != HttpStatus.ok) { + return null; + } + var splitContent = await response.toList(); + var totalLength = 0; + if (splitContent.length == 1) { + var part = splitContent[0]; + if (part is Uint8List) { + return part; + } + } + for (var list in splitContent) { + totalLength += list.length; + } + var result = Uint8List(totalLength); + var offset = 0; + for (Uint8List contentPart in splitContent) { + result.setRange(offset, offset + contentPart.length, contentPart); + offset += contentPart.length; + } + return result; +} + +/// The file name of a path. +/// +/// The file name is everything after the last occurrence of +/// [Platform.pathSeparator], or the entire string if no +/// path separator occurs in the string. +String fileName(String path) { + var separator = Platform.pathSeparator; + var lastSeparator = path.lastIndexOf(separator); + if (lastSeparator < 0) return path; + return path.substring(lastSeparator + separator.length); +} + +/// The directory name of a path. +/// +/// The directory name is everything before the last occurrence of +/// [Platform.pathSeparator], or the empty string if no +/// path separator occurs in the string. +String dirName(String path) { + var separator = Platform.pathSeparator; + var lastSeparator = path.lastIndexOf(separator); + if (lastSeparator < 0) return ""; + return path.substring(0, lastSeparator); +} + +/// Join path parts with the [Platform.pathSeparator]. +/// +/// If a part ends with a path separator, then no extra separator is +/// inserted. +String pathJoin(String part1, String part2, [String part3]) { + var separator = Platform.pathSeparator; + var separator1 = part1.endsWith(separator) ? "" : separator; + if (part3 == null) { + return "$part1$separator1$part2"; + } + var separator2 = part2.endsWith(separator) ? "" : separator; + return "$part1$separator1$part2$separator2$part3"; +} + +/// Join an unknown number of path parts with [Platform.pathSeparator]. +/// +/// If a part ends with a path separator, then no extra separator is +/// inserted. +String pathJoinAll(Iterable parts) { + var buffer = StringBuffer(); + var separator = ""; + for (var part in parts) { + buffer..write(separator)..write(part); + separator = + part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator; + } + return buffer.toString(); +} diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index abaddd9e9..5299fdf79 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.9.0 +version: 1.9.1 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config @@ -14,3 +14,6 @@ dev_dependencies: test: ^1.6.4 matcher: ^0.12.5 pedantic: 1.8.0 + build_runner: ^1.0.0 + build_web_compilers: ^2.0.0 + build_test: ^0.10.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index e4c93a592..1a9a61c1f 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -2,6 +2,7 @@ // 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. +@TestOn('vm') library package_config.discovery_test; import "dart:io"; @@ -9,6 +10,7 @@ import "package:test/test.dart"; import "package:package_config/package_config.dart"; import "src/util.dart"; +import "src/util_io.dart"; const packagesFile = """ # A comment diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 109693c4c..52fca3ffa 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -2,6 +2,7 @@ // 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. +@TestOn('vm') library package_config.discovery_test; import "package:test/test.dart"; diff --git a/pkgs/package_config/test/legacy/discovery_analysis_test.dart b/pkgs/package_config/test/legacy/discovery_analysis_test.dart index 7d08f7b92..4be636d13 100644 --- a/pkgs/package_config/test/legacy/discovery_analysis_test.dart +++ b/pkgs/package_config/test/legacy/discovery_analysis_test.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @deprecated +@TestOn('vm') library package_config.discovery_analysis_test; import "dart:async"; diff --git a/pkgs/package_config/test/legacy/discovery_test.dart b/pkgs/package_config/test/legacy/discovery_test.dart index 684abcb4a..72874c8df 100644 --- a/pkgs/package_config/test/legacy/discovery_test.dart +++ b/pkgs/package_config/test/legacy/discovery_test.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @deprecated +@TestOn('vm') library package_config.discovery_test; import "dart:async"; diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart index 2b91b2130..6e689b734 100644 --- a/pkgs/package_config/test/src/util.dart +++ b/pkgs/package_config/test/src/util.dart @@ -3,65 +3,9 @@ // BSD-style license that can be found in the LICENSE file. import 'dart:convert'; -import "dart:io"; import 'dart:typed_data'; import "package:test/test.dart"; -import "package:package_config/src/util.dart"; - -/// Creates a directory structure from [description] and runs [fileTest]. -/// -/// Description is a map, each key is a file entry. If the value is a map, -/// it's a subdirectory, otherwise it's a file and the value is the content -/// as a string. -/// Introduces a group to hold the [setUp]/[tearDown] logic. -void fileTest(String name, Map description, - void fileTest(Directory directory)) { - group("file-test", () { - var tempDir = Directory.systemTemp.createTempSync("pkgcfgtest"); - setUp(() { - _createFiles(tempDir, description); - }); - tearDown(() { - tempDir.deleteSync(recursive: true); - }); - test(name, () => fileTest(tempDir)); - }); -} - -/// Creates a set of files under a new temporary directory. -/// Returns the temporary directory. -/// -/// The [description] is a map from file names to content. -/// If the content is again a map, it represents a subdirectory -/// with the content as description. -/// Otherwise the content should be a string, -/// which is written to the file as UTF-8. -Directory createTestFiles(Map description) { - var target = Directory.systemTemp.createTempSync("pkgcfgtest"); - _createFiles(target, description); - return target; -} - -// Creates temporary files in the target directory. -void _createFiles(Directory target, Map description) { - description.forEach((name, content) { - var entryName = pathJoin(target.path, "$name"); - if (content is Map) { - _createFiles(Directory(entryName)..createSync(), content); - } else { - File(entryName).writeAsStringSync(content, flush: true); - } - }); -} - -/// Creates a [Directory] for a subdirectory of [parent]. -Directory subdir(Directory parent, String dirName) => - Directory(pathJoinAll([parent.path, ...dirName.split("/")])); - -/// Creates a [File] for an entry in the [directory] directory. -File dirFile(Directory directory, String fileName) => - File(pathJoin(directory.path, fileName)); /// Creates a package: URI. Uri pkg(String packageName, String packagePath) { diff --git a/pkgs/package_config/test/src/util_io.dart b/pkgs/package_config/test/src/util_io.dart new file mode 100644 index 000000000..d05618a07 --- /dev/null +++ b/pkgs/package_config/test/src/util_io.dart @@ -0,0 +1,62 @@ +// 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 "dart:io"; + +import "package:test/test.dart"; +import "package:package_config/src/util_io.dart"; + +/// Creates a directory structure from [description] and runs [fileTest]. +/// +/// Description is a map, each key is a file entry. If the value is a map, +/// it's a subdirectory, otherwise it's a file and the value is the content +/// as a string. +/// Introduces a group to hold the [setUp]/[tearDown] logic. +void fileTest(String name, Map description, + void fileTest(Directory directory)) { + group("file-test", () { + var tempDir = Directory.systemTemp.createTempSync("pkgcfgtest"); + setUp(() { + _createFiles(tempDir, description); + }); + tearDown(() { + tempDir.deleteSync(recursive: true); + }); + test(name, () => fileTest(tempDir)); + }); +} + +/// Creates a set of files under a new temporary directory. +/// Returns the temporary directory. +/// +/// The [description] is a map from file names to content. +/// If the content is again a map, it represents a subdirectory +/// with the content as description. +/// Otherwise the content should be a string, +/// which is written to the file as UTF-8. +Directory createTestFiles(Map description) { + var target = Directory.systemTemp.createTempSync("pkgcfgtest"); + _createFiles(target, description); + return target; +} + +// Creates temporary files in the target directory. +void _createFiles(Directory target, Map description) { + description.forEach((name, content) { + var entryName = pathJoin(target.path, "$name"); + if (content is Map) { + _createFiles(Directory(entryName)..createSync(), content); + } else { + File(entryName).writeAsStringSync(content, flush: true); + } + }); +} + +/// Creates a [Directory] for a subdirectory of [parent]. +Directory subdir(Directory parent, String dirName) => + Directory(pathJoinAll([parent.path, ...dirName.split("/")])); + +/// Creates a [File] for an entry in the [directory] directory. +File dirFile(Directory directory, String fileName) => + File(pathJoin(directory.path, fileName)); From 76d2d33cb621ba722603ac4a7c35a8892a2ad3de Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Feb 2020 14:35:04 -0800 Subject: [PATCH 346/657] Fix reference to pedantic lints (dart-lang/package_config#73) --- pkgs/package_config/analysis_options.yaml | 2 +- pkgs/package_config/pubspec.yaml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/analysis_options.yaml b/pkgs/package_config/analysis_options.yaml index 82c00e5c8..66639ec1a 100644 --- a/pkgs/package_config/analysis_options.yaml +++ b/pkgs/package_config/analysis_options.yaml @@ -2,7 +2,7 @@ # 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. -include: package:pedantic/analysis_options.yaml +include: package:pedantic/analysis_options.1.9.0.yaml analyzer: errors: annotate_overrides: ignore diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 5299fdf79..5c0589145 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -13,7 +13,8 @@ dependencies: dev_dependencies: test: ^1.6.4 matcher: ^0.12.5 - pedantic: 1.8.0 + pedantic: ^1.8.0 + build_runner: ^1.0.0 build_web_compilers: ^2.0.0 build_test: ^0.10.0 From c1b6ac18cc49dc3c924c9798ffec420961987d1c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 Feb 2020 15:52:13 -0800 Subject: [PATCH 347/657] Fix version constraint on pkg:pedantic --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 5c0589145..853c0514b 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: dev_dependencies: test: ^1.6.4 matcher: ^0.12.5 - pedantic: ^1.8.0 + pedantic: ^1.9.0 build_runner: ^1.0.0 build_web_compilers: ^2.0.0 From c886dde0251b2e78b6824da7ef2f8462c8e578a9 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 12 Mar 2020 12:47:02 +0100 Subject: [PATCH 348/657] Change to only look for package_config.json if asked for .packages by name. (dart-lang/package_config#78) Some clean-up. --- pkgs/package_config/CHANGELOG.md | 5 ++ pkgs/package_config/lib/package_config.dart | 8 ++- .../lib/src/package_config_io.dart | 70 +++++++++---------- .../lib/src/package_config_json.dart | 11 ++- pkgs/package_config/lib/src/util_io.dart | 2 +- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/discovery_test.dart | 6 +- .../test/discovery_uri_test.dart | 25 ++++--- 8 files changed, 63 insertions(+), 66 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 1cd45d007..0b5e1563e 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.9.2 + +- Updated to support new rules for picking `package_config.json` over + a specified `.packages`. + ## 1.9.1 - Remove accidental transitive import of `dart:io` from entrypoints that are diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index bca865d70..1113ac872 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -24,9 +24,10 @@ export "package_config_types.dart"; /// It is considered a `package_config.json` file if its first character /// is a `{`. /// -/// If the file is a `.packages` file and [preferNewest] is true, the default, -/// also checks if there is a `.dart_tool/package_config.json` file next to the original file, -/// and if so, loads that instead. +/// If the file is a `.packages` file (the file name is `.packages`) +/// and [preferNewest] is true, the default, also checks if there is +/// a `.dart_tool/package_config.json` file next +/// to the original file, and if so, loads that instead. /// If [preferNewest] is set to false, a directly specified `.packages` file /// is loaded even if there is an available `package_config.json` file. /// The caller can determine this from the [PackageConfig.version] @@ -50,6 +51,7 @@ Future loadPackageConfig(File file, /// non-whitespace character is a `{`. /// /// If [preferNewest] is true, the default, and the file is a `.packages` file, +/// as determined by its file name being `.packages`, /// first checks if there is a `.dart_tool/package_config.json` file /// next to the original file, and if so, loads that instead. /// The [file] *must not* be a `package:` URI. diff --git a/pkgs/package_config/lib/src/package_config_io.dart b/pkgs/package_config/lib/src/package_config_io.dart index 954be6b1e..31bc1cc99 100644 --- a/pkgs/package_config/lib/src/package_config_io.dart +++ b/pkgs/package_config/lib/src/package_config_io.dart @@ -30,6 +30,13 @@ import "util_io.dart"; /// The file must exist and be a normal file. Future readAnyConfigFile( File file, bool preferNewest, void onError(Object error)) async { + if (preferNewest && fileName(file.path) == ".packages") { + var alternateFile = + File(pathJoin(dirName(file.path), ".dart_tool", "package_config.json")); + if (alternateFile.existsSync()) { + return await readPackageConfigJsonFile(alternateFile, onError); + } + } Uint8List bytes; try { bytes = await file.readAsBytes(); @@ -37,28 +44,7 @@ Future readAnyConfigFile( onError(e); return const SimplePackageConfig.empty(); } - var firstChar = firstNonWhitespaceChar(bytes); - if (firstChar != $lbrace) { - // Definitely not a JSON object, probably a .packages. - if (preferNewest) { - var alternateFile = File( - pathJoin(dirName(file.path), ".dart_tool", "package_config.json")); - if (alternateFile.existsSync()) { - Uint8List /*?*/ bytes; - try { - bytes = await alternateFile.readAsBytes(); - } catch (e) { - onError(e); - return const SimplePackageConfig.empty(); - } - if (bytes != null) { - return parsePackageConfigBytes(bytes, alternateFile.uri, onError); - } - } - } - return packages_file.parse(bytes, file.uri, onError); - } - return parsePackageConfigBytes(bytes, file.uri, onError); + return parseAnyConfigFile(bytes, file.uri, onError); } /// Like [readAnyConfigFile] but uses a URI and an optional loader. @@ -73,11 +59,24 @@ Future readAnyConfigFileUri( } if (loader == null) { if (file.isScheme("file")) { - return readAnyConfigFile(File.fromUri(file), preferNewest, onError); + return await readAnyConfigFile(File.fromUri(file), preferNewest, onError); } loader = defaultLoader; } - Uint8List bytes; + if (preferNewest && file.pathSegments.last == ".packages") { + var alternateFile = file.resolve(".dart_tool/package_config.json"); + Uint8List /*?*/ bytes; + try { + bytes = await loader(alternateFile); + } catch (e) { + onError(e); + return const SimplePackageConfig.empty(); + } + if (bytes != null) { + return parsePackageConfigBytes(bytes, alternateFile, onError); + } + } + Uint8List /*?*/ bytes; try { bytes = await loader(file); } catch (e) { @@ -89,23 +88,18 @@ Future readAnyConfigFileUri( file.toString(), "file", "File cannot be read")); return const SimplePackageConfig.empty(); } + return parseAnyConfigFile(bytes, file, onError); +} + +/// Parses a `.packages` or `package_config.json` file's contents. +/// +/// Assumes it's a JSON file if the first non-whitespace character +/// is `{`, otherwise assumes it's a `.packages` file. +PackageConfig parseAnyConfigFile( + Uint8List bytes, Uri file, void onError(Object error)) { var firstChar = firstNonWhitespaceChar(bytes); if (firstChar != $lbrace) { // Definitely not a JSON object, probably a .packages. - if (preferNewest) { - // Check if there is a package_config.json file. - var alternateFile = file.resolveUri(packageConfigJsonPath); - Uint8List alternateBytes; - try { - alternateBytes = await loader(alternateFile); - } catch (e) { - onError(e); - return const SimplePackageConfig.empty(); - } - if (alternateBytes != null) { - return parsePackageConfigBytes(alternateBytes, alternateFile, onError); - } - } return packages_file.parse(bytes, file, onError); } return parsePackageConfigBytes(bytes, file, onError); diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index b9b34165b..27abf505c 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -39,7 +39,7 @@ PackageConfig parsePackageConfigBytes( try { jsonObject = _jsonUtf8Decoder.convert(bytes); } on FormatException catch (e) { - onError(PackageConfigFormatException(e.message, e.source, e.offset)); + onError(PackageConfigFormatException.from(e)); return const SimplePackageConfig.empty(); } return parsePackageConfigJson(jsonObject, file, onError); @@ -51,7 +51,7 @@ PackageConfig parsePackageConfigString( try { jsonObject = jsonDecode(source); } on FormatException catch (e) { - onError(PackageConfigFormatException(e.message, e.source, e.offset)); + onError(PackageConfigFormatException.from(e)); return const SimplePackageConfig.empty(); } return parsePackageConfigJson(jsonObject, file, onError); @@ -271,7 +271,6 @@ void writeDotPackages(PackageConfig config, Uri baseUri, StringSink output) { } } packages_file.write(output, config, baseUri: baseUri, comment: comment); - return; } /// If "extraData" is a JSON map, then return it, otherwise return null. @@ -304,12 +303,10 @@ bool _validateJson(dynamic object) { if (object == null || true == object || false == object) return true; if (object is num || object is String) return true; if (object is List) { - for (var element in object) if (!_validateJson(element)) return false; - return true; + return object.every(_validateJson); } if (object is Map) { - for (var value in object.values) if (!_validateJson(value)) return false; - return true; + return object.values.every(_validateJson); } return false; } diff --git a/pkgs/package_config/lib/src/util_io.dart b/pkgs/package_config/lib/src/util_io.dart index 7f21a8dcd..2aa8c94bf 100644 --- a/pkgs/package_config/lib/src/util_io.dart +++ b/pkgs/package_config/lib/src/util_io.dart @@ -13,7 +13,7 @@ Future defaultLoader(Uri uri) async { if (uri.isScheme("file")) { var file = File.fromUri(uri); try { - return file.readAsBytes(); + return await file.readAsBytes(); } catch (_) { return null; } diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 853c0514b..3f5ec27e0 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.9.1 +version: 1.9.2 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 1a9a61c1f..5cbc99214 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -301,13 +301,13 @@ void main() { }); // Find package_config.json in subdir even if initial file syntax error. - fileTest("specified file syntax error", { - "anyname": "syntax error", + fileTest("specified file syntax onError", { + ".packages": "syntax error", ".dart_tool": { "package_config.json": packageConfigFile, }, }, (Directory directory) async { - var file = dirFile(directory, "anyname"); + var file = dirFile(directory, ".packages"); var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 52fca3ffa..23c02d7bc 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -60,7 +60,7 @@ void main() { ".dart_tool": { "package_config.json": packageConfigFile, } - }, (Uri directory, loader) async { + }, (directory, loader) async { var config = await findPackageConfigUri(directory, loader: loader); expect(config.version, 2); // Found package_config.json file. validatePackagesFile(config, directory); @@ -71,7 +71,7 @@ void main() { ".packages": packagesFile, "script.dart": "main(){}", "packages": {"shouldNotBeFound": {}} - }, (Uri directory, loader) async { + }, (directory, loader) async { var config = await findPackageConfigUri(directory, loader: loader); expect(config.version, 1); // Found .packages file. validatePackagesFile(config, directory); @@ -86,7 +86,7 @@ void main() { "subdir": { "script.dart": "main(){}", } - }, (Uri directory, loader) async { + }, (directory, loader) async { var config = await findPackageConfigUri(directory.resolve("subdir/"), loader: loader); expect(config.version, 2); @@ -97,7 +97,7 @@ void main() { loaderTest(".packages recursive", { ".packages": packagesFile, "subdir": {"script.dart": "main(){}"} - }, (Uri directory, loader) async { + }, (directory, loader) async { var config; config = await findPackageConfigUri(directory.resolve("subdir/"), loader: loader); @@ -240,9 +240,9 @@ void main() { throwsFormatException); }); - loaderTest("specified file syntax error", { + loaderTest("specified file syntax onError", { "anyname": "syntax error", - }, (Uri directory, loader) async { + }, (directory, loader) async { var file = directory.resolve("anyname"); var hadError = false; await loadPackageConfigUri(file, @@ -254,23 +254,22 @@ void main() { expect(hadError, true); }); - // Find package_config.json in subdir even if initial file syntax error. - loaderTest("specified file syntax error", { + // Don't look for package_config.json if original file not named .packages. + loaderTest("specified file syntax error with alternative", { "anyname": "syntax error", ".dart_tool": { "package_config.json": packageConfigFile, }, - }, (Uri directory, loader) async { + }, (directory, loader) async { var file = directory.resolve("anyname"); - var config = await loadPackageConfigUri(file, loader: loader); - expect(config.version, 2); - validatePackagesFile(config, directory); + expect(() => loadPackageConfigUri(file, loader: loader), + throwsFormatException); }); // A file starting with `{` is a package_config.json file. loaderTest("file syntax error with {", { ".packages": "{syntax error", - }, (Uri directory, loader) async { + }, (directory, loader) async { var file = directory.resolve(".packages"); var hadError = false; await loadPackageConfigUri(file, From 4af6bbb0ef75d2bf85ac00babc1737e250c5f593 Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Fri, 13 Mar 2020 14:49:10 +0100 Subject: [PATCH 349/657] Fix union of version ranges --- pkgs/pub_semver/lib/src/version_range.dart | 6 +++-- pkgs/pub_semver/test/version_range_test.dart | 23 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 2c4088426..78cd6d026 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -243,8 +243,10 @@ class VersionRange implements Comparable, VersionConstraint { if (other is VersionRange) { // If the two ranges don't overlap, we won't be able to create a single // VersionRange for both of them. - var edgesTouch = (max == other.min && (includeMax || other.includeMin)) || - (min == other.max && (includeMin || other.includeMax)); + var edgesTouch = (max != null && + max == other.min && + (includeMax || other.includeMin)) || + (min != null && min == other.max && (includeMin || other.includeMax)); if (!edgesTouch && !allowsAny(other)) { return VersionConstraint.unionOf([this, other]); } diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index bf280c23c..67c7f351b 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -562,6 +562,29 @@ void main() { expect(result, allows(v140)); }); + test('returns a VersionUnion for a disjoint range with infinite end', () { + void isVersionUnion(VersionConstraint constraint) { + expect(constraint, allows(v080)); + expect(constraint, doesNotAllow(v123)); + expect(constraint, allows(v140)); + } + + for (final includeAMin in [true, false]) { + for (final includeAMax in [true, false]) { + for (final includeBMin in [true, false]) { + for (final includeBMax in [true, false]) { + final a = VersionRange( + min: v130, includeMin: includeAMin, includeMax: includeAMax); + final b = VersionRange( + max: v114, includeMin: includeBMin, includeMax: includeBMax); + isVersionUnion(a.union(b)); + isVersionUnion(b.union(a)); + } + } + } + } + }); + test('considers open ranges disjoint', () { var result = VersionRange(min: v003, max: v114) .union(VersionRange(min: v114, max: v200)); From 718abb92e6e94c669621bc8d87f1301302c82d4d Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sun, 15 Mar 2020 12:47:23 -0700 Subject: [PATCH 350/657] Remove author from the pubspec --- pkgs/pool/pubspec.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index ebb05d9a2..c87617f43 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -4,7 +4,6 @@ version: 1.4.1-dev description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. -author: Dart Team homepage: https://github.com/dart-lang/pool environment: From 3449b075dd78647b58a4056c742b1fe741d02523 Mon Sep 17 00:00:00 2001 From: Sigurd Meldgaard Date: Mon, 16 Mar 2020 10:01:37 +0100 Subject: [PATCH 351/657] Bump version --- pkgs/pub_semver/CHANGELOG.md | 5 +++++ pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 418325255..40f7c3e25 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.4.4 + +- Fix a bug of `VersionRange.union` where ranges bounded at infinity would get + combined wrongly. + # 1.4.3 - Update Dart SDK constraint to `>=2.0.0 <3.0.0`. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index e2ac3b078..a2238d2f7 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.4.3 +version: 1.4.4 description: >- Versions and version constraints implementing pub's versioning policy. This From 76343bfb7cb807f7862708f60c298bfdfcb03873 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 16 Mar 2020 10:21:26 -0700 Subject: [PATCH 352/657] Remove lints duplicated by pkg:pedantic --- pkgs/pub_semver/analysis_options.yaml | 37 --------------------------- 1 file changed, 37 deletions(-) diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index 248e8c6d7..d73e8049e 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -6,24 +6,15 @@ analyzer: linter: rules: - - always_declare_return_types - #- annotate_overrides - avoid_bool_literals_in_conditional_expressions - avoid_classes_with_only_static_members - - avoid_empty_else - avoid_function_literals_in_foreach_calls - - avoid_init_to_null - - avoid_null_checks_in_equality_operators - - avoid_relative_lib_imports - avoid_renaming_method_parameters - - avoid_return_types_on_setters - avoid_returning_null - avoid_returning_null_for_future - avoid_returning_null_for_void - avoid_returning_this - - avoid_shadowing_type_parameters - avoid_single_cascade_in_expression_statements - - avoid_types_as_parameter_names - avoid_unused_constructor_parameters - await_only_futures - camel_case_types @@ -33,8 +24,6 @@ linter: - constant_identifier_names - control_flow_in_finally - directives_ordering - - empty_catches - - empty_constructor_bodies - empty_statements - file_names - hash_and_equals @@ -42,54 +31,28 @@ linter: - invariant_booleans - iterable_contains_unrelated_type - join_return_with_assignment - - library_names - - library_prefixes - list_remove_unrelated_type - literal_only_boolean_expressions - no_adjacent_strings_in_list - - no_duplicate_case_values - non_constant_identifier_names - - null_closures - - omit_local_variable_types - only_throw_errors - overridden_fields - package_api_docs - package_names - package_prefixed_library_names - - prefer_adjacent_string_concatenation - - prefer_collection_literals - - prefer_conditional_assignment - prefer_const_constructors - - prefer_contains - - prefer_equal_for_default_values - - prefer_final_fields #- prefer_final_locals - - prefer_generic_function_type_aliases - prefer_initializing_formals - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - prefer_null_aware_operators - #- prefer_single_quotes - prefer_typing_uninitialized_variables - - recursive_getters - - slash_for_doc_comments - test_types_in_equals - throw_in_finally - - type_init_formals - - unawaited_futures - unnecessary_await_in_return - unnecessary_brace_in_string_interps - - unnecessary_const - unnecessary_getters_setters - unnecessary_lambdas - - unnecessary_new - unnecessary_null_aware_assignments - unnecessary_parenthesis - unnecessary_statements - - unnecessary_this - - unrelated_type_equality_checks - - use_function_type_syntax_for_parameters - - use_rethrow_when_possible - - valid_regexps - void_checks From 97668dae7172ca2b12f8161141aac6906962854b Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 17 Mar 2020 19:41:58 -0700 Subject: [PATCH 353/657] Add SourceSpan.subspan() (dart-lang/source_span#54) This is useful when a span may cover multiple logical tokens, and a user wants to single out a single specific token. --- pkgs/source_span/CHANGELOG.md | 5 +- pkgs/source_span/lib/src/file.dart | 21 +++++ pkgs/source_span/lib/src/span.dart | 52 ++++++++++++ pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/file_test.dart | 121 +++++++++++++++++++++++++++ pkgs/source_span/test/span_test.dart | 120 ++++++++++++++++++++++++++ 6 files changed, 319 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index c24535b24..5da330e47 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,4 +1,7 @@ -# 1.6.1-dev +# 1.7.0 + +* Add a `SourceSpan.subspan()` extension method which returns a slice of an + existing source span. # 1.6.0 diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index a03a875a5..9ad595cdf 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -423,4 +423,25 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { return _FileSpan(file, start, end); } } + + /// See `SourceSpanExtension.subspan`. + 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); + } +} + +// TODO(#52): Move these to instance methods in the next breaking release. +/// Extension methods on the [FileSpan] API. +extension FileSpanExtension on FileSpan { + /// See `SourceSpanExtension.subspan`. + FileSpan subspan(int start, [int end]) { + RangeError.checkValidRange(start, end, length); + if (start == 0 && (end == null || end == length)) return this; + + final startOffset = this.start.offset; + return file.span( + startOffset + start, end == null ? this.end.offset : startOffset + end); + } } diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 51e81ab80..15f0d34c1 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -2,6 +2,7 @@ // 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:charcode/charcode.dart'; import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; @@ -179,4 +180,55 @@ extension SourceSpanExtension on SourceSpan { primaryColor: primaryColor, secondaryColor: secondaryColor) .highlight(); + + /// 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]) { + RangeError.checkValidRange(start, end, length); + if (start == 0 && (end == null || end == length)) return this; + + final text = this.text; + final startLocation = this.start; + var line = startLocation.line; + var column = startLocation.column; + + // Adjust [line] and [column] as necessary if the character at [i] in [text] + // is a newline. + void consumeCodePoint(int i) { + final codeUnit = text.codeUnitAt(i); + if (codeUnit == $lf || + // A carriage return counts as a newline, but only if it's not + // followed by a line feed. + (codeUnit == $cr && + (i + 1 == text.length || text.codeUnitAt(i + 1) != $lf))) { + line += 1; + column = 0; + } else { + column += 1; + } + } + + for (var i = 0; i < start; i++) { + consumeCodePoint(i); + } + + final newStartLocation = SourceLocation(startLocation.offset + start, + sourceUrl: sourceUrl, line: line, column: column); + + SourceLocation newEndLocation; + if (end == null || end == length) { + newEndLocation = this.end; + } else if (end == start) { + newEndLocation = newStartLocation; + } else if (end != null && end != length) { + for (var i = start; i < end; i++) { + consumeCodePoint(i); + } + newEndLocation = SourceLocation(startLocation.offset + end, + sourceUrl: sourceUrl, line: line, column: column); + } + + return SourceSpan( + newStartLocation, newEndLocation, text.substring(start, end)); + } } diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index fce212461..126d9c09f 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.6.1-dev +version: 1.7.0 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 91922006d..63b523f3b 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -405,5 +405,126 @@ zip zap zop expect(span.expand(other), equals(other)); }); }); + + group('subspan()', () { + FileSpan span; + setUp(() { + span = file.span(5, 11); // "ar baz" + }); + + group('errors', () { + test('start must be greater than zero', () { + expect(() => span.subspan(-1), throwsRangeError); + }); + + test('start must be less than or equal to length', () { + expect(() => span.subspan(span.length + 1), throwsRangeError); + }); + + test('end must be greater than start', () { + expect(() => span.subspan(2, 1), throwsRangeError); + }); + + test('end must be less than or equal to length', () { + expect(() => span.subspan(0, span.length + 1), throwsRangeError); + }); + }); + + test('preserves the source URL', () { + final result = span.subspan(1, 2); + expect(result.start.sourceUrl, equals(span.sourceUrl)); + expect(result.end.sourceUrl, equals(span.sourceUrl)); + }); + + group('returns the original span', () { + test('with an implicit end', + () => expect(span.subspan(0), equals(span))); + + test('with an explicit end', + () => expect(span.subspan(0, span.length), equals(span))); + }); + + group('within a single line', () { + test('returns a strict substring of the original span', () { + final result = span.subspan(1, 5); + expect(result.text, equals('r ba')); + expect(result.start.offset, equals(6)); + expect(result.start.line, equals(0)); + expect(result.start.column, equals(6)); + expect(result.end.offset, equals(10)); + expect(result.end.line, equals(0)); + expect(result.end.column, equals(10)); + }); + + test('an implicit end goes to the end of the original span', () { + final result = span.subspan(1); + expect(result.text, equals('r baz')); + expect(result.start.offset, equals(6)); + expect(result.start.line, equals(0)); + expect(result.start.column, equals(6)); + expect(result.end.offset, equals(11)); + expect(result.end.line, equals(0)); + expect(result.end.column, equals(11)); + }); + + test('can return an empty span', () { + final result = span.subspan(3, 3); + expect(result.text, isEmpty); + expect(result.start.offset, equals(8)); + expect(result.start.line, equals(0)); + expect(result.start.column, equals(8)); + expect(result.end, equals(result.start)); + }); + }); + + group('across multiple lines', () { + setUp(() { + span = file.span(22, 30); // "boom\nzip" + }); + + test('with start and end in the middle of a line', () { + final result = span.subspan(3, 6); + expect(result.text, equals('m\nz')); + expect(result.start.offset, equals(25)); + expect(result.start.line, equals(1)); + expect(result.start.column, equals(13)); + expect(result.end.offset, equals(28)); + expect(result.end.line, equals(2)); + expect(result.end.column, equals(1)); + }); + + test('with start at the end of a line', () { + final result = span.subspan(4, 6); + expect(result.text, equals('\nz')); + expect(result.start.offset, equals(26)); + expect(result.start.line, equals(1)); + expect(result.start.column, equals(14)); + }); + + test('with start at the beginning of a line', () { + final result = span.subspan(5, 6); + expect(result.text, equals('z')); + expect(result.start.offset, equals(27)); + expect(result.start.line, equals(2)); + expect(result.start.column, equals(0)); + }); + + test('with end at the end of a line', () { + final result = span.subspan(3, 4); + expect(result.text, equals('m')); + expect(result.end.offset, equals(26)); + expect(result.end.line, equals(1)); + expect(result.end.column, equals(14)); + }); + + test('with end at the beginning of a line', () { + final result = span.subspan(3, 5); + expect(result.text, equals('m\n')); + expect(result.end.offset, equals(27)); + expect(result.end.line, equals(2)); + expect(result.end.column, equals(0)); + }); + }); + }); }); } diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index f44b02fdd..838d6b7cf 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -181,6 +181,126 @@ void main() { }); }); + group('subspan()', () { + group('errors', () { + test('start must be greater than zero', () { + expect(() => span.subspan(-1), throwsRangeError); + }); + + test('start must be less than or equal to length', () { + expect(() => span.subspan(span.length + 1), throwsRangeError); + }); + + test('end must be greater than start', () { + expect(() => span.subspan(2, 1), throwsRangeError); + }); + + test('end must be less than or equal to length', () { + expect(() => span.subspan(0, span.length + 1), throwsRangeError); + }); + }); + + test('preserves the source URL', () { + final result = span.subspan(1, 2); + expect(result.start.sourceUrl, equals(span.sourceUrl)); + expect(result.end.sourceUrl, equals(span.sourceUrl)); + }); + + group('returns the original span', () { + test('with an implicit end', () => expect(span.subspan(0), equals(span))); + + test('with an explicit end', + () => expect(span.subspan(0, span.length), equals(span))); + }); + + group('within a single line', () { + test('returns a strict substring of the original span', () { + final result = span.subspan(1, 5); + expect(result.text, equals('oo b')); + expect(result.start.offset, equals(6)); + expect(result.start.line, equals(0)); + expect(result.start.column, equals(6)); + expect(result.end.offset, equals(10)); + expect(result.end.line, equals(0)); + expect(result.end.column, equals(10)); + }); + + test('an implicit end goes to the end of the original span', () { + final result = span.subspan(1); + expect(result.text, equals('oo bar')); + expect(result.start.offset, equals(6)); + expect(result.start.line, equals(0)); + expect(result.start.column, equals(6)); + expect(result.end.offset, equals(12)); + expect(result.end.line, equals(0)); + expect(result.end.column, equals(12)); + }); + + test('can return an empty span', () { + final result = span.subspan(3, 3); + expect(result.text, isEmpty); + expect(result.start.offset, equals(8)); + expect(result.start.line, equals(0)); + expect(result.start.column, equals(8)); + expect(result.end, equals(result.start)); + }); + }); + + group('across multiple lines', () { + setUp(() { + span = SourceSpan( + SourceLocation(5, line: 2, column: 0), + SourceLocation(16, line: 4, column: 3), + 'foo\n' + 'bar\n' + 'baz'); + }); + + test('with start and end in the middle of a line', () { + final result = span.subspan(2, 5); + expect(result.text, equals('o\nb')); + expect(result.start.offset, equals(7)); + expect(result.start.line, equals(2)); + expect(result.start.column, equals(2)); + expect(result.end.offset, equals(10)); + expect(result.end.line, equals(3)); + expect(result.end.column, equals(1)); + }); + + test('with start at the end of a line', () { + final result = span.subspan(3, 5); + expect(result.text, equals('\nb')); + expect(result.start.offset, equals(8)); + expect(result.start.line, equals(2)); + expect(result.start.column, equals(3)); + }); + + test('with start at the beginning of a line', () { + final result = span.subspan(4, 5); + expect(result.text, equals('b')); + expect(result.start.offset, equals(9)); + expect(result.start.line, equals(3)); + expect(result.start.column, equals(0)); + }); + + test('with end at the end of a line', () { + final result = span.subspan(2, 3); + expect(result.text, equals('o')); + expect(result.end.offset, equals(8)); + expect(result.end.line, equals(2)); + expect(result.end.column, equals(3)); + }); + + test('with end at the beginning of a line', () { + final result = span.subspan(2, 4); + expect(result.text, equals('o\n')); + expect(result.end.offset, equals(9)); + expect(result.end.line, equals(3)); + expect(result.end.column, equals(0)); + }); + }); + }); + group('message()', () { test('prints the text being described', () { expect(span.message('oh no'), equals(""" From 9caf0c1923cef73305a371b5fafedb543ef56c22 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 18 Mar 2020 15:23:02 +0100 Subject: [PATCH 354/657] Make `.packages` files be more clever about defaults. (dart-lang/package_config#80) * Make `.packages` files be more clever about defaults. The `PackageConfig` for a `.packages` file now assigns a default language version of 2.7 to all packages, and if the package location ends in `/lib/`, it assumes the package's root directory is the parent directory of that. * Fix test. * Fix another test. --- pkgs/package_config/CHANGELOG.md | 2 ++ .../package_config/lib/src/packages_file.dart | 21 +++++++++++++++---- pkgs/package_config/test/parse_test.dart | 4 ++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 0b5e1563e..3015523c2 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -2,6 +2,8 @@ - Updated to support new rules for picking `package_config.json` over a specified `.packages`. +- Deduce package root from `.packages` derived package configuration, + and default all such packages to language version 2.7. ## 1.9.1 diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index e65e7e8a6..184b0dd04 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -7,6 +7,12 @@ import "package_config_impl.dart"; import "util.dart"; import "errors.dart"; +/// The language version prior to the release of language versioning. +/// +/// This is the default language version used by all packages from a +/// `.packages` file. +final LanguageVersion _languageVersion = LanguageVersion(2, 7); + /// Parses a `.packages` file into a [PackageConfig]. /// /// The [source] is the byte content of a `.packages` file, assumed to be @@ -100,17 +106,24 @@ PackageConfig parse( "Package URI as location for package", source, separatorIndex + 1)); continue; } - if (!packageLocation.path.endsWith('/')) { - packageLocation = - packageLocation.replace(path: packageLocation.path + "/"); + var path = packageLocation.path; + if (!path.endsWith('/')) { + path += "/"; + packageLocation = packageLocation.replace(path: path); } if (packageNames.contains(packageName)) { onError(PackageConfigFormatException( "Same package name occured more than once", source, start)); continue; } + var rootUri = packageLocation; + if (path.endsWith("/lib/")) { + // Assume default Pub package layout. Include package itself in root. + rootUri = + packageLocation.replace(path: path.substring(0, path.length - 4)); + } var package = SimplePackage.validate( - packageName, packageLocation, packageLocation, null, null, (error) { + packageName, rootUri, packageLocation, _languageVersion, null, (error) { if (error is ArgumentError) { onError(PackageConfigFormatException(error.message, source)); } else { diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 367b64384..59a7e7126 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -34,9 +34,9 @@ void main() { var foo = result["foo"]; expect(foo, isNotNull); - expect(foo.root, Uri.parse("file:///foo/lib/")); + expect(foo.root, Uri.parse("file:///foo/")); expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); - expect(foo.languageVersion, null); + expect(foo.languageVersion, LanguageVersion(2, 7)); }); test("valid empty", () { From 19182255aaa1a5b1869606264c20bafcccee25a3 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 26 Mar 2020 17:09:12 +0100 Subject: [PATCH 355/657] Fix Package constructor not accepting relative packageUriRoot. (dart-lang/package_config#82) * Fix Package constructor not accepting relative packageUriRoot. --- pkgs/package_config/CHANGELOG.md | 4 + .../lib/src/package_config.dart | 2 +- .../lib/src/package_config_impl.dart | 5 +- pkgs/package_config/pubspec.yaml | 2 +- .../test/package_config_impl_test.dart | 145 ++++++++++++++++++ 5 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 pkgs/package_config/test/package_config_impl_test.dart diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 3015523c2..6dcae80cf 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.9.3 + +- Fix `Package` constructor not accepting relative `packageUriRoot`. + ## 1.9.2 - Updated to support new rules for picking `package_config.json` over diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 364df75b1..30c758a96 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -219,7 +219,7 @@ abstract class Package { /// The [packageUriRoot], if provided, must be either an absolute /// directory URI or a relative URI reference which is then resolved /// relative to [root]. It must then also be a subdirectory of [root], - /// or the same directory. + /// or the same directory, and must end with `/`. /// If [languageVersion] is supplied, it must be a valid Dart language /// version, which means two decimal integer literals separated by a `.`, /// where the integer literals have no leading zeros unless they are diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index f68a9ea75..9e23af063 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -214,7 +214,10 @@ class SimplePackage implements Package { root = root.replace(path: root.path + "/"); } } - if (!fatalError) { + if (packageUriRoot == null) { + packageUriRoot = root; + } else if (!fatalError) { + packageUriRoot = root.resolveUri(packageUriRoot); if (!isAbsoluteDirectoryUri(packageUriRoot)) { onError(PackageConfigArgumentError( packageUriRoot, diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 3f5ec27e0..b7d596910 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 1.9.2 +version: 1.9.3 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart new file mode 100644 index 000000000..6921118f3 --- /dev/null +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -0,0 +1,145 @@ +// 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:package_config/package_config_types.dart"; +import "package:test/test.dart"; +import "src/util.dart"; + +void main() { + var unique = Object(); + var root = Uri.file("/tmp/root/"); + + group("LanguageVersion", () { + test("minimal", () { + var version = LanguageVersion(3, 5); + expect(version.major, 3); + expect(version.minor, 5); + }); + + test("negative major", () { + expect(() => LanguageVersion(-1, 1), throwsArgumentError); + }); + + test("negative minor", () { + expect(() => LanguageVersion(1, -1), throwsArgumentError); + }); + + test("minimal parse", () { + var version = LanguageVersion.parse("3.5"); + expect(version.major, 3); + expect(version.minor, 5); + }); + + void failParse(String name, String input) { + test("$name - error", () { + expect(() => LanguageVersion.parse(input), + throwsA(TypeMatcher())); + expect(() => LanguageVersion.parse(input), throwsFormatException); + var failed = false; + var actual = LanguageVersion.parse(input, onError: (_) { + failed = true; + }); + expect(failed, true); + expect(actual, isA()); + }); + } + + failParse("Leading zero major", "01.1"); + failParse("Leading zero minor", "1.01"); + failParse("Sign+ major", "+1.1"); + failParse("Sign- major", "-1.1"); + failParse("Sign+ minor", "1.+1"); + failParse("Sign- minor", "1.-1"); + failParse("WhiteSpace 1", " 1.1"); + failParse("WhiteSpace 2", "1 .1"); + failParse("WhiteSpace 3", "1. 1"); + failParse("WhiteSpace 4", "1.1 "); + }); + + group("Package", () { + test("minimal", () { + var package = Package("name", root, extraData: unique); + expect(package.name, "name"); + expect(package.root, root); + expect(package.packageUriRoot, root); + expect(package.languageVersion, null); + expect(package.extraData, same(unique)); + }); + + test("absolute package root", () { + var version = LanguageVersion(1, 1); + var absolute = root.resolve("foo/bar/"); + var package = Package("name", root, + packageUriRoot: absolute, + languageVersion: version, + extraData: unique); + expect(package.name, "name"); + expect(package.root, root); + expect(package.packageUriRoot, absolute); + expect(package.languageVersion, version); + expect(package.extraData, same(unique)); + }); + + test("relative package root", () { + var relative = Uri.parse("foo/bar/"); + var absolute = root.resolveUri(relative); + var package = + Package("name", root, packageUriRoot: relative, extraData: unique); + expect(package.name, "name"); + expect(package.root, root); + expect(package.packageUriRoot, absolute); + expect(package.languageVersion, null); + expect(package.extraData, same(unique)); + }); + + for (var badName in ["a/z", "a:z", "", "..."]) { + test("Invalid name '$badName'", () { + expect(() => Package(badName, root), throwsPackageConfigError); + }); + } + + test("Invalid root, not absolute", () { + expect( + () => Package("name", Uri.parse("/foo/")), throwsPackageConfigError); + }); + + test("Invalid root, not ending in slash", () { + expect(() => Package("name", Uri.parse("file:///foo")), + throwsPackageConfigError); + }); + + test("invalid package root, not ending in slash", () { + expect(() => Package("name", root, packageUriRoot: Uri.parse("foo")), + throwsPackageConfigError); + }); + + test("invalid package root, not inside root", () { + expect(() => Package("name", root, packageUriRoot: Uri.parse("../baz/")), + throwsPackageConfigError); + }); + }); + + group("package config", () { + test("emtpy", () { + var empty = PackageConfig([], extraData: unique); + expect(empty.version, 2); + expect(empty.packages, isEmpty); + expect(empty.extraData, same(unique)); + expect(empty.resolve(pkg("a", "b")), isNull); + }); + + test("single", () { + var package = Package("name", root); + var single = PackageConfig([package], extraData: unique); + expect(single.version, 2); + expect(single.packages, hasLength(1)); + expect(single.extraData, same(unique)); + expect(single.resolve(pkg("a", "b")), isNull); + var resolved = single.resolve(pkg("name", "a/b")); + expect(resolved, root.resolve("a/b")); + }); + }); +} + +final Matcher throwsPackageConfigError = throwsA(isA()); From 5f06761b02746ce88a5f269b1b09a146a9e6e0a3 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Wed, 6 May 2020 14:59:21 -0700 Subject: [PATCH 356/657] fix a lint about an unused import --- pkgs/package_config/.travis.yml | 2 +- pkgs/package_config/lib/src/package_config_io.dart | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml index 09fc296c2..3a47bb586 100644 --- a/pkgs/package_config/.travis.yml +++ b/pkgs/package_config/.travis.yml @@ -5,7 +5,7 @@ dart: dart_task: - test - dartfmt - - dartanalyzer: --fatal-warnings . + - dartanalyzer: --fatal-warnings --fatal-infos . matrix: include: diff --git a/pkgs/package_config/lib/src/package_config_io.dart b/pkgs/package_config/lib/src/package_config_io.dart index 31bc1cc99..bfbb1e373 100644 --- a/pkgs/package_config/lib/src/package_config_io.dart +++ b/pkgs/package_config/lib/src/package_config_io.dart @@ -8,7 +8,6 @@ import "dart:convert"; import "dart:io"; import "dart:typed_data"; -import "discovery.dart" show packageConfigJsonPath; import "errors.dart"; import "package_config_impl.dart"; import "package_config_json.dart"; From 6dc79a7796b18a1e9467e103ed6b43e57a5dab29 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Sat, 30 May 2020 14:57:29 -0700 Subject: [PATCH 357/657] Correct markdown in library dartdoc This dartdoc has "code" examples that are not rendered as code. This change fixes that. --- pkgs/source_maps/lib/source_maps.dart | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 0d171788b..0c6cc084c 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -5,19 +5,25 @@ /// Library to create and parse source maps. /// /// Create a source map using [SourceMapBuilder]. For example: -/// var json = (new SourceMapBuilder() -/// ..add(inputSpan1, outputSpan1) -/// ..add(inputSpan2, outputSpan2) -/// ..add(inputSpan3, outputSpan3) -/// .toJson(outputFile); +/// +/// ```dart +/// var json = (new SourceMapBuilder() +/// ..add(inputSpan1, outputSpan1) +/// ..add(inputSpan2, outputSpan2) +/// ..add(inputSpan3, outputSpan3) +/// .toJson(outputFile); +/// ``` /// /// Use the source_span package's [SourceSpan] and [SourceFile] classes to /// specify span locations. /// /// Parse a source map using [parse], and call `spanFor` on the returned mapping /// object. For example: -/// var mapping = parse(json); -/// mapping.spanFor(outputSpan1.line, outputSpan1.column) +/// +/// ```dart +/// var mapping = parse(json); +/// mapping.spanFor(outputSpan1.line, outputSpan1.column) +/// ``` library source_maps; import 'package:source_span/source_span.dart'; From b4d7bdc3f47d2b59b30f394729f43ef2096cdd59 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 8 Jun 2020 11:52:21 -0700 Subject: [PATCH 358/657] Remove deprecated lint --- pkgs/pool/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index f8eebb47a..2c837ba4d 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -62,7 +62,6 @@ linter: - prefer_typing_uninitialized_variables - recursive_getters - slash_for_doc_comments - - super_goes_last - test_types_in_equals - throw_in_finally - type_init_formals From c26f921bdb85466ee6522dce983732a530d1630e Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 8 Jun 2020 11:53:39 -0700 Subject: [PATCH 359/657] Remove lints duplicated in pkg:pedantic --- pkgs/pool/analysis_options.yaml | 39 ++------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index 2c837ba4d..8bef8818d 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -1,22 +1,15 @@ include: package:pedantic/analysis_options.yaml + analyzer: strong-mode: implicit-casts: false + linter: rules: - - always_declare_return_types - - annotate_overrides - - avoid_empty_else - avoid_function_literals_in_foreach_calls - - avoid_init_to_null - - avoid_null_checks_in_equality_operators - - avoid_relative_lib_imports - avoid_renaming_method_parameters - - avoid_return_types_on_setters - avoid_returning_null - avoid_returning_null_for_future - - avoid_shadowing_type_parameters - - avoid_types_as_parameter_names - avoid_unused_constructor_parameters - await_only_futures - camel_case_types @@ -25,58 +18,30 @@ linter: - constant_identifier_names - control_flow_in_finally - directives_ordering - - empty_catches - - empty_constructor_bodies - empty_statements - hash_and_equals - implementation_imports - invariant_booleans - iterable_contains_unrelated_type - - library_names - - library_prefixes - list_remove_unrelated_type - literal_only_boolean_expressions - no_adjacent_strings_in_list - - no_duplicate_case_values - non_constant_identifier_names - - null_closures - - omit_local_variable_types - only_throw_errors - overridden_fields - package_api_docs - package_names - package_prefixed_library_names - - prefer_adjacent_string_concatenation - - prefer_collection_literals - - prefer_conditional_assignment - prefer_const_constructors - - prefer_contains - - prefer_equal_for_default_values - - prefer_final_fields - #- prefer_final_locals - prefer_initializing_formals - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - #- prefer_single_quotes - prefer_typing_uninitialized_variables - - recursive_getters - - slash_for_doc_comments - test_types_in_equals - throw_in_finally - - type_init_formals - - unawaited_futures - unnecessary_await_in_return - unnecessary_brace_in_string_interps - - unnecessary_const - unnecessary_getters_setters - unnecessary_lambdas - - unnecessary_new - unnecessary_null_aware_assignments - unnecessary_parenthesis - unnecessary_statements - - unnecessary_this - - unrelated_type_equality_checks - - use_function_type_syntax_for_parameters - - use_rethrow_when_possible - - valid_regexps From 453166966c10ef615724ea2c6ea0fff9e8fe4448 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 8 Jun 2020 11:54:52 -0700 Subject: [PATCH 360/657] CI: test on the oldest supported SDK Also use Chrome instead of firefox for browser testing --- pkgs/pool/.travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index 07e132f33..18f741339 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -1,11 +1,11 @@ language: dart dart: + - 2.0.0 - dev dart_task: - - test: --platform vm - - test: --platform firefox + - test: --platform vm,chrome - dartfmt - dartanalyzer: --fatal-infos --fatal-warnings . From 4ddf2b607bafa96ce6285ed2d579b78cb26a12fe Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 14 Jul 2020 15:47:02 -0700 Subject: [PATCH 361/657] Merge the null_safety branch into master (dart-lang/source_span#56) --- pkgs/source_span/.travis.yml | 40 ++++++--- pkgs/source_span/CHANGELOG.md | 6 ++ pkgs/source_span/analysis_options.yaml | 2 + pkgs/source_span/lib/src/file.dart | 48 +++++----- pkgs/source_span/lib/src/highlighter.dart | 60 +++++++------ pkgs/source_span/lib/src/location.dart | 10 +-- pkgs/source_span/lib/src/location_mixin.dart | 2 +- pkgs/source_span/lib/src/span.dart | 10 +-- pkgs/source_span/lib/src/span_exception.dart | 22 ++--- pkgs/source_span/lib/src/span_mixin.dart | 2 +- pkgs/source_span/lib/src/utils.dart | 10 +-- pkgs/source_span/pubspec.yaml | 88 +++++++++++++++++-- pkgs/source_span/test/file_test.dart | 8 +- pkgs/source_span/test/highlight_test.dart | 4 +- pkgs/source_span/test/location_test.dart | 2 +- .../test/multiple_highlight_test.dart | 4 +- pkgs/source_span/test/span_test.dart | 5 +- pkgs/source_span/test/utils_test.dart | 8 +- 18 files changed, 214 insertions(+), 117 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index 9738ed50e..8361c623e 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.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/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 5da330e47..1723b0fc2 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/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/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index ab5a4f209..ced2e21b2 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -2,6 +2,8 @@ include: package:pedantic/analysis_options.yaml analyzer: strong-mode: implicit-casts: false + enable-experiment: + - non-nullable linter: rules: - always_declare_return_types diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 9ad595cdf..6fbcd4193 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -23,7 +23,7 @@ class SourceFile { /// 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 @@ class SourceFile { /// 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 @@ class SourceFile { /// forwards-compatibility, callers should only pass in characters less than /// or equal to `0xFFFF`. SourceFile.decoded(Iterable 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 @@ class SourceFile { /// 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 @@ class SourceFile { 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 @@ class SourceFile { /// 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 @@ class SourceFile { /// /// 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 @@ class SourceFile { /// 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 @@ class SourceFile { /// 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 @@ class FileLocation extends SourceLocationMixin implements SourceLocation { 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 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { final int _end; @override - Uri get sourceUrl => file.url; + Uri? get sourceUrl => file.url; @override int get length => _end - _start; @@ -318,7 +319,7 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { 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 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { 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 @@ class _FileSpan extends SourceSpanMixin implements 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; return file.span(_start + start, end == null ? _end : _start + end); @@ -436,7 +436,7 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { /// 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/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index cef6f79dd..491dae5ba 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -6,7 +6,6 @@ import 'dart:math' as math; 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 @@ class Highlighter { /// 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 @@ class Highlighter { : 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 @@ class Highlighter { /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors Highlighter.multiple(SourceSpan primarySpan, String primaryLabel, Map 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 @@ class Highlighter { .where((highlight) => isMultiline(highlight.span)) .length) .reduce(math.max), - _multipleFiles = !isAllTheSame(_lines.map((line) => line.url)); + _multipleFiles = + !isAllTheSame(_lines.map((line) => line.url).whereType()); /// Returns whether [lines] contains any adjacent lines from the same source /// file that aren't adjacent in the original file. @@ -127,8 +127,8 @@ class Highlighter { /// 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 @@ class Highlighter { // 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 @@ class Highlighter { // 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 @@ class Highlighter { _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 @@ class Highlighter { /// 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 @@ class Highlighter { /// 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 @@ class Highlighter { }, 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 @@ class Highlighter { // 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 @@ class Highlighter { /// /// 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 @@ class Highlighter { } /// 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 @@ class Highlighter { // // 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 @@ class Highlighter { /// 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 @@ class _Highlight { /// /// 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 @@ class _Highlight { /// 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 @@ class _Line { 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/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 93942f05f..097961841 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -16,7 +16,7 @@ class SourceLocation implements Comparable { /// /// 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 @@ class SourceLocation implements Comparable { /// 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 @@ class SourceLocation implements Comparable { 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 @@ class SourceLocation implements Comparable { /// 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/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index a54e363d0..9a1f930f8 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -48,7 +48,7 @@ abstract class SourceLocationMixin implements SourceLocation { 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/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 15f0d34c1..94c05ba7a 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -27,7 +27,7 @@ abstract class SourceSpan implements Comparable { /// /// 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 @@ extension SourceSpanExtension on SourceSpan { /// [FileSpan]s). String messageMultiple( String message, String label, Map 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 @@ extension SourceSpanExtension on SourceSpan { /// much more useful output with [SourceSpanWithContext]s (including /// [FileSpan]s). String highlightMultiple(String label, Map 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 @@ extension SourceSpanExtension on SourceSpan { /// 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 @@ extension SourceSpanExtension on SourceSpan { 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/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index 32aaa4eae..c6db03ba2 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -15,8 +15,8 @@ class SourceSpanException implements Exception { /// 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 @@ class SourceSpanException implements Exception { @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 @@ class SourceSpanFormatException extends SourceSpanException 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 @@ class MultiSourceSpanException extends SourceSpanException { /// additional information and helps distinguish it from [secondarySpans]. final Map secondarySpans; - MultiSourceSpanException(String message, SourceSpan span, this.primaryLabel, + MultiSourceSpanException(String message, SourceSpan? span, this.primaryLabel, Map secondarySpans) : secondarySpans = Map.unmodifiable(secondarySpans), super(message, span); @@ -80,11 +80,11 @@ class MultiSourceSpanException extends SourceSpanException { /// 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 @@ class MultiSourceSpanException extends SourceSpanException { useColor = true; } - final formatted = span.messageMultiple( + final formatted = span!.messageMultiple( message, primaryLabel, secondarySpans, color: useColor, primaryColor: primaryColor, @@ -108,9 +108,9 @@ class MultiSourceSpanFormatException extends MultiSourceSpanException 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 secondarySpans, [this.source]) : super(message, span, primaryLabel, secondarySpans); diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 55eae94a9..0f751ea52 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -17,7 +17,7 @@ import 'utils.dart'; /// 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/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 5cb5e90e7..72c61737c 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -16,10 +16,8 @@ T max(T obj1, T obj2) => /// Returns whether all elements of [iter] are the same value, according to /// `==`. -/// -/// Assumes [iter] doesn't contain any `null` values. bool isAllTheSame(Iterable iter) { - Object lastValue; + Object? lastValue; for (var value in iter) { if (lastValue == null) { lastValue = value; @@ -34,14 +32,14 @@ bool isAllTheSame(Iterable iter) { bool isMultiline(SourceSpan span) => span.start.line != span.end.line; /// Sets the first `null` element of [list] to [element]. -void replaceFirstNull(List list, E element) { +void replaceFirstNull(List 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(List list, E element) { +void replaceWithNull(List list, E element) { final index = list.indexOf(element); if (index < 0) { throw ArgumentError('$list contains no elements matching $element.'); @@ -63,7 +61,7 @@ int countCodeUnits(String string, int codeUnit) { /// /// 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/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 126d9c09f..89f40c8d7 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/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/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 63b523f3b..581f03f30 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -6,7 +6,7 @@ import 'package:test/test.dart'; 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 @@ zip zap zop }); group('union()', () { - FileSpan span; + late FileSpan span; setUp(() { span = file.span(5, 12); }); @@ -358,7 +358,7 @@ zip zap zop }); group('expand()', () { - FileSpan span; + late FileSpan span; setUp(() { span = file.span(5, 12); }); @@ -407,7 +407,7 @@ zip zap zop }); group('subspan()', () { - FileSpan span; + late FileSpan span; setUp(() { span = file.span(5, 11); // "ar baz" }); diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 6313108e1..7754d0076 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -10,7 +10,7 @@ import 'package:term_glyph/term_glyph.dart' as glyph; import 'package:test/test.dart'; void main() { - bool oldAscii; + late bool oldAscii; setUpAll(() { oldAscii = glyph.ascii; glyph.ascii = true; @@ -20,7 +20,7 @@ void main() { glyph.ascii = oldAscii; }); - SourceFile file; + late SourceFile file; setUp(() { file = SourceFile.fromString(''' foo bar baz diff --git a/pkgs/source_span/test/location_test.dart b/pkgs/source_span/test/location_test.dart index c22a148c0..bbe259b12 100644 --- a/pkgs/source_span/test/location_test.dart +++ b/pkgs/source_span/test/location_test.dart @@ -6,7 +6,7 @@ import 'package:source_span/source_span.dart'; 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/pkgs/source_span/test/multiple_highlight_test.dart b/pkgs/source_span/test/multiple_highlight_test.dart index d9d1b30c8..6d5ec9d23 100644 --- a/pkgs/source_span/test/multiple_highlight_test.dart +++ b/pkgs/source_span/test/multiple_highlight_test.dart @@ -7,7 +7,7 @@ import 'package:term_glyph/term_glyph.dart' as glyph; import 'package:test/test.dart'; void main() { - bool oldAscii; + late bool oldAscii; setUpAll(() { oldAscii = glyph.ascii; glyph.ascii = true; @@ -17,7 +17,7 @@ void main() { glyph.ascii = oldAscii; }); - SourceFile file; + late SourceFile file; setUp(() { file = SourceFile.fromString(''' foo bar baz diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 838d6b7cf..c27048ede 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -9,7 +9,8 @@ import 'package:source_span/source_span.dart'; 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 @@ void main() { 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/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index a4a372eec..02888dfa1 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -9,26 +9,26 @@ void main() { 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); }); From 8334a9f0621e86064cd0026e81c425d81ba15927 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 14 Jul 2020 15:47:34 -0700 Subject: [PATCH 362/657] Merge the null_safety branch into master (dart-lang/source_maps#49) --- pkgs/source_maps/.travis.yml | 35 ++-- pkgs/source_maps/CHANGELOG.md | 4 + pkgs/source_maps/analysis_options.yaml | 4 + pkgs/source_maps/lib/builder.dart | 10 +- pkgs/source_maps/lib/parser.dart | 182 ++++++++++-------- pkgs/source_maps/lib/printer.dart | 56 +++--- pkgs/source_maps/lib/refactor.dart | 10 +- pkgs/source_maps/lib/src/source_map_span.dart | 2 +- pkgs/source_maps/lib/src/vlq.dart | 8 +- pkgs/source_maps/pubspec.yaml | 85 +++++++- pkgs/source_maps/test/common.dart | 4 +- pkgs/source_maps/test/parser_test.dart | 93 ++++----- pkgs/source_maps/test/refactor_test.dart | 8 +- pkgs/source_maps/test/vlq_test.dart | 4 +- 14 files changed, 314 insertions(+), 191 deletions(-) diff --git a/pkgs/source_maps/.travis.yml b/pkgs/source_maps/.travis.yml index a49fc6ff0..785c7c2e4 100644 --- a/pkgs/source_maps/.travis.yml +++ b/pkgs/source_maps/.travis.yml @@ -1,21 +1,34 @@ language: dart dart: - - dev -dart_task: - - test: -p vm,chrome - - dartanalyzer + - be/raw/latest -matrix: +jobs: include: - # Only validate formatting using the dev release - - dart: dev - dart_task: dartfmt + - stage: analyze_and_format + name: "Analyze" + dart: be/raw/latest + os: linux + script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . + - stage: analyze_and_format + name: "Format" + dart: be/raw/latest + os: linux + script: dartfmt -n --set-exit-if-changed . + - stage: test + name: "Vm Tests" + dart: be/raw/latest + os: linux + script: pub run --enable-experiment=non-nullable test -p vm + +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: - - $HOME/.pub-cache + directories: + - $HOME/.pub-cache diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 321c37140..bc7c9ef84 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.11.0-nullsafety + +* Migrate to null safety + ## 0.10.9 * Fix a number of document comment issues. diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml index 4f9dfb038..86c836783 100644 --- a/pkgs/source_maps/analysis_options.yaml +++ b/pkgs/source_maps/analysis_options.yaml @@ -1,5 +1,9 @@ include: package:pedantic/analysis_options.yaml +analyzer: + enable-experiment: + - non-nullable + linter: rules: - comment_references diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index e6b8d82ee..5c56ca462 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -21,9 +21,7 @@ class SourceMapBuilder { /// Adds an entry mapping the [targetOffset] to [source]. void addFromOffset(SourceLocation source, SourceFile targetFile, int targetOffset, String identifier) { - if (targetFile == null) { - throw ArgumentError('targetFile cannot be null'); - } + ArgumentError.checkNotNull(targetFile, 'targetFile'); _entries.add(Entry(source, targetFile.location(targetOffset), identifier)); } @@ -33,7 +31,7 @@ class SourceMapBuilder { /// `isIdentifier` set to true, this entry is considered to represent an /// identifier whose value will be stored in the source map. [isIdentifier] /// takes precedence over [target]'s `isIdentifier` value. - void addSpan(SourceSpan source, SourceSpan target, {bool isIdentifier}) { + void addSpan(SourceSpan source, SourceSpan target, {bool? isIdentifier}) { isIdentifier ??= source is SourceMapSpan ? source.isIdentifier : false; var name = isIdentifier ? source.text : null; @@ -42,7 +40,7 @@ class SourceMapBuilder { /// Adds an entry mapping [target] to [source]. void addLocation( - SourceLocation source, SourceLocation target, String identifier) { + SourceLocation source, SourceLocation target, String? identifier) { _entries.add(Entry(source, target, identifier)); } @@ -64,7 +62,7 @@ class Entry implements Comparable { final SourceLocation target; /// An identifier name, when this location is the start of an identifier. - final String identifierName; + final String? identifierName; /// Creates a new [Entry] mapping [target] to [source]. Entry(this.source, this.target, this.identifierName); diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index e3044aa31..1f8b8175f 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -23,7 +23,8 @@ import 'src/vlq.dart'; // the string represenation. // TODO(tjblasi): Ignore the first line of [jsonMap] if the JSON safety string // `)]}'` begins the string representation of the map. -Mapping parse(String jsonMap, {Map otherMaps, mapUrl}) => +Mapping parse(String jsonMap, + {Map? otherMaps, /*String|Uri*/ Object? mapUrl}) => parseJson(jsonDecode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); /// Parses a source map or source map bundle directly from a json string. @@ -31,7 +32,8 @@ Mapping parse(String jsonMap, {Map otherMaps, mapUrl}) => /// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of /// the source map file itself. If it's passed, any URLs in the source /// map will be interpreted as relative to this URL when generating spans. -Mapping parseExtended(String jsonMap, {Map otherMaps, mapUrl}) => +Mapping parseExtended(String jsonMap, + {Map? otherMaps, /*String|Uri*/ Object? mapUrl}) => parseJsonExtended(jsonDecode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); @@ -40,8 +42,8 @@ Mapping parseExtended(String jsonMap, {Map otherMaps, mapUrl}) => /// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of /// the source map file itself. If it's passed, any URLs in the source /// map will be interpreted as relative to this URL when generating spans. -Mapping parseJsonExtended(/*List|Map*/ json, - {Map otherMaps, mapUrl}) { +Mapping parseJsonExtended(/*List|Map*/ Object? json, + {Map? otherMaps, /*String|Uri*/ Object? mapUrl}) { if (json is List) { return MappingBundle.fromJson(json, mapUrl: mapUrl); } @@ -53,7 +55,8 @@ Mapping parseJsonExtended(/*List|Map*/ json, /// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of /// the source map file itself. If it's passed, any URLs in the source /// map will be interpreted as relative to this URL when generating spans. -Mapping parseJson(Map map, {Map otherMaps, mapUrl}) { +Mapping parseJson(Map map, + {Map? otherMaps, /*String|Uri*/ Object? mapUrl}) { if (map['version'] != 3) { throw ArgumentError('unexpected source map version: ${map["version"]}. ' 'Only version 3 is supported.'); @@ -79,12 +82,12 @@ abstract class Mapping { /// [uri] is the optional location of the output file to find the span for /// to disambiguate cases where a mapping may have different mappings for /// different output files. - SourceMapSpan spanFor(int line, int column, - {Map files, String uri}); + SourceMapSpan? spanFor(int line, int column, + {Map? files, String? uri}); /// Returns the span associated with [location]. - SourceMapSpan spanForLocation(SourceLocation location, - {Map files}) { + SourceMapSpan? spanForLocation(SourceLocation location, + {Map? files}) { return spanFor(location.line, location.column, uri: location.sourceUrl?.toString(), files: files); } @@ -103,8 +106,8 @@ class MultiSectionMapping extends Mapping { final List _maps = []; /// Creates a section mapping from json. - MultiSectionMapping.fromJson(List sections, Map otherMaps, - {mapUrl}) { + MultiSectionMapping.fromJson(List sections, Map? otherMaps, + {/*String|Uri*/ Object? mapUrl}) { for (var section in sections) { var offset = section['offset']; if (offset == null) throw FormatException('section missing offset'); @@ -124,12 +127,13 @@ class MultiSectionMapping extends Mapping { if (url != null && map != null) { throw FormatException("section can't use both url and map entries"); } else if (url != null) { - if (otherMaps == null || otherMaps[url] == null) { + var other = otherMaps?[url]; + if (otherMaps == null || other == null) { throw FormatException( 'section contains refers to $url, but no map was ' 'given for it. Make sure a map is passed in "otherMaps"'); } - _maps.add(parseJson(otherMaps[url], otherMaps: otherMaps, mapUrl: url)); + _maps.add(parseJson(other, otherMaps: otherMaps, mapUrl: url)); } else if (map != null) { _maps.add(parseJson(map, otherMaps: otherMaps, mapUrl: mapUrl)); } else { @@ -141,7 +145,7 @@ class MultiSectionMapping extends Mapping { } } - int _indexFor(line, column) { + int _indexFor(int line, int column) { for (var i = 0; i < _lineStart.length; i++) { if (line < _lineStart[i]) return i - 1; if (line == _lineStart[i] && column < _columnStart[i]) return i - 1; @@ -150,8 +154,8 @@ class MultiSectionMapping extends Mapping { } @override - SourceMapSpan spanFor(int line, int column, - {Map files, String uri}) { + SourceMapSpan? spanFor(int line, int column, + {Map? files, String? uri}) { // TODO(jacobr): perhaps verify that targetUrl matches the actual uri // or at least ends in the same file name. var index = _indexFor(line, column); @@ -183,7 +187,7 @@ class MappingBundle extends Mapping { MappingBundle(); - MappingBundle.fromJson(List json, {String mapUrl}) { + MappingBundle.fromJson(List json, {/*String|Uri*/ Object? mapUrl}) { for (var map in json) { addMapping(parseJson(map, mapUrl: mapUrl) as SingleMapping); } @@ -192,7 +196,10 @@ class MappingBundle extends Mapping { void addMapping(SingleMapping mapping) { // TODO(jacobr): verify that targetUrl is valid uri instead of a windows // path. - _mappings[mapping.targetUrl] = mapping; + // TODO: Remove type arg https://github.com/dart-lang/sdk/issues/42227 + var targetUrl = ArgumentError.checkNotNull( + mapping.targetUrl, 'mapping.targetUrl'); + _mappings[targetUrl] = mapping; } /// Encodes the Mapping mappings as a json map. @@ -210,11 +217,10 @@ class MappingBundle extends Mapping { bool containsMapping(String url) => _mappings.containsKey(url); @override - SourceMapSpan spanFor(int line, int column, - {Map files, String uri}) { - if (uri == null) { - throw ArgumentError.notNull('uri'); - } + SourceMapSpan? spanFor(int line, int column, + {Map? files, String? uri}) { + // TODO: Remove type arg https://github.com/dart-lang/sdk/issues/42227 + uri = ArgumentError.checkNotNull(uri, 'uri'); // Find the longest suffix of the uri that matches the sourcemap // where the suffix starts after a path segment boundary. @@ -232,9 +238,10 @@ class MappingBundle extends Mapping { for (var i = 0; i < uri.length; ++i) { if (onBoundary) { var candidate = uri.substring(i); - if (_mappings.containsKey(candidate)) { - return _mappings[candidate] - .spanFor(line, column, files: files, uri: candidate); + var candidateMapping = _mappings[candidate]; + if (candidateMapping != null) { + return candidateMapping.spanFor(line, column, + files: files, uri: candidate); } } onBoundary = separatorCodeUnits.contains(uri.codeUnitAt(i)); @@ -270,18 +277,18 @@ class SingleMapping extends Mapping { /// field. /// /// Files whose contents aren't available are `null`. - final List files; + final List files; /// Entries indicating the beginning of each span. final List lines; /// Url of the target file. - String targetUrl; + String? targetUrl; /// Source root prepended to all entries in [urls]. - String sourceRoot; + String? sourceRoot; - final Uri _mapUrl; + final Uri? _mapUrl; final Map extensions; @@ -290,9 +297,9 @@ class SingleMapping extends Mapping { extensions = {}; factory SingleMapping.fromEntries(Iterable entries, - [String fileUrl]) { + [String? fileUrl]) { // The entries needs to be sorted by the target offsets. - var sourceEntries = List.from(entries)..sort(); + var sourceEntries = entries.toList()..sort(); var lines = []; // Indices associated with file urls that will be part of the source map. We @@ -307,7 +314,7 @@ class SingleMapping extends Mapping { var files = {}; var lineNum; - List targetEntries; + late List targetEntries; for (var sourceEntry in sourceEntries) { if (lineNum == null || sourceEntry.target.line > lineNum) { lineNum = sourceEntry.target.line; @@ -315,24 +322,21 @@ class SingleMapping extends Mapping { lines.add(TargetLineEntry(lineNum, targetEntries)); } - if (sourceEntry.source == null) { - targetEntries.add(TargetEntry(sourceEntry.target.column)); - } else { - var sourceUrl = sourceEntry.source.sourceUrl; - var urlId = urls.putIfAbsent( - sourceUrl == null ? '' : sourceUrl.toString(), () => urls.length); + var sourceUrl = sourceEntry.source.sourceUrl; + var urlId = urls.putIfAbsent( + sourceUrl == null ? '' : sourceUrl.toString(), () => urls.length); - if (sourceEntry.source is FileLocation) { - files.putIfAbsent( - urlId, () => (sourceEntry.source as FileLocation).file); - } - - var srcNameId = sourceEntry.identifierName == null - ? null - : names.putIfAbsent(sourceEntry.identifierName, () => names.length); - targetEntries.add(TargetEntry(sourceEntry.target.column, urlId, - sourceEntry.source.line, sourceEntry.source.column, srcNameId)); + if (sourceEntry.source is FileLocation) { + files.putIfAbsent( + urlId, () => (sourceEntry.source as FileLocation).file); } + + var sourceEntryIdentifierName = sourceEntry.identifierName; + var srcNameId = sourceEntryIdentifierName == null + ? null + : names.putIfAbsent(sourceEntryIdentifierName, () => names.length); + targetEntries.add(TargetEntry(sourceEntry.target.column, urlId, + sourceEntry.source.line, sourceEntry.source.column, srcNameId)); } return SingleMapping._(fileUrl, urls.values.map((i) => files[i]).toList(), urls.keys.toList(), names.keys.toList(), lines); @@ -342,14 +346,14 @@ class SingleMapping extends Mapping { : targetUrl = map['file'], urls = List.from(map['sources']), names = List.from(map['names'] ?? []), - files = List(map['sources'].length), + files = List.filled(map['sources'].length, null), sourceRoot = map['sourceRoot'], lines = [], _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl, extensions = {} { var sourcesContent = map['sourcesContent'] == null - ? const [] - : List.from(map['sourcesContent']); + ? const [] + : List.from(map['sourcesContent']); for (var i = 0; i < urls.length && i < sourcesContent.length; i++) { var source = sourcesContent[i]; if (source == null) continue; @@ -459,11 +463,11 @@ class SingleMapping extends Mapping { var newUrlId = segment.sourceUrlId; if (newUrlId == null) continue; srcUrlId = _append(buff, srcUrlId, newUrlId); - srcLine = _append(buff, srcLine, segment.sourceLine); - srcColumn = _append(buff, srcColumn, segment.sourceColumn); + srcLine = _append(buff, srcLine, segment.sourceLine!); + srcColumn = _append(buff, srcColumn, segment.sourceColumn!); if (segment.sourceNameId == null) continue; - srcNameId = _append(buff, srcNameId, segment.sourceNameId); + srcNameId = _append(buff, srcNameId, segment.sourceNameId!); } } @@ -474,7 +478,7 @@ class SingleMapping extends Mapping { 'names': names, 'mappings': buff.toString() }; - if (targetUrl != null) result['file'] = targetUrl; + if (targetUrl != null) result['file'] = targetUrl!; if (includeSourceContents) { result['sourcesContent'] = files.map((file) => file?.getText(0)).toList(); @@ -498,7 +502,7 @@ class SingleMapping extends Mapping { /// 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]. - TargetLineEntry _findLine(int line) { + TargetLineEntry? _findLine(int line) { var index = binarySearch(lines, (e) => e.line > line); return (index <= 0) ? null : lines[index - 1]; } @@ -508,7 +512,7 @@ class SingleMapping extends Mapping { /// 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. - TargetEntry _findColumn(int line, int column, TargetLineEntry lineEntry) { + TargetEntry? _findColumn(int line, int column, TargetLineEntry? lineEntry) { if (lineEntry == null || lineEntry.entries.isEmpty) return null; if (lineEntry.line != line) return lineEntry.entries.last; var entries = lineEntry.entries; @@ -517,33 +521,39 @@ class SingleMapping extends Mapping { } @override - SourceMapSpan spanFor(int line, int column, - {Map files, String uri}) { + SourceMapSpan? spanFor(int line, int column, + {Map? files, String? uri}) { var entry = _findColumn(line, column, _findLine(line)); - if (entry == null || entry.sourceUrlId == null) return null; - var url = urls[entry.sourceUrlId]; + if (entry == null) return null; + + var sourceUrlId = entry.sourceUrlId; + if (sourceUrlId == null) return null; + + var url = urls[sourceUrlId]; if (sourceRoot != null) { url = '${sourceRoot}${url}'; } - if (files != null && files[url] != null) { - var file = files[url]; - var start = file.getOffset(entry.sourceLine, entry.sourceColumn); - if (entry.sourceNameId != null) { - var text = names[entry.sourceNameId]; - return SourceMapFileSpan(files[url].span(start, start + text.length), + + var sourceNameId = entry.sourceNameId; + var file = files?[url]; + if (file != null) { + var start = file.getOffset(entry.sourceLine!, entry.sourceColumn); + if (sourceNameId != null) { + var text = names[sourceNameId]; + return SourceMapFileSpan(file.span(start, start + text.length), isIdentifier: true); } else { - return SourceMapFileSpan(files[url].location(start).pointSpan()); + return SourceMapFileSpan(file.location(start).pointSpan()); } } else { var start = SourceLocation(0, - sourceUrl: _mapUrl == null ? url : _mapUrl.resolve(url), + sourceUrl: _mapUrl?.resolve(url) ?? url, line: entry.sourceLine, column: entry.sourceColumn); // Offset and other context is not available. - if (entry.sourceNameId != null) { - return SourceMapSpan.identifier(start, names[entry.sourceNameId]); + if (sourceNameId != null) { + return SourceMapSpan.identifier(start, names[sourceNameId]); } else { return SourceMapSpan(start, start, ''); } @@ -578,18 +588,20 @@ class SingleMapping extends Mapping { ..write(line) ..write(':') ..write(entry.column); - if (entry.sourceUrlId != null) { + var sourceUrlId = entry.sourceUrlId; + if (sourceUrlId != null) { buff ..write(' --> ') ..write(sourceRoot) - ..write(urls[entry.sourceUrlId]) + ..write(urls[sourceUrlId]) ..write(': ') ..write(entry.sourceLine) ..write(':') ..write(entry.sourceColumn); } - if (entry.sourceNameId != null) { - buff..write(' (')..write(names[entry.sourceNameId])..write(')'); + var sourceNameId = entry.sourceNameId; + if (sourceNameId != null) { + buff..write(' (')..write(names[sourceNameId])..write(')'); } buff.write('\n'); } @@ -611,10 +623,10 @@ class TargetLineEntry { /// A target segment entry read from a source map class TargetEntry { final int column; - final int sourceUrlId; - final int sourceLine; - final int sourceColumn; - final int sourceNameId; + final int? sourceUrlId; + final int? sourceLine; + final int? sourceColumn; + final int? sourceNameId; TargetEntry(this.column, [this.sourceUrlId, @@ -639,9 +651,11 @@ class _MappingTokenizer implements Iterator { // Iterator API is used by decodeVlq to consume VLQ entries. @override bool moveNext() => ++index < _length; + @override - String get current => - (index >= 0 && index < _length) ? _internal[index] : null; + String get current => (index >= 0 && index < _length) + ? _internal[index] + : throw RangeError.index(index, _internal); bool get hasTokens => index < _length - 1 && _length > 0; @@ -671,7 +685,9 @@ class _MappingTokenizer implements Iterator { buff.write(_internal[i]); } buff.write(''); - buff.write(current ?? ''); + try { + buff.write(current); + } on RangeError catch (_) {} buff.write(''); for (var i = index + 1; i < _internal.length; i++) { buff.write(_internal[i]); diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index d79d2cb03..922c7fea0 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -23,7 +23,7 @@ class Printer { String get map => _maps.toJson(filename); /// Current source location mapping. - SourceLocation _loc; + SourceLocation? _loc; /// Current line in the buffer; int _line = 0; @@ -47,13 +47,21 @@ class Printer { // Return not followed by line-feed is treated as a new line. _line++; _column = 0; - if (projectMarks && _loc != null) { - if (_loc is FileLocation) { - var file = (_loc as FileLocation).file; - mark(file.location(file.getOffset(_loc.line + 1))); - } else { - mark(SourceLocation(0, - sourceUrl: _loc.sourceUrl, line: _loc.line + 1, column: 0)); + { + // **Warning**: Any calls to `mark` will change the value of `_loc`, + // so this local variable is no longer up to date after that point. + // + // This is why it has been put inside its own block to limit the + // scope in which it is available. + var loc = _loc; + if (projectMarks && loc != null) { + if (loc is FileLocation) { + var file = loc.file; + mark(file.location(file.getOffset(loc.line + 1))); + } else { + mark(SourceLocation(0, + sourceUrl: loc.sourceUrl, line: loc.line + 1, column: 0)); + } } } } else { @@ -78,8 +86,8 @@ class Printer { /// this also records the name of the identifier in the source map /// information. void mark(mark) { - SourceLocation loc; - String identifier; + late final SourceLocation loc; + String? identifier; if (mark is SourceLocation) { loc = mark; } else if (mark is SourceSpan) { @@ -106,11 +114,20 @@ class NestedPrinter implements NestedItem { final _items = []; /// Internal buffer to merge consecutive strings added to this printer. - StringBuffer _buff; + StringBuffer? _buff; /// Current indentation, which can be updated from outside this class. int indent; + /// [Printer] used during the last call to [build], if any. + Printer? printer; + + /// Returns the text produced after calling [build]. + String? get text => printer?.text; + + /// Returns the source-map information produced after calling [build]. + String? get map => printer?.map; + /// Item used to indicate that the following item is copied from the original /// source code, and hence we should preserve source-maps on every new line. static final _ORIGINAL = Object(); @@ -133,7 +150,7 @@ class NestedPrinter implements NestedItem { /// Setting [isOriginal] will make this printer propagate source map locations /// on every line-break. void add(object, - {SourceLocation location, SourceSpan span, bool isOriginal = false}) { + {SourceLocation? location, SourceSpan? span, bool isOriginal = false}) { if (object is! String || location != null || span != null || isOriginal) { _flush(); assert(location == null || span == null); @@ -162,7 +179,7 @@ class NestedPrinter implements NestedItem { /// The [location] and [span] parameters indicate the corresponding source map /// location of [line] in the original input. Only one, [location] or /// [span], should be provided at a time. - void addLine(String line, {SourceLocation location, SourceSpan span}) { + void addLine(String? line, {SourceLocation? location, SourceSpan? span}) { if (location != null || span != null) { _flush(); assert(location == null || span == null); @@ -180,8 +197,8 @@ class NestedPrinter implements NestedItem { /// Appends a string merging it with any previous strings, if possible. void _appendString(String s) { - _buff ??= StringBuffer(); - _buff.write(s); + var buf = _buff ??= StringBuffer(); + buf.write(s); } /// Adds all of the current [_buff] contents as a string item. @@ -206,15 +223,6 @@ class NestedPrinter implements NestedItem { return (StringBuffer()..writeAll(_items)).toString(); } - /// [Printer] used during the last call to [build], if any. - Printer printer; - - /// Returns the text produced after calling [build]. - String get text => printer.text; - - /// Returns the source-map information produced after calling [build]. - String get map => printer.map; - /// Builds the output of this printer and source map information. After /// calling this function, you can use [text] and [map] to retrieve the /// geenrated code and source map information, respectively. diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 5e117e8ac..64fd61050 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -17,7 +17,7 @@ import 'printer.dart'; /// Applies a series of edits using original location /// information, and composes them into the edited string. class TextEditTransaction { - final SourceFile file; + final SourceFile? file; final String original; final _edits = <_TextEdit>[]; @@ -33,9 +33,9 @@ class TextEditTransaction { _edits.add(_TextEdit(begin, end, replacement)); } - /// Create a source map [SourceLocation] for [offset]. - SourceLocation _loc(int offset) => - file != null ? file.location(offset) : null; + /// Create a source map [SourceLocation] for [offset], if [file] is not + /// `null`. + SourceLocation? _loc(int offset) => file?.location(offset); /// Applies all pending [edit]s and returns a [NestedPrinter] containing the /// rewritten string and source map information. [file]`.location` is given to @@ -58,7 +58,7 @@ class TextEditTransaction { if (consumed > edit.begin) { var sb = StringBuffer(); sb - ..write(file.location(edit.begin).toolString) + ..write(file?.location(edit.begin).toolString) ..write(': overlapping edits. Insert at offset ') ..write(edit.begin) ..write(' but have consumed ') diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index b8f1152f7..65574ca5e 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -52,7 +52,7 @@ class SourceMapFileSpan implements SourceMapSpan, FileSpan { @override String get context => _inner.context; @override - Uri get sourceUrl => _inner.sourceUrl; + Uri? get sourceUrl => _inner.sourceUrl; @override int get length => _inner.length; diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index d4e29a1c3..951ea8b96 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -33,8 +33,8 @@ final Map _digits = () { return map; }(); -final int MAX_INT32 = pow(2, 31) - 1; -final int MIN_INT32 = -pow(2, 31); +final int MAX_INT32 = (pow(2, 31) as int) - 1; +final int MIN_INT32 = -(pow(2, 31) as int); /// Creates the VLQ encoding of [value] as a sequence of characters Iterable encodeVlq(int value) { @@ -70,10 +70,10 @@ int decodeVlq(Iterator chars) { while (!stop) { if (!chars.moveNext()) throw StateError('incomplete VLQ value'); var char = chars.current; - if (!_digits.containsKey(char)) { + var digit = _digits[char]; + if (digit == null) { throw FormatException('invalid character in VLQ encoding: $char'); } - var digit = _digits[char]; stop = (digit & VLQ_CONTINUATION_BIT) == 0; digit &= VLQ_BASE_MASK; result += (digit << shift); diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 871c40acc..a59c77d54 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,16 +1,93 @@ name: source_maps -version: 0.10.9 +version: 0.11.0-nullsafety description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps environment: - sdk: '>=2.0.0 <3.0.0' + sdk: '>=2.9.0-18.0 <2.9.0' dependencies: - source_span: ^1.3.0 + source_span: '>=1.8.0-nullsafety <1.8.0' dev_dependencies: - source_span: ^1.5.4 test: ^1.2.0 term_glyph: ^1.0.0 + +dependency_overrides: + # Overrides required for a version solve + coverage: 0.14.0 + # NNBD Branches + 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_map_stack_trace: + git: + url: git://github.com/dart-lang/source_map_stack_trace.git + ref: null_safety + source_span: + git: + url: git://github.com/dart-lang/source_span.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: + git: + url: git://github.com/dart-lang/test.git + ref: null_safety + path: pkgs/test + 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 diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index c0bed6810..6ba1c6796 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -76,8 +76,8 @@ void check(SourceSpan outputSpan, Mapping mapping, SourceMapSpan inputSpan, var line = outputSpan.start.line; var column = outputSpan.start.column; var files = realOffsets ? {'input.dart': input} : null; - var span = mapping.spanFor(line, column, files: files); - var span2 = mapping.spanForLocation(outputSpan.start, files: files); + var span = mapping.spanFor(line, column, files: files)!; + var span2 = mapping.spanForLocation(outputSpan.start, files: files)!; // Both mapping APIs are equivalent. expect(span.start.offset, span2.start.offset); diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 1b73f13cb..1b3ae6f92 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -104,7 +104,7 @@ void main() { }); test('parse with no source location', () { - SingleMapping map = parse(jsonEncode(MAP_WITH_NO_SOURCE_LOCATION)); + var map = parse(jsonEncode(MAP_WITH_NO_SOURCE_LOCATION)) as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); var entry = map.lines.first.entries.first; @@ -117,7 +117,7 @@ void main() { }); test('parse with source location and no name', () { - SingleMapping map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION)); + var map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION)) as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); var entry = map.lines.first.entries.first; @@ -130,8 +130,8 @@ void main() { }); test('parse with source location and missing names entry', () { - SingleMapping map = - parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_MISSING_NAMES)); + var map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_MISSING_NAMES)) + as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); var entry = map.lines.first.entries.first; @@ -144,7 +144,8 @@ void main() { }); test('parse with source location and name', () { - SingleMapping map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_NAME)); + var map = + parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_NAME)) as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); var entry = map.lines.first.entries.first; @@ -160,12 +161,12 @@ void main() { var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = '/pkg/'; var mapping = parseJson(inputMap) as SingleMapping; - expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse('/pkg/input.dart')); + expect(mapping.spanFor(0, 0)?.sourceUrl, Uri.parse('/pkg/input.dart')); expect( mapping .spanForLocation( SourceLocation(0, sourceUrl: Uri.parse('ignored.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('/pkg/input.dart')); var newSourceRoot = '/new/'; @@ -180,7 +181,7 @@ void main() { var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); inputMap['sourceRoot'] = 'pkg/'; var mapping = parseJson(inputMap, mapUrl: 'file:///path/to/map'); - expect(mapping.spanFor(0, 0).sourceUrl, + expect(mapping.spanFor(0, 0)?.sourceUrl, Uri.parse('file:///path/to/pkg/input.dart')); }); @@ -193,29 +194,31 @@ void main() { mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.file('/path/to/output.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.file('/path/to/output2.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.file('/path/to/3/output.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); expect( - mapping.spanFor(0, 0, uri: 'file:///path/to/output.dart').sourceUrl, + mapping.spanFor(0, 0, uri: 'file:///path/to/output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); expect( - mapping.spanFor(0, 0, uri: 'file:///path/to/output2.dart').sourceUrl, + mapping.spanFor(0, 0, uri: 'file:///path/to/output2.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); expect( - mapping.spanFor(0, 0, uri: 'file:///path/to/3/output.dart').sourceUrl, + mapping + .spanFor(0, 0, uri: 'file:///path/to/3/output.dart') + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); }); @@ -224,36 +227,36 @@ void main() { mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:1/output.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:2/output2.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('package:3/output.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); - expect(mapping.spanFor(0, 0, uri: 'package:1/output.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'package:1/output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); - expect(mapping.spanFor(0, 0, uri: 'package:2/output2.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'package:2/output2.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); - expect(mapping.spanFor(0, 0, uri: 'package:3/output.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'package:3/output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); }); test('unmapped path', () { - var span = mapping.spanFor(0, 0, uri: 'unmapped_output.dart'); + var span = mapping.spanFor(0, 0, uri: 'unmapped_output.dart')!; expect(span.sourceUrl, Uri.parse('unmapped_output.dart')); expect(span.start.line, equals(0)); expect(span.start.column, equals(0)); - span = mapping.spanFor(10, 5, uri: 'unmapped_output.dart'); + span = mapping.spanFor(10, 5, uri: 'unmapped_output.dart')!; expect(span.sourceUrl, Uri.parse('unmapped_output.dart')); expect(span.start.line, equals(10)); expect(span.start.column, equals(5)); @@ -264,11 +267,11 @@ void main() { }); test('incomplete paths', () { - expect(mapping.spanFor(0, 0, uri: 'output.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); - expect(mapping.spanFor(0, 0, uri: 'output2.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'output2.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); - expect(mapping.spanFor(0, 0, uri: '3/output.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: '3/output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); }); @@ -276,11 +279,11 @@ void main() { var mapping = parseExtended(jsonEncode(SOURCE_MAP_BUNDLE), mapUrl: 'file:///path/to/map'); - expect(mapping.spanFor(0, 0, uri: 'output.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); - expect(mapping.spanFor(0, 0, uri: 'output2.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'output2.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); - expect(mapping.spanFor(0, 0, uri: '3/output.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: '3/output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); }); @@ -288,22 +291,22 @@ void main() { var mapping = MappingBundle(); mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_1, - mapUrl: 'file:///path/to/map')); - expect(mapping.spanFor(0, 0, uri: 'output.dart').sourceUrl, + mapUrl: 'file:///path/to/map') as SingleMapping); + expect(mapping.spanFor(0, 0, uri: 'output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); expect(mapping.containsMapping('output2.dart'), isFalse); mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_2, - mapUrl: 'file:///path/to/map')); + mapUrl: 'file:///path/to/map') as SingleMapping); expect(mapping.containsMapping('output2.dart'), isTrue); - expect(mapping.spanFor(0, 0, uri: 'output2.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: 'output2.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); expect(mapping.containsMapping('3/output.dart'), isFalse); mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_3, - mapUrl: 'file:///path/to/map')); + mapUrl: 'file:///path/to/map') as SingleMapping); expect(mapping.containsMapping('3/output.dart'), isTrue); - expect(mapping.spanFor(0, 0, uri: '3/output.dart').sourceUrl, + expect(mapping.spanFor(0, 0, uri: '3/output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); }); @@ -315,31 +318,33 @@ void main() { mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/output.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/output2.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping .spanForLocation(SourceLocation(0, sourceUrl: Uri.parse('http://localhost/3/output.dart'))) - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); expect( - mapping.spanFor(0, 0, uri: 'http://localhost/output.dart').sourceUrl, + mapping.spanFor(0, 0, uri: 'http://localhost/output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); expect( - mapping.spanFor(0, 0, uri: 'http://localhost/output2.dart').sourceUrl, + mapping + .spanFor(0, 0, uri: 'http://localhost/output2.dart') + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); expect( mapping .spanFor(0, 0, uri: 'http://localhost/3/output.dart') - .sourceUrl, + ?.sourceUrl, Uri.parse('file:///path/to/pkg/input3.dart')); }); }); @@ -351,10 +356,10 @@ void main() { MAP_WITH_SOURCE_LOCATION, MAP_WITH_SOURCE_LOCATION_AND_NAME ]) { - SingleMapping mapping = parseJson(expected); + var mapping = parseJson(expected) as SingleMapping; expect(mapping.toJson(), equals(expected)); - mapping = parseJsonExtended(expected); + mapping = parseJsonExtended(expected) as SingleMapping; expect(mapping.toJson(), equals(expected)); } @@ -366,7 +371,7 @@ void main() { var map = Map.from(EXPECTED_MAP); map['x_foo'] = 'a'; map['x_bar'] = [3]; - SingleMapping mapping = parseJson(map); + var mapping = parseJson(map) as SingleMapping; expect(mapping.toJson(), equals(map)); expect(mapping.extensions['x_foo'], equals('a')); expect(mapping.extensions['x_bar'].first, equals(3)); @@ -415,7 +420,7 @@ void main() { map['sourcesContent'] = ['hello, world!']; var mapping = parseJson(map) as SingleMapping; - var file = mapping.files[0]; + var file = mapping.files[0]!; expect(file.url, equals(Uri.parse('input.dart'))); expect(file.getText(0), equals('hello, world!')); }); diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 36b934a8d..9a403a1b3 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -60,7 +60,7 @@ void main() { txn.edit(34, 35, '___'); var printer = (txn.commit()..build('')); var output = printer.text; - var map = parse(printer.map); + var map = parse(printer.map!); expect(output, '0123456789\n0*23456789\n01*34__\n 789\na___cdefghij\nabcd*fghij\n'); @@ -197,7 +197,5 @@ void main() { }); } -String _span(int line, int column, Mapping map, SourceFile file) { - var span = map.spanFor(line - 1, column - 1, files: {'': file}); - return span == null ? null : span.message('').trim(); -} +String? _span(int line, int column, Mapping map, SourceFile file) => + map.spanFor(line - 1, column - 1, files: {'': file})?.message('').trim(); diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index 6021519dd..92a8f4add 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -27,8 +27,8 @@ void main() { }); test('only 32-bit ints allowed', () { - var max_int = pow(2, 31) - 1; - var min_int = -pow(2, 31); + var max_int = (pow(2, 31) as int) - 1; + var min_int = -(pow(2, 31) as int); _checkEncodeDecode(max_int - 1); _checkEncodeDecode(min_int + 1); _checkEncodeDecode(max_int); From 697988daa5dcd6241c14278579b5db775e66ba4c Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 15 Jul 2020 08:40:16 -0700 Subject: [PATCH 363/657] Merge the null_safety branch into master (dart-lang/pool#40) --- pkgs/pool/.travis.yml | 39 +++++++-- pkgs/pool/CHANGELOG.md | 3 +- pkgs/pool/analysis_options.yaml | 5 ++ pkgs/pool/benchmark/for_each_benchmark.dart | 10 +-- pkgs/pool/lib/pool.dart | 59 +++++++------ pkgs/pool/pubspec.yaml | 91 ++++++++++++++++++++- pkgs/pool/test/pool_test.dart | 17 ++-- 7 files changed, 166 insertions(+), 58 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index 18f741339..906158956 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -1,18 +1,39 @@ language: dart dart: - - 2.0.0 - - dev + - dev -dart_task: - - test: --platform vm,chrome - - dartfmt - - dartanalyzer: --fatal-infos --fatal-warnings . +jobs: + include: + - stage: analyze_and_format + name: "Analyze" + 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: - - $HOME/.pub-cache + directories: + - $HOME/.pub-cache diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index c680dd2bf..a413d7880 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,5 +1,6 @@ -## 1.4.1 +## 1.5.0-nullsafety +* Migrate to null safety. * `forEach`: Avoid `await null` if the `Stream` is not paused. Improves trivial benchmark by 40%. diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index 8bef8818d..986bccc6c 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -4,6 +4,9 @@ analyzer: strong-mode: implicit-casts: false + enable-experiment: + - non-nullable + linter: rules: - avoid_function_literals_in_foreach_calls @@ -36,6 +39,8 @@ linter: - prefer_initializing_formals - prefer_interpolation_to_compose_strings - prefer_typing_uninitialized_variables + - recursive_getters + - slash_for_doc_comments - test_types_in_equals - throw_in_finally - unnecessary_await_in_return diff --git a/pkgs/pool/benchmark/for_each_benchmark.dart b/pkgs/pool/benchmark/for_each_benchmark.dart index 7438ace78..2973b2a36 100644 --- a/pkgs/pool/benchmark/for_each_benchmark.dart +++ b/pkgs/pool/benchmark/for_each_benchmark.dart @@ -8,22 +8,22 @@ void main(List args) async { final watch = Stopwatch()..start(); final start = DateTime.now(); - DateTime lastLog; - Duration fastest; - int fastestIteration; + DateTime? lastLog; + Duration? fastest; + late int fastestIteration; var i = 1; void log(bool force) { var now = DateTime.now(); if (force || lastLog == null || - now.difference(lastLog) > const Duration(seconds: 1)) { + now.difference(lastLog!) > const Duration(seconds: 1)) { lastLog = now; print([ now.difference(start), i.toString().padLeft(10), fastestIteration.toString().padLeft(7), - fastest.inMicroseconds.toString().padLeft(9) + fastest!.inMicroseconds.toString().padLeft(9) ].join(' ')); } } diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index d8565411a..20ab8f181 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -51,16 +51,16 @@ class Pool { /// for additional files to be read before they could be closed. /// /// This is `null` if this pool shouldn't time out. - RestartableTimer _timer; + RestartableTimer? _timer; /// The amount of time to wait before timing out the pending resources. - final Duration _timeout; + final Duration? _timeout; /// A [FutureGroup] that tracks all the `onRelease` callbacks for resources /// that have been marked releasable. /// /// This is `null` until [close] is called. - FutureGroup _closeGroup; + FutureGroup? _closeGroup; /// Whether [close] has been called. bool get isClosed => _closeMemo.hasRun; @@ -78,7 +78,7 @@ class Pool { /// If [timeout] is passed, then if that much time passes without any activity /// all pending [request] futures will throw a [TimeoutException]. This is /// intended to avoid deadlocks. - Pool(this._maxAllocatedResources, {Duration timeout}) : _timeout = timeout { + Pool(this._maxAllocatedResources, {Duration? timeout}) : _timeout = timeout { if (_maxAllocatedResources <= 0) { throw ArgumentError.value(_maxAllocatedResources, 'maxAllocatedResources', 'Must be greater than zero.'); @@ -152,17 +152,17 @@ class Pool { /// to, a [StateError] is thrown. Stream forEach( Iterable elements, FutureOr Function(S source) action, - {bool Function(S item, Object error, StackTrace stack) onError}) { + {bool Function(S item, Object error, StackTrace stack)? onError}) { onError ??= (item, e, s) => true; var cancelPending = false; - Completer resumeCompleter; - StreamController controller; + Completer? resumeCompleter; + late StreamController controller; - Iterator iterator; + late Iterator iterator; - Future run(int i) async { + Future run(int _) async { while (iterator.moveNext()) { // caching `current` is necessary because there are async breaks // in this code and `iterator` is shared across many workers @@ -171,7 +171,7 @@ class Pool { _resetTimer(); if (resumeCompleter != null) { - await resumeCompleter.future; + await resumeCompleter!.future; } if (cancelPending) { @@ -182,7 +182,7 @@ class Pool { try { value = await action(current); } catch (e, stack) { - if (onError(current, e, stack)) { + if (onError!(current, e, stack)) { controller.addError(e, stack); } continue; @@ -191,20 +191,19 @@ class Pool { } } - Future doneFuture; + Future? doneFuture; void onListen() { - assert(iterator == null); iterator = elements.iterator; assert(doneFuture == null); - doneFuture = Future.wait( - Iterable.generate(_maxAllocatedResources) - .map((i) => withResource(() => run(i))), - eagerError: true) + var futures = Iterable>.generate( + _maxAllocatedResources, (i) => withResource(() => run(i))); + doneFuture = Future.wait(futures, eagerError: true) + .then((_) {}) .catchError(controller.addError); - doneFuture.whenComplete(controller.close); + doneFuture!.whenComplete(controller.close); } controller = StreamController( @@ -217,11 +216,11 @@ class Pool { }, onPause: () { assert(resumeCompleter == null); - resumeCompleter = Completer(); + resumeCompleter = Completer(); }, onResume: () { assert(resumeCompleter != null); - resumeCompleter.complete(); + resumeCompleter!.complete(); resumeCompleter = null; }, ); @@ -241,20 +240,20 @@ class Pool { /// /// This may be called more than once; it returns the same [Future] each time. Future close() => _closeMemo.runOnce(() { - if (_closeGroup != null) return _closeGroup.future; + if (_closeGroup != null) return _closeGroup!.future; _resetTimer(); _closeGroup = FutureGroup(); for (var callback in _onReleaseCallbacks) { - _closeGroup.add(Future.sync(callback)); + _closeGroup!.add(Future.sync(callback)); } _allocatedResources -= _onReleaseCallbacks.length; _onReleaseCallbacks.clear(); - if (_allocatedResources == 0) _closeGroup.close(); - return _closeGroup.future; + if (_allocatedResources == 0) _closeGroup!.close(); + return _closeGroup!.future; }); final _closeMemo = AsyncMemoizer(); @@ -267,7 +266,7 @@ class Pool { pending.complete(PoolResource._(this)); } else { _allocatedResources--; - if (isClosed && _allocatedResources == 0) _closeGroup.close(); + if (isClosed && _allocatedResources == 0) _closeGroup!.close(); } } @@ -280,9 +279,9 @@ class Pool { var pending = _requestedResources.removeFirst(); pending.complete(_runOnRelease(onRelease)); } else if (isClosed) { - _closeGroup.add(Future.sync(onRelease)); + _closeGroup!.add(Future.sync(onRelease)); _allocatedResources--; - if (_allocatedResources == 0) _closeGroup.close(); + if (_allocatedResources == 0) _closeGroup!.close(); } else { var zone = Zone.current; var registered = zone.registerCallback(onRelease); @@ -298,7 +297,7 @@ class Pool { Future _runOnRelease(Function() onRelease) { Future.sync(onRelease).then((value) { _onReleaseCompleters.removeFirst().complete(PoolResource._(this)); - }).catchError((error, StackTrace stackTrace) { + }).catchError((Object error, StackTrace stackTrace) { _onReleaseCompleters.removeFirst().completeError(error, stackTrace); }); @@ -312,9 +311,9 @@ class Pool { if (_timer == null) return; if (_requestedResources.isEmpty) { - _timer.cancel(); + _timer!.cancel(); } else { - _timer.reset(); + _timer!.reset(); } } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index c87617f43..8fc0e1435 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.4.1-dev +version: 1.5.0-nullsafety description: >- Manage a finite pool of resources. @@ -7,13 +7,96 @@ description: >- homepage: https://github.com/dart-lang/pool environment: - sdk: '>=2.0.0 <3.0.0' + sdk: '>=2.9.0-18.0 <2.9.0' dependencies: - async: '>=1.4.0 <3.0.0' - stack_trace: '>=0.9.2 <2.0.0' + async: '>=2.5.0-nullsafety <2.5.0' + stack_trace: '>=1.10.0-nullsafety <1.10.0' dev_dependencies: fake_async: ^1.0.0 pedantic: ^1.4.0 test: ^1.0.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 + clock: + git: + url: git://github.com/dart-lang/clock.git + ref: null_safety + collection: 1.15.0-nullsafety + js: + git: + url: git://github.com/dart-lang/sdk.git + path: pkg/js + fake_async: + git: + url: git://github.com/dart-lang/fake_async.git + ref: null_safety + 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 + 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 + source_span: + git: + url: git://github.com/dart-lang/source_span.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/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 091cd5513..20e92d597 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -438,7 +438,7 @@ void main() { }); group('forEach', () { - Pool pool; + late Pool pool; tearDown(() async { await pool.close(); @@ -609,7 +609,7 @@ void main() { delayedToString); // ignore: cancel_subscriptions - StreamSubscription subscription; + late StreamSubscription subscription; subscription = stream.listen( (data) { @@ -659,9 +659,9 @@ void main() { }); group('errors', () { - Future errorInIterator( - {bool Function(int item, Object error, StackTrace stack) - onError}) async { + Future errorInIterator({ + bool Function(int item, Object error, StackTrace stack)? onError, + }) async { pool = Pool(20); var listFuture = pool @@ -704,7 +704,8 @@ void main() { test('error in action, no onError', () async { pool = Pool(20); - var list = await pool.forEach(Iterable.generate(100), (i) async { + var list = await pool.forEach(Iterable.generate(100), + (int i) async { await Future.delayed(const Duration(milliseconds: 10)); if (i % 10 == 0) { throw UnsupportedError('Multiples of 10 not supported'); @@ -737,9 +738,7 @@ void Function() expectNoAsync() { /// A matcher for Futures that asserts that they don't complete. /// /// This should only be called within a [FakeAsync.run] zone. -Matcher get doesNotComplete => predicate((future) { - expect(future, const TypeMatcher()); - +Matcher get doesNotComplete => predicate((Future future) { var stack = Trace.current(1); future.then((_) => registerException( TestFailure('Expected future not to complete.'), stack)); From e1c70134378a3c472c17912b43956bf4b3b75067 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 21 Jul 2020 19:41:01 -0700 Subject: [PATCH 364/657] update for the 2.10 dev sdk (dart-lang/pool#41) This is in preparation for the actual 2.10 dev sdk release. --- pkgs/pool/.travis.yml | 12 +++---- pkgs/pool/pubspec.yaml | 76 +++++++++++++----------------------------- 2 files changed, 30 insertions(+), 58 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index 906158956..f0d3128a3 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -1,28 +1,28 @@ language: dart dart: - - dev + - preview/raw/2.10.0-0.2-dev jobs: include: - stage: analyze_and_format name: "Analyze" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - stage: analyze_and_format name: "Format" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: dartfmt -n --set-exit-if-changed . - stage: test name: "Vm Tests" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p vm - stage: test name: "Web Tests" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p chrome @@ -32,7 +32,7 @@ stages: # Only building master means that we don't run two builds for each pull request. branches: - only: [master, null_safety] + only: [master] cache: directories: diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 8fc0e1435..ea3cd611f 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -7,7 +7,8 @@ description: >- homepage: https://github.com/dart-lang/pool environment: - sdk: '>=2.9.0-18.0 <2.9.0' + # This must remain a tight constraint until nnbd is stable + sdk: '>=2.10.0-0 <2.10.0' dependencies: async: '>=2.5.0-nullsafety <2.5.0' @@ -20,83 +21,54 @@ dev_dependencies: dependency_overrides: async: - git: - url: git://github.com/dart-lang/async.git - ref: null_safety + git: git://github.com/dart-lang/async.git boolean_selector: - git: - url: git://github.com/dart-lang/boolean_selector.git - ref: null_safety + git: git://github.com/dart-lang/boolean_selector.git charcode: - git: - url: git://github.com/dart-lang/charcode.git - ref: null_safety - clock: - git: - url: git://github.com/dart-lang/clock.git - ref: null_safety - collection: 1.15.0-nullsafety + git: git://github.com/dart-lang/charcode.git + collection: + git: git://github.com/dart-lang/collection.git js: git: url: git://github.com/dart-lang/sdk.git path: pkg/js - fake_async: - git: - url: git://github.com/dart-lang/fake_async.git - ref: null_safety + ref: 2-10-pkgs matcher: + git: git://github.com/dart-lang/matcher.git + meta: git: - url: git://github.com/dart-lang/matcher.git - ref: null_safety - meta: 1.3.0-nullsafety + url: git://github.com/dart-lang/sdk.git + path: pkg/meta + ref: 2-10-pkgs path: - git: - url: git://github.com/dart-lang/path.git - ref: null_safety + git: git://github.com/dart-lang/path.git pedantic: - git: - url: git://github.com/dart-lang/pedantic.git - ref: null_safety + git: git://github.com/dart-lang/pedantic.git source_maps: - git: - url: git://github.com/dart-lang/source_maps.git - ref: null_safety + git: git://github.com/dart-lang/source_maps.git source_map_stack_trace: - git: - url: git://github.com/dart-lang/source_map_stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/source_map_stack_trace.git source_span: - git: - url: git://github.com/dart-lang/source_span.git - ref: null_safety + git: git://github.com/dart-lang/source_span.git stack_trace: - git: - url: git://github.com/dart-lang/stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/stack_trace.git stream_channel: - git: - url: git://github.com/dart-lang/stream_channel.git - ref: null_safety + git: git://github.com/dart-lang/stream_channel.git string_scanner: - git: - url: git://github.com/dart-lang/string_scanner.git - ref: null_safety + git: git://github.com/dart-lang/string_scanner.git term_glyph: - git: - url: git://github.com/dart-lang/term_glyph.git - ref: null_safety + git: git://github.com/dart-lang/term_glyph.git 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 + typed_data: + git: git://github.com/dart-lang/typed_data.git From ead4b8993bd3bf2f627d676e8bcd8121b14f454c Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 21 Jul 2020 19:41:09 -0700 Subject: [PATCH 365/657] update for the 2.10 dev sdk (dart-lang/source_maps#50) This is in preparation for the actual 2.10 dev sdk release. --- pkgs/source_maps/.travis.yml | 10 ++--- pkgs/source_maps/pubspec.yaml | 80 +++++++++++++---------------------- 2 files changed, 34 insertions(+), 56 deletions(-) diff --git a/pkgs/source_maps/.travis.yml b/pkgs/source_maps/.travis.yml index 785c7c2e4..51a3d8a48 100644 --- a/pkgs/source_maps/.travis.yml +++ b/pkgs/source_maps/.travis.yml @@ -1,23 +1,23 @@ language: dart dart: - - be/raw/latest + - preview/raw/2.10.0-0.2-dev jobs: include: - stage: analyze_and_format name: "Analyze" - dart: be/raw/latest + dart: preview/raw/2.10.0-0.2-dev os: linux script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - stage: analyze_and_format name: "Format" - dart: be/raw/latest + dart: preview/raw/2.10.0-0.2-dev os: linux script: dartfmt -n --set-exit-if-changed . - stage: test name: "Vm Tests" - dart: be/raw/latest + dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p vm @@ -27,7 +27,7 @@ stages: # Only building master means that we don't run two builds for each pull request. branches: - only: [master, null_safety] + only: [master] cache: directories: diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index a59c77d54..4bdc225a0 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -5,7 +5,8 @@ description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps environment: - sdk: '>=2.9.0-18.0 <2.9.0' + # This must remain a tight constraint until nnbd is stable + sdk: '>=2.10.0-0 <2.10.0' dependencies: source_span: '>=1.8.0-nullsafety <1.8.0' @@ -15,79 +16,56 @@ dev_dependencies: term_glyph: ^1.0.0 dependency_overrides: - # Overrides required for a version solve - coverage: 0.14.0 - # NNBD Branches async: - git: - url: git://github.com/dart-lang/async.git - ref: null_safety + git: git://github.com/dart-lang/async.git boolean_selector: - git: - url: git://github.com/dart-lang/boolean_selector.git - ref: null_safety + git: git://github.com/dart-lang/boolean_selector.git charcode: - git: - url: git://github.com/dart-lang/charcode.git - ref: null_safety - collection: 1.15.0-nullsafety + git: git://github.com/dart-lang/charcode.git + collection: + git: git://github.com/dart-lang/collection.git js: git: url: git://github.com/dart-lang/sdk.git path: pkg/js + ref: 2-10-pkgs matcher: + git: git://github.com/dart-lang/matcher.git + meta: git: - url: git://github.com/dart-lang/matcher.git - ref: null_safety - meta: 1.3.0-nullsafety + url: git://github.com/dart-lang/sdk.git + path: pkg/meta + ref: 2-10-pkgs path: - git: - url: git://github.com/dart-lang/path.git - ref: null_safety + git: git://github.com/dart-lang/path.git pedantic: - git: - url: git://github.com/dart-lang/pedantic.git - ref: null_safety + git: git://github.com/dart-lang/pedantic.git pool: - git: - url: git://github.com/dart-lang/pool.git - ref: null_safety + git: git://github.com/dart-lang/pool.git source_map_stack_trace: - git: - url: git://github.com/dart-lang/source_map_stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/source_map_stack_trace.git source_span: - git: - url: git://github.com/dart-lang/source_span.git - ref: null_safety + git: git://github.com/dart-lang/source_span.git stack_trace: - git: - url: git://github.com/dart-lang/stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/stack_trace.git stream_channel: - git: - url: git://github.com/dart-lang/stream_channel.git - ref: null_safety + git: git://github.com/dart-lang/stream_channel.git string_scanner: - git: - url: git://github.com/dart-lang/string_scanner.git - ref: null_safety + git: git://github.com/dart-lang/string_scanner.git term_glyph: - git: - url: git://github.com/dart-lang/term_glyph.git - ref: null_safety - test: - git: - url: git://github.com/dart-lang/test.git - ref: null_safety - path: pkgs/test + git: git://github.com/dart-lang/term_glyph.git 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 + path: pkgs/test + typed_data: + git: git://github.com/dart-lang/typed_data.git + From bb71863a12c3124d029840dd7a7e7e495891c65b Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Tue, 21 Jul 2020 19:41:25 -0700 Subject: [PATCH 366/657] update for the 2.10 dev sdk (dart-lang/source_span#57) This is in preparation for the actual 2.10 dev sdk release. --- pkgs/source_span/.travis.yml | 12 +++---- pkgs/source_span/pubspec.yaml | 68 +++++++++++++---------------------- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index 8361c623e..95f19ae8a 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -1,28 +1,28 @@ language: dart dart: -- dev +- preview/raw/2.10.0-0.2-dev jobs: include: - stage: analyze_and_format name: "Analyze test/" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - stage: analyze_and_format name: "Format" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: dartfmt -n --set-exit-if-changed . - stage: test name: "Vm Tests" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p vm - stage: test name: "Web Tests" - dart: dev + dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p chrome @@ -32,7 +32,7 @@ stages: # Only building master means that we don't run two builds for each pull request. branches: - only: [master, null_safety] + only: [master] cache: directories: diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 89f40c8d7..6330c6fd3 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -5,7 +5,8 @@ description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: - sdk: '>=2.9.0-18.0 <2.9.0' + # This must remain a tight constraint until nnbd is stable + sdk: '>=2.10.0-0 <2.10.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' @@ -18,75 +19,54 @@ dev_dependencies: dependency_overrides: async: - git: - url: git://github.com/dart-lang/async.git - ref: null_safety + git: git://github.com/dart-lang/async.git boolean_selector: - git: - url: git://github.com/dart-lang/boolean_selector.git - ref: null_safety + git: git://github.com/dart-lang/boolean_selector.git charcode: - git: - url: git://github.com/dart-lang/charcode.git - ref: null_safety - collection: 1.15.0-nullsafety + git: git://github.com/dart-lang/charcode.git + collection: + git: git://github.com/dart-lang/collection.git js: git: url: git://github.com/dart-lang/sdk.git path: pkg/js + ref: 2-10-pkgs matcher: + git: git://github.com/dart-lang/matcher.git + meta: git: - url: git://github.com/dart-lang/matcher.git - ref: null_safety - meta: 1.3.0-nullsafety + url: git://github.com/dart-lang/sdk.git + path: pkg/meta + ref: 2-10-pkgs path: - git: - url: git://github.com/dart-lang/path.git - ref: null_safety + git: git://github.com/dart-lang/path.git pedantic: - git: - url: git://github.com/dart-lang/pedantic.git - ref: null_safety + git: git://github.com/dart-lang/pedantic.git pool: - git: - url: git://github.com/dart-lang/pool.git - ref: null_safety + git: git://github.com/dart-lang/pool.git source_maps: - git: - url: git://github.com/dart-lang/source_maps.git - ref: null_safety + git: git://github.com/dart-lang/source_maps.git source_map_stack_trace: - git: - url: git://github.com/dart-lang/source_map_stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/source_map_stack_trace.git stack_trace: - git: - url: git://github.com/dart-lang/stack_trace.git - ref: null_safety + git: git://github.com/dart-lang/stack_trace.git stream_channel: - git: - url: git://github.com/dart-lang/stream_channel.git - ref: null_safety + git: git://github.com/dart-lang/stream_channel.git string_scanner: - git: - url: git://github.com/dart-lang/string_scanner.git - ref: null_safety + git: git://github.com/dart-lang/string_scanner.git term_glyph: - git: - url: git://github.com/dart-lang/term_glyph.git - ref: null_safety + git: git://github.com/dart-lang/term_glyph.git 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 + typed_data: + git: git://github.com/dart-lang/typed_data.git From 471c213e807a20ea3d08bf520953ac0850fd331a Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 22 Jul 2020 10:46:41 -0700 Subject: [PATCH 367/657] add back coverage override to fix travis (dart-lang/source_maps#51) --- pkgs/source_maps/pubspec.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 4bdc225a0..8fc3fb3f1 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -16,6 +16,9 @@ dev_dependencies: term_glyph: ^1.0.0 dependency_overrides: + # Overrides required for a version solve + coverage: 0.14.0 + # Null Safety Overrides async: git: git://github.com/dart-lang/async.git boolean_selector: From 71dd2a95aae6c878c54e66bf97a4f8edd9bd8d24 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 22 Jul 2020 14:26:52 -0700 Subject: [PATCH 368/657] Fixes for Dart 2.10 (dart-lang/pool#42) --- pkgs/pool/.travis.yml | 6 +----- pkgs/pool/pubspec.yaml | 4 ++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index f0d3128a3..87be92616 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -1,28 +1,24 @@ language: dart dart: - - preview/raw/2.10.0-0.2-dev + - dev jobs: include: - stage: analyze_and_format name: "Analyze" - dart: preview/raw/2.10.0-0.2-dev os: linux script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - stage: analyze_and_format name: "Format" - dart: preview/raw/2.10.0-0.2-dev os: linux script: dartfmt -n --set-exit-if-changed . - stage: test name: "Vm Tests" - dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p vm - stage: test name: "Web Tests" - dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p chrome diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index ea3cd611f..abc21b5b1 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -28,6 +28,10 @@ dependency_overrides: git: git://github.com/dart-lang/charcode.git collection: git: git://github.com/dart-lang/collection.git + clock: + git: git://github.com/dart-lang/clock.git + fake_async: + git: git://github.com/dart-lang/fake_async.git js: git: url: git://github.com/dart-lang/sdk.git From 82232f36f7a608fefe604b61e509bb494d8067ee Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 13:44:53 -0700 Subject: [PATCH 369/657] Update travis-ci: test on dev (dart-lang/source_maps#52) --- pkgs/source_maps/.travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkgs/source_maps/.travis.yml b/pkgs/source_maps/.travis.yml index 51a3d8a48..ac74df9cc 100644 --- a/pkgs/source_maps/.travis.yml +++ b/pkgs/source_maps/.travis.yml @@ -1,23 +1,20 @@ language: dart dart: - - preview/raw/2.10.0-0.2-dev + - dev jobs: include: - stage: analyze_and_format name: "Analyze" - dart: preview/raw/2.10.0-0.2-dev os: linux script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - stage: analyze_and_format name: "Format" - dart: preview/raw/2.10.0-0.2-dev os: linux script: dartfmt -n --set-exit-if-changed . - stage: test name: "Vm Tests" - dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p vm From d09f50acb992adcbb5ad3af0cfd9c8724c57be23 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 13:46:00 -0700 Subject: [PATCH 370/657] Delete .test_config No longer used/needed --- pkgs/source_span/.test_config | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/source_span/.test_config diff --git a/pkgs/source_span/.test_config b/pkgs/source_span/.test_config deleted file mode 100644 index 412fc5c5c..000000000 --- a/pkgs/source_span/.test_config +++ /dev/null @@ -1,3 +0,0 @@ -{ - "test_package": true -} \ No newline at end of file From 688d2a349c9f1abd683dfc9731c42a928793d847 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 14:07:23 -0700 Subject: [PATCH 371/657] Update travis-CI to use dev (dart-lang/source_span#58) --- pkgs/source_span/.travis.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index 95f19ae8a..8a4761a70 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -1,28 +1,24 @@ language: dart dart: -- preview/raw/2.10.0-0.2-dev +- dev jobs: include: - stage: analyze_and_format name: "Analyze test/" - dart: preview/raw/2.10.0-0.2-dev os: linux script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - stage: analyze_and_format name: "Format" - dart: preview/raw/2.10.0-0.2-dev os: linux script: dartfmt -n --set-exit-if-changed . - stage: test name: "Vm Tests" - dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p vm - stage: test name: "Web Tests" - dart: preview/raw/2.10.0-0.2-dev os: linux script: pub run --enable-experiment=non-nullable test -p chrome From 1fb0604a9a80ccd775aa4713a459a22d7e08e99a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 20:33:37 -0700 Subject: [PATCH 372/657] Delete .test_config No longer used --- pkgs/source_maps/.test_config | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/source_maps/.test_config diff --git a/pkgs/source_maps/.test_config b/pkgs/source_maps/.test_config deleted file mode 100644 index 412fc5c5c..000000000 --- a/pkgs/source_maps/.test_config +++ /dev/null @@ -1,3 +0,0 @@ -{ - "test_package": true -} \ No newline at end of file From cbb00b94b4b35fb7b60dfd16ed08eb5bba3b1cd9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 28 Jul 2020 20:34:07 -0700 Subject: [PATCH 373/657] Delete .test_config No longer used --- pkgs/pub_semver/.test_config | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/pub_semver/.test_config diff --git a/pkgs/pub_semver/.test_config b/pkgs/pub_semver/.test_config deleted file mode 100644 index 25355634f..000000000 --- a/pkgs/pub_semver/.test_config +++ /dev/null @@ -1,3 +0,0 @@ -{ - "test_package": true -} From 2ef6558ddc47da1513b4f46739d070a1c110f491 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 29 Jul 2020 12:12:24 -0700 Subject: [PATCH 374/657] change version to be non-breaking (dart-lang/source_maps#53) --- pkgs/source_maps/CHANGELOG.md | 2 +- pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index bc7c9ef84..155b6cd12 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.11.0-nullsafety +## 0.10.1-nullsafety * Migrate to null safety diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 8fc3fb3f1..d540efbb9 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.11.0-nullsafety +version: 0.10.1-nullsafety description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps From dce5cbe9bf14ebf2c5d5cb0ba58b1f418e311207 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 29 Jul 2020 13:31:39 -0700 Subject: [PATCH 375/657] version should be 0.10.10-nullsafety (dart-lang/source_maps#54) --- pkgs/source_maps/CHANGELOG.md | 2 +- pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 155b6cd12..5af57527d 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.10.1-nullsafety +## 0.10.10-nullsafety * Migrate to null safety diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index d540efbb9..1951d7232 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.1-nullsafety +version: 0.10.10-nullsafety description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps From 5d1d313f0da9e182c848c2f155b2a40037d3fe40 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 30 Jul 2020 09:08:57 -0700 Subject: [PATCH 376/657] Add tests and improve docs for Version.primary (dart-lang/pub_semver#47) --- pkgs/pub_semver/CHANGELOG.md | 2 + pkgs/pub_semver/lib/src/version.dart | 4 +- pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_test.dart | 54 +++++++++++++++++++++++++- 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 40f7c3e25..63f72851c 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.4.5-dev + # 1.4.4 - Fix a bug of `VersionRange.union` where ranges bounded at infinity would get diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index e769dcd64..314937dbf 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -131,10 +131,12 @@ class Version implements VersionConstraint, VersionRange { } } - /// Returns the primary version out of a list of candidates. + /// Returns the primary version out of [versions]. /// /// This is the highest-numbered stable (non-prerelease) version. If there /// are no stable versions, it's just the highest-numbered version. + /// + /// If [versions] is empty, returns `null`. static Version primary(List versions) { Version primary; for (var version in versions) { diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index a2238d2f7..78de107cb 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 1.4.4 +version: 1.4.5-dev description: >- Versions and version constraints implementing pub's versioning policy. This diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index df0d25b14..70d277975 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -2,9 +2,8 @@ // 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:test/test.dart'; - import 'package:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; import 'utils.dart'; @@ -330,4 +329,55 @@ void main() { equals('001.02.0003-01.dev+pre.002')); }); }); + + group('primary', () { + test('single', () { + expect( + _primary([ + '1.2.3', + ]).toString(), + '1.2.3', + ); + }); + + test('normal', () { + expect( + _primary([ + '1.2.3', + '1.2.2', + ]).toString(), + '1.2.3', + ); + }); + + test('all prerelease', () { + expect( + _primary([ + '1.2.2-dev.1', + '1.2.2-dev.2', + ]).toString(), + '1.2.2-dev.2', + ); + }); + + test('later prerelease', () { + expect( + _primary([ + '1.2.3', + '1.2.3-dev', + ]).toString(), + '1.2.3', + ); + }); + + test('empty', () { + expect( + _primary([]), + isNull, + ); + }); + }); } + +Version _primary(List input) => + Version.primary(input.map((e) => Version.parse(e)).toList()); From 575c1d08174a7cfd4db03d7359efe49a812e0ecb Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 4 Sep 2020 09:04:35 -0700 Subject: [PATCH 377/657] fix formatting --- pkgs/source_span/lib/src/highlighter.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 491dae5ba..d61ff9f61 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -288,7 +288,9 @@ class Highlighter { final currentColor = current == null ? null - : current.isPrimary ? _primaryColor : _secondaryColor; + : current.isPrimary + ? _primaryColor + : _secondaryColor; var foundCurrent = false; for (var highlight in highlightsByColumn) { final startLine = highlight?.span.start.line; From 1637967ee783613c792e37891318a601a5d7153f Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Mon, 14 Sep 2020 10:07:56 -0700 Subject: [PATCH 378/657] Work around flow analysis bug (dart-lang/source_span#59) Flow analysis currently has a bug preventing for-each loop variables from being properly promoted in the presence of closures (https://github.com/dart-lang/sdk/issues/43136); as a result of this bug the source_span package had two non-null assertions that ought to have been unnecessary. I'm preparing a fix for that bug, however if I land it as is, it will cause the front end to emit errors saying "Operand of null-aware operation '!' has type '_Highlight' which excludes null"; this in turn will cause SDK bot breakages (since source_span is imported into the SDK repo). So, in order to land the fix, we need to first update the source_span package to work around the bug; this change does that by allocating a temporary variable (which *is* promoted correctly). Once the fix for https://github.com/dart-lang/sdk/issues/43136 lands, I will make a follow-up change that deletes the temporary variable. --- pkgs/source_span/lib/src/highlighter.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index d61ff9f61..1c39185a4 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -292,7 +292,9 @@ class Highlighter { ? _primaryColor : _secondaryColor; var foundCurrent = false; - for (var highlight in highlightsByColumn) { + for (var tmp in highlightsByColumn) { + // Work around https://github.com/dart-lang/sdk/issues/43136 + final highlight = tmp; final startLine = highlight?.span.start.line; final endLine = highlight?.span.end.line; if (current != null && highlight == current) { @@ -326,9 +328,9 @@ class Highlighter { }, 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); From d851af11e5c521e3210ae2df2b32adeadd263cdc Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 18 Sep 2020 12:57:11 -0700 Subject: [PATCH 379/657] Prep to release 1.8.0-nullsafety.1 Reverts https://github.com/dart-lang/source_span/pull/59 and removes now unnecessary `!`s. This requires a newer sdk than is available on dev, so run tests on be/raw/latest for now. The dart version in flutter should already be compatible with this version. --- pkgs/source_span/.travis.yml | 2 +- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/lib/src/highlighter.dart | 4 +--- pkgs/source_span/pubspec.yaml | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index 8a4761a70..290d9a29a 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -1,7 +1,7 @@ language: dart dart: -- dev +- be/raw/latest jobs: include: diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 1723b0fc2..b70bc3a36 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.8.0-nullsafety.1 + +* Fixes a newly recognized unnecessary null check to remove warnings. + # 1.8.0-nullsafety * Migrate to null safety. diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 1c39185a4..f622c4e01 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -292,9 +292,7 @@ class Highlighter { ? _primaryColor : _secondaryColor; var foundCurrent = false; - for (var tmp in highlightsByColumn) { - // Work around https://github.com/dart-lang/sdk/issues/43136 - final highlight = tmp; + for (var highlight in highlightsByColumn) { final startLine = highlight?.span.start.line; final endLine = highlight?.span.end.line; if (current != null && highlight == current) { diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 6330c6fd3..597afdf42 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,12 @@ name: source_span -version: 1.8.0-nullsafety +version: 1.8.0-nullsafety.1 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.10.0' + sdk: '>=2.10.0-137.0 <2.10.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From d0e2596b8fd5451cde788a7e1087dfd27b5b8547 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 21 Sep 2020 11:26:25 -0700 Subject: [PATCH 380/657] Revert the revert of the flow analysis workaround (dart-lang/source_span#61) * Revert "Prep to release 1.8.0-nullsafety.1" This reverts commit d851af11e5c521e3210ae2df2b32adeadd263cdc. * update pubspec/changelog --- pkgs/source_span/.travis.yml | 2 +- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/lib/src/highlighter.dart | 4 +++- pkgs/source_span/pubspec.yaml | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml index 290d9a29a..8a4761a70 100644 --- a/pkgs/source_span/.travis.yml +++ b/pkgs/source_span/.travis.yml @@ -1,7 +1,7 @@ language: dart dart: -- be/raw/latest +- dev jobs: include: diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index b70bc3a36..ba225230b 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.8.0-nullsafety.2-dev + +* Revert unnecessary null check fix (sdk fix wont land in 2.10 stable). + # 1.8.0-nullsafety.1 * Fixes a newly recognized unnecessary null check to remove warnings. diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index f622c4e01..1c39185a4 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -292,7 +292,9 @@ class Highlighter { ? _primaryColor : _secondaryColor; var foundCurrent = false; - for (var highlight in highlightsByColumn) { + for (var tmp in highlightsByColumn) { + // Work around https://github.com/dart-lang/sdk/issues/43136 + final highlight = tmp; final startLine = highlight?.span.start.line; final endLine = highlight?.span.end.line; if (current != null && highlight == current) { diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 597afdf42..76e7b4dcf 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,12 @@ name: source_span -version: 1.8.0-nullsafety.1 +version: 1.8.0-nullsafety.2-dev description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-137.0 <2.10.0' + sdk: '>=2.10.0-0.0 <2.10.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From b37539bcb58280b7f0743d1921832c9aa7535001 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Mon, 21 Sep 2020 13:20:31 -0700 Subject: [PATCH 381/657] prep to release to unblock flutter (dart-lang/source_span#62) --- pkgs/source_span/CHANGELOG.md | 3 ++- pkgs/source_span/pubspec.yaml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index ba225230b..4d04b5b42 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,6 +1,7 @@ -# 1.8.0-nullsafety.2-dev +# 1.8.0-nullsafety.2 * Revert unnecessary null check fix (sdk fix wont land in 2.10 stable). +* Allow 2.10 stable and 2.11 dev sdks. # 1.8.0-nullsafety.1 diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 76e7b4dcf..6a3f107da 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,12 @@ name: source_span -version: 1.8.0-nullsafety.2-dev +version: 1.8.0-nullsafety.2 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0.0 <2.10.0' + sdk: '>=2.10.0-0.0 <2.11.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From 9e73f83d7adc99944318d39f22ec323c1e2f468c Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 22 Sep 2020 09:03:58 -0700 Subject: [PATCH 382/657] Prepare for the 2.11 dev SDKs (dart-lang/pool#43) Bump the upper bound to allow 2.10 stable and 2.11.0 dev SDK versions. --- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index a413d7880..5d9f6c479 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.0-nullsafety.1 + +* Allow 2.10 stable and 2.11.0 dev SDK versions. + ## 1.5.0-nullsafety * Migrate to null safety. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index abc21b5b1..68b7bb117 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.0-nullsafety +version: 1.5.0-nullsafety.1 description: >- Manage a finite pool of resources. @@ -8,7 +8,7 @@ homepage: https://github.com/dart-lang/pool environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.10.0' + sdk: '>=2.10.0-0 <2.11.0' dependencies: async: '>=2.5.0-nullsafety <2.5.0' From 618612dc9092a9a178d37f842cf2b82d1c2fe7c8 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 22 Sep 2020 09:09:03 -0700 Subject: [PATCH 383/657] Prepare for the 2.11 dev SDKs (dart-lang/source_maps#55) Bump the upper bound to allow 2.10 stable and 2.11.0 dev SDK versions. --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 5af57527d..fe1976163 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.10-nullsafety.1 + +* Allow 2.10 stable and 2.11.0 dev SDK versions. + ## 0.10.10-nullsafety * Migrate to null safety diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 1951d7232..a61224ab8 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,12 +1,12 @@ name: source_maps -version: 0.10.10-nullsafety +version: 0.10.10-nullsafety.1 description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.10.0' + sdk: '>=2.10.0-0 <2.11.0' dependencies: source_span: '>=1.8.0-nullsafety <1.8.0' From 8897a35cdd881ebf735193c80642c67f7152a697 Mon Sep 17 00:00:00 2001 From: Michael R Fairhurst Date: Mon, 28 Sep 2020 02:54:40 -0700 Subject: [PATCH 384/657] Remove unused async imports (dart-lang/package_config#91) Since this version doesn't support Dart pre 2.0, these imports are unnecessary. --- pkgs/package_config/lib/discovery.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart index a2f53c0e6..a72bb1255 100644 --- a/pkgs/package_config/lib/discovery.dart +++ b/pkgs/package_config/lib/discovery.dart @@ -5,7 +5,6 @@ @Deprecated("Use the package_config.json based API") library package_config.discovery; -import "dart:async"; import "dart:io"; import "dart:typed_data" show Uint8List; From 712d70677d75100e322ec398b1118702dce48ff2 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Tue, 29 Sep 2020 13:25:08 -0700 Subject: [PATCH 385/657] Remove workaround for SDK bug. (dart-lang/source_span#63) Now that https://github.com/dart-lang/sdk/issues/43136 is fixed, the workaround is no longer needed. --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/lib/src/highlighter.dart | 4 +--- pkgs/source_span/pubspec.yaml | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 4d04b5b42..52c3fb504 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.8.0-nullsafety.3 + +* Remove workaround for https://github.com/dart-lang/sdk/issues/43136, which is + now fixed. + # 1.8.0-nullsafety.2 * Revert unnecessary null check fix (sdk fix wont land in 2.10 stable). diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 1c39185a4..f622c4e01 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -292,9 +292,7 @@ class Highlighter { ? _primaryColor : _secondaryColor; var foundCurrent = false; - for (var tmp in highlightsByColumn) { - // Work around https://github.com/dart-lang/sdk/issues/43136 - final highlight = tmp; + for (var highlight in highlightsByColumn) { final startLine = highlight?.span.start.line; final endLine = highlight?.span.end.line; if (current != null && highlight == current) { diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 6a3f107da..50450fccb 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,12 @@ name: source_span -version: 1.8.0-nullsafety.2 +version: 1.8.0-nullsafety.3-dev description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0.0 <2.11.0' + sdk: '>=2.11.0-0.0 <2.11.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From c5aa0eae0fca95113b2e0dd73c76dccb139fabb5 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 23 Oct 2020 13:06:17 -0700 Subject: [PATCH 386/657] allow the 2.12 prerelease sdks (dart-lang/pool#44) --- pkgs/pool/CHANGELOG.md | 4 +++ pkgs/pool/pubspec.yaml | 68 ++++-------------------------------------- 2 files changed, 9 insertions(+), 63 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 5d9f6c479..035605e5a 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.0-nullsafety.2 + +* Allow prerelease versions of the 2.12 sdk. + ## 1.5.0-nullsafety.1 * Allow 2.10 stable and 2.11.0 dev SDK versions. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 68b7bb117..5e0a69b7b 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.0-nullsafety.1 +version: 1.5.0-nullsafety.2 description: >- Manage a finite pool of resources. @@ -8,71 +8,13 @@ homepage: https://github.com/dart-lang/pool environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.11.0' + sdk: '>=2.10.0-0 <2.12.0' dependencies: async: '>=2.5.0-nullsafety <2.5.0' stack_trace: '>=1.10.0-nullsafety <1.10.0' dev_dependencies: - fake_async: ^1.0.0 - pedantic: ^1.4.0 - test: ^1.0.0 - -dependency_overrides: - async: - git: git://github.com/dart-lang/async.git - boolean_selector: - git: git://github.com/dart-lang/boolean_selector.git - charcode: - git: git://github.com/dart-lang/charcode.git - collection: - git: git://github.com/dart-lang/collection.git - clock: - git: git://github.com/dart-lang/clock.git - fake_async: - git: git://github.com/dart-lang/fake_async.git - js: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/js - ref: 2-10-pkgs - matcher: - git: git://github.com/dart-lang/matcher.git - meta: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/meta - ref: 2-10-pkgs - path: - git: git://github.com/dart-lang/path.git - pedantic: - git: git://github.com/dart-lang/pedantic.git - source_maps: - git: git://github.com/dart-lang/source_maps.git - source_map_stack_trace: - git: git://github.com/dart-lang/source_map_stack_trace.git - source_span: - git: git://github.com/dart-lang/source_span.git - stack_trace: - git: git://github.com/dart-lang/stack_trace.git - stream_channel: - git: git://github.com/dart-lang/stream_channel.git - string_scanner: - git: git://github.com/dart-lang/string_scanner.git - term_glyph: - git: git://github.com/dart-lang/term_glyph.git - test_api: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_api - test_core: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_core - test: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test - typed_data: - git: git://github.com/dart-lang/typed_data.git + fake_async: ^1.2.0-nullsafety + pedantic: ^1.10.0-nullsafety + test: ^1.16.0-nullsafety From 8ad7c52042ba31de2877ca698c1cba03d05830e4 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 23 Oct 2020 13:07:00 -0700 Subject: [PATCH 387/657] allow the 2.12 prerelease sdks (dart-lang/source_maps#56) --- pkgs/source_maps/CHANGELOG.md | 4 +++ pkgs/source_maps/pubspec.yaml | 66 +++-------------------------------- 2 files changed, 8 insertions(+), 62 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index fe1976163..6d3bb3541 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.10-nullsafety.2 + +* Allow prerelease versions of the 2.12 sdk. + ## 0.10.10-nullsafety.1 * Allow 2.10 stable and 2.11.0 dev SDK versions. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index a61224ab8..73fa7657d 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,74 +1,16 @@ name: source_maps -version: 0.10.10-nullsafety.1 +version: 0.10.10-nullsafety.2 description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.11.0' + sdk: '>=2.10.0-0 <2.12.0' dependencies: source_span: '>=1.8.0-nullsafety <1.8.0' dev_dependencies: - test: ^1.2.0 - term_glyph: ^1.0.0 - -dependency_overrides: - # Overrides required for a version solve - coverage: 0.14.0 - # Null Safety Overrides - async: - git: git://github.com/dart-lang/async.git - boolean_selector: - git: git://github.com/dart-lang/boolean_selector.git - charcode: - git: git://github.com/dart-lang/charcode.git - collection: - git: git://github.com/dart-lang/collection.git - js: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/js - ref: 2-10-pkgs - matcher: - git: git://github.com/dart-lang/matcher.git - meta: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/meta - ref: 2-10-pkgs - path: - git: git://github.com/dart-lang/path.git - pedantic: - git: git://github.com/dart-lang/pedantic.git - pool: - git: git://github.com/dart-lang/pool.git - source_map_stack_trace: - git: git://github.com/dart-lang/source_map_stack_trace.git - source_span: - git: git://github.com/dart-lang/source_span.git - stack_trace: - git: git://github.com/dart-lang/stack_trace.git - stream_channel: - git: git://github.com/dart-lang/stream_channel.git - string_scanner: - git: git://github.com/dart-lang/string_scanner.git - term_glyph: - git: git://github.com/dart-lang/term_glyph.git - test_api: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_api - test_core: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_core - test: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test - typed_data: - git: git://github.com/dart-lang/typed_data.git - + test: ^1.16.0-nullsafety + term_glyph: ^1.2.0-nullsafety From 648fcb52ba96c5ea7377f4e0d0b5550860068714 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 23 Oct 2020 13:08:34 -0700 Subject: [PATCH 388/657] allow the 2.12 prerelease sdks (dart-lang/source_span#64) --- pkgs/source_span/CHANGELOG.md | 1 + pkgs/source_span/pubspec.yaml | 60 ++--------------------------------- 2 files changed, 4 insertions(+), 57 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 52c3fb504..de8e4ca51 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -2,6 +2,7 @@ * Remove workaround for https://github.com/dart-lang/sdk/issues/43136, which is now fixed. +* Allow prerelease versions of the 2.12 sdk. # 1.8.0-nullsafety.2 diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 50450fccb..2932d1127 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,12 @@ name: source_span -version: 1.8.0-nullsafety.3-dev +version: 1.8.0-nullsafety.3 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: # This must remain a tight constraint until nnbd is stable - sdk: '>=2.11.0-0.0 <2.11.0' + sdk: '>=2.11.0-0.0 <2.12.0' dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' @@ -15,58 +15,4 @@ dependencies: term_glyph: '>=1.2.0-nullsafety <1.2.0' dev_dependencies: - test: ^1.6.0 - -dependency_overrides: - async: - git: git://github.com/dart-lang/async.git - boolean_selector: - git: git://github.com/dart-lang/boolean_selector.git - charcode: - git: git://github.com/dart-lang/charcode.git - collection: - git: git://github.com/dart-lang/collection.git - js: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/js - ref: 2-10-pkgs - matcher: - git: git://github.com/dart-lang/matcher.git - meta: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/meta - ref: 2-10-pkgs - path: - git: git://github.com/dart-lang/path.git - pedantic: - git: git://github.com/dart-lang/pedantic.git - pool: - git: git://github.com/dart-lang/pool.git - source_maps: - git: git://github.com/dart-lang/source_maps.git - source_map_stack_trace: - git: git://github.com/dart-lang/source_map_stack_trace.git - stack_trace: - git: git://github.com/dart-lang/stack_trace.git - stream_channel: - git: git://github.com/dart-lang/stream_channel.git - string_scanner: - git: git://github.com/dart-lang/string_scanner.git - term_glyph: - git: git://github.com/dart-lang/term_glyph.git - test_api: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_api - test_core: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_core - test: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test - typed_data: - git: git://github.com/dart-lang/typed_data.git + test: ^1.16.0-nullsafety From 0d507156dcefd29c766791c26ad8d4e2f6e76ff0 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 3 Nov 2020 14:23:08 -0800 Subject: [PATCH 389/657] Bump SDK constraints for pub (dart-lang/pool#45) Use a 2.12.0 lower bound since pub does not understand allowed experiments for earlier versions. Use a 3.0.0 upper bound to avoid a warning in pub and to give some flexibility in publishing for stable. --- pkgs/pool/CHANGELOG.md | 5 +++++ pkgs/pool/pubspec.yaml | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 035605e5a..6fd755bbb 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.5.0-nullsafety.3 + +* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release + guidelines. + ## 1.5.0-nullsafety.2 * Allow prerelease versions of the 2.12 sdk. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 5e0a69b7b..67d8b6c7a 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.0-nullsafety.2 +version: 1.5.0-nullsafety.3 description: >- Manage a finite pool of resources. @@ -7,8 +7,7 @@ description: >- homepage: https://github.com/dart-lang/pool environment: - # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.12.0' + sdk: ">=2.12.0-0 <3.0.0" dependencies: async: '>=2.5.0-nullsafety <2.5.0' From 7cf68751f3d03d3c27b4a45bfdc7598addfca6a3 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 3 Nov 2020 14:25:35 -0800 Subject: [PATCH 390/657] Bump SDK constraints for pub (dart-lang/source_maps#57) Use a 2.12.0 lower bound since pub does not understand allowed experiments for earlier versions. Use a 3.0.0 upper bound to avoid a warning in pub and to give some flexibility in publishing for stable. --- pkgs/source_maps/CHANGELOG.md | 5 +++++ pkgs/source_maps/pubspec.yaml | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 6d3bb3541..7bdead97f 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.10.10-nullsafety.3 + +* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release + guidelines. + ## 0.10.10-nullsafety.2 * Allow prerelease versions of the 2.12 sdk. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 73fa7657d..ab75dc5c6 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,12 +1,11 @@ name: source_maps -version: 0.10.10-nullsafety.2 +version: 0.10.10-nullsafety.3 description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps environment: - # This must remain a tight constraint until nnbd is stable - sdk: '>=2.10.0-0 <2.12.0' + sdk: ">=2.12.0-0 <3.0.0" dependencies: source_span: '>=1.8.0-nullsafety <1.8.0' From 5a914124d1ff8bafa1744774dcd973b966606c93 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 3 Nov 2020 14:28:19 -0800 Subject: [PATCH 391/657] Bump SDK constraints for pub (dart-lang/source_span#65) Use a 2.12.0 lower bound since pub does not understand allowed experiments for earlier versions. Use a 3.0.0 upper bound to avoid a warning in pub and to give some flexibility in publishing for stable. --- pkgs/source_span/CHANGELOG.md | 5 +++++ pkgs/source_span/pubspec.yaml | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index de8e4ca51..2c812566a 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.8.0-nullsafety.4 + +* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release + guidelines. + # 1.8.0-nullsafety.3 * Remove workaround for https://github.com/dart-lang/sdk/issues/43136, which is diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 2932d1127..a5db06e14 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,12 +1,11 @@ name: source_span -version: 1.8.0-nullsafety.3 +version: 1.8.0-nullsafety.4 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: - # This must remain a tight constraint until nnbd is stable - sdk: '>=2.11.0-0.0 <2.12.0' + sdk: ">=2.12.0-0.0 <3.0.0" dependencies: charcode: '>=1.2.0-nullsafety <1.2.0' From 778a4bb3bfbbf48da04741381416d7159955b10b Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 3 Nov 2020 16:24:31 -0800 Subject: [PATCH 392/657] Remove dependency on package:charcode (dart-lang/source_span#66) Copy in the charcode constants that are used in this package to a private library. --- pkgs/source_span/CHANGELOG.md | 2 ++ pkgs/source_span/lib/src/charcode.dart | 15 +++++++++++++++ pkgs/source_span/lib/src/highlighter.dart | 2 +- pkgs/source_span/lib/src/span.dart | 2 +- pkgs/source_span/pubspec.yaml | 3 +-- 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 pkgs/source_span/lib/src/charcode.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 2c812566a..ae1c0d6ae 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.8.0-nullsafety.5-dev + # 1.8.0-nullsafety.4 * Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release diff --git a/pkgs/source_span/lib/src/charcode.dart b/pkgs/source_span/lib/src/charcode.dart new file mode 100644 index 000000000..51826380a --- /dev/null +++ b/pkgs/source_span/lib/src/charcode.dart @@ -0,0 +1,15 @@ +// 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. + +/// "Carriage return" control character. +const int $cr = 0x0D; + +/// "Line feed" control character. +const int $lf = 0x0A; + +/// Space character. +const int $space = 0x20; + +/// "Horizontal Tab" control character, common name. +const int $tab = 0x09; diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index f622c4e01..5d28fc3bb 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -4,11 +4,11 @@ import 'dart:math' as math; -import 'package:charcode/charcode.dart'; import 'package:collection/collection.dart'; import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; +import 'charcode.dart'; import 'colors.dart' as colors; import 'location.dart'; import 'span.dart'; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 94c05ba7a..ba8bec715 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -2,10 +2,10 @@ // 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:charcode/charcode.dart'; import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; +import 'charcode.dart'; import 'file.dart'; import 'highlighter.dart'; import 'location.dart'; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index a5db06e14..9f7fca3c2 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.8.0-nullsafety.4 +version: 1.8.0-nullsafety.5-dev description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span @@ -8,7 +8,6 @@ environment: sdk: ">=2.12.0-0.0 <3.0.0" dependencies: - 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' From e3c69b9be3add6635a22564e592803cd4e2f1c9b Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 9 Nov 2020 20:06:33 -0800 Subject: [PATCH 393/657] Remove unused dart:async imports. As of Dart 2.1, Future/Stream have been exported from dart:core. --- pkgs/package_config/test/legacy/discovery_analysis_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/package_config/test/legacy/discovery_analysis_test.dart b/pkgs/package_config/test/legacy/discovery_analysis_test.dart index 4be636d13..7554d85d9 100644 --- a/pkgs/package_config/test/legacy/discovery_analysis_test.dart +++ b/pkgs/package_config/test/legacy/discovery_analysis_test.dart @@ -6,7 +6,6 @@ @TestOn('vm') library package_config.discovery_analysis_test; -import "dart:async"; import "dart:io"; import "package:package_config/discovery_analysis.dart"; From e4fcf2cb1c3c7ed2fdab609b903f643d9e5a4736 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 11 Nov 2020 08:19:35 -0800 Subject: [PATCH 394/657] Update analysis_options.yaml --- pkgs/pool/analysis_options.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index 986bccc6c..ae67bc00b 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -4,9 +4,6 @@ analyzer: strong-mode: implicit-casts: false - enable-experiment: - - non-nullable - linter: rules: - avoid_function_literals_in_foreach_calls From 21b831d74e81751717799629e310639a141a60f8 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 11 Nov 2020 09:54:20 -0800 Subject: [PATCH 395/657] remove redundant experiment --- pkgs/source_maps/analysis_options.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml index 86c836783..4f9dfb038 100644 --- a/pkgs/source_maps/analysis_options.yaml +++ b/pkgs/source_maps/analysis_options.yaml @@ -1,9 +1,5 @@ include: package:pedantic/analysis_options.yaml -analyzer: - enable-experiment: - - non-nullable - linter: rules: - comment_references From 35e8cc03c1984e163cd56178449f7efa8cb9d5b7 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Wed, 11 Nov 2020 10:25:13 -0800 Subject: [PATCH 396/657] remove redundant experiment (dart-lang/source_span#68) --- pkgs/source_span/analysis_options.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index ced2e21b2..ab5a4f209 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -2,8 +2,6 @@ include: package:pedantic/analysis_options.yaml analyzer: strong-mode: implicit-casts: false - enable-experiment: - - non-nullable linter: rules: - always_declare_return_types From 92e0d59f2d5096313a44e10ec3c3e534eff6d91c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 12 Nov 2020 17:43:24 -0800 Subject: [PATCH 397/657] Delete .test_config (dart-lang/pool#47) --- pkgs/pool/.test_config | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 pkgs/pool/.test_config diff --git a/pkgs/pool/.test_config b/pkgs/pool/.test_config deleted file mode 100644 index 412fc5c5c..000000000 --- a/pkgs/pool/.test_config +++ /dev/null @@ -1,3 +0,0 @@ -{ - "test_package": true -} \ No newline at end of file From e2b4a8c19ab7ee4327afa057bb2ccdb31ebe0f4a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 20 Nov 2020 08:30:52 -0800 Subject: [PATCH 398/657] Migrate to null safety (dart-lang/pub_semver#52) - Switch to a major version bump. - Reformat `.travis.yml`. Indent list elements to the same position as the containing key. This matches yaml style in other Google files. - Update SDK constraints to use the `2.11.0` dev SDKs. - Renames some variables with noise word "the" to match the field name and avoid the shadowing with `this.`. - Add override for analyzer package. Co-authored-by: Nate Bosch --- pkgs/pub_semver/.travis.yml | 21 +++------- pkgs/pub_semver/CHANGELOG.md | 5 ++- pkgs/pub_semver/lib/src/utils.dart | 6 +-- pkgs/pub_semver/lib/src/version.dart | 22 +++++----- .../lib/src/version_constraint.dart | 16 +++---- pkgs/pub_semver/lib/src/version_range.dart | 35 +++++++++------- pkgs/pub_semver/lib/src/version_union.dart | 32 +++++++------- pkgs/pub_semver/pubspec.yaml | 14 ++++--- pkgs/pub_semver/test/utils.dart | 42 +++++++++---------- pkgs/pub_semver/test/version_test.dart | 5 +-- 10 files changed, 96 insertions(+), 102 deletions(-) diff --git a/pkgs/pub_semver/.travis.yml b/pkgs/pub_semver/.travis.yml index 0e732d0e7..e40520c4d 100644 --- a/pkgs/pub_semver/.travis.yml +++ b/pkgs/pub_semver/.travis.yml @@ -1,23 +1,12 @@ language: dart dart: - - dev - - 2.0.0 +- dev dart_task: - - test - -matrix: - include: - # Only validate formatting using the dev release - - dart: dev - dart_task: dartfmt - - dart: dev - dart_task: - dartanalyzer: --fatal-warnings --fatal-hints . - - dart: 2.0.0 - dart_task: - dartanalyzer: --fatal-warnings . +- test: -p vm,chrome +- dart_task: dartfmt +- dartanalyzer: --fatal-infos . # Only building master means that we don't run two builds for each pull request. branches: @@ -25,4 +14,4 @@ branches: cache: directories: - - $HOME/.pub-cache + - $HOME/.pub-cache diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 63f72851c..371970723 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,4 +1,7 @@ -# 1.4.5-dev +# 2.0.0-nullsafety.0 + +- Migrate to null safety. +- `Version.primary` now throws `StateError` if the `versions` argument is empty. # 1.4.4 diff --git a/pkgs/pub_semver/lib/src/utils.dart b/pkgs/pub_semver/lib/src/utils.dart index 60617f22e..a9f714f02 100644 --- a/pkgs/pub_semver/lib/src/utils.dart +++ b/pkgs/pub_semver/lib/src/utils.dart @@ -19,7 +19,7 @@ bool allowsLower(VersionRange range1, VersionRange range2) { if (range1.min == null) return range2.min != null; if (range2.min == null) return false; - var comparison = range1.min.compareTo(range2.min); + var comparison = range1.min!.compareTo(range2.min!); if (comparison == -1) return true; if (comparison == 1) return false; return range1.includeMin && !range2.includeMin; @@ -30,7 +30,7 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { if (range1.max == null) return range2.max != null; if (range2.max == null) return false; - var comparison = range1.max.compareTo(range2.max); + var comparison = range1.max!.compareTo(range2.max!); if (comparison == 1) return true; if (comparison == -1) return false; return range1.includeMax && !range2.includeMax; @@ -41,7 +41,7 @@ bool allowsHigher(VersionRange range1, VersionRange range2) { bool strictlyLower(VersionRange range1, VersionRange range2) { if (range1.max == null || range2.min == null) return false; - var comparison = range1.max.compareTo(range2.min); + var comparison = range1.max!.compareTo(range2.min!); if (comparison == -1) return true; if (comparison == 1) return false; return !range1.includeMax || !range2.includeMin; diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 314937dbf..552b49835 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -92,8 +92,8 @@ class Version implements VersionConstraint, VersionRange { @override bool get includeMax => true; - Version._(this.major, this.minor, this.patch, String preRelease, String build, - this._text) + Version._(this.major, this.minor, this.patch, String? preRelease, + String? build, this._text) : preRelease = preRelease == null ? [] : _splitParts(preRelease), build = build == null ? [] : _splitParts(build) { if (major < 0) throw ArgumentError('Major version must be non-negative.'); @@ -102,7 +102,8 @@ class Version implements VersionConstraint, VersionRange { } /// Creates a new [Version] object. - factory Version(int major, int minor, int patch, {String pre, String build}) { + factory Version(int major, int minor, int patch, + {String? pre, String? build}) { var text = '$major.$minor.$patch'; if (pre != null) text += '-$pre'; if (build != null) text += '+$build'; @@ -118,9 +119,9 @@ class Version implements VersionConstraint, VersionRange { } try { - var major = int.parse(match[1]); - var minor = int.parse(match[2]); - var patch = int.parse(match[3]); + var major = int.parse(match[1]!); + var minor = int.parse(match[2]!); + var patch = int.parse(match[3]!); var preRelease = match[5]; var build = match[8]; @@ -136,12 +137,11 @@ class Version implements VersionConstraint, VersionRange { /// This is the highest-numbered stable (non-prerelease) version. If there /// are no stable versions, it's just the highest-numbered version. /// - /// If [versions] is empty, returns `null`. + /// If [versions] is empty, throws a [StateError]. static Version primary(List versions) { - Version primary; - for (var version in versions) { - if (primary == null || - (!version.isPreRelease && primary.isPreRelease) || + var primary = versions.first; + for (var version in versions.skip(1)) { + if ((!version.isPreRelease && primary.isPreRelease) || (version.isPreRelease == primary.isPreRelease && version > primary)) { primary = version; } diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index ac39b6b18..6eb6c3a29 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -57,16 +57,16 @@ abstract class VersionConstraint { if (text == 'any') return any; // Try to parse and consume a version number. - Version matchVersion() { + Version? matchVersion() { var version = startVersion.firstMatch(text); if (version == null) return null; text = text.substring(version.end); - return Version.parse(version[0]); + return Version.parse(version[0]!); } // Try to parse and consume a comparison operator followed by a version. - VersionRange matchComparison() { + VersionRange? matchComparison() { var comparison = startComparison.firstMatch(text); if (comparison == null) return null; @@ -97,7 +97,7 @@ abstract class VersionConstraint { } // Try to parse the "^" operator followed by a version. - VersionConstraint matchCompatibleWith() { + VersionConstraint? matchCompatibleWith() { if (!text.startsWith(compatibleWithChar)) return null; text = text.substring(compatibleWithChar.length); @@ -120,9 +120,9 @@ abstract class VersionConstraint { var compatibleWith = matchCompatibleWith(); if (compatibleWith != null) return compatibleWith; - Version min; + Version? min; var includeMin = false; - Version max; + Version? max; var includeMax = false; for (;;) { @@ -137,7 +137,7 @@ abstract class VersionConstraint { } if (newRange.min != null) { - if (min == null || newRange.min > min) { + if (min == null || newRange.min! > min) { min = newRange.min; includeMin = newRange.includeMin; } else if (newRange.min == min && !newRange.includeMin) { @@ -146,7 +146,7 @@ abstract class VersionConstraint { } if (newRange.max != null) { - if (max == null || newRange.max < max) { + if (max == null || newRange.max! < max) { max = newRange.max; includeMax = newRange.includeMax; } else if (newRange.max == max && !newRange.includeMax) { diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 78cd6d026..a2a63276a 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -25,7 +25,7 @@ class VersionRange implements Comparable, VersionConstraint { /// /// This may be `null` in which case the range has no minimum end and allows /// any version less than the maximum. - final Version min; + final Version? min; /// The maximum end of the range. /// @@ -35,7 +35,7 @@ class VersionRange implements Comparable, VersionConstraint { /// /// This may be `null` in which case the range has no maximum end and allows /// any version greater than the minimum. - final Version max; + final Version? max; /// If `true` then [min] is allowed by the range. final bool includeMin; @@ -58,8 +58,8 @@ class VersionRange implements Comparable, VersionConstraint { /// pre-release versions of an exclusive [max]. Otherwise, it will use the /// default behavior for pre-release versions of [max]. factory VersionRange( - {Version min, - Version max, + {Version? min, + Version? max, bool includeMin = false, bool includeMax = false, bool alwaysIncludeMaxPreRelease = false}) { @@ -111,12 +111,12 @@ class VersionRange implements Comparable, VersionConstraint { @override bool allows(Version other) { if (min != null) { - if (other < min) return false; + if (other < min!) return false; if (!includeMin && other == min) return false; } if (max != null) { - if (other > max) return false; + if (other > max!) return false; if (!includeMax && other == max) return false; } @@ -167,7 +167,7 @@ class VersionRange implements Comparable, VersionConstraint { if (other is VersionRange) { // Intersect the two ranges. - Version intersectMin; + Version? intersectMin; bool intersectIncludeMin; if (allowsLower(this, other)) { if (strictlyLower(this, other)) return VersionConstraint.empty; @@ -179,7 +179,7 @@ class VersionRange implements Comparable, VersionConstraint { intersectIncludeMin = includeMin; } - Version intersectMax; + Version? intersectMax; bool intersectIncludeMax; if (allowsHigher(this, other)) { intersectMax = other.max; @@ -199,7 +199,7 @@ class VersionRange implements Comparable, VersionConstraint { // Because we already verified that the lower range isn't strictly // lower, there must be some overlap. assert(intersectIncludeMin && intersectIncludeMax); - return intersectMin; + return intersectMin!; } // If we got here, there is an actual range. @@ -251,7 +251,7 @@ class VersionRange implements Comparable, VersionConstraint { return VersionConstraint.unionOf([this, other]); } - Version unionMin; + Version? unionMin; bool unionIncludeMin; if (allowsLower(this, other)) { unionMin = min; @@ -261,7 +261,7 @@ class VersionRange implements Comparable, VersionConstraint { unionIncludeMin = other.includeMin; } - Version unionMax; + Version? unionMax; bool unionIncludeMax; if (allowsHigher(this, other)) { unionMax = max; @@ -326,7 +326,7 @@ class VersionRange implements Comparable, VersionConstraint { } else if (other is VersionRange) { if (!allowsAny(other)) return this; - VersionRange before; + VersionRange? before; if (!allowsLower(this, other)) { before = null; } else if (min == other.min) { @@ -342,7 +342,7 @@ class VersionRange implements Comparable, VersionConstraint { alwaysIncludeMaxPreRelease: true); } - VersionRange after; + VersionRange? after; if (!allowsHigher(this, other)) { after = null; } else if (max == other.max) { @@ -359,7 +359,7 @@ class VersionRange implements Comparable, VersionConstraint { } if (before == null && after == null) return VersionConstraint.empty; - if (before == null) return after; + if (before == null) return after!; if (after == null) return before; return VersionUnion.fromRanges([before, after]); } else if (other is VersionUnion) { @@ -404,7 +404,7 @@ class VersionRange implements Comparable, VersionConstraint { return 1; } - var result = min.compareTo(other.min); + var result = min!.compareTo(other.min!); if (result != 0) return result; if (includeMin != other.includeMin) return includeMin ? -1 : 1; @@ -420,7 +420,7 @@ class VersionRange implements Comparable, VersionConstraint { return -1; } - var result = max.compareTo(other.max); + var result = max!.compareTo(other.max!); if (result != 0) return result; if (includeMax != other.includeMax) return includeMax ? 1 : -1; return 0; @@ -430,10 +430,13 @@ class VersionRange implements Comparable, VersionConstraint { String toString() { var buffer = StringBuffer(); + final min = this.min; if (min != null) { buffer..write(includeMin ? '>=' : '>')..write(min); } + final max = this.max; + if (max != null) { if (min != null) buffer.write(' '); if (includeMax) { diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index 8a235220c..24b82f4cc 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -50,19 +50,19 @@ class VersionUnion implements VersionConstraint { // Because both lists of ranges are ordered by minimum version, we can // safely move through them linearly here. - ourRanges.moveNext(); - theirRanges.moveNext(); - while (ourRanges.current != null && theirRanges.current != null) { + var ourRangesMoved = ourRanges.moveNext(); + var theirRangesMoved = theirRanges.moveNext(); + while (ourRangesMoved && theirRangesMoved) { if (ourRanges.current.allowsAll(theirRanges.current)) { - theirRanges.moveNext(); + theirRangesMoved = theirRanges.moveNext(); } else { - ourRanges.moveNext(); + ourRangesMoved = ourRanges.moveNext(); } } // If our ranges have allowed all of their ranges, we'll have consumed all // of them. - return theirRanges.current == null; + return !theirRangesMoved; } @override @@ -72,9 +72,9 @@ class VersionUnion implements VersionConstraint { // Because both lists of ranges are ordered by minimum version, we can // safely move through them linearly here. - ourRanges.moveNext(); - theirRanges.moveNext(); - while (ourRanges.current != null && theirRanges.current != null) { + var ourRangesMoved = ourRanges.moveNext(); + var theirRangesMoved = theirRanges.moveNext(); + while (ourRangesMoved && theirRangesMoved) { if (ourRanges.current.allowsAny(theirRanges.current)) { return true; } @@ -82,9 +82,9 @@ class VersionUnion implements VersionConstraint { // Move the constraint with the lower max value forward. This ensures that // we keep both lists in sync as much as possible. if (allowsHigher(theirRanges.current, ourRanges.current)) { - ourRanges.moveNext(); + ourRangesMoved = ourRanges.moveNext(); } else { - theirRanges.moveNext(); + theirRangesMoved = theirRanges.moveNext(); } } @@ -99,9 +99,9 @@ class VersionUnion implements VersionConstraint { // Because both lists of ranges are ordered by minimum version, we can // safely move through them linearly here. var newRanges = []; - ourRanges.moveNext(); - theirRanges.moveNext(); - while (ourRanges.current != null && theirRanges.current != null) { + var ourRangesMoved = ourRanges.moveNext(); + var theirRangesMoved = theirRanges.moveNext(); + while (ourRangesMoved && theirRangesMoved) { var intersection = ourRanges.current.intersect(theirRanges.current); if (!intersection.isEmpty) newRanges.add(intersection as VersionRange); @@ -110,9 +110,9 @@ class VersionUnion implements VersionConstraint { // we keep both lists in sync as much as possible, and that large ranges // have a chance to match multiple small ranges that they contain. if (allowsHigher(theirRanges.current, ourRanges.current)) { - ourRanges.moveNext(); + ourRangesMoved = ourRanges.moveNext(); } else { - theirRanges.moveNext(); + theirRangesMoved = theirRanges.moveNext(); } } diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 78de107cb..dc2d6ac0c 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,16 +1,18 @@ name: pub_semver -version: 1.4.5-dev - +version: 2.0.0-nullsafety.0 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. -homepage: https://github.com/dart-lang/pub_semver +repository: https://github.com/dart-lang/pub_semver environment: - sdk: '>=2.0.0 <3.0.0' + sdk: '>=2.12.0-0 <3.0.0' dependencies: - collection: ^1.0.0 + collection: ^1.15.0-nullsafety.2 dev_dependencies: - test: ^1.0.0 + test: ^1.16.0-nullsafety.1 + +dependency_overrides: + analyzer: any diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index eb3358a98..595415abf 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -79,13 +79,13 @@ class _VersionConstraintMatcher implements Matcher { /// Gets a [Matcher] that validates that a [VersionConstraint] allows all /// given versions. Matcher allows(Version v1, - [Version v2, - Version v3, - Version v4, - Version v5, - Version v6, - Version v7, - Version v8]) { + [Version? v2, + Version? v3, + Version? v4, + Version? v5, + Version? v6, + Version? v7, + Version? v8]) { var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); return _VersionConstraintMatcher(versions, true); } @@ -93,25 +93,25 @@ Matcher allows(Version v1, /// Gets a [Matcher] that validates that a [VersionConstraint] allows none of /// the given versions. Matcher doesNotAllow(Version v1, - [Version v2, - Version v3, - Version v4, - Version v5, - Version v6, - Version v7, - Version v8]) { + [Version? v2, + Version? v3, + Version? v4, + Version? v5, + Version? v6, + Version? v7, + Version? v8]) { var versions = _makeVersionList(v1, v2, v3, v4, v5, v6, v7, v8); return _VersionConstraintMatcher(versions, false); } List _makeVersionList(Version v1, - [Version v2, - Version v3, - Version v4, - Version v5, - Version v6, - Version v7, - Version v8]) { + [Version? v2, + Version? v3, + Version? v4, + Version? v5, + Version? v6, + Version? v7, + Version? v8]) { var versions = [v1]; if (v2 != null) versions.add(v2); if (v3 != null) versions.add(v3); diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 70d277975..6ff4b3e98 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -371,10 +371,7 @@ void main() { }); test('empty', () { - expect( - _primary([]), - isNull, - ); + expect(() => Version.primary([]), throwsStateError); }); }); } From c86d4c98c8286e2fc7263df3407834d5f3c5f612 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Wed, 2 Dec 2020 16:23:00 +0100 Subject: [PATCH 399/657] Migrate to null safety (dart-lang/package_config#93) * Migrate non-deprecated libraries to null safety. * Major version increment, removing deprecated APIs. This is the null safe, non-deprecated API for package_config.json file manipulation. Also address dart-lang/package_config#86. --- pkgs/package_config/CHANGELOG.md | 5 + pkgs/package_config/README.md | 9 +- pkgs/package_config/analysis_options.yaml | 1 - pkgs/package_config/lib/discovery.dart | 226 ------------ .../lib/discovery_analysis.dart | 167 --------- pkgs/package_config/lib/package_config.dart | 23 +- pkgs/package_config/lib/packages.dart | 96 ----- pkgs/package_config/lib/packages_file.dart | 232 ------------ pkgs/package_config/lib/src/discovery.dart | 14 +- pkgs/package_config/lib/src/errors.dart | 7 +- .../lib/src/package_config.dart | 54 +-- .../lib/src/package_config_impl.dart | 82 +++-- .../lib/src/package_config_io.dart | 39 ++- .../lib/src/package_config_json.dart | 91 ++--- .../package_config/lib/src/packages_file.dart | 4 +- .../package_config/lib/src/packages_impl.dart | 128 ------- .../lib/src/packages_io_impl.dart | 46 --- pkgs/package_config/lib/src/util.dart | 4 +- pkgs/package_config/lib/src/util_io.dart | 8 +- pkgs/package_config/pubspec.yaml | 55 ++- pkgs/package_config/test/discovery_test.dart | 6 +- .../test/discovery_uri_test.dart | 8 +- pkgs/package_config/test/legacy/all.dart | 20 -- .../test/legacy/discovery_analysis_test.dart | 127 ------- .../test/legacy/discovery_test.dart | 329 ------------------ .../test/legacy/parse_test.dart | 246 ------------- .../test/legacy/parse_write_test.dart | 133 ------- pkgs/package_config/test/parse_test.dart | 48 +-- pkgs/package_config/test/src/util.dart | 10 +- pkgs/package_config/test/src/util_io.dart | 16 +- 30 files changed, 275 insertions(+), 1959 deletions(-) delete mode 100644 pkgs/package_config/lib/discovery.dart delete mode 100644 pkgs/package_config/lib/discovery_analysis.dart delete mode 100644 pkgs/package_config/lib/packages.dart delete mode 100644 pkgs/package_config/lib/packages_file.dart delete mode 100644 pkgs/package_config/lib/src/packages_impl.dart delete mode 100644 pkgs/package_config/lib/src/packages_io_impl.dart delete mode 100644 pkgs/package_config/test/legacy/all.dart delete mode 100644 pkgs/package_config/test/legacy/discovery_analysis_test.dart delete mode 100644 pkgs/package_config/test/legacy/discovery_test.dart delete mode 100644 pkgs/package_config/test/legacy/parse_test.dart delete mode 100644 pkgs/package_config/test/legacy/parse_write_test.dart diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 6dcae80cf..32ff3f17f 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.0.0 + +- Migrate to null safety. +- Remove legacy APIs. + ## 1.9.3 - Fix `Package` constructor not accepting relative `packageUriRoot`. diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index b47a6825b..1ad4b41c1 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -7,11 +7,12 @@ in the Package Configuration v2 [design document](https://github.com/dart-lang/l The primary libraries are * `package_config.dart`: Defines the `PackageConfig` class and other types needed to use - package configurations. + package configurations, and provides functions to find, read and + write package configuration files. -* `package_config_discovery.dart`: - Provides functions for reading configurations from files, - and writing them back out. +* `package_config_types.dart`: + Just the `PackageConfig` class and other types needed to use + package configurations. This library does not depend on `dart:io`. The package includes deprecated backwards compatible functionality to work with the `.packages` file. This functionality will not be maintained, diff --git a/pkgs/package_config/analysis_options.yaml b/pkgs/package_config/analysis_options.yaml index 66639ec1a..a7854087c 100644 --- a/pkgs/package_config/analysis_options.yaml +++ b/pkgs/package_config/analysis_options.yaml @@ -6,6 +6,5 @@ include: package:pedantic/analysis_options.1.9.0.yaml analyzer: errors: annotate_overrides: ignore - curly_braces_in_flow_control_structures: ignore prefer_single_quotes: ignore use_function_type_syntax_for_parameters: ignore diff --git a/pkgs/package_config/lib/discovery.dart b/pkgs/package_config/lib/discovery.dart deleted file mode 100644 index a72bb1255..000000000 --- a/pkgs/package_config/lib/discovery.dart +++ /dev/null @@ -1,226 +0,0 @@ -// Copyright (c) 2015, 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. - -@Deprecated("Use the package_config.json based API") -library package_config.discovery; - -import "dart:io"; -import "dart:typed_data" show Uint8List; - -import "package:path/path.dart" as path; - -import "packages.dart"; -import "packages_file.dart" as pkgfile show parse; -import "src/packages_impl.dart"; -import "src/packages_io_impl.dart"; - -/// Reads a package resolution file and creates a [Packages] object from it. -/// -/// The [packagesFile] must exist and be loadable. -/// Currently that means the URI must have a `file`, `http` or `https` scheme, -/// and that the file can be loaded and its contents parsed correctly. -/// -/// If the [loader] is provided, it is used to fetch non-`file` URIs, and -/// it can support other schemes or set up more complex HTTP requests. -/// -/// This function can be used to load an explicitly configured package -/// resolution file, for example one specified using a `--packages` -/// command-line parameter. -Future loadPackagesFile(Uri packagesFile, - {Future> loader(Uri uri)}) async { - Packages parseBytes(List bytes) { - return MapPackages(pkgfile.parse(bytes, packagesFile)); - } - - if (packagesFile.scheme == "file") { - return parseBytes(await File.fromUri(packagesFile).readAsBytes()); - } - if (loader == null) { - return parseBytes(await _httpGet(packagesFile)); - } - return parseBytes(await loader(packagesFile)); -} - -/// Create a [Packages] object for a package directory. -/// -/// The [packagesDir] URI should refer to a directory. -/// Package names are resolved as relative to sub-directories of the -/// package directory. -/// -/// This function can be used for explicitly configured package directories, -/// for example one specified using a `--package-root` comand-line parameter. -Packages getPackagesDirectory(Uri packagesDir) { - if (packagesDir.scheme == "file") { - return FilePackagesDirectoryPackages(Directory.fromUri(packagesDir)); - } - if (!packagesDir.path.endsWith('/')) { - packagesDir = packagesDir.replace(path: packagesDir.path + '/'); - } - return NonFilePackagesDirectoryPackages(packagesDir); -} - -/// Discover the package configuration for a Dart script. -/// -/// The [baseUri] points to either the Dart script or its directory. -/// A package resolution strategy is found by going through the following steps, -/// and stopping when something is found. -/// -/// * Check if a `.packages` file exists in the same directory. -/// * If `baseUri`'s scheme is not `file`, then assume a `packages` directory -/// in the same directory, and resolve packages relative to that. -/// * If `baseUri`'s scheme *is* `file`: -/// * Check if a `packages` directory exists. -/// * Otherwise check each successive parent directory of `baseUri` for a -/// `.packages` file. -/// -/// If any of these tests succeed, a `Packages` class is returned. -/// Returns the constant [noPackages] if no resolution strategy is found. -/// -/// This function currently only supports `file`, `http` and `https` URIs. -/// It needs to be able to load a `.packages` file from the URI, so only -/// recognized schemes are accepted. -/// -/// To support other schemes, or more complex HTTP requests, -/// an optional [loader] function can be supplied. -/// It's called to load the `.packages` file for a non-`file` scheme. -/// The loader function returns the *contents* of the file -/// identified by the URI it's given. -/// The content should be a UTF-8 encoded `.packages` file, and must return an -/// error future if loading fails for any reason. -Future findPackages(Uri baseUri, - {Future> loader(Uri unsupportedUri)}) { - if (baseUri.scheme == "file") { - return Future.sync(() => findPackagesFromFile(baseUri)); - } else if (loader != null) { - return findPackagesFromNonFile(baseUri, loader: loader); - } else if (baseUri.scheme == "http" || baseUri.scheme == "https") { - return findPackagesFromNonFile(baseUri, loader: _httpGet); - } else { - return Future.value(Packages.noPackages); - } -} - -/// Find the location of the package resolution file/directory for a Dart file. -/// -/// Checks for a `.packages` file in the [workingDirectory]. -/// If not found, checks for a `packages` directory in the same directory. -/// If still not found, starts checking parent directories for -/// `.packages` until reaching the root directory. -/// -/// Returns a [File] object of a `.packages` file if one is found, or a -/// [Directory] object for the `packages/` directory if that is found. -FileSystemEntity _findPackagesFile(String workingDirectory) { - var dir = Directory(workingDirectory); - if (!dir.isAbsolute) dir = dir.absolute; - if (!dir.existsSync()) { - throw ArgumentError.value( - workingDirectory, "workingDirectory", "Directory does not exist."); - } - File checkForConfigFile(Directory directory) { - assert(directory.isAbsolute); - var file = File(path.join(directory.path, ".packages")); - if (file.existsSync()) return file; - return null; - } - - // Check for $cwd/.packages - var packagesCfgFile = checkForConfigFile(dir); - if (packagesCfgFile != null) return packagesCfgFile; - // Check for $cwd/packages/ - var packagesDir = Directory(path.join(dir.path, "packages")); - if (packagesDir.existsSync()) return packagesDir; - // Check for cwd(/..)+/.packages - var parentDir = dir.parent; - while (parentDir.path != dir.path) { - packagesCfgFile = checkForConfigFile(parentDir); - if (packagesCfgFile != null) break; - dir = parentDir; - parentDir = dir.parent; - } - return packagesCfgFile; -} - -/// Finds a package resolution strategy for a local Dart script. -/// -/// The [fileBaseUri] points to either a Dart script or the directory of the -/// script. The `fileBaseUri` must be a `file:` URI. -/// -/// This function first tries to locate a `.packages` file in the `fileBaseUri` -/// directory. If that is not found, it instead checks for the presence of -/// a `packages/` directory in the same place. -/// If that also fails, it starts checking parent directories for a `.packages` -/// file, and stops if it finds it. -/// Otherwise it gives up and returns [Packages.noPackages]. -Packages findPackagesFromFile(Uri fileBaseUri) { - var baseDirectoryUri = fileBaseUri; - if (!fileBaseUri.path.endsWith('/')) { - baseDirectoryUri = baseDirectoryUri.resolve("."); - } - var baseDirectoryPath = baseDirectoryUri.toFilePath(); - var location = _findPackagesFile(baseDirectoryPath); - if (location == null) return Packages.noPackages; - if (location is File) { - var fileBytes = location.readAsBytesSync(); - var map = pkgfile.parse(fileBytes, Uri.file(location.path)); - return MapPackages(map); - } - assert(location is Directory); - return FilePackagesDirectoryPackages(location); -} - -/// Finds a package resolution strategy for a Dart script. -/// -/// The [nonFileUri] points to either a Dart script or the directory of the -/// script. -/// The [nonFileUri] should not be a `file:` URI since the algorithm for -/// finding a package resolution strategy is more elaborate for `file:` URIs. -/// In that case, use [findPackagesFromFile]. -/// -/// This function first tries to locate a `.packages` file in the [nonFileUri] -/// directory. If that is not found, it instead assumes a `packages/` directory -/// in the same place. -/// -/// By default, this function only works for `http:` and `https:` URIs. -/// To support other schemes, a loader must be provided, which is used to -/// try to load the `.packages` file. The loader should return the contents -/// of the requested `.packages` file as bytes, which will be assumed to be -/// UTF-8 encoded. -Future findPackagesFromNonFile(Uri nonFileUri, - {Future> loader(Uri name)}) async { - loader ??= _httpGet; - var packagesFileUri = nonFileUri.resolve(".packages"); - - try { - var fileBytes = await loader(packagesFileUri); - var map = pkgfile.parse(fileBytes, packagesFileUri); - return MapPackages(map); - } catch (_) { - // Didn't manage to load ".packages". Assume a "packages/" directory. - var packagesDirectoryUri = nonFileUri.resolve("packages/"); - return NonFilePackagesDirectoryPackages(packagesDirectoryUri); - } -} - -/// Fetches a file over http. -Future> _httpGet(Uri uri) async { - var client = HttpClient(); - var request = await client.getUrl(uri); - var response = await request.close(); - if (response.statusCode != HttpStatus.ok) { - throw HttpException('${response.statusCode} ${response.reasonPhrase}', - uri: uri); - } - var splitContent = await response.toList(); - var totalLength = 0; - for (var list in splitContent) { - totalLength += list.length; - } - var result = Uint8List(totalLength); - var offset = 0; - for (var contentPart in splitContent) { - result.setRange(offset, offset + contentPart.length, contentPart); - offset += contentPart.length; - } - return result; -} diff --git a/pkgs/package_config/lib/discovery_analysis.dart b/pkgs/package_config/lib/discovery_analysis.dart deleted file mode 100644 index 2af07292e..000000000 --- a/pkgs/package_config/lib/discovery_analysis.dart +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2015, 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. - -/// Analyse a directory structure and find packages resolvers for each -/// sub-directory. -/// -/// The resolvers are generally the same that would be found by using -/// the `discovery.dart` library on each sub-directory in turn, -/// but more efficiently and with some heuristics for directories that -/// wouldn't otherwise have a package resolution strategy, or that are -/// determined to be "package directories" themselves. -@Deprecated("Use the package_config.json based API") -library package_config.discovery_analysis; - -import "dart:collection" show HashMap; -import "dart:io" show File, Directory; - -import "package:path/path.dart" as path; - -import "packages.dart"; -import "packages_file.dart" as pkgfile; -import "src/packages_impl.dart"; -import "src/packages_io_impl.dart"; - -/// Associates a [Packages] package resolution strategy with a directory. -/// -/// The package resolution applies to the directory and any sub-directory -/// that doesn't have its own overriding child [PackageContext]. -abstract class PackageContext { - /// The directory that introduced the [packages] resolver. - Directory get directory; - - /// A [Packages] resolver that applies to the directory. - /// - /// Introduced either by a `.packages` file or a `packages/` directory. - Packages get packages; - - /// Child contexts that apply to sub-directories of [directory]. - List get children; - - /// Look up the [PackageContext] that applies to a specific directory. - /// - /// The directory must be inside [directory]. - PackageContext operator [](Directory directory); - - /// A map from directory to package resolver. - /// - /// Has an entry for this package context and for each child context - /// contained in this one. - Map asMap(); - - /// Analyze [directory] and sub-directories for package resolution strategies. - /// - /// Returns a mapping from sub-directories to [Packages] objects. - /// - /// The analysis assumes that there are no `.packages` files in a parent - /// directory of `directory`. If there is, its corresponding `Packages` object - /// should be provided as `root`. - static PackageContext findAll(Directory directory, - {Packages root = Packages.noPackages}) { - if (!directory.existsSync()) { - throw ArgumentError("Directory not found: $directory"); - } - var contexts = []; - void findRoots(Directory directory) { - Packages packages; - List oldContexts; - var packagesFile = File(path.join(directory.path, ".packages")); - if (packagesFile.existsSync()) { - packages = _loadPackagesFile(packagesFile); - oldContexts = contexts; - contexts = []; - } else { - var packagesDir = Directory(path.join(directory.path, "packages")); - if (packagesDir.existsSync()) { - packages = FilePackagesDirectoryPackages(packagesDir); - oldContexts = contexts; - contexts = []; - } - } - for (var entry in directory.listSync()) { - if (entry is Directory) { - if (packages == null || !entry.path.endsWith("/packages")) { - findRoots(entry); - } - } - } - if (packages != null) { - oldContexts.add(_PackageContext(directory, packages, contexts)); - contexts = oldContexts; - } - } - - findRoots(directory); - // If the root is not itself context root, add a the wrapper context. - if (contexts.length == 1 && contexts[0].directory == directory) { - return contexts[0]; - } - return _PackageContext(directory, root, contexts); - } -} - -class _PackageContext implements PackageContext { - final Directory directory; - final Packages packages; - final List children; - _PackageContext(this.directory, this.packages, List children) - : children = List.unmodifiable(children); - - Map asMap() { - var result = HashMap(); - void recurse(_PackageContext current) { - result[current.directory] = current.packages; - for (var child in current.children) { - recurse(child); - } - } - - recurse(this); - return result; - } - - PackageContext operator [](Directory directory) { - var path = directory.path; - if (!path.startsWith(this.directory.path)) { - throw ArgumentError("Not inside $path: $directory"); - } - var current = this; - // The current path is know to agree with directory until deltaIndex. - var deltaIndex = current.directory.path.length; - List children = current.children; - var i = 0; - while (i < children.length) { - // TODO(lrn): Sort children and use binary search. - _PackageContext child = children[i]; - var childPath = child.directory.path; - if (_stringsAgree(path, childPath, deltaIndex, childPath.length)) { - deltaIndex = childPath.length; - if (deltaIndex == path.length) { - return child; - } - current = child; - children = current.children; - i = 0; - continue; - } - i++; - } - return current; - } - - static bool _stringsAgree(String a, String b, int start, int end) { - if (a.length < end || b.length < end) return false; - for (var i = start; i < end; i++) { - if (a.codeUnitAt(i) != b.codeUnitAt(i)) return false; - } - return true; - } -} - -Packages _loadPackagesFile(File file) { - var uri = Uri.file(file.path); - var bytes = file.readAsBytesSync(); - var map = pkgfile.parse(bytes, uri); - return MapPackages(map); -} diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index 1113ac872..3dfd8ef29 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -3,8 +3,11 @@ // BSD-style license that can be found in the LICENSE file. /// A package configuration is a way to assign file paths to package URIs, -/// and vice-versa, -library package_config.package_config_discovery; +/// and vice-versa. +/// +/// This package provides functionality to find, read and write package +/// configurations in the [specified format](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). +library package_config.package_config; import "dart:io" show File, Directory; import "dart:typed_data" show Uint8List; @@ -39,7 +42,7 @@ export "package_config_types.dart"; /// a valid configuration from the invalid configuration file. /// If no [onError] is provided, errors are thrown immediately. Future loadPackageConfig(File file, - {bool preferNewest = true, void onError(Object error)}) => + {bool preferNewest = true, void onError(Object error)?}) => readAnyConfigFile(file, preferNewest, onError ?? throwError); /// Reads a specific package configuration URI. @@ -84,9 +87,9 @@ Future loadPackageConfig(File file, /// a valid configuration from the invalid configuration file. /// If no [onError] is provided, errors are thrown immediately. Future loadPackageConfigUri(Uri file, - {Future loader(Uri uri) /*?*/, + {Future loader(Uri uri)?, bool preferNewest = true, - void onError(Object error)}) => + void onError(Object error)?}) => readAnyConfigFileUri(file, loader, onError ?? throwError, preferNewest); /// Finds a package configuration relative to [directory]. @@ -109,8 +112,8 @@ Future loadPackageConfigUri(Uri file, /// If no [onError] is provided, errors are thrown immediately. /// /// Returns `null` if no configuration file is found. -Future findPackageConfig(Directory directory, - {bool recurse = true, void onError(Object error)}) => +Future findPackageConfig(Directory directory, + {bool recurse = true, void onError(Object error)?}) => discover.findPackageConfig(directory, recurse, onError ?? throwError); /// Finds a package configuration relative to [location]. @@ -153,10 +156,10 @@ Future findPackageConfig(Directory directory, /// If no [onError] is provided, errors are thrown immediately. /// /// Returns `null` if no configuration file is found. -Future findPackageConfigUri(Uri location, +Future findPackageConfigUri(Uri location, {bool recurse = true, - Future loader(Uri uri), - void onError(Object error)}) => + Future loader(Uri uri)?, + void onError(Object error)?}) => discover.findPackageConfigUri( location, loader, onError ?? throwError, recurse); diff --git a/pkgs/package_config/lib/packages.dart b/pkgs/package_config/lib/packages.dart deleted file mode 100644 index 203f32fdb..000000000 --- a/pkgs/package_config/lib/packages.dart +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2015, 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. - -@Deprecated("Use the package_config.json based API") -library package_config.packages; - -import "src/packages_impl.dart"; - -/// A package resolution strategy. -/// -/// Allows converting a `package:` URI to a different kind of URI. -/// -/// May also allow listing the available packages and converting -/// to a `Map` that gives the base location of each available -/// package. In some cases there is no way to find the available packages, -/// in which case [packages] and [asMap] will throw if used. -/// One such case is if the packages are resolved relative to a -/// `packages/` directory available over HTTP. -@Deprecated("Use the package_config.json based API") -abstract class Packages { - /// A [Packages] resolver containing no packages. - /// - /// This constant object is returned by [find] above if no - /// package resolution strategy is found. - static const Packages noPackages = NoPackages(); - - /// Resolve a package URI into a non-package URI. - /// - /// Translates a `package:` URI, according to the package resolution - /// strategy, into a URI that can be loaded. - /// By default, only `file`, `http` and `https` URIs are returned. - /// Custom `Packages` objects may return other URIs. - /// - /// If resolution fails because a package with the requested package name - /// is not available, the [notFound] function is called. - /// If no `notFound` function is provided, it defaults to throwing an error. - /// - /// The [packageUri] must be a valid package URI. - Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}); - - /// Return the names of the available packages. - /// - /// Returns an iterable that allows iterating the names of available packages. - /// - /// Some `Packages` objects are unable to find the package names, - /// and getting `packages` from such a `Packages` object will throw. - Iterable get packages; - - /// Retrieve metadata associated with a package. - /// - /// Metadata have string keys and values, and are looked up by key. - /// - /// Returns `null` if the argument is not a valid package name, - /// or if the package is not one of the packages configured by - /// this packages object, or if the package does not have associated - /// metadata with the provided [key]. - /// - /// Not all `Packages` objects can support metadata. - /// Those will always return `null`. - String packageMetadata(String packageName, String key); - - /// Retrieve metadata associated with a library. - /// - /// If [libraryUri] is a `package:` URI, the returned value - /// is the same that would be returned by [packageMetadata] with - /// the package's name and the same key. - /// - /// If [libraryUri] is not a `package:` URI, and this [Packages] - /// object has a [defaultPackageName], then the [key] is looked - /// up on the default package instead. - /// - /// Otherwise the result is `null`. - String libraryMetadata(Uri libraryUri, String key); - - /// Return the names-to-base-URI mapping of the available packages. - /// - /// Returns a map from package name to a base URI. - /// The [resolve] method will resolve a package URI with a specific package - /// name to a path extending the base URI that this map gives for that - /// package name. - /// - /// Some `Packages` objects are unable to find the package names, - /// and calling `asMap` on such a `Packages` object will throw. - Map asMap(); - - /// The name of the "default package". - /// - /// A default package is a package that *non-package* libraries - /// may be considered part of for some purposes. - /// - /// The value is `null` if there is no default package. - /// Not all implementations of [Packages] supports a default package, - /// and will always have a `null` value for those. - String get defaultPackageName; -} diff --git a/pkgs/package_config/lib/packages_file.dart b/pkgs/package_config/lib/packages_file.dart deleted file mode 100644 index ef0b0b3ca..000000000 --- a/pkgs/package_config/lib/packages_file.dart +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2015, 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. - -@Deprecated("Use the package_config.json based API") -library package_config.packages_file; - -import "package:charcode/ascii.dart"; - -import "src/util.dart" show isValidPackageName; - -/// Parses a `.packages` file into a map from package name to base URI. -/// -/// The [source] is the byte content of a `.packages` file, assumed to be -/// UTF-8 encoded. In practice, all significant parts of the file must be ASCII, -/// so Latin-1 or Windows-1252 encoding will also work fine. -/// -/// If the file content is available as a string, its [String.codeUnits] can -/// be used as the `source` argument of this function. -/// -/// The [baseLocation] is used as a base URI to resolve all relative -/// URI references against. -/// If the content was read from a file, `baseLocation` should be the -/// location of that file. -/// -/// If [allowDefaultPackage] is set to true, an entry with an empty package name -/// is accepted. This entry does not correspond to a package, but instead -/// represents a *default package* which non-package libraries may be considered -/// part of in some cases. The value of that entry must be a valid package name. -/// -/// Returns a simple mapping from package name to package location. -/// If default package is allowed, the map maps the empty string to the default package's name. -Map parse(List source, Uri baseLocation, - {bool allowDefaultPackage = false}) { - var index = 0; - var result = {}; - while (index < source.length) { - var isComment = false; - var start = index; - var separatorIndex = -1; - var end = source.length; - var char = source[index++]; - if (char == $cr || char == $lf) { - continue; - } - if (char == $colon) { - if (!allowDefaultPackage) { - throw FormatException("Missing package name", source, index - 1); - } - separatorIndex = index - 1; - } - isComment = char == $hash; - while (index < source.length) { - char = source[index++]; - if (char == $colon && separatorIndex < 0) { - separatorIndex = index - 1; - } else if (char == $cr || char == $lf) { - end = index - 1; - break; - } - } - if (isComment) continue; - if (separatorIndex < 0) { - throw FormatException("No ':' on line", source, index - 1); - } - var packageName = String.fromCharCodes(source, start, separatorIndex); - if (packageName.isEmpty - ? !allowDefaultPackage - : !isValidPackageName(packageName)) { - throw FormatException("Not a valid package name", packageName, 0); - } - var packageValue = String.fromCharCodes(source, separatorIndex + 1, end); - Uri packageLocation; - if (packageName.isEmpty) { - if (!isValidPackageName(packageValue)) { - throw FormatException( - "Default package entry value is not a valid package name"); - } - packageLocation = Uri(path: packageValue); - } else { - packageLocation = baseLocation.resolve(packageValue); - if (!packageLocation.path.endsWith('/')) { - packageLocation = - packageLocation.replace(path: packageLocation.path + "/"); - } - } - if (result.containsKey(packageName)) { - if (packageName.isEmpty) { - throw FormatException( - "More than one default package entry", source, start); - } - throw FormatException("Same package name occured twice", source, start); - } - result[packageName] = packageLocation; - } - return result; -} - -/// Writes the mapping to a [StringSink]. -/// -/// If [comment] is provided, the output will contain this comment -/// with `# ` in front of each line. -/// Lines are defined as ending in line feed (`'\n'`). If the final -/// line of the comment doesn't end in a line feed, one will be added. -/// -/// If [baseUri] is provided, package locations will be made relative -/// to the base URI, if possible, before writing. -/// -/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an -/// empty string mapping to the _default package name_. -/// -/// All the keys of [packageMapping] must be valid package names, -/// and the values must be URIs that do not have the `package:` scheme. -void write(StringSink output, Map packageMapping, - {Uri baseUri, String comment, bool allowDefaultPackage = false}) { - ArgumentError.checkNotNull(allowDefaultPackage, 'allowDefaultPackage'); - - if (baseUri != null && !baseUri.isAbsolute) { - throw ArgumentError.value(baseUri, "baseUri", "Must be absolute"); - } - - if (comment != null) { - var lines = comment.split('\n'); - if (lines.last.isEmpty) lines.removeLast(); - for (var commentLine in lines) { - output.write('# '); - output.writeln(commentLine); - } - } else { - output.write("# generated by package:package_config at "); - output.write(DateTime.now()); - output.writeln(); - } - - packageMapping.forEach((String packageName, Uri uri) { - // If [packageName] is empty then [uri] is the _default package name_. - if (allowDefaultPackage && packageName.isEmpty) { - final defaultPackageName = uri.toString(); - if (!isValidPackageName(defaultPackageName)) { - throw ArgumentError.value( - defaultPackageName, - 'defaultPackageName', - '"$defaultPackageName" is not a valid package name', - ); - } - output.write(':'); - output.write(defaultPackageName); - output.writeln(); - return; - } - // Validate packageName. - if (!isValidPackageName(packageName)) { - throw ArgumentError('"$packageName" is not a valid package name'); - } - if (uri.scheme == "package") { - throw ArgumentError.value( - "Package location must not be a package: URI", uri.toString()); - } - output.write(packageName); - output.write(':'); - // If baseUri provided, make uri relative. - if (baseUri != null) { - uri = _relativize(uri, baseUri); - } - if (!uri.path.endsWith('/')) { - uri = uri.replace(path: uri.path + '/'); - } - output.write(uri); - output.writeln(); - }); -} - -/// Attempts to return a relative URI for [uri]. -/// -/// The result URI satisfies `baseUri.resolveUri(result) == uri`, -/// but may be relative. -/// The `baseUri` must be absolute. -Uri _relativize(Uri uri, Uri baseUri) { - assert(baseUri.isAbsolute); - if (uri.hasQuery || uri.hasFragment) { - uri = Uri( - scheme: uri.scheme, - userInfo: uri.hasAuthority ? uri.userInfo : null, - host: uri.hasAuthority ? uri.host : null, - port: uri.hasAuthority ? uri.port : null, - path: uri.path); - } - - // Already relative. We assume the caller knows what they are doing. - if (!uri.isAbsolute) return uri; - - if (baseUri.scheme != uri.scheme) { - return uri; - } - - // If authority differs, we could remove the scheme, but it's not worth it. - if (uri.hasAuthority != baseUri.hasAuthority) return uri; - if (uri.hasAuthority) { - if (uri.userInfo != baseUri.userInfo || - uri.host.toLowerCase() != baseUri.host.toLowerCase() || - uri.port != baseUri.port) { - return uri; - } - } - - baseUri = baseUri.normalizePath(); - var base = baseUri.pathSegments.toList(); - if (base.isNotEmpty) { - base = List.from(base)..removeLast(); - } - uri = uri.normalizePath(); - var target = uri.pathSegments.toList(); - if (target.isNotEmpty && target.last.isEmpty) target.removeLast(); - var index = 0; - while (index < base.length && index < target.length) { - if (base[index] != target[index]) { - break; - } - index++; - } - if (index == base.length) { - if (index == target.length) { - return Uri(path: "./"); - } - return Uri(path: target.skip(index).join('/')); - } else if (index > 0) { - return Uri( - path: '../' * (base.length - index) + target.skip(index).join('/')); - } else { - return uri; - } -} diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index 8ac6a0128..a3e01d710 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -32,7 +32,7 @@ final Uri parentPath = Uri(path: ".."); /// If any of these tests succeed, a `PackageConfig` class is returned. /// Returns `null` if no configuration was found. If a configuration /// is needed, then the caller can supply [PackageConfig.empty]. -Future findPackageConfig( +Future findPackageConfig( Directory baseDirectory, bool recursive, void onError(Object error)) async { var directory = baseDirectory; if (!directory.isAbsolute) directory = directory.absolute; @@ -53,10 +53,10 @@ Future findPackageConfig( } /// Similar to [findPackageConfig] but based on a URI. -Future findPackageConfigUri( +Future findPackageConfigUri( Uri location, - Future loader(Uri uri) /*?*/, - void onError(Object error) /*?*/, + Future loader(Uri uri)?, + void onError(Object error), bool recursive) async { if (location.isScheme("package")) { onError(PackageConfigArgumentError( @@ -102,7 +102,7 @@ Future findPackageConfigUri( /// If [onError] is supplied, parsing errors are reported using that, and /// a best-effort attempt is made to return a package configuration. /// This may be the empty package configuration. -Future findPackagConfigInDirectory( +Future findPackagConfigInDirectory( Directory directory, void onError(Object error)) async { var packageConfigFile = await checkForPackageConfigJsonFile(directory); if (packageConfigFile != null) { @@ -115,7 +115,7 @@ Future findPackagConfigInDirectory( return null; } -Future /*?*/ checkForPackageConfigJsonFile(Directory directory) async { +Future checkForPackageConfigJsonFile(Directory directory) async { assert(directory.isAbsolute); var file = File(pathJoin(directory.path, ".dart_tool", "package_config.json")); @@ -123,7 +123,7 @@ Future /*?*/ checkForPackageConfigJsonFile(Directory directory) async { return null; } -Future checkForDotPackagesFile(Directory directory) async { +Future checkForDotPackagesFile(Directory directory) async { var file = File(pathJoin(directory.path, ".packages")); if (await file.exists()) return file; return null; diff --git a/pkgs/package_config/lib/src/errors.dart b/pkgs/package_config/lib/src/errors.dart index c9736177c..f3515711d 100644 --- a/pkgs/package_config/lib/src/errors.dart +++ b/pkgs/package_config/lib/src/errors.dart @@ -12,7 +12,7 @@ abstract class PackageConfigError { class PackageConfigArgumentError extends ArgumentError implements PackageConfigError { - PackageConfigArgumentError(Object /*?*/ value, String name, String message) + PackageConfigArgumentError(Object? value, String name, String message) : super.value(value, name, message); PackageConfigArgumentError.from(ArgumentError error) @@ -21,8 +21,7 @@ class PackageConfigArgumentError extends ArgumentError class PackageConfigFormatException extends FormatException implements PackageConfigError { - PackageConfigFormatException(String message, Object /*?*/ source, - [int /*?*/ offset]) + PackageConfigFormatException(String message, Object? source, [int? offset]) : super(message, source, offset); PackageConfigFormatException.from(FormatException exception) @@ -30,4 +29,4 @@ class PackageConfigFormatException extends FormatException } /// The default `onError` handler. -void /*Never*/ throwError(Object error) => throw error; +Never throwError(Object error) => throw error; diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 30c758a96..63d01eacd 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -50,7 +50,7 @@ abstract class PackageConfig { /// [PackageConfig.extraData] of the created configuration. /// /// The version of the resulting configuration is always [maxVersion]. - factory PackageConfig(Iterable packages, {dynamic extraData}) => + factory PackageConfig(Iterable packages, {Object? extraData}) => SimplePackageConfig(maxVersion, packages, extraData); /// Parses a package configuration file. @@ -67,10 +67,10 @@ abstract class PackageConfig { /// the configuration are reported by calling [onError] instead of /// throwing, and parser makes a *best effort* attempt to continue /// despite the error. The input must still be valid JSON. - /// The result may be a [PackageConfig.empty] if there is no way to + /// The result may be [PackageConfig.empty] if there is no way to /// extract useful information from the bytes. static PackageConfig parseBytes(Uint8List bytes, Uri baseUri, - {void onError(Object error)}) => + {void onError(Object error)?}) => parsePackageConfigBytes(bytes, baseUri, onError ?? throwError); /// Parses a package configuration file. @@ -87,10 +87,10 @@ abstract class PackageConfig { /// the configuration are reported by calling [onError] instead of /// throwing, and parser makes a *best effort* attempt to continue /// despite the error. The input must still be valid JSON. - /// The result may be a [PackageConfig.empty] if there is no way to + /// The result may be [PackageConfig.empty] if there is no way to /// extract useful information from the bytes. static PackageConfig parseString(String configuration, Uri baseUri, - {void onError(Object error)}) => + {void onError(Object error)?}) => parsePackageConfigString(configuration, baseUri, onError ?? throwError); /// Parses the JSON data of a package configuration file. @@ -108,10 +108,10 @@ abstract class PackageConfig { /// the configuration are reported by calling [onError] instead of /// throwing, and parser makes a *best effort* attempt to continue /// despite the error. The input must still be valid JSON. - /// The result may be a [PackageConfig.empty] if there is no way to + /// The result may be [PackageConfig.empty] if there is no way to /// extract useful information from the bytes. - static PackageConfig parseJson(dynamic jsonData, Uri baseUri, - {void onError(Object error)}) => + static PackageConfig parseJson(Object? jsonData, Uri baseUri, + {void onError(Object error)?}) => parsePackageConfigJson(jsonData, baseUri, onError ?? throwError); /// Writes a configuration file for this configuration on [output]. @@ -119,7 +119,7 @@ abstract class PackageConfig { /// If [baseUri] is provided, URI references in the generated file /// will be made relative to [baseUri] where possible. static void writeBytes(PackageConfig configuration, Sink output, - [Uri /*?*/ baseUri]) { + [Uri? baseUri]) { writePackageConfigJsonUtf8(configuration, baseUri, output); } @@ -128,7 +128,7 @@ abstract class PackageConfig { /// If [baseUri] is provided, URI references in the generated file /// will be made relative to [baseUri] where possible. static void writeString(PackageConfig configuration, StringSink output, - [Uri /*?*/ baseUri]) { + [Uri? baseUri]) { writePackageConfigJsonString(configuration, baseUri, output); } @@ -136,8 +136,8 @@ abstract class PackageConfig { /// /// If [baseUri] is provided, URI references in the generated data /// will be made relative to [baseUri] where possible. - static Map toJson(PackageConfig configuration, - [Uri /*?*/ baseUri]) => + static Map toJson(PackageConfig configuration, + [Uri? baseUri]) => packageConfigToJson(configuration, baseUri); /// The configuration version number. @@ -162,7 +162,7 @@ abstract class PackageConfig { /// Returns the [Package] fron [packages] with [packageName] as /// [Package.name]. Returns `null` if the package is not available in the /// current configuration. - Package /*?*/ operator [](String packageName); + Package? operator [](String packageName); /// Provides the associated package for a specific [file] (or directory). /// @@ -171,7 +171,7 @@ abstract class PackageConfig { /// of the [file]'s location. /// /// Returns `null` if the file does not belong to any package. - Package /*?*/ packageOf(Uri file); + Package? packageOf(Uri file); /// Resolves a `package:` URI to a non-package URI /// @@ -188,7 +188,7 @@ abstract class PackageConfig { /// in this package configuration. /// Returns the remaining path of the package URI resolved relative to the /// [Package.packageUriRoot] of the corresponding package. - Uri /*?*/ resolve(Uri packageUri); + Uri? resolve(Uri packageUri); /// The package URI which resolves to [nonPackageUri]. /// @@ -199,14 +199,14 @@ abstract class PackageConfig { /// /// Returns a package URI which [resolve] will convert to [nonPackageUri], /// if any such URI exists. Returns `null` if no such package URI exists. - Uri /*?*/ toPackageUri(Uri nonPackageUri); + Uri? toPackageUri(Uri nonPackageUri); /// Extra data associated with the package configuration. /// /// The data may be in any format, depending on who introduced it. /// The standard `packjage_config.json` file storage will only store /// JSON-like list/map data structures. - dynamic get extraData; + Object? get extraData; } /// Configuration data for a single package. @@ -227,11 +227,11 @@ abstract class Package { /// If [extraData] is supplied, it will be available as the /// [Package.extraData] of the created package. factory Package(String name, Uri root, - {Uri /*?*/ packageUriRoot, - LanguageVersion /*?*/ languageVersion, - dynamic extraData}) => + {Uri? packageUriRoot, + LanguageVersion? languageVersion, + Object? extraData}) => SimplePackage.validate( - name, root, packageUriRoot, languageVersion, extraData, throwError); + name, root, packageUriRoot, languageVersion, extraData, throwError)!; /// The package-name of the package. String get name; @@ -263,14 +263,18 @@ abstract class Package { /// Dart files in the package. /// A package version is defined by two non-negative numbers, /// the *major* and *minor* version numbers. - LanguageVersion /*?*/ get languageVersion; + /// + /// A package may have no language version associated with it + /// in the package configuration, in which case tools should + /// use a default behavior for the package. + LanguageVersion? get languageVersion; /// Extra data associated with the specific package. /// /// The data may be in any format, depending on who introduced it. - /// The standard `packjage_config.json` file storage will only store + /// The standard `package_config.json` file storage will only store /// JSON-like list/map data structures. - dynamic get extraData; + Object? get extraData; } /// A language version. @@ -307,7 +311,7 @@ abstract class LanguageVersion implements Comparable { /// If [onError] is not supplied, it defaults to throwing the exception. /// If the call does not throw, then an [InvalidLanguageVersion] is returned /// containing the original [source]. - static LanguageVersion parse(String source, {void onError(Object error)}) => + static LanguageVersion parse(String source, {void onError(Object error)?}) => parseLanguageVersion(source, onError ?? throwError); /// The major language version. diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 9e23af063..5c6b7f728 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -14,10 +14,10 @@ class SimplePackageConfig implements PackageConfig { final int version; final Map _packages; final PackageTree _packageTree; - final dynamic extraData; + final Object? extraData; factory SimplePackageConfig(int version, Iterable packages, - [dynamic extraData, void onError(Object error)]) { + [Object? extraData, void onError(Object error)?]) { onError ??= throwError; var validVersion = _validateVersion(version, onError); var sortedPackages = [...packages]..sort(_compareRoot); @@ -53,11 +53,7 @@ class SimplePackageConfig implements PackageConfig { var packageNames = {}; var tree = MutablePackageTree(); for (var originalPackage in packages) { - if (originalPackage == null) { - onError(ArgumentError.notNull("element of packages")); - continue; - } - SimplePackage package; + SimplePackage? package; if (originalPackage is! SimplePackage) { // SimplePackage validates these properties. package = SimplePackage.validate( @@ -68,7 +64,7 @@ class SimplePackageConfig implements PackageConfig { originalPackage.extraData, (error) { if (error is PackageConfigArgumentError) { onError(PackageConfigArgumentError(packages, "packages", - "Package ${package.name}: ${error.message}")); + "Package ${package!.name}: ${error.message}")); } else { onError(error); } @@ -92,7 +88,7 @@ class SimplePackageConfig implements PackageConfig { onError(PackageConfigArgumentError( originalPackages, "packages", - "Packages ${package.name} and ${existingPackage.name} " + "Packages ${package!.name} and ${existingPackage.name} " "have the same root directory: ${package.root}.\n")); } else { assert(error.isPackageRootConflict); @@ -100,7 +96,7 @@ class SimplePackageConfig implements PackageConfig { onError(PackageConfigArgumentError( originalPackages, "packages", - "Package ${package.name} is inside the package URI root of " + "Package ${package!.name} is inside the package URI root of " "package ${existingPackage.name}.\n" "${existingPackage.name} URI root: " "${existingPackage.packageUriRoot}\n" @@ -117,7 +113,7 @@ class SimplePackageConfig implements PackageConfig { Iterable get packages => _packages.values; - Package /*?*/ operator [](String packageName) => _packages[packageName]; + Package? operator [](String packageName) => _packages[packageName]; /// Provides the associated package for a specific [file] (or directory). /// @@ -125,15 +121,15 @@ class SimplePackageConfig implements PackageConfig { /// That is, the [Package.rootUri] directory is a parent directory /// of the [file]'s location. /// Returns `null` if the file does not belong to any package. - Package /*?*/ packageOf(Uri file) => _packageTree.packageOf(file); + Package? packageOf(Uri file) => _packageTree.packageOf(file); - Uri /*?*/ resolve(Uri packageUri) { + Uri? resolve(Uri packageUri) { var packageName = checkValidPackageUri(packageUri, "packageUri"); - return _packages[packageName]?.packageUriRoot?.resolveUri( + return _packages[packageName]?.packageUriRoot.resolveUri( Uri(path: packageUri.path.substring(packageName.length + 1))); } - Uri /*?*/ toPackageUri(Uri nonPackageUri) { + Uri? toPackageUri(Uri nonPackageUri) { if (nonPackageUri.isScheme("package")) { throw PackageConfigArgumentError( nonPackageUri, "nonPackageUri", "Must not be a package URI"); @@ -161,8 +157,8 @@ class SimplePackage implements Package { final String name; final Uri root; final Uri packageUriRoot; - final LanguageVersion /*?*/ languageVersion; - final dynamic extraData; + final LanguageVersion? languageVersion; + final Object? extraData; SimplePackage._(this.name, this.root, this.packageUriRoot, this.languageVersion, this.extraData); @@ -182,12 +178,12 @@ class SimplePackage implements Package { /// /// Returns `null` if the input is invalid and an approximately valid package /// cannot be salvaged from the input. - static SimplePackage /*?*/ validate( + static SimplePackage? validate( String name, Uri root, - Uri packageUriRoot, - LanguageVersion /*?*/ languageVersion, - dynamic extraData, + Uri? packageUriRoot, + LanguageVersion? languageVersion, + Object? extraData, void onError(Object error)) { var fatalError = false; var invalidIndex = checkPackageName(name); @@ -244,7 +240,7 @@ class SimplePackage implements Package { /// Reports a format exception on [onError] if not, or if the numbers /// are too large (at most 32-bit signed integers). LanguageVersion parseLanguageVersion( - String source, void onError(Object error)) { + String? source, void onError(Object error)) { var index = 0; // Reads a positive decimal numeral. Returns the value of the numeral, // or a negative number in case of an error. @@ -254,7 +250,7 @@ LanguageVersion parseLanguageVersion( // It is a recoverable error if the numeral starts with leading zeros. int readNumeral() { const maxValue = 0x7FFFFFFF; - if (index == source.length) { + if (index == source!.length) { onError(PackageConfigFormatException("Missing number", source, index)); return -1; } @@ -291,7 +287,7 @@ LanguageVersion parseLanguageVersion( if (major < 0) { return SimpleInvalidLanguageVersion(source); } - if (index == source.length || source.codeUnitAt(index) != $dot) { + if (index == source!.length || source.codeUnitAt(index) != $dot) { onError(PackageConfigFormatException("Missing '.'", source, index)); return SimpleInvalidLanguageVersion(source); } @@ -319,7 +315,7 @@ abstract class _SimpleLanguageVersionBase implements LanguageVersion { class SimpleLanguageVersion extends _SimpleLanguageVersionBase { final int major; final int minor; - String /*?*/ _source; + String? _source; SimpleLanguageVersion(this.major, this.minor, this._source); bool operator ==(Object other) => @@ -332,17 +328,17 @@ class SimpleLanguageVersion extends _SimpleLanguageVersionBase { class SimpleInvalidLanguageVersion extends _SimpleLanguageVersionBase implements InvalidLanguageVersion { - final String _source; + final String? _source; SimpleInvalidLanguageVersion(this._source); int get major => -1; int get minor => -1; - String toString() => _source; + String toString() => _source!; } abstract class PackageTree { Iterable get allPackages; - SimplePackage /*?*/ packageOf(Uri file); + SimplePackage? packageOf(Uri file); } /// Packages of a package configuration ordered by root path. @@ -373,12 +369,17 @@ class MutablePackageTree implements PackageTree { /// Indexed by [Package.name]. /// If a package has no nested packages (which is most often the case), /// there is no tree object associated with it. - Map /*?*/ _packageChildren; + Map? _packageChildren; Iterable get allPackages sync* { - for (var package in packages) yield package; - if (_packageChildren != null) { - for (var tree in _packageChildren.values) yield* tree.allPackages; + for (var package in packages) { + yield package; + } + var children = _packageChildren; + if (children != null) { + for (var tree in children.values) { + yield* tree.allPackages; + } } } @@ -424,7 +425,7 @@ class MutablePackageTree implements PackageTree { packages.add(package); } - SimplePackage /*?*/ packageOf(Uri file) { + SimplePackage? packageOf(Uri file) { return findPackageOf(0, file.toString()); } @@ -434,7 +435,7 @@ class MutablePackageTree implements PackageTree { /// /// Assumes the first [start] characters of path agrees with all /// the packages at this level of the tree. - SimplePackage /*?*/ findPackageOf(int start, String path) { + SimplePackage? findPackageOf(int start, String path) { for (var childPackage in packages) { var childPath = childPackage.root.toString(); if (_beginsWith(start, childPath, path)) { @@ -447,14 +448,9 @@ class MutablePackageTree implements PackageTree { _beginsWith(childPathLength, uriRoot, path)) { return childPackage; } - // Otherwise add [package] as child of [childPackage]. - // TODO(lrn): When NNBD comes, convert to: - // return _packageChildren?[childPackage.name] - // ?.packageOf(childPathLength, path) ?? childPackage; - if (_packageChildren == null) return childPackage; - var childTree = _packageChildren[childPackage.name]; - if (childTree == null) return childPackage; - return childTree.findPackageOf(childPathLength, path) ?? childPackage; + return _packageChildren?[childPackage.name] + ?.findPackageOf(childPathLength, path) ?? + childPackage; } } return null; @@ -474,7 +470,7 @@ class EmptyPackageTree implements PackageTree { Iterable get allPackages => const Iterable.empty(); - SimplePackage packageOf(Uri file) => null; + SimplePackage? packageOf(Uri file) => null; } /// Checks whether [longerPath] begins with [parentPath]. diff --git a/pkgs/package_config/lib/src/package_config_io.dart b/pkgs/package_config/lib/src/package_config_io.dart index bfbb1e373..d3e59be47 100644 --- a/pkgs/package_config/lib/src/package_config_io.dart +++ b/pkgs/package_config/lib/src/package_config_io.dart @@ -15,6 +15,21 @@ import "packages_file.dart" as packages_file; import "util.dart"; import "util_io.dart"; +/// Name of directory where Dart tools store their configuration. +/// +/// Directory is created in the package root directory. +const dartToolDirName = ".dart_tool"; + +/// Name of file containing new package configuration data. +/// +/// File is stored in the dart tool directory. +const packageConfigFileName = "package_config.json"; + +/// Name of file containing legacy package configuration data. +/// +/// File is stored in the package root directory. +const packagesFileName = ".packages"; + /// Reads a package configuration file. /// /// Detects whether the [file] is a version one `.packages` file or @@ -29,9 +44,9 @@ import "util_io.dart"; /// The file must exist and be a normal file. Future readAnyConfigFile( File file, bool preferNewest, void onError(Object error)) async { - if (preferNewest && fileName(file.path) == ".packages") { - var alternateFile = - File(pathJoin(dirName(file.path), ".dart_tool", "package_config.json")); + if (preferNewest && fileName(file.path) == packagesFileName) { + var alternateFile = File( + pathJoin(dirName(file.path), dartToolDirName, packageConfigFileName)); if (alternateFile.existsSync()) { return await readPackageConfigJsonFile(alternateFile, onError); } @@ -49,7 +64,7 @@ Future readAnyConfigFile( /// Like [readAnyConfigFile] but uses a URI and an optional loader. Future readAnyConfigFileUri( Uri file, - Future loader(Uri uri) /*?*/, + Future loader(Uri uri)?, void onError(Object error), bool preferNewest) async { if (file.isScheme("package")) { @@ -62,9 +77,9 @@ Future readAnyConfigFileUri( } loader = defaultLoader; } - if (preferNewest && file.pathSegments.last == ".packages") { - var alternateFile = file.resolve(".dart_tool/package_config.json"); - Uint8List /*?*/ bytes; + if (preferNewest && file.pathSegments.last == packagesFileName) { + var alternateFile = file.resolve("$dartToolDirName/$packageConfigFileName"); + Uint8List? bytes; try { bytes = await loader(alternateFile); } catch (e) { @@ -75,7 +90,7 @@ Future readAnyConfigFileUri( return parsePackageConfigBytes(bytes, alternateFile, onError); } } - Uint8List /*?*/ bytes; + Uint8List? bytes; try { bytes = await loader(file); } catch (e) { @@ -131,15 +146,17 @@ Future readDotPackagesFile( Future writePackageConfigJsonFile( PackageConfig config, Directory targetDirectory) async { // Write .dart_tool/package_config.json first. - var file = - File(pathJoin(targetDirectory.path, ".dart_tool", "package_config.json")); + var dartToolDir = Directory(pathJoin(targetDirectory.path, dartToolDirName)); + await dartToolDir.create(recursive: true); + var file = File(pathJoin(dartToolDir.path, packageConfigFileName)); var baseUri = file.uri; + var sink = file.openWrite(encoding: utf8); writePackageConfigJsonUtf8(config, baseUri, sink); var doneJson = sink.close(); // Write .packages too. - file = File(pathJoin(targetDirectory.path, ".packages")); + file = File(pathJoin(targetDirectory.path, packagesFileName)); baseUri = file.uri; sink = file.openWrite(encoding: utf8); writeDotPackages(config, baseUri, sink); diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index 27abf505c..25b04c4d1 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -59,10 +59,10 @@ PackageConfig parsePackageConfigString( /// Creates a [PackageConfig] from a parsed JSON-like object structure. /// -/// The [json] argument must be a JSON object (`Map`) +/// The [json] argument must be a JSON object (`Map`) /// containing a `"configVersion"` entry with an integer value in the range /// 1 to [PackageConfig.maxVersion], -/// and with a `"packages"` entry which is a JSON array (`List`) +/// and with a `"packages"` entry which is a JSON array (`List`) /// containing JSON objects which each has the following properties: /// /// * `"name"`: The package name as a string. @@ -80,7 +80,7 @@ PackageConfig parsePackageConfigString( /// The [baseLocation] is used as base URI to resolve the "rootUri" /// URI referencestring. PackageConfig parsePackageConfigJson( - dynamic json, Uri baseLocation, void onError(Object error)) { + Object? json, Uri baseLocation, void onError(Object error)) { if (!baseLocation.hasScheme || baseLocation.isScheme("package")) { throw PackageConfigArgumentError(baseLocation.toString(), "baseLocation", "Must be an absolute non-package: URI"); @@ -97,10 +97,10 @@ PackageConfig parsePackageConfigJson( return "object"; } - T checkType(dynamic value, String name, [String /*?*/ packageName]) { + T? checkType(Object? value, String name, [String? packageName]) { if (value is T) return value; - // The only types we are called with are [int], [String], [List] - // and Map. Recognize which to give a better error message. + // The only types we are called with are [int], [String], [List] + // and Map. Recognize which to give a better error message. var message = "$name${packageName != null ? " of package $packageName" : ""}" " is not a JSON ${typeName()}"; @@ -108,12 +108,12 @@ PackageConfig parsePackageConfigJson( return null; } - Package /*?*/ parsePackage(Map entry) { - String /*?*/ name; - String /*?*/ rootUri; - String /*?*/ packageUri; - String /*?*/ languageVersion; - Map /*?*/ extraData; + Package? parsePackage(Map entry) { + String? name; + String? rootUri; + String? packageUri; + String? languageVersion; + Map? extraData; var hasName = false; var hasRoot = false; var hasVersion = false; @@ -146,22 +146,22 @@ PackageConfig parsePackageConfigJson( onError(PackageConfigFormatException("Missing rootUri entry", entry)); } if (name == null || rootUri == null) return null; - var root = baseLocation.resolve(rootUri); + var root = baseLocation.resolve(rootUri!); if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/"); var packageRoot = root; - if (packageUri != null) packageRoot = root.resolve(packageUri); + if (packageUri != null) packageRoot = root.resolve(packageUri!); if (!packageRoot.path.endsWith("/")) { packageRoot = packageRoot.replace(path: packageRoot.path + "/"); } - LanguageVersion /*?*/ version; + LanguageVersion? version; if (languageVersion != null) { version = parseLanguageVersion(languageVersion, onError); } else if (hasVersion) { version = SimpleInvalidLanguageVersion("invalid"); } - return SimplePackage.validate(name, root, packageRoot, version, extraData, + return SimplePackage.validate(name!, root, packageRoot, version, extraData, (error) { if (error is ArgumentError) { onError( @@ -172,22 +172,22 @@ PackageConfig parsePackageConfigJson( }); } - var map = checkType>(json, "value"); + var map = checkType>(json, "value"); if (map == null) return const SimplePackageConfig.empty(); - Map /*?*/ extraData; - List /*?*/ packageList; - int /*?*/ configVersion; + Map? extraData; + List? packageList; + int? configVersion; map.forEach((key, value) { switch (key) { case _configVersionKey: configVersion = checkType(value, _configVersionKey) ?? 2; break; case _packagesKey: - var packageArray = checkType>(value, _packagesKey) ?? []; + var packageArray = checkType>(value, _packagesKey) ?? []; var packages = []; for (var package in packageArray) { var packageMap = - checkType>(package, "package entry"); + checkType>(package, "package entry"); if (packageMap != null) { var entry = parsePackage(packageMap); if (entry != null) { @@ -210,7 +210,7 @@ PackageConfig parsePackageConfigJson( onError(PackageConfigFormatException("Missing packages list", json)); packageList = []; } - return SimplePackageConfig(configVersion, packageList, extraData, (error) { + return SimplePackageConfig(configVersion!, packageList!, extraData, (error) { if (error is ArgumentError) { onError(PackageConfigFormatException(error.message, error.invalidValue)); } else { @@ -222,26 +222,26 @@ PackageConfig parsePackageConfigJson( final _jsonUtf8Encoder = JsonUtf8Encoder(" "); void writePackageConfigJsonUtf8( - PackageConfig config, Uri baseUri, Sink> output) { + PackageConfig config, Uri? baseUri, Sink> output) { // Can be optimized. var data = packageConfigToJson(config, baseUri); output.add(_jsonUtf8Encoder.convert(data) as Uint8List); } void writePackageConfigJsonString( - PackageConfig config, Uri baseUri, StringSink output) { + PackageConfig config, Uri? baseUri, StringSink output) { // Can be optimized. var data = packageConfigToJson(config, baseUri); output.write(JsonEncoder.withIndent(" ").convert(data) as Uint8List); } -Map packageConfigToJson(PackageConfig config, Uri baseUri) => - { +Map packageConfigToJson(PackageConfig config, Uri? baseUri) => + { ...?_extractExtraData(config.extraData, _topNames), _configVersionKey: PackageConfig.maxVersion, _packagesKey: [ for (var package in config.packages) - { + { _nameKey: package.name, _rootUriKey: relativizeUri(package.root, baseUri).toString(), if (package.root != package.packageUriRoot) @@ -259,15 +259,15 @@ Map packageConfigToJson(PackageConfig config, Uri baseUri) => void writeDotPackages(PackageConfig config, Uri baseUri, StringSink output) { var extraData = config.extraData; // Write .packages too. - String /*?*/ comment; - if (extraData != null) { - String /*?*/ generator = extraData[_generatorKey]; - if (generator != null) { - String /*?*/ generated = extraData[_generatedKey]; - String /*?*/ generatorVersion = extraData[_generatorVersionKey]; + String? comment; + if (extraData is Map) { + var generator = extraData[_generatorKey]; + if (generator is String) { + var generated = extraData[_generatedKey]; + var generatorVersion = extraData[_generatorVersionKey]; comment = "Generated by $generator" - "${generatorVersion != null ? " $generatorVersion" : ""}" - "${generated != null ? " on $generated" : ""}."; + "${generatorVersion is String ? " $generatorVersion" : ""}" + "${generated is String ? " on $generated" : ""}."; } } packages_file.write(output, config, baseUri: baseUri, comment: comment); @@ -277,20 +277,21 @@ void writeDotPackages(PackageConfig config, Uri baseUri, StringSink output) { /// /// If the value contains any of the [reservedNames] for the current context, /// entries with that name in the extra data are dropped. -Map /*?*/ _extractExtraData( - dynamic data, Iterable reservedNames) { - if (data is Map) { +Map? _extractExtraData( + Object? data, Iterable reservedNames) { + if (data is Map) { if (data.isEmpty) return null; for (var name in reservedNames) { if (data.containsKey(name)) { - data = { + var filteredData = { for (var key in data.keys) if (!reservedNames.contains(key)) key: data[key] }; - if (data.isEmpty) return null; - for (var value in data.values) { + if (filteredData.isEmpty) return null; + for (var value in filteredData.values) { if (!_validateJson(value)) return null; } + return filteredData; } } return data; @@ -299,13 +300,13 @@ Map /*?*/ _extractExtraData( } /// Checks that the object is a valid JSON-like data structure. -bool _validateJson(dynamic object) { +bool _validateJson(Object? object) { if (object == null || true == object || false == object) return true; if (object is num || object is String) return true; - if (object is List) { + if (object is List) { return object.every(_validateJson); } - if (object is Map) { + if (object is Map) { return object.values.every(_validateJson); } return false; diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index 184b0dd04..071d548a5 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -154,7 +154,7 @@ PackageConfig parse( /// All the keys of [packageMapping] must be valid package names, /// and the values must be URIs that do not have the `package:` scheme. void write(StringSink output, PackageConfig config, - {Uri baseUri, String comment}) { + {Uri? baseUri, String? comment}) { if (baseUri != null && !baseUri.isAbsolute) { throw PackageConfigArgumentError(baseUri, "baseUri", "Must be absolute"); } @@ -187,7 +187,7 @@ void write(StringSink output, PackageConfig config, output.write(':'); // If baseUri is provided, make the URI relative to baseUri. if (baseUri != null) { - uri = relativizeUri(uri, baseUri); + uri = relativizeUri(uri, baseUri)!; } if (!uri.path.endsWith('/')) { uri = uri.replace(path: uri.path + '/'); diff --git a/pkgs/package_config/lib/src/packages_impl.dart b/pkgs/package_config/lib/src/packages_impl.dart deleted file mode 100644 index 19f103922..000000000 --- a/pkgs/package_config/lib/src/packages_impl.dart +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2015, 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. - -/// Implementations of [Packages] that may be used in either server or browser -/// based applications. For implementations that can only run in the browser, -/// see [package_config.packages_io_impl]. -@Deprecated("Use the package_config.json based API") -library package_config.packages_impl; - -import "dart:collection" show UnmodifiableMapView; - -import "../packages.dart"; -import "util.dart" show checkValidPackageUri; - -/// A [Packages] null-object. -class NoPackages implements Packages { - const NoPackages(); - - Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { - var packageName = checkValidPackageUri(packageUri, "packageUri"); - if (notFound != null) return notFound(packageUri); - throw ArgumentError.value( - packageUri, "packageUri", 'No package named "$packageName"'); - } - - Iterable get packages => Iterable.empty(); - - Map asMap() => const {}; - - String get defaultPackageName => null; - - String packageMetadata(String packageName, String key) => null; - - String libraryMetadata(Uri libraryUri, String key) => null; -} - -/// Base class for [Packages] implementations. -/// -/// This class implements the [resolve] method in terms of a private -/// member -abstract class PackagesBase implements Packages { - Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) { - packageUri = packageUri.normalizePath(); - var packageName = checkValidPackageUri(packageUri, "packageUri"); - var packageBase = getBase(packageName); - if (packageBase == null) { - if (notFound != null) return notFound(packageUri); - throw ArgumentError.value( - packageUri, "packageUri", 'No package named "$packageName"'); - } - var packagePath = packageUri.path.substring(packageName.length + 1); - return packageBase.resolve(packagePath); - } - - /// Find a base location for a package name. - /// - /// Returns `null` if no package exists with that name, and that can be - /// determined. - Uri getBase(String packageName); - - String get defaultPackageName => null; - - String packageMetadata(String packageName, String key) => null; - - String libraryMetadata(Uri libraryUri, String key) => null; -} - -/// A [Packages] implementation based on an existing map. -class MapPackages extends PackagesBase { - final Map _mapping; - MapPackages(this._mapping); - - Uri getBase(String packageName) => - packageName.isEmpty ? null : _mapping[packageName]; - - Iterable get packages => _mapping.keys; - - Map asMap() => UnmodifiableMapView(_mapping); - - String get defaultPackageName => _mapping[""]?.toString(); - - String packageMetadata(String packageName, String key) { - if (packageName.isEmpty) return null; - var uri = _mapping[packageName]; - if (uri == null || !uri.hasFragment) return null; - // This can be optimized, either by caching the map or by - // parsing incrementally instead of parsing the entire fragment. - return Uri.splitQueryString(uri.fragment)[key]; - } - - String libraryMetadata(Uri libraryUri, String key) { - if (libraryUri.isScheme("package")) { - return packageMetadata(libraryUri.pathSegments.first, key); - } - var defaultPackageNameUri = _mapping[""]; - if (defaultPackageNameUri != null) { - return packageMetadata(defaultPackageNameUri.toString(), key); - } - return null; - } -} - -/// A [Packages] implementation based on a remote (e.g., HTTP) directory. -/// -/// There is no way to detect which packages exist short of trying to use -/// them. You can't necessarily check whether a directory exists, -/// except by checking for a know file in the directory. -class NonFilePackagesDirectoryPackages extends PackagesBase { - final Uri _packageBase; - NonFilePackagesDirectoryPackages(this._packageBase); - - Uri getBase(String packageName) => _packageBase.resolve("$packageName/"); - - Error _failListingPackages() { - return UnsupportedError( - "Cannot list packages for a ${_packageBase.scheme}: " - "based package root"); - } - - Iterable get packages { - throw _failListingPackages(); - } - - Map asMap() { - throw _failListingPackages(); - } -} diff --git a/pkgs/package_config/lib/src/packages_io_impl.dart b/pkgs/package_config/lib/src/packages_io_impl.dart deleted file mode 100644 index c623f4d5d..000000000 --- a/pkgs/package_config/lib/src/packages_io_impl.dart +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2015, 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. - -/// Implementations of [Packages] that can only be used in server based -/// applications. -@Deprecated("Use the package_config.json based API") -library package_config.packages_io_impl; - -import "dart:collection" show UnmodifiableMapView; -import "dart:io" show Directory; - -import "packages_impl.dart"; - -import "util_io.dart"; - -/// A [Packages] implementation based on a local directory. -class FilePackagesDirectoryPackages extends PackagesBase { - final Directory _packageDir; - final Map _packageToBaseUriMap = {}; - - FilePackagesDirectoryPackages(this._packageDir); - - Uri getBase(String packageName) { - return _packageToBaseUriMap.putIfAbsent(packageName, () { - return Uri.file(pathJoin(_packageDir.path, packageName, '.')); - }); - } - - Iterable _listPackageNames() { - return _packageDir - .listSync() - .whereType() - .map((e) => fileName(e.path)); - } - - Iterable get packages => _listPackageNames(); - - Map asMap() { - var result = {}; - for (var packageName in _listPackageNames()) { - result[packageName] = getBase(packageName); - } - return UnmodifiableMapView(result); - } -} diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 50b140fa0..9b263ae7a 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -153,10 +153,10 @@ int firstNonWhitespaceChar(List bytes) { /// `baseUri.resolveUri(result) == uri`, /// /// The `baseUri` must be absolute. -Uri relativizeUri(Uri uri, Uri /*?*/ baseUri) { +Uri? relativizeUri(Uri? uri, Uri? baseUri) { if (baseUri == null) return uri; assert(baseUri.isAbsolute); - if (uri.hasQuery || uri.hasFragment) { + if (uri!.hasQuery || uri.hasFragment) { uri = Uri( scheme: uri.scheme, userInfo: uri.hasAuthority ? uri.userInfo : null, diff --git a/pkgs/package_config/lib/src/util_io.dart b/pkgs/package_config/lib/src/util_io.dart index 2aa8c94bf..8e5f0b88e 100644 --- a/pkgs/package_config/lib/src/util_io.dart +++ b/pkgs/package_config/lib/src/util_io.dart @@ -9,7 +9,7 @@ library package_config.util_io; import 'dart:io'; import 'dart:typed_data'; -Future defaultLoader(Uri uri) async { +Future defaultLoader(Uri uri) async { if (uri.isScheme("file")) { var file = File.fromUri(uri); try { @@ -24,7 +24,7 @@ Future defaultLoader(Uri uri) async { throw UnsupportedError("Default URI unsupported scheme: $uri"); } -Future _httpGet(Uri uri) async { +Future _httpGet(Uri uri) async { assert(uri.isScheme("http") || uri.isScheme("https")); var client = HttpClient(); var request = await client.getUrl(uri); @@ -45,7 +45,7 @@ Future _httpGet(Uri uri) async { } var result = Uint8List(totalLength); var offset = 0; - for (Uint8List contentPart in splitContent) { + for (var contentPart in splitContent as Iterable) { result.setRange(offset, offset + contentPart.length, contentPart); offset += contentPart.length; } @@ -80,7 +80,7 @@ String dirName(String path) { /// /// If a part ends with a path separator, then no extra separator is /// inserted. -String pathJoin(String part1, String part2, [String part3]) { +String pathJoin(String part1, String part2, [String? part3]) { var separator = Platform.pathSeparator; var separator1 = part1.endsWith(separator) ? "" : separator; if (part3 == null) { diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index b7d596910..05c5266b2 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,20 +1,55 @@ name: package_config -version: 1.9.3 +version: 2.0.0-dev description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=2.7.0 <3.0.0' + sdk: '>=2.12.0-0 <3.0.0' dependencies: - path: ^1.6.4 - charcode: ^1.1.0 + path: ^1.8.0-nullsafety.3 dev_dependencies: - test: ^1.6.4 - matcher: ^0.12.5 - pedantic: ^1.9.0 + build_resolvers: ^1.10.0 + build_runner: ^1.10.0 + build_runner_core: ^1.10.0 + build_test: ^1.3.0 + build_web_compilers: ^2.15.0 + pedantic: ^1.10.0-nullsafety.3 + test: ^1.16.0-nullsafety.4 - build_runner: ^1.0.0 - build_web_compilers: ^2.0.0 - build_test: ^0.10.0 +dependency_overrides: + analyzer: + git: + url: git://github.com/dart-lang/sdk.git + path: pkg/analyzer + build_resolvers: + git: + url: git://github.com/dart-lang/build.git + path: build_resolvers + build_runner: + git: + url: git://github.com/dart-lang/build.git + path: build_runner + build_runner_core: + git: + url: git://github.com/dart-lang/build.git + path: build_runner_core + build_test: + git: + url: git://github.com/dart-lang/build.git + path: build_test + coverage: + git: git://github.com/dart-lang/coverage.git + test: + git: + url: git://github.com/dart-lang/test.git + path: pkgs/test + test_api: + git: + url: git://github.com/dart-lang/test.git + path: pkgs/test_api + test_core: + git: + url: git://github.com/dart-lang/test.git + path: pkgs/test_core diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 5cbc99214..df2374d0b 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -63,7 +63,7 @@ void main() { "package_config.json": packageConfigFile, } }, (Directory directory) async { - var config = await findPackageConfig(directory); + var config = (await findPackageConfig(directory))!; expect(config.version, 2); // Found package_config.json file. validatePackagesFile(config, directory); }); @@ -74,7 +74,7 @@ void main() { "script.dart": "main(){}", "packages": {"shouldNotBeFound": {}} }, (Directory directory) async { - var config = await findPackageConfig(directory); + var config = (await findPackageConfig(directory))!; expect(config.version, 1); // Found .packages file. validatePackagesFile(config, directory); }); @@ -89,7 +89,7 @@ void main() { "script.dart": "main(){}", } }, (Directory directory) async { - var config = await findPackageConfig(subdir(directory, "subdir/")); + var config = (await findPackageConfig(subdir(directory, "subdir/")))!; expect(config.version, 2); validatePackagesFile(config, directory); }); diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 23c02d7bc..a89527918 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -61,7 +61,7 @@ void main() { "package_config.json": packageConfigFile, } }, (directory, loader) async { - var config = await findPackageConfigUri(directory, loader: loader); + var config = (await findPackageConfigUri(directory, loader: loader))!; expect(config.version, 2); // Found package_config.json file. validatePackagesFile(config, directory); }); @@ -72,7 +72,7 @@ void main() { "script.dart": "main(){}", "packages": {"shouldNotBeFound": {}} }, (directory, loader) async { - var config = await findPackageConfigUri(directory, loader: loader); + var config = (await findPackageConfigUri(directory, loader: loader))!; expect(config.version, 1); // Found .packages file. validatePackagesFile(config, directory); }); @@ -87,8 +87,8 @@ void main() { "script.dart": "main(){}", } }, (directory, loader) async { - var config = await findPackageConfigUri(directory.resolve("subdir/"), - loader: loader); + var config = (await findPackageConfigUri(directory.resolve("subdir/"), + loader: loader))!; expect(config.version, 2); validatePackagesFile(config, directory); }); diff --git a/pkgs/package_config/test/legacy/all.dart b/pkgs/package_config/test/legacy/all.dart deleted file mode 100644 index 22e2e4f9e..000000000 --- a/pkgs/package_config/test/legacy/all.dart +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2015, 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. - -@deprecated -library package_config.all_test; - -import "package:test/test.dart"; - -import "discovery_analysis_test.dart" as discovery_analysis; -import "discovery_test.dart" as discovery; -import "parse_test.dart" as parse; -import "parse_write_test.dart" as parse_write; - -void main() { - group("parse:", parse.main); - group("discovery:", discovery.main); - group("discovery-analysis:", discovery_analysis.main); - group("parse/write:", parse_write.main); -} diff --git a/pkgs/package_config/test/legacy/discovery_analysis_test.dart b/pkgs/package_config/test/legacy/discovery_analysis_test.dart deleted file mode 100644 index 7554d85d9..000000000 --- a/pkgs/package_config/test/legacy/discovery_analysis_test.dart +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2015, 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. - -@deprecated -@TestOn('vm') -library package_config.discovery_analysis_test; - -import "dart:io"; - -import "package:package_config/discovery_analysis.dart"; -import "package:package_config/packages.dart"; -import "package:path/path.dart" as path; -import "package:test/test.dart"; - -void main() { - fileTest("basic", { - ".packages": packagesFile, - "foo": {".packages": packagesFile}, - "bar": { - "packages": {"foo": {}, "bar": {}, "baz": {}} - }, - "baz": {} - }, (Directory directory) { - var dirUri = Uri.directory(directory.path); - var ctx = PackageContext.findAll(directory); - var root = ctx[directory]; - expect(root, same(ctx)); - validatePackagesFile(root.packages, dirUri); - var fooDir = sub(directory, "foo"); - var foo = ctx[fooDir]; - expect(identical(root, foo), isFalse); - validatePackagesFile(foo.packages, dirUri.resolve("foo/")); - var barDir = sub(directory, "bar"); - var bar = ctx[sub(directory, "bar")]; - validatePackagesDir(bar.packages, dirUri.resolve("bar/")); - var barbar = ctx[sub(barDir, "bar")]; - expect(barbar, same(bar)); // inherited. - var baz = ctx[sub(directory, "baz")]; - expect(baz, same(root)); // inherited. - - var map = ctx.asMap(); - expect(map.keys.map((dir) => dir.path), - unorderedEquals([directory.path, fooDir.path, barDir.path])); - return null; - }); -} - -Directory sub(Directory parent, String dirName) { - return Directory(path.join(parent.path, dirName)); -} - -const packagesFile = """ -# A comment -foo:file:///dart/packages/foo/ -bar:http://example.com/dart/packages/bar/ -baz:packages/baz/ -"""; - -void validatePackagesFile(Packages resolver, Uri location) { - expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); -} - -void validatePackagesDir(Packages resolver, Uri location) { - // Expect three packages: foo, bar and baz - expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(location.resolve("packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(location.resolve("packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - if (location.scheme == "file") { - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); - } else { - expect(() => resolver.packages, throwsUnsupportedError); - } -} - -Uri pkg(String packageName, String packagePath) { - var path; - if (packagePath.startsWith('/')) { - path = "$packageName$packagePath"; - } else { - path = "$packageName/$packagePath"; - } - return Uri(scheme: "package", path: path); -} - -/// Create a directory structure from [description] and run [fileTest]. -/// -/// Description is a map, each key is a file entry. If the value is a map, -/// it's a sub-dir, otherwise it's a file and the value is the content -/// as a string. -void fileTest( - String name, Map description, Future fileTest(Directory directory)) { - group("file-test", () { - var tempDir = Directory.systemTemp.createTempSync("file-test"); - setUp(() { - _createFiles(tempDir, description); - }); - tearDown(() { - tempDir.deleteSync(recursive: true); - }); - test(name, () => fileTest(tempDir)); - }); -} - -void _createFiles(Directory target, Map description) { - description.forEach((name, content) { - if (content is Map) { - var subDir = Directory(path.join(target.path, name)); - subDir.createSync(); - _createFiles(subDir, content); - } else { - var file = File(path.join(target.path, name)); - file.writeAsStringSync(content, flush: true); - } - }); -} diff --git a/pkgs/package_config/test/legacy/discovery_test.dart b/pkgs/package_config/test/legacy/discovery_test.dart deleted file mode 100644 index 72874c8df..000000000 --- a/pkgs/package_config/test/legacy/discovery_test.dart +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) 2015, 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. - -@deprecated -@TestOn('vm') -library package_config.discovery_test; - -import "dart:async"; -import "dart:io"; -import "package:test/test.dart"; -import "package:package_config/packages.dart"; -import "package:package_config/discovery.dart"; -import "package:path/path.dart" as path; - -const packagesFile = """ -# A comment -foo:file:///dart/packages/foo/ -bar:http://example.com/dart/packages/bar/ -baz:packages/baz/ -"""; - -void validatePackagesFile(Packages resolver, Uri location) { - expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); -} - -void validatePackagesDir(Packages resolver, Uri location) { - // Expect three packages: foo, bar and baz - expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(location.resolve("packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(location.resolve("packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(location.resolve("packages/baz/qux/foo"))); - if (location.scheme == "file") { - expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"])); - } else { - expect(() => resolver.packages, throwsUnsupportedError); - } -} - -Uri pkg(String packageName, String packagePath) { - var path; - if (packagePath.startsWith('/')) { - path = "$packageName$packagePath"; - } else { - path = "$packageName/$packagePath"; - } - return Uri(scheme: "package", path: path); -} - -void main() { - generalTest(".packages", { - ".packages": packagesFile, - "script.dart": "main(){}", - "packages": {"shouldNotBeFound": {}} - }, (Uri location) async { - Packages resolver; - resolver = await findPackages(location); - validatePackagesFile(resolver, location); - resolver = await findPackages(location.resolve("script.dart")); - validatePackagesFile(resolver, location); - var specificDiscovery = (location.scheme == "file") - ? findPackagesFromFile - : findPackagesFromNonFile; - resolver = await specificDiscovery(location); - validatePackagesFile(resolver, location); - resolver = await specificDiscovery(location.resolve("script.dart")); - validatePackagesFile(resolver, location); - }); - - generalTest("packages/", { - "packages": {"foo": {}, "bar": {}, "baz": {}}, - "script.dart": "main(){}" - }, (Uri location) async { - Packages resolver; - var isFile = (location.scheme == "file"); - resolver = await findPackages(location); - validatePackagesDir(resolver, location); - resolver = await findPackages(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - var specificDiscovery = - isFile ? findPackagesFromFile : findPackagesFromNonFile; - resolver = await specificDiscovery(location); - validatePackagesDir(resolver, location); - resolver = await specificDiscovery(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - }); - - generalTest("underscore packages", { - "packages": {"_foo": {}} - }, (Uri location) async { - var resolver = await findPackages(location); - expect(resolver.resolve(pkg("_foo", "foo.dart")), - equals(location.resolve("packages/_foo/foo.dart"))); - }); - - fileTest(".packages recursive", { - ".packages": packagesFile, - "subdir": {"script.dart": "main(){}"} - }, (Uri location) async { - Packages resolver; - resolver = await findPackages(location.resolve("subdir/")); - validatePackagesFile(resolver, location); - resolver = await findPackages(location.resolve("subdir/script.dart")); - validatePackagesFile(resolver, location); - resolver = await findPackagesFromFile(location.resolve("subdir/")); - validatePackagesFile(resolver, location); - resolver = - await findPackagesFromFile(location.resolve("subdir/script.dart")); - validatePackagesFile(resolver, location); - }); - - httpTest(".packages not recursive", { - ".packages": packagesFile, - "subdir": {"script.dart": "main(){}"} - }, (Uri location) async { - Packages resolver; - var subdir = location.resolve("subdir/"); - resolver = await findPackages(subdir); - validatePackagesDir(resolver, subdir); - resolver = await findPackages(subdir.resolve("script.dart")); - validatePackagesDir(resolver, subdir); - resolver = await findPackagesFromNonFile(subdir); - validatePackagesDir(resolver, subdir); - resolver = await findPackagesFromNonFile(subdir.resolve("script.dart")); - validatePackagesDir(resolver, subdir); - }); - - fileTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { - // A file: location with no .packages or packages returns - // Packages.noPackages. - Packages resolver; - resolver = await findPackages(location); - expect(resolver, same(Packages.noPackages)); - resolver = await findPackages(location.resolve("script.dart")); - expect(resolver, same(Packages.noPackages)); - resolver = findPackagesFromFile(location); - expect(resolver, same(Packages.noPackages)); - resolver = findPackagesFromFile(location.resolve("script.dart")); - expect(resolver, same(Packages.noPackages)); - }); - - httpTest("no packages", {"script.dart": "main(){}"}, (Uri location) async { - // A non-file: location with no .packages or packages/: - // Assumes a packages dir exists, and resolves relative to that. - Packages resolver; - resolver = await findPackages(location); - validatePackagesDir(resolver, location); - resolver = await findPackages(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location.resolve("script.dart")); - validatePackagesDir(resolver, location); - }); - - test(".packages w/ loader", () async { - var location = Uri.parse("krutch://example.com/path/"); - Future> loader(Uri file) async { - if (file.path.endsWith(".packages")) { - return packagesFile.codeUnits; - } - throw "not found"; - } - - // A non-file: location with no .packages or packages/: - // Assumes a packages dir exists, and resolves relative to that. - Packages resolver; - resolver = await findPackages(location, loader: loader); - validatePackagesFile(resolver, location); - resolver = - await findPackages(location.resolve("script.dart"), loader: loader); - validatePackagesFile(resolver, location); - resolver = await findPackagesFromNonFile(location, loader: loader); - validatePackagesFile(resolver, location); - resolver = await findPackagesFromNonFile(location.resolve("script.dart"), - loader: loader); - validatePackagesFile(resolver, location); - }); - - test("no packages w/ loader", () async { - var location = Uri.parse("krutch://example.com/path/"); - Future> loader(Uri file) async { - throw "not found"; - } - - // A non-file: location with no .packages or packages/: - // Assumes a packages dir exists, and resolves relative to that. - Packages resolver; - resolver = await findPackages(location, loader: loader); - validatePackagesDir(resolver, location); - resolver = - await findPackages(location.resolve("script.dart"), loader: loader); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location, loader: loader); - validatePackagesDir(resolver, location); - resolver = await findPackagesFromNonFile(location.resolve("script.dart"), - loader: loader); - validatePackagesDir(resolver, location); - }); - - generalTest("loadPackagesFile", {".packages": packagesFile}, - (Uri directory) async { - var file = directory.resolve(".packages"); - var resolver = await loadPackagesFile(file); - validatePackagesFile(resolver, file); - }); - - generalTest( - "loadPackagesFile non-default name", {"pheldagriff": packagesFile}, - (Uri directory) async { - var file = directory.resolve("pheldagriff"); - var resolver = await loadPackagesFile(file); - validatePackagesFile(resolver, file); - }); - - test("loadPackagesFile w/ loader", () async { - Future> loader(Uri uri) async => packagesFile.codeUnits; - var file = Uri.parse("krutz://example.com/.packages"); - var resolver = await loadPackagesFile(file, loader: loader); - validatePackagesFile(resolver, file); - }); - - generalTest("loadPackagesFile not found", {}, (Uri directory) async { - var file = directory.resolve(".packages"); - expect( - loadPackagesFile(file), - throwsA(anyOf( - TypeMatcher(), TypeMatcher()))); - }); - - generalTest("loadPackagesFile syntax error", {".packages": "syntax error"}, - (Uri directory) async { - var file = directory.resolve(".packages"); - expect(loadPackagesFile(file), throwsFormatException); - }); - - generalTest("getPackagesDir", { - "packages": {"foo": {}, "bar": {}, "baz": {}} - }, (Uri directory) async { - var packages = directory.resolve("packages/"); - var resolver = getPackagesDirectory(packages); - var resolved = resolver.resolve(pkg("foo", "flip/flop")); - expect(resolved, packages.resolve("foo/flip/flop")); - }); -} - -/// Create a directory structure from [description] and run [fileTest]. -/// -/// Description is a map, each key is a file entry. If the value is a map, -/// it's a sub-dir, otherwise it's a file and the value is the content -/// as a string. -void fileTest(String name, Map description, Future fileTest(Uri directory)) { - group("file-test", () { - var tempDir = Directory.systemTemp.createTempSync("file-test"); - setUp(() { - _createFiles(tempDir, description); - }); - tearDown(() { - tempDir.deleteSync(recursive: true); - }); - test(name, () => fileTest(Uri.file(path.join(tempDir.path, ".")))); - }); -} - -/// HTTP-server the directory structure from [description] and run [htpTest]. -/// -/// Description is a map, each key is a file entry. If the value is a map, -/// it's a sub-dir, otherwise it's a file and the value is the content -/// as a string. -void httpTest(String name, Map description, Future httpTest(Uri directory)) { - group("http-test", () { - var serverSub; - var uri; - setUp(() { - return HttpServer.bind(InternetAddress.loopbackIPv4, 0).then((server) { - uri = Uri( - scheme: "http", host: "127.0.0.1", port: server.port, path: "/"); - serverSub = server.listen((HttpRequest request) { - // No error handling. - var path = request.uri.path; - if (path.startsWith('/')) path = path.substring(1); - if (path.endsWith('/')) path = path.substring(0, path.length - 1); - var parts = path.split('/'); - dynamic fileOrDir = description; - for (var i = 0; i < parts.length; i++) { - fileOrDir = fileOrDir[parts[i]]; - if (fileOrDir == null) { - request.response.statusCode = 404; - request.response.close(); - return; - } - } - request.response.write(fileOrDir); - request.response.close(); - }); - }); - }); - tearDown(() => serverSub.cancel()); - test(name, () => httpTest(uri)); - }); -} - -void generalTest(String name, Map description, Future action(Uri location)) { - fileTest(name, description, action); - httpTest(name, description, action); -} - -void _createFiles(Directory target, Map description) { - description.forEach((name, content) { - if (content is Map) { - var subDir = Directory(path.join(target.path, name)); - subDir.createSync(); - _createFiles(subDir, content); - } else { - var file = File(path.join(target.path, name)); - file.writeAsStringSync(content, flush: true); - } - }); -} diff --git a/pkgs/package_config/test/legacy/parse_test.dart b/pkgs/package_config/test/legacy/parse_test.dart deleted file mode 100644 index b9cf1f8fd..000000000 --- a/pkgs/package_config/test/legacy/parse_test.dart +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) 2015, 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. - -@deprecated -library package_config.parse_test; - -import "package:package_config/packages.dart"; -import "package:package_config/packages_file.dart" show parse; -import "package:package_config/src/packages_impl.dart"; -import "package:test/test.dart"; - -void main() { - var base = Uri.parse("file:///one/two/three/packages.map"); - test("empty", () { - var packages = doParse(emptySample, base); - expect(packages.asMap(), isEmpty); - }); - test("comment only", () { - var packages = doParse(commentOnlySample, base); - expect(packages.asMap(), isEmpty); - }); - test("empty lines only", () { - var packages = doParse(emptyLinesSample, base); - expect(packages.asMap(), isEmpty); - }); - - test("empty lines only", () { - var packages = doParse(emptyLinesSample, base); - expect(packages.asMap(), isEmpty); - }); - - test("single", () { - var packages = doParse(singleRelativeSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("single no slash", () { - var packages = doParse(singleRelativeSampleNoSlash, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("single no newline", () { - var packages = doParse(singleRelativeSampleNoNewline, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("single absolute authority", () { - var packages = doParse(singleAbsoluteSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(Uri.parse("http://example.com/some/where/bar/baz.dart"))); - }); - - test("single empty path", () { - var packages = doParse(singleEmptyPathSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.replace(path: "${base.path}/bar/baz.dart"))); - }); - - test("single absolute path", () { - var packages = doParse(singleAbsolutePathSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.replace(path: "/test/bar/baz.dart"))); - }); - - test("multiple", () { - var packages = doParse(multiRelativeSample, base); - expect(packages.packages.toList()..sort(), equals(["bar", "foo"])); - expect(packages.resolve(Uri.parse("package:foo/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - expect(packages.resolve(Uri.parse("package:bar/foo/baz.dart")), - equals(base.resolve("../test2/").resolve("foo/baz.dart"))); - }); - - test("dot-dot 1", () { - var packages = doParse(singleRelativeSample, base); - expect(packages.packages.toList(), equals(["foo"])); - expect(packages.resolve(Uri.parse("package:foo/qux/../bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("all valid chars can be used in URI segment", () { - var packages = doParse(allValidCharsSample, base); - expect(packages.packages.toList(), equals([allValidChars])); - expect(packages.resolve(Uri.parse("package:$allValidChars/bar/baz.dart")), - equals(base.resolve("../test/").resolve("bar/baz.dart"))); - }); - - test("no invalid chars accepted", () { - var map = {}; - for (var i = 0; i < allValidChars.length; i++) { - map[allValidChars.codeUnitAt(i)] = true; - } - for (var i = 0; i <= 255; i++) { - if (map[i] == true) continue; - var char = String.fromCharCode(i); - expect(() => doParse("x${char}x:x", null), - anyOf(throwsNoSuchMethodError, throwsFormatException)); - } - }); - - test("no escapes", () { - expect(() => doParse("x%41x:x", base), throwsFormatException); - }); - - test("same name twice", () { - expect( - () => doParse(singleRelativeSample * 2, base), throwsFormatException); - }); - - test("disallow default package", () { - expect(() => doParse(":foo", base, allowDefaultPackage: false), - throwsFormatException); - }); - - test("allow default package", () { - var packages = doParse(":foo", base, allowDefaultPackage: true); - expect(packages.defaultPackageName, "foo"); - }); - - test("allow default package name with dot", () { - var packages = doParse(":foo.bar", base, allowDefaultPackage: true); - expect(packages.defaultPackageName, "foo.bar"); - }); - - test("not two default packages", () { - expect(() => doParse(":foo\n:bar", base, allowDefaultPackage: true), - throwsFormatException); - }); - - test("default package invalid package name", () { - // Not a valid *package name*. - expect(() => doParse(":foo/bar", base, allowDefaultPackage: true), - throwsFormatException); - }); - - group("metadata", () { - var packages = doParse( - ":foo\n" - "foo:foo#metafoo=1\n" - "bar:bar#metabar=2\n" - "baz:baz\n" - "qux:qux#metaqux1=3&metaqux2=4\n", - base, - allowDefaultPackage: true); - test("non-existing", () { - // non-package name. - expect(packages.packageMetadata("///", "f"), null); - expect(packages.packageMetadata("", "f"), null); - // unconfigured package name. - expect(packages.packageMetadata("absent", "f"), null); - // package name without that metadata - expect(packages.packageMetadata("foo", "notfoo"), null); - }); - test("lookup", () { - expect(packages.packageMetadata("foo", "metafoo"), "1"); - expect(packages.packageMetadata("bar", "metabar"), "2"); - expect(packages.packageMetadata("qux", "metaqux1"), "3"); - expect(packages.packageMetadata("qux", "metaqux2"), "4"); - }); - test("by library URI", () { - expect( - packages.libraryMetadata( - Uri.parse("package:foo/index.dart"), "metafoo"), - "1"); - expect( - packages.libraryMetadata( - Uri.parse("package:bar/index.dart"), "metabar"), - "2"); - expect( - packages.libraryMetadata( - Uri.parse("package:qux/index.dart"), "metaqux1"), - "3"); - expect( - packages.libraryMetadata( - Uri.parse("package:qux/index.dart"), "metaqux2"), - "4"); - }); - test("by default package", () { - expect( - packages.libraryMetadata( - Uri.parse("file:///whatever.dart"), "metafoo"), - "1"); - }); - }); - - for (var invalidSample in invalid) { - test("invalid '$invalidSample'", () { - var result; - try { - result = doParse(invalidSample, base); - } on FormatException { - // expected - return; - } - fail("Resolved to $result"); - }); - } -} - -Packages doParse(String sample, Uri baseUri, - {bool allowDefaultPackage = false}) { - var map = parse(sample.codeUnits, baseUri, - allowDefaultPackage: allowDefaultPackage); - return MapPackages(map); -} - -// Valid samples. -var emptySample = ""; -var commentOnlySample = "# comment only\n"; -var emptyLinesSample = "\n\n\r\n"; -var singleRelativeSample = "foo:../test/\n"; -var singleRelativeSampleNoSlash = "foo:../test\n"; -var singleRelativeSampleNoNewline = "foo:../test/"; -var singleAbsoluteSample = "foo:http://example.com/some/where/\n"; -var singleEmptyPathSample = "foo:\n"; -var singleAbsolutePathSample = "foo:/test/\n"; -var multiRelativeSample = "foo:../test/\nbar:../test2/\n"; -// All valid path segment characters in an URI. -var allValidChars = r"!$&'()*+,-.0123456789;=" - r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"; - -var allValidCharsSample = "${allValidChars}:../test/\n"; - -// Invalid samples. -var invalid = [ - ":baz.dart", // empty. - "foobar=baz.dart", // no colon (but an equals, which is not the same) - ".:../test/", // dot segment - "..:../test/", // dot-dot segment - "...:../test/", // dot-dot-dot segment - "foo/bar:../test/", // slash in name - "/foo:../test/", // slash at start of name - "?:../test/", // invalid characters. - "[:../test/", // invalid characters. - "x#:../test/", // invalid characters. -]; diff --git a/pkgs/package_config/test/legacy/parse_write_test.dart b/pkgs/package_config/test/legacy/parse_write_test.dart deleted file mode 100644 index a51ced1ba..000000000 --- a/pkgs/package_config/test/legacy/parse_write_test.dart +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) 2015, 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. - -@deprecated -library package_config.parse_write_test; - -import "dart:convert" show utf8; -import "package:package_config/packages_file.dart"; -import "package:test/test.dart"; - -void main() { - void testBase(baseDirString) { - var baseDir = Uri.parse(baseDirString); - group("${baseDir.scheme} base", () { - var packagesFile = baseDir.resolve(".packages"); - - void roundTripTest(String name, Map map) { - group(name, () { - test("write with no baseUri", () { - var content = writeToString(map).codeUnits; - var resultMap = parse(content, packagesFile); - expect(resultMap, map); - }); - - test("write with base directory", () { - var content = writeToString(map, baseUri: baseDir).codeUnits; - var resultMap = parse(content, packagesFile); - expect(resultMap, map); - }); - - test("write with base .packages file", () { - var content = writeToString(map, baseUri: packagesFile).codeUnits; - var resultMap = parse(content, packagesFile); - expect(resultMap, map); - }); - - test("write with defaultPackageName", () { - var content = writeToString( - {'': Uri.parse('my_pkg')}..addAll(map), - allowDefaultPackage: true, - ).codeUnits; - var resultMap = parse( - content, - packagesFile, - allowDefaultPackage: true, - ); - expect(resultMap[''].toString(), 'my_pkg'); - expect( - resultMap, - {'': Uri.parse('my_pkg')}..addAll(map), - ); - }); - - test("write with defaultPackageName (utf8)", () { - var content = utf8.encode(writeToString( - {'': Uri.parse('my_pkg')}..addAll(map), - allowDefaultPackage: true, - )); - var resultMap = parse( - content, - packagesFile, - allowDefaultPackage: true, - ); - expect(resultMap[''].toString(), 'my_pkg'); - expect( - resultMap, - {'': Uri.parse('my_pkg')}..addAll(map), - ); - }); - }); - } - - var lowerDir = baseDir.resolve("path3/path4/"); - var higherDir = baseDir.resolve("../"); - var parallelDir = baseDir.resolve("../path3/"); - var rootDir = baseDir.resolve("/"); - var fileDir = Uri.parse("file:///path1/part2/"); - var httpDir = Uri.parse("http://example.com/path1/path2/"); - var otherDir = Uri.parse("other:/path1/path2/"); - - roundTripTest("empty", {}); - roundTripTest("lower directory", {"foo": lowerDir}); - roundTripTest("higher directory", {"foo": higherDir}); - roundTripTest("parallel directory", {"foo": parallelDir}); - roundTripTest("same directory", {"foo": baseDir}); - roundTripTest("root directory", {"foo": rootDir}); - roundTripTest("file directory", {"foo": fileDir}); - roundTripTest("http directory", {"foo": httpDir}); - roundTripTest("other scheme directory", {"foo": otherDir}); - roundTripTest("multiple same-type directories", - {"foo": lowerDir, "bar": higherDir, "baz": parallelDir}); - roundTripTest("multiple scheme directories", - {"foo": fileDir, "bar": httpDir, "baz": otherDir}); - roundTripTest("multiple scheme directories and mutliple same type", { - "foo": fileDir, - "bar": httpDir, - "baz": otherDir, - "qux": lowerDir, - "hip": higherDir, - "dep": parallelDir - }); - }); - } - - testBase("file:///base1/base2/"); - testBase("http://example.com/base1/base2/"); - testBase("other:/base1/base2/"); - - // Check that writing adds the comment. - test("write preserves comment", () { - var comment = "comment line 1\ncomment line 2\ncomment line 3"; - var result = writeToString({}, comment: comment); - // Comment with "# " before each line and "\n" after last. - var expectedComment = - "# comment line 1\n# comment line 2\n# comment line 3\n"; - expect(result, startsWith(expectedComment)); - }); -} - -String writeToString( - Map map, { - Uri baseUri, - String comment, - bool allowDefaultPackage = false, -}) { - var buffer = StringBuffer(); - write(buffer, map, - baseUri: baseUri, - comment: comment, - allowDefaultPackage: allowDefaultPackage); - return buffer.toString(); -} diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 59a7e7126..385be368e 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -32,7 +32,7 @@ void main() { expect(result.resolve(pkg("baz", "baz.dart")), Uri.parse("file:///tmp/lib/baz.dart")); - var foo = result["foo"]; + var foo = result["foo"]!; expect(foo, isNotNull); expect(foo.root, Uri.parse("file:///foo/")); expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); @@ -111,8 +111,10 @@ void main() { "other": [42] } """; - var config = parsePackageConfigBytes(utf8.encode(packageConfigFile), - Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); + var config = parsePackageConfigBytes( + utf8.encode(packageConfigFile) as Uint8List, + Uri.parse("file:///tmp/.dart_tool/file.dart"), + throwError); expect(config.version, 2); expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz", "noslash"}); @@ -124,28 +126,28 @@ void main() { expect(config.resolve(pkg("baz", "baz.dart")), Uri.parse("file:///tmp/lib/baz.dart")); - var foo = config["foo"]; + var foo = config["foo"]!; expect(foo, isNotNull); expect(foo.root, Uri.parse("file:///foo/")); expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); expect(foo.languageVersion, LanguageVersion(2, 5)); expect(foo.extraData, {"nonstandard": true}); - var bar = config["bar"]; + var bar = config["bar"]!; expect(bar, isNotNull); expect(bar.root, Uri.parse("file:///bar/")); expect(bar.packageUriRoot, Uri.parse("file:///bar/lib/")); expect(bar.languageVersion, LanguageVersion(9999, 9999)); expect(bar.extraData, null); - var baz = config["baz"]; + var baz = config["baz"]!; expect(baz, isNotNull); expect(baz.root, Uri.parse("file:///tmp/")); expect(baz.packageUriRoot, Uri.parse("file:///tmp/lib/")); expect(baz.languageVersion, null); // No slash after root or package root. One is inserted. - var noslash = config["noslash"]; + var noslash = config["noslash"]!; expect(noslash, isNotNull); expect(noslash.root, Uri.parse("file:///tmp/noslash/")); expect(noslash.packageUriRoot, Uri.parse("file:///tmp/noslash/lib/")); @@ -185,8 +187,10 @@ void main() { "configVersion": 2 } """; - var config = parsePackageConfigBytes(utf8.encode(packageConfigFile), - Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); + var config = parsePackageConfigBytes( + utf8.encode(packageConfigFile) as Uint8List, + Uri.parse("file:///tmp/.dart_tool/file.dart"), + throwError); expect(config.version, 2); expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"}); @@ -209,8 +213,10 @@ void main() { var name = '"name":"foo"'; var root = '"rootUri":"/foo/"'; test("minimal", () { - var config = parsePackageConfigBytes(utf8.encode("{$cfg,$pkgs}"), - Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); + var config = parsePackageConfigBytes( + utf8.encode("{$cfg,$pkgs}") as Uint8List, + Uri.parse("file:///tmp/.dart_tool/file.dart"), + throwError); expect(config.version, 2); expect(config.packages, isEmpty); }); @@ -218,7 +224,7 @@ void main() { // A package must have a name and a rootUri, the remaining properties // are optional. var config = parsePackageConfigBytes( - utf8.encode('{$cfg,"packages":[{$name,$root}]}'), + utf8.encode('{$cfg,"packages":[{$name,$root}]}') as Uint8List, Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); expect(config.version, 2); @@ -235,17 +241,17 @@ void main() { {"name": "qux", "rootUri": "/foo/qux/", "packageUri": "lib/"}, ] })); - var config = parsePackageConfigBytes(configBytes, + var config = parsePackageConfigBytes(configBytes as Uint8List, Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); expect(config.version, 2); - expect(config.packageOf(Uri.parse("file:///foo/lala/lala.dart")).name, + expect(config.packageOf(Uri.parse("file:///foo/lala/lala.dart"))!.name, "foo"); - expect( - config.packageOf(Uri.parse("file:///foo/bar/lala.dart")).name, "bar"); - expect(config.packageOf(Uri.parse("file:///foo/bar/baz/lala.dart")).name, + expect(config.packageOf(Uri.parse("file:///foo/bar/lala.dart"))!.name, + "bar"); + expect(config.packageOf(Uri.parse("file:///foo/bar/baz/lala.dart"))!.name, "baz"); - expect( - config.packageOf(Uri.parse("file:///foo/qux/lala.dart")).name, "qux"); + expect(config.packageOf(Uri.parse("file:///foo/qux/lala.dart"))!.name, + "qux"); expect(config.toPackageUri(Uri.parse("file:///foo/lib/diz")), Uri.parse("package:foo/diz")); expect(config.toPackageUri(Uri.parse("file:///foo/bar/lib/diz")), @@ -260,7 +266,7 @@ void main() { void testThrows(String name, String source) { test(name, () { expect( - () => parsePackageConfigBytes(utf8.encode(source), + () => parsePackageConfigBytes(utf8.encode(source) as Uint8List, Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError), throwsA(TypeMatcher())); }); @@ -386,7 +392,7 @@ void main() { for (var package in config.packages) { var name = package.name; test("package $name", () { - var expectedPackage = expected[name]; + var expectedPackage = expected[name]!; expect(expectedPackage, isNotNull); expect(package.root, expectedPackage.root, reason: "root"); expect(package.packageUriRoot, expectedPackage.packageUriRoot, diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart index 6e689b734..2b262e1b2 100644 --- a/pkgs/package_config/test/src/util.dart +++ b/pkgs/package_config/test/src/util.dart @@ -34,18 +34,18 @@ ${packages.map((nu) => """ /// it's a subdirectory, otherwise it's a file and the value is the content /// as a string. void loaderTest(String name, Map description, - void loaderTest(Uri root, Future loader(Uri uri))) { + void loaderTest(Uri root, Future loader(Uri uri))) { var root = Uri(scheme: "test", path: "/"); - Future loader(Uri uri) async { + Future loader(Uri uri) async { var path = uri.path; if (!uri.isScheme("test") || !path.startsWith("/")) return null; var parts = path.split("/"); - dynamic value = description; + Object? value = description; for (var i = 1; i < parts.length; i++) { - if (value is! Map) return null; + if (value is! Map) return null; value = value[parts[i]]; } - if (value is String) return utf8.encode(value); + if (value is String) return utf8.encode(value) as Uint8List; return null; } diff --git a/pkgs/package_config/test/src/util_io.dart b/pkgs/package_config/test/src/util_io.dart index d05618a07..37deee9e1 100644 --- a/pkgs/package_config/test/src/util_io.dart +++ b/pkgs/package_config/test/src/util_io.dart @@ -35,20 +35,20 @@ void fileTest(String name, Map description, /// with the content as description. /// Otherwise the content should be a string, /// which is written to the file as UTF-8. -Directory createTestFiles(Map description) { - var target = Directory.systemTemp.createTempSync("pkgcfgtest"); - _createFiles(target, description); - return target; -} +// Directory createTestFiles(Map description) { +// var target = Directory.systemTemp.createTempSync("pkgcfgtest"); +// _createFiles(target, description); +// return target; +// } // Creates temporary files in the target directory. -void _createFiles(Directory target, Map description) { +void _createFiles(Directory target, Map description) { description.forEach((name, content) { var entryName = pathJoin(target.path, "$name"); - if (content is Map) { + if (content is Map) { _createFiles(Directory(entryName)..createSync(), content); } else { - File(entryName).writeAsStringSync(content, flush: true); + File(entryName).writeAsStringSync(content as String, flush: true); } }); } From 3a99a4ecbc2cd0508ff20b1e1b56a5397d83da67 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Mon, 7 Dec 2020 13:32:36 -0800 Subject: [PATCH 400/657] migrate from `dartanalyzer` to `dart analyze` the experiment is no longer required and warnings are fatal by default --- pkgs/pool/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml index 87be92616..431bd27e0 100644 --- a/pkgs/pool/.travis.yml +++ b/pkgs/pool/.travis.yml @@ -8,7 +8,7 @@ jobs: - stage: analyze_and_format name: "Analyze" os: linux - script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . + script: dart analyze --fatal-infos . - stage: analyze_and_format name: "Format" os: linux From ba5cc8d21bdbeccffa9327d0287511b430767433 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Wed, 9 Dec 2020 15:06:53 -0800 Subject: [PATCH 401/657] Add override for _fe_analyzer_shared (dart-lang/package_config#96) We currently need the dependency overrides because of the circular dev_dependencies and the major version change. It is still safe to publish since no normal dependencies are overridden. The dependency overrides are causing us to pull in incompatible versions of `analyzer` and `_fe_analyzer_shared` since there was a breaking change in the latter. Pulling it in from the SDK should cause both to be compatible until we can drop the overrides entirely. --- pkgs/package_config/pubspec.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 05c5266b2..48b8d3c95 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -19,6 +19,10 @@ dev_dependencies: test: ^1.16.0-nullsafety.4 dependency_overrides: + _fe_analyzer_shared: + git: + url: git://github.com/dart-lang/sdk.git + path: pkg/_fe_analyzer_shared analyzer: git: url: git://github.com/dart-lang/sdk.git From 02e6eb5c0c6e6f1e295377caa56d06ad8689a5d2 Mon Sep 17 00:00:00 2001 From: Phil Quitslund Date: Thu, 10 Dec 2020 10:41:31 -0800 Subject: [PATCH 402/657] migrate to `dart analyze` (warnings are now fatal by default) --- pkgs/package_config/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml index 3a47bb586..c4e5bdb8f 100644 --- a/pkgs/package_config/.travis.yml +++ b/pkgs/package_config/.travis.yml @@ -5,7 +5,7 @@ dart: dart_task: - test - dartfmt - - dartanalyzer: --fatal-warnings --fatal-infos . + - dart analyze --fatal-infos . matrix: include: From c9395552ff2def38ea8e858560c766185522c6ce Mon Sep 17 00:00:00 2001 From: Lasse Reichstein Holst Nielsen Date: Tue, 19 Jan 2021 15:00:16 +0100 Subject: [PATCH 403/657] Change version to 2.0.0-nullsafety.0 for consistency. --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 48b8d3c95..c1cfd9456 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.0-dev +version: 2.0.0-nullsafety.0 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config From 4576b85ed4a30859a744dcca906326b963208871 Mon Sep 17 00:00:00 2001 From: Alexander Thomas Date: Wed, 20 Jan 2021 16:06:47 +0100 Subject: [PATCH 404/657] Migrate to GitHub Actions (dart-lang/source_maps#60) * Delete .travis.yml --- .../.github/workflows/test-package.yml | 61 +++++++++++++++++++ pkgs/source_maps/.travis.yml | 31 ---------- 2 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 pkgs/source_maps/.github/workflows/test-package.yml delete mode 100644 pkgs/source_maps/.travis.yml diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml new file mode 100644 index 000000000..21a3c50b6 --- /dev/null +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -0,0 +1,61 @@ +name: Dart CI + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Check formatting + run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - name: Analyze code + run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Run VM tests + run: dart test --platform vm + if: always() && steps.install.outcome == 'success' diff --git a/pkgs/source_maps/.travis.yml b/pkgs/source_maps/.travis.yml deleted file mode 100644 index ac74df9cc..000000000 --- a/pkgs/source_maps/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -language: dart - -dart: - - dev - -jobs: - include: - - stage: analyze_and_format - name: "Analyze" - os: linux - script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - - stage: analyze_and_format - name: "Format" - os: linux - script: dartfmt -n --set-exit-if-changed . - - stage: test - name: "Vm Tests" - os: linux - script: pub run --enable-experiment=non-nullable test -p vm - -stages: - - analyze_and_format - - test - -# Only building master means that we don't run two builds for each pull request. -branches: - only: [master] - -cache: - directories: - - $HOME/.pub-cache From 78ba828aecfc0a59bd796c6b5258739f59e8977c Mon Sep 17 00:00:00 2001 From: Alexander Thomas Date: Wed, 20 Jan 2021 18:01:59 +0100 Subject: [PATCH 405/657] Migrate to GitHub Actions (dart-lang/source_span#69) * Migrate to GitHub Actions * Delete .travis.yml --- .../.github/workflows/test-package.yml | 64 +++++++++++++++++++ pkgs/source_span/.travis.yml | 35 ---------- 2 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 pkgs/source_span/.github/workflows/test-package.yml delete mode 100644 pkgs/source_span/.travis.yml diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml new file mode 100644 index 000000000..0a2a87433 --- /dev/null +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -0,0 +1,64 @@ +name: Dart CI + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Check formatting + run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - name: Analyze code + run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Run VM tests + run: dart test --platform vm + if: always() && steps.install.outcome == 'success' + - name: Run Chrome tests + run: dart test --platform chrome + if: always() && steps.install.outcome == 'success' diff --git a/pkgs/source_span/.travis.yml b/pkgs/source_span/.travis.yml deleted file mode 100644 index 8a4761a70..000000000 --- a/pkgs/source_span/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: dart - -dart: -- dev - -jobs: - include: - - stage: analyze_and_format - name: "Analyze test/" - os: linux - script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos . - - stage: analyze_and_format - name: "Format" - os: linux - script: dartfmt -n --set-exit-if-changed . - - stage: test - name: "Vm Tests" - os: linux - script: pub run --enable-experiment=non-nullable test -p vm - - stage: test - name: "Web Tests" - 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] - -cache: - directories: - - $HOME/.pub-cache From 846247817732cdab8bf5f02a83d42a6913e0b52a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 21 Jan 2021 00:19:08 -0800 Subject: [PATCH 406/657] Migrate to GitHub Actions (dart-lang/pool#51) --- pkgs/pool/.github/workflows/ci.yml | 64 ++++++++++++++++++++++++++++++ pkgs/pool/.travis.yml | 35 ---------------- 2 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 pkgs/pool/.github/workflows/ci.yml delete mode 100644 pkgs/pool/.travis.yml diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml new file mode 100644 index 000000000..f55a818da --- /dev/null +++ b/pkgs/pool/.github/workflows/ci.yml @@ -0,0 +1,64 @@ +name: CI + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Check formatting + run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - name: Analyze code + run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Run VM tests + run: dart test --platform vm + if: always() && steps.install.outcome == 'success' + - name: Run Chrome tests + run: dart test --platform chrome + if: always() && steps.install.outcome == 'success' diff --git a/pkgs/pool/.travis.yml b/pkgs/pool/.travis.yml deleted file mode 100644 index 431bd27e0..000000000 --- a/pkgs/pool/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -language: dart - -dart: - - dev - -jobs: - include: - - stage: analyze_and_format - name: "Analyze" - os: linux - script: dart analyze --fatal-infos . - - stage: analyze_and_format - name: "Format" - os: linux - script: dartfmt -n --set-exit-if-changed . - - stage: test - name: "Vm Tests" - os: linux - script: pub run --enable-experiment=non-nullable test -p vm - - stage: test - name: "Web Tests" - 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] - -cache: - directories: - - $HOME/.pub-cache From 43d80949f6710a34c66df5a4c34247e4079ae03c Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 21 Jan 2021 16:32:45 +0100 Subject: [PATCH 407/657] Make it possible to control whether the `rootUri` path is relativized. (dart-lang/package_config#102) * Make it possible to control whether the `rootUri` path is relativized. Adds `relativeRoot` boolean to `PackageConfig` which does nothing except to control whether the `root` URI is made relative to the configuration file when written to a configuration file. The parsers remember whether the root URI was relative originally. Also fixes bad cast. --- pkgs/package_config/CHANGELOG.md | 2 + .../lib/src/package_config.dart | 19 ++++++-- .../lib/src/package_config_impl.dart | 9 ++-- .../lib/src/package_config_json.dart | 19 +++++--- .../package_config/lib/src/packages_file.dart | 8 ++-- pkgs/package_config/lib/src/util.dart | 15 ++++++ pkgs/package_config/pubspec.yaml | 2 +- .../test/package_config_impl_test.dart | 47 ++++++++++++++++++- pkgs/package_config/test/parse_test.dart | 5 ++ 9 files changed, 107 insertions(+), 19 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 32ff3f17f..4a04782b4 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -2,6 +2,8 @@ - Migrate to null safety. - Remove legacy APIs. +- Adds `relativeRoot` property to `Package` which controls whether to + make the root URI relative when writing a configuration file. ## 1.9.3 diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 63d01eacd..26aa39622 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -224,14 +224,20 @@ abstract class Package { /// version, which means two decimal integer literals separated by a `.`, /// where the integer literals have no leading zeros unless they are /// a single zero digit. + /// + /// The [relativeRoot] controls whether the [root] is written as + /// relative to the `package_config.json` file when the package + /// configuration is written to a file. It defaults to being relative. + /// /// If [extraData] is supplied, it will be available as the /// [Package.extraData] of the created package. factory Package(String name, Uri root, {Uri? packageUriRoot, LanguageVersion? languageVersion, - Object? extraData}) => - SimplePackage.validate( - name, root, packageUriRoot, languageVersion, extraData, throwError)!; + Object? extraData, + bool relativeRoot = true}) => + SimplePackage.validate(name, root, packageUriRoot, languageVersion, + extraData, relativeRoot, throwError)!; /// The package-name of the package. String get name; @@ -275,6 +281,13 @@ abstract class Package { /// The standard `package_config.json` file storage will only store /// JSON-like list/map data structures. Object? get extraData; + + /// Whether the [root] URI should be written as relative. + /// + /// When the configuration is written to a `package_config.json` + /// file, the [root] URI can be either relative to the file + /// location or absolute, controller by this value. + bool get relativeRoot; } /// A language version. diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 5c6b7f728..c75111580 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -61,7 +61,8 @@ class SimplePackageConfig implements PackageConfig { originalPackage.root, originalPackage.packageUriRoot, originalPackage.languageVersion, - originalPackage.extraData, (error) { + originalPackage.extraData, + originalPackage.relativeRoot, (error) { if (error is PackageConfigArgumentError) { onError(PackageConfigArgumentError(packages, "packages", "Package ${package!.name}: ${error.message}")); @@ -159,9 +160,10 @@ class SimplePackage implements Package { final Uri packageUriRoot; final LanguageVersion? languageVersion; final Object? extraData; + final bool relativeRoot; SimplePackage._(this.name, this.root, this.packageUriRoot, - this.languageVersion, this.extraData); + this.languageVersion, this.extraData, this.relativeRoot); /// Creates a [SimplePackage] with the provided content. /// @@ -184,6 +186,7 @@ class SimplePackage implements Package { Uri? packageUriRoot, LanguageVersion? languageVersion, Object? extraData, + bool relativeRoot, void onError(Object error)) { var fatalError = false; var invalidIndex = checkPackageName(name); @@ -229,7 +232,7 @@ class SimplePackage implements Package { } if (fatalError) return null; return SimplePackage._( - name, root, packageUriRoot, languageVersion, extraData); + name, root, packageUriRoot, languageVersion, extraData, relativeRoot); } } diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index 25b04c4d1..979c35ed4 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -146,7 +146,9 @@ PackageConfig parsePackageConfigJson( onError(PackageConfigFormatException("Missing rootUri entry", entry)); } if (name == null || rootUri == null) return null; - var root = baseLocation.resolve(rootUri!); + var parsedRootUri = Uri.parse(rootUri!); + var relativeRoot = !hasAbsolutePath(parsedRootUri); + var root = baseLocation.resolveUri(parsedRootUri); if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/"); var packageRoot = root; if (packageUri != null) packageRoot = root.resolve(packageUri!); @@ -161,8 +163,8 @@ PackageConfig parsePackageConfigJson( version = SimpleInvalidLanguageVersion("invalid"); } - return SimplePackage.validate(name!, root, packageRoot, version, extraData, - (error) { + return SimplePackage.validate( + name!, root, packageRoot, version, extraData, relativeRoot, (error) { if (error is ArgumentError) { onError( PackageConfigFormatException(error.message, error.invalidValue)); @@ -232,7 +234,7 @@ void writePackageConfigJsonString( PackageConfig config, Uri? baseUri, StringSink output) { // Can be optimized. var data = packageConfigToJson(config, baseUri); - output.write(JsonEncoder.withIndent(" ").convert(data) as Uint8List); + output.write(JsonEncoder.withIndent(" ").convert(data)); } Map packageConfigToJson(PackageConfig config, Uri? baseUri) => @@ -243,11 +245,14 @@ Map packageConfigToJson(PackageConfig config, Uri? baseUri) => for (var package in config.packages) { _nameKey: package.name, - _rootUriKey: relativizeUri(package.root, baseUri).toString(), + _rootUriKey: trailingSlash((package.relativeRoot + ? relativizeUri(package.root, baseUri) + : package.root) + .toString()), if (package.root != package.packageUriRoot) - _packageUriKey: + _packageUriKey: trailingSlash( relativizeUri(package.packageUriRoot, package.root) - .toString(), + .toString()), if (package.languageVersion != null && package.languageVersion is! InvalidLanguageVersion) _languageVersionKey: package.languageVersion.toString(), diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index 071d548a5..ddcf8563b 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -96,11 +96,13 @@ PackageConfig parse( var packageValue = String.fromCharCodes(source, separatorIndex + 1, end); Uri packageLocation; try { - packageLocation = baseLocation.resolve(packageValue); + packageLocation = Uri.parse(packageValue); } on FormatException catch (e) { onError(PackageConfigFormatException.from(e)); continue; } + var relativeRoot = !hasAbsolutePath(packageLocation); + packageLocation = baseLocation.resolveUri(packageLocation); if (packageLocation.isScheme("package")) { onError(PackageConfigFormatException( "Package URI as location for package", source, separatorIndex + 1)); @@ -122,8 +124,8 @@ PackageConfig parse( rootUri = packageLocation.replace(path: path.substring(0, path.length - 4)); } - var package = SimplePackage.validate( - packageName, rootUri, packageLocation, _languageVersion, null, (error) { + var package = SimplePackage.validate(packageName, rootUri, packageLocation, + _languageVersion, null, relativeRoot, (error) { if (error is ArgumentError) { onError(PackageConfigFormatException(error.message, source)); } else { diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 9b263ae7a..f490cdc1c 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -137,6 +137,21 @@ int firstNonWhitespaceChar(List bytes) { return -1; } +/// Appends a trailing `/` if the path doesn't end with one. +String trailingSlash(String path) { + if (path.isEmpty || path.endsWith("/")) return path; + return path + "/"; +} + +/// Whether a URI should not be considered relative to the base URI. +/// +/// Used to determine whether a parsed root URI is relative +/// to the configuration file or not. +/// If it is relative, then it's rewritten as relative when +/// output again later. If not, it's output as absolute. +bool hasAbsolutePath(Uri uri) => + uri.hasScheme || uri.hasAuthority || uri.hasAbsolutePath; + /// Attempts to return a relative path-only URI for [uri]. /// /// First removes any query or fragment part from [uri]. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index c1cfd9456..5903bc8ac 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.0-nullsafety.0 +version: 2.0.0-nullsafety.1 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 6921118f3..bb00d1210 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -2,6 +2,8 @@ // 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 "dart:convert" show jsonDecode; + import "package:package_config/package_config_types.dart"; import "package:test/test.dart"; import "src/util.dart"; @@ -72,6 +74,7 @@ void main() { var absolute = root.resolve("foo/bar/"); var package = Package("name", root, packageUriRoot: absolute, + relativeRoot: false, languageVersion: version, extraData: unique); expect(package.name, "name"); @@ -79,16 +82,18 @@ void main() { expect(package.packageUriRoot, absolute); expect(package.languageVersion, version); expect(package.extraData, same(unique)); + expect(package.relativeRoot, false); }); test("relative package root", () { var relative = Uri.parse("foo/bar/"); var absolute = root.resolveUri(relative); - var package = - Package("name", root, packageUriRoot: relative, extraData: unique); + var package = Package("name", root, + packageUriRoot: relative, relativeRoot: true, extraData: unique); expect(package.name, "name"); expect(package.root, root); expect(package.packageUriRoot, absolute); + expect(package.relativeRoot, true); expect(package.languageVersion, null); expect(package.extraData, same(unique)); }); @@ -140,6 +145,44 @@ void main() { expect(resolved, root.resolve("a/b")); }); }); + test("writeString", () { + var config = PackageConfig([ + Package("foo", Uri.parse("file:///pkg/foo/"), + packageUriRoot: Uri.parse("file:///pkg/foo/lib/"), + relativeRoot: false, + languageVersion: LanguageVersion(2, 4), + extraData: {"foo": "foo!"}), + Package("bar", Uri.parse("file:///pkg/bar/"), + packageUriRoot: Uri.parse("file:///pkg/bar/lib/"), + relativeRoot: true, + extraData: {"bar": "bar!"}), + ], extraData: { + "extra": "data" + }); + var buffer = StringBuffer(); + PackageConfig.writeString(config, buffer, Uri.parse("file:///pkg/")); + var text = buffer.toString(); + var json = jsonDecode(text); // Is valid JSON. + expect(json, { + "configVersion": 2, + "packages": unorderedEquals([ + { + "name": "foo", + "rootUri": "file:///pkg/foo/", + "packageUri": "lib/", + "languageVersion": "2.4", + "foo": "foo!", + }, + { + "name": "bar", + "rootUri": "bar/", + "packageUri": "lib/", + "bar": "bar!", + }, + ]), + "extra": "data", + }); + }); } final Matcher throwsPackageConfigError = throwsA(isA()); diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 385be368e..ef73c2e1e 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -37,6 +37,7 @@ void main() { expect(foo.root, Uri.parse("file:///foo/")); expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); expect(foo.languageVersion, LanguageVersion(2, 7)); + expect(foo.relativeRoot, false); }); test("valid empty", () { @@ -132,6 +133,7 @@ void main() { expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); expect(foo.languageVersion, LanguageVersion(2, 5)); expect(foo.extraData, {"nonstandard": true}); + expect(foo.relativeRoot, false); var bar = config["bar"]!; expect(bar, isNotNull); @@ -139,12 +141,14 @@ void main() { expect(bar.packageUriRoot, Uri.parse("file:///bar/lib/")); expect(bar.languageVersion, LanguageVersion(9999, 9999)); expect(bar.extraData, null); + expect(bar.relativeRoot, false); var baz = config["baz"]!; expect(baz, isNotNull); expect(baz.root, Uri.parse("file:///tmp/")); expect(baz.packageUriRoot, Uri.parse("file:///tmp/lib/")); expect(baz.languageVersion, null); + expect(baz.relativeRoot, true); // No slash after root or package root. One is inserted. var noslash = config["noslash"]!; @@ -152,6 +156,7 @@ void main() { expect(noslash.root, Uri.parse("file:///tmp/noslash/")); expect(noslash.packageUriRoot, Uri.parse("file:///tmp/noslash/lib/")); expect(noslash.languageVersion, null); + expect(noslash.relativeRoot, true); expect(config.extraData, { "generator": "pub", From 0adf2fb718ec0d260d746a541633f50ca43f0707 Mon Sep 17 00:00:00 2001 From: Alexander Thomas Date: Thu, 28 Jan 2021 16:23:31 +0100 Subject: [PATCH 408/657] Migrate GitHub Actions (dart-lang/pub_semver#53) --- .../.github/workflows/test-package.yml | 64 +++++++++++++++++++ pkgs/pub_semver/.travis.yml | 17 ----- 2 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 pkgs/pub_semver/.github/workflows/test-package.yml delete mode 100644 pkgs/pub_semver/.travis.yml diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml new file mode 100644 index 000000000..0a2a87433 --- /dev/null +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -0,0 +1,64 @@ +name: Dart CI + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Check formatting + run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - name: Analyze code + run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Run VM tests + run: dart test --platform vm + if: always() && steps.install.outcome == 'success' + - name: Run Chrome tests + run: dart test --platform chrome + if: always() && steps.install.outcome == 'success' diff --git a/pkgs/pub_semver/.travis.yml b/pkgs/pub_semver/.travis.yml deleted file mode 100644 index e40520c4d..000000000 --- a/pkgs/pub_semver/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: dart - -dart: -- dev - -dart_task: -- test: -p vm,chrome -- dart_task: dartfmt -- dartanalyzer: --fatal-infos . - -# Only building master means that we don't run two builds for each pull request. -branches: - only: [master] - -cache: - directories: - - $HOME/.pub-cache From 9bf6b87cb42b2817d0c0d8cb874268ee6d6c07f3 Mon Sep 17 00:00:00 2001 From: Alexander Thomas Date: Thu, 28 Jan 2021 16:24:37 +0100 Subject: [PATCH 409/657] Migrate to GitHub Actions (dart-lang/package_config#103) --- .../.github/workflows/test-package.yml | 61 +++++++++++++++++++ pkgs/package_config/.travis.yml | 21 ------- pkgs/package_config/README.md | 2 +- 3 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 pkgs/package_config/.github/workflows/test-package.yml delete mode 100644 pkgs/package_config/.travis.yml diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml new file mode 100644 index 000000000..20220ab61 --- /dev/null +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -0,0 +1,61 @@ +name: Dart CI + +on: + # Run on PRs and pushes to the default branch. + push: + branches: [ master ] + pull_request: + branches: [ master ] + schedule: + - cron: "0 0 * * 0" + +env: + PUB_ENVIRONMENT: bot.github + +jobs: + # Check code formatting and static analysis on a single OS (linux) + # against Dart dev. + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Check formatting + run: dart format --output=none --set-exit-if-changed . + if: always() && steps.install.outcome == 'success' + - name: Analyze code + run: dart analyze --fatal-infos + if: always() && steps.install.outcome == 'success' + + # Run tests on a matrix consisting of two dimensions: + # 1. OS: ubuntu-latest, (macos-latest, windows-latest) + # 2. release channel: dev + test: + needs: analyze + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Add macos-latest and/or windows-latest if relevant for this package. + os: [ubuntu-latest] + sdk: [dev] + steps: + - uses: actions/checkout@v2 + - uses: dart-lang/setup-dart@v0.3 + with: + sdk: ${{ matrix.sdk }} + - id: install + name: Install dependencies + run: dart pub get + - name: Run tests + run: dart run build_runner test -- -p chrome,vm + if: always() && steps.install.outcome == 'success' diff --git a/pkgs/package_config/.travis.yml b/pkgs/package_config/.travis.yml deleted file mode 100644 index c4e5bdb8f..000000000 --- a/pkgs/package_config/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: dart -sudo: false -dart: - - dev -dart_task: - - test - - dartfmt - - dart analyze --fatal-infos . - -matrix: - include: - - dart: dev - script: pub run build_runner test -- -p chrome - -# Only building master means that we don't run two builds for each pull request. -branches: - only: [master] - -cache: - directories: - - $HOME/.pub-cache diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 1ad4b41c1..ada1bd0ec 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/dart-lang/package_config.svg?branch=master)](https://travis-ci.org/dart-lang/package_config) +[![Build Status](https://github.com/dart-lang/package_config/workflows/Dart%20CI/badge.svg)](https://github.com/dart-lang/package_config/actions?query=workflow%3A"Dart+CI"+branch%3Amaster) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config) Support for working with **Package Configuration** files as described From 1ccc5d42328f1ae05f19d329674bea8a5dc954e9 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Mon, 1 Feb 2021 12:18:44 -0800 Subject: [PATCH 410/657] Revert "Remove dependency on package:charcode (dart-lang/source_span#66)" (dart-lang/source_span#70) This reverts commit 778a4bb3bfbbf48da04741381416d7159955b10b. Reverting to keep `lib/` directory content the same as the latest published version. --- pkgs/source_span/CHANGELOG.md | 2 -- pkgs/source_span/lib/src/charcode.dart | 15 --------------- pkgs/source_span/lib/src/highlighter.dart | 2 +- pkgs/source_span/lib/src/span.dart | 2 +- pkgs/source_span/pubspec.yaml | 3 ++- 5 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 pkgs/source_span/lib/src/charcode.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index ae1c0d6ae..2c812566a 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,5 +1,3 @@ -# 1.8.0-nullsafety.5-dev - # 1.8.0-nullsafety.4 * Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release diff --git a/pkgs/source_span/lib/src/charcode.dart b/pkgs/source_span/lib/src/charcode.dart deleted file mode 100644 index 51826380a..000000000 --- a/pkgs/source_span/lib/src/charcode.dart +++ /dev/null @@ -1,15 +0,0 @@ -// 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. - -/// "Carriage return" control character. -const int $cr = 0x0D; - -/// "Line feed" control character. -const int $lf = 0x0A; - -/// Space character. -const int $space = 0x20; - -/// "Horizontal Tab" control character, common name. -const int $tab = 0x09; diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 5d28fc3bb..f622c4e01 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -4,11 +4,11 @@ import 'dart:math' as math; +import 'package:charcode/charcode.dart'; import 'package:collection/collection.dart'; import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; -import 'charcode.dart'; import 'colors.dart' as colors; import 'location.dart'; import 'span.dart'; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index ba8bec715..94c05ba7a 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -2,10 +2,10 @@ // 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:charcode/charcode.dart'; import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; -import 'charcode.dart'; import 'file.dart'; import 'highlighter.dart'; import 'location.dart'; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 9f7fca3c2..a5db06e14 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.8.0-nullsafety.5-dev +version: 1.8.0-nullsafety.4 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span @@ -8,6 +8,7 @@ environment: sdk: ">=2.12.0-0.0 <3.0.0" dependencies: + 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' From 8a9af6bded2c393ba2fc847d45cab65d3b014ba8 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 2 Feb 2021 15:41:26 -0800 Subject: [PATCH 411/657] Prepare to publish for stable null safety (dart-lang/source_span#71) --- pkgs/source_span/CHANGELOG.md | 8 ++++++-- pkgs/source_span/pubspec.yaml | 10 +++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 2c812566a..599835fe7 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.8.0 + +* Stable release for null safety. + # 1.8.0-nullsafety.4 * Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release @@ -12,7 +16,7 @@ # 1.8.0-nullsafety.2 * Revert unnecessary null check fix (sdk fix wont land in 2.10 stable). -* Allow 2.10 stable and 2.11 dev sdks. +* Allow 2.10 stable and 2.11 dev sdks. # 1.8.0-nullsafety.1 @@ -23,7 +27,7 @@ * 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/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index a5db06e14..c589022d5 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.8.0-nullsafety.4 +version: 1.8.0 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span @@ -8,10 +8,10 @@ environment: sdk: ">=2.12.0-0.0 <3.0.0" dependencies: - 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' + charcode: ^1.2.0 + collection: ^1.15.0 + path: ^1.8.0 + term_glyph: ^1.2.0 dev_dependencies: test: ^1.16.0-nullsafety From e13c6af6304a26cea128b96fd82ebb065792f827 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 2 Feb 2021 16:31:39 -0800 Subject: [PATCH 412/657] Prepare to publish for stable null safety (dart-lang/source_maps#61) --- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 7bdead97f..a59cf3006 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.10 + +* Stable release for null safety. + ## 0.10.10-nullsafety.3 * Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index ab75dc5c6..648010a3f 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.10-nullsafety.3 +version: 0.10.10 description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps @@ -8,7 +8,7 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: - source_span: '>=1.8.0-nullsafety <1.8.0' + source_span: ^1.8.0 dev_dependencies: test: ^1.16.0-nullsafety From 2d1b038528c3c1053f46ce72d8c581e19ca986f4 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Tue, 2 Feb 2021 17:22:57 -0800 Subject: [PATCH 413/657] Prepare to publish for stable null safety (dart-lang/pool#52) --- pkgs/pool/CHANGELOG.md | 6 +++++- pkgs/pool/pubspec.yaml | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 6fd755bbb..9e0a5a519 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.0 + +* Stable release for null safety. + ## 1.5.0-nullsafety.3 * Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release @@ -15,7 +19,7 @@ * Migrate to null safety. * `forEach`: Avoid `await null` if the `Stream` is not paused. - Improves trivial benchmark by 40%. + Improves trivial benchmark by 40%. ## 1.4.0 diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 67d8b6c7a..421baf5f2 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.0-nullsafety.3 +version: 1.5.0 description: >- Manage a finite pool of resources. @@ -10,8 +10,8 @@ environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: - async: '>=2.5.0-nullsafety <2.5.0' - stack_trace: '>=1.10.0-nullsafety <1.10.0' + async: ^2.5.0 + stack_trace: ^1.10.0 dev_dependencies: fake_async: ^1.2.0-nullsafety From da6912bc6aa4f55b491c83d4039f7e4656769e4b Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 4 Feb 2021 11:03:30 -0800 Subject: [PATCH 414/657] Revert "Revert "Remove dependency on package:charcode (dart-lang/source_span#66)" (dart-lang/source_span#70)" (dart-lang/source_span#73) This reverts commit 1ccc5d42328f1ae05f19d329674bea8a5dc954e9. --- pkgs/source_span/CHANGELOG.md | 2 ++ pkgs/source_span/lib/src/charcode.dart | 15 +++++++++++++++ pkgs/source_span/lib/src/highlighter.dart | 2 +- pkgs/source_span/lib/src/span.dart | 2 +- pkgs/source_span/pubspec.yaml | 3 +-- 5 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 pkgs/source_span/lib/src/charcode.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 599835fe7..6f78c4b72 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.8.1 + # 1.8.0 * Stable release for null safety. diff --git a/pkgs/source_span/lib/src/charcode.dart b/pkgs/source_span/lib/src/charcode.dart new file mode 100644 index 000000000..51826380a --- /dev/null +++ b/pkgs/source_span/lib/src/charcode.dart @@ -0,0 +1,15 @@ +// 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. + +/// "Carriage return" control character. +const int $cr = 0x0D; + +/// "Line feed" control character. +const int $lf = 0x0A; + +/// Space character. +const int $space = 0x20; + +/// "Horizontal Tab" control character, common name. +const int $tab = 0x09; diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index f622c4e01..5d28fc3bb 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -4,11 +4,11 @@ import 'dart:math' as math; -import 'package:charcode/charcode.dart'; import 'package:collection/collection.dart'; import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; +import 'charcode.dart'; import 'colors.dart' as colors; import 'location.dart'; import 'span.dart'; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 94c05ba7a..ba8bec715 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -2,10 +2,10 @@ // 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:charcode/charcode.dart'; import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; +import 'charcode.dart'; import 'file.dart'; import 'highlighter.dart'; import 'location.dart'; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index c589022d5..12382a5ba 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.8.0 +version: 1.8.1-dev description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span @@ -8,7 +8,6 @@ environment: sdk: ">=2.12.0-0.0 <3.0.0" dependencies: - charcode: ^1.2.0 collection: ^1.15.0 path: ^1.8.0 term_glyph: ^1.2.0 From 313d8597d261bde7d5da4e2cfb40fa55ecfacd7c Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Thu, 4 Feb 2021 11:21:13 -0800 Subject: [PATCH 415/657] Fix header for multispan with null secondary urls (dart-lang/source_span#72) If a multiple span highlight was created where all the secondary spans had `null` URLs they were filtered out from the comparison checking whether multiple files are involved. This bug was caused during the null safety migration. A similar bug previously existed if the primary span had a null URL and is also fixed. - Take a nullable list in `isAllTheSame`. Avoid using `null` as a sentinel for no item seen, use `.first` and `.skip(1)` to compare all elements. - Add tests for the case of primary and secondary spans with a null URL. --- pkgs/source_span/CHANGELOG.md | 3 ++ pkgs/source_span/lib/src/highlighter.dart | 3 +- pkgs/source_span/lib/src/utils.dart | 11 +++-- pkgs/source_span/pubspec.yaml | 2 +- .../test/multiple_highlight_test.dart | 45 ++++++++++++++++--- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 6f78c4b72..6fda0a058 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,5 +1,8 @@ # 1.8.1 +* Fix a bug where the URL header for the highlights with multiple files would + get omitted only one span has a non-null URI. + # 1.8.0 * Stable release for null safety. diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 5d28fc3bb..19d8965ee 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -107,8 +107,7 @@ class Highlighter { .where((highlight) => isMultiline(highlight.span)) .length) .reduce(math.max), - _multipleFiles = - !isAllTheSame(_lines.map((line) => line.url).whereType()); + _multipleFiles = !isAllTheSame(_lines.map((line) => line.url)); /// Returns whether [lines] contains any adjacent lines from the same source /// file that aren't adjacent in the original file. diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 72c61737c..ccc88bdab 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -16,12 +16,11 @@ T max(T obj1, T obj2) => /// Returns whether all elements of [iter] are the same value, according to /// `==`. -bool isAllTheSame(Iterable iter) { - Object? lastValue; - for (var value in iter) { - if (lastValue == null) { - lastValue = value; - } else if (value != lastValue) { +bool isAllTheSame(Iterable iter) { + if (iter.isEmpty) return true; + final firstValue = iter.first; + for (var value in iter.skip(1)) { + if (value != firstValue) { return false; } } diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 12382a5ba..89599dfdb 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.8.1-dev +version: 1.8.1 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/multiple_highlight_test.dart b/pkgs/source_span/test/multiple_highlight_test.dart index 6d5ec9d23..b0c28a50a 100644 --- a/pkgs/source_span/test/multiple_highlight_test.dart +++ b/pkgs/source_span/test/multiple_highlight_test.dart @@ -261,14 +261,14 @@ gibble bibble bop }); }); - test('highlights multiple files with their URLs', () { - final file2 = SourceFile.fromString(''' + group('writes headers when highlighting multiple files', () { + test('writes all file URLs', () { + final span2 = SourceFile.fromString(''' quibble bibble boop -''', url: 'file2.txt'); +''', url: 'file2.txt').span(8, 14); - expect( - file.span(31, 34).highlightMultiple('one', {file2.span(8, 14): 'two'}), - equals(""" + expect( + file.span(31, 34).highlightMultiple('one', {span2: 'two'}), equals(""" ,--> file1.txt 3 | zip zap zop | ^^^ one @@ -277,5 +277,38 @@ quibble bibble boop 1 | quibble bibble boop | ====== two '""")); + }); + + test('allows secondary spans to have null URL', () { + final span2 = SourceSpan(SourceLocation(1, sourceUrl: null), + SourceLocation(4, sourceUrl: null), 'foo'); + + expect( + file.span(31, 34).highlightMultiple('one', {span2: 'two'}), equals(""" + ,--> file1.txt +3 | zip zap zop + | ^^^ one + ' + , +1 | foo + | === two + '""")); + }); + + test('allows primary span to have null URL', () { + final span1 = SourceSpan(SourceLocation(1, sourceUrl: null), + SourceLocation(4, sourceUrl: null), 'foo'); + + expect( + span1.highlightMultiple('one', {file.span(31, 34): 'two'}), equals(""" + , +1 | foo + | ^^^ one + ' + ,--> file1.txt +3 | zip zap zop + | === two + '""")); + }); }); } From e96a1b0651fdd5ea397c51baf123ec0e068eedcd Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 5 Feb 2021 09:39:15 -0800 Subject: [PATCH 416/657] stable null safety release, clean up deps (dart-lang/package_config#105) --- pkgs/package_config/pubspec.yaml | 54 ++++++-------------------------- 1 file changed, 9 insertions(+), 45 deletions(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 5903bc8ac..4f74712d6 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.0-nullsafety.1 +version: 2.0.0 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config @@ -7,53 +7,17 @@ environment: sdk: '>=2.12.0-0 <3.0.0' dependencies: - path: ^1.8.0-nullsafety.3 + path: ^1.8.0 dev_dependencies: - build_resolvers: ^1.10.0 build_runner: ^1.10.0 - build_runner_core: ^1.10.0 build_test: ^1.3.0 - build_web_compilers: ^2.15.0 - pedantic: ^1.10.0-nullsafety.3 - test: ^1.16.0-nullsafety.4 + build_web_compilers: ^2.12.2 + pedantic: ^1.10.0-nullsafety.0 + test: ^1.16.0-nullsafety.19 +# Required due to dependency cycles dependency_overrides: - _fe_analyzer_shared: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/_fe_analyzer_shared - analyzer: - git: - url: git://github.com/dart-lang/sdk.git - path: pkg/analyzer - build_resolvers: - git: - url: git://github.com/dart-lang/build.git - path: build_resolvers - build_runner: - git: - url: git://github.com/dart-lang/build.git - path: build_runner - build_runner_core: - git: - url: git://github.com/dart-lang/build.git - path: build_runner_core - build_test: - git: - url: git://github.com/dart-lang/build.git - path: build_test - coverage: - git: git://github.com/dart-lang/coverage.git - test: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test - test_api: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_api - test_core: - git: - url: git://github.com/dart-lang/test.git - path: pkgs/test_core + test: ^1.16.0-nullsafety.19 + coverage: ^0.15.1 + analyzer: ^0.41.0 From 2d3b5e21dedc7384a1c4307aeef9ffed9b0e01f3 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Fri, 5 Feb 2021 11:05:55 -0800 Subject: [PATCH 417/657] stable null safety release (dart-lang/pub_semver#54) --- pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/pubspec.yaml | 7 ++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 371970723..5140fe277 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.0.0 + +- Stable null safety release. + # 2.0.0-nullsafety.0 - Migrate to null safety. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index dc2d6ac0c..f628d38cf 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.0.0-nullsafety.0 +version: 2.0.0 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. @@ -9,10 +9,7 @@ environment: sdk: '>=2.12.0-0 <3.0.0' dependencies: - collection: ^1.15.0-nullsafety.2 + collection: ^1.15.0 dev_dependencies: test: ^1.16.0-nullsafety.1 - -dependency_overrides: - analyzer: any From ec2b4685ecbb4ed93b1e7e8ed8e8519df810d98d Mon Sep 17 00:00:00 2001 From: Alexander Thomas Date: Tue, 9 Feb 2021 11:53:19 +0100 Subject: [PATCH 418/657] Include duplicate package name in error message (dart-lang/package_config#104) --- pkgs/package_config/lib/src/package_config_impl.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index c75111580..122999106 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -77,7 +77,7 @@ class SimplePackageConfig implements PackageConfig { var name = package.name; if (packageNames.contains(name)) { onError(PackageConfigArgumentError( - name, "packages", "Duplicate package name")); + name, "packages", "Duplicate package name '$name'")); continue; } packageNames.add(name); From 1020d5abe3c6ab5e7dd772feeecfe9a8127f5f25 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 11 Mar 2021 09:56:42 -0800 Subject: [PATCH 419/657] fix latest lints (dart-lang/source_maps#62) --- pkgs/source_maps/lib/parser.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 1f8b8175f..99a3c81b1 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -531,7 +531,7 @@ class SingleMapping extends Mapping { var url = urls[sourceUrlId]; if (sourceRoot != null) { - url = '${sourceRoot}${url}'; + url = '$sourceRoot$url'; } var sourceNameId = entry.sourceNameId; From 56a74123ffd838842e1bdf6068fa054e975435a2 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Fri, 19 Mar 2021 13:36:04 -0700 Subject: [PATCH 420/657] Use unique library names (dart-lang/package_config#107) The current dartdocs output does not link correctly because of the conflicting library names. - Use a stable SDK and dependencies. - Test on the oldest supported SDK. - Remove dependency overrides. --- .../.github/workflows/test-package.yml | 2 +- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/lib/package_config_types.dart | 2 +- pkgs/package_config/pubspec.yaml | 14 ++++---------- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 20220ab61..d0e1e23e5 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [dev] + sdk: [2.12.0, dev] steps: - uses: actions/checkout@v2 - uses: dart-lang/setup-dart@v0.3 diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 4a04782b4..9949b51db 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.1 + +- Use unique library names to correct docs issue. + ## 2.0.0 - Migrate to null safety. diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart index f0637b11b..b3fca164c 100644 --- a/pkgs/package_config/lib/package_config_types.dart +++ b/pkgs/package_config/lib/package_config_types.dart @@ -4,7 +4,7 @@ /// A package configuration is a way to assign file paths to package URIs, /// and vice-versa, -library package_config.package_config; +library package_config.package_config_types; export "src/package_config.dart" show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion; diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 4f74712d6..1ee725098 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,10 +1,10 @@ name: package_config -version: 2.0.0 +version: 2.0.1 description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' dependencies: path: ^1.8.0 @@ -13,11 +13,5 @@ dev_dependencies: build_runner: ^1.10.0 build_test: ^1.3.0 build_web_compilers: ^2.12.2 - pedantic: ^1.10.0-nullsafety.0 - test: ^1.16.0-nullsafety.19 - -# Required due to dependency cycles -dependency_overrides: - test: ^1.16.0-nullsafety.19 - coverage: ^0.15.1 - analyzer: ^0.41.0 + pedantic: ^1.10.0 + test: ^1.16.0 From 8f45e2eb9fc350caa170000868c358edfc9f1334 Mon Sep 17 00:00:00 2001 From: Franklin Yow <58489007+franklinyow@users.noreply.github.com> Date: Tue, 30 Mar 2021 16:57:08 -0700 Subject: [PATCH 421/657] Update LICENSE Changes to comply with open source review --- pkgs/source_maps/LICENSE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/LICENSE b/pkgs/source_maps/LICENSE index 5c60afea3..162572a44 100644 --- a/pkgs/source_maps/LICENSE +++ b/pkgs/source_maps/LICENSE @@ -1,4 +1,5 @@ -Copyright 2014, the Dart project authors. All rights reserved. +Copyright 2014, the Dart project authors. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,7 +10,7 @@ met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From 93dc30366a2aefc430d9b1a8313b3a5413a84e04 Mon Sep 17 00:00:00 2001 From: Franklin Yow <58489007+franklinyow@users.noreply.github.com> Date: Wed, 31 Mar 2021 15:56:53 -0700 Subject: [PATCH 422/657] Update LICENSE (dart-lang/pub_semver#55) --- pkgs/pub_semver/LICENSE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/LICENSE b/pkgs/pub_semver/LICENSE index 5c60afea3..000cd7bec 100644 --- a/pkgs/pub_semver/LICENSE +++ b/pkgs/pub_semver/LICENSE @@ -1,4 +1,5 @@ -Copyright 2014, the Dart project authors. All rights reserved. +Copyright 2014, the Dart project authors. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,7 +10,7 @@ met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From 8d79ded38d38ee92cff620cd287da9f5e2157d80 Mon Sep 17 00:00:00 2001 From: Franklin Yow <58489007+franklinyow@users.noreply.github.com> Date: Wed, 31 Mar 2021 15:58:32 -0700 Subject: [PATCH 423/657] Update LICENSE (dart-lang/source_span#75) --- pkgs/source_span/LICENSE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/LICENSE b/pkgs/source_span/LICENSE index 5c60afea3..000cd7bec 100644 --- a/pkgs/source_span/LICENSE +++ b/pkgs/source_span/LICENSE @@ -1,4 +1,5 @@ -Copyright 2014, the Dart project authors. All rights reserved. +Copyright 2014, the Dart project authors. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,7 +10,7 @@ met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From acac15a194ed1dc2daba3524bfabc1a334ca267a Mon Sep 17 00:00:00 2001 From: Franklin Yow <58489007+franklinyow@users.noreply.github.com> Date: Thu, 1 Apr 2021 12:47:12 -0700 Subject: [PATCH 424/657] Update LICENSE Changes to comply with internal review --- pkgs/pool/LICENSE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/LICENSE b/pkgs/pool/LICENSE index 5c60afea3..000cd7bec 100644 --- a/pkgs/pool/LICENSE +++ b/pkgs/pool/LICENSE @@ -1,4 +1,5 @@ -Copyright 2014, the Dart project authors. All rights reserved. +Copyright 2014, the Dart project authors. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,7 +10,7 @@ met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From f72b4a0098553482101113d83296e078022a2287 Mon Sep 17 00:00:00 2001 From: Franklin Yow <58489007+franklinyow@users.noreply.github.com> Date: Fri, 2 Apr 2021 16:07:34 -0700 Subject: [PATCH 425/657] Update LICENSE Changes to comply with internal review --- pkgs/package_config/LICENSE | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/LICENSE b/pkgs/package_config/LICENSE index f75d7c237..767000764 100644 --- a/pkgs/package_config/LICENSE +++ b/pkgs/package_config/LICENSE @@ -1,4 +1,5 @@ -Copyright 2019, the Dart project authors. All rights reserved. +Copyright 2019, the Dart project authors. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -9,7 +10,7 @@ met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From 1b5cba3eba88966f843378429399f68f8258a888 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 26 Apr 2021 10:20:02 -0700 Subject: [PATCH 426/657] fix lint (dart-lang/source_span#76) * Fix newly enforced lint * pubspec and CI cleanup --- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- pkgs/source_span/CHANGELOG.md | 2 ++ pkgs/source_span/pubspec.yaml | 6 +++--- pkgs/source_span/test/file_test.dart | 2 +- pkgs/source_span/test/span_test.dart | 5 ++--- pkgs/source_span/test/utils_test.dart | 2 +- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 0a2a87433..8c20eeb6d 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 6fda0a058..fa4b193c1 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.8.2-dev + # 1.8.1 * Fix a bug where the URL header for the highlights with multiple files would diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 89599dfdb..3343428f3 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,11 +1,11 @@ name: source_span -version: 1.8.1 +version: 1.8.2-dev description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: - sdk: ">=2.12.0-0.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: collection: ^1.15.0 @@ -13,4 +13,4 @@ dependencies: term_glyph: ^1.2.0 dev_dependencies: - test: ^1.16.0-nullsafety + test: ^1.16.0 diff --git a/pkgs/source_span/test/file_test.dart b/pkgs/source_span/test/file_test.dart index 581f03f30..dff51ee28 100644 --- a/pkgs/source_span/test/file_test.dart +++ b/pkgs/source_span/test/file_test.dart @@ -2,8 +2,8 @@ // 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:test/test.dart'; import 'package:source_span/source_span.dart'; +import 'package:test/test.dart'; void main() { late SourceFile file; diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index c27048ede..348cc9e7d 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -2,11 +2,10 @@ // 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:test/test.dart'; -import 'package:term_glyph/term_glyph.dart' as glyph; - import 'package:source_span/source_span.dart'; import 'package:source_span/src/colors.dart' as colors; +import 'package:term_glyph/term_glyph.dart' as glyph; +import 'package:test/test.dart'; void main() { late bool oldAscii; diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index 02888dfa1..293b30023 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -2,8 +2,8 @@ // 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:test/test.dart'; import 'package:source_span/src/utils.dart'; +import 'package:test/test.dart'; void main() { group('find line start', () { From a4e89f0f2e60d9ef4ea4b60ac56ba7184d74fc83 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 26 Apr 2021 10:48:40 -0700 Subject: [PATCH 427/657] update ci (dart-lang/source_maps#64) --- pkgs/source_maps/.github/workflows/test-package.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 21a3c50b6..e47bf6600 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install @@ -47,10 +47,10 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [dev] + sdk: [2.12.0, dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install From b885a1ea2d046023b19559602e3a79a5660d3dbc Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 27 Apr 2021 16:38:44 -0700 Subject: [PATCH 428/657] Fix newly enforced lint (dart-lang/pub_semver#57) --- pkgs/pub_semver/test/utils.dart | 3 +-- pkgs/pub_semver/test/version_constraint_test.dart | 3 +-- pkgs/pub_semver/test/version_range_test.dart | 3 +-- pkgs/pub_semver/test/version_union_test.dart | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index 595415abf..66f103eda 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -2,9 +2,8 @@ // 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:test/test.dart'; - import 'package:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; /// Some stock example versions to use in tests. final v003 = Version.parse('0.0.3'); diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index c9d8e611b..1434cfe8e 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -2,9 +2,8 @@ // 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:test/test.dart'; - import 'package:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; import 'utils.dart'; diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 67c7f351b..6e27c3a6f 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -2,9 +2,8 @@ // 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:test/test.dart'; - import 'package:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; import 'utils.dart'; diff --git a/pkgs/pub_semver/test/version_union_test.dart b/pkgs/pub_semver/test/version_union_test.dart index 89f9a8553..857f10e87 100644 --- a/pkgs/pub_semver/test/version_union_test.dart +++ b/pkgs/pub_semver/test/version_union_test.dart @@ -2,9 +2,8 @@ // 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:test/test.dart'; - import 'package:pub_semver/pub_semver.dart'; +import 'package:test/test.dart'; import 'utils.dart'; From 19d8ed4069f10bf1f46a18365a77fef2a85bf8e9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 27 Apr 2021 16:40:55 -0700 Subject: [PATCH 429/657] Update CI (dart-lang/pub_semver#58) --- pkgs/pub_semver/.github/workflows/test-package.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 0a2a87433..cdc25d958 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install @@ -47,10 +47,10 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [dev] + sdk: [2.12.0, dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install From 1230976b0a3526edfad0f4b2d69b961ad8e3d26f Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 26 May 2021 12:46:33 -0700 Subject: [PATCH 430/657] Use latest CI setup, test on oldest supported SDK (dart-lang/pool#55) --- pkgs/pool/.github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index f55a818da..9a455e756 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install @@ -47,10 +47,10 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [dev] + sdk: [2.12.0, dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1.0 with: sdk: ${{ matrix.sdk }} - id: install From c7adc8b35de00acd672991f76dee61d41f75e5c8 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 5 Jun 2021 13:28:33 -0700 Subject: [PATCH 431/657] Add dependabot --- pkgs/package_config/.github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 pkgs/package_config/.github/dependabot.yml diff --git a/pkgs/package_config/.github/dependabot.yml b/pkgs/package_config/.github/dependabot.yml new file mode 100644 index 000000000..430a85e7d --- /dev/null +++ b/pkgs/package_config/.github/dependabot.yml @@ -0,0 +1,11 @@ +# Set update schedule for GitHub Actions +# See https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot + +version: 2 +updates: + +- package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" From 273066187fb72762eab1fdc2fbe041bd39086564 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 5 Jun 2021 13:36:53 -0700 Subject: [PATCH 432/657] Bump dart-lang/setup-dart from 0.3 to 1 (dart-lang/package_config#110) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 0.3 to 1. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/v0.3...v1) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index d0e1e23e5..33bf62bd9 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.12.0, dev] steps: - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v0.3 + - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} - id: install From 8049cb6e3338ffcc00e7c5baaf43af20955a3ef3 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 10 Jul 2021 20:59:52 -0700 Subject: [PATCH 433/657] Dart format with latest SDK (dart-lang/package_config#111) --- pkgs/package_config/lib/src/util_io.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/src/util_io.dart b/pkgs/package_config/lib/src/util_io.dart index 8e5f0b88e..9c48f049e 100644 --- a/pkgs/package_config/lib/src/util_io.dart +++ b/pkgs/package_config/lib/src/util_io.dart @@ -98,7 +98,9 @@ String pathJoinAll(Iterable parts) { var buffer = StringBuffer(); var separator = ""; for (var part in parts) { - buffer..write(separator)..write(part); + buffer + ..write(separator) + ..write(part); separator = part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator; } From df19c5c971463a5a744fae21e20de5c7ac8cd8a9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 15 Jul 2021 10:35:22 -0700 Subject: [PATCH 434/657] Update to latest deps, fix remaining lints (dart-lang/package_config#112) --- pkgs/package_config/analysis_options.yaml | 5 - pkgs/package_config/lib/package_config.dart | 26 +- .../lib/package_config_types.dart | 4 +- pkgs/package_config/lib/src/discovery.dart | 42 +- .../lib/src/package_config.dart | 24 +- .../lib/src/package_config_impl.dart | 126 +++--- .../lib/src/package_config_io.dart | 46 +-- .../lib/src/package_config_json.dart | 82 ++-- .../package_config/lib/src/packages_file.dart | 40 +- pkgs/package_config/lib/src/util.dart | 32 +- pkgs/package_config/lib/src/util_io.dart | 22 +- pkgs/package_config/pubspec.yaml | 6 +- pkgs/package_config/test/discovery_test.dart | 208 +++++----- .../test/discovery_uri_test.dart | 182 ++++----- .../test/package_config_impl_test.dart | 144 +++---- pkgs/package_config/test/parse_test.dart | 378 +++++++++--------- pkgs/package_config/test/src/util.dart | 17 +- pkgs/package_config/test/src/util_io.dart | 16 +- 18 files changed, 718 insertions(+), 682 deletions(-) diff --git a/pkgs/package_config/analysis_options.yaml b/pkgs/package_config/analysis_options.yaml index a7854087c..a0ba68de2 100644 --- a/pkgs/package_config/analysis_options.yaml +++ b/pkgs/package_config/analysis_options.yaml @@ -3,8 +3,3 @@ # BSD-style license that can be found in the LICENSE file. include: package:pedantic/analysis_options.1.9.0.yaml -analyzer: - errors: - annotate_overrides: ignore - prefer_single_quotes: ignore - use_function_type_syntax_for_parameters: ignore diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index 3dfd8ef29..bd227e4e5 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -9,15 +9,15 @@ /// configurations in the [specified format](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). library package_config.package_config; -import "dart:io" show File, Directory; -import "dart:typed_data" show Uint8List; +import 'dart:io' show File, Directory; +import 'dart:typed_data' show Uint8List; -import "src/discovery.dart" as discover; -import "src/errors.dart" show throwError; -import "src/package_config.dart"; -import "src/package_config_io.dart"; +import 'src/discovery.dart' as discover; +import 'src/errors.dart' show throwError; +import 'src/package_config.dart'; +import 'src/package_config_io.dart'; -export "package_config_types.dart"; +export 'package_config_types.dart'; /// Reads a specific package configuration file. /// @@ -42,7 +42,7 @@ export "package_config_types.dart"; /// a valid configuration from the invalid configuration file. /// If no [onError] is provided, errors are thrown immediately. Future loadPackageConfig(File file, - {bool preferNewest = true, void onError(Object error)?}) => + {bool preferNewest = true, void Function(Object error)? onError}) => readAnyConfigFile(file, preferNewest, onError ?? throwError); /// Reads a specific package configuration URI. @@ -87,9 +87,9 @@ Future loadPackageConfig(File file, /// a valid configuration from the invalid configuration file. /// If no [onError] is provided, errors are thrown immediately. Future loadPackageConfigUri(Uri file, - {Future loader(Uri uri)?, + {Future Function(Uri uri)? loader, bool preferNewest = true, - void onError(Object error)?}) => + void Function(Object error)? onError}) => readAnyConfigFileUri(file, loader, onError ?? throwError, preferNewest); /// Finds a package configuration relative to [directory]. @@ -113,7 +113,7 @@ Future loadPackageConfigUri(Uri file, /// /// Returns `null` if no configuration file is found. Future findPackageConfig(Directory directory, - {bool recurse = true, void onError(Object error)?}) => + {bool recurse = true, void Function(Object error)? onError}) => discover.findPackageConfig(directory, recurse, onError ?? throwError); /// Finds a package configuration relative to [location]. @@ -158,8 +158,8 @@ Future findPackageConfig(Directory directory, /// Returns `null` if no configuration file is found. Future findPackageConfigUri(Uri location, {bool recurse = true, - Future loader(Uri uri)?, - void onError(Object error)?}) => + Future Function(Uri uri)? loader, + void Function(Object error)? onError}) => discover.findPackageConfigUri( location, loader, onError ?? throwError, recurse); diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart index b3fca164c..482f82ac2 100644 --- a/pkgs/package_config/lib/package_config_types.dart +++ b/pkgs/package_config/lib/package_config_types.dart @@ -6,6 +6,6 @@ /// and vice-versa, library package_config.package_config_types; -export "src/package_config.dart" +export 'src/package_config.dart' show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion; -export "src/errors.dart" show PackageConfigError; +export 'src/errors.dart' show PackageConfigError; diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index a3e01d710..a6cc451f2 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -2,21 +2,21 @@ // 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 "dart:io"; +import 'dart:io'; import 'dart:typed_data'; import 'package_config_io.dart'; -import "errors.dart"; -import "package_config_impl.dart"; -import "package_config_json.dart"; -import "packages_file.dart" as packages_file; -import "util_io.dart" show defaultLoader, pathJoin; +import 'errors.dart'; +import 'package_config_impl.dart'; +import 'package_config_json.dart'; +import 'packages_file.dart' as packages_file; +import 'util_io.dart' show defaultLoader, pathJoin; -final Uri packageConfigJsonPath = Uri(path: ".dart_tool/package_config.json"); -final Uri dotPackagesPath = Uri(path: ".packages"); -final Uri currentPath = Uri(path: "."); -final Uri parentPath = Uri(path: ".."); +final Uri packageConfigJsonPath = Uri(path: '.dart_tool/package_config.json'); +final Uri dotPackagesPath = Uri(path: '.packages'); +final Uri currentPath = Uri(path: '.'); +final Uri parentPath = Uri(path: '..'); /// Discover the package configuration for a Dart script. /// @@ -32,8 +32,8 @@ final Uri parentPath = Uri(path: ".."); /// If any of these tests succeed, a `PackageConfig` class is returned. /// Returns `null` if no configuration was found. If a configuration /// is needed, then the caller can supply [PackageConfig.empty]. -Future findPackageConfig( - Directory baseDirectory, bool recursive, void onError(Object error)) async { +Future findPackageConfig(Directory baseDirectory, + bool recursive, void Function(Object error) onError) async { var directory = baseDirectory; if (!directory.isAbsolute) directory = directory.absolute; if (!await directory.exists()) { @@ -55,16 +55,16 @@ Future findPackageConfig( /// Similar to [findPackageConfig] but based on a URI. Future findPackageConfigUri( Uri location, - Future loader(Uri uri)?, - void onError(Object error), + Future Function(Uri uri)? loader, + void Function(Object error) onError, bool recursive) async { - if (location.isScheme("package")) { + if (location.isScheme('package')) { onError(PackageConfigArgumentError( - location, "location", "Must not be a package: URI")); + location, 'location', 'Must not be a package: URI')); return null; } if (loader == null) { - if (location.isScheme("file")) { + if (location.isScheme('file')) { return findPackageConfig( Directory.fromUri(location.resolveUri(currentPath)), recursive, @@ -72,7 +72,7 @@ Future findPackageConfigUri( } loader = defaultLoader; } - if (!location.path.endsWith("/")) location = location.resolveUri(currentPath); + if (!location.path.endsWith('/')) location = location.resolveUri(currentPath); while (true) { var file = location.resolveUri(packageConfigJsonPath); var bytes = await loader(file); @@ -103,7 +103,7 @@ Future findPackageConfigUri( /// a best-effort attempt is made to return a package configuration. /// This may be the empty package configuration. Future findPackagConfigInDirectory( - Directory directory, void onError(Object error)) async { + Directory directory, void Function(Object error) onError) async { var packageConfigFile = await checkForPackageConfigJsonFile(directory); if (packageConfigFile != null) { return await readPackageConfigJsonFile(packageConfigFile, onError); @@ -118,13 +118,13 @@ Future findPackagConfigInDirectory( Future checkForPackageConfigJsonFile(Directory directory) async { assert(directory.isAbsolute); var file = - File(pathJoin(directory.path, ".dart_tool", "package_config.json")); + File(pathJoin(directory.path, '.dart_tool', 'package_config.json')); if (await file.exists()) return file; return null; } Future checkForDotPackagesFile(Directory directory) async { - var file = File(pathJoin(directory.path, ".packages")); + var file = File(pathJoin(directory.path, '.packages')); if (await file.exists()) return file; return null; } diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 26aa39622..8210132a1 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -5,7 +5,7 @@ import 'dart:typed_data'; import 'errors.dart'; -import "package_config_impl.dart"; +import 'package_config_impl.dart'; import 'package_config_json.dart'; /// A package configuration. @@ -70,7 +70,7 @@ abstract class PackageConfig { /// The result may be [PackageConfig.empty] if there is no way to /// extract useful information from the bytes. static PackageConfig parseBytes(Uint8List bytes, Uri baseUri, - {void onError(Object error)?}) => + {void Function(Object error)? onError}) => parsePackageConfigBytes(bytes, baseUri, onError ?? throwError); /// Parses a package configuration file. @@ -90,7 +90,7 @@ abstract class PackageConfig { /// The result may be [PackageConfig.empty] if there is no way to /// extract useful information from the bytes. static PackageConfig parseString(String configuration, Uri baseUri, - {void onError(Object error)?}) => + {void Function(Object error)? onError}) => parsePackageConfigString(configuration, baseUri, onError ?? throwError); /// Parses the JSON data of a package configuration file. @@ -111,7 +111,7 @@ abstract class PackageConfig { /// The result may be [PackageConfig.empty] if there is no way to /// extract useful information from the bytes. static PackageConfig parseJson(Object? jsonData, Uri baseUri, - {void onError(Object error)?}) => + {void Function(Object error)? onError}) => parsePackageConfigJson(jsonData, baseUri, onError ?? throwError); /// Writes a configuration file for this configuration on [output]. @@ -302,8 +302,8 @@ abstract class LanguageVersion implements Comparable { /// The maximal value allowed by [major] and [minor] values; static const int maxValue = 0x7FFFFFFF; factory LanguageVersion(int major, int minor) { - RangeError.checkValueInInterval(major, 0, maxValue, "major"); - RangeError.checkValueInInterval(minor, 0, maxValue, "major"); + RangeError.checkValueInInterval(major, 0, maxValue, 'major'); + RangeError.checkValueInInterval(minor, 0, maxValue, 'major'); return SimpleLanguageVersion(major, minor, null); } @@ -324,7 +324,8 @@ abstract class LanguageVersion implements Comparable { /// If [onError] is not supplied, it defaults to throwing the exception. /// If the call does not throw, then an [InvalidLanguageVersion] is returned /// containing the original [source]. - static LanguageVersion parse(String source, {void onError(Object error)?}) => + static LanguageVersion parse(String source, + {void Function(Object error)? onError}) => parseLanguageVersion(source, onError ?? throwError); /// The major language version. @@ -352,6 +353,7 @@ abstract class LanguageVersion implements Comparable { /// is greater than the latter's major version, or if they have /// the same major version and the former's minor version is greater than /// the latter's. + @override int compareTo(LanguageVersion other); /// Valid language versions with the same [major] and [minor] values are @@ -359,14 +361,17 @@ abstract class LanguageVersion implements Comparable { /// /// Invalid language versions ([InvalidLanguageVersion]) are not equal to /// any other object. + @override bool operator ==(Object other); + @override int get hashCode; /// A string representation of the language version. /// /// A valid language version is represented as /// `"${version.major}.${version.minor}"`. + @override String toString(); } @@ -377,16 +382,21 @@ abstract class LanguageVersion implements Comparable { /// which did not throw on an error. abstract class InvalidLanguageVersion implements LanguageVersion { /// The value -1 for an invalid language version. + @override int get major; /// The value -1 for an invalid language version. + @override int get minor; /// An invalid language version is only equal to itself. + @override bool operator ==(Object other); + @override int get hashCode; /// The original invalid version string. + @override String toString(); } diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 122999106..4167d35f8 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -3,21 +3,23 @@ // BSD-style license that can be found in the LICENSE file. import 'errors.dart'; -import "package_config.dart"; -import "util.dart"; +import 'package_config.dart'; +import 'util.dart'; -export "package_config.dart"; +export 'package_config.dart'; // Implementations of the main data types exposed by the API of this package. class SimplePackageConfig implements PackageConfig { + @override final int version; final Map _packages; final PackageTree _packageTree; + @override final Object? extraData; factory SimplePackageConfig(int version, Iterable packages, - [Object? extraData, void onError(Object error)?]) { + [Object? extraData, void Function(Object error)? onError]) { onError ??= throwError; var validVersion = _validateVersion(version, onError); var sortedPackages = [...packages]..sort(_compareRoot); @@ -39,17 +41,18 @@ class SimplePackageConfig implements PackageConfig { _packages = const {}, extraData = null; - static int _validateVersion(int version, void onError(Object error)) { + static int _validateVersion( + int version, void Function(Object error) onError) { if (version < 0 || version > PackageConfig.maxVersion) { - onError(PackageConfigArgumentError(version, "version", - "Must be in the range 1 to ${PackageConfig.maxVersion}")); + onError(PackageConfigArgumentError(version, 'version', + 'Must be in the range 1 to ${PackageConfig.maxVersion}')); return 2; // The minimal version supporting a SimplePackageConfig. } return version; } static PackageTree _validatePackages(Iterable originalPackages, - List packages, void onError(Object error)) { + List packages, void Function(Object error) onError) { var packageNames = {}; var tree = MutablePackageTree(); for (var originalPackage in packages) { @@ -64,8 +67,8 @@ class SimplePackageConfig implements PackageConfig { originalPackage.extraData, originalPackage.relativeRoot, (error) { if (error is PackageConfigArgumentError) { - onError(PackageConfigArgumentError(packages, "packages", - "Package ${package!.name}: ${error.message}")); + onError(PackageConfigArgumentError(packages, 'packages', + 'Package ${package!.name}: ${error.message}')); } else { onError(error); } @@ -77,7 +80,7 @@ class SimplePackageConfig implements PackageConfig { var name = package.name; if (packageNames.contains(name)) { onError(PackageConfigArgumentError( - name, "packages", "Duplicate package name '$name'")); + name, 'packages', "Duplicate package name '$name'")); continue; } packageNames.add(name); @@ -88,20 +91,20 @@ class SimplePackageConfig implements PackageConfig { if (error.isRootConflict) { onError(PackageConfigArgumentError( originalPackages, - "packages", - "Packages ${package!.name} and ${existingPackage.name} " - "have the same root directory: ${package.root}.\n")); + 'packages', + 'Packages ${package!.name} and ${existingPackage.name} ' + 'have the same root directory: ${package.root}.\n')); } else { assert(error.isPackageRootConflict); // Package is inside the package URI root of the existing package. onError(PackageConfigArgumentError( originalPackages, - "packages", - "Package ${package!.name} is inside the package URI root of " - "package ${existingPackage.name}.\n" - "${existingPackage.name} URI root: " - "${existingPackage.packageUriRoot}\n" - "${package.name} root: ${package.root}\n")); + 'packages', + 'Package ${package!.name} is inside the package URI root of ' + 'package ${existingPackage.name}.\n' + '${existingPackage.name} URI root: ' + '${existingPackage.packageUriRoot}\n' + '${package.name} root: ${package.root}\n')); } } else { // Any other error. @@ -112,8 +115,10 @@ class SimplePackageConfig implements PackageConfig { return tree; } + @override Iterable get packages => _packages.values; + @override Package? operator [](String packageName) => _packages[packageName]; /// Provides the associated package for a specific [file] (or directory). @@ -122,22 +127,25 @@ class SimplePackageConfig implements PackageConfig { /// That is, the [Package.rootUri] directory is a parent directory /// of the [file]'s location. /// Returns `null` if the file does not belong to any package. + @override Package? packageOf(Uri file) => _packageTree.packageOf(file); + @override Uri? resolve(Uri packageUri) { - var packageName = checkValidPackageUri(packageUri, "packageUri"); + var packageName = checkValidPackageUri(packageUri, 'packageUri'); return _packages[packageName]?.packageUriRoot.resolveUri( Uri(path: packageUri.path.substring(packageName.length + 1))); } + @override Uri? toPackageUri(Uri nonPackageUri) { - if (nonPackageUri.isScheme("package")) { + if (nonPackageUri.isScheme('package')) { throw PackageConfigArgumentError( - nonPackageUri, "nonPackageUri", "Must not be a package URI"); + nonPackageUri, 'nonPackageUri', 'Must not be a package URI'); } if (nonPackageUri.hasQuery || nonPackageUri.hasFragment) { - throw PackageConfigArgumentError(nonPackageUri, "nonPackageUri", - "Must not have query or fragment part"); + throw PackageConfigArgumentError(nonPackageUri, 'nonPackageUri', + 'Must not have query or fragment part'); } // Find package that file belongs to. var package = _packageTree.packageOf(nonPackageUri); @@ -147,7 +155,7 @@ class SimplePackageConfig implements PackageConfig { var root = package.packageUriRoot.toString(); if (_beginsWith(package.root.toString().length, root, path)) { var rest = path.substring(root.length); - return Uri(scheme: "package", path: "${package.name}/$rest"); + return Uri(scheme: 'package', path: '${package.name}/$rest'); } return null; } @@ -155,11 +163,17 @@ class SimplePackageConfig implements PackageConfig { /// Configuration data for a single package. class SimplePackage implements Package { + @override final String name; + @override final Uri root; + @override final Uri packageUriRoot; + @override final LanguageVersion? languageVersion; + @override final Object? extraData; + @override final bool relativeRoot; SimplePackage._(this.name, this.root, this.packageUriRoot, @@ -187,30 +201,30 @@ class SimplePackage implements Package { LanguageVersion? languageVersion, Object? extraData, bool relativeRoot, - void onError(Object error)) { + void Function(Object error) onError) { var fatalError = false; var invalidIndex = checkPackageName(name); if (invalidIndex >= 0) { onError(PackageConfigFormatException( - "Not a valid package name", name, invalidIndex)); + 'Not a valid package name', name, invalidIndex)); fatalError = true; } - if (root.isScheme("package")) { + if (root.isScheme('package')) { onError(PackageConfigArgumentError( - "$root", "root", "Must not be a package URI")); + '$root', 'root', 'Must not be a package URI')); fatalError = true; } else if (!isAbsoluteDirectoryUri(root)) { onError(PackageConfigArgumentError( - "$root", - "root", - "In package $name: Not an absolute URI with no query or fragment " - "with a path ending in /")); + '$root', + 'root', + 'In package $name: Not an absolute URI with no query or fragment ' + 'with a path ending in /')); // Try to recover. If the URI has a scheme, // then ensure that the path ends with `/`. if (!root.hasScheme) { fatalError = true; - } else if (!root.path.endsWith("/")) { - root = root.replace(path: root.path + "/"); + } else if (!root.path.endsWith('/')) { + root = root.replace(path: root.path + '/'); } } if (packageUriRoot == null) { @@ -220,13 +234,13 @@ class SimplePackage implements Package { if (!isAbsoluteDirectoryUri(packageUriRoot)) { onError(PackageConfigArgumentError( packageUriRoot, - "packageUriRoot", - "In package $name: Not an absolute URI with no query or fragment " - "with a path ending in /")); + 'packageUriRoot', + 'In package $name: Not an absolute URI with no query or fragment ' + 'with a path ending in /')); packageUriRoot = root; } else if (!isUriPrefix(root, packageUriRoot)) { - onError(PackageConfigArgumentError(packageUriRoot, "packageUriRoot", - "The package URI root is not below the package root")); + onError(PackageConfigArgumentError(packageUriRoot, 'packageUriRoot', + 'The package URI root is not below the package root')); packageUriRoot = root; } } @@ -243,7 +257,7 @@ class SimplePackage implements Package { /// Reports a format exception on [onError] if not, or if the numbers /// are too large (at most 32-bit signed integers). LanguageVersion parseLanguageVersion( - String? source, void onError(Object error)) { + String? source, void Function(Object error) onError) { var index = 0; // Reads a positive decimal numeral. Returns the value of the numeral, // or a negative number in case of an error. @@ -254,7 +268,7 @@ LanguageVersion parseLanguageVersion( int readNumeral() { const maxValue = 0x7FFFFFFF; if (index == source!.length) { - onError(PackageConfigFormatException("Missing number", source, index)); + onError(PackageConfigFormatException('Missing number', source, index)); return -1; } var start = index; @@ -262,7 +276,7 @@ LanguageVersion parseLanguageVersion( var char = source.codeUnitAt(index); var digit = char ^ 0x30; if (digit > 9) { - onError(PackageConfigFormatException("Missing number", source, index)); + onError(PackageConfigFormatException('Missing number', source, index)); return -1; } var firstDigit = digit; @@ -271,7 +285,7 @@ LanguageVersion parseLanguageVersion( value = value * 10 + digit; if (value > maxValue) { onError( - PackageConfigFormatException("Number too large", source, start)); + PackageConfigFormatException('Number too large', source, start)); return -1; } index++; @@ -281,7 +295,7 @@ LanguageVersion parseLanguageVersion( } while (digit <= 9); if (firstDigit == 0 && index > start + 1) { onError(PackageConfigFormatException( - "Leading zero not allowed", source, start)); + 'Leading zero not allowed', source, start)); } return value; } @@ -301,13 +315,14 @@ LanguageVersion parseLanguageVersion( } if (index != source.length) { onError(PackageConfigFormatException( - "Unexpected trailing character", source, index)); + 'Unexpected trailing character', source, index)); return SimpleInvalidLanguageVersion(source); } return SimpleLanguageVersion(major, minor, source); } abstract class _SimpleLanguageVersionBase implements LanguageVersion { + @override int compareTo(LanguageVersion other) { var result = major.compareTo(other.major); if (result != 0) return result; @@ -316,26 +331,34 @@ abstract class _SimpleLanguageVersionBase implements LanguageVersion { } class SimpleLanguageVersion extends _SimpleLanguageVersionBase { + @override final int major; + @override final int minor; String? _source; SimpleLanguageVersion(this.major, this.minor, this._source); + @override bool operator ==(Object other) => other is LanguageVersion && major == other.major && minor == other.minor; + @override int get hashCode => (major * 17 ^ minor * 37) & 0x3FFFFFFF; - String toString() => _source ??= "$major.$minor"; + @override + String toString() => _source ??= '$major.$minor'; } class SimpleInvalidLanguageVersion extends _SimpleLanguageVersionBase implements InvalidLanguageVersion { final String? _source; SimpleInvalidLanguageVersion(this._source); + @override int get major => -1; + @override int get minor => -1; + @override String toString() => _source!; } @@ -374,6 +397,7 @@ class MutablePackageTree implements PackageTree { /// there is no tree object associated with it. Map? _packageChildren; + @override Iterable get allPackages sync* { for (var package in packages) { yield package; @@ -399,7 +423,8 @@ class MutablePackageTree implements PackageTree { /// /// The packages are added in order of their root path. /// It is never necessary to insert a node between two existing levels. - void add(int start, SimplePackage package, void onError(Object error)) { + void add( + int start, SimplePackage package, void Function(Object error) onError) { var path = package.root.toString(); for (var treePackage in packages) { // Check is package is inside treePackage. @@ -428,6 +453,7 @@ class MutablePackageTree implements PackageTree { packages.add(package); } + @override SimplePackage? packageOf(Uri file) { return findPackageOf(0, file.toString()); } @@ -471,8 +497,10 @@ class MutablePackageTree implements PackageTree { class EmptyPackageTree implements PackageTree { const EmptyPackageTree(); + @override Iterable get allPackages => const Iterable.empty(); + @override SimplePackage? packageOf(Uri file) => null; } diff --git a/pkgs/package_config/lib/src/package_config_io.dart b/pkgs/package_config/lib/src/package_config_io.dart index d3e59be47..9aed621e0 100644 --- a/pkgs/package_config/lib/src/package_config_io.dart +++ b/pkgs/package_config/lib/src/package_config_io.dart @@ -4,31 +4,31 @@ // dart:io dependent functionality for reading and writing configuration files. -import "dart:convert"; -import "dart:io"; -import "dart:typed_data"; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; -import "errors.dart"; -import "package_config_impl.dart"; -import "package_config_json.dart"; -import "packages_file.dart" as packages_file; -import "util.dart"; -import "util_io.dart"; +import 'errors.dart'; +import 'package_config_impl.dart'; +import 'package_config_json.dart'; +import 'packages_file.dart' as packages_file; +import 'util.dart'; +import 'util_io.dart'; /// Name of directory where Dart tools store their configuration. /// /// Directory is created in the package root directory. -const dartToolDirName = ".dart_tool"; +const dartToolDirName = '.dart_tool'; /// Name of file containing new package configuration data. /// /// File is stored in the dart tool directory. -const packageConfigFileName = "package_config.json"; +const packageConfigFileName = 'package_config.json'; /// Name of file containing legacy package configuration data. /// /// File is stored in the package root directory. -const packagesFileName = ".packages"; +const packagesFileName = '.packages'; /// Reads a package configuration file. /// @@ -43,7 +43,7 @@ const packagesFileName = ".packages"; /// /// The file must exist and be a normal file. Future readAnyConfigFile( - File file, bool preferNewest, void onError(Object error)) async { + File file, bool preferNewest, void Function(Object error) onError) async { if (preferNewest && fileName(file.path) == packagesFileName) { var alternateFile = File( pathJoin(dirName(file.path), dartToolDirName, packageConfigFileName)); @@ -64,21 +64,21 @@ Future readAnyConfigFile( /// Like [readAnyConfigFile] but uses a URI and an optional loader. Future readAnyConfigFileUri( Uri file, - Future loader(Uri uri)?, - void onError(Object error), + Future Function(Uri uri)? loader, + void Function(Object error) onError, bool preferNewest) async { - if (file.isScheme("package")) { + if (file.isScheme('package')) { throw PackageConfigArgumentError( - file, "file", "Must not be a package: URI"); + file, 'file', 'Must not be a package: URI'); } if (loader == null) { - if (file.isScheme("file")) { + if (file.isScheme('file')) { return await readAnyConfigFile(File.fromUri(file), preferNewest, onError); } loader = defaultLoader; } if (preferNewest && file.pathSegments.last == packagesFileName) { - var alternateFile = file.resolve("$dartToolDirName/$packageConfigFileName"); + var alternateFile = file.resolve('$dartToolDirName/$packageConfigFileName'); Uint8List? bytes; try { bytes = await loader(alternateFile); @@ -99,7 +99,7 @@ Future readAnyConfigFileUri( } if (bytes == null) { onError(PackageConfigArgumentError( - file.toString(), "file", "File cannot be read")); + file.toString(), 'file', 'File cannot be read')); return const SimplePackageConfig.empty(); } return parseAnyConfigFile(bytes, file, onError); @@ -110,7 +110,7 @@ Future readAnyConfigFileUri( /// Assumes it's a JSON file if the first non-whitespace character /// is `{`, otherwise assumes it's a `.packages` file. PackageConfig parseAnyConfigFile( - Uint8List bytes, Uri file, void onError(Object error)) { + Uint8List bytes, Uri file, void Function(Object error) onError) { var firstChar = firstNonWhitespaceChar(bytes); if (firstChar != $lbrace) { // Definitely not a JSON object, probably a .packages. @@ -120,7 +120,7 @@ PackageConfig parseAnyConfigFile( } Future readPackageConfigJsonFile( - File file, void onError(Object error)) async { + File file, void Function(Object error) onError) async { Uint8List bytes; try { bytes = await file.readAsBytes(); @@ -132,7 +132,7 @@ Future readPackageConfigJsonFile( } Future readDotPackagesFile( - File file, void onError(Object error)) async { + File file, void Function(Object error) onError) async { Uint8List bytes; try { bytes = await file.readAsBytes(); diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index 979c35ed4..1998b6606 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -4,21 +4,21 @@ // Parsing and serialization of package configurations. -import "dart:convert"; -import "dart:typed_data"; +import 'dart:convert'; +import 'dart:typed_data'; -import "errors.dart"; -import "package_config_impl.dart"; -import "packages_file.dart" as packages_file; -import "util.dart"; +import 'errors.dart'; +import 'package_config_impl.dart'; +import 'packages_file.dart' as packages_file; +import 'util.dart'; -const String _configVersionKey = "configVersion"; -const String _packagesKey = "packages"; +const String _configVersionKey = 'configVersion'; +const String _packagesKey = 'packages'; const List _topNames = [_configVersionKey, _packagesKey]; -const String _nameKey = "name"; -const String _rootUriKey = "rootUri"; -const String _packageUriKey = "packageUri"; -const String _languageVersionKey = "languageVersion"; +const String _nameKey = 'name'; +const String _rootUriKey = 'rootUri'; +const String _packageUriKey = 'packageUri'; +const String _languageVersionKey = 'languageVersion'; const List _packageNames = [ _nameKey, _rootUriKey, @@ -26,14 +26,14 @@ const List _packageNames = [ _languageVersionKey ]; -const String _generatedKey = "generated"; -const String _generatorKey = "generator"; -const String _generatorVersionKey = "generatorVersion"; +const String _generatedKey = 'generated'; +const String _generatorKey = 'generator'; +const String _generatorVersionKey = 'generatorVersion'; final _jsonUtf8Decoder = json.fuse(utf8).decoder; PackageConfig parsePackageConfigBytes( - Uint8List bytes, Uri file, void onError(Object error)) { + Uint8List bytes, Uri file, void Function(Object error) onError) { // TODO(lrn): Make this simpler. Maybe parse directly from bytes. var jsonObject; try { @@ -46,7 +46,7 @@ PackageConfig parsePackageConfigBytes( } PackageConfig parsePackageConfigString( - String source, Uri file, void onError(Object error)) { + String source, Uri file, void Function(Object error) onError) { var jsonObject; try { jsonObject = jsonDecode(source); @@ -80,21 +80,21 @@ PackageConfig parsePackageConfigString( /// The [baseLocation] is used as base URI to resolve the "rootUri" /// URI referencestring. PackageConfig parsePackageConfigJson( - Object? json, Uri baseLocation, void onError(Object error)) { - if (!baseLocation.hasScheme || baseLocation.isScheme("package")) { - throw PackageConfigArgumentError(baseLocation.toString(), "baseLocation", - "Must be an absolute non-package: URI"); + Object? json, Uri baseLocation, void Function(Object error) onError) { + if (!baseLocation.hasScheme || baseLocation.isScheme('package')) { + throw PackageConfigArgumentError(baseLocation.toString(), 'baseLocation', + 'Must be an absolute non-package: URI'); } - if (!baseLocation.path.endsWith("/")) { - baseLocation = baseLocation.resolveUri(Uri(path: ".")); + if (!baseLocation.path.endsWith('/')) { + baseLocation = baseLocation.resolveUri(Uri(path: '.')); } String typeName() { - if (0 is T) return "int"; - if ("" is T) return "string"; - if (const [] is T) return "array"; - return "object"; + if (0 is T) return 'int'; + if ('' is T) return 'string'; + if (const [] is T) return 'array'; + return 'object'; } T? checkType(Object? value, String name, [String? packageName]) { @@ -103,7 +103,7 @@ PackageConfig parsePackageConfigJson( // and Map. Recognize which to give a better error message. var message = "$name${packageName != null ? " of package $packageName" : ""}" - " is not a JSON ${typeName()}"; + ' is not a JSON ${typeName()}'; onError(PackageConfigFormatException(message, value)); return null; } @@ -140,27 +140,27 @@ PackageConfig parsePackageConfigJson( } }); if (!hasName) { - onError(PackageConfigFormatException("Missing name entry", entry)); + onError(PackageConfigFormatException('Missing name entry', entry)); } if (!hasRoot) { - onError(PackageConfigFormatException("Missing rootUri entry", entry)); + onError(PackageConfigFormatException('Missing rootUri entry', entry)); } if (name == null || rootUri == null) return null; var parsedRootUri = Uri.parse(rootUri!); var relativeRoot = !hasAbsolutePath(parsedRootUri); var root = baseLocation.resolveUri(parsedRootUri); - if (!root.path.endsWith("/")) root = root.replace(path: root.path + "/"); + if (!root.path.endsWith('/')) root = root.replace(path: root.path + '/'); var packageRoot = root; if (packageUri != null) packageRoot = root.resolve(packageUri!); - if (!packageRoot.path.endsWith("/")) { - packageRoot = packageRoot.replace(path: packageRoot.path + "/"); + if (!packageRoot.path.endsWith('/')) { + packageRoot = packageRoot.replace(path: packageRoot.path + '/'); } LanguageVersion? version; if (languageVersion != null) { version = parseLanguageVersion(languageVersion, onError); } else if (hasVersion) { - version = SimpleInvalidLanguageVersion("invalid"); + version = SimpleInvalidLanguageVersion('invalid'); } return SimplePackage.validate( @@ -174,7 +174,7 @@ PackageConfig parsePackageConfigJson( }); } - var map = checkType>(json, "value"); + var map = checkType>(json, 'value'); if (map == null) return const SimplePackageConfig.empty(); Map? extraData; List? packageList; @@ -189,7 +189,7 @@ PackageConfig parsePackageConfigJson( var packages = []; for (var package in packageArray) { var packageMap = - checkType>(package, "package entry"); + checkType>(package, 'package entry'); if (packageMap != null) { var entry = parsePackage(packageMap); if (entry != null) { @@ -205,11 +205,11 @@ PackageConfig parsePackageConfigJson( } }); if (configVersion == null) { - onError(PackageConfigFormatException("Missing configVersion entry", json)); + onError(PackageConfigFormatException('Missing configVersion entry', json)); configVersion = 2; } if (packageList == null) { - onError(PackageConfigFormatException("Missing packages list", json)); + onError(PackageConfigFormatException('Missing packages list', json)); packageList = []; } return SimplePackageConfig(configVersion!, packageList!, extraData, (error) { @@ -221,7 +221,7 @@ PackageConfig parsePackageConfigJson( }); } -final _jsonUtf8Encoder = JsonUtf8Encoder(" "); +final _jsonUtf8Encoder = JsonUtf8Encoder(' '); void writePackageConfigJsonUtf8( PackageConfig config, Uri? baseUri, Sink> output) { @@ -234,7 +234,7 @@ void writePackageConfigJsonString( PackageConfig config, Uri? baseUri, StringSink output) { // Can be optimized. var data = packageConfigToJson(config, baseUri); - output.write(JsonEncoder.withIndent(" ").convert(data)); + output.write(JsonEncoder.withIndent(' ').convert(data)); } Map packageConfigToJson(PackageConfig config, Uri? baseUri) => @@ -270,7 +270,7 @@ void writeDotPackages(PackageConfig config, Uri baseUri, StringSink output) { if (generator is String) { var generated = extraData[_generatedKey]; var generatorVersion = extraData[_generatorVersionKey]; - comment = "Generated by $generator" + comment = 'Generated by $generator' "${generatorVersion is String ? " $generatorVersion" : ""}" "${generated is String ? " on $generated" : ""}."; } diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index ddcf8563b..244663326 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -2,10 +2,10 @@ // 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_config_impl.dart"; +import 'package_config_impl.dart'; -import "util.dart"; -import "errors.dart"; +import 'util.dart'; +import 'errors.dart'; /// The language version prior to the release of language versioning. /// @@ -31,10 +31,10 @@ final LanguageVersion _languageVersion = LanguageVersion(2, 7); /// [Package.packageUriRoot] is the same as its [Package.root] /// and it has no [Package.languageVersion]. PackageConfig parse( - List source, Uri baseLocation, void onError(Object error)) { - if (baseLocation.isScheme("package")) { + List source, Uri baseLocation, void Function(Object error) onError) { + if (baseLocation.isScheme('package')) { onError(PackageConfigArgumentError( - baseLocation, "baseLocation", "Must not be a package: URI")); + baseLocation, 'baseLocation', 'Must not be a package: URI')); return PackageConfig.empty; } var index = 0; @@ -51,7 +51,7 @@ PackageConfig parse( } if (char == $colon) { onError(PackageConfigFormatException( - "Missing package name", source, index - 1)); + 'Missing package name', source, index - 1)); ignoreLine = true; // Ignore if package name is invalid. } else { ignoreLine = char == $hash; // Ignore if comment. @@ -81,16 +81,16 @@ PackageConfig parse( var invalidIndex = checkPackageName(packageName); if (invalidIndex >= 0) { onError(PackageConfigFormatException( - "Not a valid package name", source, start + invalidIndex)); + 'Not a valid package name', source, start + invalidIndex)); continue; } if (queryStart >= 0) { onError(PackageConfigFormatException( - "Location URI must not have query", source, queryStart)); + 'Location URI must not have query', source, queryStart)); end = queryStart; } else if (fragmentStart >= 0) { onError(PackageConfigFormatException( - "Location URI must not have fragment", source, fragmentStart)); + 'Location URI must not have fragment', source, fragmentStart)); end = fragmentStart; } var packageValue = String.fromCharCodes(source, separatorIndex + 1, end); @@ -103,23 +103,23 @@ PackageConfig parse( } var relativeRoot = !hasAbsolutePath(packageLocation); packageLocation = baseLocation.resolveUri(packageLocation); - if (packageLocation.isScheme("package")) { + if (packageLocation.isScheme('package')) { onError(PackageConfigFormatException( - "Package URI as location for package", source, separatorIndex + 1)); + 'Package URI as location for package', source, separatorIndex + 1)); continue; } var path = packageLocation.path; if (!path.endsWith('/')) { - path += "/"; + path += '/'; packageLocation = packageLocation.replace(path: path); } if (packageNames.contains(packageName)) { onError(PackageConfigFormatException( - "Same package name occured more than once", source, start)); + 'Same package name occured more than once', source, start)); continue; } var rootUri = packageLocation; - if (path.endsWith("/lib/")) { + if (path.endsWith('/lib/')) { // Assume default Pub package layout. Include package itself in root. rootUri = packageLocation.replace(path: path.substring(0, path.length - 4)); @@ -158,7 +158,7 @@ PackageConfig parse( void write(StringSink output, PackageConfig config, {Uri? baseUri, String? comment}) { if (baseUri != null && !baseUri.isAbsolute) { - throw PackageConfigArgumentError(baseUri, "baseUri", "Must be absolute"); + throw PackageConfigArgumentError(baseUri, 'baseUri', 'Must be absolute'); } if (comment != null) { @@ -169,7 +169,7 @@ void write(StringSink output, PackageConfig config, output.writeln(commentLine); } } else { - output.write("# generated by package:package_config at "); + output.write('# generated by package:package_config at '); output.write(DateTime.now()); output.writeln(); } @@ -179,11 +179,11 @@ void write(StringSink output, PackageConfig config, // Validate packageName. if (!isValidPackageName(packageName)) { throw PackageConfigArgumentError( - config, "config", '"$packageName" is not a valid package name'); + config, 'config', '"$packageName" is not a valid package name'); } - if (uri.scheme == "package") { + if (uri.scheme == 'package') { throw PackageConfigArgumentError( - config, "config", "Package location must not be a package URI: $uri"); + config, 'config', 'Package location must not be a package URI: $uri'); } output.write(packageName); output.write(':'); diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index f490cdc1c..61488ac41 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -5,13 +5,13 @@ /// Utility methods used by more than one library in the package. library package_config.util; -import "errors.dart"; +import 'errors.dart'; // All ASCII characters that are valid in a package name, with space // for all the invalid ones (including space). const String _validPackageNameCharacters = r" ! $ &'()*+,-. 0123456789 ; = " - r"@ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ~ "; + r'@ABCDEFGHIJKLMNOPQRSTUVWXYZ _ abcdefghijklmnopqrstuvwxyz ~ '; /// Tests whether something is a valid Dart package name. bool isValidPackageName(String string) { @@ -47,17 +47,17 @@ int checkPackageName(String string) { /// Returns the package name extracted from the package URI, /// which is the path segment between `package:` and the first `/`. String checkValidPackageUri(Uri packageUri, String name) { - if (packageUri.scheme != "package") { - throw PackageConfigArgumentError(packageUri, name, "Not a package: URI"); + if (packageUri.scheme != 'package') { + throw PackageConfigArgumentError(packageUri, name, 'Not a package: URI'); } if (packageUri.hasAuthority) { throw PackageConfigArgumentError( - packageUri, name, "Package URIs must not have a host part"); + packageUri, name, 'Package URIs must not have a host part'); } if (packageUri.hasQuery) { // A query makes no sense if resolved to a file: URI. throw PackageConfigArgumentError( - packageUri, name, "Package URIs must not have a query part"); + packageUri, name, 'Package URIs must not have a query part'); } if (packageUri.hasFragment) { // We could leave the fragment after the URL when resolving, @@ -65,7 +65,7 @@ String checkValidPackageUri(Uri packageUri, String name) { // "package:foo/foo.dart#2" were considered different libraries. // Keep the syntax open in case we ever get multiple libraries in one file. throw PackageConfigArgumentError( - packageUri, name, "Package URIs must not have a fragment part"); + packageUri, name, 'Package URIs must not have a fragment part'); } if (packageUri.path.startsWith('/')) { throw PackageConfigArgumentError( @@ -81,7 +81,7 @@ String checkValidPackageUri(Uri packageUri, String name) { if (badIndex >= 0) { if (packageName.isEmpty) { throw PackageConfigArgumentError( - packageUri, name, "Package names mus be non-empty"); + packageUri, name, 'Package names mus be non-empty'); } if (badIndex == packageName.length) { throw PackageConfigArgumentError(packageUri, name, @@ -89,13 +89,13 @@ String checkValidPackageUri(Uri packageUri, String name) { } assert(badIndex < packageName.length); var badCharCode = packageName.codeUnitAt(badIndex); - var badChar = "U+" + badCharCode.toRadixString(16).padLeft(4, '0'); + var badChar = 'U+' + badCharCode.toRadixString(16).padLeft(4, '0'); if (badCharCode >= 0x20 && badCharCode <= 0x7e) { // Printable character. badChar = "'${packageName[badIndex]}' ($badChar)"; } throw PackageConfigArgumentError( - packageUri, name, "Package names must not contain $badChar"); + packageUri, name, 'Package names must not contain $badChar'); } return packageName; } @@ -110,7 +110,7 @@ bool isAbsoluteDirectoryUri(Uri uri) { if (uri.hasFragment) return false; if (!uri.hasScheme) return false; var path = uri.path; - if (!path.endsWith("/")) return false; + if (!path.endsWith('/')) return false; return true; } @@ -139,8 +139,8 @@ int firstNonWhitespaceChar(List bytes) { /// Appends a trailing `/` if the path doesn't end with one. String trailingSlash(String path) { - if (path.isEmpty || path.endsWith("/")) return path; - return path + "/"; + if (path.isEmpty || path.endsWith('/')) return path; + return path + '/'; } /// Whether a URI should not be considered relative to the base URI. @@ -212,15 +212,15 @@ Uri? relativizeUri(Uri? uri, Uri? baseUri) { } if (index == base.length) { if (index == target.length) { - return Uri(path: "./"); + return Uri(path: './'); } return Uri(path: target.skip(index).join('/')); } else if (index > 0) { var buffer = StringBuffer(); for (var n = base.length - index; n > 0; --n) { - buffer.write("../"); + buffer.write('../'); } - buffer.writeAll(target.skip(index), "/"); + buffer.writeAll(target.skip(index), '/'); return Uri(path: buffer.toString()); } else { return uri; diff --git a/pkgs/package_config/lib/src/util_io.dart b/pkgs/package_config/lib/src/util_io.dart index 9c48f049e..914ea384e 100644 --- a/pkgs/package_config/lib/src/util_io.dart +++ b/pkgs/package_config/lib/src/util_io.dart @@ -10,7 +10,7 @@ import 'dart:io'; import 'dart:typed_data'; Future defaultLoader(Uri uri) async { - if (uri.isScheme("file")) { + if (uri.isScheme('file')) { var file = File.fromUri(uri); try { return await file.readAsBytes(); @@ -18,14 +18,14 @@ Future defaultLoader(Uri uri) async { return null; } } - if (uri.isScheme("http") || uri.isScheme("https")) { + if (uri.isScheme('http') || uri.isScheme('https')) { return _httpGet(uri); } - throw UnsupportedError("Default URI unsupported scheme: $uri"); + throw UnsupportedError('Default URI unsupported scheme: $uri'); } Future _httpGet(Uri uri) async { - assert(uri.isScheme("http") || uri.isScheme("https")); + assert(uri.isScheme('http') || uri.isScheme('https')); var client = HttpClient(); var request = await client.getUrl(uri); var response = await request.close(); @@ -72,7 +72,7 @@ String fileName(String path) { String dirName(String path) { var separator = Platform.pathSeparator; var lastSeparator = path.lastIndexOf(separator); - if (lastSeparator < 0) return ""; + if (lastSeparator < 0) return ''; return path.substring(0, lastSeparator); } @@ -82,12 +82,12 @@ String dirName(String path) { /// inserted. String pathJoin(String part1, String part2, [String? part3]) { var separator = Platform.pathSeparator; - var separator1 = part1.endsWith(separator) ? "" : separator; + var separator1 = part1.endsWith(separator) ? '' : separator; if (part3 == null) { - return "$part1$separator1$part2"; + return '$part1$separator1$part2'; } - var separator2 = part2.endsWith(separator) ? "" : separator; - return "$part1$separator1$part2$separator2$part3"; + var separator2 = part2.endsWith(separator) ? '' : separator; + return '$part1$separator1$part2$separator2$part3'; } /// Join an unknown number of path parts with [Platform.pathSeparator]. @@ -96,13 +96,13 @@ String pathJoin(String part1, String part2, [String? part3]) { /// inserted. String pathJoinAll(Iterable parts) { var buffer = StringBuffer(); - var separator = ""; + var separator = ''; for (var part in parts) { buffer ..write(separator) ..write(part); separator = - part.endsWith(Platform.pathSeparator) ? "" : Platform.pathSeparator; + part.endsWith(Platform.pathSeparator) ? '' : Platform.pathSeparator; } return buffer.toString(); } diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 1ee725098..687c3d303 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -10,8 +10,8 @@ dependencies: path: ^1.8.0 dev_dependencies: - build_runner: ^1.10.0 - build_test: ^1.3.0 - build_web_compilers: ^2.12.2 + build_runner: ^2.0.0 + build_test: ^2.1.2 + build_web_compilers: ^3.0.0 pedantic: ^1.10.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index df2374d0b..d2c3d8330 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -5,21 +5,21 @@ @TestOn('vm') library package_config.discovery_test; -import "dart:io"; -import "package:test/test.dart"; -import "package:package_config/package_config.dart"; +import 'dart:io'; +import 'package:test/test.dart'; +import 'package:package_config/package_config.dart'; -import "src/util.dart"; -import "src/util_io.dart"; +import 'src/util.dart'; +import 'src/util_io.dart'; -const packagesFile = """ +const packagesFile = ''' # A comment foo:file:///dart/packages/foo/ bar:/dart/packages/bar/ baz:packages/baz/ -"""; +'''; -const packageConfigFile = """ +const packageConfigFile = ''' { "configVersion": 2, "packages": [ @@ -38,29 +38,29 @@ const packageConfigFile = """ ], "extra": [42] } -"""; +'''; void validatePackagesFile(PackageConfig resolver, Directory directory) { expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(Uri.parse("file:///dart/packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(Uri.directory(directory.path).resolve("packages/baz/qux/foo"))); + expect(resolver.resolve(pkg('foo', 'bar/baz')), + equals(Uri.parse('file:///dart/packages/foo/bar/baz'))); + expect(resolver.resolve(pkg('bar', 'baz/qux')), + equals(Uri.parse('file:///dart/packages/bar/baz/qux'))); + expect(resolver.resolve(pkg('baz', 'qux/foo')), + equals(Uri.directory(directory.path).resolve('packages/baz/qux/foo'))); expect([for (var p in resolver.packages) p.name], - unorderedEquals(["foo", "bar", "baz"])); + unorderedEquals(['foo', 'bar', 'baz'])); } void main() { - group("findPackages", () { + group('findPackages', () { // Finds package_config.json if there. - fileTest("package_config.json", { - ".packages": "invalid .packages file", - "script.dart": "main(){}", - "packages": {"shouldNotBeFound": {}}, - ".dart_tool": { - "package_config.json": packageConfigFile, + fileTest('package_config.json', { + '.packages': 'invalid .packages file', + 'script.dart': 'main(){}', + 'packages': {'shouldNotBeFound': {}}, + '.dart_tool': { + 'package_config.json': packageConfigFile, } }, (Directory directory) async { var config = (await findPackageConfig(directory))!; @@ -69,10 +69,10 @@ void main() { }); // Finds .packages if no package_config.json. - fileTest(".packages", { - ".packages": packagesFile, - "script.dart": "main(){}", - "packages": {"shouldNotBeFound": {}} + fileTest('.packages', { + '.packages': packagesFile, + 'script.dart': 'main(){}', + 'packages': {'shouldNotBeFound': {}} }, (Directory directory) async { var config = (await findPackageConfig(directory))!; expect(config.version, 1); // Found .packages file. @@ -80,68 +80,68 @@ void main() { }); // Finds package_config.json in super-directory. - fileTest("package_config.json recursive", { - ".packages": packagesFile, - ".dart_tool": { - "package_config.json": packageConfigFile, + fileTest('package_config.json recursive', { + '.packages': packagesFile, + '.dart_tool': { + 'package_config.json': packageConfigFile, }, - "subdir": { - "script.dart": "main(){}", + 'subdir': { + 'script.dart': 'main(){}', } }, (Directory directory) async { - var config = (await findPackageConfig(subdir(directory, "subdir/")))!; + var config = (await findPackageConfig(subdir(directory, 'subdir/')))!; expect(config.version, 2); validatePackagesFile(config, directory); }); // Finds .packages in super-directory. - fileTest(".packages recursive", { - ".packages": packagesFile, - "subdir": {"script.dart": "main(){}"} + fileTest('.packages recursive', { + '.packages': packagesFile, + 'subdir': {'script.dart': 'main(){}'} }, (Directory directory) async { var config; - config = await findPackageConfig(subdir(directory, "subdir/")); + config = await findPackageConfig(subdir(directory, 'subdir/')); expect(config.version, 1); validatePackagesFile(config, directory); }); // Does not find a packages/ directory, and returns null if nothing found. - fileTest("package directory packages not supported", { - "packages": { - "foo": {}, + fileTest('package directory packages not supported', { + 'packages': { + 'foo': {}, } }, (Directory directory) async { var config = await findPackageConfig(directory); expect(config, null); }); - group("throws", () { - fileTest("invalid .packages", { - ".packages": "not a .packages file", + group('throws', () { + fileTest('invalid .packages', { + '.packages': 'not a .packages file', }, (Directory directory) { expect(findPackageConfig(directory), throwsA(TypeMatcher())); }); - fileTest("invalid .packages as JSON", { - ".packages": packageConfigFile, + fileTest('invalid .packages as JSON', { + '.packages': packageConfigFile, }, (Directory directory) { expect(findPackageConfig(directory), throwsA(TypeMatcher())); }); - fileTest("invalid .packages", { - ".dart_tool": { - "package_config.json": "not a JSON file", + fileTest('invalid .packages', { + '.dart_tool': { + 'package_config.json': 'not a JSON file', } }, (Directory directory) { expect(findPackageConfig(directory), throwsA(TypeMatcher())); }); - fileTest("invalid .packages as INI", { - ".dart_tool": { - "package_config.json": packagesFile, + fileTest('invalid .packages as INI', { + '.dart_tool': { + 'package_config.json': packagesFile, } }, (Directory directory) { expect(findPackageConfig(directory), @@ -149,9 +149,9 @@ void main() { }); }); - group("handles error", () { - fileTest("invalid .packages", { - ".packages": "not a .packages file", + group('handles error', () { + fileTest('invalid .packages', { + '.packages': 'not a .packages file', }, (Directory directory) async { var hadError = false; await findPackageConfig(directory, @@ -162,8 +162,8 @@ void main() { expect(hadError, true); }); - fileTest("invalid .packages as JSON", { - ".packages": packageConfigFile, + fileTest('invalid .packages as JSON', { + '.packages': packageConfigFile, }, (Directory directory) async { var hadError = false; await findPackageConfig(directory, @@ -174,9 +174,9 @@ void main() { expect(hadError, true); }); - fileTest("invalid package_config not JSON", { - ".dart_tool": { - "package_config.json": "not a JSON file", + fileTest('invalid package_config not JSON', { + '.dart_tool': { + 'package_config.json': 'not a JSON file', } }, (Directory directory) async { var hadError = false; @@ -188,9 +188,9 @@ void main() { expect(hadError, true); }); - fileTest("invalid package config as INI", { - ".dart_tool": { - "package_config.json": packagesFile, + fileTest('invalid package config as INI', { + '.dart_tool': { + 'package_config.json': packagesFile, } }, (Directory directory) async { var hadError = false; @@ -204,86 +204,86 @@ void main() { }); }); - group("loadPackageConfig", () { + group('loadPackageConfig', () { // Load a specific files - group("package_config.json", () { + group('package_config.json', () { var files = { - ".packages": packagesFile, - ".dart_tool": { - "package_config.json": packageConfigFile, + '.packages': packagesFile, + '.dart_tool': { + 'package_config.json': packageConfigFile, }, }; - fileTest("directly", files, (Directory directory) async { + fileTest('directly', files, (Directory directory) async { var file = - dirFile(subdir(directory, ".dart_tool"), "package_config.json"); + dirFile(subdir(directory, '.dart_tool'), 'package_config.json'); var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); - fileTest("indirectly through .packages", files, + fileTest('indirectly through .packages', files, (Directory directory) async { - var file = dirFile(directory, ".packages"); + var file = dirFile(directory, '.packages'); var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); - fileTest("prefer .packages", files, (Directory directory) async { - var file = dirFile(directory, ".packages"); + fileTest('prefer .packages', files, (Directory directory) async { + var file = dirFile(directory, '.packages'); var config = await loadPackageConfig(file, preferNewest: false); expect(config.version, 1); validatePackagesFile(config, directory); }); }); - fileTest("package_config.json non-default name", { - ".packages": packagesFile, - "subdir": { - "pheldagriff": packageConfigFile, + fileTest('package_config.json non-default name', { + '.packages': packagesFile, + 'subdir': { + 'pheldagriff': packageConfigFile, }, }, (Directory directory) async { - var file = dirFile(directory, "subdir/pheldagriff"); + var file = dirFile(directory, 'subdir/pheldagriff'); var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); - fileTest("package_config.json named .packages", { - "subdir": { - ".packages": packageConfigFile, + fileTest('package_config.json named .packages', { + 'subdir': { + '.packages': packageConfigFile, }, }, (Directory directory) async { - var file = dirFile(directory, "subdir/.packages"); + var file = dirFile(directory, 'subdir/.packages'); var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); - fileTest(".packages", { - ".packages": packagesFile, + fileTest('.packages', { + '.packages': packagesFile, }, (Directory directory) async { - var file = dirFile(directory, ".packages"); + var file = dirFile(directory, '.packages'); var config = await loadPackageConfig(file); expect(config.version, 1); validatePackagesFile(config, directory); }); - fileTest(".packages non-default name", { - "pheldagriff": packagesFile, + fileTest('.packages non-default name', { + 'pheldagriff': packagesFile, }, (Directory directory) async { - var file = dirFile(directory, "pheldagriff"); + var file = dirFile(directory, 'pheldagriff'); var config = await loadPackageConfig(file); expect(config.version, 1); validatePackagesFile(config, directory); }); - fileTest("no config found", {}, (Directory directory) { - var file = dirFile(directory, "anyname"); + fileTest('no config found', {}, (Directory directory) { + var file = dirFile(directory, 'anyname'); expect(() => loadPackageConfig(file), throwsA(TypeMatcher())); }); - fileTest("no config found, handled", {}, (Directory directory) async { - var file = dirFile(directory, "anyname"); + fileTest('no config found, handled', {}, (Directory directory) async { + var file = dirFile(directory, 'anyname'); var hadError = false; await loadPackageConfig(file, onError: expectAsync1((error) { @@ -293,31 +293,31 @@ void main() { expect(hadError, true); }); - fileTest("specified file syntax error", { - "anyname": "syntax error", + fileTest('specified file syntax error', { + 'anyname': 'syntax error', }, (Directory directory) { - var file = dirFile(directory, "anyname"); + var file = dirFile(directory, 'anyname'); expect(() => loadPackageConfig(file), throwsFormatException); }); // Find package_config.json in subdir even if initial file syntax error. - fileTest("specified file syntax onError", { - ".packages": "syntax error", - ".dart_tool": { - "package_config.json": packageConfigFile, + fileTest('specified file syntax onError', { + '.packages': 'syntax error', + '.dart_tool': { + 'package_config.json': packageConfigFile, }, }, (Directory directory) async { - var file = dirFile(directory, ".packages"); + var file = dirFile(directory, '.packages'); var config = await loadPackageConfig(file); expect(config.version, 2); validatePackagesFile(config, directory); }); // A file starting with `{` is a package_config.json file. - fileTest("file syntax error with {", { - ".packages": "{syntax error", + fileTest('file syntax error with {', { + '.packages': '{syntax error', }, (Directory directory) { - var file = dirFile(directory, ".packages"); + var file = dirFile(directory, '.packages'); expect(() => loadPackageConfig(file), throwsFormatException); }); }); diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index a89527918..0a9b91720 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -5,19 +5,19 @@ @TestOn('vm') library package_config.discovery_test; -import "package:test/test.dart"; -import "package:package_config/package_config.dart"; +import 'package:test/test.dart'; +import 'package:package_config/package_config.dart'; -import "src/util.dart"; +import 'src/util.dart'; -const packagesFile = """ +const packagesFile = ''' # A comment foo:file:///dart/packages/foo/ bar:/dart/packages/bar/ baz:packages/baz/ -"""; +'''; -const packageConfigFile = """ +const packageConfigFile = ''' { "configVersion": 2, "packages": [ @@ -36,29 +36,29 @@ const packageConfigFile = """ ], "extra": [42] } -"""; +'''; void validatePackagesFile(PackageConfig resolver, Uri directory) { expect(resolver, isNotNull); - expect(resolver.resolve(pkg("foo", "bar/baz")), - equals(Uri.parse("file:///dart/packages/foo/bar/baz"))); - expect(resolver.resolve(pkg("bar", "baz/qux")), - equals(directory.resolve("/dart/packages/bar/baz/qux"))); - expect(resolver.resolve(pkg("baz", "qux/foo")), - equals(directory.resolve("packages/baz/qux/foo"))); + expect(resolver.resolve(pkg('foo', 'bar/baz')), + equals(Uri.parse('file:///dart/packages/foo/bar/baz'))); + expect(resolver.resolve(pkg('bar', 'baz/qux')), + equals(directory.resolve('/dart/packages/bar/baz/qux'))); + expect(resolver.resolve(pkg('baz', 'qux/foo')), + equals(directory.resolve('packages/baz/qux/foo'))); expect([for (var p in resolver.packages) p.name], - unorderedEquals(["foo", "bar", "baz"])); + unorderedEquals(['foo', 'bar', 'baz'])); } void main() { - group("findPackages", () { + group('findPackages', () { // Finds package_config.json if there. - loaderTest("package_config.json", { - ".packages": "invalid .packages file", - "script.dart": "main(){}", - "packages": {"shouldNotBeFound": {}}, - ".dart_tool": { - "package_config.json": packageConfigFile, + loaderTest('package_config.json', { + '.packages': 'invalid .packages file', + 'script.dart': 'main(){}', + 'packages': {'shouldNotBeFound': {}}, + '.dart_tool': { + 'package_config.json': packageConfigFile, } }, (directory, loader) async { var config = (await findPackageConfigUri(directory, loader: loader))!; @@ -67,10 +67,10 @@ void main() { }); // Finds .packages if no package_config.json. - loaderTest(".packages", { - ".packages": packagesFile, - "script.dart": "main(){}", - "packages": {"shouldNotBeFound": {}} + loaderTest('.packages', { + '.packages': packagesFile, + 'script.dart': 'main(){}', + 'packages': {'shouldNotBeFound': {}} }, (directory, loader) async { var config = (await findPackageConfigUri(directory, loader: loader))!; expect(config.version, 1); // Found .packages file. @@ -78,69 +78,69 @@ void main() { }); // Finds package_config.json in super-directory. - loaderTest("package_config.json recursive", { - ".packages": packagesFile, - ".dart_tool": { - "package_config.json": packageConfigFile, + loaderTest('package_config.json recursive', { + '.packages': packagesFile, + '.dart_tool': { + 'package_config.json': packageConfigFile, }, - "subdir": { - "script.dart": "main(){}", + 'subdir': { + 'script.dart': 'main(){}', } }, (directory, loader) async { - var config = (await findPackageConfigUri(directory.resolve("subdir/"), + var config = (await findPackageConfigUri(directory.resolve('subdir/'), loader: loader))!; expect(config.version, 2); validatePackagesFile(config, directory); }); // Finds .packages in super-directory. - loaderTest(".packages recursive", { - ".packages": packagesFile, - "subdir": {"script.dart": "main(){}"} + loaderTest('.packages recursive', { + '.packages': packagesFile, + 'subdir': {'script.dart': 'main(){}'} }, (directory, loader) async { var config; - config = await findPackageConfigUri(directory.resolve("subdir/"), + config = await findPackageConfigUri(directory.resolve('subdir/'), loader: loader); expect(config.version, 1); validatePackagesFile(config, directory); }); // Does not find a packages/ directory, and returns null if nothing found. - loaderTest("package directory packages not supported", { - "packages": { - "foo": {}, + loaderTest('package directory packages not supported', { + 'packages': { + 'foo': {}, } }, (Uri directory, loader) async { var config = await findPackageConfigUri(directory, loader: loader); expect(config, null); }); - loaderTest("invalid .packages", { - ".packages": "not a .packages file", + loaderTest('invalid .packages', { + '.packages': 'not a .packages file', }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), throwsA(TypeMatcher())); }); - loaderTest("invalid .packages as JSON", { - ".packages": packageConfigFile, + loaderTest('invalid .packages as JSON', { + '.packages': packageConfigFile, }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), throwsA(TypeMatcher())); }); - loaderTest("invalid .packages", { - ".dart_tool": { - "package_config.json": "not a JSON file", + loaderTest('invalid .packages', { + '.dart_tool': { + 'package_config.json': 'not a JSON file', } }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), throwsA(TypeMatcher())); }); - loaderTest("invalid .packages as INI", { - ".dart_tool": { - "package_config.json": packagesFile, + loaderTest('invalid .packages as INI', { + '.dart_tool': { + 'package_config.json': packagesFile, } }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), @@ -148,80 +148,80 @@ void main() { }); }); - group("loadPackageConfig", () { + group('loadPackageConfig', () { // Load a specific files - group("package_config.json", () { + group('package_config.json', () { var files = { - ".packages": packagesFile, - ".dart_tool": { - "package_config.json": packageConfigFile, + '.packages': packagesFile, + '.dart_tool': { + 'package_config.json': packageConfigFile, }, }; - loaderTest("directly", files, (Uri directory, loader) async { - var file = directory.resolve(".dart_tool/package_config.json"); + loaderTest('directly', files, (Uri directory, loader) async { + var file = directory.resolve('.dart_tool/package_config.json'); var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); - loaderTest("indirectly through .packages", files, + loaderTest('indirectly through .packages', files, (Uri directory, loader) async { - var file = directory.resolve(".packages"); + var file = directory.resolve('.packages'); var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); }); - loaderTest("package_config.json non-default name", { - ".packages": packagesFile, - "subdir": { - "pheldagriff": packageConfigFile, + loaderTest('package_config.json non-default name', { + '.packages': packagesFile, + 'subdir': { + 'pheldagriff': packageConfigFile, }, }, (Uri directory, loader) async { - var file = directory.resolve("subdir/pheldagriff"); + var file = directory.resolve('subdir/pheldagriff'); var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); - loaderTest("package_config.json named .packages", { - "subdir": { - ".packages": packageConfigFile, + loaderTest('package_config.json named .packages', { + 'subdir': { + '.packages': packageConfigFile, }, }, (Uri directory, loader) async { - var file = directory.resolve("subdir/.packages"); + var file = directory.resolve('subdir/.packages'); var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 2); validatePackagesFile(config, directory); }); - loaderTest(".packages", { - ".packages": packagesFile, + loaderTest('.packages', { + '.packages': packagesFile, }, (Uri directory, loader) async { - var file = directory.resolve(".packages"); + var file = directory.resolve('.packages'); var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 1); validatePackagesFile(config, directory); }); - loaderTest(".packages non-default name", { - "pheldagriff": packagesFile, + loaderTest('.packages non-default name', { + 'pheldagriff': packagesFile, }, (Uri directory, loader) async { - var file = directory.resolve("pheldagriff"); + var file = directory.resolve('pheldagriff'); var config = await loadPackageConfigUri(file, loader: loader); expect(config.version, 1); validatePackagesFile(config, directory); }); - loaderTest("no config found", {}, (Uri directory, loader) { - var file = directory.resolve("anyname"); + loaderTest('no config found', {}, (Uri directory, loader) { + var file = directory.resolve('anyname'); expect(() => loadPackageConfigUri(file, loader: loader), throwsA(isA())); }); - loaderTest("no config found, handle error", {}, + loaderTest('no config found, handle error', {}, (Uri directory, loader) async { - var file = directory.resolve("anyname"); + var file = directory.resolve('anyname'); var hadError = false; await loadPackageConfigUri(file, loader: loader, @@ -232,18 +232,18 @@ void main() { expect(hadError, true); }); - loaderTest("specified file syntax error", { - "anyname": "syntax error", + loaderTest('specified file syntax error', { + 'anyname': 'syntax error', }, (Uri directory, loader) { - var file = directory.resolve("anyname"); + var file = directory.resolve('anyname'); expect(() => loadPackageConfigUri(file, loader: loader), throwsFormatException); }); - loaderTest("specified file syntax onError", { - "anyname": "syntax error", + loaderTest('specified file syntax onError', { + 'anyname': 'syntax error', }, (directory, loader) async { - var file = directory.resolve("anyname"); + var file = directory.resolve('anyname'); var hadError = false; await loadPackageConfigUri(file, loader: loader, @@ -255,22 +255,22 @@ void main() { }); // Don't look for package_config.json if original file not named .packages. - loaderTest("specified file syntax error with alternative", { - "anyname": "syntax error", - ".dart_tool": { - "package_config.json": packageConfigFile, + loaderTest('specified file syntax error with alternative', { + 'anyname': 'syntax error', + '.dart_tool': { + 'package_config.json': packageConfigFile, }, }, (directory, loader) async { - var file = directory.resolve("anyname"); + var file = directory.resolve('anyname'); expect(() => loadPackageConfigUri(file, loader: loader), throwsFormatException); }); // A file starting with `{` is a package_config.json file. - loaderTest("file syntax error with {", { - ".packages": "{syntax error", + loaderTest('file syntax error with {', { + '.packages': '{syntax error', }, (directory, loader) async { - var file = directory.resolve(".packages"); + var file = directory.resolve('.packages'); var hadError = false; await loadPackageConfigUri(file, loader: loader, diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index bb00d1210..cef121713 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -2,39 +2,39 @@ // 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 "dart:convert" show jsonDecode; +import 'dart:convert' show jsonDecode; -import "package:package_config/package_config_types.dart"; -import "package:test/test.dart"; -import "src/util.dart"; +import 'package:package_config/package_config_types.dart'; +import 'package:test/test.dart'; +import 'src/util.dart'; void main() { var unique = Object(); - var root = Uri.file("/tmp/root/"); + var root = Uri.file('/tmp/root/'); - group("LanguageVersion", () { - test("minimal", () { + group('LanguageVersion', () { + test('minimal', () { var version = LanguageVersion(3, 5); expect(version.major, 3); expect(version.minor, 5); }); - test("negative major", () { + test('negative major', () { expect(() => LanguageVersion(-1, 1), throwsArgumentError); }); - test("negative minor", () { + test('negative minor', () { expect(() => LanguageVersion(1, -1), throwsArgumentError); }); - test("minimal parse", () { - var version = LanguageVersion.parse("3.5"); + test('minimal parse', () { + var version = LanguageVersion.parse('3.5'); expect(version.major, 3); expect(version.minor, 5); }); void failParse(String name, String input) { - test("$name - error", () { + test('$name - error', () { expect(() => LanguageVersion.parse(input), throwsA(TypeMatcher())); expect(() => LanguageVersion.parse(input), throwsFormatException); @@ -47,37 +47,37 @@ void main() { }); } - failParse("Leading zero major", "01.1"); - failParse("Leading zero minor", "1.01"); - failParse("Sign+ major", "+1.1"); - failParse("Sign- major", "-1.1"); - failParse("Sign+ minor", "1.+1"); - failParse("Sign- minor", "1.-1"); - failParse("WhiteSpace 1", " 1.1"); - failParse("WhiteSpace 2", "1 .1"); - failParse("WhiteSpace 3", "1. 1"); - failParse("WhiteSpace 4", "1.1 "); + failParse('Leading zero major', '01.1'); + failParse('Leading zero minor', '1.01'); + failParse('Sign+ major', '+1.1'); + failParse('Sign- major', '-1.1'); + failParse('Sign+ minor', '1.+1'); + failParse('Sign- minor', '1.-1'); + failParse('WhiteSpace 1', ' 1.1'); + failParse('WhiteSpace 2', '1 .1'); + failParse('WhiteSpace 3', '1. 1'); + failParse('WhiteSpace 4', '1.1 '); }); - group("Package", () { - test("minimal", () { - var package = Package("name", root, extraData: unique); - expect(package.name, "name"); + group('Package', () { + test('minimal', () { + var package = Package('name', root, extraData: unique); + expect(package.name, 'name'); expect(package.root, root); expect(package.packageUriRoot, root); expect(package.languageVersion, null); expect(package.extraData, same(unique)); }); - test("absolute package root", () { + test('absolute package root', () { var version = LanguageVersion(1, 1); - var absolute = root.resolve("foo/bar/"); - var package = Package("name", root, + var absolute = root.resolve('foo/bar/'); + var package = Package('name', root, packageUriRoot: absolute, relativeRoot: false, languageVersion: version, extraData: unique); - expect(package.name, "name"); + expect(package.name, 'name'); expect(package.root, root); expect(package.packageUriRoot, absolute); expect(package.languageVersion, version); @@ -85,12 +85,12 @@ void main() { expect(package.relativeRoot, false); }); - test("relative package root", () { - var relative = Uri.parse("foo/bar/"); + test('relative package root', () { + var relative = Uri.parse('foo/bar/'); var absolute = root.resolveUri(relative); - var package = Package("name", root, + var package = Package('name', root, packageUriRoot: relative, relativeRoot: true, extraData: unique); - expect(package.name, "name"); + expect(package.name, 'name'); expect(package.root, root); expect(package.packageUriRoot, absolute); expect(package.relativeRoot, true); @@ -98,89 +98,89 @@ void main() { expect(package.extraData, same(unique)); }); - for (var badName in ["a/z", "a:z", "", "..."]) { + for (var badName in ['a/z', 'a:z', '', '...']) { test("Invalid name '$badName'", () { expect(() => Package(badName, root), throwsPackageConfigError); }); } - test("Invalid root, not absolute", () { + test('Invalid root, not absolute', () { expect( - () => Package("name", Uri.parse("/foo/")), throwsPackageConfigError); + () => Package('name', Uri.parse('/foo/')), throwsPackageConfigError); }); - test("Invalid root, not ending in slash", () { - expect(() => Package("name", Uri.parse("file:///foo")), + test('Invalid root, not ending in slash', () { + expect(() => Package('name', Uri.parse('file:///foo')), throwsPackageConfigError); }); - test("invalid package root, not ending in slash", () { - expect(() => Package("name", root, packageUriRoot: Uri.parse("foo")), + test('invalid package root, not ending in slash', () { + expect(() => Package('name', root, packageUriRoot: Uri.parse('foo')), throwsPackageConfigError); }); - test("invalid package root, not inside root", () { - expect(() => Package("name", root, packageUriRoot: Uri.parse("../baz/")), + test('invalid package root, not inside root', () { + expect(() => Package('name', root, packageUriRoot: Uri.parse('../baz/')), throwsPackageConfigError); }); }); - group("package config", () { - test("emtpy", () { + group('package config', () { + test('emtpy', () { var empty = PackageConfig([], extraData: unique); expect(empty.version, 2); expect(empty.packages, isEmpty); expect(empty.extraData, same(unique)); - expect(empty.resolve(pkg("a", "b")), isNull); + expect(empty.resolve(pkg('a', 'b')), isNull); }); - test("single", () { - var package = Package("name", root); + test('single', () { + var package = Package('name', root); var single = PackageConfig([package], extraData: unique); expect(single.version, 2); expect(single.packages, hasLength(1)); expect(single.extraData, same(unique)); - expect(single.resolve(pkg("a", "b")), isNull); - var resolved = single.resolve(pkg("name", "a/b")); - expect(resolved, root.resolve("a/b")); + expect(single.resolve(pkg('a', 'b')), isNull); + var resolved = single.resolve(pkg('name', 'a/b')); + expect(resolved, root.resolve('a/b')); }); }); - test("writeString", () { + test('writeString', () { var config = PackageConfig([ - Package("foo", Uri.parse("file:///pkg/foo/"), - packageUriRoot: Uri.parse("file:///pkg/foo/lib/"), + Package('foo', Uri.parse('file:///pkg/foo/'), + packageUriRoot: Uri.parse('file:///pkg/foo/lib/'), relativeRoot: false, languageVersion: LanguageVersion(2, 4), - extraData: {"foo": "foo!"}), - Package("bar", Uri.parse("file:///pkg/bar/"), - packageUriRoot: Uri.parse("file:///pkg/bar/lib/"), + extraData: {'foo': 'foo!'}), + Package('bar', Uri.parse('file:///pkg/bar/'), + packageUriRoot: Uri.parse('file:///pkg/bar/lib/'), relativeRoot: true, - extraData: {"bar": "bar!"}), + extraData: {'bar': 'bar!'}), ], extraData: { - "extra": "data" + 'extra': 'data' }); var buffer = StringBuffer(); - PackageConfig.writeString(config, buffer, Uri.parse("file:///pkg/")); + PackageConfig.writeString(config, buffer, Uri.parse('file:///pkg/')); var text = buffer.toString(); var json = jsonDecode(text); // Is valid JSON. expect(json, { - "configVersion": 2, - "packages": unorderedEquals([ + 'configVersion': 2, + 'packages': unorderedEquals([ { - "name": "foo", - "rootUri": "file:///pkg/foo/", - "packageUri": "lib/", - "languageVersion": "2.4", - "foo": "foo!", + 'name': 'foo', + 'rootUri': 'file:///pkg/foo/', + 'packageUri': 'lib/', + 'languageVersion': '2.4', + 'foo': 'foo!', }, { - "name": "bar", - "rootUri": "bar/", - "packageUri": "lib/", - "bar": "bar!", + 'name': 'bar', + 'rootUri': 'bar/', + 'packageUri': 'lib/', + 'bar': 'bar!', }, ]), - "extra": "data", + 'extra': 'data', }); }); } diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index ef73c2e1e..a163e127f 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -2,61 +2,61 @@ // 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 "dart:convert"; +import 'dart:convert'; import 'dart:typed_data'; -import "package:test/test.dart"; +import 'package:test/test.dart'; -import "package:package_config/package_config_types.dart"; -import "package:package_config/src/packages_file.dart" as packages; -import "package:package_config/src/package_config_json.dart"; -import "src/util.dart"; +import 'package:package_config/package_config_types.dart'; +import 'package:package_config/src/packages_file.dart' as packages; +import 'package:package_config/src/package_config_json.dart'; +import 'src/util.dart'; void throwError(Object error) => throw error; void main() { - group(".packages", () { - test("valid", () { - var packagesFile = "# Generated by pub yadda yadda\n" - "foo:file:///foo/lib/\n" - "bar:/bar/lib/\n" - "baz:lib/\n"; + group('.packages', () { + test('valid', () { + var packagesFile = '# Generated by pub yadda yadda\n' + 'foo:file:///foo/lib/\n' + 'bar:/bar/lib/\n' + 'baz:lib/\n'; var result = packages.parse(utf8.encode(packagesFile), - Uri.parse("file:///tmp/file.dart"), throwError); + Uri.parse('file:///tmp/file.dart'), throwError); expect(result.version, 1); - expect({for (var p in result.packages) p.name}, {"foo", "bar", "baz"}); - expect(result.resolve(pkg("foo", "foo.dart")), - Uri.parse("file:///foo/lib/foo.dart")); - expect(result.resolve(pkg("bar", "bar.dart")), - Uri.parse("file:///bar/lib/bar.dart")); - expect(result.resolve(pkg("baz", "baz.dart")), - Uri.parse("file:///tmp/lib/baz.dart")); + expect({for (var p in result.packages) p.name}, {'foo', 'bar', 'baz'}); + expect(result.resolve(pkg('foo', 'foo.dart')), + Uri.parse('file:///foo/lib/foo.dart')); + expect(result.resolve(pkg('bar', 'bar.dart')), + Uri.parse('file:///bar/lib/bar.dart')); + expect(result.resolve(pkg('baz', 'baz.dart')), + Uri.parse('file:///tmp/lib/baz.dart')); - var foo = result["foo"]!; + var foo = result['foo']!; expect(foo, isNotNull); - expect(foo.root, Uri.parse("file:///foo/")); - expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); + expect(foo.root, Uri.parse('file:///foo/')); + expect(foo.packageUriRoot, Uri.parse('file:///foo/lib/')); expect(foo.languageVersion, LanguageVersion(2, 7)); expect(foo.relativeRoot, false); }); - test("valid empty", () { - var packagesFile = "# Generated by pub yadda yadda\n"; + test('valid empty', () { + var packagesFile = '# Generated by pub yadda yadda\n'; var result = packages.parse( - utf8.encode(packagesFile), Uri.file("/tmp/file.dart"), throwError); + utf8.encode(packagesFile), Uri.file('/tmp/file.dart'), throwError); expect(result.version, 1); expect({for (var p in result.packages) p.name}, {}); }); - group("invalid", () { - var baseFile = Uri.file("/tmp/file.dart"); + group('invalid', () { + var baseFile = Uri.file('/tmp/file.dart'); void testThrows(String name, String content) { test(name, () { expect( () => packages.parse(utf8.encode(content), baseFile, throwError), throwsA(TypeMatcher())); }); - test(name + ", handle error", () { + test(name + ', handle error', () { var hadError = false; packages.parse(utf8.encode(content), baseFile, (error) { hadError = true; @@ -66,21 +66,21 @@ void main() { }); } - testThrows("repeated package name", "foo:lib/\nfoo:lib\n"); - testThrows("no colon", "foo\n"); - testThrows("empty package name", ":lib/\n"); - testThrows("dot only package name", ".:lib/\n"); - testThrows("dot only package name", "..:lib/\n"); - testThrows("invalid package name character", "f\\o:lib/\n"); - testThrows("package URI", "foo:package:bar/lib/"); - testThrows("location with query", "f\\o:lib/?\n"); - testThrows("location with fragment", "f\\o:lib/#\n"); + testThrows('repeated package name', 'foo:lib/\nfoo:lib\n'); + testThrows('no colon', 'foo\n'); + testThrows('empty package name', ':lib/\n'); + testThrows('dot only package name', '.:lib/\n'); + testThrows('dot only package name', '..:lib/\n'); + testThrows('invalid package name character', 'f\\o:lib/\n'); + testThrows('package URI', 'foo:package:bar/lib/'); + testThrows('location with query', 'f\\o:lib/?\n'); + testThrows('location with fragment', 'f\\o:lib/#\n'); }); }); - group("package_config.json", () { - test("valid", () { - var packageConfigFile = """ + group('package_config.json', () { + test('valid', () { + var packageConfigFile = ''' { "configVersion": 2, "packages": [ @@ -111,62 +111,62 @@ void main() { "generator": "pub", "other": [42] } - """; + '''; var config = parsePackageConfigBytes( utf8.encode(packageConfigFile) as Uint8List, - Uri.parse("file:///tmp/.dart_tool/file.dart"), + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); expect(config.version, 2); expect({for (var p in config.packages) p.name}, - {"foo", "bar", "baz", "noslash"}); + {'foo', 'bar', 'baz', 'noslash'}); - expect(config.resolve(pkg("foo", "foo.dart")), - Uri.parse("file:///foo/lib/foo.dart")); - expect(config.resolve(pkg("bar", "bar.dart")), - Uri.parse("file:///bar/lib/bar.dart")); - expect(config.resolve(pkg("baz", "baz.dart")), - Uri.parse("file:///tmp/lib/baz.dart")); + expect(config.resolve(pkg('foo', 'foo.dart')), + Uri.parse('file:///foo/lib/foo.dart')); + expect(config.resolve(pkg('bar', 'bar.dart')), + Uri.parse('file:///bar/lib/bar.dart')); + expect(config.resolve(pkg('baz', 'baz.dart')), + Uri.parse('file:///tmp/lib/baz.dart')); - var foo = config["foo"]!; + var foo = config['foo']!; expect(foo, isNotNull); - expect(foo.root, Uri.parse("file:///foo/")); - expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/")); + expect(foo.root, Uri.parse('file:///foo/')); + expect(foo.packageUriRoot, Uri.parse('file:///foo/lib/')); expect(foo.languageVersion, LanguageVersion(2, 5)); - expect(foo.extraData, {"nonstandard": true}); + expect(foo.extraData, {'nonstandard': true}); expect(foo.relativeRoot, false); - var bar = config["bar"]!; + var bar = config['bar']!; expect(bar, isNotNull); - expect(bar.root, Uri.parse("file:///bar/")); - expect(bar.packageUriRoot, Uri.parse("file:///bar/lib/")); + expect(bar.root, Uri.parse('file:///bar/')); + expect(bar.packageUriRoot, Uri.parse('file:///bar/lib/')); expect(bar.languageVersion, LanguageVersion(9999, 9999)); expect(bar.extraData, null); expect(bar.relativeRoot, false); - var baz = config["baz"]!; + var baz = config['baz']!; expect(baz, isNotNull); - expect(baz.root, Uri.parse("file:///tmp/")); - expect(baz.packageUriRoot, Uri.parse("file:///tmp/lib/")); + expect(baz.root, Uri.parse('file:///tmp/')); + expect(baz.packageUriRoot, Uri.parse('file:///tmp/lib/')); expect(baz.languageVersion, null); expect(baz.relativeRoot, true); // No slash after root or package root. One is inserted. - var noslash = config["noslash"]!; + var noslash = config['noslash']!; expect(noslash, isNotNull); - expect(noslash.root, Uri.parse("file:///tmp/noslash/")); - expect(noslash.packageUriRoot, Uri.parse("file:///tmp/noslash/lib/")); + expect(noslash.root, Uri.parse('file:///tmp/noslash/')); + expect(noslash.packageUriRoot, Uri.parse('file:///tmp/noslash/lib/')); expect(noslash.languageVersion, null); expect(noslash.relativeRoot, true); expect(config.extraData, { - "generator": "pub", - "other": [42] + 'generator': 'pub', + 'other': [42] }); }); - test("valid other order", () { + test('valid other order', () { // The ordering in the file is not important. - var packageConfigFile = """ + var packageConfigFile = ''' { "generator": "pub", "other": [42], @@ -191,23 +191,23 @@ void main() { ], "configVersion": 2 } - """; + '''; var config = parsePackageConfigBytes( utf8.encode(packageConfigFile) as Uint8List, - Uri.parse("file:///tmp/.dart_tool/file.dart"), + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); expect(config.version, 2); - expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"}); + expect({for (var p in config.packages) p.name}, {'foo', 'bar', 'baz'}); - expect(config.resolve(pkg("foo", "foo.dart")), - Uri.parse("file:///foo/lib/foo.dart")); - expect(config.resolve(pkg("bar", "bar.dart")), - Uri.parse("file:///bar/lib/bar.dart")); - expect(config.resolve(pkg("baz", "baz.dart")), - Uri.parse("file:///tmp/lib/baz.dart")); + expect(config.resolve(pkg('foo', 'foo.dart')), + Uri.parse('file:///foo/lib/foo.dart')); + expect(config.resolve(pkg('bar', 'bar.dart')), + Uri.parse('file:///bar/lib/bar.dart')); + expect(config.resolve(pkg('baz', 'baz.dart')), + Uri.parse('file:///tmp/lib/baz.dart')); expect(config.extraData, { - "generator": "pub", - "other": [42] + 'generator': 'pub', + 'other': [42] }); }); @@ -217,94 +217,94 @@ void main() { var pkgs = '"packages":[]'; var name = '"name":"foo"'; var root = '"rootUri":"/foo/"'; - test("minimal", () { + test('minimal', () { var config = parsePackageConfigBytes( - utf8.encode("{$cfg,$pkgs}") as Uint8List, - Uri.parse("file:///tmp/.dart_tool/file.dart"), + utf8.encode('{$cfg,$pkgs}') as Uint8List, + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); expect(config.version, 2); expect(config.packages, isEmpty); }); - test("minimal package", () { + test('minimal package', () { // A package must have a name and a rootUri, the remaining properties // are optional. var config = parsePackageConfigBytes( utf8.encode('{$cfg,"packages":[{$name,$root}]}') as Uint8List, - Uri.parse("file:///tmp/.dart_tool/file.dart"), + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); expect(config.version, 2); - expect(config.packages.first.name, "foo"); + expect(config.packages.first.name, 'foo'); }); - test("nested packages", () { + test('nested packages', () { var configBytes = utf8.encode(json.encode({ - "configVersion": 2, - "packages": [ - {"name": "foo", "rootUri": "/foo/", "packageUri": "lib/"}, - {"name": "bar", "rootUri": "/foo/bar/", "packageUri": "lib/"}, - {"name": "baz", "rootUri": "/foo/bar/baz/", "packageUri": "lib/"}, - {"name": "qux", "rootUri": "/foo/qux/", "packageUri": "lib/"}, + 'configVersion': 2, + 'packages': [ + {'name': 'foo', 'rootUri': '/foo/', 'packageUri': 'lib/'}, + {'name': 'bar', 'rootUri': '/foo/bar/', 'packageUri': 'lib/'}, + {'name': 'baz', 'rootUri': '/foo/bar/baz/', 'packageUri': 'lib/'}, + {'name': 'qux', 'rootUri': '/foo/qux/', 'packageUri': 'lib/'}, ] })); var config = parsePackageConfigBytes(configBytes as Uint8List, - Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError); + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); expect(config.version, 2); - expect(config.packageOf(Uri.parse("file:///foo/lala/lala.dart"))!.name, - "foo"); - expect(config.packageOf(Uri.parse("file:///foo/bar/lala.dart"))!.name, - "bar"); - expect(config.packageOf(Uri.parse("file:///foo/bar/baz/lala.dart"))!.name, - "baz"); - expect(config.packageOf(Uri.parse("file:///foo/qux/lala.dart"))!.name, - "qux"); - expect(config.toPackageUri(Uri.parse("file:///foo/lib/diz")), - Uri.parse("package:foo/diz")); - expect(config.toPackageUri(Uri.parse("file:///foo/bar/lib/diz")), - Uri.parse("package:bar/diz")); - expect(config.toPackageUri(Uri.parse("file:///foo/bar/baz/lib/diz")), - Uri.parse("package:baz/diz")); - expect(config.toPackageUri(Uri.parse("file:///foo/qux/lib/diz")), - Uri.parse("package:qux/diz")); + expect(config.packageOf(Uri.parse('file:///foo/lala/lala.dart'))!.name, + 'foo'); + expect(config.packageOf(Uri.parse('file:///foo/bar/lala.dart'))!.name, + 'bar'); + expect(config.packageOf(Uri.parse('file:///foo/bar/baz/lala.dart'))!.name, + 'baz'); + expect(config.packageOf(Uri.parse('file:///foo/qux/lala.dart'))!.name, + 'qux'); + expect(config.toPackageUri(Uri.parse('file:///foo/lib/diz')), + Uri.parse('package:foo/diz')); + expect(config.toPackageUri(Uri.parse('file:///foo/bar/lib/diz')), + Uri.parse('package:bar/diz')); + expect(config.toPackageUri(Uri.parse('file:///foo/bar/baz/lib/diz')), + Uri.parse('package:baz/diz')); + expect(config.toPackageUri(Uri.parse('file:///foo/qux/lib/diz')), + Uri.parse('package:qux/diz')); }); - group("invalid", () { + group('invalid', () { void testThrows(String name, String source) { test(name, () { expect( () => parsePackageConfigBytes(utf8.encode(source) as Uint8List, - Uri.parse("file:///tmp/.dart_tool/file.dart"), throwError), + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError), throwsA(TypeMatcher())); }); } - testThrows("comment", '# comment\n {$cfg,$pkgs}'); - testThrows(".packages file", 'foo:/foo\n'); - testThrows("no configVersion", '{$pkgs}'); - testThrows("no packages", '{$cfg}'); - group("config version:", () { - testThrows("null", '{"configVersion":null,$pkgs}'); - testThrows("string", '{"configVersion":"2",$pkgs}'); - testThrows("array", '{"configVersion":[2],$pkgs}'); + testThrows('comment', '# comment\n {$cfg,$pkgs}'); + testThrows('.packages file', 'foo:/foo\n'); + testThrows('no configVersion', '{$pkgs}'); + testThrows('no packages', '{$cfg}'); + group('config version:', () { + testThrows('null', '{"configVersion":null,$pkgs}'); + testThrows('string', '{"configVersion":"2",$pkgs}'); + testThrows('array', '{"configVersion":[2],$pkgs}'); }); - group("packages:", () { - testThrows("null", '{$cfg,"packages":null}'); - testThrows("string", '{$cfg,"packages":"foo"}'); - testThrows("object", '{$cfg,"packages":{}}'); + group('packages:', () { + testThrows('null', '{$cfg,"packages":null}'); + testThrows('string', '{$cfg,"packages":"foo"}'); + testThrows('object', '{$cfg,"packages":{}}'); }); - group("packages entry:", () { - testThrows("null", '{$cfg,"packages":[null]}'); - testThrows("string", '{$cfg,"packages":["foo"]}'); - testThrows("array", '{$cfg,"packages":[[]]}'); + group('packages entry:', () { + testThrows('null', '{$cfg,"packages":[null]}'); + testThrows('string', '{$cfg,"packages":["foo"]}'); + testThrows('array', '{$cfg,"packages":[[]]}'); }); - group("package", () { - testThrows("no name", '{$cfg,"packages":[{$root}]}'); - group("name:", () { - testThrows("null", '{$cfg,"packages":[{"name":null,$root}]}'); - testThrows("num", '{$cfg,"packages":[{"name":1,$root}]}'); - testThrows("object", '{$cfg,"packages":[{"name":{},$root}]}'); - testThrows("empty", '{$cfg,"packages":[{"name":"",$root}]}'); - testThrows("one-dot", '{$cfg,"packages":[{"name":".",$root}]}'); - testThrows("two-dot", '{$cfg,"packages":[{"name":"..",$root}]}'); + group('package', () { + testThrows('no name', '{$cfg,"packages":[{$root}]}'); + group('name:', () { + testThrows('null', '{$cfg,"packages":[{"name":null,$root}]}'); + testThrows('num', '{$cfg,"packages":[{"name":1,$root}]}'); + testThrows('object', '{$cfg,"packages":[{"name":{},$root}]}'); + testThrows('empty', '{$cfg,"packages":[{"name":"",$root}]}'); + testThrows('one-dot', '{$cfg,"packages":[{"name":".",$root}]}'); + testThrows('two-dot', '{$cfg,"packages":[{"name":"..",$root}]}'); testThrows( "invalid char '\\'", '{$cfg,"packages":[{"name":"\\",$root}]}'); testThrows( @@ -313,82 +313,82 @@ void main() { "invalid char ' '", '{$cfg,"packages":[{"name":" ",$root}]}'); }); - testThrows("no root", '{$cfg,"packages":[{$name}]}'); - group("root:", () { - testThrows("null", '{$cfg,"packages":[{$name,"rootUri":null}]}'); - testThrows("num", '{$cfg,"packages":[{$name,"rootUri":1}]}'); - testThrows("object", '{$cfg,"packages":[{$name,"rootUri":{}}]}'); - testThrows("fragment", '{$cfg,"packages":[{$name,"rootUri":"x/#"}]}'); - testThrows("query", '{$cfg,"packages":[{$name,"rootUri":"x/?"}]}'); - testThrows("package-URI", + testThrows('no root', '{$cfg,"packages":[{$name}]}'); + group('root:', () { + testThrows('null', '{$cfg,"packages":[{$name,"rootUri":null}]}'); + testThrows('num', '{$cfg,"packages":[{$name,"rootUri":1}]}'); + testThrows('object', '{$cfg,"packages":[{$name,"rootUri":{}}]}'); + testThrows('fragment', '{$cfg,"packages":[{$name,"rootUri":"x/#"}]}'); + testThrows('query', '{$cfg,"packages":[{$name,"rootUri":"x/?"}]}'); + testThrows('package-URI', '{$cfg,"packages":[{$name,"rootUri":"package:x/x/"}]}'); }); - group("package-URI root:", () { + group('package-URI root:', () { testThrows( - "null", '{$cfg,"packages":[{$name,$root,"packageUri":null}]}'); - testThrows("num", '{$cfg,"packages":[{$name,$root,"packageUri":1}]}'); + 'null', '{$cfg,"packages":[{$name,$root,"packageUri":null}]}'); + testThrows('num', '{$cfg,"packages":[{$name,$root,"packageUri":1}]}'); testThrows( - "object", '{$cfg,"packages":[{$name,$root,"packageUri":{}}]}'); - testThrows("fragment", + 'object', '{$cfg,"packages":[{$name,$root,"packageUri":{}}]}'); + testThrows('fragment', '{$cfg,"packages":[{$name,$root,"packageUri":"x/#"}]}'); testThrows( - "query", '{$cfg,"packages":[{$name,$root,"packageUri":"x/?"}]}'); - testThrows("package: URI", + 'query', '{$cfg,"packages":[{$name,$root,"packageUri":"x/?"}]}'); + testThrows('package: URI', '{$cfg,"packages":[{$name,$root,"packageUri":"package:x/x/"}]}'); - testThrows("not inside root", + testThrows('not inside root', '{$cfg,"packages":[{$name,$root,"packageUri":"../other/"}]}'); }); - group("language version", () { - testThrows("null", + group('language version', () { + testThrows('null', '{$cfg,"packages":[{$name,$root,"languageVersion":null}]}'); testThrows( - "num", '{$cfg,"packages":[{$name,$root,"languageVersion":1}]}'); - testThrows("object", + 'num', '{$cfg,"packages":[{$name,$root,"languageVersion":1}]}'); + testThrows('object', '{$cfg,"packages":[{$name,$root,"languageVersion":{}}]}'); - testThrows("empty", + testThrows('empty', '{$cfg,"packages":[{$name,$root,"languageVersion":""}]}'); - testThrows("non number.number", + testThrows('non number.number', '{$cfg,"packages":[{$name,$root,"languageVersion":"x.1"}]}'); - testThrows("number.non number", + testThrows('number.non number', '{$cfg,"packages":[{$name,$root,"languageVersion":"1.x"}]}'); - testThrows("non number", + testThrows('non number', '{$cfg,"packages":[{$name,$root,"languageVersion":"x"}]}'); - testThrows("one number", + testThrows('one number', '{$cfg,"packages":[{$name,$root,"languageVersion":"1"}]}'); - testThrows("three numbers", + testThrows('three numbers', '{$cfg,"packages":[{$name,$root,"languageVersion":"1.2.3"}]}'); - testThrows("leading zero first", + testThrows('leading zero first', '{$cfg,"packages":[{$name,$root,"languageVersion":"01.1"}]}'); - testThrows("leading zero second", + testThrows('leading zero second', '{$cfg,"packages":[{$name,$root,"languageVersion":"1.01"}]}'); - testThrows("trailing-", + testThrows('trailing-', '{$cfg,"packages":[{$name,$root,"languageVersion":"1.1-1"}]}'); - testThrows("trailing+", + testThrows('trailing+', '{$cfg,"packages":[{$name,$root,"languageVersion":"1.1+1"}]}'); }); }); - testThrows("duplicate package name", + testThrows('duplicate package name', '{$cfg,"packages":[{$name,$root},{$name,"rootUri":"/other/"}]}'); - testThrows("same roots", + testThrows('same roots', '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); testThrows( // The roots of foo and bar are the same. - "same roots", + 'same roots', '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); testThrows( // The root of bar is inside the root of foo, // but the package root of foo is inside the root of bar. - "between root and lib", + 'between root and lib', '{$cfg,"packages":[' '{"name":"foo","rootUri":"/foo/","packageUri":"bar/lib/"},' '{"name":"bar","rootUri":"/foo/bar/"},"packageUri":"baz/lib"]}'); }); }); - group("factories", () { + group('factories', () { void testConfig(String name, PackageConfig config, PackageConfig expected) { group(name, () { - test("structure", () { + test('structure', () { expect(config.version, expected.version); var expectedPackages = {for (var p in expected.packages) p.name}; var actualPackages = {for (var p in config.packages) p.name}; @@ -396,20 +396,20 @@ void main() { }); for (var package in config.packages) { var name = package.name; - test("package $name", () { + test('package $name', () { var expectedPackage = expected[name]!; expect(expectedPackage, isNotNull); - expect(package.root, expectedPackage.root, reason: "root"); + expect(package.root, expectedPackage.root, reason: 'root'); expect(package.packageUriRoot, expectedPackage.packageUriRoot, - reason: "package root"); + reason: 'package root'); expect(package.languageVersion, expectedPackage.languageVersion, - reason: "languageVersion"); + reason: 'languageVersion'); }); } }); } - var configText = """ + var configText = ''' {"configVersion": 2, "packages": [ { "name": "foo", @@ -418,37 +418,37 @@ void main() { "languageVersion": "1.2" } ]} - """; - var baseUri = Uri.parse("file:///start/"); + '''; + var baseUri = Uri.parse('file:///start/'); var config = PackageConfig([ - Package("foo", Uri.parse("file:///start/foo/"), - packageUriRoot: Uri.parse("file:///start/foo/bar/"), + Package('foo', Uri.parse('file:///start/foo/'), + packageUriRoot: Uri.parse('file:///start/foo/bar/'), languageVersion: LanguageVersion(1, 2)) ]); testConfig( - "string", PackageConfig.parseString(configText, baseUri), config); + 'string', PackageConfig.parseString(configText, baseUri), config); testConfig( - "bytes", + 'bytes', PackageConfig.parseBytes( Uint8List.fromList(configText.codeUnits), baseUri), config); - testConfig("json", PackageConfig.parseJson(jsonDecode(configText), baseUri), + testConfig('json', PackageConfig.parseJson(jsonDecode(configText), baseUri), config); - baseUri = Uri.parse("file:///start2/"); + baseUri = Uri.parse('file:///start2/'); config = PackageConfig([ - Package("foo", Uri.parse("file:///start2/foo/"), - packageUriRoot: Uri.parse("file:///start2/foo/bar/"), + Package('foo', Uri.parse('file:///start2/foo/'), + packageUriRoot: Uri.parse('file:///start2/foo/bar/'), languageVersion: LanguageVersion(1, 2)) ]); testConfig( - "string2", PackageConfig.parseString(configText, baseUri), config); + 'string2', PackageConfig.parseString(configText, baseUri), config); testConfig( - "bytes2", + 'bytes2', PackageConfig.parseBytes( Uint8List.fromList(configText.codeUnits), baseUri), config); - testConfig("json2", + testConfig('json2', PackageConfig.parseJson(jsonDecode(configText), baseUri), config); }); } diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart index 2b262e1b2..32e92174c 100644 --- a/pkgs/package_config/test/src/util.dart +++ b/pkgs/package_config/test/src/util.dart @@ -5,13 +5,13 @@ import 'dart:convert'; import 'dart:typed_data'; -import "package:test/test.dart"; +import 'package:test/test.dart'; /// Creates a package: URI. Uri pkg(String packageName, String packagePath) { var path = "$packageName${packagePath.startsWith('/') ? "" : "/"}$packagePath"; - return Uri(scheme: "package", path: path); + return Uri(scheme: 'package', path: path); } // Remove if not used. @@ -33,13 +33,16 @@ ${packages.map((nu) => """ /// Description is a map, each key is a file entry. If the value is a map, /// it's a subdirectory, otherwise it's a file and the value is the content /// as a string. -void loaderTest(String name, Map description, - void loaderTest(Uri root, Future loader(Uri uri))) { - var root = Uri(scheme: "test", path: "/"); +void loaderTest( + String name, + Map description, + void Function(Uri root, Future Function(Uri) loader) loaderTest, +) { + var root = Uri(scheme: 'test', path: '/'); Future loader(Uri uri) async { var path = uri.path; - if (!uri.isScheme("test") || !path.startsWith("/")) return null; - var parts = path.split("/"); + if (!uri.isScheme('test') || !path.startsWith('/')) return null; + var parts = path.split('/'); Object? value = description; for (var i = 1; i < parts.length; i++) { if (value is! Map) return null; diff --git a/pkgs/package_config/test/src/util_io.dart b/pkgs/package_config/test/src/util_io.dart index 37deee9e1..109dff112 100644 --- a/pkgs/package_config/test/src/util_io.dart +++ b/pkgs/package_config/test/src/util_io.dart @@ -2,10 +2,10 @@ // 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 "dart:io"; +import 'dart:io'; -import "package:test/test.dart"; -import "package:package_config/src/util_io.dart"; +import 'package:test/test.dart'; +import 'package:package_config/src/util_io.dart'; /// Creates a directory structure from [description] and runs [fileTest]. /// @@ -14,9 +14,9 @@ import "package:package_config/src/util_io.dart"; /// as a string. /// Introduces a group to hold the [setUp]/[tearDown] logic. void fileTest(String name, Map description, - void fileTest(Directory directory)) { - group("file-test", () { - var tempDir = Directory.systemTemp.createTempSync("pkgcfgtest"); + void Function(Directory directory) fileTest) { + group('file-test', () { + var tempDir = Directory.systemTemp.createTempSync('pkgcfgtest'); setUp(() { _createFiles(tempDir, description); }); @@ -44,7 +44,7 @@ void fileTest(String name, Map description, // Creates temporary files in the target directory. void _createFiles(Directory target, Map description) { description.forEach((name, content) { - var entryName = pathJoin(target.path, "$name"); + var entryName = pathJoin(target.path, '$name'); if (content is Map) { _createFiles(Directory(entryName)..createSync(), content); } else { @@ -55,7 +55,7 @@ void _createFiles(Directory target, Map description) { /// Creates a [Directory] for a subdirectory of [parent]. Directory subdir(Directory parent, String dirName) => - Directory(pathJoinAll([parent.path, ...dirName.split("/")])); + Directory(pathJoinAll([parent.path, ...dirName.split('/')])); /// Creates a [File] for an entry in the [directory] directory. File dirFile(Directory directory, String fileName) => From 028521a02f773c2ef8841eee3dd9d8c4e83bb25b Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Mon, 2 Aug 2021 15:56:51 +0100 Subject: [PATCH 435/657] Fix typo: "packjage_config" (dart-lang/package_config#113) --- pkgs/package_config/lib/src/package_config.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 8210132a1..3c5cc5196 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -204,7 +204,7 @@ abstract class PackageConfig { /// Extra data associated with the package configuration. /// /// The data may be in any format, depending on who introduced it. - /// The standard `packjage_config.json` file storage will only store + /// The standard `package_config.json` file storage will only store /// JSON-like list/map data structures. Object? get extraData; } From 0061cdb33d393d3732ff897c1e6d10911369d927 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Fri, 6 Aug 2021 00:57:55 -0700 Subject: [PATCH 436/657] Ignore unnecessary casts from utf8.encode (dart-lang/package_config#114) An upcoming SDK change will change the return type to `Uint8List` which makes the casts unnecessary and introduces analyzer diagnostics. Preemptively ignore these to make it easier to roll the SDK. https://dart-review.googlesource.com/c/sdk/+/208190 --- pkgs/package_config/CHANGELOG.md | 2 ++ pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/parse_test.dart | 6 ++++++ pkgs/package_config/test/src/util.dart | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 9949b51db..898ebc4bb 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.2-dev + ## 2.0.1 - Use unique library names to correct docs issue. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 687c3d303..5cc9cc0a5 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.1 +version: 2.0.2-dev description: Support for working with Package Configuration files. homepage: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index a163e127f..d5c2e7268 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -113,6 +113,7 @@ void main() { } '''; var config = parsePackageConfigBytes( + // ignore: unnecessary_cast utf8.encode(packageConfigFile) as Uint8List, Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); @@ -193,6 +194,7 @@ void main() { } '''; var config = parsePackageConfigBytes( + // ignore: unnecessary_cast utf8.encode(packageConfigFile) as Uint8List, Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); @@ -219,6 +221,7 @@ void main() { var root = '"rootUri":"/foo/"'; test('minimal', () { var config = parsePackageConfigBytes( + // ignore: unnecessary_cast utf8.encode('{$cfg,$pkgs}') as Uint8List, Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); @@ -229,6 +232,7 @@ void main() { // A package must have a name and a rootUri, the remaining properties // are optional. var config = parsePackageConfigBytes( + // ignore: unnecessary_cast utf8.encode('{$cfg,"packages":[{$name,$root}]}') as Uint8List, Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); @@ -246,6 +250,7 @@ void main() { {'name': 'qux', 'rootUri': '/foo/qux/', 'packageUri': 'lib/'}, ] })); + // ignore: unnecessary_cast var config = parsePackageConfigBytes(configBytes as Uint8List, Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); expect(config.version, 2); @@ -271,6 +276,7 @@ void main() { void testThrows(String name, String source) { test(name, () { expect( + // ignore: unnecessary_cast () => parsePackageConfigBytes(utf8.encode(source) as Uint8List, Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError), throwsA(TypeMatcher())); diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart index 32e92174c..246e12964 100644 --- a/pkgs/package_config/test/src/util.dart +++ b/pkgs/package_config/test/src/util.dart @@ -48,6 +48,7 @@ void loaderTest( if (value is! Map) return null; value = value[parts[i]]; } + // ignore: unnecessary_cast if (value is String) return utf8.encode(value) as Uint8List; return null; } From c27d9edc05f5707947a97cb5e3f23ca35d30fc27 Mon Sep 17 00:00:00 2001 From: Konstantin Scheglov Date: Fri, 3 Sep 2021 15:25:21 -0600 Subject: [PATCH 437/657] Fix pre-existing HintCode.UNNECESSARY_TYPE_CHECK_TRUE (dart-lang/pub_semver#60) --- pkgs/pub_semver/test/version_constraint_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/pub_semver/test/version_constraint_test.dart b/pkgs/pub_semver/test/version_constraint_test.dart index 1434cfe8e..4fbcbe0cb 100644 --- a/pkgs/pub_semver/test/version_constraint_test.dart +++ b/pkgs/pub_semver/test/version_constraint_test.dart @@ -36,7 +36,6 @@ void main() { test('parses "any"', () { var constraint = VersionConstraint.parse('any'); - expect(constraint is VersionConstraint, isTrue); expect( constraint, allows(Version.parse('0.0.0'), Version.parse('1.2.3'), From 96dee58f0b60ca3dff64e5f0f047e4b730e86526 Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Fri, 10 Sep 2021 14:27:49 +0200 Subject: [PATCH 438/657] Annotate `Version` with `@sealed`. (dart-lang/pub_semver#49) --- pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/lib/src/version.dart | 2 ++ pkgs/pub_semver/pubspec.yaml | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 5140fe277..d53b9504c 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.0.1-dev +- Annotated `Version` with `@sealed` to discourage users from implementing the + interface. + # 2.0.0 - Stable null safety release. diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 552b49835..73402af38 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -5,6 +5,7 @@ import 'dart:math' as math; import 'package:collection/collection.dart'; +import 'package:meta/meta.dart' show sealed; import 'patterns.dart'; import 'version_constraint.dart'; @@ -14,6 +15,7 @@ import 'version_range.dart'; final _equality = const IterableEquality(); /// A parsed semantic version number. +@sealed class Version implements VersionConstraint, VersionRange { /// No released version: i.e. "0.0.0". static Version get none => Version(0, 0, 0); diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index f628d38cf..fce9bb0e2 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.0.0 +version: 2.0.1-dev description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. @@ -10,6 +10,7 @@ environment: dependencies: collection: ^1.15.0 + meta: ^1.3.0 dev_dependencies: test: ^1.16.0-nullsafety.1 From 16371057d5eebf097f3d87e1aba4c7f96b7fe7dd Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Fri, 10 Sep 2021 14:32:44 +0200 Subject: [PATCH 439/657] Add `Version.canonicalizedVersion` to help scrub leading zeros. (dart-lang/pub_semver#50) --- pkgs/pub_semver/CHANGELOG.md | 4 +++- pkgs/pub_semver/lib/src/version.dart | 26 ++++++++++++++++++++++ pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_test.dart | 30 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index d53b9504c..a2d5753ce 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,4 +1,6 @@ -# 2.0.1-dev +# 2.1.0 +- Added `Version.canonicalizedVersion` to help scrub leading zeros and highlight + that `Version.toString()` preserves leading zeros. - Annotated `Version` with `@sealed` to discourage users from implementing the interface. diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index 73402af38..ba6ce8f78 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -321,9 +321,35 @@ class Version implements VersionConstraint, VersionRange { } } + /// Get non-canonical string representation of this [Version]. + /// + /// If created with [Version.parse], the string from which the version was + /// parsed is returned. Unlike the [canonicalizedVersion] this preserves + /// artifacts such as leading zeros. @override String toString() => _text; + /// Get a canonicalized string representation of this [Version]. + /// + /// Unlike [Version.toString()] this always returns a canonical string + /// representation of this [Version]. + /// + /// **Example** + /// ```dart + /// final v = Version.parse('01.02.03-01.dev+pre.02'); + /// + /// assert(v.toString() == '01.02.03-01.dev+pre.02'); + /// assert(v.canonicalizedVersion == '1.2.3-1.dev+pre.2'); + /// assert(Version.parse(v.canonicalizedVersion) == v); + /// ``` + String get canonicalizedVersion => Version( + major, + minor, + patch, + pre: preRelease.isNotEmpty ? preRelease.join('.') : null, + build: build.isNotEmpty ? build.join('.') : null, + ).toString(); + /// Compares a dot-separated component of two versions. /// /// This is used for the pre-release and build version parts. This follows diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index fce9bb0e2..214f0cd9c 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.0.1-dev +version: 2.1.0 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 6ff4b3e98..467d0b7d4 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -330,6 +330,36 @@ void main() { }); }); + group('canonicalizedVersion', () { + test('returns version string', () { + expect(Version(0, 0, 0).canonicalizedVersion, equals('0.0.0')); + expect(Version(12, 34, 56).canonicalizedVersion, equals('12.34.56')); + + expect(Version(1, 2, 3, pre: 'alpha.1').canonicalizedVersion, + equals('1.2.3-alpha.1')); + expect(Version(1, 2, 3, pre: 'x.7.z-92').canonicalizedVersion, + equals('1.2.3-x.7.z-92')); + + expect(Version(1, 2, 3, build: 'build.1').canonicalizedVersion, + equals('1.2.3+build.1')); + expect(Version(1, 2, 3, pre: 'pre', build: 'bui').canonicalizedVersion, + equals('1.2.3-pre+bui')); + }); + + test('discards leading zeroes', () { + expect(Version.parse('001.02.0003-01.dev+pre.002').canonicalizedVersion, + equals('1.2.3-1.dev+pre.2')); + }); + + test('example from documentation', () { + final v = Version.parse('01.02.03-01.dev+pre.02'); + + assert(v.toString() == '01.02.03-01.dev+pre.02'); + assert(v.canonicalizedVersion == '1.2.3-1.dev+pre.2'); + assert(Version.parse(v.canonicalizedVersion) == v); + }); + }); + group('primary', () { test('single', () { expect( From c1531e295d5a64c2740a805842a52ed7e2f8fd8f Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Mon, 13 Sep 2021 14:06:47 +0200 Subject: [PATCH 440/657] Switch to package:lints --- pkgs/package_config/analysis_options.yaml | 2 +- pkgs/package_config/lib/src/package_config_json.dart | 4 ++-- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/discovery_test.dart | 3 +-- pkgs/package_config/test/discovery_uri_test.dart | 5 ++--- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/pkgs/package_config/analysis_options.yaml b/pkgs/package_config/analysis_options.yaml index a0ba68de2..278ec4868 100644 --- a/pkgs/package_config/analysis_options.yaml +++ b/pkgs/package_config/analysis_options.yaml @@ -2,4 +2,4 @@ # 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. -include: package:pedantic/analysis_options.1.9.0.yaml +include: package:lints/recommended.yaml diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index 1998b6606..fe185a2ea 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -35,7 +35,7 @@ final _jsonUtf8Decoder = json.fuse(utf8).decoder; PackageConfig parsePackageConfigBytes( Uint8List bytes, Uri file, void Function(Object error) onError) { // TODO(lrn): Make this simpler. Maybe parse directly from bytes. - var jsonObject; + Object? jsonObject; try { jsonObject = _jsonUtf8Decoder.convert(bytes); } on FormatException catch (e) { @@ -47,7 +47,7 @@ PackageConfig parsePackageConfigBytes( PackageConfig parsePackageConfigString( String source, Uri file, void Function(Object error) onError) { - var jsonObject; + Object? jsonObject; try { jsonObject = jsonDecode(source); } on FormatException catch (e) { diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 5cc9cc0a5..e7c9a0a3a 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -13,5 +13,5 @@ dev_dependencies: build_runner: ^2.0.0 build_test: ^2.1.2 build_web_compilers: ^3.0.0 - pedantic: ^1.10.0 + lints: ^1.0.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index d2c3d8330..4a1bba0a6 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -99,8 +99,7 @@ void main() { '.packages': packagesFile, 'subdir': {'script.dart': 'main(){}'} }, (Directory directory) async { - var config; - config = await findPackageConfig(subdir(directory, 'subdir/')); + var config = (await findPackageConfig(subdir(directory, 'subdir/')))!; expect(config.version, 1); validatePackagesFile(config, directory); }); diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 0a9b91720..e487e471d 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -98,9 +98,8 @@ void main() { '.packages': packagesFile, 'subdir': {'script.dart': 'main(){}'} }, (directory, loader) async { - var config; - config = await findPackageConfigUri(directory.resolve('subdir/'), - loader: loader); + var config = (await findPackageConfigUri(directory.resolve('subdir/'), + loader: loader))!; expect(config.version, 1); validatePackagesFile(config, directory); }); From 89cfab15a5bf72b9d8d04dc70f237392eaff4dfc Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Mon, 13 Sep 2021 14:32:57 +0200 Subject: [PATCH 441/657] Update description --- pkgs/package_config/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index e7c9a0a3a..6f80473c9 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,6 +1,6 @@ name: package_config -version: 2.0.2-dev -description: Support for working with Package Configuration files. +version: 2.0.2 +description: Support for reading and writing Dart Package Configuration files. homepage: https://github.com/dart-lang/package_config environment: From 8d518f7a0ec94304c35c673f775948099d63c1ac Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Mon, 13 Sep 2021 14:33:03 +0200 Subject: [PATCH 442/657] Add example --- pkgs/package_config/example/main.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 pkgs/package_config/example/main.dart diff --git a/pkgs/package_config/example/main.dart b/pkgs/package_config/example/main.dart new file mode 100644 index 000000000..42a596375 --- /dev/null +++ b/pkgs/package_config/example/main.dart @@ -0,0 +1,18 @@ +// 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:package_config/package_config.dart'; +import 'dart:io' show Directory; + +void main() async { + var packageConfig = await findPackageConfig(Directory.current); + if (packageConfig == null) { + print('Failed to locate or read package config.'); + } else { + print('This package depends on ${packageConfig.packages.length} packages:'); + for (var package in packageConfig.packages) { + print('- ${package.name}'); + } + } +} From 9b60f7b3b70179036251993cec28e418e68f894b Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Mon, 13 Sep 2021 14:37:50 +0200 Subject: [PATCH 443/657] Expand readme --- pkgs/package_config/CHANGELOG.md | 6 +++++- pkgs/package_config/README.md | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 898ebc4bb..c85ac5011 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,4 +1,8 @@ -## 2.0.2-dev +## 2.0.2 + +- Update package description and README. +- Change to package:lints for style checking. +- Add an example. ## 2.0.1 diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index ada1bd0ec..15ed4f6b2 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -4,7 +4,13 @@ Support for working with **Package Configuration** files as described in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). -The primary libraries are +A Dart package configuration file is used to resolve Dart package names (e.g. +`foobar`) to Dart files containing the source code for that package (e.g. +`file:///Users/myuser/.pub-cache/hosted/pub.dartlang.org/foobar-1.1.0`). The +standard package configuration file is `.dart_tool/package_config.json`, and is +written by the Dart tool when the command `dart pub get` is run. + +The primary libraries of this package are * `package_config.dart`: Defines the `PackageConfig` class and other types needed to use package configurations, and provides functions to find, read and From 38958749c9d2bc7403c9b67b54f90a981672bd32 Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Mon, 13 Sep 2021 15:06:24 +0200 Subject: [PATCH 444/657] Fix dartdoc generation --- pkgs/package_config/lib/package_config_types.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart index 482f82ac2..38b68ce6d 100644 --- a/pkgs/package_config/lib/package_config_types.dart +++ b/pkgs/package_config/lib/package_config_types.dart @@ -3,7 +3,13 @@ // BSD-style license that can be found in the LICENSE file. /// A package configuration is a way to assign file paths to package URIs, -/// and vice-versa, +/// and vice-versa. + +/// {@canonicalFor package_config.InvalidLanguageVersion} +/// {@canonicalFor package_config.LanguageVersion} +/// {@canonicalFor package_config.Package} +/// {@canonicalFor package_config.PackageConfig} +/// {@canonicalFor errors.PackageConfigError} library package_config.package_config_types; export 'src/package_config.dart' From 754c0a831f0db6d2c739e6abc3ab0cc6ccf06da4 Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Mon, 13 Sep 2021 16:16:00 +0200 Subject: [PATCH 445/657] Add /// --- pkgs/package_config/lib/package_config_types.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart index 38b68ce6d..976009b6c 100644 --- a/pkgs/package_config/lib/package_config_types.dart +++ b/pkgs/package_config/lib/package_config_types.dart @@ -4,7 +4,7 @@ /// A package configuration is a way to assign file paths to package URIs, /// and vice-versa. - +/// /// {@canonicalFor package_config.InvalidLanguageVersion} /// {@canonicalFor package_config.LanguageVersion} /// {@canonicalFor package_config.Package} From de5de03b9dbf04db865a8be89e27761296b7a46d Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sat, 2 Oct 2021 20:57:54 -0700 Subject: [PATCH 446/657] Move to pkg:lints, small tweak to dependency constraints in pubspec (dart-lang/pub_semver#62) Also, dart format --- pkgs/pub_semver/CHANGELOG.md | 2 ++ pkgs/pub_semver/analysis_options.yaml | 2 +- pkgs/pub_semver/lib/src/version_range.dart | 8 ++++++-- pkgs/pub_semver/pubspec.yaml | 7 ++++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index a2d5753ce..ae26139ca 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,5 @@ +# 2.1.1-dev + # 2.1.0 - Added `Version.canonicalizedVersion` to help scrub leading zeros and highlight that `Version.toString()` preserves leading zeros. diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index d73e8049e..a5aacab9a 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml analyzer: strong-mode: diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index a2a63276a..9431b09bb 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -432,7 +432,9 @@ class VersionRange implements Comparable, VersionConstraint { final min = this.min; if (min != null) { - buffer..write(includeMin ? '>=' : '>')..write(min); + buffer + ..write(includeMin ? '>=' : '>') + ..write(min); } final max = this.max; @@ -440,7 +442,9 @@ class VersionRange implements Comparable, VersionConstraint { if (max != null) { if (min != null) buffer.write(' '); if (includeMax) { - buffer..write('<=')..write(max); + buffer + ..write('<=') + ..write(max); } else { buffer.write('<'); if (max.isFirstPreRelease) { diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 214f0cd9c..ca45a9e8f 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,16 +1,17 @@ name: pub_semver -version: 2.1.0 +version: 2.1.1-dev description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. repository: https://github.com/dart-lang/pub_semver environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' dependencies: collection: ^1.15.0 meta: ^1.3.0 dev_dependencies: - test: ^1.16.0-nullsafety.1 + lints: ^1.0.0 + test: ^1.16.0 From 0569ed0b8a6551c87581d33da6e8ed2c81d7e28e Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 4 Oct 2021 13:14:26 -0700 Subject: [PATCH 447/657] Fix broken lints, update to pkg:lints, Bump SDK constraint (dart-lang/source_span#77) Also cleaned out changelog --- pkgs/source_span/CHANGELOG.md | 28 ++------------------ pkgs/source_span/analysis_options.yaml | 4 ++- pkgs/source_span/lib/src/file.dart | 5 ++-- pkgs/source_span/lib/src/location.dart | 4 +-- pkgs/source_span/lib/src/location_mixin.dart | 4 +-- pkgs/source_span/lib/src/span.dart | 2 +- pkgs/source_span/lib/src/span_mixin.dart | 4 +-- pkgs/source_span/pubspec.yaml | 3 ++- 8 files changed, 16 insertions(+), 38 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index fa4b193c1..90aba0b6b 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,5 +1,7 @@ # 1.8.2-dev +- Require Dart >= 2.14. + # 1.8.1 * Fix a bug where the URL header for the highlights with multiple files would @@ -9,32 +11,6 @@ * Stable release for null safety. -# 1.8.0-nullsafety.4 - -* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release - guidelines. - -# 1.8.0-nullsafety.3 - -* Remove workaround for https://github.com/dart-lang/sdk/issues/43136, which is - now fixed. -* Allow prerelease versions of the 2.12 sdk. - -# 1.8.0-nullsafety.2 - -* Revert unnecessary null check fix (sdk fix wont land in 2.10 stable). -* Allow 2.10 stable and 2.11 dev sdks. - -# 1.8.0-nullsafety.1 - -* Fixes a newly recognized unnecessary null check to remove warnings. - -# 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/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index ab5a4f209..002297f45 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -1,7 +1,9 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml + analyzer: strong-mode: implicit-casts: false + linter: rules: - always_declare_return_types diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 6fbcd4193..473b8c17a 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -398,9 +398,8 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { sourceUrl == other.sourceUrl; } - // Eliminates dart2js warning about overriding `==`, but not `hashCode` @override - int get hashCode => super.hashCode; + int get hashCode => Object.hash(_start, _end, sourceUrl); /// Returns a new span that covers both `this` and [other]. /// @@ -409,7 +408,7 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { @override FileSpan expand(FileSpan other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError('Source URLs \"$sourceUrl\" and ' + throw ArgumentError('Source URLs "$sourceUrl" and ' " \"${other.sourceUrl}\" don't match."); } diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 097961841..634863bf0 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -61,7 +61,7 @@ class SourceLocation implements Comparable { /// This always returns a non-negative value. int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError('Source URLs \"$sourceUrl\" and ' + throw ArgumentError('Source URLs "$sourceUrl" and ' "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); @@ -76,7 +76,7 @@ class SourceLocation implements Comparable { @override int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError('Source URLs \"$sourceUrl\" and ' + throw ArgumentError('Source URLs "$sourceUrl" and ' "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index 9a1f930f8..bae38befa 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -23,7 +23,7 @@ abstract class SourceLocationMixin implements SourceLocation { @override int distance(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError('Source URLs \"$sourceUrl\" and ' + throw ArgumentError('Source URLs "$sourceUrl" and ' "\"${other.sourceUrl}\" don't match."); } return (offset - other.offset).abs(); @@ -35,7 +35,7 @@ abstract class SourceLocationMixin implements SourceLocation { @override int compareTo(SourceLocation other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError('Source URLs \"$sourceUrl\" and ' + throw ArgumentError('Source URLs "$sourceUrl" and ' "\"${other.sourceUrl}\" don't match."); } return offset - other.offset; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index ba8bec715..30590ea88 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -102,7 +102,7 @@ class SourceSpanBase extends SourceSpanMixin { SourceSpanBase(this.start, this.end, this.text) { if (end.sourceUrl != start.sourceUrl) { - throw ArgumentError('Source URLs \"${start.sourceUrl}\" and ' + throw ArgumentError('Source URLs "${start.sourceUrl}" and ' " \"${end.sourceUrl}\" don't match."); } else if (end.offset < start.offset) { throw ArgumentError('End $end must come after start $start.'); diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 0f751ea52..4d7bab473 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -31,7 +31,7 @@ abstract class SourceSpanMixin implements SourceSpan { @override SourceSpan union(SourceSpan other) { if (sourceUrl != other.sourceUrl) { - throw ArgumentError('Source URLs \"$sourceUrl\" and ' + throw ArgumentError('Source URLs "$sourceUrl" and ' " \"${other.sourceUrl}\" don't match."); } @@ -77,7 +77,7 @@ abstract class SourceSpanMixin implements SourceSpan { other is SourceSpan && start == other.start && end == other.end; @override - int get hashCode => start.hashCode + (31 * end.hashCode); + int get hashCode => Object.hash(start, end); @override String toString() => '<$runtimeType: from $start to $end "$text">'; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 3343428f3..08bf64b8d 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -5,7 +5,7 @@ description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.14.0 <3.0.0" dependencies: collection: ^1.15.0 @@ -13,4 +13,5 @@ dependencies: term_glyph: ^1.2.0 dev_dependencies: + lints: ^1.0.0 test: ^1.16.0 From 5bb1de7b237b3c8682ace686648f4048061d2158 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 4 Oct 2021 14:54:42 -0700 Subject: [PATCH 448/657] Migrate to pkg:lints, fix related lints, cleanup in pubspec (dart-lang/source_maps#65) Removed pre-release versions from changelog --- pkgs/source_maps/CHANGELOG.md | 19 +----- pkgs/source_maps/analysis_options.yaml | 2 +- pkgs/source_maps/lib/parser.dart | 23 +++---- pkgs/source_maps/lib/printer.dart | 14 ++--- pkgs/source_maps/lib/refactor.dart | 17 +++--- pkgs/source_maps/lib/src/utils.dart | 3 + pkgs/source_maps/lib/src/vlq.dart | 36 +++++------ pkgs/source_maps/pubspec.yaml | 9 +-- pkgs/source_maps/test/builder_test.dart | 8 ++- pkgs/source_maps/test/common.dart | 10 ++-- pkgs/source_maps/test/end2end_test.dart | 9 +-- pkgs/source_maps/test/parser_test.dart | 79 ++++++++++++------------- pkgs/source_maps/test/printer_test.dart | 24 ++++---- pkgs/source_maps/test/vlq_test.dart | 28 ++++----- 14 files changed, 139 insertions(+), 142 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index a59cf3006..366dce2e5 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,24 +1,9 @@ +# 0.10.11-dev + ## 0.10.10 * Stable release for null safety. -## 0.10.10-nullsafety.3 - -* Update SDK constraints to `>=2.12.0-0 <3.0.0` based on beta release - guidelines. - -## 0.10.10-nullsafety.2 - -* Allow prerelease versions of the 2.12 sdk. - -## 0.10.10-nullsafety.1 - -* Allow 2.10 stable and 2.11.0 dev SDK versions. - -## 0.10.10-nullsafety - -* Migrate to null safety - ## 0.10.9 * Fix a number of document comment issues. diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml index 4f9dfb038..c09985a51 100644 --- a/pkgs/source_maps/analysis_options.yaml +++ b/pkgs/source_maps/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml linter: rules: diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 99a3c81b1..e3c7179f9 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -313,7 +313,7 @@ class SingleMapping extends Mapping { /// The file for each URL, indexed by [urls]' values. var files = {}; - var lineNum; + int? lineNum; late List targetEntries; for (var sourceEntry in sourceEntries) { if (lineNum == null || sourceEntry.target.line > lineNum) { @@ -601,7 +601,10 @@ class SingleMapping extends Mapping { } var sourceNameId = entry.sourceNameId; if (sourceNameId != null) { - buff..write(' (')..write(names[sourceNameId])..write(')'); + buff + ..write(' (') + ..write(names[sourceNameId]) + ..write(')'); } buff.write('\n'); } @@ -660,11 +663,11 @@ class _MappingTokenizer implements Iterator { bool get hasTokens => index < _length - 1 && _length > 0; _TokenKind get nextKind { - if (!hasTokens) return _TokenKind.EOF; + if (!hasTokens) return _TokenKind.eof; var next = _internal[index + 1]; - if (next == ';') return _TokenKind.LINE; - if (next == ',') return _TokenKind.SEGMENT; - return _TokenKind.VALUE; + if (next == ';') return _TokenKind.line; + if (next == ',') return _TokenKind.segment; + return _TokenKind.value; } int _consumeValue() => decodeVlq(this); @@ -698,10 +701,10 @@ class _MappingTokenizer implements Iterator { } class _TokenKind { - static const _TokenKind LINE = _TokenKind(isNewLine: true); - static const _TokenKind SEGMENT = _TokenKind(isNewSegment: true); - static const _TokenKind EOF = _TokenKind(isEof: true); - static const _TokenKind VALUE = _TokenKind(); + static const _TokenKind line = _TokenKind(isNewLine: true); + static const _TokenKind segment = _TokenKind(isNewSegment: true); + static const _TokenKind eof = _TokenKind(isEof: true); + static const _TokenKind value = _TokenKind(); final bool isNewLine; final bool isNewSegment; final bool isEof; diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 922c7fea0..7d128f7ec 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -9,9 +9,7 @@ import 'package:source_span/source_span.dart'; import 'builder.dart'; import 'src/source_map_span.dart'; - -const int _LF = 10; -const int _CR = 13; +import 'src/utils.dart'; /// A simple printer that keeps track of offset locations and records source /// maps locations. @@ -43,7 +41,9 @@ class Printer { var length = chars.length; for (var i = 0; i < length; i++) { var c = chars[i]; - if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) { + if (c == lineFeed || + (c == carriageReturn && + (i + 1 == length || chars[i + 1] != lineFeed))) { // Return not followed by line-feed is treated as a new line. _line++; _column = 0; @@ -130,7 +130,7 @@ class NestedPrinter implements NestedItem { /// Item used to indicate that the following item is copied from the original /// source code, and hence we should preserve source-maps on every new line. - static final _ORIGINAL = Object(); + static final _original = Object(); NestedPrinter([this.indent = 0]); @@ -156,7 +156,7 @@ class NestedPrinter implements NestedItem { assert(location == null || span == null); if (location != null) _items.add(location); if (span != null) _items.add(span); - if (isOriginal) _items.add(_ORIGINAL); + if (isOriginal) _items.add(_original); } if (object is String) { @@ -243,7 +243,7 @@ class NestedPrinter implements NestedItem { propagate = false; } else if (item is SourceLocation || item is SourceSpan) { printer.mark(item); - } else if (item == _ORIGINAL) { + } else if (item == _original) { // we insert booleans when we are about to quote text that was copied // from the original source. In such case, we will propagate marks on // every new-line. diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 64fd61050..97bd2a708 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -11,6 +11,7 @@ library source_maps.refactor; import 'package:source_span/source_span.dart'; import 'printer.dart'; +import 'src/utils.dart'; /// Editable text transaction. /// @@ -65,7 +66,9 @@ class TextEditTransaction { ..write(consumed) ..write(' input characters. List of edits:'); for (var e in _edits) { - sb..write('\n ')..write(e); + sb + ..write('\n ') + ..write(e); } throw UnsupportedError(sb.toString()); } @@ -91,7 +94,7 @@ class _TextEdit implements Comparable<_TextEdit> { final int end; /// The replacement used by the edit, can be a string or a [NestedPrinter]. - final replace; + final Object replace; _TextEdit(this.begin, this.end, this.replace); @@ -114,7 +117,7 @@ String guessIndent(String code, int charOffset) { var lineStart = 0; for (var i = charOffset - 1; i >= 0; i--) { var c = code.codeUnitAt(i); - if (c == _LF || c == _CR) { + if (c == lineFeed || c == carriageReturn) { lineStart = i + 1; break; } @@ -124,7 +127,7 @@ String guessIndent(String code, int charOffset) { var whitespaceEnd = code.length; for (var i = lineStart; i < code.length; i++) { var c = code.codeUnitAt(i); - if (c != _SPACE && c != _TAB) { + if (c != _space && c != _tab) { whitespaceEnd = i; break; } @@ -133,7 +136,5 @@ String guessIndent(String code, int charOffset) { return code.substring(lineStart, whitespaceEnd); } -const int _CR = 13; -const int _LF = 10; -const int _TAB = 9; -const int _SPACE = 32; +const int _tab = 9; +const int _space = 32; diff --git a/pkgs/source_maps/lib/src/utils.dart b/pkgs/source_maps/lib/src/utils.dart index f9870d2f3..eb238342d 100644 --- a/pkgs/source_maps/lib/src/utils.dart +++ b/pkgs/source_maps/lib/src/utils.dart @@ -27,3 +27,6 @@ int binarySearch(List list, bool Function(dynamic) matches) { } return max; } + +const int lineFeed = 10; +const int carriageReturn = 13; diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index 951ea8b96..6c41b6e2c 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -14,31 +14,31 @@ library source_maps.src.vlq; import 'dart:math'; -const int VLQ_BASE_SHIFT = 5; +const int vlqBaseShift = 5; -const int VLQ_BASE_MASK = (1 << 5) - 1; +const int vlqBaseMask = (1 << 5) - 1; -const int VLQ_CONTINUATION_BIT = 1 << 5; +const int vlqContinuationBit = 1 << 5; -const int VLQ_CONTINUATION_MASK = 1 << 5; +const int vlqContinuationMask = 1 << 5; -const String BASE64_DIGITS = +const String base64Digits = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; final Map _digits = () { var map = {}; for (var i = 0; i < 64; i++) { - map[BASE64_DIGITS[i]] = i; + map[base64Digits[i]] = i; } return map; }(); -final int MAX_INT32 = (pow(2, 31) as int) - 1; -final int MIN_INT32 = -(pow(2, 31) as int); +final int maxInt32 = (pow(2, 31) as int) - 1; +final int minInt32 = -(pow(2, 31) as int); /// Creates the VLQ encoding of [value] as a sequence of characters Iterable encodeVlq(int value) { - if (value < MIN_INT32 || value > MAX_INT32) { + if (value < minInt32 || value > maxInt32) { throw ArgumentError('expected 32 bit int, got: $value'); } var res = []; @@ -49,12 +49,12 @@ Iterable encodeVlq(int value) { } value = (value << 1) | signBit; do { - var digit = value & VLQ_BASE_MASK; - value >>= VLQ_BASE_SHIFT; + var digit = value & vlqBaseMask; + value >>= vlqBaseShift; if (value > 0) { - digit |= VLQ_CONTINUATION_BIT; + digit |= vlqContinuationBit; } - res.add(BASE64_DIGITS[digit]); + res.add(base64Digits[digit]); } while (value > 0); return res; } @@ -62,7 +62,7 @@ Iterable encodeVlq(int value) { /// Decodes a value written as a sequence of VLQ characters. The first input /// character will be `chars.current` after calling `chars.moveNext` once. The /// iterator is advanced until a stop character is found (a character without -/// the [VLQ_CONTINUATION_BIT]). +/// the [vlqContinuationBit]). int decodeVlq(Iterator chars) { var result = 0; var stop = false; @@ -74,10 +74,10 @@ int decodeVlq(Iterator chars) { if (digit == null) { throw FormatException('invalid character in VLQ encoding: $char'); } - stop = (digit & VLQ_CONTINUATION_BIT) == 0; - digit &= VLQ_BASE_MASK; + stop = (digit & vlqContinuationBit) == 0; + digit &= vlqBaseMask; result += (digit << shift); - shift += VLQ_BASE_SHIFT; + shift += vlqBaseShift; } // Result uses the least significant bit as a sign bit. We convert it into a @@ -93,7 +93,7 @@ int decodeVlq(Iterator chars) { result = negate ? -result : result; // TODO(sigmund): can we detect this earlier? - if (result < MIN_INT32 || result > MAX_INT32) { + if (result < minInt32 || result > maxInt32) { throw FormatException( 'expected an encoded 32 bit int, but we got: $result'); } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 648010a3f..23e53a589 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,15 +1,16 @@ name: source_maps -version: 0.10.10 +version: 0.10.11-dev description: Library to programmatically manipulate source map files. homepage: https://github.com/dart-lang/source_maps environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: source_span: ^1.8.0 dev_dependencies: - test: ^1.16.0-nullsafety - term_glyph: ^1.2.0-nullsafety + lints: ^1.0.0 + test: ^1.16.0 + term_glyph: ^1.2.0 diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index fddf46c88..b9bb9c770 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -5,8 +5,10 @@ library test.source_maps_test; import 'dart:convert'; -import 'package:test/test.dart'; + import 'package:source_maps/source_maps.dart'; +import 'package:test/test.dart'; + import 'common.dart'; void main() { @@ -17,7 +19,7 @@ void main() { ..addSpan(inputVar2, outputVar2) ..addSpan(inputExpr, outputExpr)) .build(output.url.toString()); - expect(map, equals(EXPECTED_MAP)); + expect(map, equals(expectedMap)); }); test('builder - with location', () { @@ -27,6 +29,6 @@ void main() { ..addLocation(inputVar2.start, outputVar2.start, 'longVar2') ..addLocation(inputExpr.start, outputExpr.start, null)) .toJson(output.url.toString()); - expect(str, jsonEncode(EXPECTED_MAP)); + expect(str, jsonEncode(expectedMap)); }); } diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart index 6ba1c6796..f6139de47 100644 --- a/pkgs/source_maps/test/common.dart +++ b/pkgs/source_maps/test/common.dart @@ -10,7 +10,7 @@ import 'package:source_span/source_span.dart'; import 'package:test/test.dart'; /// Content of the source file -const String INPUT = ''' +const String inputContent = ''' /** this is a comment. */ int longVar1 = 3; @@ -19,7 +19,7 @@ int longName(int longVar2) { return longVar1 + longVar2; } '''; -var input = SourceFile.fromString(INPUT, url: 'input.dart'); +final input = SourceFile.fromString(inputContent, url: 'input.dart'); /// A span in the input file SourceMapSpan ispan(int start, int end, [bool isIdentifier = false]) => @@ -36,11 +36,11 @@ SourceMapSpan inputVar2NoSymbol = ispan(87, 95); SourceMapSpan inputExpr = ispan(108, 127); /// Content of the target file -const String OUTPUT = ''' +const String outputContent = ''' var x = 3; f(y) => x + y; '''; -var output = SourceFile.fromString(OUTPUT, url: 'output.dart'); +final output = SourceFile.fromString(outputContent, url: 'output.dart'); /// A span in the output file SourceMapSpan ospan(int start, int end, [bool isIdentifier = false]) => @@ -62,7 +62,7 @@ SourceMapSpan outputExpr = ospan(19, 24); /// /// This mapping is stored in the tests so we can independently test the builder /// and parser algorithms without relying entirely on end2end tests. -const Map EXPECTED_MAP = { +const Map expectedMap = { 'version': 3, 'sourceRoot': '', 'sources': ['input.dart'], diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 954339fbd..153fcc286 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -4,9 +4,10 @@ library test.end2end_test; -import 'package:test/test.dart'; import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; +import 'package:test/test.dart'; + import 'common.dart'; void main() { @@ -106,12 +107,12 @@ void main() { }); test('printer projecting marks + parse', () { - var out = INPUT.replaceAll('long', '_s'); + var out = inputContent.replaceAll('long', '_s'); var file = SourceFile.fromString(out, url: 'output2.dart'); var printer = Printer('output2.dart'); printer.mark(ispan(0, 0)); - var segments = INPUT.split('long'); + var segments = inputContent.split('long'); expect(segments.length, 6); printer.add(segments[0], projectMarks: true); printer.mark(inputVar1); @@ -153,7 +154,7 @@ void main() { // Start of the last line var oOffset = out.length - 2; - var iOffset = INPUT.length - 2; + var iOffset = inputContent.length - 2; check(file.span(oOffset, oOffset), mapping, ispan(iOffset, iOffset), true); check(file.span(oOffset + 1, oOffset + 1), mapping, ispan(iOffset, iOffset), true); diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 1b3ae6f92..7c7b142bb 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -2,15 +2,15 @@ // 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. -library test.parser_test; - import 'dart:convert'; -import 'package:test/test.dart'; + import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; +import 'package:test/test.dart'; + import 'common.dart'; -const Map MAP_WITH_NO_SOURCE_LOCATION = { +const Map _mapWithNoSourceLocation = { 'version': 3, 'sourceRoot': '', 'sources': ['input.dart'], @@ -19,7 +19,7 @@ const Map MAP_WITH_NO_SOURCE_LOCATION = { 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION = { +const Map _mapWithSourceLocation = { 'version': 3, 'sourceRoot': '', 'sources': ['input.dart'], @@ -28,7 +28,7 @@ const Map MAP_WITH_SOURCE_LOCATION = { 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_MISSING_NAMES = { +const Map _mapWithSourceLocationAndMissingNames = { 'version': 3, 'sourceRoot': '', 'sources': ['input.dart'], @@ -36,7 +36,7 @@ const Map MAP_WITH_SOURCE_LOCATION_AND_MISSING_NAMES = { 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME = { +const Map _mapWithSourceLocationAndName = { 'version': 3, 'sourceRoot': '', 'sources': ['input.dart'], @@ -45,7 +45,7 @@ const Map MAP_WITH_SOURCE_LOCATION_AND_NAME = { 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_1 = { +const Map _mapWithSourceLocationAndName1 = { 'version': 3, 'sourceRoot': 'pkg/', 'sources': ['input1.dart'], @@ -54,7 +54,7 @@ const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_1 = { 'file': 'output.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_2 = { +const Map _mapWithSourceLocationAndName2 = { 'version': 3, 'sourceRoot': 'pkg/', 'sources': ['input2.dart'], @@ -63,7 +63,7 @@ const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_2 = { 'file': 'output2.dart' }; -const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_3 = { +const Map _mapWithSourceLocationAndName3 = { 'version': 3, 'sourceRoot': 'pkg/', 'sources': ['input3.dart'], @@ -72,15 +72,15 @@ const Map MAP_WITH_SOURCE_LOCATION_AND_NAME_3 = { 'file': '3/output.dart' }; -const List SOURCE_MAP_BUNDLE = [ - MAP_WITH_SOURCE_LOCATION_AND_NAME_1, - MAP_WITH_SOURCE_LOCATION_AND_NAME_2, - MAP_WITH_SOURCE_LOCATION_AND_NAME_3, +const _sourceMapBundle = [ + _mapWithSourceLocationAndName1, + _mapWithSourceLocationAndName2, + _mapWithSourceLocationAndName3, ]; void main() { test('parse', () { - var mapping = parseJson(EXPECTED_MAP); + var mapping = parseJson(expectedMap); check(outputVar1, mapping, inputVar1, false); check(outputVar2, mapping, inputVar2, false); check(outputFunction, mapping, inputFunction, false); @@ -88,7 +88,7 @@ void main() { }); test('parse + json', () { - var mapping = parse(jsonEncode(EXPECTED_MAP)); + var mapping = parse(jsonEncode(expectedMap)); check(outputVar1, mapping, inputVar1, false); check(outputVar2, mapping, inputVar2, false); check(outputFunction, mapping, inputFunction, false); @@ -96,7 +96,7 @@ void main() { }); test('parse with file', () { - var mapping = parseJson(EXPECTED_MAP); + var mapping = parseJson(expectedMap); check(outputVar1, mapping, inputVar1, true); check(outputVar2, mapping, inputVar2, true); check(outputFunction, mapping, inputFunction, true); @@ -104,7 +104,7 @@ void main() { }); test('parse with no source location', () { - var map = parse(jsonEncode(MAP_WITH_NO_SOURCE_LOCATION)) as SingleMapping; + var map = parse(jsonEncode(_mapWithNoSourceLocation)) as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); var entry = map.lines.first.entries.first; @@ -117,7 +117,7 @@ void main() { }); test('parse with source location and no name', () { - var map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION)) as SingleMapping; + var map = parse(jsonEncode(_mapWithSourceLocation)) as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); var entry = map.lines.first.entries.first; @@ -130,7 +130,7 @@ void main() { }); test('parse with source location and missing names entry', () { - var map = parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_MISSING_NAMES)) + var map = parse(jsonEncode(_mapWithSourceLocationAndMissingNames)) as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); @@ -144,8 +144,7 @@ void main() { }); test('parse with source location and name', () { - var map = - parse(jsonEncode(MAP_WITH_SOURCE_LOCATION_AND_NAME)) as SingleMapping; + var map = parse(jsonEncode(_mapWithSourceLocationAndName)) as SingleMapping; expect(map.lines.length, 1); expect(map.lines.first.entries.length, 1); var entry = map.lines.first.entries.first; @@ -158,7 +157,7 @@ void main() { }); test('parse with source root', () { - var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); + var inputMap = Map.from(_mapWithSourceLocation); inputMap['sourceRoot'] = '/pkg/'; var mapping = parseJson(inputMap) as SingleMapping; expect(mapping.spanFor(0, 0)?.sourceUrl, Uri.parse('/pkg/input.dart')); @@ -178,7 +177,7 @@ void main() { }); test('parse with map URL', () { - var inputMap = Map.from(MAP_WITH_SOURCE_LOCATION); + var inputMap = Map.from(_mapWithSourceLocation); inputMap['sourceRoot'] = 'pkg/'; var mapping = parseJson(inputMap, mapUrl: 'file:///path/to/map'); expect(mapping.spanFor(0, 0)?.sourceUrl, @@ -187,7 +186,7 @@ void main() { group('parse with bundle', () { var mapping = - parseJsonExtended(SOURCE_MAP_BUNDLE, mapUrl: 'file:///path/to/map'); + parseJsonExtended(_sourceMapBundle, mapUrl: 'file:///path/to/map'); test('simple', () { expect( @@ -276,7 +275,7 @@ void main() { }); test('parseExtended', () { - var mapping = parseExtended(jsonEncode(SOURCE_MAP_BUNDLE), + var mapping = parseExtended(jsonEncode(_sourceMapBundle), mapUrl: 'file:///path/to/map'); expect(mapping.spanFor(0, 0, uri: 'output.dart')?.sourceUrl, @@ -290,20 +289,20 @@ void main() { test('build bundle incrementally', () { var mapping = MappingBundle(); - mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_1, + mapping.addMapping(parseJson(_mapWithSourceLocationAndName1, mapUrl: 'file:///path/to/map') as SingleMapping); expect(mapping.spanFor(0, 0, uri: 'output.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input1.dart')); expect(mapping.containsMapping('output2.dart'), isFalse); - mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_2, + mapping.addMapping(parseJson(_mapWithSourceLocationAndName2, mapUrl: 'file:///path/to/map') as SingleMapping); expect(mapping.containsMapping('output2.dart'), isTrue); expect(mapping.spanFor(0, 0, uri: 'output2.dart')?.sourceUrl, Uri.parse('file:///path/to/pkg/input2.dart')); expect(mapping.containsMapping('3/output.dart'), isFalse); - mapping.addMapping(parseJson(MAP_WITH_SOURCE_LOCATION_AND_NAME_3, + mapping.addMapping(parseJson(_mapWithSourceLocationAndName3, mapUrl: 'file:///path/to/map') as SingleMapping); expect(mapping.containsMapping('3/output.dart'), isTrue); expect(mapping.spanFor(0, 0, uri: '3/output.dart')?.sourceUrl, @@ -351,10 +350,10 @@ void main() { test('parse and re-emit', () { for (var expected in [ - EXPECTED_MAP, - MAP_WITH_NO_SOURCE_LOCATION, - MAP_WITH_SOURCE_LOCATION, - MAP_WITH_SOURCE_LOCATION_AND_NAME + expectedMap, + _mapWithNoSourceLocation, + _mapWithSourceLocation, + _mapWithSourceLocationAndName ]) { var mapping = parseJson(expected) as SingleMapping; expect(mapping.toJson(), equals(expected)); @@ -363,12 +362,12 @@ void main() { expect(mapping.toJson(), equals(expected)); } - var mapping = parseJsonExtended(SOURCE_MAP_BUNDLE) as MappingBundle; - expect(mapping.toJson(), equals(SOURCE_MAP_BUNDLE)); + var mapping = parseJsonExtended(_sourceMapBundle) as MappingBundle; + expect(mapping.toJson(), equals(_sourceMapBundle)); }); test('parse extensions', () { - var map = Map.from(EXPECTED_MAP); + var map = Map.from(expectedMap); map['x_foo'] = 'a'; map['x_bar'] = [3]; var mapping = parseJson(map) as SingleMapping; @@ -396,19 +395,19 @@ void main() { group('from parse()', () { group('are null', () { test('with no sourcesContent field', () { - var mapping = parseJson(EXPECTED_MAP) as SingleMapping; + var mapping = parseJson(expectedMap) as SingleMapping; expect(mapping.files, equals([null])); }); test('with null sourcesContent values', () { - var map = Map.from(EXPECTED_MAP); + var map = Map.from(expectedMap); map['sourcesContent'] = [null]; var mapping = parseJson(map) as SingleMapping; expect(mapping.files, equals([null])); }); test('with a too-short sourcesContent', () { - var map = Map.from(EXPECTED_MAP); + var map = Map.from(expectedMap); map['sourcesContent'] = []; var mapping = parseJson(map) as SingleMapping; expect(mapping.files, equals([null])); @@ -416,7 +415,7 @@ void main() { }); test('are parsed from sourcesContent', () { - var map = Map.from(EXPECTED_MAP); + var map = Map.from(expectedMap); map['sourcesContent'] = ['hello, world!']; var mapping = parseJson(map) as SingleMapping; diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index fc7991359..3db321dde 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -5,9 +5,11 @@ library test.printer_test; import 'dart:convert'; -import 'package:test/test.dart'; + import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; +import 'package:test/test.dart'; + import 'common.dart'; void main() { @@ -23,15 +25,15 @@ void main() { ..add('y) => ') ..mark(inputExpr) ..add('x + y;\n'); - expect(printer.text, OUTPUT); - expect(printer.map, jsonEncode(EXPECTED_MAP)); + expect(printer.text, outputContent); + expect(printer.map, jsonEncode(expectedMap)); }); test('printer projecting marks', () { - var out = INPUT.replaceAll('long', '_s'); + var out = inputContent.replaceAll('long', '_s'); var printer = Printer('output2.dart'); - var segments = INPUT.split('long'); + var segments = inputContent.split('long'); expect(segments.length, 6); printer ..mark(ispan(0, 0)) @@ -92,8 +94,8 @@ void main() { ..add('y) => ', span: inputVar2) ..add('x + y;\n', span: inputExpr) ..build('output.dart'); - expect(printer.text, OUTPUT); - expect(printer.map, jsonEncode(EXPECTED_MAP)); + expect(printer.text, outputContent); + expect(printer.map, jsonEncode(expectedMap)); }); test('nested use', () { @@ -105,13 +107,13 @@ void main() { ..add(NestedPrinter()..add('y) => ', span: inputVar2)) ..add('x + y;\n', span: inputExpr) ..build('output.dart'); - expect(printer.text, OUTPUT); - expect(printer.map, jsonEncode(EXPECTED_MAP)); + expect(printer.text, outputContent); + expect(printer.map, jsonEncode(expectedMap)); }); test('add indentation', () { - var out = INPUT.replaceAll('long', '_s'); - var lines = INPUT.trim().split('\n'); + var out = inputContent.replaceAll('long', '_s'); + var lines = inputContent.trim().split('\n'); expect(lines.length, 7); var printer = NestedPrinter(); for (var i = 0; i < lines.length; i++) { diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index 92a8f4add..5a4f02a73 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -27,20 +27,20 @@ void main() { }); test('only 32-bit ints allowed', () { - var max_int = (pow(2, 31) as int) - 1; - var min_int = -(pow(2, 31) as int); - _checkEncodeDecode(max_int - 1); - _checkEncodeDecode(min_int + 1); - _checkEncodeDecode(max_int); - _checkEncodeDecode(min_int); - - expect(encodeVlq(min_int).join(''), 'hgggggE'); - expect(decodeVlq('hgggggE'.split('').iterator), min_int); - - expect(() => encodeVlq(max_int + 1), throwsA(anything)); - expect(() => encodeVlq(max_int + 2), throwsA(anything)); - expect(() => encodeVlq(min_int - 1), throwsA(anything)); - expect(() => encodeVlq(min_int - 2), throwsA(anything)); + var maxInt = (pow(2, 31) as int) - 1; + var minInt = -(pow(2, 31) as int); + _checkEncodeDecode(maxInt - 1); + _checkEncodeDecode(minInt + 1); + _checkEncodeDecode(maxInt); + _checkEncodeDecode(minInt); + + expect(encodeVlq(minInt).join(''), 'hgggggE'); + expect(decodeVlq('hgggggE'.split('').iterator), minInt); + + expect(() => encodeVlq(maxInt + 1), throwsA(anything)); + expect(() => encodeVlq(maxInt + 2), throwsA(anything)); + expect(() => encodeVlq(minInt - 1), throwsA(anything)); + expect(() => encodeVlq(minInt - 2), throwsA(anything)); // if we allowed more than 32 bits, these would be the expected encodings // for the large numbers above. From 3856eb97e7312d5eb661fd5759c59c31a92ef303 Mon Sep 17 00:00:00 2001 From: Greg Spencer Date: Wed, 10 Nov 2021 09:55:27 -0800 Subject: [PATCH 449/657] Fix RegExp for version pattern (dart-lang/pub_semver#63) Escape the `.` character instead of allowing any character in between the digits. --- pkgs/pub_semver/CHANGELOG.md | 5 ++++- pkgs/pub_semver/lib/src/patterns.dart | 2 +- pkgs/pub_semver/pubspec.yaml | 2 +- pkgs/pub_semver/test/version_test.dart | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index ae26139ca..6f0d45bd2 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,4 +1,7 @@ -# 2.1.1-dev +# 2.1.1 + +- Fixed the version parsing pattern to only accept dots between version + components. # 2.1.0 - Added `Version.canonicalizedVersion` to help scrub leading zeros and highlight diff --git a/pkgs/pub_semver/lib/src/patterns.dart b/pkgs/pub_semver/lib/src/patterns.dart index d5f189711..03119acf9 100644 --- a/pkgs/pub_semver/lib/src/patterns.dart +++ b/pkgs/pub_semver/lib/src/patterns.dart @@ -4,7 +4,7 @@ /// Regex that matches a version number at the beginning of a string. final startVersion = RegExp(r'^' // Start at beginning. - r'(\d+).(\d+).(\d+)' // Version number. + r'(\d+)\.(\d+)\.(\d+)' // Version number. r'(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?' // Pre-release. r'(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?'); // Build. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index ca45a9e8f..99392f5d6 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.1.1-dev +version: 2.1.1 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 467d0b7d4..2979706b5 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -300,6 +300,7 @@ void main() { equals(Version(1, 0, 0, pre: 'rc-1', build: 'build-1'))); expect(() => Version.parse('1.0'), throwsFormatException); + expect(() => Version.parse('1a2b3'), throwsFormatException); expect(() => Version.parse('1.2.3.4'), throwsFormatException); expect(() => Version.parse('1234'), throwsFormatException); expect(() => Version.parse('-2.3.4'), throwsFormatException); From 0674a0fcbd6126f03a28121e6c620155e978d014 Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 25 Nov 2021 11:00:11 +0100 Subject: [PATCH 450/657] Faster read; faster lookup; more tests; error on new package inside existing package root Previously adding (reading a file consisting of) n non-overlapping packages took O(n^2) time. Looking up a single package in a structure with n non-overlapping packages took O(n) time. Here this is changed so the timings are more like O(n) and O(1), respectively. (all of these should be taken with a grain of salt as not only the number of packages influence the time, but also the length of the paths which I completely ignore here). Run like this: ``` $ for i in 1 10 100 1000 5000 10000 50000; do dart test/bench.dart $i; done ``` (With no warmup, only run once etc --- there's lots of variations between runs, but for this purpose it doesn't really matter.) Before: Read file with 1 packages in 18 ms, looked up all packages in 0 ms Read file with 10 packages in 22 ms, looked up all packages in 0 ms Read file with 100 packages in 28 ms, looked up all packages in 1 ms Read file with 1000 packages in 78 ms, looked up all packages in 14 ms Read file with 5000 packages in 442 ms, looked up all packages in 384 ms Read file with 10000 packages in 2254 ms, looked up all packages in 1826 ms Read file with 50000 packages in 67572 ms, looked up all packages in 84050 ms After: Read file with 1 packages in 24 ms, looked up all packages in 0 ms Read file with 10 packages in 23 ms, looked up all packages in 0 ms Read file with 100 packages in 25 ms, looked up all packages in 1 ms Read file with 1000 packages in 60 ms, looked up all packages in 6 ms Read file with 5000 packages in 127 ms, looked up all packages in 10 ms Read file with 10000 packages in 187 ms, looked up all packages in 13 ms Read file with 50000 packages in 525 ms, looked up all packages in 61 ms Furthermore: * Previously no error was given if a package was inside the package root of another package. Now an error is given and tests are added. * Previously at least one test didn't work because of a json syntax error. This has been fixed. --- .../lib/src/package_config_impl.dart | 260 +++++++++--------- pkgs/package_config/test/bench.dart | 71 +++++ pkgs/package_config/test/parse_test.dart | 68 ++++- 3 files changed, 269 insertions(+), 130 deletions(-) create mode 100644 pkgs/package_config/test/bench.dart diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 4167d35f8..c22622b3a 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -54,12 +54,12 @@ class SimplePackageConfig implements PackageConfig { static PackageTree _validatePackages(Iterable originalPackages, List packages, void Function(Object error) onError) { var packageNames = {}; - var tree = MutablePackageTree(); + var tree = TrielikePackageTree(); for (var originalPackage in packages) { - SimplePackage? package; + SimplePackage? newPackage; if (originalPackage is! SimplePackage) { // SimplePackage validates these properties. - package = SimplePackage.validate( + newPackage = SimplePackage.validate( originalPackage.name, originalPackage.root, originalPackage.packageUriRoot, @@ -68,43 +68,58 @@ class SimplePackageConfig implements PackageConfig { originalPackage.relativeRoot, (error) { if (error is PackageConfigArgumentError) { onError(PackageConfigArgumentError(packages, 'packages', - 'Package ${package!.name}: ${error.message}')); + 'Package ${newPackage!.name}: ${error.message}')); } else { onError(error); } }); - if (package == null) continue; + if (newPackage == null) continue; } else { - package = originalPackage; + newPackage = originalPackage; } - var name = package.name; + var name = newPackage.name; if (packageNames.contains(name)) { onError(PackageConfigArgumentError( name, 'packages', "Duplicate package name '$name'")); continue; } packageNames.add(name); - tree.add(0, package, (error) { + tree.add(newPackage, (error) { if (error is ConflictException) { // There is a conflict with an existing package. var existingPackage = error.existingPackage; - if (error.isRootConflict) { - onError(PackageConfigArgumentError( - originalPackages, - 'packages', - 'Packages ${package!.name} and ${existingPackage.name} ' - 'have the same root directory: ${package.root}.\n')); - } else { - assert(error.isPackageRootConflict); - // Package is inside the package URI root of the existing package. - onError(PackageConfigArgumentError( - originalPackages, - 'packages', - 'Package ${package!.name} is inside the package URI root of ' - 'package ${existingPackage.name}.\n' - '${existingPackage.name} URI root: ' - '${existingPackage.packageUriRoot}\n' - '${package.name} root: ${package.root}\n')); + switch (error.conflictType) { + case ConflictType.SameRoots: + onError(PackageConfigArgumentError( + originalPackages, + 'packages', + 'Packages ${newPackage!.name} and ${existingPackage.name} ' + 'have the same root directory: ${newPackage.root}.\n')); + break; + case ConflictType.Interleaving: + // The new package is inside the package URI root of the existing + // package. + onError(PackageConfigArgumentError( + originalPackages, + 'packages', + 'Package ${newPackage!.name} is inside the root of ' + 'package ${existingPackage.name}, and the package root ' + 'of ${existingPackage.name} is inside the root of ' + '${newPackage.name}.\n' + '${existingPackage.name} package root: ' + '${existingPackage.packageUriRoot}\n' + '${newPackage.name} root: ${newPackage.root}\n')); + break; + case ConflictType.InsidePackageRoot: + onError(PackageConfigArgumentError( + originalPackages, + 'packages', + 'Package ${newPackage!.name} is inside the package root of ' + 'package ${existingPackage.name}.\n' + '${existingPackage.name} package root: ' + '${existingPackage.packageUriRoot}\n' + '${newPackage.name} root: ${newPackage.root}\n')); + break; } } else { // Any other error. @@ -367,6 +382,11 @@ abstract class PackageTree { SimplePackage? packageOf(Uri file); } +class _TrielikePackageTreeHelper { + SimplePackage? package; + Map map = {}; +} + /// Packages of a package configuration ordered by root path. /// /// A package has a root path and a package root path, where the latter @@ -375,122 +395,120 @@ abstract class PackageTree { /// A package is said to be inside another package if the root path URI of /// the latter is a prefix of the root path URI of the former. /// -/// No two packages of a package may have the same root path, so this -/// path prefix ordering defines a tree-like partial ordering on packages -/// of a configuration. -/// +/// No two packages of a package may have the same root path. /// The package root path of a package must not be inside another package's /// root path. -/// Entire other packages are allowed inside a package's root or -/// package root path. -/// -/// The package tree contains an ordered mapping of unrelated packages -/// (represented by their name) to their immediately nested packages' names. -class MutablePackageTree implements PackageTree { - /// A list of packages that are not nested inside each other. - final List packages = []; +/// Entire other packages are allowed inside a package's root. +class TrielikePackageTree implements PackageTree { + final Map _map = {}; - /// The tree of the immediately nested packages inside each package. - /// - /// Indexed by [Package.name]. - /// If a package has no nested packages (which is most often the case), - /// there is no tree object associated with it. - Map? _packageChildren; + /// A list of all packages. + final List _packages = []; @override Iterable get allPackages sync* { - for (var package in packages) { + for (var package in _packages) { yield package; } - var children = _packageChildren; - if (children != null) { - for (var tree in children.values) { - yield* tree.allPackages; + } + + bool _checkConflict(_TrielikePackageTreeHelper currentMapHelper, + SimplePackage newPackage, void Function(Object error) onError) { + if (currentMapHelper.package != null) { + var existingPackage = currentMapHelper.package!; + // Trying to add package that is inside the existing package. + // 1) If it's an exact match it's not allowed (i.e. the roots can't be + // the same). + if (newPackage.root.path.length == existingPackage.root.path.length) { + onError(ConflictException( + newPackage, existingPackage, ConflictType.SameRoots)); + return true; + } + // 2) The existing package has a packageUriRoot thats inside the + // root of the new package. + if (_beginsWith(0, newPackage.root.toString(), + existingPackage.packageUriRoot.toString())) { + onError(ConflictException( + newPackage, existingPackage, ConflictType.Interleaving)); + return true; + } + // 3) The new package is inside the packageUriRoot of existing package. + if (_beginsWith(0, existingPackage.packageUriRoot.toString(), + newPackage.root.toString())) { + onError(ConflictException( + newPackage, existingPackage, ConflictType.InsidePackageRoot)); + return true; } } + return false; } - /// Tries to (add) `package` to the tree. + /// Tries to add `newPackage` to the tree. /// /// Reports a [ConflictException] if the added package conflicts with an /// existing package. - /// It conflicts if its root or package root is the same as another - /// package's root or package root, or is between the two. + /// It conflicts if its root or package root is the same as an existing + /// package's root or package root, is between the two, or if it's inside the + /// package root of an existing package. /// - /// If a conflict is detected between [package] and a previous package, + /// If a conflict is detected between [newPackage] and a previous package, /// then [onError] is called with a [ConflictException] object - /// and the [package] is not added to the tree. + /// and the [newPackage] is not added to the tree. /// /// The packages are added in order of their root path. - /// It is never necessary to insert a node between two existing levels. - void add( - int start, SimplePackage package, void Function(Object error) onError) { - var path = package.root.toString(); - for (var treePackage in packages) { - // Check is package is inside treePackage. - var treePackagePath = treePackage.root.toString(); - assert(treePackagePath.length > start); - assert(path.startsWith(treePackagePath.substring(0, start))); - if (_beginsWith(start, treePackagePath, path)) { - // Package *is* inside treePackage. - var treePackagePathLength = treePackagePath.length; - if (path.length == treePackagePathLength) { - // Has same root. Do not add package. - onError(ConflictException.root(package, treePackage)); - return; - } - var treePackageUriRoot = treePackage.packageUriRoot.toString(); - if (_beginsWith(treePackagePathLength, path, treePackageUriRoot)) { - // The treePackage's package root is inside package, which is inside - // the treePackage. This is not allowed. - onError(ConflictException.packageRoot(package, treePackage)); - return; - } - _treeOf(treePackage).add(treePackagePathLength, package, onError); - return; + void add(SimplePackage newPackage, void Function(Object error) onError) { + var root = newPackage.root; + var currentMapHelper = _map[root.scheme] ??= _TrielikePackageTreeHelper(); + if (_checkConflict(currentMapHelper, newPackage, onError)) return; + var segments = root.pathSegments; + for (var i = 0; i < segments.length - 1; i++) { + var path = segments[i]; + currentMapHelper = + currentMapHelper.map[path] ??= _TrielikePackageTreeHelper(); + if (_checkConflict(currentMapHelper, newPackage, onError)) return; + } + currentMapHelper.package = newPackage; + _packages.add(newPackage); + } + + bool _isMatch(String path, _TrielikePackageTreeHelper currentMapHelper, + List potential) { + if (currentMapHelper.package != null) { + var currentPackage = currentMapHelper.package!; + var currentPackageRootLength = currentPackage.root.toString().length; + if (path.length == currentPackageRootLength) return true; + var currentPackageUriRoot = currentPackage.packageUriRoot.toString(); + // Is [file] is inside the package root of [currentPackage]? + if (currentPackageUriRoot.length == currentPackageRootLength || + _beginsWith(currentPackageRootLength, currentPackageUriRoot, path)) { + return true; } + potential.add(currentPackage); } - packages.add(package); + return false; } @override SimplePackage? packageOf(Uri file) { - return findPackageOf(0, file.toString()); - } - - /// Finds package containing [path] in this tree. - /// - /// Returns `null` if no such package is found. - /// - /// Assumes the first [start] characters of path agrees with all - /// the packages at this level of the tree. - SimplePackage? findPackageOf(int start, String path) { - for (var childPackage in packages) { - var childPath = childPackage.root.toString(); - if (_beginsWith(start, childPath, path)) { - // The [package] is inside [childPackage]. - var childPathLength = childPath.length; - if (path.length == childPathLength) return childPackage; - var uriRoot = childPackage.packageUriRoot.toString(); - // Is [package] is inside the URI root of [childPackage]. - if (uriRoot.length == childPathLength || - _beginsWith(childPathLength, uriRoot, path)) { - return childPackage; - } - return _packageChildren?[childPackage.name] - ?.findPackageOf(childPathLength, path) ?? - childPackage; + var currentMapHelper = _map[file.scheme]; + if (currentMapHelper == null) return null; + var path = file.toString(); + var potential = []; + if (_isMatch(path, currentMapHelper, potential)) { + return currentMapHelper.package; + } + var segments = file.pathSegments; + + for (var i = 0; i < segments.length - 1; i++) { + var segment = segments[i]; + currentMapHelper = currentMapHelper!.map[segment]; + if (currentMapHelper == null) break; + if (_isMatch(path, currentMapHelper, potential)) { + return currentMapHelper.package; } } - return null; - } - - /// Returns the [PackageTree] of the children of [package]. - /// - /// Ensures that the object is allocated if necessary. - MutablePackageTree _treeOf(SimplePackage package) { - var children = _packageChildren ??= {}; - return children[package.name] ??= MutablePackageTree(); + if (potential.isEmpty) return null; + return potential.last; } } @@ -516,6 +534,8 @@ bool _beginsWith(int start, String parentPath, String longerPath) { return true; } +enum ConflictType { SameRoots, Interleaving, InsidePackageRoot } + /// Conflict between packages added to the same configuration. /// /// The [package] conflicts with [existingPackage] if it has @@ -530,18 +550,10 @@ class ConflictException { final SimplePackage package; /// Whether the conflict is with the package URI root of [existingPackage]. - final bool isPackageRootConflict; + final ConflictType conflictType; /// Creates a root conflict between [package] and [existingPackage]. - ConflictException.root(this.package, this.existingPackage) - : isPackageRootConflict = false; - - /// Creates a package root conflict between [package] and [existingPackage]. - ConflictException.packageRoot(this.package, this.existingPackage) - : isPackageRootConflict = true; - - /// WHether the conflict is with the root URI of [existingPackage]. - bool get isRootConflict => !isPackageRootConflict; + ConflictException(this.package, this.existingPackage, this.conflictType); } /// Used for sorting packages by root path. diff --git a/pkgs/package_config/test/bench.dart b/pkgs/package_config/test/bench.dart new file mode 100644 index 000000000..746643185 --- /dev/null +++ b/pkgs/package_config/test/bench.dart @@ -0,0 +1,71 @@ +// Copyright (c) 2021, 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 'dart:convert'; +import 'dart:typed_data'; + +import 'package:package_config/src/package_config_json.dart'; + +void throwError(Object error) => throw error; + +void bench(final int size, final bool doPrint) { + var sb = StringBuffer(); + sb.writeln('{'); + sb.writeln('"configVersion": 2,'); + sb.writeln('"packages": ['); + for (var i = 0; i < size; i++) { + if (i != 0) { + sb.writeln(','); + } + sb.writeln('{'); + sb.writeln(' "name": "p_$i",'); + sb.writeln(' "rootUri": "file:///p_$i/",'); + sb.writeln(' "packageUri": "lib/",'); + sb.writeln(' "languageVersion": "2.5",'); + sb.writeln(' "nonstandard": true'); + sb.writeln('}'); + } + sb.writeln('],'); + sb.writeln('"generator": "pub",'); + sb.writeln('"other": [42]'); + sb.writeln('}'); + var stopwatch = Stopwatch()..start(); + var config = parsePackageConfigBytes( + // ignore: unnecessary_cast + utf8.encode(sb.toString()) as Uint8List, + Uri.parse('file:///tmp/.dart_tool/file.dart'), + throwError); + final int read = stopwatch.elapsedMilliseconds; + + stopwatch.reset(); + for (var i = 0; i < size; i++) { + if (config.packageOf(Uri.parse('file:///p_$i/lib/src/foo.dart'))!.name != + 'p_$i') { + throw "Unexpected result!"; + } + } + final int lookup = stopwatch.elapsedMilliseconds; + + if (doPrint) { + print('Read file with $size packages in $read ms, ' + 'looked up all packages in $lookup ms'); + } +} + +void main(List args) { + if (args.length != 1 && args.length != 2) { + throw "Expects arguments: ?"; + } + final size = int.parse(args[0]); + if (args.length > 1) { + final warmups = int.parse(args[1]); + print("Performing $warmups warmup iterations."); + for (var i = 0; i < warmups; i++) { + bench(10, false); + } + } + + // Benchmark. + bench(size, true); +} diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index d5c2e7268..0a7770d58 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -272,6 +272,36 @@ void main() { Uri.parse('package:qux/diz')); }); + test('nested packages 2', () { + var configBytes = utf8.encode(json.encode({ + 'configVersion': 2, + 'packages': [ + {'name': 'foo', 'rootUri': '/', 'packageUri': 'lib/'}, + {'name': 'bar', 'rootUri': '/bar/', 'packageUri': 'lib/'}, + {'name': 'baz', 'rootUri': '/bar/baz/', 'packageUri': 'lib/'}, + {'name': 'qux', 'rootUri': '/qux/', 'packageUri': 'lib/'}, + ] + })); + // ignore: unnecessary_cast + var config = parsePackageConfigBytes(configBytes as Uint8List, + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); + expect(config.version, 2); + expect( + config.packageOf(Uri.parse('file:///lala/lala.dart'))!.name, 'foo'); + expect(config.packageOf(Uri.parse('file:///bar/lala.dart'))!.name, 'bar'); + expect(config.packageOf(Uri.parse('file:///bar/baz/lala.dart'))!.name, + 'baz'); + expect(config.packageOf(Uri.parse('file:///qux/lala.dart'))!.name, 'qux'); + expect(config.toPackageUri(Uri.parse('file:///lib/diz')), + Uri.parse('package:foo/diz')); + expect(config.toPackageUri(Uri.parse('file:///bar/lib/diz')), + Uri.parse('package:bar/diz')); + expect(config.toPackageUri(Uri.parse('file:///bar/baz/lib/diz')), + Uri.parse('package:baz/diz')); + expect(config.toPackageUri(Uri.parse('file:///qux/lib/diz')), + Uri.parse('package:qux/diz')); + }); + group('invalid', () { void testThrows(String name, String source) { test(name, () { @@ -283,6 +313,21 @@ void main() { }); } + void testThrowsContains( + String name, String source, String containsString) { + test(name, () { + dynamic exception; + try { + parsePackageConfigBytes(utf8.encode(source) as Uint8List, + Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); + } catch (e) { + exception = e; + } + if (exception == null) fail("Didn't get exception"); + expect('$exception', contains(containsString)); + }); + } + testThrows('comment', '# comment\n {$cfg,$pkgs}'); testThrows('.packages file', 'foo:/foo\n'); testThrows('no configVersion', '{$pkgs}'); @@ -375,19 +420,30 @@ void main() { }); testThrows('duplicate package name', '{$cfg,"packages":[{$name,$root},{$name,"rootUri":"/other/"}]}'); - testThrows('same roots', - '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); - testThrows( + testThrowsContains( // The roots of foo and bar are the same. 'same roots', - '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}'); - testThrows( + '{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}', + 'the same root directory'); + testThrowsContains( + // The roots of foo and bar are the same. + 'same roots 2', + '{$cfg,"packages":[{$name,"rootUri":"/"},{"name":"bar","rootUri":"/"}]}', + 'the same root directory'); + testThrowsContains( // The root of bar is inside the root of foo, // but the package root of foo is inside the root of bar. 'between root and lib', '{$cfg,"packages":[' '{"name":"foo","rootUri":"/foo/","packageUri":"bar/lib/"},' - '{"name":"bar","rootUri":"/foo/bar/"},"packageUri":"baz/lib"]}'); + '{"name":"bar","rootUri":"/foo/bar/","packageUri":"baz/lib"}]}', + 'package root of foo is inside the root of bar'); + testThrowsContains( + 'root in lib', + '{$cfg,"packages":[' + '{"name":"foo","rootUri":"/foo/","packageUri":"lib/"},' + '{"name":"bar","rootUri":"/foo/lib/bar/","packageUri":"lib"}]}', + 'Package bar is inside the package root of package foo'); }); }); From c3b52af04b3a3e880c28fd988041341181c12cd1 Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 25 Nov 2021 11:07:49 +0100 Subject: [PATCH 451/657] Fix for 'Prefer using lowerCamelCase for constant names.' --- .../lib/src/package_config_impl.dart | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index c22622b3a..90862e344 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -89,14 +89,14 @@ class SimplePackageConfig implements PackageConfig { // There is a conflict with an existing package. var existingPackage = error.existingPackage; switch (error.conflictType) { - case ConflictType.SameRoots: + case ConflictType.sameRoots: onError(PackageConfigArgumentError( originalPackages, 'packages', 'Packages ${newPackage!.name} and ${existingPackage.name} ' 'have the same root directory: ${newPackage.root}.\n')); break; - case ConflictType.Interleaving: + case ConflictType.interleaving: // The new package is inside the package URI root of the existing // package. onError(PackageConfigArgumentError( @@ -110,7 +110,7 @@ class SimplePackageConfig implements PackageConfig { '${existingPackage.packageUriRoot}\n' '${newPackage.name} root: ${newPackage.root}\n')); break; - case ConflictType.InsidePackageRoot: + case ConflictType.insidePackageRoot: onError(PackageConfigArgumentError( originalPackages, 'packages', @@ -421,7 +421,7 @@ class TrielikePackageTree implements PackageTree { // the same). if (newPackage.root.path.length == existingPackage.root.path.length) { onError(ConflictException( - newPackage, existingPackage, ConflictType.SameRoots)); + newPackage, existingPackage, ConflictType.sameRoots)); return true; } // 2) The existing package has a packageUriRoot thats inside the @@ -429,14 +429,14 @@ class TrielikePackageTree implements PackageTree { if (_beginsWith(0, newPackage.root.toString(), existingPackage.packageUriRoot.toString())) { onError(ConflictException( - newPackage, existingPackage, ConflictType.Interleaving)); + newPackage, existingPackage, ConflictType.interleaving)); return true; } // 3) The new package is inside the packageUriRoot of existing package. if (_beginsWith(0, existingPackage.packageUriRoot.toString(), newPackage.root.toString())) { onError(ConflictException( - newPackage, existingPackage, ConflictType.InsidePackageRoot)); + newPackage, existingPackage, ConflictType.insidePackageRoot)); return true; } } @@ -534,7 +534,7 @@ bool _beginsWith(int start, String parentPath, String longerPath) { return true; } -enum ConflictType { SameRoots, Interleaving, InsidePackageRoot } +enum ConflictType { sameRoots, interleaving, insidePackageRoot } /// Conflict between packages added to the same configuration. /// From a0159d4239e8c5728ba9ab3b1f3920082a376ecb Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 25 Nov 2021 11:43:45 +0100 Subject: [PATCH 452/657] Allow inside lib anyway, for internal reasons --- .../lib/src/package_config_impl.dart | 4 ++++ pkgs/package_config/test/parse_test.dart | 21 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 90862e344..3ae54c2af 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -432,6 +432,9 @@ class TrielikePackageTree implements PackageTree { newPackage, existingPackage, ConflictType.interleaving)); return true; } + /* + For internal reasons we allow this (for now). One should still never do it + though. // 3) The new package is inside the packageUriRoot of existing package. if (_beginsWith(0, existingPackage.packageUriRoot.toString(), newPackage.root.toString())) { @@ -439,6 +442,7 @@ class TrielikePackageTree implements PackageTree { newPackage, existingPackage, ConflictType.insidePackageRoot)); return true; } + */ } return false; } diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 0a7770d58..174a099e0 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -438,12 +438,25 @@ void main() { '{"name":"foo","rootUri":"/foo/","packageUri":"bar/lib/"},' '{"name":"bar","rootUri":"/foo/bar/","packageUri":"baz/lib"}]}', 'package root of foo is inside the root of bar'); - testThrowsContains( - 'root in lib', - '{$cfg,"packages":[' + + // This shouldn't be allowed, but for internal reasons it is. + test("package inside package root", () { + var config = parsePackageConfigBytes( + utf8.encode( + '{$cfg,"packages":[' '{"name":"foo","rootUri":"/foo/","packageUri":"lib/"},' '{"name":"bar","rootUri":"/foo/lib/bar/","packageUri":"lib"}]}', - 'Package bar is inside the package root of package foo'); + ) as Uint8List, + Uri.parse('file:///tmp/.dart_tool/file.dart'), + throwError); + expect( + config + .packageOf(Uri.parse('file:///foo/lib/bar/lib/lala.dart'))! + .name, + 'foo'); // why not bar? + expect(config.toPackageUri(Uri.parse('file:///foo/lib/bar/lib/diz')), + Uri.parse('package:foo/bar/lib/diz')); // why not package:bar/diz? + }); }); }); From 4e5c229f81ec508fa2f8bbcb2ed7b520df05ac50 Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 25 Nov 2021 12:33:40 +0100 Subject: [PATCH 453/657] Feedback --- .../lib/src/package_config_impl.dart | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 3ae54c2af..86f31db8b 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -8,6 +8,8 @@ import 'util.dart'; export 'package_config.dart'; +const bool _disallowPackagesInsidePackageUriRoot = false; + // Implementations of the main data types exposed by the API of this package. class SimplePackageConfig implements PackageConfig { @@ -432,17 +434,18 @@ class TrielikePackageTree implements PackageTree { newPackage, existingPackage, ConflictType.interleaving)); return true; } - /* - For internal reasons we allow this (for now). One should still never do it - though. + + // For internal reasons we allow this (for now). One should still never do + // it thouh. // 3) The new package is inside the packageUriRoot of existing package. - if (_beginsWith(0, existingPackage.packageUriRoot.toString(), - newPackage.root.toString())) { - onError(ConflictException( - newPackage, existingPackage, ConflictType.insidePackageRoot)); - return true; + if (_disallowPackagesInsidePackageUriRoot) { + if (_beginsWith(0, existingPackage.packageUriRoot.toString(), + newPackage.root.toString())) { + onError(ConflictException( + newPackage, existingPackage, ConflictType.insidePackageRoot)); + return true; + } } - */ } return false; } From a731f2ec5454fbba1c3ebcd26eac76ad5edbf0b3 Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 25 Nov 2021 12:35:57 +0100 Subject: [PATCH 454/657] Feedback --- .../lib/src/package_config_impl.dart | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 86f31db8b..64bc50a8a 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -384,9 +384,9 @@ abstract class PackageTree { SimplePackage? packageOf(Uri file); } -class _TrielikePackageTreeHelper { +class _PackageTrieNode { SimplePackage? package; - Map map = {}; + Map map = {}; } /// Packages of a package configuration ordered by root path. @@ -402,7 +402,7 @@ class _TrielikePackageTreeHelper { /// root path. /// Entire other packages are allowed inside a package's root. class TrielikePackageTree implements PackageTree { - final Map _map = {}; + final Map _map = {}; /// A list of all packages. final List _packages = []; @@ -414,10 +414,10 @@ class TrielikePackageTree implements PackageTree { } } - bool _checkConflict(_TrielikePackageTreeHelper currentMapHelper, + bool _checkConflict(_PackageTrieNode currentTrieNode, SimplePackage newPackage, void Function(Object error) onError) { - if (currentMapHelper.package != null) { - var existingPackage = currentMapHelper.package!; + if (currentTrieNode.package != null) { + var existingPackage = currentTrieNode.package!; // Trying to add package that is inside the existing package. // 1) If it's an exact match it's not allowed (i.e. the roots can't be // the same). @@ -465,23 +465,23 @@ class TrielikePackageTree implements PackageTree { /// The packages are added in order of their root path. void add(SimplePackage newPackage, void Function(Object error) onError) { var root = newPackage.root; - var currentMapHelper = _map[root.scheme] ??= _TrielikePackageTreeHelper(); - if (_checkConflict(currentMapHelper, newPackage, onError)) return; + var currentTrieNode = _map[root.scheme] ??= _PackageTrieNode(); + if (_checkConflict(currentTrieNode, newPackage, onError)) return; var segments = root.pathSegments; for (var i = 0; i < segments.length - 1; i++) { var path = segments[i]; - currentMapHelper = - currentMapHelper.map[path] ??= _TrielikePackageTreeHelper(); - if (_checkConflict(currentMapHelper, newPackage, onError)) return; + currentTrieNode = + currentTrieNode.map[path] ??= _PackageTrieNode(); + if (_checkConflict(currentTrieNode, newPackage, onError)) return; } - currentMapHelper.package = newPackage; + currentTrieNode.package = newPackage; _packages.add(newPackage); } - bool _isMatch(String path, _TrielikePackageTreeHelper currentMapHelper, + bool _isMatch(String path, _PackageTrieNode currentTrieNode, List potential) { - if (currentMapHelper.package != null) { - var currentPackage = currentMapHelper.package!; + if (currentTrieNode.package != null) { + var currentPackage = currentTrieNode.package!; var currentPackageRootLength = currentPackage.root.toString().length; if (path.length == currentPackageRootLength) return true; var currentPackageUriRoot = currentPackage.packageUriRoot.toString(); @@ -497,21 +497,21 @@ class TrielikePackageTree implements PackageTree { @override SimplePackage? packageOf(Uri file) { - var currentMapHelper = _map[file.scheme]; - if (currentMapHelper == null) return null; + var currentTrieNode = _map[file.scheme]; + if (currentTrieNode == null) return null; var path = file.toString(); var potential = []; - if (_isMatch(path, currentMapHelper, potential)) { - return currentMapHelper.package; + if (_isMatch(path, currentTrieNode, potential)) { + return currentTrieNode.package; } var segments = file.pathSegments; for (var i = 0; i < segments.length - 1; i++) { var segment = segments[i]; - currentMapHelper = currentMapHelper!.map[segment]; - if (currentMapHelper == null) break; - if (_isMatch(path, currentMapHelper, potential)) { - return currentMapHelper.package; + currentTrieNode = currentTrieNode!.map[segment]; + if (currentTrieNode == null) break; + if (_isMatch(path, currentTrieNode, potential)) { + return currentTrieNode.package; } } if (potential.isEmpty) return null; From b280a3ed9a444102f14808592dcf040c286a1270 Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 25 Nov 2021 12:37:42 +0100 Subject: [PATCH 455/657] Formatting --- pkgs/package_config/lib/src/package_config_impl.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 64bc50a8a..9966bb088 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -470,8 +470,7 @@ class TrielikePackageTree implements PackageTree { var segments = root.pathSegments; for (var i = 0; i < segments.length - 1; i++) { var path = segments[i]; - currentTrieNode = - currentTrieNode.map[path] ??= _PackageTrieNode(); + currentTrieNode = currentTrieNode.map[path] ??= _PackageTrieNode(); if (_checkConflict(currentTrieNode, newPackage, onError)) return; } currentTrieNode.package = newPackage; From fd7708b60bc8e8792cc1fb9af9f9408c75494bea Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Thu, 25 Nov 2021 15:11:35 +0100 Subject: [PATCH 456/657] feedback --- .../lib/src/package_config_impl.dart | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 9966bb088..aef817664 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -56,7 +56,7 @@ class SimplePackageConfig implements PackageConfig { static PackageTree _validatePackages(Iterable originalPackages, List packages, void Function(Object error) onError) { var packageNames = {}; - var tree = TrielikePackageTree(); + var tree = TriePackageTree(); for (var originalPackage in packages) { SimplePackage? newPackage; if (originalPackage is! SimplePackage) { @@ -386,6 +386,8 @@ abstract class PackageTree { class _PackageTrieNode { SimplePackage? package; + + /// Indexed by path segment. Map map = {}; } @@ -401,7 +403,8 @@ class _PackageTrieNode { /// The package root path of a package must not be inside another package's /// root path. /// Entire other packages are allowed inside a package's root. -class TrielikePackageTree implements PackageTree { +class TriePackageTree implements PackageTree { + /// Indexed by URI scheme. final Map _map = {}; /// A list of all packages. @@ -414,10 +417,10 @@ class TrielikePackageTree implements PackageTree { } } - bool _checkConflict(_PackageTrieNode currentTrieNode, - SimplePackage newPackage, void Function(Object error) onError) { - if (currentTrieNode.package != null) { - var existingPackage = currentTrieNode.package!; + bool _checkConflict(_PackageTrieNode node, SimplePackage newPackage, + void Function(Object error) onError) { + var existingPackage = node.package; + if (existingPackage != null) { // Trying to add package that is inside the existing package. // 1) If it's an exact match it's not allowed (i.e. the roots can't be // the same). @@ -465,26 +468,28 @@ class TrielikePackageTree implements PackageTree { /// The packages are added in order of their root path. void add(SimplePackage newPackage, void Function(Object error) onError) { var root = newPackage.root; - var currentTrieNode = _map[root.scheme] ??= _PackageTrieNode(); - if (_checkConflict(currentTrieNode, newPackage, onError)) return; + var node = _map[root.scheme] ??= _PackageTrieNode(); + if (_checkConflict(node, newPackage, onError)) return; var segments = root.pathSegments; + // Notice that we're skipping the last segment as it's always the empty + // string because roots are directories. for (var i = 0; i < segments.length - 1; i++) { var path = segments[i]; - currentTrieNode = currentTrieNode.map[path] ??= _PackageTrieNode(); - if (_checkConflict(currentTrieNode, newPackage, onError)) return; + node = node.map[path] ??= _PackageTrieNode(); + if (_checkConflict(node, newPackage, onError)) return; } - currentTrieNode.package = newPackage; + node.package = newPackage; _packages.add(newPackage); } - bool _isMatch(String path, _PackageTrieNode currentTrieNode, - List potential) { - if (currentTrieNode.package != null) { - var currentPackage = currentTrieNode.package!; + bool _isMatch( + String path, _PackageTrieNode node, List potential) { + var currentPackage = node.package; + if (currentPackage != null) { var currentPackageRootLength = currentPackage.root.toString().length; if (path.length == currentPackageRootLength) return true; var currentPackageUriRoot = currentPackage.packageUriRoot.toString(); - // Is [file] is inside the package root of [currentPackage]? + // Is [file] inside the package root of [currentPackage]? if (currentPackageUriRoot.length == currentPackageRootLength || _beginsWith(currentPackageRootLength, currentPackageUriRoot, path)) { return true; From c1305da5849ed0d97e3a2a1033a8ee0e7ccc7748 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 22 Dec 2021 16:05:27 -0800 Subject: [PATCH 457/657] Don't crash when highlighting multiple spans with null URLs (dart-lang/source_span#78) --- pkgs/source_span/CHANGELOG.md | 6 ++-- pkgs/source_span/lib/src/highlighter.dart | 33 +++++++++++-------- pkgs/source_span/pubspec.yaml | 2 +- .../test/multiple_highlight_test.dart | 17 ++++++++++ 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 90aba0b6b..c0096b7ea 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,6 +1,8 @@ -# 1.8.2-dev +# 1.8.2 -- Require Dart >= 2.14. +* Fix a bug where highlighting multiple spans with `null` URLs could cause an + assertion error. Now when multiple spans are passed with `null` URLs, they're + highlighted as though they all come from different source files. # 1.8.1 diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 19d8965ee..d4e5ebf0e 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -126,14 +126,20 @@ class Highlighter { /// 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<_Highlight, Uri?>( - highlights, (highlight) => highlight.span.sourceUrl); + // Assign spans without URLs opaque Objects as keys. Each such Object will + // be different, but they can then be used later on to determine which lines + // came from the same span even if they'd all otherwise have `null` URLs. + final highlightsByUrl = groupBy<_Highlight, Object>( + highlights, (highlight) => highlight.span.sourceUrl ?? Object()); for (var list in highlightsByUrl.values) { list.sort((highlight1, highlight2) => highlight1.span.compareTo(highlight2.span)); } - return highlightsByUrl.values.expand((highlightsForFile) { + return highlightsByUrl.entries.expand((entry) { + final url = entry.key; + final highlightsForFile = entry.value; + // First, create a list of all the lines in the current file that we have // context for along with their line numbers. final lines = <_Line>[]; @@ -147,7 +153,6 @@ class Highlighter { final linesBeforeSpan = '\n'.allMatches(context.substring(0, lineStart)).length; - final url = highlight.span.sourceUrl; var lineNumber = highlight.span.start.line - linesBeforeSpan; for (var line in context.split('\n')) { // Only add a line if it hasn't already been added for a previous span. @@ -162,14 +167,12 @@ class Highlighter { final activeHighlights = <_Highlight>[]; var highlightIndex = 0; for (var line in lines) { - activeHighlights.removeWhere((highlight) => - highlight.span.sourceUrl != line.url || - highlight.span.end.line < line.number); + activeHighlights + .removeWhere((highlight) => highlight.span.end.line < line.number); final oldHighlightLength = activeHighlights.length; for (var highlight in highlightsForFile.skip(highlightIndex)) { if (highlight.span.start.line > line.number) break; - if (highlight.span.sourceUrl != line.url) break; activeHighlights.add(highlight); } highlightIndex += activeHighlights.length - oldHighlightLength; @@ -258,9 +261,9 @@ class Highlighter { } /// Writes the beginning of the file highlight for the file with the given - /// [url]. - void _writeFileStart(Uri? url) { - if (!_multipleFiles || url == null) { + /// [url] (or opaque object if it comes from a span with a null URL). + void _writeFileStart(Object url) { + if (!_multipleFiles || url is! Uri) { _writeSidebar(end: glyph.downEnd); } else { _writeSidebar(end: glyph.topLeftCorner); @@ -409,7 +412,8 @@ class Highlighter { /// of [character]. void _writeUnderline(_Line line, SourceSpan span, String character) { assert(!isMultiline(span)); - assert(line.text.contains(span.text)); + assert(line.text.contains(span.text), + '"${line.text}" should contain "${span.text}"'); var startColumn = span.start.column; var endColumn = span.end.column; @@ -664,7 +668,10 @@ class _Line { final int number; /// The URL of the source file in which this line appears. - final Uri? url; + /// + /// For lines created from spans without an explicit URL, this is an opaque + /// object that differs between lines that come from different spans. + final Object url; /// All highlights that cover any portion of this line, in source span order. /// diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 08bf64b8d..ad81db6be 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.8.2-dev +version: 1.8.2 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/multiple_highlight_test.dart b/pkgs/source_span/test/multiple_highlight_test.dart index b0c28a50a..a9f5fdac4 100644 --- a/pkgs/source_span/test/multiple_highlight_test.dart +++ b/pkgs/source_span/test/multiple_highlight_test.dart @@ -311,4 +311,21 @@ quibble bibble boop '""")); }); }); + + test('highlights multiple null URLs as separate files', () { + final span1 = SourceSpan(SourceLocation(1, sourceUrl: null), + SourceLocation(4, sourceUrl: null), 'foo'); + final span2 = SourceSpan(SourceLocation(1, sourceUrl: null), + SourceLocation(4, sourceUrl: null), 'bar'); + + expect(span1.highlightMultiple('one', {span2: 'two'}), equals(""" + , +1 | foo + | ^^^ one + ' + , +1 | bar + | === two + '""")); + }); } From 7095a039c0953341dc3176360091326913cba628 Mon Sep 17 00:00:00 2001 From: Nate Bosch Date: Mon, 31 Jan 2022 10:26:28 -0800 Subject: [PATCH 458/657] Preemptively bump to a -dev version (dart-lang/package_config#118) The code in the repo has diverged from what was published in `2.0.2` so we don't want the pubspec to still have that version. There are no user facing changes. --- pkgs/package_config/CHANGELOG.md | 2 ++ pkgs/package_config/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index c85ac5011..8c58fbb63 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.0.3-dev + ## 2.0.2 - Update package description and README. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 6f80473c9..def12cbb7 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.2 +version: 2.0.3-dev description: Support for reading and writing Dart Package Configuration files. homepage: https://github.com/dart-lang/package_config From 66077cdbaa04489f86d4b14d2123519928f4db6e Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Mon, 7 Feb 2022 13:14:18 +0100 Subject: [PATCH 459/657] Fix broken link for language-versioning spec (dart-lang/package_config#120) Thanks! And yes, it's an issue that files do not have permalinks, but we also do want to use the hierarchical structure of the repo for placing them where they belong, and we don't want to keep copies around, because that risks older copies being stale. No good solution found. (If only you could tag files and refer to them by tag.) --- pkgs/package_config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 15ed4f6b2..712a23c80 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -2,7 +2,7 @@ [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config) Support for working with **Package Configuration** files as described -in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). +in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/2.8/language-versioning/package-config-file-v2.md). A Dart package configuration file is used to resolve Dart package names (e.g. `foobar`) to Dart files containing the source code for that package (e.g. From d3190c6843c6fd48a99a35389c30923bbebf672e Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 1 Mar 2022 10:06:13 -0800 Subject: [PATCH 460/657] Update pubspec.yaml (dart-lang/pub_semver#64) --- pkgs/pub_semver/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 99392f5d6..aa7ab52c8 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -6,7 +6,7 @@ description: >- repository: https://github.com/dart-lang/pub_semver environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' dependencies: collection: ^1.15.0 From fcea93be4967077f73dba731aa7f04728f0e2229 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Mar 2022 11:16:35 -0800 Subject: [PATCH 461/657] Bump actions/checkout from 2 to 3 (dart-lang/package_config#122) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 33bf62bd9..3db1d6c24 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.12.0, dev] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: dart-lang/setup-dart@v1 with: sdk: ${{ matrix.sdk }} From 719d6abbf04696fdf3cae1933fabb4335af9699c Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 7 Mar 2022 16:15:36 -0800 Subject: [PATCH 462/657] Update README.md (dart-lang/pub_semver#65) --- pkgs/pub_semver/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index 5e0c36cd8..8282501d6 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -1,3 +1,6 @@ +[![Dart CI](https://github.com/dart-lang/pub_semver/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/pub_semver/actions/workflows/test-package.yml) +[![Pub](https://img.shields.io/pub/v/pub_semver.svg)](https://pub.dev/packages/pub_semver) + Handles version numbers and version constraints in the same way that [pub][] does. The semantics here very closely follow the [Semantic Versioning spec version 2.0.0-rc.1][semver]. It differs from semver From f9bc8902f6a5959ad5829a14438a7d930bbdf62f Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Tue, 5 Apr 2022 15:56:33 -0700 Subject: [PATCH 463/657] Add SourceSpanWithContextExtension.subspan (dart-lang/source_span#81) --- pkgs/source_span/CHANGELOG.md | 5 ++ pkgs/source_span/lib/src/span.dart | 47 ++-------------- .../lib/src/span_with_context.dart | 15 ++++++ pkgs/source_span/lib/src/utils.dart | 54 +++++++++++++++++++ pkgs/source_span/pubspec.yaml | 2 +- pkgs/source_span/test/span_test.dart | 7 +++ 6 files changed, 85 insertions(+), 45 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index c0096b7ea..f906a87a6 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.9.0 + +* Add `SourceSpanWithContextExtension.subspan` that returns a + `SourceSpanWithContext` rather than a plain `SourceSpan`. + # 1.8.2 * Fix a bug where highlighting multiple spans with `null` URLs could cause an diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 30590ea88..05fd340a2 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -5,12 +5,12 @@ import 'package:path/path.dart' as p; import 'package:term_glyph/term_glyph.dart' as glyph; -import 'charcode.dart'; import 'file.dart'; import 'highlighter.dart'; import 'location.dart'; import 'span_mixin.dart'; import 'span_with_context.dart'; +import 'utils.dart'; /// A class that describes a segment of source text. abstract class SourceSpan implements Comparable { @@ -187,48 +187,7 @@ extension SourceSpanExtension on SourceSpan { RangeError.checkValidRange(start, end, length); if (start == 0 && (end == null || end == length)) return this; - final text = this.text; - final startLocation = this.start; - var line = startLocation.line; - var column = startLocation.column; - - // Adjust [line] and [column] as necessary if the character at [i] in [text] - // is a newline. - void consumeCodePoint(int i) { - final codeUnit = text.codeUnitAt(i); - if (codeUnit == $lf || - // A carriage return counts as a newline, but only if it's not - // followed by a line feed. - (codeUnit == $cr && - (i + 1 == text.length || text.codeUnitAt(i + 1) != $lf))) { - line += 1; - column = 0; - } else { - column += 1; - } - } - - for (var i = 0; i < start; i++) { - consumeCodePoint(i); - } - - final newStartLocation = SourceLocation(startLocation.offset + start, - sourceUrl: sourceUrl, line: line, column: column); - - SourceLocation newEndLocation; - if (end == null || end == length) { - newEndLocation = this.end; - } else if (end == start) { - newEndLocation = newStartLocation; - } else { - for (var i = start; i < end; i++) { - consumeCodePoint(i); - } - newEndLocation = SourceLocation(startLocation.offset + end, - sourceUrl: sourceUrl, line: line, column: column); - } - - return SourceSpan( - newStartLocation, newEndLocation, text.substring(start, end)); + final locations = subspanLocations(this, start, end); + return SourceSpan(locations[0], locations[1], text.substring(start, end)); } } diff --git a/pkgs/source_span/lib/src/span_with_context.dart b/pkgs/source_span/lib/src/span_with_context.dart index da09cc0b8..776c78988 100644 --- a/pkgs/source_span/lib/src/span_with_context.dart +++ b/pkgs/source_span/lib/src/span_with_context.dart @@ -34,3 +34,18 @@ class SourceSpanWithContext extends SourceSpanBase { } } } + +// TODO(#52): Move these to instance methods in the next breaking release. +/// Extension methods on the base [SourceSpan] API. +extension SourceSpanWithContextExtension on SourceSpanWithContext { + /// Returns a span from [start] code units (inclusive) to [end] code units + /// (exclusive) after the beginning of this span. + SourceSpanWithContext subspan(int start, [int? end]) { + RangeError.checkValidRange(start, end, length); + if (start == 0 && (end == null || end == length)) return this; + + final locations = subspanLocations(this, start, end); + return SourceSpanWithContext( + locations[0], locations[1], text.substring(start, end), context); + } +} diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index ccc88bdab..7df0bafca 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -2,7 +2,10 @@ // 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 'charcode.dart'; +import 'location.dart'; import 'span.dart'; +import 'span_with_context.dart'; /// Returns the minimum of [obj1] and [obj2] according to /// [Comparable.compareTo]. @@ -89,3 +92,54 @@ int? findLineStart(String context, String text, int column) { // ignore: avoid_returning_null return null; } + +/// Returns a two-element list containing the start and end locations of the +/// span from [start] code units (inclusive) to [end] code units (exclusive) +/// after the beginning of [span]. +/// +/// This is factored out so it can be shared between +/// [SourceSpanExtension.subspan] and [SourceSpanWithContextExtension.subspan]. +List subspanLocations(SourceSpan span, int start, [int? end]) { + final text = span.text; + final startLocation = span.start; + var line = startLocation.line; + var column = startLocation.column; + + // Adjust [line] and [column] as necessary if the character at [i] in [text] + // is a newline. + void consumeCodePoint(int i) { + final codeUnit = text.codeUnitAt(i); + if (codeUnit == $lf || + // A carriage return counts as a newline, but only if it's not + // followed by a line feed. + (codeUnit == $cr && + (i + 1 == text.length || text.codeUnitAt(i + 1) != $lf))) { + line += 1; + column = 0; + } else { + column += 1; + } + } + + for (var i = 0; i < start; i++) { + consumeCodePoint(i); + } + + final newStartLocation = SourceLocation(startLocation.offset + start, + sourceUrl: span.sourceUrl, line: line, column: column); + + SourceLocation newEndLocation; + if (end == null || end == span.length) { + newEndLocation = span.end; + } else if (end == start) { + newEndLocation = newStartLocation; + } else { + for (var i = start; i < end; i++) { + consumeCodePoint(i); + } + newEndLocation = SourceLocation(startLocation.offset + end, + sourceUrl: span.sourceUrl, line: line, column: column); + } + + return [newStartLocation, newEndLocation]; +} diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index ad81db6be..84db52e24 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.8.2 +version: 1.9.0 description: A library for identifying source spans and locations. homepage: https://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/span_test.dart b/pkgs/source_span/test/span_test.dart index 348cc9e7d..22c498efb 100644 --- a/pkgs/source_span/test/span_test.dart +++ b/pkgs/source_span/test/span_test.dart @@ -206,6 +206,13 @@ void main() { expect(result.end.sourceUrl, equals(span.sourceUrl)); }); + test('preserves the context', () { + final start = SourceLocation(2); + final end = SourceLocation(5); + final span = SourceSpanWithContext(start, end, 'abc', '--abc--'); + expect(span.subspan(1, 2).context, equals('--abc--')); + }); + group('returns the original span', () { test('with an implicit end', () => expect(span.subspan(0), equals(span))); From 2ee4e12f1a0d4cb90222587ca0f34b75cedcc794 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 29 Apr 2022 16:51:35 -0700 Subject: [PATCH 464/657] Update pubspec.yaml --- pkgs/pool/pubspec.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 421baf5f2..feb49023d 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,10 +1,9 @@ name: pool version: 1.5.0 - description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. -homepage: https://github.com/dart-lang/pool +repository: https://github.com/dart-lang/pool environment: sdk: ">=2.12.0-0 <3.0.0" From 68d89c0e2c23bf9a7906c3a2de4c89153f1816b3 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 29 Apr 2022 23:52:59 +0000 Subject: [PATCH 465/657] rev to a dev version --- pkgs/pool/CHANGELOG.md | 2 ++ pkgs/pool/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 9e0a5a519..c60ce08dc 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.5.1-dev + ## 1.5.0 * Stable release for null safety. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index feb49023d..5f50eb063 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.0 +version: 1.5.1-dev description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. From 0ed2b4a7b4929b18927ffdc6cd79a11349804333 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Sat, 30 Apr 2022 04:40:51 +0000 Subject: [PATCH 466/657] switch to package:lints --- pkgs/pool/CHANGELOG.md | 3 +++ pkgs/pool/analysis_options.yaml | 46 +-------------------------------- pkgs/pool/pubspec.yaml | 8 +++--- pkgs/pool/test/pool_test.dart | 1 - 4 files changed, 8 insertions(+), 50 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index c60ce08dc..c9694dd02 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,5 +1,8 @@ ## 1.5.1-dev +* Switch to using `package:lints` for analysis. +* Populate the pubspec `repository` field. + ## 1.5.0 * Stable release for null safety. diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index ae67bc00b..4fa4b8d13 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -1,49 +1,5 @@ -include: package:pedantic/analysis_options.yaml +include: package:lints/recommended.yaml analyzer: strong-mode: implicit-casts: false - -linter: - rules: - - avoid_function_literals_in_foreach_calls - - avoid_renaming_method_parameters - - avoid_returning_null - - avoid_returning_null_for_future - - avoid_unused_constructor_parameters - - await_only_futures - - camel_case_types - - cancel_subscriptions - - comment_references - - constant_identifier_names - - control_flow_in_finally - - directives_ordering - - empty_statements - - hash_and_equals - - implementation_imports - - invariant_booleans - - iterable_contains_unrelated_type - - list_remove_unrelated_type - - literal_only_boolean_expressions - - no_adjacent_strings_in_list - - non_constant_identifier_names - - only_throw_errors - - overridden_fields - - package_api_docs - - package_names - - package_prefixed_library_names - - prefer_const_constructors - - prefer_initializing_formals - - prefer_interpolation_to_compose_strings - - prefer_typing_uninitialized_variables - - recursive_getters - - slash_for_doc_comments - - test_types_in_equals - - throw_in_finally - - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_getters_setters - - unnecessary_lambdas - - unnecessary_null_aware_assignments - - unnecessary_parenthesis - - unnecessary_statements diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 5f50eb063..26ca100b4 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -6,13 +6,13 @@ description: >- repository: https://github.com/dart-lang/pool environment: - sdk: ">=2.12.0-0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: async: ^2.5.0 stack_trace: ^1.10.0 dev_dependencies: - fake_async: ^1.2.0-nullsafety - pedantic: ^1.10.0-nullsafety - test: ^1.16.0-nullsafety + fake_async: ^1.2.0 + lints: ^1.0.0 + test: ^1.16.0 diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 20e92d597..2dd90f4a5 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:fake_async/fake_async.dart'; -import 'package:pedantic/pedantic.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart'; import 'package:test/test.dart'; From a690ba7b5b6a134eff6d1cd343c6e94c2fdc4dff Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Sat, 30 Apr 2022 05:22:12 +0000 Subject: [PATCH 467/657] test against Dart 2.15 --- pkgs/pool/.github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 9a455e756..76d5352da 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.12.0, dev] + sdk: [2.15.0, dev] steps: - uses: actions/checkout@v2 - uses: dart-lang/setup-dart@v1.0 From 87732e1abedb65a30fc357a5bace952a8f34e88c Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 2 May 2022 10:06:06 -0700 Subject: [PATCH 468/657] Update pubspec.yaml (dart-lang/package_config#123) --- pkgs/package_config/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index def12cbb7..d4ed6b94f 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,7 +1,7 @@ name: package_config version: 2.0.3-dev description: Support for reading and writing Dart Package Configuration files. -homepage: https://github.com/dart-lang/package_config +repository: https://github.com/dart-lang/package_config environment: sdk: '>=2.12.0 <3.0.0' From a0fdffcb3100ce46cd1533dbd52c9ffaede2e936 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 3 May 2022 22:00:09 +0000 Subject: [PATCH 469/657] populate the pubspec repository field --- pkgs/source_maps/CHANGELOG.md | 3 +++ pkgs/source_maps/README.md | 5 +++-- pkgs/source_maps/pubspec.yaml | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 366dce2e5..dcd04000b 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,5 +1,8 @@ # 0.10.11-dev +- Switch to `package:lints`. +- Populate the pubspec `repository` field. + ## 0.10.10 * Stable release for null safety. diff --git a/pkgs/source_maps/README.md b/pkgs/source_maps/README.md index 5c7f638f4..89e9eff82 100644 --- a/pkgs/source_maps/README.md +++ b/pkgs/source_maps/README.md @@ -1,5 +1,6 @@ -Source Maps -=========== +[![Dart CI](https://github.com/dart-lang/source_maps/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/source_maps/actions/workflows/test-package.yml) +[![pub package](https://img.shields.io/pub/v/source_maps.svg)](https://pub.dev/packages/source_maps) +[![package publisher](https://img.shields.io/pub/publisher/source_maps.svg)](https://pub.dev/packages/source_maps/publisher) This project implements a Dart pub package to work with source maps. The implementation is based on the [source map version 3 spec][spec] which was diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 23e53a589..b1cb177b5 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,8 +1,7 @@ name: source_maps version: 0.10.11-dev - description: Library to programmatically manipulate source map files. -homepage: https://github.com/dart-lang/source_maps +repository: https://github.com/dart-lang/source_maps environment: sdk: ">=2.12.0 <3.0.0" From 4db895023a0cba08501d97c8c358d088449ec270 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 3 May 2022 15:13:01 -0700 Subject: [PATCH 470/657] populate the pubspec repository field (dart-lang/source_span#82) --- pkgs/source_span/CHANGELOG.md | 4 ++++ pkgs/source_span/README.md | 4 ++++ pkgs/source_span/pubspec.yaml | 5 ++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index f906a87a6..5722045c2 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.9.1-dev + +* Populate the pubspec `repository` field. + # 1.9.0 * Add `SourceSpanWithContextExtension.subspan` that returns a diff --git a/pkgs/source_span/README.md b/pkgs/source_span/README.md index 4e2547e28..be91debd0 100644 --- a/pkgs/source_span/README.md +++ b/pkgs/source_span/README.md @@ -1,3 +1,7 @@ +[![Dart CI](https://github.com/dart-lang/source_span/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/source_span/actions/workflows/test-package.yml) +[![pub package](https://img.shields.io/pub/v/source_span.svg)](https://pub.dev/packages/source_span) +[![package publisher](https://img.shields.io/pub/publisher/source_span.svg)](https://pub.dev/packages/source_span/publisher) + `source_span` is a library for tracking locations in source code. It's designed to provide a standard representation for source code locations and spans so that disparate packages can easily pass them among one another, and to make it easy diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 84db52e24..63a64b09c 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,8 +1,7 @@ name: source_span -version: 1.9.0 - +version: 1.9.1-dev description: A library for identifying source spans and locations. -homepage: https://github.com/dart-lang/source_span +repository: https://github.com/dart-lang/source_span environment: sdk: ">=2.14.0 <3.0.0" From 43742539e3a04673f79fe68842a4285ce58eb8c1 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 19 May 2022 03:03:04 +0000 Subject: [PATCH 471/657] prep for publishing 2.0.3 --- pkgs/package_config/CHANGELOG.md | 6 +++++- pkgs/package_config/README.md | 1 + pkgs/package_config/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 8c58fbb63..4e095f2b0 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,4 +1,8 @@ -## 2.0.3-dev +## 2.0.3 + +- Improve file read performance; improve lookup performance. +- Emit an error when a package is inside the package root of another package. +- Fix a link in the readme. ## 2.0.2 diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 712a23c80..9e2e41f0b 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -1,5 +1,6 @@ [![Build Status](https://github.com/dart-lang/package_config/workflows/Dart%20CI/badge.svg)](https://github.com/dart-lang/package_config/actions?query=workflow%3A"Dart+CI"+branch%3Amaster) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config) +[![package publisher](https://img.shields.io/pub/publisher/package_config.svg)](https://pub.dev/packages/package_config/publisher) Support for working with **Package Configuration** files as described in the Package Configuration v2 [design document](https://github.com/dart-lang/language/blob/master/accepted/2.8/language-versioning/package-config-file-v2.md). diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index d4ed6b94f..ea0f3b456 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.3-dev +version: 2.0.3 description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/package_config From 20062b37f8a62b521bcbe1f4f2c300b25f4efcb1 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 20 May 2022 18:59:01 +0000 Subject: [PATCH 472/657] revert version change --- pkgs/package_config/CHANGELOG.md | 2 +- pkgs/package_config/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 4e095f2b0..9ecfe22b3 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.3 +## 2.0.3-dev - Improve file read performance; improve lookup performance. - Emit an error when a package is inside the package root of another package. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index ea0f3b456..d4ed6b94f 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.3 +version: 2.0.3-dev description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/package_config From cd86f83cbd32bfe7221b3265b5516ea8e0b38756 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Mon, 23 May 2022 16:01:41 +0200 Subject: [PATCH 473/657] Adds `minVersion` to `findPackageConfig{,Uri}` methods. (dart-lang/package_config#125) * Adds `minVersion` to `findPackageConfig{,Uri}` methods. This parameter currently allows you to ignore `.packages` files while searching for a configuration file. If we later add a version 3 of the configuration, it should also allow ignoring version 2 configurations. --- pkgs/package_config/CHANGELOG.md | 9 +++- pkgs/package_config/lib/package_config.dart | 34 +++++++++++--- pkgs/package_config/lib/src/discovery.dart | 47 +++++++++++++------ .../lib/src/package_config.dart | 2 +- .../lib/src/package_config_impl.dart | 5 +- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/discovery_test.dart | 26 ++++++++++ .../test/discovery_uri_test.dart | 27 +++++++++++ 8 files changed, 127 insertions(+), 25 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 9ecfe22b3..b6e91bbd3 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,4 +1,11 @@ -## 2.0.3-dev +## 2.1.0 + +- Adds `minVersion` to `findPackageConfig` and `findPackageConfigVersion` + which allows ignoring earlier versions (which currently only means + ignoring version 1, aka. `.packages` files.) + +- Changes the version number of `SimplePackageConfig.empty` to the + current maximum version. - Improve file read performance; improve lookup performance. - Emit an error when a package is inside the package root of another package. diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index bd227e4e5..a2c0321b8 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -111,10 +111,21 @@ Future loadPackageConfigUri(Uri file, /// a valid configuration from the invalid configuration file. /// If no [onError] is provided, errors are thrown immediately. /// +/// If [minVersion] is set to something greater than its default, +/// any lower-version configuration files are ignored in the search. +/// /// Returns `null` if no configuration file is found. Future findPackageConfig(Directory directory, - {bool recurse = true, void Function(Object error)? onError}) => - discover.findPackageConfig(directory, recurse, onError ?? throwError); + {bool recurse = true, + void Function(Object error)? onError, + int minVersion = 1}) { + if (minVersion > PackageConfig.maxVersion) { + throw ArgumentError.value(minVersion, 'minVersion', + 'Maximum known version is ${PackageConfig.maxVersion}'); + } + return discover.findPackageConfig( + directory, minVersion, recurse, onError ?? throwError); +} /// Finds a package configuration relative to [location]. /// @@ -155,13 +166,22 @@ Future findPackageConfig(Directory directory, /// a valid configuration from the invalid configuration file. /// If no [onError] is provided, errors are thrown immediately. /// +/// If [minVersion] is set to something greater than its default, +/// any lower-version configuration files are ignored in the search. +/// /// Returns `null` if no configuration file is found. Future findPackageConfigUri(Uri location, - {bool recurse = true, - Future Function(Uri uri)? loader, - void Function(Object error)? onError}) => - discover.findPackageConfigUri( - location, loader, onError ?? throwError, recurse); + {bool recurse = true, + int minVersion = 1, + Future Function(Uri uri)? loader, + void Function(Object error)? onError}) { + if (minVersion > PackageConfig.maxVersion) { + throw ArgumentError.value(minVersion, 'minVersion', + 'Maximum known version is ${PackageConfig.maxVersion}'); + } + return discover.findPackageConfigUri( + location, minVersion, loader, onError ?? throwError, recurse); +} /// Writes a package configuration to the provided directory. /// diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index a6cc451f2..ccc86ea23 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -25,15 +25,20 @@ final Uri parentPath = Uri(path: '..'); /// and stopping when something is found. /// /// * Check if a `.dart_tool/package_config.json` file exists in the directory. -/// * Check if a `.packages` file exists in the directory. +/// * Check if a `.packages` file exists in the directory +/// (if `minVersion <= 1`). /// * Repeat these checks for the parent directories until reaching the /// root directory if [recursive] is true. /// /// If any of these tests succeed, a `PackageConfig` class is returned. /// Returns `null` if no configuration was found. If a configuration /// is needed, then the caller can supply [PackageConfig.empty]. +/// +/// If [minVersion] is greated than 1, `.packages` files are ignored. +/// If [minVersion] is greater than the version read from the +/// `package_config.json` file, it too is ignored. Future findPackageConfig(Directory baseDirectory, - bool recursive, void Function(Object error) onError) async { + int minVersion, bool recursive, void Function(Object error) onError) async { var directory = baseDirectory; if (!directory.isAbsolute) directory = directory.absolute; if (!await directory.exists()) { @@ -41,7 +46,8 @@ Future findPackageConfig(Directory baseDirectory, } do { // Check for $cwd/.packages - var packageConfig = await findPackagConfigInDirectory(directory, onError); + var packageConfig = + await findPackagConfigInDirectory(directory, minVersion, onError); if (packageConfig != null) return packageConfig; if (!recursive) break; // Check in parent directories. @@ -55,6 +61,7 @@ Future findPackageConfig(Directory baseDirectory, /// Similar to [findPackageConfig] but based on a URI. Future findPackageConfigUri( Uri location, + int minVersion, Future Function(Uri uri)? loader, void Function(Object error) onError, bool recursive) async { @@ -67,6 +74,7 @@ Future findPackageConfigUri( if (location.isScheme('file')) { return findPackageConfig( Directory.fromUri(location.resolveUri(currentPath)), + minVersion, recursive, onError); } @@ -77,12 +85,15 @@ Future findPackageConfigUri( var file = location.resolveUri(packageConfigJsonPath); var bytes = await loader(file); if (bytes != null) { - return parsePackageConfigBytes(bytes, file, onError); + var config = parsePackageConfigBytes(bytes, file, onError); + if (config.version >= minVersion) return config; } - file = location.resolveUri(dotPackagesPath); - bytes = await loader(file); - if (bytes != null) { - return packages_file.parse(bytes, file, onError); + if (minVersion <= 1) { + file = location.resolveUri(dotPackagesPath); + bytes = await loader(file); + if (bytes != null) { + return packages_file.parse(bytes, file, onError); + } } if (!recursive) break; var parent = location.resolveUri(parentPath); @@ -102,15 +113,23 @@ Future findPackageConfigUri( /// If [onError] is supplied, parsing errors are reported using that, and /// a best-effort attempt is made to return a package configuration. /// This may be the empty package configuration. -Future findPackagConfigInDirectory( - Directory directory, void Function(Object error) onError) async { +/// +/// If [minVersion] is greated than 1, `.packages` files are ignored. +/// If [minVersion] is greater than the version read from the +/// `package_config.json` file, it too is ignored. +Future findPackagConfigInDirectory(Directory directory, + int minVersion, void Function(Object error) onError) async { var packageConfigFile = await checkForPackageConfigJsonFile(directory); if (packageConfigFile != null) { - return await readPackageConfigJsonFile(packageConfigFile, onError); + var config = await readPackageConfigJsonFile(packageConfigFile, onError); + if (config.version < minVersion) return null; + return config; } - packageConfigFile = await checkForDotPackagesFile(directory); - if (packageConfigFile != null) { - return await readDotPackagesFile(packageConfigFile, onError); + if (minVersion <= 1) { + packageConfigFile = await checkForDotPackagesFile(directory); + if (packageConfigFile != null) { + return await readDotPackagesFile(packageConfigFile, onError); + } } return null; } diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 3c5cc5196..ba52c147d 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -39,7 +39,7 @@ abstract class PackageConfig { /// including the two paths being the same. /// /// * No package's root must be the same as another package's root. - /// * The package-root of a package must be inside the pacakge's root. + /// * The package-root of a package must be inside the package's root. /// * If one package's package-root is inside another package's root, /// then the latter package's package root must not be inside the former /// package's root. (No getting between a package and its package root!) diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index aef817664..4c8f23443 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -37,8 +37,11 @@ class SimplePackageConfig implements PackageConfig { /// /// The empty configuration can be used in cases where no configuration is /// found, but code expects a non-null configuration. + /// + /// The version number is [PackageConfig.maxVersion] to avoid + /// minimum-version filters discarding the configuration. const SimplePackageConfig.empty() - : version = 1, + : version = PackageConfig.maxVersion, _packageTree = const EmptyPackageTree(), _packages = const {}, extraData = null; diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index d4ed6b94f..56e30b5df 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.0.3-dev +version: 2.1.0 description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/package_config diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 4a1bba0a6..17b6aa099 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -201,6 +201,32 @@ void main() { expect(hadError, true); }); }); + + // Does not find .packages if no package_config.json and minVersion > 1. + fileTest('.packages ignored', { + '.packages': packagesFile, + 'script.dart': 'main(){}' + }, (Directory directory) async { + var config = (await findPackageConfig(directory, minVersion: 2)); + expect(config, null); + }); + + // Finds package_config.json in super-directory, with .packages in + // subdir and minVersion > 1. + fileTest('package_config.json recursive .packages ignored', { + '.dart_tool': { + 'package_config.json': packageConfigFile, + }, + 'subdir': { + '.packages': packagesFile, + 'script.dart': 'main(){}', + } + }, (Directory directory) async { + var config = (await findPackageConfig(subdir(directory, 'subdir/'), + minVersion: 2))!; + expect(config.version, 2); + validatePackagesFile(config, directory); + }); }); group('loadPackageConfig', () { diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index e487e471d..6183ce3ba 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -145,6 +145,33 @@ void main() { expect(() => findPackageConfigUri(directory, loader: loader), throwsA(TypeMatcher())); }); + + // Does not find .packages if no package_config.json and minVersion > 1. + loaderTest('.packages ignored', { + '.packages': packagesFile, + 'script.dart': 'main(){}' + }, (directory, loader) async { + var config = (await findPackageConfigUri(directory, + minVersion: 2, loader: loader)); + expect(config, null); + }); + + // Finds package_config.json in super-directory, with .packages in + // subdir and minVersion > 1. + loaderTest('package_config.json recursive ignores .packages', { + '.dart_tool': { + 'package_config.json': packageConfigFile, + }, + 'subdir': { + '.packages': packagesFile, + 'script.dart': 'main(){}', + } + }, (directory, loader) async { + var config = (await findPackageConfigUri(directory.resolve('subdir/'), + minVersion: 2, loader: loader))!; + expect(config.version, 2); + validatePackagesFile(config, directory); + }); }); group('loadPackageConfig', () { From 7dc5e0657a7402ef41433445fdbbe911845c709d Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Wed, 15 Jun 2022 13:04:13 -0700 Subject: [PATCH 474/657] prep for publishing 1.5.1 --- pkgs/pool/CHANGELOG.md | 2 +- pkgs/pool/README.md | 4 ++++ pkgs/pool/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index c9694dd02..64b51cc97 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.5.1-dev +## 1.5.1 * Switch to using `package:lints` for analysis. * Populate the pubspec `repository` field. diff --git a/pkgs/pool/README.md b/pkgs/pool/README.md index 641e77287..9e74f4d0d 100644 --- a/pkgs/pool/README.md +++ b/pkgs/pool/README.md @@ -1,3 +1,7 @@ +[![Dart CI](https://github.com/dart-lang/pool/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/pool/actions/workflows/test-package.yml) +[![pub package](https://img.shields.io/pub/v/pool.svg)](https://pub.dev/packages/pool) +[![package publisher](https://img.shields.io/pub/publisher/pool.svg)](https://pub.dev/packages/pool/publisher) + The pool package exposes a `Pool` class which makes it easy to manage a limited pool of resources. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 26ca100b4..b32438885 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.1-dev +version: 1.5.1 description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. From e05e41bff0698289b182a7adb2916cede315cdd0 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Wed, 15 Jun 2022 13:16:41 -0700 Subject: [PATCH 475/657] Update README.md --- pkgs/pool/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/README.md b/pkgs/pool/README.md index 9e74f4d0d..b100ed35d 100644 --- a/pkgs/pool/README.md +++ b/pkgs/pool/README.md @@ -1,4 +1,4 @@ -[![Dart CI](https://github.com/dart-lang/pool/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/pool/actions/workflows/test-package.yml) +[![Dart CI](https://github.com/dart-lang/pool/actions/workflows/ci.yml/badge.svg)](https://github.com/dart-lang/pool/actions/workflows/ci.yml) [![pub package](https://img.shields.io/pub/v/pool.svg)](https://pub.dev/packages/pool) [![package publisher](https://img.shields.io/pub/publisher/pool.svg)](https://pub.dev/packages/pool/publisher) From 3c857aba528b75f86d3c1af3c11a4e05efc8f397 Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 20 Jul 2022 16:07:36 -0700 Subject: [PATCH 476/657] Properly indent multi-line labels for mutli-span highlights (dart-lang/source_span#86) --- pkgs/source_span/CHANGELOG.md | 4 +- pkgs/source_span/analysis_options.yaml | 1 - pkgs/source_span/lib/src/highlighter.dart | 66 ++++++++++--- pkgs/source_span/pubspec.yaml | 2 +- .../test/multiple_highlight_test.dart | 96 +++++++++++++++++++ 5 files changed, 153 insertions(+), 16 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 5722045c2..4c4907906 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,4 +1,6 @@ -# 1.9.1-dev +# 1.9.1 + +* Properly handle multi-line labels for multi-span highlights. * Populate the pubspec `repository` field. diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index 002297f45..97c0552ff 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -39,7 +39,6 @@ linter: - file_names - hash_and_equals - implementation_imports - - invariant_booleans - iterable_contains_unrelated_type - library_names - library_prefixes diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index d4e5ebf0e..53f3d6377 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -367,12 +367,13 @@ class Highlighter { _writeMultilineHighlights(line, highlightsByColumn, current: highlight); if (highlightsByColumn.isNotEmpty) _buffer.write(' '); - _colorize(() { + final underlineLength = _colorize(() { + final start = _buffer.length; _writeUnderline(line, highlight.span, highlight.isPrimary ? '^' : glyph.horizontalLineBold); - _writeLabel(highlight.label); + return _buffer.length - start; }, color: color); - _buffer.writeln(); + _writeLabel(highlight, highlightsByColumn, underlineLength); } else if (highlight.span.start.line == line.number) { if (highlightsByColumn.contains(highlight)) return; replaceFirstNull(highlightsByColumn, highlight); @@ -394,16 +395,17 @@ class Highlighter { _buffer.write(' '); _writeMultilineHighlights(line, highlightsByColumn, current: highlight); - _colorize(() { + final underlineLength = _colorize(() { + final start = _buffer.length; if (coversWholeLine) { _buffer.write(glyph.horizontalLine * 3); } else { _writeArrow(line, math.max(highlight.span.end.column - 1, 0), beginning: false); } - _writeLabel(highlight.label); + return _buffer.length - start; }, color: color); - _buffer.writeln(); + _writeLabel(highlight, highlightsByColumn, underlineLength); replaceWithNull(highlightsByColumn, highlight); } } @@ -442,9 +444,45 @@ class Highlighter { ..write('^'); } - /// Writes a space followed by [label] if [label] isn't `null`. - void _writeLabel(String? label) { - if (label != null) _buffer.write(' $label'); + /// Writes [highlight]'s label. + /// + /// The `_buffer` is assumed to be written to the point where the first line + /// of `highlight.label` can be written after a space, but this takes care of + /// writing indentation and highlight columns for later lines. + /// + /// The [highlightsByColumn] are used to write ongoing highlight lines if the + /// label is more than one line long. + /// + /// The [underlineLength] is the length of the line written between the + /// highlights and the beginning of the first label. + void _writeLabel(_Highlight highlight, List<_Highlight?> highlightsByColumn, + int underlineLength) { + final label = highlight.label; + if (label == null) { + _buffer.writeln(); + return; + } + + final lines = label.split('\n'); + final color = highlight.isPrimary ? _primaryColor : _secondaryColor; + _colorize(() => _buffer.write(' ${lines.first}'), color: color); + _buffer.writeln(); + + for (var text in lines.skip(1)) { + _writeSidebar(); + _buffer.write(' '); + for (var columnHighlight in highlightsByColumn) { + if (columnHighlight == null || columnHighlight == highlight) { + _buffer.write(' '); + } else { + _buffer.write(glyph.verticalLine); + } + } + + _buffer.write(' ' * underlineLength); + _colorize(() => _buffer.write(' $text'), color: color); + _buffer.writeln(); + } } /// Writes a snippet from the source text, converting hard tab characters into @@ -496,10 +534,11 @@ class Highlighter { /// 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}) { + T _colorize(T Function() callback, {required String? color}) { if (_primaryColor != null && color != null) _buffer.write(color); - callback(); + final result = callback(); if (_primaryColor != null && color != null) _buffer.write(colors.none); + return result; } } @@ -522,14 +561,15 @@ class _Highlight { /// used in the same message. final String? label; - _Highlight(SourceSpan span, {this.label, bool primary = false}) + _Highlight(SourceSpan span, {String? label, bool primary = false}) : span = (() { var newSpan = _normalizeContext(span); newSpan = _normalizeNewlines(newSpan); newSpan = _normalizeTrailingNewline(newSpan); return _normalizeEndOfLine(newSpan); })(), - isPrimary = primary; + isPrimary = primary, + label = label?.replaceAll('\r\n', '\n'); /// Normalizes [span] to ensure that it's a [SourceSpanWithContext] whose /// context actually contains its text at the expected column. diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 63a64b09c..8bde1c281 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.9.1-dev +version: 1.9.1 description: A library for identifying source spans and locations. repository: https://github.com/dart-lang/source_span diff --git a/pkgs/source_span/test/multiple_highlight_test.dart b/pkgs/source_span/test/multiple_highlight_test.dart index a9f5fdac4..ba4d686b3 100644 --- a/pkgs/source_span/test/multiple_highlight_test.dart +++ b/pkgs/source_span/test/multiple_highlight_test.dart @@ -328,4 +328,100 @@ quibble bibble boop | === two '""")); }); + + group('indents mutli-line labels', () { + test('for the primary label', () { + expect(file.span(17, 21).highlightMultiple('line 1\nline 2\nline 3', {}), + equals(""" + , +2 | whiz bang boom + | ^^^^ line 1 + | line 2 + | line 3 + '""")); + }); + + group('for a secondary label', () { + test('on the same line', () { + expect( + file.span(17, 21).highlightMultiple( + 'primary', {file.span(22, 26): 'line 1\nline 2\nline 3'}), + equals(""" + , +2 | whiz bang boom + | ^^^^ primary + | ==== line 1 + | line 2 + | line 3 + '""")); + }); + + test('on a different line', () { + expect( + file.span(17, 21).highlightMultiple( + 'primary', {file.span(31, 34): 'line 1\nline 2\nline 3'}), + equals(""" + , +2 | whiz bang boom + | ^^^^ primary +3 | zip zap zop + | === line 1 + | line 2 + | line 3 + '""")); + }); + }); + + group('for a multiline span', () { + test('that covers the whole last line', () { + expect( + file.span(12, 70).highlightMultiple('line 1\nline 2\nline 3', {}), + equals(""" + , +2 | / whiz bang boom +3 | | zip zap zop +4 | | fwee fwoo fwip +5 | | argle bargle boo + | '--- line 1 + | line 2 + | line 3 + '""")); + }); + + test('that covers part of the last line', () { + expect( + file.span(12, 66).highlightMultiple('line 1\nline 2\nline 3', {}), + equals(""" + , +2 | / whiz bang boom +3 | | zip zap zop +4 | | fwee fwoo fwip +5 | | argle bargle boo + | '------------^ line 1 + | line 2 + | line 3 + '""")); + }); + }); + + test('with an overlapping span', () { + expect( + file.span(12, 70).highlightMultiple('line 1\nline 2\nline 3', + {file.span(54, 89): 'two', file.span(0, 27): 'three'}), + equals(""" + , +1 | /- foo bar baz +2 | |/ whiz bang boom + | '+--- three +3 | | zip zap zop +4 | | fwee fwoo fwip +5 | /+ argle bargle boo + | |'--- line 1 + | | line 2 + | | line 3 +6 | | gibble bibble bop + | '---- two + '""")); + }); + }); } From 6eab75df7cd02175c73ef9b7643592074f96cd71 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 1 Aug 2022 08:56:35 -0700 Subject: [PATCH 477/657] Drop invariant_booleans (dart-lang/pub_semver#67) --- pkgs/pub_semver/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index a5aacab9a..2a5cecd36 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -28,7 +28,6 @@ linter: - file_names - hash_and_equals - implementation_imports - - invariant_booleans - iterable_contains_unrelated_type - join_return_with_assignment - list_remove_unrelated_type From b2f885ff8fe7fa8f695aba40b2f17c4367376121 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 4 Oct 2022 09:40:27 -0700 Subject: [PATCH 478/657] update the CI; update readme (dart-lang/pub_semver#69) * update the CI; update readme * fix setup-dart version --- pkgs/pub_semver/.github/dependabot.yaml | 8 ++++++++ pkgs/pub_semver/.github/workflows/test-package.yml | 8 ++++---- pkgs/pub_semver/CHANGELOG.md | 4 ++++ pkgs/pub_semver/README.md | 7 ++++++- pkgs/pub_semver/analysis_options.yaml | 5 +++-- pkgs/pub_semver/lib/src/version_union.dart | 4 ++-- pkgs/pub_semver/pubspec.yaml | 2 +- 7 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 pkgs/pub_semver/.github/dependabot.yaml diff --git a/pkgs/pub_semver/.github/dependabot.yaml b/pkgs/pub_semver/.github/dependabot.yaml new file mode 100644 index 000000000..214481934 --- /dev/null +++ b/pkgs/pub_semver/.github/dependabot.yaml @@ -0,0 +1,8 @@ +# Dependabot configuration file. +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index cdc25d958..1f5521683 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [2.12.0, dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 6f0d45bd2..68c2a702c 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.1-dev + +- Add markdown badges to the readme. + # 2.1.1 - Fixed the version parsing pattern to only accept dots between version diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index 8282501d6..ad0740ce0 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -1,8 +1,13 @@ [![Dart CI](https://github.com/dart-lang/pub_semver/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/pub_semver/actions/workflows/test-package.yml) [![Pub](https://img.shields.io/pub/v/pub_semver.svg)](https://pub.dev/packages/pub_semver) +[![package publisher](https://img.shields.io/pub/publisher/pub_semver.svg)](https://pub.dev/packages/pub_semver/publisher) Handles version numbers and version constraints in the same way that [pub][] -does. The semantics here very closely follow the +does. + +## Semantics + +The semantics here very closely follow the [Semantic Versioning spec version 2.0.0-rc.1][semver]. It differs from semver in a few corner cases: diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index 2a5cecd36..056968072 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -1,8 +1,9 @@ include: package:lints/recommended.yaml analyzer: - strong-mode: - implicit-casts: false + language: + strict-casts: true + strict-inference: true linter: rules: diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index 24b82f4cc..69ae03413 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -214,10 +214,10 @@ class VersionUnion implements VersionConstraint { @override bool operator ==(Object other) => other is VersionUnion && - const ListEquality().equals(ranges, other.ranges); + const ListEquality().equals(ranges, other.ranges); @override - int get hashCode => const ListEquality().hash(ranges); + int get hashCode => const ListEquality().hash(ranges); @override String toString() => ranges.join(' or '); diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index aa7ab52c8..aa60fdff6 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.1.1 +version: 2.1.2-dev description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. From 3e69e5a83c6d2a52736e1e6d96d66ecfb4d2f3ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Oct 2022 09:56:22 -0700 Subject: [PATCH 479/657] Bump actions/checkout from 3.0.2 to 3.1.0 (dart-lang/pub_semver#70) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.0.2 to 3.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/2541b1294d2704b0964813337f33b291d3f8596b...93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 1f5521683..68f255c74 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.12.0, dev] steps: - - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From 30eceda0feb980020c4cac482c91b021b31cd326 Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Thu, 6 Oct 2022 12:54:31 +0200 Subject: [PATCH 480/657] Refactor away from deprecated error (dart-lang/pub_semver#72) * Refactor away from deprecated error `FallThroughError` is deprecated, and scheduled for removal in 3.0 * Update version_constraint.dart --- pkgs/pub_semver/lib/src/version_constraint.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 6eb6c3a29..50d7c7799 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -93,7 +93,7 @@ abstract class VersionConstraint { case '>': return VersionRange(min: version, includeMin: false); } - throw FallThroughError(); + throw UnsupportedError(op!); } // Try to parse the "^" operator followed by a version. From d3770d868327dbee96909037b071a4d1486853dc Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 14 Oct 2022 17:54:30 +0000 Subject: [PATCH 481/657] prep for publishing (dart-lang/pub_semver#73) --- pkgs/pub_semver/CHANGELOG.md | 2 +- pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 68c2a702c..b0346329f 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,4 +1,4 @@ -# 2.1.1-dev +# 2.1.2 - Add markdown badges to the readme. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index aa60fdff6..623606faf 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.1.2-dev +version: 2.1.2 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. From 35655f497c5597426790f0552102cf7e34bf0c7b Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 18 Oct 2022 18:30:04 +0000 Subject: [PATCH 482/657] update ci; prep for publishing (dart-lang/source_maps#67) * update ci; prep for publishing * review comments --- pkgs/source_maps/.github/dependabot.yaml | 8 ++++++++ pkgs/source_maps/.github/workflows/test-package.yml | 8 ++++---- pkgs/source_maps/CHANGELOG.md | 5 ++--- pkgs/source_maps/pubspec.yaml | 8 ++++---- 4 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 pkgs/source_maps/.github/dependabot.yaml diff --git a/pkgs/source_maps/.github/dependabot.yaml b/pkgs/source_maps/.github/dependabot.yaml new file mode 100644 index 000000000..214481934 --- /dev/null +++ b/pkgs/source_maps/.github/dependabot.yaml @@ -0,0 +1,8 @@ +# Dependabot configuration file. +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index e47bf6600..81ebfebcd 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [2.12.0, dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index dcd04000b..a282117f6 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,7 +1,6 @@ -# 0.10.11-dev +# 0.10.11 -- Switch to `package:lints`. -- Populate the pubspec `repository` field. +* Populate the pubspec `repository` field. ## 0.10.10 diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index b1cb177b5..e32c27857 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,15 +1,15 @@ name: source_maps -version: 0.10.11-dev +version: 0.10.11 description: Library to programmatically manipulate source map files. repository: https://github.com/dart-lang/source_maps environment: - sdk: ">=2.12.0 <3.0.0" + sdk: '>=2.18.0 <3.0.0' dependencies: source_span: ^1.8.0 dev_dependencies: - lints: ^1.0.0 - test: ^1.16.0 + lints: ^2.0.0 term_glyph: ^1.2.0 + test: ^1.16.0 From 512570677b821da576d856bc1a26b5e4173585bc Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 18 Oct 2022 19:48:28 +0000 Subject: [PATCH 483/657] adjust the min sdk we test against (dart-lang/source_maps#68) --- pkgs/source_maps/.github/workflows/test-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 81ebfebcd..d257b9f9c 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.12.0, dev] + sdk: [2.18.0, dev] steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d From 3488a00d49c5691b9d34adc1076efee0d08bf9a3 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Wed, 19 Oct 2022 16:41:42 +0000 Subject: [PATCH 484/657] Update README.md (dart-lang/source_maps#69) * Update README.md * update the changelog --- pkgs/source_maps/CHANGELOG.md | 1 + pkgs/source_maps/README.md | 2 +- pkgs/source_maps/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index a282117f6..366501968 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,6 +1,7 @@ # 0.10.11 * Populate the pubspec `repository` field. +* Update the source map documentation link in the readme. ## 0.10.10 diff --git a/pkgs/source_maps/README.md b/pkgs/source_maps/README.md index 89e9eff82..e81f2782c 100644 --- a/pkgs/source_maps/README.md +++ b/pkgs/source_maps/README.md @@ -26,5 +26,5 @@ Some upcoming features we are planning to add to this package are: instance, if you have 2 tools that produce source maps and you call one with the result of the other. -[closure]: http://code.google.com/p/closure-compiler/wiki/SourceMaps +[closure]: https://github.com/google/closure-compiler/wiki/Source-Maps [spec]: https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index e32c27857..eaaa46cd8 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,6 +1,6 @@ name: source_maps version: 0.10.11 -description: Library to programmatically manipulate source map files. +description: A library to programmatically manipulate source map files. repository: https://github.com/dart-lang/source_maps environment: From 013c00fda144cfba74303fd237d1a73731dadd60 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 25 Oct 2022 10:24:43 -0700 Subject: [PATCH 485/657] Require Dart 2.18, update lints, latest pkg:lints, add dependabot (dart-lang/source_span#88) --- pkgs/source_span/.github/dependabot.yml | 10 +++ .../.github/workflows/test-package.yml | 10 +-- pkgs/source_span/CHANGELOG.md | 4 + pkgs/source_span/analysis_options.yaml | 87 ++++++------------- pkgs/source_span/lib/src/file.dart | 10 +-- pkgs/source_span/lib/src/highlighter.dart | 24 ++--- pkgs/source_span/lib/src/location.dart | 7 +- pkgs/source_span/lib/src/location_mixin.dart | 2 +- pkgs/source_span/lib/src/span.dart | 4 +- pkgs/source_span/lib/src/span_exception.dart | 19 ++-- pkgs/source_span/lib/src/span_mixin.dart | 6 +- pkgs/source_span/lib/src/utils.dart | 4 +- pkgs/source_span/pubspec.yaml | 6 +- pkgs/source_span/test/highlight_test.dart | 40 ++++----- .../test/multiple_highlight_test.dart | 12 +-- pkgs/source_span/test/utils_test.dart | 10 +-- 16 files changed, 114 insertions(+), 141 deletions(-) create mode 100644 pkgs/source_span/.github/dependabot.yml diff --git a/pkgs/source_span/.github/dependabot.yml b/pkgs/source_span/.github/dependabot.yml new file mode 100644 index 000000000..9735d75f3 --- /dev/null +++ b/pkgs/source_span/.github/dependabot.yml @@ -0,0 +1,10 @@ +# Set update schedule for GitHub Actions +# See https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot + +version: 2 +updates: + +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 8c20eeb6d..bc4359926 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install @@ -47,10 +47,10 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [dev] + sdk: [2.18.0, dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 4c4907906..05c7e71d5 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.9.2-dev + +* Require Dart 2.18 + # 1.9.1 * Properly handle multi-line labels for multi-span highlights. diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index 97c0552ff..8b32d108a 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -1,91 +1,56 @@ +# https://dart.dev/guides/language/analysis-options include: package:lints/recommended.yaml analyzer: - strong-mode: - implicit-casts: false + language: + strict-casts: true + strict-inference: true + strict-raw-types: true linter: rules: - always_declare_return_types - - annotate_overrides - avoid_bool_literals_in_conditional_expressions + - avoid_catching_errors - avoid_classes_with_only_static_members - - avoid_empty_else - - avoid_function_literals_in_foreach_calls - - avoid_init_to_null - - avoid_null_checks_in_equality_operators - - avoid_relative_lib_imports - - avoid_renaming_method_parameters - - avoid_return_types_on_setters + - avoid_dynamic_calls + - avoid_private_typedef_functions + - avoid_redundant_argument_values - avoid_returning_null - avoid_returning_null_for_future - - avoid_returning_null_for_void - avoid_returning_this - - avoid_shadowing_type_parameters - - avoid_single_cascade_in_expression_statements - - avoid_types_as_parameter_names - avoid_unused_constructor_parameters - - await_only_futures - - camel_case_types + - avoid_void_async - cancel_subscriptions - cascade_invocations - comment_references - - constant_identifier_names - - control_flow_in_finally - directives_ordering - - empty_catches - - empty_constructor_bodies - - empty_statements - - file_names - - hash_and_equals - - implementation_imports - - iterable_contains_unrelated_type - - library_names - - library_prefixes - - list_remove_unrelated_type + - join_return_with_assignment + - lines_longer_than_80_chars + - literal_only_boolean_expressions + - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - - no_duplicate_case_values - - non_constant_identifier_names - - null_closures - omit_local_variable_types - only_throw_errors - - overridden_fields - package_api_docs - - package_names - - package_prefixed_library_names - - prefer_adjacent_string_concatenation - - prefer_collection_literals - - prefer_conditional_assignment + - prefer_asserts_in_initializer_lists - prefer_const_constructors - - prefer_contains - - prefer_equal_for_default_values - - prefer_final_fields + - prefer_const_declarations + - prefer_expression_function_bodies - prefer_final_locals - - prefer_generic_function_type_aliases - - prefer_initializing_formals - - prefer_interpolation_to_compose_strings - - prefer_is_empty - - prefer_is_not_empty - - prefer_null_aware_operators - - prefer_typing_uninitialized_variables - - recursive_getters - - slash_for_doc_comments + - prefer_relative_imports + - prefer_single_quotes + - sort_pub_dependencies - test_types_in_equals - throw_in_finally - - type_init_formals + - type_annotate_public_apis - unawaited_futures - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_const - - unnecessary_getters_setters - unnecessary_lambdas - - unnecessary_new - - unnecessary_null_aware_assignments - unnecessary_parenthesis + - unnecessary_raw_strings - unnecessary_statements - - unnecessary_this - - unrelated_type_equality_checks - - use_function_type_syntax_for_parameters - - use_rethrow_when_possible - - valid_regexps - - void_checks + - use_if_null_to_convert_nulls_to_bools + - use_raw_strings + - use_string_buffers + - use_super_parameters diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 473b8c17a..52d1b6cca 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -51,14 +51,14 @@ class SourceFile { /// This constructor is deprecated. /// - /// Use [new SourceFile.fromString] instead. + /// Use [SourceFile.fromString] instead. @Deprecated('Will be removed in 2.0.0') - SourceFile(String text, {url}) : this.decoded(text.runes, url: url); + SourceFile(String text, {Object? url}) : this.decoded(text.runes, url: url); /// Creates a new source file from [text]. /// /// [url] may be either a [String], a [Uri], or `null`. - SourceFile.fromString(String text, {url}) + SourceFile.fromString(String text, {Object? url}) : this.decoded(text.codeUnits, url: url); /// Creates a new source file from a list of decoded code units. @@ -70,7 +70,7 @@ class SourceFile { /// surrogate pairs. **This behavior is deprecated**. For /// forwards-compatibility, callers should only pass in characters less than /// or equal to `0xFFFF`. - SourceFile.decoded(Iterable decodedChars, {url}) + SourceFile.decoded(Iterable decodedChars, {Object? url}) : url = url is String ? Uri.parse(url) : url as Uri?, _decodedChars = Uint32List.fromList(decodedChars.toList()) { for (var i = 0; i < _decodedChars.length; i++) { @@ -387,7 +387,7 @@ class _FileSpan extends SourceSpanMixin implements FileSpan { } @override - bool operator ==(other) { + bool operator ==(Object other) { if (other is! FileSpan) return super == other; if (other is! _FileSpan) { return super == other && sourceUrl == other.sourceUrl; diff --git a/pkgs/source_span/lib/src/highlighter.dart b/pkgs/source_span/lib/src/highlighter.dart index 53f3d6377..19e04d02e 100644 --- a/pkgs/source_span/lib/src/highlighter.dart +++ b/pkgs/source_span/lib/src/highlighter.dart @@ -58,7 +58,7 @@ class Highlighter { /// should be used. /// /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors - Highlighter(SourceSpan span, {color}) + Highlighter(SourceSpan span, {Object? color}) : this._(_collateLines([_Highlight(span, primary: true)]), () { if (color == true) return colors.red; if (color == false) return null; @@ -95,13 +95,14 @@ class Highlighter { Highlighter._(this._lines, this._primaryColor, this._secondaryColor) : _paddingBeforeSidebar = 1 + math.max( - // In a purely mathematical world, floor(log10(n)) would give the - // number of digits in n, but floating point errors render that - // unreliable in practice. - (_lines.last.number + 1).toString().length, - // If [_lines] aren't contiguous, we'll write "..." in place of a - // line number. - _contiguous(_lines) ? 0 : 3), + // In a purely mathematical world, floor(log10(n)) would give the + // number of digits in n, but floating point errors render that + // unreliable in practice. + (_lines.last.number + 1).toString().length, + // If [_lines] aren't contiguous, we'll write "..." in place of a + // line number. + _contiguous(_lines) ? 0 : 3, + ), _maxMultilineSpans = _lines .map((line) => line.highlights .where((highlight) => isMultiline(highlight.span)) @@ -155,7 +156,7 @@ class Highlighter { var lineNumber = highlight.span.start.line - linesBeforeSpan; for (var line in context.split('\n')) { - // Only add a line if it hasn't already been added for a previous span. + // Only add a line if it hasn't already been added for a previous span if (lines.isEmpty || lineNumber > lines.last.number) { lines.add(_Line(line, lineNumber, url)); } @@ -192,7 +193,8 @@ class Highlighter { // 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. + // column is empty; if it contains a highlight, it should be drawn for that + // column. final highlightsByColumn = List<_Highlight?>.filled(_maxMultilineSpans, null); @@ -332,7 +334,7 @@ class Highlighter { } else if (endLine == line.number && highlight.span.end.column == line.text.length) { _buffer.write(highlight.label == null - ? glyph.glyphOrAscii('└', '\\') + ? glyph.glyphOrAscii('└', r'\') : vertical); } else { _colorize(() { diff --git a/pkgs/source_span/lib/src/location.dart b/pkgs/source_span/lib/src/location.dart index 634863bf0..8f22d7ba2 100644 --- a/pkgs/source_span/lib/src/location.dart +++ b/pkgs/source_span/lib/src/location.dart @@ -42,7 +42,7 @@ class SourceLocation implements Comparable { /// 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, {Object? sourceUrl, int? line, int? column}) : sourceUrl = sourceUrl is String ? Uri.parse(sourceUrl) : sourceUrl as Uri?, line = line ?? 0, @@ -83,7 +83,7 @@ class SourceLocation implements Comparable { } @override - bool operator ==(other) => + bool operator ==(Object other) => other is SourceLocation && sourceUrl == other.sourceUrl && offset == other.offset; @@ -98,6 +98,5 @@ class SourceLocation implements Comparable { /// 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}) - : super(offset, sourceUrl: sourceUrl, line: line, column: column); + SourceLocationBase(super.offset, {super.sourceUrl, super.line, super.column}); } diff --git a/pkgs/source_span/lib/src/location_mixin.dart b/pkgs/source_span/lib/src/location_mixin.dart index bae38befa..a44f5e295 100644 --- a/pkgs/source_span/lib/src/location_mixin.dart +++ b/pkgs/source_span/lib/src/location_mixin.dart @@ -42,7 +42,7 @@ abstract class SourceLocationMixin implements SourceLocation { } @override - bool operator ==(other) => + bool operator ==(Object other) => other is SourceLocation && sourceUrl == other.sourceUrl && offset == other.offset; diff --git a/pkgs/source_span/lib/src/span.dart b/pkgs/source_span/lib/src/span.dart index 05fd340a2..941dedce1 100644 --- a/pkgs/source_span/lib/src/span.dart +++ b/pkgs/source_span/lib/src/span.dart @@ -67,7 +67,7 @@ abstract class SourceSpan implements Comparable { /// characters if it's `true`. /// /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors - String message(String message, {color}); + String message(String message, {Object? color}); /// Prints the text associated with this span in a user-friendly way. /// @@ -87,7 +87,7 @@ abstract class SourceSpan implements Comparable { /// characters if it's `true`. /// /// [ANSI terminal color escape]: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors - String highlight({color}); + String highlight({Object? color}); } /// A base class for source spans with [start], [end], and [text] known at diff --git a/pkgs/source_span/lib/src/span_exception.dart b/pkgs/source_span/lib/src/span_exception.dart index c6db03ba2..90ad690d3 100644 --- a/pkgs/source_span/lib/src/span_exception.dart +++ b/pkgs/source_span/lib/src/span_exception.dart @@ -28,7 +28,7 @@ class SourceSpanException implements Exception { /// should be highlighted using the default color. If it's `false` or `null`, /// it indicates that the text shouldn't be highlighted. @override - String toString({color}) { + String toString({Object? color}) { if (span == null) return message; return 'Error on ${span!.message(message, color: color)}'; } @@ -43,8 +43,7 @@ class SourceSpanFormatException extends SourceSpanException @override int? get offset => span?.start.offset; - SourceSpanFormatException(String message, SourceSpan? span, [this.source]) - : super(message, span); + SourceSpanFormatException(super.message, super.span, [this.source]); } /// A [SourceSpanException] that also highlights some secondary spans to provide @@ -64,10 +63,9 @@ class MultiSourceSpanException extends SourceSpanException { /// additional information and helps distinguish it from [secondarySpans]. final Map secondarySpans; - MultiSourceSpanException(String message, SourceSpan? span, this.primaryLabel, + MultiSourceSpanException(super.message, super.span, this.primaryLabel, Map secondarySpans) - : secondarySpans = Map.unmodifiable(secondarySpans), - super(message, span); + : secondarySpans = Map.unmodifiable(secondarySpans); /// Returns a string representation of `this`. /// @@ -80,7 +78,7 @@ class MultiSourceSpanException extends SourceSpanException { /// If [color] is `true` or a string, [secondaryColor] is used to highlight /// [secondarySpans]. @override - String toString({color, String? secondaryColor}) { + String toString({Object? color, String? secondaryColor}) { if (span == null) return message; var useColor = false; @@ -110,8 +108,7 @@ class MultiSourceSpanFormatException extends MultiSourceSpanException @override int? get offset => span?.start.offset; - MultiSourceSpanFormatException(String message, SourceSpan? span, - String primaryLabel, Map secondarySpans, - [this.source]) - : super(message, span, primaryLabel, secondarySpans); + MultiSourceSpanFormatException( + super.message, super.span, super.primaryLabel, super.secondarySpans, + [this.source]); } diff --git a/pkgs/source_span/lib/src/span_mixin.dart b/pkgs/source_span/lib/src/span_mixin.dart index 4d7bab473..29b6119d2 100644 --- a/pkgs/source_span/lib/src/span_mixin.dart +++ b/pkgs/source_span/lib/src/span_mixin.dart @@ -50,7 +50,7 @@ abstract class SourceSpanMixin implements SourceSpan { } @override - String message(String message, {color}) { + String message(String message, {Object? color}) { final buffer = StringBuffer() ..write('line ${start.line + 1}, column ${start.column + 1}'); if (sourceUrl != null) buffer.write(' of ${p.prettyUri(sourceUrl)}'); @@ -67,13 +67,13 @@ abstract class SourceSpanMixin implements SourceSpan { } @override - String highlight({color}) { + String highlight({Object? color}) { if (this is! SourceSpanWithContext && length == 0) return ''; return Highlighter(this, color: color).highlight(); } @override - bool operator ==(other) => + bool operator ==(Object other) => other is SourceSpan && start == other.start && end == other.end; @override diff --git a/pkgs/source_span/lib/src/utils.dart b/pkgs/source_span/lib/src/utils.dart index 7df0bafca..aba14ecf9 100644 --- a/pkgs/source_span/lib/src/utils.dart +++ b/pkgs/source_span/lib/src/utils.dart @@ -9,12 +9,12 @@ import 'span_with_context.dart'; /// Returns the minimum of [obj1] and [obj2] according to /// [Comparable.compareTo]. -T min(T obj1, T obj2) => +T min>(T obj1, T obj2) => obj1.compareTo(obj2) > 0 ? obj2 : obj1; /// Returns the maximum of [obj1] and [obj2] according to /// [Comparable.compareTo]. -T max(T obj1, T obj2) => +T max>(T obj1, T obj2) => obj1.compareTo(obj2) > 0 ? obj1 : obj2; /// Returns whether all elements of [iter] are the same value, according to diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 8bde1c281..4531a74e3 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,10 +1,10 @@ name: source_span -version: 1.9.1 +version: 1.9.2-dev description: A library for identifying source spans and locations. repository: https://github.com/dart-lang/source_span environment: - sdk: ">=2.14.0 <3.0.0" + sdk: ">=2.18.0 <3.0.0" dependencies: collection: ^1.15.0 @@ -12,5 +12,5 @@ dependencies: term_glyph: ^1.2.0 dev_dependencies: - lints: ^1.0.0 + lints: ^2.0.0 test: ^1.16.0 diff --git a/pkgs/source_span/test/highlight_test.dart b/pkgs/source_span/test/highlight_test.dart index 7754d0076..93c42dbaa 100644 --- a/pkgs/source_span/test/highlight_test.dart +++ b/pkgs/source_span/test/highlight_test.dart @@ -232,28 +232,28 @@ foo bar '''); - expect(file.span(4, 9).highlight(), equals(""" + expect(file.span(4, 9).highlight(), equals(r""" , 2 | / -3 | \\ bar +3 | \ bar '""")); }); test('highlights the full last line', () { - expect(file.span(4, 27).highlight(), equals(""" + expect(file.span(4, 27).highlight(), equals(r""" , 1 | foo bar baz | ,-----^ -2 | \\ whiz bang boom +2 | \ whiz bang boom '""")); }); test('highlights the full last line with no trailing newline', () { - expect(file.span(4, 26).highlight(), equals(""" + expect(file.span(4, 26).highlight(), equals(r""" , 1 | foo bar baz | ,-----^ -2 | \\ whiz bang boom +2 | \ whiz bang boom '""")); }); @@ -264,21 +264,21 @@ whiz bang boom\r zip zap zop\r '''); - expect(file.span(4, 29).highlight(), equals(""" + expect(file.span(4, 29).highlight(), equals(r""" , 1 | foo bar baz | ,-----^ -2 | \\ whiz bang boom +2 | \ whiz bang boom '""")); }); test('highlights the full last line at the end of the file', () { - expect(file.span(4, 39).highlight(), equals(""" + expect(file.span(4, 39).highlight(), equals(r""" , 1 | foo bar baz | ,-----^ 2 | | whiz bang boom -3 | \\ zip zap zop +3 | \ zip zap zop '""")); }); @@ -290,12 +290,12 @@ foo bar baz whiz bang boom zip zap zop'''); - expect(file.span(4, 38).highlight(), equals(""" + expect(file.span(4, 38).highlight(), equals(r""" , 1 | foo bar baz | ,-----^ 2 | | whiz bang boom -3 | \\ zip zap zop +3 | \ zip zap zop '""")); }); @@ -306,31 +306,31 @@ foo bar '''); - expect(file.span(0, 5).highlight(), equals(""" + expect(file.span(0, 5).highlight(), equals(r""" , 1 | / foo -2 | \\ +2 | \ '""")); }); test('highlights multiple empty lines', () { final file = SourceFile.fromString('foo\n\n\n\nbar'); - expect(file.span(4, 7).highlight(), equals(""" + expect(file.span(4, 7).highlight(), equals(r""" , 2 | / 3 | | -4 | \\ +4 | \ '""")); }); // Regression test for #32 test('highlights the end of a line and an empty line', () { final file = SourceFile.fromString('foo\n\n'); - expect(file.span(3, 5).highlight(), equals(""" + expect(file.span(3, 5).highlight(), equals(r""" , 1 | foo | ,----^ -2 | \\ +2 | \ '""")); }); }); @@ -520,12 +520,12 @@ whiz bang\tboom 'foo\nbar\n', 'previous\nlines\nfoo\nbar\nfollowing line\n'); - expect(span.highlight(), equals(""" + expect(span.highlight(), equals(r""" , 1 | previous 2 | lines 3 | / foo -4 | \\ bar +4 | \ bar 5 | following line '""")); }); diff --git a/pkgs/source_span/test/multiple_highlight_test.dart b/pkgs/source_span/test/multiple_highlight_test.dart index ba4d686b3..139d53c8a 100644 --- a/pkgs/source_span/test/multiple_highlight_test.dart +++ b/pkgs/source_span/test/multiple_highlight_test.dart @@ -280,8 +280,7 @@ quibble bibble boop }); test('allows secondary spans to have null URL', () { - final span2 = SourceSpan(SourceLocation(1, sourceUrl: null), - SourceLocation(4, sourceUrl: null), 'foo'); + final span2 = SourceSpan(SourceLocation(1), SourceLocation(4), 'foo'); expect( file.span(31, 34).highlightMultiple('one', {span2: 'two'}), equals(""" @@ -296,8 +295,7 @@ quibble bibble boop }); test('allows primary span to have null URL', () { - final span1 = SourceSpan(SourceLocation(1, sourceUrl: null), - SourceLocation(4, sourceUrl: null), 'foo'); + final span1 = SourceSpan(SourceLocation(1), SourceLocation(4), 'foo'); expect( span1.highlightMultiple('one', {file.span(31, 34): 'two'}), equals(""" @@ -313,10 +311,8 @@ quibble bibble boop }); test('highlights multiple null URLs as separate files', () { - final span1 = SourceSpan(SourceLocation(1, sourceUrl: null), - SourceLocation(4, sourceUrl: null), 'foo'); - final span2 = SourceSpan(SourceLocation(1, sourceUrl: null), - SourceLocation(4, sourceUrl: null), 'bar'); + final span1 = SourceSpan(SourceLocation(1), SourceLocation(4), 'foo'); + final span2 = SourceSpan(SourceLocation(1), SourceLocation(4), 'bar'); expect(span1.highlightMultiple('one', {span2: 'two'}), equals(""" , diff --git a/pkgs/source_span/test/utils_test.dart b/pkgs/source_span/test/utils_test.dart index 293b30023..91397c01b 100644 --- a/pkgs/source_span/test/utils_test.dart +++ b/pkgs/source_span/test/utils_test.dart @@ -8,14 +8,14 @@ import 'package:test/test.dart'; void main() { group('find line start', () { test('skip entries in wrong column', () { - final context = '0_bb\n1_bbb\n2b____\n3bbb\n'; + const context = '0_bb\n1_bbb\n2b____\n3bbb\n'; 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'; + const context = '0123\n56789\nabcdefgh\n'; final index = findLineStart(context, '', 5)!; expect(index, 5); expect(context[index], '5'); @@ -38,19 +38,19 @@ void main() { }); test('found on the first line', () { - final context = '0\n2\n45\n'; + const context = '0\n2\n45\n'; final index = findLineStart(context, '0', 0); expect(index, 0); }); test('finds text that starts with a newline', () { - final context = '0\n2\n45\n'; + const context = '0\n2\n45\n'; final index = findLineStart(context, '\n2', 1); expect(index, 0); }); test('not found', () { - final context = '0\n2\n45\n'; + const context = '0\n2\n45\n'; final index = findLineStart(context, '0', 1); expect(index, isNull); }); From e9949575add8301db15880ad60d43c36b1dfb79a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 7 Nov 2022 09:53:02 -0800 Subject: [PATCH 486/657] update and fix lints, bump min SDK (dart-lang/pub_semver#74) --- .../.github/workflows/test-package.yml | 2 +- pkgs/pub_semver/CHANGELOG.md | 8 +-- pkgs/pub_semver/analysis_options.yaml | 51 +++++++++---------- pkgs/pub_semver/lib/src/version.dart | 23 +++++---- .../lib/src/version_constraint.dart | 7 +-- pkgs/pub_semver/lib/src/version_range.dart | 6 +-- pkgs/pub_semver/lib/src/version_union.dart | 4 +- pkgs/pub_semver/pubspec.yaml | 6 +-- pkgs/pub_semver/test/utils.dart | 6 +-- pkgs/pub_semver/test/version_range_test.dart | 5 +- pkgs/pub_semver/test/version_test.dart | 2 +- 11 files changed, 55 insertions(+), 65 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 68f255c74..5c5b39d11 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.12.0, dev] + sdk: [2.17.0, dev] steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index b0346329f..e23ce1030 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.3-dev + +- Require Dart 2.17. + # 2.1.2 - Add markdown badges to the readme. @@ -16,10 +20,6 @@ # 2.0.0 - Stable null safety release. - -# 2.0.0-nullsafety.0 - -- Migrate to null safety. - `Version.primary` now throws `StateError` if the `versions` argument is empty. # 1.4.4 diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index 056968072..56d7c9061 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -1,58 +1,55 @@ +# https://dart.dev/guides/language/analysis-options include: package:lints/recommended.yaml analyzer: language: strict-casts: true strict-inference: true + strict-raw-types: true linter: rules: + - always_declare_return_types - avoid_bool_literals_in_conditional_expressions + - avoid_catching_errors - avoid_classes_with_only_static_members - - avoid_function_literals_in_foreach_calls - - avoid_renaming_method_parameters + - avoid_dynamic_calls + - avoid_private_typedef_functions + - avoid_redundant_argument_values - avoid_returning_null - avoid_returning_null_for_future - - avoid_returning_null_for_void - avoid_returning_this - - avoid_single_cascade_in_expression_statements - avoid_unused_constructor_parameters - - await_only_futures - - camel_case_types + - avoid_void_async - cancel_subscriptions - cascade_invocations - comment_references - - constant_identifier_names - - control_flow_in_finally - directives_ordering - - empty_statements - - file_names - - hash_and_equals - - implementation_imports - - iterable_contains_unrelated_type - join_return_with_assignment - - list_remove_unrelated_type + - lines_longer_than_80_chars - literal_only_boolean_expressions + - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - - non_constant_identifier_names + - no_runtimeType_toString + - omit_local_variable_types - only_throw_errors - - overridden_fields - package_api_docs - - package_names - - package_prefixed_library_names + - prefer_asserts_in_initializer_lists - prefer_const_constructors - #- prefer_final_locals - - prefer_initializing_formals - - prefer_interpolation_to_compose_strings - - prefer_null_aware_operators - - prefer_typing_uninitialized_variables + - prefer_const_declarations + - prefer_expression_function_bodies + - prefer_relative_imports + - prefer_single_quotes + - sort_pub_dependencies - test_types_in_equals - throw_in_finally + - type_annotate_public_apis + - unawaited_futures - unnecessary_await_in_return - - unnecessary_brace_in_string_interps - - unnecessary_getters_setters - unnecessary_lambdas - - unnecessary_null_aware_assignments - unnecessary_parenthesis - unnecessary_statements - - void_checks + - use_if_null_to_convert_nulls_to_bools + - use_raw_strings + - use_string_buffers + - use_super_parameters diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index ba6ce8f78..f9e536087 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -12,7 +12,7 @@ import 'version_constraint.dart'; import 'version_range.dart'; /// The equality operator to use for comparing version components. -final _equality = const IterableEquality(); +const _equality = IterableEquality(); /// A parsed semantic version number. @sealed @@ -70,14 +70,14 @@ class Version implements VersionConstraint, VersionRange { /// This is split into a list of components, each of which may be either a /// string or a non-negative integer. It may also be empty, indicating that /// this version has no pre-release identifier. - final List preRelease; + final List preRelease; /// The build identifier: "foo" in "1.2.3+foo". /// /// This is split into a list of components, each of which may be either a /// string or a non-negative integer. It may also be empty, indicating that /// this version has no build identifier. - final List build; + final List build; /// The original string representation of the version number. /// @@ -96,7 +96,7 @@ class Version implements VersionConstraint, VersionRange { Version._(this.major, this.minor, this.patch, String? preRelease, String? build, this._text) - : preRelease = preRelease == null ? [] : _splitParts(preRelease), + : preRelease = preRelease == null ? [] : _splitParts(preRelease), build = build == null ? [] : _splitParts(build) { if (major < 0) throw ArgumentError('Major version must be non-negative.'); if (minor < 0) throw ArgumentError('Minor version must be non-negative.'); @@ -154,12 +154,13 @@ class Version implements VersionConstraint, VersionRange { /// Splits a string of dot-delimited identifiers into their component parts. /// /// Identifiers that are numeric are converted to numbers. - static List _splitParts(String text) { - return text.split('.').map((part) { - // Return an integer part if possible, otherwise return the string as-is - return int.tryParse(part) ?? part; - }).toList(); - } + static List _splitParts(String text) => text + .split('.') + .map((part) => + // Return an integer part if possible, otherwise return the string + // as-is + int.tryParse(part) ?? part) + .toList(); @override bool operator ==(Object other) => @@ -354,7 +355,7 @@ class Version implements VersionConstraint, VersionRange { /// /// This is used for the pre-release and build version parts. This follows /// Rule 12 of the Semantic Versioning spec (v2.0.0-rc.1). - int _compareLists(List a, List b) { + int _compareLists(List a, List b) { for (var i = 0; i < math.max(a.length, b.length); i++) { var aPart = (i < a.length) ? a[i] : null; var bPart = (i < b.length) ? b[i] : null; diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 50d7c7799..3bde4911b 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -84,14 +84,11 @@ abstract class VersionConstraint { case '<=': return VersionRange(max: version, includeMax: true); case '<': - return VersionRange( - max: version, - includeMax: false, - alwaysIncludeMaxPreRelease: true); + return VersionRange(max: version, alwaysIncludeMaxPreRelease: true); case '>=': return VersionRange(min: version, includeMin: true); case '>': - return VersionRange(min: version, includeMin: false); + return VersionRange(min: version); } throw UnsupportedError(op!); } diff --git a/pkgs/pub_semver/lib/src/version_range.dart b/pkgs/pub_semver/lib/src/version_range.dart index 9431b09bb..6f2ed54b0 100644 --- a/pkgs/pub_semver/lib/src/version_range.dart +++ b/pkgs/pub_semver/lib/src/version_range.dart @@ -85,7 +85,7 @@ class VersionRange implements Comparable, VersionConstraint { VersionRange._(this.min, this.max, this.includeMin, this.includeMax); @override - bool operator ==(other) { + bool operator ==(Object other) { if (other is! VersionRange) return false; return min == other.min && @@ -294,7 +294,6 @@ class VersionRange implements Comparable, VersionConstraint { return VersionRange( min: min, max: max, - includeMin: false, includeMax: includeMax, alwaysIncludeMaxPreRelease: true); } @@ -305,7 +304,6 @@ class VersionRange implements Comparable, VersionConstraint { min: min, max: max, includeMin: includeMin, - includeMax: false, alwaysIncludeMaxPreRelease: true); } @@ -314,12 +312,10 @@ class VersionRange implements Comparable, VersionConstraint { min: min, max: other, includeMin: includeMin, - includeMax: false, alwaysIncludeMaxPreRelease: true), VersionRange( min: other, max: max, - includeMin: false, includeMax: includeMax, alwaysIncludeMaxPreRelease: true) ]); diff --git a/pkgs/pub_semver/lib/src/version_union.dart b/pkgs/pub_semver/lib/src/version_union.dart index 69ae03413..844d3b8ef 100644 --- a/pkgs/pub_semver/lib/src/version_union.dart +++ b/pkgs/pub_semver/lib/src/version_union.dart @@ -35,8 +35,8 @@ class VersionUnion implements VersionConstraint { /// /// It's up to the caller to ensure that the invariants described in [ranges] /// are maintained. They are not verified by this constructor. To - /// automatically ensure that they're maintained, use [new - /// VersionConstraint.unionOf] instead. + /// automatically ensure that they're maintained, use + /// [VersionConstraint.unionOf] instead. VersionUnion.fromRanges(this.ranges); @override diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 623606faf..bac877573 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,17 +1,17 @@ name: pub_semver -version: 2.1.2 +version: 2.1.3-dev description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. repository: https://github.com/dart-lang/pub_semver environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.17.0 <3.0.0' dependencies: collection: ^1.15.0 meta: ^1.3.0 dev_dependencies: - lints: ^1.0.0 + lints: ^2.0.0 test: ^1.16.0 diff --git a/pkgs/pub_semver/test/utils.dart b/pkgs/pub_semver/test/utils.dart index 66f103eda..bd7aa8f8f 100644 --- a/pkgs/pub_semver/test/utils.dart +++ b/pkgs/pub_semver/test/utils.dart @@ -34,7 +34,7 @@ class _VersionConstraintMatcher implements Matcher { _VersionConstraintMatcher(this._expected, this._allow); @override - bool matches(item, Map matchState) => + bool matches(dynamic item, Map matchState) => (item is VersionConstraint) && _expected.every((version) => item.allows(version) == _allow); @@ -46,8 +46,8 @@ class _VersionConstraintMatcher implements Matcher { } @override - Description describeMismatch( - item, Description mismatchDescription, Map matchState, bool verbose) { + Description describeMismatch(dynamic item, Description mismatchDescription, + Map matchState, bool verbose) { if (item is! VersionConstraint) { mismatchDescription.add('was not a VersionConstraint'); return mismatchDescription; diff --git a/pkgs/pub_semver/test/version_range_test.dart b/pkgs/pub_semver/test/version_range_test.dart index 6e27c3a6f..5978df0c7 100644 --- a/pkgs/pub_semver/test/version_range_test.dart +++ b/pkgs/pub_semver/test/version_range_test.dart @@ -961,12 +961,11 @@ void main() { test('includeMin comes before !includeMin', () { _expectComparesSmaller( VersionRange(min: v003, max: v080, includeMin: true), - VersionRange(min: v003, max: v080, includeMin: false)); + VersionRange(min: v003, max: v080)); }); test('includeMax comes after !includeMax', () { - _expectComparesSmaller( - VersionRange(min: v003, max: v080, includeMax: false), + _expectComparesSmaller(VersionRange(min: v003, max: v080), VersionRange(min: v003, max: v080, includeMax: true)); }); diff --git a/pkgs/pub_semver/test/version_test.dart b/pkgs/pub_semver/test/version_test.dart index 2979706b5..d7f1197c8 100644 --- a/pkgs/pub_semver/test/version_test.dart +++ b/pkgs/pub_semver/test/version_test.dart @@ -408,4 +408,4 @@ void main() { } Version _primary(List input) => - Version.primary(input.map((e) => Version.parse(e)).toList()); + Version.primary(input.map(Version.parse).toList()); From 279e48bdaa227646bb72e6fd982d50e217e59496 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 9 Nov 2022 15:47:54 -0800 Subject: [PATCH 487/657] blast_repo fixes (dart-lang/pool#58) Dependabot GitHub Action --- pkgs/pool/.github/dependabot.yml | 9 +++++++++ pkgs/pool/.github/workflows/ci.yml | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 pkgs/pool/.github/dependabot.yml diff --git a/pkgs/pool/.github/dependabot.yml b/pkgs/pool/.github/dependabot.yml new file mode 100644 index 000000000..1603cdd9e --- /dev/null +++ b/pkgs/pool/.github/dependabot.yml @@ -0,0 +1,9 @@ +# Dependabot configuration file. +# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates +version: 2 + +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 76d5352da..2a8bacf90 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [2.15.0, dev] steps: - - uses: actions/checkout@v2 - - uses: dart-lang/setup-dart@v1.0 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install From 9c7bb2019aff54ae452b2da8c5b809e4faf4cc51 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 11 Nov 2022 16:18:49 -0800 Subject: [PATCH 488/657] rev to 2.1.3 in preparation for release (dart-lang/pub_semver#75) * rev to 2.1.3 in preparation for release * Update CHANGELOG.md Co-authored-by: Kevin Moore Co-authored-by: Kevin Moore --- pkgs/pub_semver/CHANGELOG.md | 5 ++++- pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index e23ce1030..8c394e346 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,5 +1,8 @@ -# 2.1.3-dev +# 2.1.3 +- Add type parameters to the signatures of the `Version.preRelease` and + `Version.build` fields (`List` ==> `List`). + [#74](https://github.com/dart-lang/pub_semver/pull/74). - Require Dart 2.17. # 2.1.2 diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index bac877573..e7906a70b 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.1.3-dev +version: 2.1.3 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. From 8c91bc23a9602502e8756dfd83bb2c25c3fb7baa Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 15 Nov 2022 12:29:53 -0800 Subject: [PATCH 489/657] blast_repo fixes (dart-lang/package_config#127) Dependabot GitHub Action --- pkgs/package_config/.github/dependabot.yml | 7 +++---- pkgs/package_config/.github/workflows/test-package.yml | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pkgs/package_config/.github/dependabot.yml b/pkgs/package_config/.github/dependabot.yml index 430a85e7d..b2f1dec5a 100644 --- a/pkgs/package_config/.github/dependabot.yml +++ b/pkgs/package_config/.github/dependabot.yml @@ -4,8 +4,7 @@ version: 2 updates: -- package-ecosystem: "github-actions" - directory: "/" +- package-ecosystem: github-actions + directory: / schedule: - # Check for updates to GitHub Actions every weekday - interval: "daily" + interval: monthly diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 3db1d6c24..6b28e8555 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@v3 - - uses: dart-lang/setup-dart@v1 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [2.12.0, dev] steps: - - uses: actions/checkout@v3 - - uses: dart-lang/setup-dart@v1 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} - id: install From ca63b528422112514abc5c124b9c436f4ccb7576 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 09:33:39 -0800 Subject: [PATCH 490/657] Bump actions/checkout from 3.1.0 to 3.2.0 (dart-lang/package_config#128) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 6b28e8555..9c89e08ce 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.12.0, dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From ded49cfc531047109f3325174336bb4fd1006ead Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 10:12:07 -0800 Subject: [PATCH 491/657] Bump actions/checkout from 3.1.0 to 3.2.0 (dart-lang/source_span#89) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index bc4359926..cc5abcf3c 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From 03161571970cb7cead716f752c1f1cfa02dfb57a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 10:12:10 -0800 Subject: [PATCH 492/657] Bump actions/checkout from 3.1.0 to 3.2.0 (dart-lang/source_maps#70) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index d257b9f9c..265a4f31b 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From e6420799abadd1bc3d9a6638480aca4fd09adf7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 10:12:16 -0800 Subject: [PATCH 493/657] Bump actions/checkout from 3.1.0 to 3.2.0 (dart-lang/pub_semver#76) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 5c5b39d11..70142f9e5 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.17.0, dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From 02fdb7c3ae34ebf33d27a9040fee2bef90c83930 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Jan 2023 13:04:30 -0800 Subject: [PATCH 494/657] Bump actions/checkout from 3.1.0 to 3.2.0 (dart-lang/pool#59) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...755da8c3cf115ac066823e79a1e1788f8940201b) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 2a8bacf90..90a25eba8 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.15.0, dev] steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From 5266f39df95e54f623cd5bc10d068a6a67222c68 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 9 Jan 2023 15:02:49 -0800 Subject: [PATCH 495/657] Migrate from no-implicit-casts to strict-casts (dart-lang/pool#60) --- pkgs/pool/analysis_options.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index 4fa4b8d13..055ac1087 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -1,5 +1,5 @@ include: package:lints/recommended.yaml analyzer: - strong-mode: - implicit-casts: false + language: + strict-casts: true From 681f007bdc748d94b1730624659d3d5725d3ec3b Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 30 Jan 2023 09:23:49 -0800 Subject: [PATCH 496/657] Support latest pkg:build_web_compilers, lints. Update min SDK (dart-lang/package_config#129) --- pkgs/package_config/.github/workflows/test-package.yml | 2 +- pkgs/package_config/CHANGELOG.md | 4 ++++ pkgs/package_config/lib/src/package_config_impl.dart | 2 +- pkgs/package_config/lib/src/package_config_json.dart | 4 ++-- pkgs/package_config/lib/src/packages_file.dart | 2 +- pkgs/package_config/lib/src/util.dart | 4 ++-- pkgs/package_config/pubspec.yaml | 8 ++++---- pkgs/package_config/test/parse_test.dart | 2 +- 8 files changed, 16 insertions(+), 12 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 9c89e08ce..b28046588 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.12.0, dev] + sdk: [2.18.0, dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index b6e91bbd3..62ef87d6e 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.1-dev + +- Require Dart 2.18 + ## 2.1.0 - Adds `minVersion` to `findPackageConfig` and `findPackageConfigVersion` diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index 4c8f23443..f832d6adf 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -244,7 +244,7 @@ class SimplePackage implements Package { if (!root.hasScheme) { fatalError = true; } else if (!root.path.endsWith('/')) { - root = root.replace(path: root.path + '/'); + root = root.replace(path: '${root.path}/'); } } if (packageUriRoot == null) { diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index fe185a2ea..bd22db4ec 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -149,11 +149,11 @@ PackageConfig parsePackageConfigJson( var parsedRootUri = Uri.parse(rootUri!); var relativeRoot = !hasAbsolutePath(parsedRootUri); var root = baseLocation.resolveUri(parsedRootUri); - if (!root.path.endsWith('/')) root = root.replace(path: root.path + '/'); + if (!root.path.endsWith('/')) root = root.replace(path: '${root.path}/'); var packageRoot = root; if (packageUri != null) packageRoot = root.resolve(packageUri!); if (!packageRoot.path.endsWith('/')) { - packageRoot = packageRoot.replace(path: packageRoot.path + '/'); + packageRoot = packageRoot.replace(path: '${packageRoot.path}/'); } LanguageVersion? version; diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index 244663326..3fd7db9b5 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -192,7 +192,7 @@ void write(StringSink output, PackageConfig config, uri = relativizeUri(uri, baseUri)!; } if (!uri.path.endsWith('/')) { - uri = uri.replace(path: uri.path + '/'); + uri = uri.replace(path: '${uri.path}/'); } output.write(uri); output.writeln(); diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 61488ac41..3bf1bece3 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -89,7 +89,7 @@ String checkValidPackageUri(Uri packageUri, String name) { } assert(badIndex < packageName.length); var badCharCode = packageName.codeUnitAt(badIndex); - var badChar = 'U+' + badCharCode.toRadixString(16).padLeft(4, '0'); + var badChar = 'U+${badCharCode.toRadixString(16).padLeft(4, '0')}'; if (badCharCode >= 0x20 && badCharCode <= 0x7e) { // Printable character. badChar = "'${packageName[badIndex]}' ($badChar)"; @@ -140,7 +140,7 @@ int firstNonWhitespaceChar(List bytes) { /// Appends a trailing `/` if the path doesn't end with one. String trailingSlash(String path) { if (path.isEmpty || path.endsWith('/')) return path; - return path + '/'; + return '$path/'; } /// Whether a URI should not be considered relative to the base URI. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 56e30b5df..08255ffa9 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,10 +1,10 @@ name: package_config -version: 2.1.0 +version: 2.1.1-dev description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/package_config environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.18.0 <3.0.0' dependencies: path: ^1.8.0 @@ -12,6 +12,6 @@ dependencies: dev_dependencies: build_runner: ^2.0.0 build_test: ^2.1.2 - build_web_compilers: ^3.0.0 - lints: ^1.0.0 + build_web_compilers: '>=3.0.0 <5.0.0' + lints: ^2.0.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 174a099e0..94269e20f 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -56,7 +56,7 @@ void main() { () => packages.parse(utf8.encode(content), baseFile, throwError), throwsA(TypeMatcher())); }); - test(name + ', handle error', () { + test('$name, handle error', () { var hadError = false; packages.parse(utf8.encode(content), baseFile, (error) { hadError = true; From b4f8e178edc247e271441c291efd9339f8b9eeb8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 21:55:11 -0800 Subject: [PATCH 497/657] Bump dart-lang/setup-dart from 1.3 to 1.4 (dart-lang/pool#63) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/6a218f2413a3e78e9087f638a238f6b40893203d...a57a6c04cf7d4840e88432aad6281d1e125f0d46) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 90a25eba8..1bc0f7caa 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.15.0, dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install From d62677e559dded6170afaed6cda9d47e6871f7ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Jan 2023 23:35:01 -0800 Subject: [PATCH 498/657] Bump actions/checkout from 3.2.0 to 3.3.0 (dart-lang/pool#62) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 1bc0f7caa..b387db33f 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.15.0, dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From 8e570cac2c4575ddce001ba6d0eeb3452c2e8a92 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 08:07:47 -0800 Subject: [PATCH 499/657] Bump dart-lang/setup-dart from 1.3 to 1.4 (dart-lang/pub_semver#79) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/6a218f2413a3e78e9087f638a238f6b40893203d...a57a6c04cf7d4840e88432aad6281d1e125f0d46) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 70142f9e5..e0871c5aa 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.17.0, dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install From 1fd7a318bb0279afbf247048e0de9a04f9feaa76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 08:33:54 -0800 Subject: [PATCH 500/657] Bump actions/checkout from 3.2.0 to 3.3.0 (dart-lang/pub_semver#78) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index e0871c5aa..5a3d9cfe1 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.17.0, dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From 9fa02d2ccd2698ceede5dd67ca1bf06eb223d7aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 09:04:54 -0800 Subject: [PATCH 501/657] Bump dart-lang/setup-dart from 1.3 to 1.4 (dart-lang/source_maps#71) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/6a218f2413a3e78e9087f638a238f6b40893203d...a57a6c04cf7d4840e88432aad6281d1e125f0d46) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 265a4f31b..54fc2c89e 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install From b32781391362dffd3b579430eff85ab91695cea6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 09:06:20 -0800 Subject: [PATCH 502/657] Bump dart-lang/setup-dart from 1.3 to 1.4 (dart-lang/source_span#91) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/6a218f2413a3e78e9087f638a238f6b40893203d...a57a6c04cf7d4840e88432aad6281d1e125f0d46) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index cc5abcf3c..6e0c5d097 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install From 8a9307efbe99d311e94e446ddd69dff16c7667e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 09:13:43 -0800 Subject: [PATCH 503/657] Bump actions/checkout from 3.2.0 to 3.3.0 (dart-lang/source_span#90) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 6e0c5d097..5a03db3b3 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From 8ed4c0f54d744366fa322c9ba4238cdc209e4093 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 09:14:18 -0800 Subject: [PATCH 504/657] Bump actions/checkout from 3.2.0 to 3.3.0 (dart-lang/source_maps#72) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 54fc2c89e..729b3139a 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From f4e80817eb0b9ae444833887a510ca1c6eee39f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 12:37:33 -0800 Subject: [PATCH 505/657] Bump actions/checkout from 3.2.0 to 3.3.0 (dart-lang/package_config#131) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/755da8c3cf115ac066823e79a1e1788f8940201b...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index b28046588..0123c53bb 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: ${{ matrix.sdk }} From 6adef6143472173f725497c02cc895a44ad31041 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 12:42:17 -0800 Subject: [PATCH 506/657] Bump dart-lang/setup-dart from 1.3 to 1.4 (dart-lang/package_config#130) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/6a218f2413a3e78e9087f638a238f6b40893203d...a57a6c04cf7d4840e88432aad6281d1e125f0d46) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 0123c53bb..2fdd91f4e 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} - id: install From 5499677013783d5499f8c73faebf7a4cf76ec230 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Fri, 3 Feb 2023 12:15:20 -0800 Subject: [PATCH 507/657] add an api usage example (dart-lang/source_span#92) * add an api usage example * Apply suggestions from code review Co-authored-by: Kevin Moore * make method private --------- Co-authored-by: Kevin Moore --- pkgs/source_span/CHANGELOG.md | 3 +- pkgs/source_span/README.md | 2 ++ pkgs/source_span/example/main.dart | 51 ++++++++++++++++++++++++++++++ pkgs/source_span/pubspec.yaml | 3 +- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 pkgs/source_span/example/main.dart diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 05c7e71d5..fa1735aa2 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,6 +1,7 @@ # 1.9.2-dev * Require Dart 2.18 +* Add an API usage example in `example/`. # 1.9.1 @@ -201,7 +202,7 @@ # 1.0.0 This package was extracted from the -[`source_maps`](http://pub.dartlang.org/packages/source_maps) package, but the +[`source_maps`](https://pub.dev/packages/source_maps) package, but the API has many differences. Among them: * `Span` has been renamed to `SourceSpan` and `Location` has been renamed to diff --git a/pkgs/source_span/README.md b/pkgs/source_span/README.md index be91debd0..0faf0cbc4 100644 --- a/pkgs/source_span/README.md +++ b/pkgs/source_span/README.md @@ -2,6 +2,8 @@ [![pub package](https://img.shields.io/pub/v/source_span.svg)](https://pub.dev/packages/source_span) [![package publisher](https://img.shields.io/pub/publisher/source_span.svg)](https://pub.dev/packages/source_span/publisher) +## About this package + `source_span` is a library for tracking locations in source code. It's designed to provide a standard representation for source code locations and spans so that disparate packages can easily pass them among one another, and to make it easy diff --git a/pkgs/source_span/example/main.dart b/pkgs/source_span/example/main.dart new file mode 100644 index 000000000..e29676590 --- /dev/null +++ b/pkgs/source_span/example/main.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2023, 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 'dart:io'; + +import 'package:source_span/source_span.dart'; + +void main(List args) { + final file = File('README.md'); + final contents = file.readAsStringSync(); + + final sourceFile = SourceFile.fromString(contents, url: file.uri); + final spans = _parseFile(contents, sourceFile); + + for (var span in spans.take(30)) { + print('[${span.start.line + 1}:${span.start.column + 1}] ${span.text}'); + } +} + +Iterable _parseFile(String contents, SourceFile sourceFile) sync* { + var wordStart = 0; + var inWhiteSpace = true; + + for (var i = 0; i < contents.length; i++) { + final codeUnit = contents.codeUnitAt(i); + + if (codeUnit == _eol || codeUnit == _space) { + if (!inWhiteSpace) { + inWhiteSpace = true; + + // emit a word + yield sourceFile.span(wordStart, i); + } + } else { + if (inWhiteSpace) { + inWhiteSpace = false; + + wordStart = i; + } + } + } + + if (!inWhiteSpace) { + // emit a word + yield sourceFile.span(wordStart, contents.length); + } +} + +const int _eol = 10; +const int _space = 32; diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 4531a74e3..d00730c39 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,6 +1,7 @@ name: source_span version: 1.9.2-dev -description: A library for identifying source spans and locations. +description: >- + Provides a standard representation for source code locations and spans. repository: https://github.com/dart-lang/source_span environment: From 82382c6ad371a529e9fe9a17f31754e29abbd220 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 7 Feb 2023 13:59:28 -0800 Subject: [PATCH 508/657] tighten up analysis; add types at the api boundaries (dart-lang/source_maps#73) --- pkgs/source_maps/CHANGELOG.md | 4 ++ pkgs/source_maps/README.md | 15 ++---- pkgs/source_maps/analysis_options.yaml | 6 +-- pkgs/source_maps/lib/builder.dart | 2 +- pkgs/source_maps/lib/parser.dart | 48 ++++++++++--------- pkgs/source_maps/lib/printer.dart | 10 ++-- pkgs/source_maps/lib/refactor.dart | 2 +- pkgs/source_maps/lib/source_maps.dart | 2 +- pkgs/source_maps/lib/src/source_map_span.dart | 4 +- pkgs/source_maps/lib/src/utils.dart | 2 +- pkgs/source_maps/lib/src/vlq.dart | 2 +- pkgs/source_maps/pubspec.yaml | 4 +- pkgs/source_maps/test/parser_test.dart | 2 +- pkgs/source_maps/test/refactor_test.dart | 4 +- pkgs/source_maps/test/utils_test.dart | 8 ++-- pkgs/source_maps/test/vlq_test.dart | 3 +- 16 files changed, 58 insertions(+), 60 deletions(-) diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 366501968..e29a375da 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.10.12 + +* Add additional types at API boundaries. + # 0.10.11 * Populate the pubspec `repository` field. diff --git a/pkgs/source_maps/README.md b/pkgs/source_maps/README.md index e81f2782c..ad8fd258a 100644 --- a/pkgs/source_maps/README.md +++ b/pkgs/source_maps/README.md @@ -2,8 +2,11 @@ [![pub package](https://img.shields.io/pub/v/source_maps.svg)](https://pub.dev/packages/source_maps) [![package publisher](https://img.shields.io/pub/publisher/source_maps.svg)](https://pub.dev/packages/source_maps/publisher) -This project implements a Dart pub package to work with source maps. The -implementation is based on the [source map version 3 spec][spec] which was +This project implements a Dart pub package to work with source maps. + +## Docs and usage + +The implementation is based on the [source map version 3 spec][spec] which was originated from the [Closure Compiler][closure] and has been implemented in Chrome and Firefox. @@ -18,13 +21,5 @@ In this package we provide: * A parser that reads the source map format and provides APIs to read the mapping information. -Some upcoming features we are planning to add to this package are: - - * A printer that lets you generate code, but record source map information in - the process. - * A tool that can compose source maps together. This would be useful for - instance, if you have 2 tools that produce source maps and you call one with - the result of the other. - [closure]: https://github.com/google/closure-compiler/wiki/Source-Maps [spec]: https://docs.google.com/a/google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit diff --git a/pkgs/source_maps/analysis_options.yaml b/pkgs/source_maps/analysis_options.yaml index c09985a51..d978f811c 100644 --- a/pkgs/source_maps/analysis_options.yaml +++ b/pkgs/source_maps/analysis_options.yaml @@ -1,5 +1 @@ -include: package:lints/recommended.yaml - -linter: - rules: - - comment_references +include: package:dart_flutter_team_lints/analysis_options.yaml diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart index 5c56ca462..54ba7433f 100644 --- a/pkgs/source_maps/lib/builder.dart +++ b/pkgs/source_maps/lib/builder.dart @@ -45,7 +45,7 @@ class SourceMapBuilder { } /// Encodes all mappings added to this builder as a json map. - Map build(String fileUrl) { + Map build(String fileUrl) { return SingleMapping.fromEntries(_entries, fileUrl).toJson(); } diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index e3c7179f9..701a63f1c 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -25,7 +25,7 @@ import 'src/vlq.dart'; // `)]}'` begins the string representation of the map. Mapping parse(String jsonMap, {Map? otherMaps, /*String|Uri*/ Object? mapUrl}) => - parseJson(jsonDecode(jsonMap), otherMaps: otherMaps, mapUrl: mapUrl); + parseJson(jsonDecode(jsonMap) as Map, otherMaps: otherMaps, mapUrl: mapUrl); /// Parses a source map or source map bundle directly from a json string. /// @@ -50,7 +50,7 @@ Mapping parseJsonExtended(/*List|Map*/ Object? json, return parseJson(json as Map); } -/// Parses a source map +/// Parses a source map. /// /// [mapUrl], which may be either a [String] or a [Uri], indicates the URL of /// the source map file itself. If it's passed, any URLs in the source @@ -69,10 +69,10 @@ Mapping parseJson(Map map, throw FormatException('map containing "sections" ' 'cannot contain "mappings", "sources", or "names".'); } - return MultiSectionMapping.fromJson(map['sections'], otherMaps, + return MultiSectionMapping.fromJson(map['sections'] as List, otherMaps, mapUrl: mapUrl); } - return SingleMapping.fromJson(map, mapUrl: mapUrl); + return SingleMapping.fromJson(map.cast(), mapUrl: mapUrl); } /// A mapping parsed out of a source map. @@ -108,21 +108,21 @@ class MultiSectionMapping extends Mapping { /// Creates a section mapping from json. MultiSectionMapping.fromJson(List sections, Map? otherMaps, {/*String|Uri*/ Object? mapUrl}) { - for (var section in sections) { - var offset = section['offset']; + for (var section in sections.cast()) { + var offset = section['offset'] as Map?; if (offset == null) throw FormatException('section missing offset'); - var line = section['offset']['line']; + var line = offset['line'] as int?; if (line == null) throw FormatException('offset missing line'); - var column = section['offset']['column']; + var column = offset['column'] as int?; if (column == null) throw FormatException('offset missing column'); _lineStart.add(line); _columnStart.add(column); - var url = section['url']; - var map = section['map']; + var url = section['url'] as String?; + var map = section['map'] as Map?; if (url != null && map != null) { throw FormatException("section can't use both url and map entries"); @@ -189,7 +189,7 @@ class MappingBundle extends Mapping { MappingBundle.fromJson(List json, {/*String|Uri*/ Object? mapUrl}) { for (var map in json) { - addMapping(parseJson(map, mapUrl: mapUrl) as SingleMapping); + addMapping(parseJson(map as Map, mapUrl: mapUrl) as SingleMapping); } } @@ -342,18 +342,18 @@ class SingleMapping extends Mapping { urls.keys.toList(), names.keys.toList(), lines); } - SingleMapping.fromJson(Map map, {mapUrl}) - : targetUrl = map['file'], - urls = List.from(map['sources']), - names = List.from(map['names'] ?? []), - files = List.filled(map['sources'].length, null), - sourceRoot = map['sourceRoot'], + SingleMapping.fromJson(Map map, {mapUrl}) + : targetUrl = map['file'] as String?, + urls = List.from(map['sources'] as List), + names = List.from((map['names'] as List?) ?? []), + files = List.filled((map['sources'] as List).length, null), + sourceRoot = map['sourceRoot'] as String?, lines = [], - _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : mapUrl, + _mapUrl = mapUrl is String ? Uri.parse(mapUrl) : (mapUrl as Uri?), extensions = {} { var sourcesContent = map['sourcesContent'] == null ? const [] - : List.from(map['sourcesContent']); + : List.from(map['sourcesContent'] as List); for (var i = 0; i < urls.length && i < sourcesContent.length; i++) { var source = sourcesContent[i]; if (source == null) continue; @@ -366,7 +366,7 @@ class SingleMapping extends Mapping { var srcLine = 0; var srcColumn = 0; var srcNameId = 0; - var tokenizer = _MappingTokenizer(map['mappings']); + var tokenizer = _MappingTokenizer(map['mappings'] as String); var entries = []; while (tokenizer.hasTokens) { @@ -432,7 +432,7 @@ class SingleMapping extends Mapping { /// /// If [includeSourceContents] is `true`, this includes the source file /// contents from [files] in the map if possible. - Map toJson({bool includeSourceContents = false}) { + Map toJson({bool includeSourceContents = false}) { var buff = StringBuffer(); var line = 0; var column = 0; @@ -471,12 +471,12 @@ class SingleMapping extends Mapping { } } - var result = { + var result = { 'version': 3, 'sourceRoot': sourceRoot ?? '', 'sources': urls, 'names': names, - 'mappings': buff.toString() + 'mappings': buff.toString(), }; if (targetUrl != null) result['file'] = targetUrl!; @@ -690,6 +690,8 @@ class _MappingTokenizer implements Iterator { buff.write(''); try { buff.write(current); + // TODO: Determine whether this try / catch can be removed. + // ignore: avoid_catching_errors } on RangeError catch (_) {} buff.write(''); for (var i = index + 1; i < _internal.length; i++) { diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart index 7d128f7ec..17733cdd3 100644 --- a/pkgs/source_maps/lib/printer.dart +++ b/pkgs/source_maps/lib/printer.dart @@ -36,7 +36,7 @@ class Printer { /// adds a source map location on each new line, projecting that every new /// line in the target file (printed here) corresponds to a new line in the /// source file. - void add(String str, {projectMarks = false}) { + void add(String str, {bool projectMarks = false}) { var chars = str.runes.toList(); var length = chars.length; for (var i = 0; i < length; i++) { @@ -85,7 +85,7 @@ class Printer { /// [SourceSpan]. When the mark is a [SourceMapSpan] with `isIdentifier` set, /// this also records the name of the identifier in the source map /// information. - void mark(mark) { + void mark(Object mark) { late final SourceLocation loc; String? identifier; if (mark is SourceLocation) { @@ -105,13 +105,13 @@ class Printer { /// including [NestedPrinter]s, and it let's you automatically indent text. /// /// This class is especially useful when doing code generation, where different -/// peices of the code are generated independently on separate printers, and are +/// pieces of the code are generated independently on separate printers, and are /// finally put together in the end. class NestedPrinter implements NestedItem { /// Items recoded by this printer, which can be [String] literals, /// [NestedItem]s, and source map information like [SourceLocation] and /// [SourceSpan]. - final _items = []; + final List _items = []; /// Internal buffer to merge consecutive strings added to this printer. StringBuffer? _buff; @@ -149,7 +149,7 @@ class NestedPrinter implements NestedItem { /// Indicate [isOriginal] when [object] is copied directly from the user code. /// Setting [isOriginal] will make this printer propagate source map locations /// on every line-break. - void add(object, + void add(Object object, {SourceLocation? location, SourceSpan? span, bool isOriginal = false}) { if (object is! String || location != null || span != null || isOriginal) { _flush(); diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart index 97bd2a708..98e0c9345 100644 --- a/pkgs/source_maps/lib/refactor.dart +++ b/pkgs/source_maps/lib/refactor.dart @@ -30,7 +30,7 @@ class TextEditTransaction { /// Edit the original text, replacing text on the range [begin] and [end] /// with the [replacement]. [replacement] can be either a string or a /// [NestedPrinter]. - void edit(int begin, int end, replacement) { + void edit(int begin, int end, Object replacement) { _edits.add(_TextEdit(begin, end, replacement)); } diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart index 0c6cc084c..58f805a3a 100644 --- a/pkgs/source_maps/lib/source_maps.dart +++ b/pkgs/source_maps/lib/source_maps.dart @@ -28,8 +28,8 @@ library source_maps; import 'package:source_span/source_span.dart'; -import 'parser.dart'; import 'builder.dart'; +import 'parser.dart'; export 'builder.dart'; export 'parser.dart'; diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index 65574ca5e..2840db4e9 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -61,13 +61,13 @@ class SourceMapFileSpan implements SourceMapSpan, FileSpan { @override int compareTo(SourceSpan other) => _inner.compareTo(other); @override - String highlight({color}) => _inner.highlight(color: color); + String highlight({Object? color}) => _inner.highlight(color: color); @override SourceSpan union(SourceSpan other) => _inner.union(other); @override FileSpan expand(FileSpan other) => _inner.expand(other); @override - String message(String message, {color}) => + String message(String message, {Object? color}) => _inner.message(message, color: color); @override String toString() => diff --git a/pkgs/source_maps/lib/src/utils.dart b/pkgs/source_maps/lib/src/utils.dart index eb238342d..f70531e95 100644 --- a/pkgs/source_maps/lib/src/utils.dart +++ b/pkgs/source_maps/lib/src/utils.dart @@ -10,7 +10,7 @@ library source_maps.utils; /// and all items after `n` match too. The result is -1 when there are no /// items, 0 when all items match, and list.length when none does. // TODO(sigmund): remove this function after dartbug.com/5624 is fixed. -int binarySearch(List list, bool Function(dynamic) matches) { +int binarySearch(List list, bool Function(T) matches) { if (list.isEmpty) return -1; if (matches(list.first)) return 0; if (!matches(list.last)) return list.length; diff --git a/pkgs/source_maps/lib/src/vlq.dart b/pkgs/source_maps/lib/src/vlq.dart index 6c41b6e2c..61b476839 100644 --- a/pkgs/source_maps/lib/src/vlq.dart +++ b/pkgs/source_maps/lib/src/vlq.dart @@ -76,7 +76,7 @@ int decodeVlq(Iterator chars) { } stop = (digit & vlqContinuationBit) == 0; digit &= vlqBaseMask; - result += (digit << shift); + result += digit << shift; shift += vlqBaseShift; } diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index eaaa46cd8..f716ef6d0 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.11 +version: 0.10.12 description: A library to programmatically manipulate source map files. repository: https://github.com/dart-lang/source_maps @@ -10,6 +10,6 @@ dependencies: source_span: ^1.8.0 dev_dependencies: - lints: ^2.0.0 + dart_flutter_team_lints: ^0.1.0 term_glyph: ^1.2.0 test: ^1.16.0 diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index 7c7b142bb..cf320b6ef 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -373,7 +373,7 @@ void main() { var mapping = parseJson(map) as SingleMapping; expect(mapping.toJson(), equals(map)); expect(mapping.extensions['x_foo'], equals('a')); - expect(mapping.extensions['x_bar'].first, equals(3)); + expect((mapping.extensions['x_bar'] as List).first, equals(3)); }); group('source files', () { diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 9a403a1b3..0389631dd 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -4,11 +4,11 @@ library polymer.test.refactor_test; -import 'package:test/test.dart'; -import 'package:source_maps/refactor.dart'; import 'package:source_maps/parser.dart' show parse, Mapping; +import 'package:source_maps/refactor.dart'; import 'package:source_span/source_span.dart'; import 'package:term_glyph/term_glyph.dart' as term_glyph; +import 'package:test/test.dart'; void main() { setUpAll(() { diff --git a/pkgs/source_maps/test/utils_test.dart b/pkgs/source_maps/test/utils_test.dart index 3064d6b22..4abdce298 100644 --- a/pkgs/source_maps/test/utils_test.dart +++ b/pkgs/source_maps/test/utils_test.dart @@ -5,8 +5,8 @@ /// Tests for the binary search utility algorithm. library test.utils_test; -import 'package:test/test.dart'; import 'package:source_maps/src/utils.dart'; +import 'package:test/test.dart'; void main() { group('binary search', () { @@ -31,7 +31,7 @@ void main() { test('compare with linear search', () { for (var size = 0; size < 100; size++) { - var list = []; + var list = []; for (var i = 0; i < size; i++) { list.add(i); } @@ -44,8 +44,8 @@ void main() { }); } -int _linearSearch(list, predicate) { - if (list.length == 0) return -1; +int _linearSearch(List list, bool Function(T) predicate) { + if (list.isEmpty) return -1; for (var i = 0; i < list.length; i++) { if (predicate(list[i])) return i; } diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index 5a4f02a73..94193007a 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -5,8 +5,9 @@ library test.vlq_test; import 'dart:math'; -import 'package:test/test.dart'; + import 'package:source_maps/src/vlq.dart'; +import 'package:test/test.dart'; void main() { test('encode and decode - simple values', () { From 10e2a107dc320a25301f2108109a57b11819546d Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Sun, 12 Feb 2023 17:07:35 -0800 Subject: [PATCH 509/657] Fix new type error, use dart_flutter_team_lints (dart-lang/pub_semver#80) --- pkgs/pub_semver/analysis_options.yaml | 18 +----------------- pkgs/pub_semver/lib/src/version.dart | 2 +- pkgs/pub_semver/pubspec.yaml | 4 ++-- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index 56d7c9061..210af85b9 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -1,5 +1,5 @@ # https://dart.dev/guides/language/analysis-options -include: package:lints/recommended.yaml +include: package:dart_flutter_team_lints/analysis_options.yaml analyzer: language: @@ -9,11 +9,8 @@ analyzer: linter: rules: - - always_declare_return_types - avoid_bool_literals_in_conditional_expressions - - avoid_catching_errors - avoid_classes_with_only_static_members - - avoid_dynamic_calls - avoid_private_typedef_functions - avoid_redundant_argument_values - avoid_returning_null @@ -24,31 +21,18 @@ linter: - cancel_subscriptions - cascade_invocations - comment_references - - directives_ordering - join_return_with_assignment - - lines_longer_than_80_chars - literal_only_boolean_expressions - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString - - omit_local_variable_types - - only_throw_errors - package_api_docs - - prefer_asserts_in_initializer_lists - prefer_const_constructors - prefer_const_declarations - prefer_expression_function_bodies - prefer_relative_imports - - prefer_single_quotes - - sort_pub_dependencies - test_types_in_equals - - throw_in_finally - - type_annotate_public_apis - - unawaited_futures - unnecessary_await_in_return - - unnecessary_lambdas - - unnecessary_parenthesis - - unnecessary_statements - use_if_null_to_convert_nulls_to_bools - use_raw_strings - use_string_buffers diff --git a/pkgs/pub_semver/lib/src/version.dart b/pkgs/pub_semver/lib/src/version.dart index f9e536087..90f3d535f 100644 --- a/pkgs/pub_semver/lib/src/version.dart +++ b/pkgs/pub_semver/lib/src/version.dart @@ -12,7 +12,7 @@ import 'version_constraint.dart'; import 'version_range.dart'; /// The equality operator to use for comparing version components. -const _equality = IterableEquality(); +const _equality = IterableEquality(); /// A parsed semantic version number. @sealed diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index e7906a70b..990cf8eca 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.1.3 +version: 2.1.4-dev description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. @@ -13,5 +13,5 @@ dependencies: meta: ^1.3.0 dev_dependencies: - lints: ^2.0.0 + dart_flutter_team_lints: ^0.1.0 test: ^1.16.0 From 6c18c52be0c153b82831a6e9e2931ab103061b8d Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Sun, 12 Feb 2023 17:16:27 -0800 Subject: [PATCH 510/657] Update CHANGELOG.md (dart-lang/pub_semver#81) --- pkgs/pub_semver/CHANGELOG.md | 51 +++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 8c394e346..057895a90 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,31 +1,34 @@ -# 2.1.3 +## 2.1.4-dev + +## 2.1.3 - Add type parameters to the signatures of the `Version.preRelease` and `Version.build` fields (`List` ==> `List`). [#74](https://github.com/dart-lang/pub_semver/pull/74). - Require Dart 2.17. -# 2.1.2 +## 2.1.2 - Add markdown badges to the readme. -# 2.1.1 +## 2.1.1 - Fixed the version parsing pattern to only accept dots between version components. -# 2.1.0 +## 2.1.0 + - Added `Version.canonicalizedVersion` to help scrub leading zeros and highlight that `Version.toString()` preserves leading zeros. - Annotated `Version` with `@sealed` to discourage users from implementing the interface. -# 2.0.0 +## 2.0.0 - Stable null safety release. - `Version.primary` now throws `StateError` if the `versions` argument is empty. -# 1.4.4 +## 1.4.4 - Fix a bug of `VersionRange.union` where ranges bounded at infinity would get combined wrongly. @@ -35,16 +38,16 @@ - Update Dart SDK constraint to `>=2.0.0 <3.0.0`. - Update `package:collection` constraint to `^1.0.0`. -# 1.4.2 +## 1.4.2 * Set max SDK version to `<3.0.0`. -# 1.4.1 +## 1.4.1 * Fix a bug where there upper bound of a version range with a build identifier could accidentally be rewritten. -# 1.4.0 +## 1.4.0 * Add a `Version.firstPreRelease` getter that returns the first possible pre-release of a version. @@ -66,41 +69,41 @@ disables the replacement described above and allows users to create ranges that do include the pre-release versions of an exclusive max version. -# 1.3.7 +## 1.3.7 * Fix more bugs with `VersionRange.intersect()`, `VersionRange.difference()`, and `VersionRange.union()` involving version ranges with pre-release maximums. -# 1.3.6 +## 1.3.6 * Fix a bug where constraints that only allowed pre-release versions would be parsed as empty constraints. -# 1.3.5 +## 1.3.5 * Fix a bug where `VersionRange.intersect()` would return incorrect results for pre-release versions with the same base version number as release versions. -# 1.3.4 +## 1.3.4 * Fix a bug where `VersionRange.allowsAll()`, `VersionRange.allowsAny()`, and `VersionRange.difference()` would return incorrect results for pre-release versions with the same base version number as release versions. -# 1.3.3 +## 1.3.3 * Fix a bug where `VersionRange.difference()` with a union constraint that covered the entire range would crash. -# 1.3.2 +## 1.3.2 * Fix a checked-mode error in `VersionRange.difference()`. -# 1.3.1 +## 1.3.1 * Fix a new strong mode error. -# 1.3.0 +## 1.3.0 * Make the `VersionUnion` class public. This was previously used internally to implement `new VersionConstraint.unionOf()` and `VersionConstraint.union()`. @@ -112,21 +115,21 @@ * Make `VersionRange` implement `Comparable`. Ranges are ordered first by lower bound, then by upper bound. -# 1.2.4 +## 1.2.4 * Fix all remaining strong mode warnings. -# 1.2.3 +## 1.2.3 * Addressed three strong mode warnings. -# 1.2.2 +## 1.2.2 * Make the package analyze under strong mode and compile with the DDC (Dart Dev Compiler). Fix two issues with a private subclass of `VersionConstraint` having different types for overridden methods. -# 1.2.1 +## 1.2.1 * Allow version ranges like `>=1.2.3-dev.1 <1.2.3` to match pre-release versions of `1.2.3`. Previously, these didn't match, since the pre-release versions had @@ -134,7 +137,7 @@ added if they also have the same major, minor, and patch numbers as the min *and* the min is also a pre-release version. -# 1.2.0 +## 1.2.0 * Add a `VersionConstraint.union()` method and a `new VersionConstraint.unionOf()` constructor. These each return a constraint that @@ -148,7 +151,7 @@ * `Version` now implements `VersionRange`. -# 1.1.0 +## 1.1.0 * Add support for the `^` operator for compatible versions according to pub's notion of compatibility. `^1.2.3` is equivalent to `>=1.2.3 <2.0.0`; `^0.1.2` @@ -162,6 +165,6 @@ * Add a custom `VersionRange.hashCode` to make it properly hashable. -# 1.0.0 +## 1.0.0 * Initial release. From 6555abea194cc1cd10e8ccd52e5286d7278cd4e3 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 16 Feb 2023 17:31:33 -0800 Subject: [PATCH 511/657] configure publishing automation (dart-lang/source_maps#74) * configure publishing automation * update changelog --- pkgs/source_maps/.github/workflows/publish.yaml | 14 ++++++++++++++ pkgs/source_maps/CHANGELOG.md | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 pkgs/source_maps/.github/workflows/publish.yaml diff --git a/pkgs/source_maps/.github/workflows/publish.yaml b/pkgs/source_maps/.github/workflows/publish.yaml new file mode 100644 index 000000000..fcb7ccb89 --- /dev/null +++ b/pkgs/source_maps/.github/workflows/publish.yaml @@ -0,0 +1,14 @@ +# A CI configuration to auto-publish pub packages. + +name: Publish + +on: + pull_request: + branches: [ master ] + push: + tags: [ 'v[0-9]+.[0-9]+.[0-9]+*' ] + +jobs: + publish: + if: ${{ github.repository_owner == 'dart-lang' }} + uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index e29a375da..275d197da 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,8 +1,8 @@ -# 0.10.12 +## 0.10.12 * Add additional types at API boundaries. -# 0.10.11 +## 0.10.11 * Populate the pubspec `repository` field. * Update the source map documentation link in the readme. From 923f2fd1abaae9f651dca5752469f7725ef474f2 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 20 Feb 2023 09:30:38 -0800 Subject: [PATCH 512/657] blast_repo fixes (dart-lang/pool#64) auto-publish no-response --- pkgs/pool/.github/workflows/no-response.yml | 34 +++++++++++++++++++++ pkgs/pool/.github/workflows/publish.yaml | 14 +++++++++ 2 files changed, 48 insertions(+) create mode 100644 pkgs/pool/.github/workflows/no-response.yml create mode 100644 pkgs/pool/.github/workflows/publish.yaml diff --git a/pkgs/pool/.github/workflows/no-response.yml b/pkgs/pool/.github/workflows/no-response.yml new file mode 100644 index 000000000..ac3e456ec --- /dev/null +++ b/pkgs/pool/.github/workflows/no-response.yml @@ -0,0 +1,34 @@ +# A workflow to close issues where the author hasn't responded to a request for +# more information; see https://github.com/godofredoc/no-response for docs. + +name: No Response + +# Both `issue_comment` and `scheduled` event types are required. +on: + issue_comment: + types: [created] + schedule: + # Every day at 8am + - cron: '0 8 * * *' + +# All permissions not specified are set to 'none'. +permissions: + issues: write + +jobs: + noResponse: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'dart-lang' }} + steps: + - uses: godofredoc/no-response@0ce2dc0e63e1c7d2b87752ceed091f6d32c9df09 + with: + responseRequiredLabel: "needs-info" + responseRequiredColor: 4774bc + daysUntilClose: 14 + # Comment to post when closing an Issue for lack of response. + closeComment: > + Without additional information we're not able to resolve this issue, + so it will be closed at this time. You're still free to add more + info and respond to any questions above, though. We'll reopen the + issue if you do. Thanks for your contribution! + token: ${{ github.token }} diff --git a/pkgs/pool/.github/workflows/publish.yaml b/pkgs/pool/.github/workflows/publish.yaml new file mode 100644 index 000000000..fcb7ccb89 --- /dev/null +++ b/pkgs/pool/.github/workflows/publish.yaml @@ -0,0 +1,14 @@ +# A CI configuration to auto-publish pub packages. + +name: Publish + +on: + pull_request: + branches: [ master ] + push: + tags: [ 'v[0-9]+.[0-9]+.[0-9]+*' ] + +jobs: + publish: + if: ${{ github.repository_owner == 'dart-lang' }} + uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main From 1ef23dfd424b85581e0125ed216ea145acedfe6a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 20 Feb 2023 09:44:50 -0800 Subject: [PATCH 513/657] move to package:dart_flutter_team_lints, require Dart 2.19 (dart-lang/pool#65) --- pkgs/pool/.github/workflows/ci.yml | 2 +- pkgs/pool/CHANGELOG.md | 4 ++++ pkgs/pool/analysis_options.yaml | 2 +- pkgs/pool/pubspec.yaml | 6 +++--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index b387db33f..31dd71900 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.15.0, dev] + sdk: [2.19.0, dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 64b51cc97..8d16309f1 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.2-dev + +* Require Dart 2.19 + ## 1.5.1 * Switch to using `package:lints` for analysis. diff --git a/pkgs/pool/analysis_options.yaml b/pkgs/pool/analysis_options.yaml index 055ac1087..44cda4da2 100644 --- a/pkgs/pool/analysis_options.yaml +++ b/pkgs/pool/analysis_options.yaml @@ -1,4 +1,4 @@ -include: package:lints/recommended.yaml +include: package:dart_flutter_team_lints/analysis_options.yaml analyzer: language: diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index b32438885..fff7adbef 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,18 +1,18 @@ name: pool -version: 1.5.1 +version: 1.5.2-dev description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. repository: https://github.com/dart-lang/pool environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.19.0 <3.0.0" dependencies: async: ^2.5.0 stack_trace: ^1.10.0 dev_dependencies: + dart_flutter_team_lints: ^0.1.0 fake_async: ^1.2.0 - lints: ^1.0.0 test: ^1.16.0 From fc983289b7f6e8db245ac82b7f5ecddf22cedf73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Apr 2023 19:52:56 -0700 Subject: [PATCH 514/657] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (dart-lang/pool#67) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/a57a6c04cf7d4840e88432aad6281d1e125f0d46...d6a63dab3335f427404425de0fbfed4686d93c4f) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 31dd71900..0bf20516d 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.19.0, dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install From 2b105c61b6234d7914c3bca865ac3cf07a6d7ca2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:35:25 -0700 Subject: [PATCH 515/657] Bump actions/checkout from 3.3.0 to 3.5.0 (dart-lang/pool#66) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 0bf20516d..5dbe7c0bf 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From cb538c12ed484fd09ed6ae238c35303a6df3f17c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:38:56 -0700 Subject: [PATCH 516/657] Bump actions/checkout from 3.3.0 to 3.5.0 (dart-lang/source_maps#75) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 729b3139a..00edb862a 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From 1debd19e12803969fdb8c8b7b7e2580c8da21a1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:39:09 -0700 Subject: [PATCH 517/657] Bump actions/checkout from 3.3.0 to 3.5.0 (dart-lang/package_config#133) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 2fdd91f4e..8ca52ec84 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From d6d52d64da8619304c4fe8b7baee083e292d865a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:41:03 -0700 Subject: [PATCH 518/657] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (dart-lang/source_maps#76) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/a57a6c04cf7d4840e88432aad6281d1e125f0d46...d6a63dab3335f427404425de0fbfed4686d93c4f) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 00edb862a..bc89aa25e 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install From df5710bafce012c8b492f8a4d554d77e4feb944f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:54:23 -0700 Subject: [PATCH 519/657] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (dart-lang/package_config#132) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/a57a6c04cf7d4840e88432aad6281d1e125f0d46...d6a63dab3335f427404425de0fbfed4686d93c4f) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 8ca52ec84..edf05e203 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install From 7a2837b681011a6165b233c1f2f13c1359cdf700 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:32:56 -0700 Subject: [PATCH 520/657] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (dart-lang/source_span#95) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/a57a6c04cf7d4840e88432aad6281d1e125f0d46...d6a63dab3335f427404425de0fbfed4686d93c4f) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 5a03db3b3..2874adcba 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install From e658a4052df7d9b8b3976efff8d0c879d49430b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:33:00 -0700 Subject: [PATCH 521/657] Bump actions/checkout from 3.3.0 to 3.5.0 (dart-lang/pub_semver#83) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 5a3d9cfe1..c33722171 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.17.0, dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 with: sdk: ${{ matrix.sdk }} From dab9e4e893addf9323873f1b4fcc769a617624e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:36:58 -0700 Subject: [PATCH 522/657] Bump actions/checkout from 3.3.0 to 3.5.0 (dart-lang/source_span#94) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.3.0 to 3.5.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/ac593985615ec2ede58e132d2e21d2b1cbd6127c...8f4b7f84864484a7bf31766abe9204da3cbe65b3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 2874adcba..b70103cd7 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From b6822a17b839f80d9c655d023177675f6500a519 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:55:25 -0700 Subject: [PATCH 523/657] Bump dart-lang/setup-dart from 1.4.0 to 1.5.0 (dart-lang/pub_semver#82) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/a57a6c04cf7d4840e88432aad6281d1e125f0d46...d6a63dab3335f427404425de0fbfed4686d93c4f) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index c33722171..35a98b0c1 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.17.0, dev] steps: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 - - uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46 + - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} - id: install From dd5ecf129c04901bd81fc0b1a076cd0aad889c37 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Wed, 5 Apr 2023 15:28:04 -0700 Subject: [PATCH 524/657] blast_repo fixes (dart-lang/source_span#96) * blast_repo fixes auto-publish * update changelog --- .../.github/workflows/publish.yaml | 14 ++++ pkgs/source_span/CHANGELOG.md | 70 +++++++++---------- 2 files changed, 49 insertions(+), 35 deletions(-) create mode 100644 pkgs/source_span/.github/workflows/publish.yaml diff --git a/pkgs/source_span/.github/workflows/publish.yaml b/pkgs/source_span/.github/workflows/publish.yaml new file mode 100644 index 000000000..2239b63d3 --- /dev/null +++ b/pkgs/source_span/.github/workflows/publish.yaml @@ -0,0 +1,14 @@ +# A CI configuration to auto-publish pub packages. + +name: Publish + +on: + pull_request: + branches: [ master ] + push: + tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] + +jobs: + publish: + if: ${{ github.repository_owner == 'dart-lang' }} + uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index fa1735aa2..f69f0b872 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,40 +1,40 @@ -# 1.9.2-dev +## 1.9.2-dev * Require Dart 2.18 * Add an API usage example in `example/`. -# 1.9.1 +## 1.9.1 * Properly handle multi-line labels for multi-span highlights. * Populate the pubspec `repository` field. -# 1.9.0 +## 1.9.0 * Add `SourceSpanWithContextExtension.subspan` that returns a `SourceSpanWithContext` rather than a plain `SourceSpan`. -# 1.8.2 +## 1.8.2 * Fix a bug where highlighting multiple spans with `null` URLs could cause an assertion error. Now when multiple spans are passed with `null` URLs, they're highlighted as though they all come from different source files. -# 1.8.1 +## 1.8.1 * Fix a bug where the URL header for the highlights with multiple files would get omitted only one span has a non-null URI. -# 1.8.0 +## 1.8.0 * Stable release for null safety. -# 1.7.0 +## 1.7.0 * Add a `SourceSpan.subspan()` extension method which returns a slice of an existing source span. -# 1.6.0 +## 1.6.0 * Add support for highlighting multiple source spans at once, providing more context for span-based messages. This is exposed through the new APIs @@ -42,28 +42,28 @@ extension methods), `MultiSourceSpanException`, and `MultiSourceSpanFormatException`. -# 1.5.6 +## 1.5.6 * Fix padding around line numbers that are powers of 10 in `FileSpan.highlight()`. -# 1.5.5 +## 1.5.5 * Fix a bug where `FileSpan.highlight()` would crash for spans that covered a trailing newline and a single additional empty line. -# 1.5.4 +## 1.5.4 * `FileSpan.highlight()` now properly highlights point spans at the beginning of lines. -# 1.5.3 +## 1.5.3 * Fix an edge case where `FileSpan.highlight()` would put the highlight indicator in the wrong position when highlighting a point span after the end of a file. -# 1.5.2 +## 1.5.2 * `SourceFile.span()` now goes to the end of the file by default, rather than ending one character before the end of the file. This matches the documented @@ -75,7 +75,7 @@ * Fix an edge case where `FileSpan.highlight()` could crash when highlighting a span that ended with an empty line. -# 1.5.1 +## 1.5.1 * Produce better source span highlights for multi-line spans that cover the entire last line of the span, including the newline. @@ -83,7 +83,7 @@ * Produce better source span highlights for spans that contain Windows-style newlines. -# 1.5.0 +## 1.5.0 * Improve the output of `SourceSpan.highlight()` and `SourceSpan.message()`: @@ -94,11 +94,11 @@ [`term_glyph.ascii`]: https://pub.dartlang.org/documentation/term_glyph/latest/term_glyph/ascii.html -# 1.4.1 +## 1.4.1 * Set max SDK version to `<3.0.0`, and adjust other dependencies. -# 1.4.0 +## 1.4.0 * The `new SourceFile()` constructor is deprecated. This constructed a source file from a string's runes, rather than its code units, which runs counter to @@ -111,36 +111,36 @@ * The current behavior when characters larger than `0xFFFF` are passed to `new SourceFile.decoded()` is now considered deprecated. -# 1.3.1 +## 1.3.1 * Properly highlight spans for lines that include tabs with `SourceSpan.highlight()` and `SourceSpan.message()`. -# 1.3.0 +## 1.3.0 * Add `SourceSpan.highlight()`, which returns just the highlighted text that would be included in `SourceSpan.message()`. -# 1.2.4 +## 1.2.4 * Fix a new strong mode error. -# 1.2.3 +## 1.2.3 * Fix a bug where a point span at the end of a file without a trailing newline would be printed incorrectly. -# 1.2.2 +## 1.2.2 * Allow `SourceSpanException.message`, `SourceSpanFormatException.source`, and `SourceSpanWithContext.context` to be overridden in strong mode. -# 1.2.1 +## 1.2.1 * Fix the declared type of `FileSpan.start` and `FileSpan.end`. In 1.2.0 these were mistakenly changed from `FileLocation` to `SourceLocation`. -# 1.2.0 +## 1.2.0 * **Deprecated:** Extending `SourceLocation` directly is deprecated. Instead, extend the new `SourceLocationBase` class or mix in the new @@ -148,58 +148,58 @@ * Dramatically improve the performance of `FileLocation`. -# 1.1.6 +## 1.1.6 * Optimize `getLine()` in `SourceFile` when repeatedly called. -# 1.1.5 +## 1.1.5 * Fixed another case in which `FileSpan.union` could throw an exception for external implementations of `FileSpan`. -# 1.1.4 +## 1.1.4 * Eliminated dart2js warning about overriding `==`, but not `hashCode`. -# 1.1.3 +## 1.1.3 * `FileSpan.compareTo`, `FileSpan.==`, `FileSpan.union`, and `FileSpan.expand` no longer throw exceptions for external implementations of `FileSpan`. * `FileSpan.hashCode` now fully agrees with `FileSpan.==`. -# 1.1.2 +## 1.1.2 * Fixed validation in `SourceSpanWithContext` to allow multiple occurrences of `text` within `context`. -# 1.1.1 +## 1.1.1 * Fixed `FileSpan`'s context to include the full span text, not just the first line of it. -# 1.1.0 +## 1.1.0 * Added `SourceSpanWithContext`: a span that also includes the full line of text that contains the span. -# 1.0.3 +## 1.0.3 * Cleanup equality operator to accept any Object rather than just a `SourceLocation`. -# 1.0.2 +## 1.0.2 * Avoid unintentionally allocating extra objects for internal `FileSpan` operations. * Ensure that `SourceSpan.operator==` works on arbitrary `Object`s. -# 1.0.1 +## 1.0.1 * Use a more compact internal representation for `FileSpan`. -# 1.0.0 +## 1.0.0 This package was extracted from the [`source_maps`](https://pub.dev/packages/source_maps) package, but the From 0c19dae62cfc724eb020ce7ba087c266d790efda Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum Date: Wed, 5 Apr 2023 16:52:39 -0700 Subject: [PATCH 525/657] Add public access to a SourceFile's code units (dart-lang/source_span#93) * Add public access to a SourceFile's code units This makes it possible to efficiently reparse information from around a `FileSpan`, such as to expand it through surrounding whitespace characters. Otherwise, a caller would have to call `getText()` which can be very expensive in a tight loop. * Fix lints * Update CHANGELOG.md Co-authored-by: Devon Carew --------- Co-authored-by: Devon Carew --- pkgs/source_span/CHANGELOG.md | 3 ++- pkgs/source_span/lib/src/file.dart | 10 +++++++++- pkgs/source_span/pubspec.yaml | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index f69f0b872..17812f6f6 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,5 +1,6 @@ -## 1.9.2-dev +## 1.10.0 +* Add a `SourceFile.codeUnits` property. * Require Dart 2.18 * Add an API usage example in `example/`. diff --git a/pkgs/source_span/lib/src/file.dart b/pkgs/source_span/lib/src/file.dart index 52d1b6cca..74c923459 100644 --- a/pkgs/source_span/lib/src/file.dart +++ b/pkgs/source_span/lib/src/file.dart @@ -32,7 +32,15 @@ class SourceFile { /// the file. final _lineStarts = [0]; - /// The code points of the characters in the file. + /// The code units of the characters in the file. + /// + /// If this was constructed with the deprecated `SourceFile()` constructor, + /// this will instead contain the code _points_ of the characters in the file + /// (so characters above 2^16 are represented as individual integers rather + /// than surrogate pairs). + List get codeUnits => _decodedChars; + + /// The code units of the characters in this file. final Uint32List _decodedChars; /// The length of the file in characters. diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index d00730c39..44156ee5a 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.9.2-dev +version: 1.10.0 description: >- Provides a standard representation for source code locations and spans. repository: https://github.com/dart-lang/source_span From 5eaf67b999ffcc0cf588b79590e46185ece2ecf5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 11:12:49 -0700 Subject: [PATCH 526/657] Bump actions/checkout from 3.5.0 to 3.5.2 (dart-lang/source_span#97) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...8e5e7e5ab8b370d6c329ec480221332ada57f0ab) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index b70103cd7..2d36a3b10 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From b7769f1b1d66d36138466e9be688e8b6b62a2f56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 May 2023 11:12:53 -0700 Subject: [PATCH 527/657] Bump actions/checkout from 3.5.0 to 3.5.2 (dart-lang/source_maps#77) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...8e5e7e5ab8b370d6c329ec480221332ada57f0ab) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index bc89aa25e..0acf9e85c 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 269838e6f53a4fe58e7603ad89fc0701ac84f098 Mon Sep 17 00:00:00 2001 From: Jonas Finnemann Jensen Date: Thu, 4 May 2023 14:33:15 +0200 Subject: [PATCH 528/657] Prepare release with topics (dart-lang/pub_semver#86) --- pkgs/pub_semver/CHANGELOG.md | 4 +++- pkgs/pub_semver/pubspec.yaml | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 057895a90..e5db48952 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,4 +1,6 @@ -## 2.1.4-dev +## 2.1.4 + +- Added topics to `pubspec.yaml`. ## 2.1.3 diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 990cf8eca..219e99655 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,9 +1,12 @@ name: pub_semver -version: 2.1.4-dev +version: 2.1.4 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. repository: https://github.com/dart-lang/pub_semver +topics: + - dart-pub + - semver environment: sdk: '>=2.17.0 <3.0.0' From a543f2f29afe1a398ce53ddccc07ec4569838465 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 12:20:25 -0700 Subject: [PATCH 529/657] Bump actions/checkout from 3.5.0 to 3.5.2 (dart-lang/package_config#134) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...8e5e7e5ab8b370d6c329ec480221332ada57f0ab) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index edf05e203..2c1be945f 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From dde204efa4281fc2253ce055683bb6fda8378996 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 12:24:18 -0700 Subject: [PATCH 530/657] Bump actions/checkout from 3.5.0 to 3.5.2 (dart-lang/pub_semver#85) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...8e5e7e5ab8b370d6c329ec480221332ada57f0ab) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 35a98b0c1..4bad718a0 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.17.0, dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 982c8a82c64482fb2860a4314fdb3400cf4caffe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 12:30:07 -0700 Subject: [PATCH 531/657] Bump actions/checkout from 3.5.0 to 3.5.2 (dart-lang/pool#68) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.0 to 3.5.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/8f4b7f84864484a7bf31766abe9204da3cbe65b3...8e5e7e5ab8b370d6c329ec480221332ada57f0ab) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 5dbe7c0bf..23400de05 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.19.0, dev] steps: - - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From c88be35329e7f12d5645c245b38149fd8b3a75ff Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 22 May 2023 09:20:23 -0700 Subject: [PATCH 532/657] blast_repo fixes (dart-lang/pub_semver#87) dependabot --- pkgs/pub_semver/.github/dependabot.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/pub_semver/.github/dependabot.yaml b/pkgs/pub_semver/.github/dependabot.yaml index 214481934..439e796b4 100644 --- a/pkgs/pub_semver/.github/dependabot.yaml +++ b/pkgs/pub_semver/.github/dependabot.yaml @@ -2,7 +2,9 @@ version: 2 updates: - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: github-actions + directory: / schedule: - interval: "monthly" + interval: monthly + labels: + - autosubmit From e6c23dc872370fff00dfe5c13433281ca6bfcbab Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 22 May 2023 09:20:32 -0700 Subject: [PATCH 533/657] blast_repo fixes (dart-lang/pool#69) dependabot --- pkgs/pool/.github/dependabot.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/pool/.github/dependabot.yml b/pkgs/pool/.github/dependabot.yml index 1603cdd9e..725f03af2 100644 --- a/pkgs/pool/.github/dependabot.yml +++ b/pkgs/pool/.github/dependabot.yml @@ -3,7 +3,9 @@ version: 2 updates: - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: github-actions + directory: / schedule: - interval: "monthly" + interval: monthly + labels: + - autosubmit From 3af89623aacf60144f2449d0fe397d5b9ab95b05 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 22 May 2023 09:22:56 -0700 Subject: [PATCH 534/657] blast_repo fixes (dart-lang/package_config#135) dependabot --- pkgs/package_config/.github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkgs/package_config/.github/dependabot.yml b/pkgs/package_config/.github/dependabot.yml index b2f1dec5a..c84404dc9 100644 --- a/pkgs/package_config/.github/dependabot.yml +++ b/pkgs/package_config/.github/dependabot.yml @@ -8,3 +8,5 @@ updates: directory: / schedule: interval: monthly + labels: + - autosubmit From cee7105053cb97d17d481070e94fba7c5a28e9fe Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 23 May 2023 10:10:13 -0700 Subject: [PATCH 535/657] blast_repo fixes (dart-lang/source_maps#78) dependabot --- pkgs/source_maps/.github/dependabot.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/source_maps/.github/dependabot.yaml b/pkgs/source_maps/.github/dependabot.yaml index 214481934..439e796b4 100644 --- a/pkgs/source_maps/.github/dependabot.yaml +++ b/pkgs/source_maps/.github/dependabot.yaml @@ -2,7 +2,9 @@ version: 2 updates: - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: github-actions + directory: / schedule: - interval: "monthly" + interval: monthly + labels: + - autosubmit From 5ea8221d905037ea059695ce534915e54bba8c7e Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Tue, 23 May 2023 10:10:17 -0700 Subject: [PATCH 536/657] blast_repo fixes (dart-lang/source_span#98) dependabot --- pkgs/source_span/.github/dependabot.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkgs/source_span/.github/dependabot.yml b/pkgs/source_span/.github/dependabot.yml index 9735d75f3..c6531d433 100644 --- a/pkgs/source_span/.github/dependabot.yml +++ b/pkgs/source_span/.github/dependabot.yml @@ -4,7 +4,9 @@ version: 2 updates: -- package-ecosystem: "github-actions" - directory: "/" +- package-ecosystem: github-actions + directory: / schedule: - interval: "monthly" + interval: monthly + labels: + - autosubmit From 6257e94c9650af5f1f66a5664a70e71afae28cce Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 31 May 2023 13:29:08 -0700 Subject: [PATCH 537/657] Bump lints, require Dart 3.0 (dart-lang/pub_semver#89) --- .../.github/workflows/test-package.yml | 2 +- pkgs/pub_semver/CHANGELOG.md | 4 ++++ .../lib/src/version_constraint.dart | 20 ++++++++----------- pkgs/pub_semver/pubspec.yaml | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 4bad718a0..6e9fc3911 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.17.0, dev] + sdk: [3.0.0, dev] steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index e5db48952..33899354f 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.5-wip + +- Require Dart `3.0.0`. + ## 2.1.4 - Added topics to `pubspec.yaml`. diff --git a/pkgs/pub_semver/lib/src/version_constraint.dart b/pkgs/pub_semver/lib/src/version_constraint.dart index 3bde4911b..948118ef3 100644 --- a/pkgs/pub_semver/lib/src/version_constraint.dart +++ b/pkgs/pub_semver/lib/src/version_constraint.dart @@ -70,7 +70,7 @@ abstract class VersionConstraint { var comparison = startComparison.firstMatch(text); if (comparison == null) return null; - var op = comparison[0]; + var op = comparison[0]!; text = text.substring(comparison.end); skipWhitespace(); @@ -80,17 +80,13 @@ abstract class VersionConstraint { '"$originalText", got "$text".'); } - switch (op) { - case '<=': - return VersionRange(max: version, includeMax: true); - case '<': - return VersionRange(max: version, alwaysIncludeMaxPreRelease: true); - case '>=': - return VersionRange(min: version, includeMin: true); - case '>': - return VersionRange(min: version); - } - throw UnsupportedError(op!); + return switch (op) { + '<=' => VersionRange(max: version, includeMax: true), + '<' => VersionRange(max: version, alwaysIncludeMaxPreRelease: true), + '>=' => VersionRange(min: version, includeMin: true), + '>' => VersionRange(min: version), + _ => throw UnsupportedError(op), + }; } // Try to parse the "^" operator followed by a version. diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 219e99655..72ffdfe28 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.1.4 +version: 2.1.5-wip description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. @@ -9,12 +9,12 @@ topics: - semver environment: - sdk: '>=2.17.0 <3.0.0' + sdk: ^3.0.0 dependencies: collection: ^1.15.0 meta: ^1.3.0 dev_dependencies: - dart_flutter_team_lints: ^0.1.0 + dart_flutter_team_lints: ^1.0.0 test: ^1.16.0 From f2ffb25d3d862244389eed89c5082aa4aebd2c6e Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 7 Jun 2023 17:22:34 -0700 Subject: [PATCH 538/657] Require Dart 3.0, update lints (dart-lang/pool#71) --- pkgs/pool/.github/workflows/ci.yml | 2 +- pkgs/pool/CHANGELOG.md | 5 ++--- pkgs/pool/pubspec.yaml | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 23400de05..9c507b69a 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.19.0, dev] + sdk: [3.0.0, dev] steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 8d16309f1..e17e848cc 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,10 +1,9 @@ -## 1.5.2-dev +## 1.5.2-wip -* Require Dart 2.19 +* Require Dart 3.0. ## 1.5.1 -* Switch to using `package:lints` for analysis. * Populate the pubspec `repository` field. ## 1.5.0 diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index fff7adbef..08e4027a9 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,18 +1,18 @@ name: pool -version: 1.5.2-dev +version: 1.5.2-wip description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. repository: https://github.com/dart-lang/pool environment: - sdk: ">=2.19.0 <3.0.0" + sdk: ^3.0.0 dependencies: async: ^2.5.0 stack_trace: ^1.10.0 dev_dependencies: - dart_flutter_team_lints: ^0.1.0 + dart_flutter_team_lints: ^1.0.0 fake_async: ^1.2.0 test: ^1.16.0 From a9e43f06cdd1116fb7170148cbcbb96938723e62 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 12 Jun 2023 08:50:05 -0700 Subject: [PATCH 539/657] Require Dart 3, update lints (dart-lang/source_maps#79) --- pkgs/source_maps/.github/workflows/test-package.yml | 2 +- pkgs/source_maps/CHANGELOG.md | 4 ++++ pkgs/source_maps/README.md | 2 +- pkgs/source_maps/lib/src/source_map_span.dart | 2 -- pkgs/source_maps/pubspec.yaml | 6 +++--- pkgs/source_maps/test/builder_test.dart | 2 -- pkgs/source_maps/test/end2end_test.dart | 2 -- pkgs/source_maps/test/printer_test.dart | 2 -- pkgs/source_maps/test/refactor_test.dart | 4 +--- pkgs/source_maps/test/vlq_test.dart | 2 -- 10 files changed, 10 insertions(+), 18 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 0acf9e85c..1f8243089 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.18.0, dev] + sdk: [3.0.0, dev] steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 275d197da..5afbb6c53 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.13-wip + +- Require Dart 3.0 + ## 0.10.12 * Add additional types at API boundaries. diff --git a/pkgs/source_maps/README.md b/pkgs/source_maps/README.md index ad8fd258a..30da7f8cd 100644 --- a/pkgs/source_maps/README.md +++ b/pkgs/source_maps/README.md @@ -16,7 +16,7 @@ In this package we provide: original source map specification. These data types are great for tracking source locations on source maps, but they can also be used by tools to reporting useful error messages that include on source locations. - * A builder that creates a source map programatically and produces the encoded + * A builder that creates a source map programmatically and produces the encoded source map format. * A parser that reads the source map format and provides APIs to read the mapping information. diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index 2840db4e9..8ca12b96f 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -2,8 +2,6 @@ // 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. -library source_maps.source_map_span; - import 'package:source_span/source_span.dart'; /// A [SourceSpan] for spans coming from or being written to source maps. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index f716ef6d0..4180b8d72 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,15 +1,15 @@ name: source_maps -version: 0.10.12 +version: 0.10.13-wip description: A library to programmatically manipulate source map files. repository: https://github.com/dart-lang/source_maps environment: - sdk: '>=2.18.0 <3.0.0' + sdk: ^3.0.0 dependencies: source_span: ^1.8.0 dev_dependencies: - dart_flutter_team_lints: ^0.1.0 + dart_flutter_team_lints: ^1.0.0 term_glyph: ^1.2.0 test: ^1.16.0 diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart index b9bb9c770..4f773e773 100644 --- a/pkgs/source_maps/test/builder_test.dart +++ b/pkgs/source_maps/test/builder_test.dart @@ -2,8 +2,6 @@ // 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. -library test.source_maps_test; - import 'dart:convert'; import 'package:source_maps/source_maps.dart'; diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart index 153fcc286..84dd5badc 100644 --- a/pkgs/source_maps/test/end2end_test.dart +++ b/pkgs/source_maps/test/end2end_test.dart @@ -2,8 +2,6 @@ // 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. -library test.end2end_test; - import 'package:source_maps/source_maps.dart'; import 'package:source_span/source_span.dart'; import 'package:test/test.dart'; diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart index 3db321dde..89265e36b 100644 --- a/pkgs/source_maps/test/printer_test.dart +++ b/pkgs/source_maps/test/printer_test.dart @@ -2,8 +2,6 @@ // 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. -library test.printer_test; - import 'dart:convert'; import 'package:source_maps/source_maps.dart'; diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart index 0389631dd..5bc3818e5 100644 --- a/pkgs/source_maps/test/refactor_test.dart +++ b/pkgs/source_maps/test/refactor_test.dart @@ -2,9 +2,7 @@ // 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. -library polymer.test.refactor_test; - -import 'package:source_maps/parser.dart' show parse, Mapping; +import 'package:source_maps/parser.dart' show Mapping, parse; import 'package:source_maps/refactor.dart'; import 'package:source_span/source_span.dart'; import 'package:term_glyph/term_glyph.dart' as term_glyph; diff --git a/pkgs/source_maps/test/vlq_test.dart b/pkgs/source_maps/test/vlq_test.dart index 94193007a..4568cffc4 100644 --- a/pkgs/source_maps/test/vlq_test.dart +++ b/pkgs/source_maps/test/vlq_test.dart @@ -2,8 +2,6 @@ // 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. -library test.vlq_test; - import 'dart:math'; import 'package:source_maps/src/vlq.dart'; From 812bd5b3aadf5d80e4b120b93237b9c250b5c9ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 02:16:18 +0000 Subject: [PATCH 540/657] Bump actions/checkout from 3.5.2 to 3.5.3 (dart-lang/pool#72) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
Release notes

Sourced from actions/checkout's releases.

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

v2.3.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 9c507b69a..c1107a5a7 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From b2fcb7e4af3368c381af56986c35db3b1143cade Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 16:09:12 +0000 Subject: [PATCH 541/657] Bump actions/checkout from 3.5.2 to 3.5.3 (dart-lang/pub_semver#90) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
Release notes

Sourced from actions/checkout's releases.

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

v2.3.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 6e9fc3911..7ad5f74e0 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 79f9b5519fa3313fc8410037f19870343c835967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 17:18:04 +0000 Subject: [PATCH 542/657] Bump actions/checkout from 3.5.2 to 3.5.3 (dart-lang/source_maps#80) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
Release notes

Sourced from actions/checkout's releases.

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

v2.3.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 1f8243089..325fac8f3 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 79b03a999edf9e76f8b32ad9702ebf6564c38889 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 17:25:29 +0000 Subject: [PATCH 543/657] Bump actions/checkout from 3.5.2 to 3.5.3 (dart-lang/source_span#99) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
Release notes

Sourced from actions/checkout's releases.

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

v2.3.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 2d36a3b10..7e593e5ce 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 52722601cb0bf2f90ba34b3e89f24c8f6028b746 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 20:23:57 +0000 Subject: [PATCH 544/657] Bump actions/checkout from 3.5.2 to 3.5.3 (dart-lang/package_config#138) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.2 to 3.5.3.
Release notes

Sourced from actions/checkout's releases.

v3.5.3

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v3.5.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

v2.3.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.2&new-version=3.5.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 2c1be945f..34b8073d5 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 1b7fb96dbc5a3ff3f46f17eccd8872b16bcf2647 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 21 Jul 2023 10:37:29 -0700 Subject: [PATCH 545/657] Update to team lints, require Dart 3.0 (dart-lang/package_config#139) --- .../.github/workflows/test-package.yml | 2 +- pkgs/package_config/CHANGELOG.md | 4 ++-- pkgs/package_config/analysis_options.yaml | 2 +- pkgs/package_config/example/main.dart | 3 ++- pkgs/package_config/lib/package_config.dart | 2 +- .../lib/package_config_types.dart | 4 ++-- pkgs/package_config/lib/src/discovery.dart | 3 +-- pkgs/package_config/lib/src/errors.dart | 1 + .../lib/src/package_config_json.dart | 9 ++++++-- .../package_config/lib/src/packages_file.dart | 5 ++--- pkgs/package_config/pubspec.yaml | 8 +++---- pkgs/package_config/test/bench.dart | 22 +++++++++---------- pkgs/package_config/test/discovery_test.dart | 5 +++-- .../test/discovery_uri_test.dart | 6 ++--- pkgs/package_config/test/parse_test.dart | 20 ++++++++++------- pkgs/package_config/test/src/util_io.dart | 2 +- 16 files changed, 54 insertions(+), 44 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 34b8073d5..d14e9f416 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.18.0, dev] + sdk: [3.0.0, dev] steps: - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 62ef87d6e..d084d8514 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,6 +1,6 @@ -## 2.1.1-dev +## 2.1.1-wip -- Require Dart 2.18 +- Require Dart 3.0 ## 2.1.0 diff --git a/pkgs/package_config/analysis_options.yaml b/pkgs/package_config/analysis_options.yaml index 278ec4868..c0249e5e1 100644 --- a/pkgs/package_config/analysis_options.yaml +++ b/pkgs/package_config/analysis_options.yaml @@ -2,4 +2,4 @@ # 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. -include: package:lints/recommended.yaml +include: package:dart_flutter_team_lints/analysis_options.yaml diff --git a/pkgs/package_config/example/main.dart b/pkgs/package_config/example/main.dart index 42a596375..db137caf4 100644 --- a/pkgs/package_config/example/main.dart +++ b/pkgs/package_config/example/main.dart @@ -2,9 +2,10 @@ // 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:package_config/package_config.dart'; import 'dart:io' show Directory; +import 'package:package_config/package_config.dart'; + void main() async { var packageConfig = await findPackageConfig(Directory.current); if (packageConfig == null) { diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index a2c0321b8..8f40a8b65 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -9,7 +9,7 @@ /// configurations in the [specified format](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). library package_config.package_config; -import 'dart:io' show File, Directory; +import 'dart:io' show Directory, File; import 'dart:typed_data' show Uint8List; import 'src/discovery.dart' as discover; diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart index 976009b6c..756be0518 100644 --- a/pkgs/package_config/lib/package_config_types.dart +++ b/pkgs/package_config/lib/package_config_types.dart @@ -12,6 +12,6 @@ /// {@canonicalFor errors.PackageConfigError} library package_config.package_config_types; -export 'src/package_config.dart' - show PackageConfig, Package, LanguageVersion, InvalidLanguageVersion; export 'src/errors.dart' show PackageConfigError; +export 'src/package_config.dart' + show InvalidLanguageVersion, LanguageVersion, Package, PackageConfig; diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index ccc86ea23..352bed8ca 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -5,10 +5,9 @@ import 'dart:io'; import 'dart:typed_data'; -import 'package_config_io.dart'; - import 'errors.dart'; import 'package_config_impl.dart'; +import 'package_config_io.dart'; import 'package_config_json.dart'; import 'packages_file.dart' as packages_file; import 'util_io.dart' show defaultLoader, pathJoin; diff --git a/pkgs/package_config/lib/src/errors.dart b/pkgs/package_config/lib/src/errors.dart index f3515711d..69c41370a 100644 --- a/pkgs/package_config/lib/src/errors.dart +++ b/pkgs/package_config/lib/src/errors.dart @@ -29,4 +29,5 @@ class PackageConfigFormatException extends FormatException } /// The default `onError` handler. +// ignore: only_throw_errors Never throwError(Object error) => throw error; diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index bd22db4ec..47e7e96b6 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -167,7 +167,9 @@ PackageConfig parsePackageConfigJson( name!, root, packageRoot, version, extraData, relativeRoot, (error) { if (error is ArgumentError) { onError( - PackageConfigFormatException(error.message, error.invalidValue)); + PackageConfigFormatException( + error.message.toString(), error.invalidValue), + ); } else { onError(error); } @@ -214,7 +216,10 @@ PackageConfig parsePackageConfigJson( } return SimplePackageConfig(configVersion!, packageList!, extraData, (error) { if (error is ArgumentError) { - onError(PackageConfigFormatException(error.message, error.invalidValue)); + onError( + PackageConfigFormatException( + error.message.toString(), error.invalidValue), + ); } else { onError(error); } diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index 3fd7db9b5..5d1467755 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -2,10 +2,9 @@ // 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 'errors.dart'; import 'package_config_impl.dart'; - import 'util.dart'; -import 'errors.dart'; /// The language version prior to the release of language versioning. /// @@ -127,7 +126,7 @@ PackageConfig parse( var package = SimplePackage.validate(packageName, rootUri, packageLocation, _languageVersion, null, relativeRoot, (error) { if (error is ArgumentError) { - onError(PackageConfigFormatException(error.message, source)); + onError(PackageConfigFormatException(error.message.toString(), source)); } else { onError(error); } diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 08255ffa9..e121ab033 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,10 +1,10 @@ name: package_config -version: 2.1.1-dev +version: 2.1.1-wip description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/package_config environment: - sdk: '>=2.18.0 <3.0.0' + sdk: ^3.0.0 dependencies: path: ^1.8.0 @@ -12,6 +12,6 @@ dependencies: dev_dependencies: build_runner: ^2.0.0 build_test: ^2.1.2 - build_web_compilers: '>=3.0.0 <5.0.0' - lints: ^2.0.0 + build_web_compilers: ^4.0.0 + dart_flutter_team_lints: ^1.0.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/bench.dart b/pkgs/package_config/test/bench.dart index 746643185..8428481f7 100644 --- a/pkgs/package_config/test/bench.dart +++ b/pkgs/package_config/test/bench.dart @@ -5,10 +5,9 @@ import 'dart:convert'; import 'dart:typed_data'; +import 'package:package_config/src/errors.dart'; import 'package:package_config/src/package_config_json.dart'; -void throwError(Object error) => throw error; - void bench(final int size, final bool doPrint) { var sb = StringBuffer(); sb.writeln('{'); @@ -32,20 +31,21 @@ void bench(final int size, final bool doPrint) { sb.writeln('}'); var stopwatch = Stopwatch()..start(); var config = parsePackageConfigBytes( - // ignore: unnecessary_cast - utf8.encode(sb.toString()) as Uint8List, - Uri.parse('file:///tmp/.dart_tool/file.dart'), - throwError); - final int read = stopwatch.elapsedMilliseconds; + // ignore: unnecessary_cast + utf8.encode(sb.toString()) as Uint8List, + Uri.parse('file:///tmp/.dart_tool/file.dart'), + throwError, + ); + final read = stopwatch.elapsedMilliseconds; stopwatch.reset(); for (var i = 0; i < size; i++) { if (config.packageOf(Uri.parse('file:///p_$i/lib/src/foo.dart'))!.name != 'p_$i') { - throw "Unexpected result!"; + throw StateError('Unexpected result!'); } } - final int lookup = stopwatch.elapsedMilliseconds; + final lookup = stopwatch.elapsedMilliseconds; if (doPrint) { print('Read file with $size packages in $read ms, ' @@ -55,12 +55,12 @@ void bench(final int size, final bool doPrint) { void main(List args) { if (args.length != 1 && args.length != 2) { - throw "Expects arguments: ?"; + throw ArgumentError('Expects arguments: ?'); } final size = int.parse(args[0]); if (args.length > 1) { final warmups = int.parse(args[1]); - print("Performing $warmups warmup iterations."); + print('Performing $warmups warmup iterations.'); for (var i = 0; i < warmups; i++) { bench(10, false); } diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 17b6aa099..3eb0ea153 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -6,8 +6,9 @@ library package_config.discovery_test; import 'dart:io'; -import 'package:test/test.dart'; + import 'package:package_config/package_config.dart'; +import 'package:test/test.dart'; import 'src/util.dart'; import 'src/util_io.dart'; @@ -207,7 +208,7 @@ void main() { '.packages': packagesFile, 'script.dart': 'main(){}' }, (Directory directory) async { - var config = (await findPackageConfig(directory, minVersion: 2)); + var config = await findPackageConfig(directory, minVersion: 2); expect(config, null); }); diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index 6183ce3ba..c8fbcb87c 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -5,8 +5,8 @@ @TestOn('vm') library package_config.discovery_test; -import 'package:test/test.dart'; import 'package:package_config/package_config.dart'; +import 'package:test/test.dart'; import 'src/util.dart'; @@ -151,8 +151,8 @@ void main() { '.packages': packagesFile, 'script.dart': 'main(){}' }, (directory, loader) async { - var config = (await findPackageConfigUri(directory, - minVersion: 2, loader: loader)); + var config = + await findPackageConfigUri(directory, minVersion: 2, loader: loader); expect(config, null); }); diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 94269e20f..ad4c74949 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -5,14 +5,13 @@ import 'dart:convert'; import 'dart:typed_data'; -import 'package:test/test.dart'; - import 'package:package_config/package_config_types.dart'; -import 'package:package_config/src/packages_file.dart' as packages; +import 'package:package_config/src/errors.dart'; import 'package:package_config/src/package_config_json.dart'; -import 'src/util.dart'; +import 'package:package_config/src/packages_file.dart' as packages; +import 'package:test/test.dart'; -void throwError(Object error) => throw error; +import 'src/util.dart'; void main() { group('.packages', () { @@ -318,8 +317,12 @@ void main() { test(name, () { dynamic exception; try { - parsePackageConfigBytes(utf8.encode(source) as Uint8List, - Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError); + parsePackageConfigBytes( + // ignore: unnecessary_cast + utf8.encode(source) as Uint8List, + Uri.parse('file:///tmp/.dart_tool/file.dart'), + throwError, + ); } catch (e) { exception = e; } @@ -440,8 +443,9 @@ void main() { 'package root of foo is inside the root of bar'); // This shouldn't be allowed, but for internal reasons it is. - test("package inside package root", () { + test('package inside package root', () { var config = parsePackageConfigBytes( + // ignore: unnecessary_cast utf8.encode( '{$cfg,"packages":[' '{"name":"foo","rootUri":"/foo/","packageUri":"lib/"},' diff --git a/pkgs/package_config/test/src/util_io.dart b/pkgs/package_config/test/src/util_io.dart index 109dff112..e032556f4 100644 --- a/pkgs/package_config/test/src/util_io.dart +++ b/pkgs/package_config/test/src/util_io.dart @@ -4,8 +4,8 @@ import 'dart:io'; -import 'package:test/test.dart'; import 'package:package_config/src/util_io.dart'; +import 'package:test/test.dart'; /// Creates a directory structure from [description] and runs [fileTest]. /// From 687ba74f82da9ca33282e2f9b2f5d5e2fecc0d7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 02:18:57 +0000 Subject: [PATCH 546/657] Bump actions/checkout from 3.5.3 to 3.6.0 (dart-lang/pool#73) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
Release notes

Sourced from actions/checkout's releases.

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.3&new-version=3.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index c1107a5a7..6c8907b19 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From ac53d454e8f834872e6c6d5ce271d2a6187b13f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 16:58:45 +0000 Subject: [PATCH 547/657] Bump actions/checkout from 3.5.3 to 3.6.0 (dart-lang/pub_semver#91) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
Release notes

Sourced from actions/checkout's releases.

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.3&new-version=3.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 7ad5f74e0..24d44c9ac 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From b773a934097f156a2ef46718bbfcc40f15feeabf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 17:25:56 +0000 Subject: [PATCH 548/657] Bump actions/checkout from 3.5.3 to 3.6.0 (dart-lang/source_span#101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
Release notes

Sourced from actions/checkout's releases.

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.3&new-version=3.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 7e593e5ce..3c54fc1b7 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From cc7051e5cc372cc7af1f024775b2cba6865c4375 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 17:46:04 +0000 Subject: [PATCH 549/657] Bump actions/checkout from 3.5.3 to 3.6.0 (dart-lang/source_maps#81) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
Release notes

Sourced from actions/checkout's releases.

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.3&new-version=3.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 325fac8f3..6e4f6ec13 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 9c69749f299fb5f031f6a8a281b4b2799feb8303 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 20:17:04 +0000 Subject: [PATCH 550/657] Bump actions/checkout from 3.5.3 to 3.6.0 (dart-lang/package_config#140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 3.6.0.
Release notes

Sourced from actions/checkout's releases.

v3.6.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3.5.3...v3.6.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

v3.0.1

v3.0.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.5.3&new-version=3.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index d14e9f416..5ee9b9226 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 9a4199c431608c955f2175b180d6ae6e1292b6ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 02:44:48 +0000 Subject: [PATCH 551/657] Bump actions/checkout from 3.6.0 to 4.1.0 (dart-lang/pool#75) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.0.
Release notes

Sourced from actions/checkout's releases.

v4.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.0.0...v4.1.0

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.6.0&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 6c8907b19..eb8c73d8d 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From fd5db62e368e79da2e597d085a0b99dc86d2640d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 16:41:17 +0000 Subject: [PATCH 552/657] Bump actions/checkout from 3.6.0 to 4.1.0 (dart-lang/pub_semver#92) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.0.
Release notes

Sourced from actions/checkout's releases.

v4.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.0.0...v4.1.0

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.6.0&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 24d44c9ac..585fbb43a 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f with: sdk: ${{ matrix.sdk }} From 48bbfc3ca9f8857173e3b92e88d8c33e9cbedd4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 17:55:17 +0000 Subject: [PATCH 553/657] Bump dart-lang/setup-dart from 1.5.0 to 1.5.1 (dart-lang/source_maps#82) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.0 to 1.5.1.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.0&new-version=1.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 6e4f6ec13..f476e3586 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install From 916d92d5dc5290e1a1434a6b75ebbfc167c199dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 18:02:11 +0000 Subject: [PATCH 554/657] Bump dart-lang/setup-dart from 1.5.0 to 1.5.1 (dart-lang/source_span#103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.0 to 1.5.1.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.0&new-version=1.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 3c54fc1b7..fe375c613 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install From fb8a8325791529d7c428459f63cebb75a96bb9b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 18:07:05 +0000 Subject: [PATCH 555/657] Bump actions/checkout from 3.6.0 to 4.1.0 (dart-lang/source_span#102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.0.
Release notes

Sourced from actions/checkout's releases.

v4.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.0.0...v4.1.0

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.6.0&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index fe375c613..4d307f3f5 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} From 4225920dc204d378248efa525b1cefcbe6988ca3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Oct 2023 20:24:54 +0000 Subject: [PATCH 556/657] Bump dart-lang/setup-dart from 1.5.0 to 1.5.1 (dart-lang/package_config#142) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.0 to 1.5.1.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.0&new-version=1.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 5ee9b9226..6a09c5a68 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install From a8ce33657f705a401c8a5322bce18e7f617e44f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:26:42 +0000 Subject: [PATCH 557/657] Bump actions/checkout from 3.6.0 to 4.1.0 (dart-lang/package_config#141) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.0.
Release notes

Sourced from actions/checkout's releases.

v4.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.0.0...v4.1.0

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.6.0&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 6a09c5a68..c3e89aacd 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} From 475b676ce287374ed629175695323c99c7530a47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:37:09 +0000 Subject: [PATCH 558/657] Bump actions/checkout from 3.6.0 to 4.1.0 (dart-lang/source_maps#83) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 3.6.0 to 4.1.0.
Release notes

Sourced from actions/checkout's releases.

v4.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.0.0...v4.1.0

v4.0.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v3...v4.0.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

v3.1.0

v3.0.2

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=3.6.0&new-version=4.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index f476e3586..8f5c3b290 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} From 10ed16c388fc86a422fc0320e7a757bc16664dcb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 18:38:43 +0000 Subject: [PATCH 559/657] Bump dart-lang/setup-dart from 1.5.0 to 1.5.1 (dart-lang/pub_semver#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.0 to 1.5.1.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available in an environment variable, DART_HOME (dart-lang/pub_semver#43).
  • Fixed an issue where cached downloads could lead to unzip issues on self-hosted runners (dart-lang/pub_semver#35).

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.0&new-version=1.5.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 585fbb43a..657b236db 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install From 7265fe753784a2cd8a49db7ab1303b35889cc42c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 07:15:10 -0700 Subject: [PATCH 560/657] Bump dart-lang/setup-dart from 1.5.0 to 1.5.1 (dart-lang/pool#74) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](https://github.com/dart-lang/setup-dart/compare/d6a63dab3335f427404425de0fbfed4686d93c4f...8a4b97ea2017cc079571daec46542f76189836b1) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index eb8c73d8d..d945ee6f5 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 with: sdk: ${{ matrix.sdk }} - id: install From 3e4052b205191fb722743a45be1b3f19bf2f4fb2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 02:05:22 +0000 Subject: [PATCH 561/657] Bump dart-lang/setup-dart from 1.5.1 to 1.6.0 (dart-lang/pool#76) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.1 to 1.6.0.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available in an environment variable, DART_HOME (dart-lang/pool#43).
  • Fixed an issue where cached downloads could lead to unzip issues on self-hosted runners (dart-lang/pool#35).

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.1&new-version=1.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index d945ee6f5..28e9efa21 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install From 41c1ecc06252bafd30b8875eb399c36ae97a2117 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:54:44 +0000 Subject: [PATCH 562/657] Bump actions/checkout from 4.1.0 to 4.1.1 (dart-lang/pool#77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.0...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 28e9efa21..b69f2bd51 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} From 393f66316ab720162883d5ab70cfc8eb7f8902e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 16:29:05 +0000 Subject: [PATCH 563/657] Bump dart-lang/setup-dart from 1.5.1 to 1.6.0 (dart-lang/pub_semver#94) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.1 to 1.6.0.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available in an environment variable, DART_HOME (dart-lang/pub_semver#43).
  • Fixed an issue where cached downloads could lead to unzip issues on self-hosted runners (dart-lang/pub_semver#35).

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.1&new-version=1.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 657b236db..86a16617d 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install From edc6bb398595da7800c5b8d4fd1bb08127f0ea60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 16:32:55 +0000 Subject: [PATCH 564/657] Bump actions/checkout from 4.1.0 to 4.1.1 (dart-lang/pub_semver#95) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.0...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 86a16617d..4cb7d3a73 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} From 423525954dfa317adefcf5c232d0fad30fd682b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:16:06 +0000 Subject: [PATCH 565/657] Bump dart-lang/setup-dart from 1.5.1 to 1.6.0 (dart-lang/source_maps#85) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.1 to 1.6.0.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.1&new-version=1.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 8f5c3b290..cbb07af93 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install From 2f31c0f291f365b03b27a0559446e4e4d8faf58f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:32:29 +0000 Subject: [PATCH 566/657] Bump dart-lang/setup-dart from 1.5.1 to 1.6.0 (dart-lang/source_span#104) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.1 to 1.6.0.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.1&new-version=1.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 4d307f3f5..dda97e4da 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [2.18.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install From 329aec4ed899c5cbe35e6a668889bbbdea801c1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:55:53 +0000 Subject: [PATCH 567/657] Bump actions/checkout from 4.1.0 to 4.1.1 (dart-lang/source_span#105) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.0...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index dda97e4da..6878c5c55 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [2.18.0, dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} From 07d324021af0d93d5076a4a89b087ed691aaa1b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:56:40 +0000 Subject: [PATCH 568/657] Bump actions/checkout from 4.1.0 to 4.1.1 (dart-lang/source_maps#84) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.0...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index cbb07af93..38ced1a4f 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} From aff00e80119d63faa70d6ba7bb7caa230f1003be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 20:33:04 +0000 Subject: [PATCH 569/657] Bump dart-lang/setup-dart from 1.5.1 to 1.6.0 (dart-lang/package_config#143) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.5.1 to 1.6.0.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

  • Added a flavor option setup.sh to allow downloading unpublished builds.

v1.0.0

  • Promoted to 1.0 stable.

v0.5

  • Fixed a Windows pub global activate path issue.

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.5.1&new-version=1.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index c3e89aacd..dd76bff17 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 - - uses: dart-lang/setup-dart@8a4b97ea2017cc079571daec46542f76189836b1 + - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} - id: install From 2019cfabc7ee175b6b9c204a2c98e1e728de926e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 21:39:05 +0000 Subject: [PATCH 570/657] Bump actions/checkout from 4.1.0 to 4.1.1 (dart-lang/package_config#144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.0 to 4.1.1.
Release notes

Sourced from actions/checkout's releases.

v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.0...v4.1.1

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.0&new-version=4.1.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index dd76bff17..2aa74dfe3 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d with: sdk: ${{ matrix.sdk }} From c6f2c0e3a3f7ff01d6f73b55f3a80b4b34341901 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 29 Nov 2023 10:23:56 -0800 Subject: [PATCH 571/657] Move to latest lints, require Dart 3.1 (dart-lang/source_span#106) --- .../.github/workflows/test-package.yml | 2 +- pkgs/source_span/CHANGELOG.md | 4 +++ pkgs/source_span/analysis_options.yaml | 25 +------------------ pkgs/source_span/pubspec.yaml | 6 ++--- 4 files changed, 9 insertions(+), 28 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 6878c5c55..77ba45b39 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [2.18.0, dev] + sdk: [3.1.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index 17812f6f6..f46c1614b 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.10.1-wip + +* Require Dart 3.1 + ## 1.10.0 * Add a `SourceFile.codeUnits` property. diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index 8b32d108a..ae73fa5e9 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -1,5 +1,5 @@ # https://dart.dev/guides/language/analysis-options -include: package:lints/recommended.yaml +include: package:dart_flutter_team_lints/analysis_options.yaml analyzer: language: @@ -9,48 +9,25 @@ analyzer: linter: rules: - - always_declare_return_types - avoid_bool_literals_in_conditional_expressions - - avoid_catching_errors - avoid_classes_with_only_static_members - - avoid_dynamic_calls - avoid_private_typedef_functions - avoid_redundant_argument_values - - avoid_returning_null - - avoid_returning_null_for_future - avoid_returning_this - avoid_unused_constructor_parameters - avoid_void_async - cancel_subscriptions - cascade_invocations - - comment_references - - directives_ordering - join_return_with_assignment - - lines_longer_than_80_chars - literal_only_boolean_expressions - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - - omit_local_variable_types - - only_throw_errors - package_api_docs - - prefer_asserts_in_initializer_lists - - prefer_const_constructors - prefer_const_declarations - prefer_expression_function_bodies - prefer_final_locals - - prefer_relative_imports - - prefer_single_quotes - - sort_pub_dependencies - - test_types_in_equals - - throw_in_finally - - type_annotate_public_apis - - unawaited_futures - unnecessary_await_in_return - - unnecessary_lambdas - - unnecessary_parenthesis - unnecessary_raw_strings - - unnecessary_statements - use_if_null_to_convert_nulls_to_bools - use_raw_strings - use_string_buffers - - use_super_parameters diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 44156ee5a..45804e781 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,11 +1,11 @@ name: source_span -version: 1.10.0 +version: 1.10.1-wip description: >- Provides a standard representation for source code locations and spans. repository: https://github.com/dart-lang/source_span environment: - sdk: ">=2.18.0 <3.0.0" + sdk: ^3.1.0 dependencies: collection: ^1.15.0 @@ -13,5 +13,5 @@ dependencies: term_glyph: ^1.2.0 dev_dependencies: - lints: ^2.0.0 + dart_flutter_team_lints: ^2.0.0 test: ^1.16.0 From 6a6f22d52cd0ac65af7ae8f7804404d03be3570d Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 4 Dec 2023 10:34:15 -0800 Subject: [PATCH 572/657] drop outdated lints (dart-lang/pub_semver#96) --- pkgs/pub_semver/analysis_options.yaml | 7 ------- pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index 210af85b9..01270cd05 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -13,27 +13,20 @@ linter: - avoid_classes_with_only_static_members - avoid_private_typedef_functions - avoid_redundant_argument_values - - avoid_returning_null - - avoid_returning_null_for_future - avoid_returning_this - avoid_unused_constructor_parameters - avoid_void_async - cancel_subscriptions - cascade_invocations - - comment_references - join_return_with_assignment - literal_only_boolean_expressions - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString - package_api_docs - - prefer_const_constructors - prefer_const_declarations - prefer_expression_function_bodies - - prefer_relative_imports - - test_types_in_equals - unnecessary_await_in_return - use_if_null_to_convert_nulls_to_bools - use_raw_strings - use_string_buffers - - use_super_parameters diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 72ffdfe28..9d23664d5 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -16,5 +16,5 @@ dependencies: meta: ^1.3.0 dev_dependencies: - dart_flutter_team_lints: ^1.0.0 + dart_flutter_team_lints: ^2.0.0 test: ^1.16.0 From b6943f4bd6bf20178569486fd885afc63575d62d Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 20 Dec 2023 09:57:23 -0800 Subject: [PATCH 573/657] blast_repo fixes (dart-lang/pool#78) no-response --- pkgs/pool/.github/workflows/no-response.yml | 35 +++++++++++---------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/pkgs/pool/.github/workflows/no-response.yml b/pkgs/pool/.github/workflows/no-response.yml index ac3e456ec..8e5ed57cd 100644 --- a/pkgs/pool/.github/workflows/no-response.yml +++ b/pkgs/pool/.github/workflows/no-response.yml @@ -1,12 +1,10 @@ # A workflow to close issues where the author hasn't responded to a request for -# more information; see https://github.com/godofredoc/no-response for docs. +# more information; see https://github.com/actions/stale. name: No Response -# Both `issue_comment` and `scheduled` event types are required. +# Run as a daily cron. on: - issue_comment: - types: [created] schedule: # Every day at 8am - cron: '0 8 * * *' @@ -14,21 +12,26 @@ on: # All permissions not specified are set to 'none'. permissions: issues: write + pull-requests: write jobs: - noResponse: + no-response: runs-on: ubuntu-latest if: ${{ github.repository_owner == 'dart-lang' }} steps: - - uses: godofredoc/no-response@0ce2dc0e63e1c7d2b87752ceed091f6d32c9df09 + - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 with: - responseRequiredLabel: "needs-info" - responseRequiredColor: 4774bc - daysUntilClose: 14 - # Comment to post when closing an Issue for lack of response. - closeComment: > - Without additional information we're not able to resolve this issue, - so it will be closed at this time. You're still free to add more - info and respond to any questions above, though. We'll reopen the - issue if you do. Thanks for your contribution! - token: ${{ github.token }} + # Don't automatically mark inactive issues+PRs as stale. + days-before-stale: -1 + # Close needs-info issues and PRs after 14 days of inactivity. + days-before-close: 14 + stale-issue-label: "needs-info" + close-issue-message: > + Without additional information we're not able to resolve this issue. + Feel free to add more info or respond to any questions above and we + can reopen the case. Thanks for your contribution! + stale-pr-label: "needs-info" + close-pr-message: > + Without additional information we're not able to resolve this PR. + Feel free to add more info or respond to any questions above. + Thanks for your contribution! From c6932a4a2b09760b71de189fbe59b8cd93883d94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 02:33:22 +0000 Subject: [PATCH 574/657] Bump actions/stale from 8.0.0 to 9.0.0 (dart-lang/pool#79) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/stale](https://github.com/actions/stale) from 8.0.0 to 9.0.0.
Release notes

Sourced from actions/stale's releases.

v9.0.0

Breaking Changes

  1. Action is now stateful: If the action ends because of operations-per-run then the next run will start from the first unprocessed issue skipping the issues processed during the previous run(s). The state is reset when all the issues are processed. This should be considered for scheduling workflow runs.
  2. Version 9 of this action updated the runtime to Node.js 20. All scripts are now run with Node.js 20 instead of Node.js 16 and are affected by any breaking changes between Node.js 16 and 20.

What Else Changed

  1. Performance optimization that removes unnecessary API calls by @​dsame dart-lang/pool#1033 fixes dart-lang/pool#792
  2. Logs displaying current github API rate limit by @​dsame dart-lang/pool#1032 addresses dart-lang/pool#1029

For more information, please read the action documentation and its section about statefulness

New Contributors

Full Changelog: https://github.com/actions/stale/compare/v8...v9.0.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/stale&package-manager=github_actions&previous-version=8.0.0&new-version=9.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/no-response.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/pool/.github/workflows/no-response.yml b/pkgs/pool/.github/workflows/no-response.yml index 8e5ed57cd..ab1ac4984 100644 --- a/pkgs/pool/.github/workflows/no-response.yml +++ b/pkgs/pool/.github/workflows/no-response.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository_owner == 'dart-lang' }} steps: - - uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 + - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e with: # Don't automatically mark inactive issues+PRs as stale. days-before-stale: -1 From a9396b06c4c4a2a32072962293ae4345d79201bf Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 10 Jan 2024 13:21:18 -0800 Subject: [PATCH 575/657] Update to latest lints, Require Dart 3.2 (dart-lang/package_config#145) --- .../.github/workflows/test-package.yml | 2 +- pkgs/package_config/CHANGELOG.md | 2 +- pkgs/package_config/lib/package_config.dart | 4 ++-- pkgs/package_config/lib/src/errors.dart | 9 ++++---- .../lib/src/package_config.dart | 8 +++---- .../lib/src/package_config_impl.dart | 13 +++-------- .../lib/src/package_config_io.dart | 2 +- .../lib/src/package_config_json.dart | 8 +++---- .../package_config/lib/src/packages_file.dart | 6 ----- pkgs/package_config/pubspec.yaml | 4 ++-- pkgs/package_config/test/discovery_test.dart | 22 ++++++++----------- .../test/discovery_uri_test.dart | 14 ++++++------ .../test/package_config_impl_test.dart | 2 +- pkgs/package_config/test/parse_test.dart | 4 ++-- pkgs/package_config/test/src/util.dart | 2 +- 15 files changed, 42 insertions(+), 60 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 2aa74dfe3..2e475912a 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [3.0.0, dev] + sdk: [3.2, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index d084d8514..a682bc3a4 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,6 +1,6 @@ ## 2.1.1-wip -- Require Dart 3.0 +- Require Dart 3.2 ## 2.1.0 diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index 8f40a8b65..194fe894e 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -102,7 +102,7 @@ Future loadPackageConfigUri(Uri file, /// then the parent directories are checked recursively, /// all the way to the root directory, to check if those contains /// a package configuration. -/// If [recurse] is set to [false], this parent directory check is not +/// If [recurse] is set to `false`, this parent directory check is not /// performed. /// /// If [onError] is provided, the configuration file parsing will report errors @@ -140,7 +140,7 @@ Future findPackageConfig(Directory directory, /// then the parent directories are checked recursively, /// all the way to the root directory, to check if those contains /// a package configuration. -/// If [recurse] is set to [false], this parent directory check is not +/// If [recurse] is set to `false`, this parent directory check is not /// performed. /// /// If [loader] is provided, URIs are loaded using that function. diff --git a/pkgs/package_config/lib/src/errors.dart b/pkgs/package_config/lib/src/errors.dart index 69c41370a..a66fef7f3 100644 --- a/pkgs/package_config/lib/src/errors.dart +++ b/pkgs/package_config/lib/src/errors.dart @@ -12,8 +12,9 @@ abstract class PackageConfigError { class PackageConfigArgumentError extends ArgumentError implements PackageConfigError { - PackageConfigArgumentError(Object? value, String name, String message) - : super.value(value, name, message); + PackageConfigArgumentError( + Object? super.value, String super.name, String super.message) + : super.value(); PackageConfigArgumentError.from(ArgumentError error) : super.value(error.invalidValue, error.name, error.message); @@ -21,8 +22,8 @@ class PackageConfigArgumentError extends ArgumentError class PackageConfigFormatException extends FormatException implements PackageConfigError { - PackageConfigFormatException(String message, Object? source, [int? offset]) - : super(message, source, offset); + PackageConfigFormatException(super.message, Object? super.source, + [super.offset]); PackageConfigFormatException.from(FormatException exception) : super(exception.message, exception.source, exception.offset); diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index ba52c147d..c00ac67af 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -32,7 +32,7 @@ abstract class PackageConfig { /// absolute directory URIs, valid language version, if any), /// and there must not be two packages with the same name. /// - /// The package's root ([Package.rootUri]) and package-root + /// The package's root ([Package.root]) and package-root /// ([Package.packageUriRoot]) paths must satisfy a number of constraints /// We say that one path (which we know ends with a `/` charater) /// is inside another path, if the latter path is a prefix of the former path, @@ -95,7 +95,7 @@ abstract class PackageConfig { /// Parses the JSON data of a package configuration file. /// - /// The [configuration] must be a JSON-like Dart data structure, + /// The [jsonData] must be a JSON-like Dart data structure, /// like the one provided by parsing JSON text using `dart:convert`, /// containing a valid package configuration. /// @@ -167,7 +167,7 @@ abstract class PackageConfig { /// Provides the associated package for a specific [file] (or directory). /// /// Returns a [Package] which contains the [file]'s path, if any. - /// That is, the [Package.rootUri] directory is a parent directory + /// That is, the [Package.root] directory is a parent directory /// of the [file]'s location. /// /// Returns `null` if the file does not belong to any package. @@ -247,7 +247,7 @@ abstract class Package { /// Is always an absolute URI with no query or fragment parts, /// and with a path ending in `/`. /// - /// All files in the [rootUri] directory are considered + /// All files in the [root] directory are considered /// part of the package for purposes where that that matters. Uri get root; diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index f832d6adf..d8e8d495f 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -141,12 +141,6 @@ class SimplePackageConfig implements PackageConfig { @override Package? operator [](String packageName) => _packages[packageName]; - /// Provides the associated package for a specific [file] (or directory). - /// - /// Returns a [Package] which contains the [file]'s path. - /// That is, the [Package.rootUri] directory is a parent directory - /// of the [file]'s location. - /// Returns `null` if the file does not belong to any package. @override Package? packageOf(Uri file) => _packageTree.packageOf(file); @@ -270,7 +264,7 @@ class SimplePackage implements Package { } } -/// Checks whether [version] is a valid Dart language version string. +/// Checks whether [source] is a valid Dart language version string. /// /// The format is (as RegExp) `^(0|[1-9]\d+)\.(0|[1-9]\d+)$`. /// @@ -553,9 +547,8 @@ enum ConflictType { sameRoots, interleaving, insidePackageRoot } /// Conflict between packages added to the same configuration. /// /// The [package] conflicts with [existingPackage] if it has -/// the same root path ([isRootConflict]) or the package URI root path -/// of [existingPackage] is inside the root path of [package] -/// ([isPackageRootConflict]). +/// the same root path or the package URI root path +/// of [existingPackage] is inside the root path of [package]. class ConflictException { /// The existing package that [package] conflicts with. final SimplePackage existingPackage; diff --git a/pkgs/package_config/lib/src/package_config_io.dart b/pkgs/package_config/lib/src/package_config_io.dart index 9aed621e0..8c5773b2b 100644 --- a/pkgs/package_config/lib/src/package_config_io.dart +++ b/pkgs/package_config/lib/src/package_config_io.dart @@ -38,7 +38,7 @@ const packagesFileName = '.packages'; /// If the [file] is a `.packages` file and [preferNewest] is true, /// first checks whether there is an adjacent `.dart_tool/package_config.json` /// file, and if so, reads that instead. -/// If [preferNewset] is false, the specified file is loaded even if it is +/// If [preferNewest] is false, the specified file is loaded even if it is /// a `.packages` file and there is an available `package_config.json` file. /// /// The file must exist and be a normal file. diff --git a/pkgs/package_config/lib/src/package_config_json.dart b/pkgs/package_config/lib/src/package_config_json.dart index 47e7e96b6..65560a0f0 100644 --- a/pkgs/package_config/lib/src/package_config_json.dart +++ b/pkgs/package_config/lib/src/package_config_json.dart @@ -75,10 +75,8 @@ PackageConfig parsePackageConfigString( /// where the integer numeral cannot have a sign, and can only have a /// leading zero if the entire numeral is a single zero. /// -/// All other properties are stored in [extraData]. -/// /// The [baseLocation] is used as base URI to resolve the "rootUri" -/// URI referencestring. +/// URI reference string. PackageConfig parsePackageConfigJson( Object? json, Uri baseLocation, void Function(Object error) onError) { if (!baseLocation.hasScheme || baseLocation.isScheme('package')) { @@ -93,7 +91,7 @@ PackageConfig parsePackageConfigJson( String typeName() { if (0 is T) return 'int'; if ('' is T) return 'string'; - if (const [] is T) return 'array'; + if (const [] is T) return 'array'; return 'object'; } @@ -239,7 +237,7 @@ void writePackageConfigJsonString( PackageConfig config, Uri? baseUri, StringSink output) { // Can be optimized. var data = packageConfigToJson(config, baseUri); - output.write(JsonEncoder.withIndent(' ').convert(data)); + output.write(const JsonEncoder.withIndent(' ').convert(data)); } Map packageConfigToJson(PackageConfig config, Uri? baseUri) => diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index 5d1467755..f84db1075 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -148,12 +148,6 @@ PackageConfig parse( /// /// If [baseUri] is provided, package locations will be made relative /// to the base URI, if possible, before writing. -/// -/// If [allowDefaultPackage] is `true`, the [packageMapping] may contain an -/// empty string mapping to the _default package name_. -/// -/// All the keys of [packageMapping] must be valid package names, -/// and the values must be URIs that do not have the `package:` scheme. void write(StringSink output, PackageConfig config, {Uri? baseUri, String? comment}) { if (baseUri != null && !baseUri.isAbsolute) { diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index e121ab033..b7130793f 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -4,7 +4,7 @@ description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/package_config environment: - sdk: ^3.0.0 + sdk: ^3.2.0 dependencies: path: ^1.8.0 @@ -13,5 +13,5 @@ dev_dependencies: build_runner: ^2.0.0 build_test: ^2.1.2 build_web_compilers: ^4.0.0 - dart_flutter_team_lints: ^1.0.0 + dart_flutter_team_lints: ^2.0.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 3eb0ea153..ee77559b1 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -59,7 +59,7 @@ void main() { fileTest('package_config.json', { '.packages': 'invalid .packages file', 'script.dart': 'main(){}', - 'packages': {'shouldNotBeFound': {}}, + 'packages': {'shouldNotBeFound': {}}, '.dart_tool': { 'package_config.json': packageConfigFile, } @@ -73,7 +73,7 @@ void main() { fileTest('.packages', { '.packages': packagesFile, 'script.dart': 'main(){}', - 'packages': {'shouldNotBeFound': {}} + 'packages': {'shouldNotBeFound': {}} }, (Directory directory) async { var config = (await findPackageConfig(directory))!; expect(config.version, 1); // Found .packages file. @@ -108,7 +108,7 @@ void main() { // Does not find a packages/ directory, and returns null if nothing found. fileTest('package directory packages not supported', { 'packages': { - 'foo': {}, + 'foo': {}, } }, (Directory directory) async { var config = await findPackageConfig(directory); @@ -119,15 +119,13 @@ void main() { fileTest('invalid .packages', { '.packages': 'not a .packages file', }, (Directory directory) { - expect(findPackageConfig(directory), - throwsA(TypeMatcher())); + expect(findPackageConfig(directory), throwsA(isA())); }); fileTest('invalid .packages as JSON', { '.packages': packageConfigFile, }, (Directory directory) { - expect(findPackageConfig(directory), - throwsA(TypeMatcher())); + expect(findPackageConfig(directory), throwsA(isA())); }); fileTest('invalid .packages', { @@ -135,8 +133,7 @@ void main() { 'package_config.json': 'not a JSON file', } }, (Directory directory) { - expect(findPackageConfig(directory), - throwsA(TypeMatcher())); + expect(findPackageConfig(directory), throwsA(isA())); }); fileTest('invalid .packages as INI', { @@ -144,8 +141,7 @@ void main() { 'package_config.json': packagesFile, } }, (Directory directory) { - expect(findPackageConfig(directory), - throwsA(TypeMatcher())); + expect(findPackageConfig(directory), throwsA(isA())); }); }); @@ -304,8 +300,8 @@ void main() { fileTest('no config found', {}, (Directory directory) { var file = dirFile(directory, 'anyname'); - expect(() => loadPackageConfig(file), - throwsA(TypeMatcher())); + expect( + () => loadPackageConfig(file), throwsA(isA())); }); fileTest('no config found, handled', {}, (Directory directory) async { diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index c8fbcb87c..b71ed5172 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -56,7 +56,7 @@ void main() { loaderTest('package_config.json', { '.packages': 'invalid .packages file', 'script.dart': 'main(){}', - 'packages': {'shouldNotBeFound': {}}, + 'packages': {'shouldNotBeFound': {}}, '.dart_tool': { 'package_config.json': packageConfigFile, } @@ -70,7 +70,7 @@ void main() { loaderTest('.packages', { '.packages': packagesFile, 'script.dart': 'main(){}', - 'packages': {'shouldNotBeFound': {}} + 'packages': {'shouldNotBeFound': {}} }, (directory, loader) async { var config = (await findPackageConfigUri(directory, loader: loader))!; expect(config.version, 1); // Found .packages file. @@ -107,7 +107,7 @@ void main() { // Does not find a packages/ directory, and returns null if nothing found. loaderTest('package directory packages not supported', { 'packages': { - 'foo': {}, + 'foo': {}, } }, (Uri directory, loader) async { var config = await findPackageConfigUri(directory, loader: loader); @@ -118,14 +118,14 @@ void main() { '.packages': 'not a .packages file', }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), - throwsA(TypeMatcher())); + throwsA(isA())); }); loaderTest('invalid .packages as JSON', { '.packages': packageConfigFile, }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), - throwsA(TypeMatcher())); + throwsA(isA())); }); loaderTest('invalid .packages', { @@ -134,7 +134,7 @@ void main() { } }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), - throwsA(TypeMatcher())); + throwsA(isA())); }); loaderTest('invalid .packages as INI', { @@ -143,7 +143,7 @@ void main() { } }, (Uri directory, loader) { expect(() => findPackageConfigUri(directory, loader: loader), - throwsA(TypeMatcher())); + throwsA(isA())); }); // Does not find .packages if no package_config.json and minVersion > 1. diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index cef121713..87d1fd413 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -36,7 +36,7 @@ void main() { void failParse(String name, String input) { test('$name - error', () { expect(() => LanguageVersion.parse(input), - throwsA(TypeMatcher())); + throwsA(isA())); expect(() => LanguageVersion.parse(input), throwsFormatException); var failed = false; var actual = LanguageVersion.parse(input, onError: (_) { diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index ad4c74949..402fe8c42 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -53,7 +53,7 @@ void main() { test(name, () { expect( () => packages.parse(utf8.encode(content), baseFile, throwError), - throwsA(TypeMatcher())); + throwsA(isA())); }); test('$name, handle error', () { var hadError = false; @@ -308,7 +308,7 @@ void main() { // ignore: unnecessary_cast () => parsePackageConfigBytes(utf8.encode(source) as Uint8List, Uri.parse('file:///tmp/.dart_tool/file.dart'), throwError), - throwsA(TypeMatcher())); + throwsA(isA())); }); } diff --git a/pkgs/package_config/test/src/util.dart b/pkgs/package_config/test/src/util.dart index 246e12964..780ee80dc 100644 --- a/pkgs/package_config/test/src/util.dart +++ b/pkgs/package_config/test/src/util.dart @@ -28,7 +28,7 @@ ${packages.map((nu) => """ } """; -/// Mimics a directory structure of [description] and runs [fileTest]. +/// Mimics a directory structure of [description] and runs [loaderTest]. /// /// Description is a map, each key is a file entry. If the value is a map, /// it's a subdirectory, otherwise it's a file and the value is the content From 936e0cfb559180537679e56a46bb59b07f57e83c Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Wed, 10 Jan 2024 14:51:25 -0800 Subject: [PATCH 576/657] add test validating current behavior of packageOf, run CI on windows (dart-lang/package_config#137) - validates the behavior of https://github.com/dart-lang/package_config/issues/136 today (but does not change it) - removes build_runner deps for testing, there is no need to use it for such a small package - fixes a bug in discovery_test.dart that was probably landed due to inability to run tests --- .../.github/workflows/test-package.yml | 5 ++--- pkgs/package_config/pubspec.yaml | 3 --- pkgs/package_config/test/discovery_test.dart | 2 +- pkgs/package_config/test/parse_test.dart | 19 +++++++++++++++++++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 2e475912a..1768fc834 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -45,8 +45,7 @@ jobs: strategy: fail-fast: false matrix: - # Add macos-latest and/or windows-latest if relevant for this package. - os: [ubuntu-latest] + os: [ubuntu-latest, windows-latest] sdk: [3.2, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 @@ -57,5 +56,5 @@ jobs: name: Install dependencies run: dart pub get - name: Run tests - run: dart run build_runner test -- -p chrome,vm + run: dart test -p chrome,vm if: always() && steps.install.outcome == 'success' diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index b7130793f..6ac7f54dd 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -10,8 +10,5 @@ dependencies: path: ^1.8.0 dev_dependencies: - build_runner: ^2.0.0 - build_test: ^2.1.2 - build_web_compilers: ^4.0.0 dart_flutter_team_lints: ^2.0.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index ee77559b1..2ca337a19 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -59,7 +59,7 @@ void main() { fileTest('package_config.json', { '.packages': 'invalid .packages file', 'script.dart': 'main(){}', - 'packages': {'shouldNotBeFound': {}}, + 'packages': {'shouldNotBeFound': {}}, '.dart_tool': { 'package_config.json': packageConfigFile, } diff --git a/pkgs/package_config/test/parse_test.dart b/pkgs/package_config/test/parse_test.dart index 402fe8c42..a92b9bfcc 100644 --- a/pkgs/package_config/test/parse_test.dart +++ b/pkgs/package_config/test/parse_test.dart @@ -301,6 +301,25 @@ void main() { Uri.parse('package:qux/diz')); }); + test('packageOf is case sensitive on windows', () { + var configBytes = utf8.encode(json.encode({ + 'configVersion': 2, + 'packages': [ + {'name': 'foo', 'rootUri': 'file:///C:/Foo/', 'packageUri': 'lib/'}, + ] + })); + var config = parsePackageConfigBytes( + // ignore: unnecessary_cast + configBytes as Uint8List, + Uri.parse('file:///C:/tmp/.dart_tool/file.dart'), + throwError); + expect(config.version, 2); + expect( + config.packageOf(Uri.parse('file:///C:/foo/lala/lala.dart')), null); + expect(config.packageOf(Uri.parse('file:///C:/Foo/lala/lala.dart'))!.name, + 'foo'); + }); + group('invalid', () { void testThrows(String name, String source) { test(name, () { From bd7c82be9b454b8bb44a7eef88e74bc4a49fa545 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 02:59:18 +0000 Subject: [PATCH 577/657] Bump dart-lang/setup-dart from 1.6.0 to 1.6.2 (dart-lang/pool#80) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.0 to 1.6.2.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available in an environment variable, DART_HOME (dart-lang/pool#43).
  • Fixed an issue where cached downloads could lead to unzip issues on self-hosted runners (dart-lang/pool#35).

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.0&new-version=1.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index b69f2bd51..23167a398 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install From 7dd06254eb67095a0e15ffe8438e38f88865bb7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:28:03 +0000 Subject: [PATCH 578/657] Bump dart-lang/setup-dart from 1.6.0 to 1.6.2 (dart-lang/pub_semver#98) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.0 to 1.6.2.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available in an environment variable, DART_HOME (dart-lang/pub_semver#43).
  • Fixed an issue where cached downloads could lead to unzip issues on self-hosted runners (dart-lang/pub_semver#35).

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.0&new-version=1.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 4cb7d3a73..4e4e97d8d 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install From 035d7abf765c68e88ac9263304d687aeb27beb0d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:25:16 +0000 Subject: [PATCH 579/657] Bump dart-lang/setup-dart from 1.6.0 to 1.6.2 (dart-lang/source_span#107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.0 to 1.6.2.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.0&new-version=1.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 77ba45b39..b98d276c3 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.1.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install From 07f93debcd8accc838b2cfa7858f9f87b625d4da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:46:57 +0000 Subject: [PATCH 580/657] Bump dart-lang/setup-dart from 1.6.0 to 1.6.2 (dart-lang/source_maps#86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.0 to 1.6.2.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.0&new-version=1.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 38ced1a4f..84cd3ea5c 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install From 935c91e7617aaf72d8df1471400cb5c8eb52a6d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 20:17:20 +0000 Subject: [PATCH 581/657] Bump dart-lang/setup-dart from 1.6.0 to 1.6.2 (dart-lang/package_config#146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.0 to 1.6.2.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

v1.2.0

  • Fixed a path issue impacting git dependencies on Windows.

v1.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.0&new-version=1.6.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 1768fc834..0fdbdeaf4 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,7 +49,7 @@ jobs: sdk: [3.2, dev] steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 - - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d + - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} - id: install From ec8a37c1468cfeec2b5c71217e29b1bfd89812f5 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Wed, 28 Feb 2024 11:39:40 -0800 Subject: [PATCH 582/657] Latest lints, test wasm on dev channel (dart-lang/pool#81) --- pkgs/pool/.github/workflows/ci.yml | 3 + pkgs/pool/lib/pool.dart | 35 ++++++------ pkgs/pool/pubspec.yaml | 2 +- pkgs/pool/test/pool_test.dart | 88 +++++++++++++++--------------- 4 files changed, 67 insertions(+), 61 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 23167a398..d8339569b 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -62,3 +62,6 @@ jobs: - name: Run Chrome tests run: dart test --platform chrome if: always() && steps.install.outcome == 'success' + - name: Run Chrome tests - wasm + run: dart test --platform chrome -c dart2wasm + if: always() && steps.install.outcome == 'success' && matrix.sdk == 'dev' diff --git a/pkgs/pool/lib/pool.dart b/pkgs/pool/lib/pool.dart index 20ab8f181..70e9df158 100644 --- a/pkgs/pool/lib/pool.dart +++ b/pkgs/pool/lib/pool.dart @@ -239,23 +239,26 @@ class Pool { /// an error, the returned future completes with that error. /// /// This may be called more than once; it returns the same [Future] each time. - Future close() => _closeMemo.runOnce(() { - if (_closeGroup != null) return _closeGroup!.future; + Future close() => _closeMemo.runOnce(_close); - _resetTimer(); + Future _close() { + if (_closeGroup != null) return _closeGroup!.future; - _closeGroup = FutureGroup(); - for (var callback in _onReleaseCallbacks) { - _closeGroup!.add(Future.sync(callback)); - } + _resetTimer(); - _allocatedResources -= _onReleaseCallbacks.length; - _onReleaseCallbacks.clear(); + _closeGroup = FutureGroup(); + for (var callback in _onReleaseCallbacks) { + _closeGroup!.add(Future.sync(callback)); + } + + _allocatedResources -= _onReleaseCallbacks.length; + _onReleaseCallbacks.clear(); + + if (_allocatedResources == 0) _closeGroup!.close(); + return _closeGroup!.future; + } - if (_allocatedResources == 0) _closeGroup!.close(); - return _closeGroup!.future; - }); - final _closeMemo = AsyncMemoizer(); + final _closeMemo = AsyncMemoizer(); /// If there are any pending requests, this will fire the oldest one. void _onResourceReleased() { @@ -272,7 +275,7 @@ class Pool { /// If there are any pending requests, this will fire the oldest one after /// running [onRelease]. - void _onResourceReleaseAllowed(Function() onRelease) { + void _onResourceReleaseAllowed(void Function() onRelease) { _resetTimer(); if (_requestedResources.isNotEmpty) { @@ -294,7 +297,7 @@ class Pool { /// /// Futures returned by [_runOnRelease] always complete in the order they were /// created, even if earlier [onRelease] callbacks take longer to run. - Future _runOnRelease(Function() onRelease) { + Future _runOnRelease(void Function() onRelease) { Future.sync(onRelease).then((value) { _onReleaseCompleters.removeFirst().complete(PoolResource._(this)); }).catchError((Object error, StackTrace stackTrace) { @@ -367,7 +370,7 @@ class PoolResource { /// This is useful when a resource's main function is complete, but it may /// produce additional information later on. For example, an isolate's task /// may be complete, but it could still emit asynchronous errors. - void allowRelease(Function() onRelease) { + void allowRelease(FutureOr Function() onRelease) { if (_released) { throw StateError('A PoolResource may only be released once.'); } diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 08e4027a9..7fb5021d3 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -13,6 +13,6 @@ dependencies: stack_trace: ^1.10.0 dev_dependencies: - dart_flutter_team_lints: ^1.0.0 + dart_flutter_team_lints: ^2.0.0 fake_async: ^1.2.0 test: ^1.16.0 diff --git a/pkgs/pool/test/pool_test.dart b/pkgs/pool/test/pool_test.dart index 2dd90f4a5..6334a8abd 100644 --- a/pkgs/pool/test/pool_test.dart +++ b/pkgs/pool/test/pool_test.dart @@ -41,7 +41,7 @@ void main() { // This will only complete once [lastAllocatedResource] is released. expect(pool.request(), completes); - Future.delayed(const Duration(microseconds: 1)).then((_) { + Future.delayed(const Duration(microseconds: 1)).then((_) { lastAllocatedResource.release(); }); }); @@ -55,7 +55,7 @@ void main() { test('can be called freely up to the limit', () { var pool = Pool(50); for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync0(() => Completer().future)); + pool.withResource(expectAsync0(() => Completer().future)); } }); @@ -63,7 +63,7 @@ void main() { FakeAsync().run((async) { var pool = Pool(50); for (var i = 0; i < 50; i++) { - pool.withResource(expectAsync0(() => Completer().future)); + pool.withResource(expectAsync0(() => Completer().future)); } pool.withResource(expectNoAsync()); @@ -75,20 +75,20 @@ void main() { FakeAsync().run((async) { var pool = Pool(50); for (var i = 0; i < 49; i++) { - pool.withResource(expectAsync0(() => Completer().future)); + pool.withResource(expectAsync0(() => Completer().future)); } - var completer = Completer(); + var completer = Completer(); pool.withResource(() => completer.future); var blockedResourceAllocated = false; pool.withResource(() { blockedResourceAllocated = true; }); - Future.delayed(const Duration(microseconds: 1)).then((_) { + Future.delayed(const Duration(microseconds: 1)).then((_) { expect(blockedResourceAllocated, isFalse); completer.complete(); - return Future.delayed(const Duration(microseconds: 1)); + return Future.delayed(const Duration(microseconds: 1)); }).then((_) { expect(blockedResourceAllocated, isTrue); }); @@ -128,7 +128,7 @@ void main() { // This will only complete once [lastAllocatedResource] is released. expect(pool.request(), completes); - Future.delayed(const Duration(seconds: 3)).then((_) { + Future.delayed(const Duration(seconds: 3)).then((_) { lastAllocatedResource.release(); expect(pool.request(), doesNotComplete); }); @@ -146,7 +146,7 @@ void main() { } expect(pool.request(), doesNotComplete); - Future.delayed(const Duration(seconds: 3)).then((_) { + Future.delayed(const Duration(seconds: 3)).then((_) { expect(pool.request(), doesNotComplete); }); @@ -177,11 +177,11 @@ void main() { var resource = await pool.request(); var onReleaseCalled = false; resource.allowRelease(() => onReleaseCalled = true); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onReleaseCalled, isFalse); expect(pool.request(), completes); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onReleaseCalled, isTrue); }); @@ -195,7 +195,7 @@ void main() { var onReleaseCalled = false; resource.allowRelease(() => onReleaseCalled = true); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onReleaseCalled, isTrue); }); @@ -206,13 +206,13 @@ void main() { var requestComplete = false; unawaited(pool.request().then((_) => requestComplete = true)); - var completer = Completer(); + var completer = Completer(); resource.allowRelease(() => completer.future); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(requestComplete, isFalse); completer.complete(); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(requestComplete, isTrue); }); @@ -228,21 +228,21 @@ void main() { unawaited(pool.request().then((_) => request2Complete = true)); var onRelease1Called = false; - var completer1 = Completer(); + var completer1 = Completer(); resource1.allowRelease(() { onRelease1Called = true; return completer1.future; }); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onRelease1Called, isTrue); var onRelease2Called = false; - var completer2 = Completer(); + var completer2 = Completer(); resource2.allowRelease(() { onRelease2Called = true; return completer2.future; }); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(onRelease2Called, isTrue); expect(request1Complete, isFalse); expect(request2Complete, isFalse); @@ -251,12 +251,12 @@ void main() { // was triggered by the second blocking request, it should complete the // first one to preserve ordering. completer2.complete(); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(request1Complete, isTrue); expect(request2Complete, isFalse); completer1.complete(); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); expect(request1Complete, isTrue); expect(request2Complete, isTrue); }); @@ -286,7 +286,7 @@ void main() { var resource = await pool.request(); resource.release(); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); }); group('close()', () { @@ -313,7 +313,7 @@ void main() { var pool = Pool(1); var resource1 = await pool.request(); - var completer = Completer(); + var completer = Completer(); expect( pool.request().then((resource2) { expect(completer.isCompleted, isTrue); @@ -323,7 +323,7 @@ void main() { expect(pool.close(), completes); resource1.allowRelease(() => completer.future); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.complete(); }); @@ -347,11 +347,11 @@ void main() { resource1Released = true; resource1.release(); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); resource2Released = true; resource2.release(); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); var resource3 = await resource3Future; resource3Released = true; @@ -364,7 +364,7 @@ void main() { // Set up an onRelease callback whose completion is controlled by // [completer]. - var completer = Completer(); + var completer = Completer(); resource.allowRelease(() => completer.future); expect( pool.request().then((_) { @@ -372,10 +372,10 @@ void main() { }), completes); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); unawaited(pool.close()); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.complete(); }); @@ -384,9 +384,9 @@ void main() { var resource1 = await pool.request(); var resource2 = await pool.request(); - var completer1 = Completer(); + var completer1 = Completer(); resource1.allowRelease(() => completer1.future); - var completer2 = Completer(); + var completer2 = Completer(); resource2.allowRelease(() => completer2.future); expect( @@ -396,10 +396,10 @@ void main() { }), completes); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer1.complete(); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer2.complete(); }); @@ -407,17 +407,17 @@ void main() { var pool = Pool(1); var resource = await pool.request(); - var completer = Completer(); + var completer = Completer(); expect( pool.close().then((_) { expect(completer.isCompleted, isTrue); }), completes); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); resource.allowRelease(() => completer.future); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.complete(); }); @@ -425,13 +425,13 @@ void main() { var pool = Pool(1); var resource = await pool.request(); - var completer = Completer(); + var completer = Completer(); resource.allowRelease(() => completer.future); expect(pool.done, throwsA('oh no!')); expect(pool.close(), throwsA('oh no!')); - await Future.delayed(Duration.zero); + await Future.delayed(Duration.zero); completer.completeError('oh no!'); }); }); @@ -446,7 +446,7 @@ void main() { const delayedToStringDuration = Duration(milliseconds: 10); Future delayedToString(int i) => - Future.delayed(delayedToStringDuration, () => i.toString()); + Future.delayed(delayedToStringDuration, () => i.toString()); for (var itemCount in [0, 5]) { for (var poolSize in [1, 5, 6]) { @@ -505,7 +505,7 @@ void main() { 'before the entire iterable is iterated.'); return i; }), (i) async { - await Future.delayed(Duration(milliseconds: i)); + await Future.delayed(Duration(milliseconds: i)); return i; }); @@ -585,7 +585,7 @@ void main() { pool.close(); }); - await subscription.asFuture(); + await subscription.asFuture(); expect(dataCount, 100); await subscription.cancel(); }); @@ -616,7 +616,7 @@ void main() { if (int.parse(data) % 3 == 1) { subscription.pause(Future(() async { - await Future.delayed(const Duration(milliseconds: 100)); + await Future.delayed(const Duration(milliseconds: 100)); })); } }, @@ -690,7 +690,7 @@ void main() { pool = Pool(20); var listFuture = pool.forEach(Iterable.generate(100), (i) async { - await Future.delayed(const Duration(milliseconds: 10)); + await Future.delayed(const Duration(milliseconds: 10)); if (i == 10) { throw UnsupportedError('10 is not supported'); } @@ -705,7 +705,7 @@ void main() { var list = await pool.forEach(Iterable.generate(100), (int i) async { - await Future.delayed(const Duration(milliseconds: 10)); + await Future.delayed(const Duration(milliseconds: 10)); if (i % 10 == 0) { throw UnsupportedError('Multiples of 10 not supported'); } From bff0401456cb06981c345e875ecd370be66c302a Mon Sep 17 00:00:00 2001 From: Michael Thomsen Date: Tue, 5 Mar 2024 01:20:14 +0100 Subject: [PATCH 583/657] Fix typo (dart-lang/package_config#149) --- pkgs/package_config/lib/src/package_config.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index c00ac67af..048555fc1 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -26,7 +26,7 @@ abstract class PackageConfig { /// is expected, but none have been specified or found. static const PackageConfig empty = SimplePackageConfig.empty(); - /// Creats a package configuration with the provided available [packages]. + /// Creates a package configuration with the provided available [packages]. /// /// The packages must be valid packages (valid package name, valid /// absolute directory URIs, valid language version, if any), From 0bc41a970f77296d99cfe435edf16545e69fa069 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 02:59:29 +0000 Subject: [PATCH 584/657] Bump actions/checkout from 4.1.1 to 4.1.2 (dart-lang/pool#82) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
Release notes

Sourced from actions/checkout's releases.

v4.1.2

We are investigating the following issue with this release and have rolled-back the v4 tag to point to v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.1...v4.1.2

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index d8339569b..7d9adb67b 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From c935922faac33286bbd669d2536bbe109b418c6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:53:28 +0000 Subject: [PATCH 585/657] Bump actions/checkout from 4.1.1 to 4.1.2 (dart-lang/pub_semver#99) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
Release notes

Sourced from actions/checkout's releases.

v4.1.2

We are investigating the following issue with this release and have rolled-back the v4 tag to point to v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.1...v4.1.2

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 4e4e97d8d..8f1b1a691 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From 72bd3fb9f7849f42211742a962520092c0eca050 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 17:17:50 +0000 Subject: [PATCH 586/657] Bump actions/checkout from 4.1.1 to 4.1.2 (dart-lang/source_span#108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
Release notes

Sourced from actions/checkout's releases.

v4.1.2

We are investigating the following issue with this release and have rolled-back the v4 tag to point to v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.1...v4.1.2

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index b98d276c3..7ffd87247 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From d8dfdf346b09787f26f45db95947ceb50750f82a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 17:44:12 +0000 Subject: [PATCH 587/657] Bump actions/checkout from 4.1.1 to 4.1.2 (dart-lang/source_maps#87) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
Release notes

Sourced from actions/checkout's releases.

v4.1.2

We are investigating the following issue with this release and have rolled-back the v4 tag to point to v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.1...v4.1.2

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 84cd3ea5c..3e522b91d 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From b9ca0553113924fffba7b6d8b2879e775d3ce5e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:35:07 +0000 Subject: [PATCH 588/657] Bump actions/checkout from 4.1.1 to 4.1.2 (dart-lang/package_config#150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.2.
Release notes

Sourced from actions/checkout's releases.

v4.1.2

We are investigating the following issue with this release and have rolled-back the v4 tag to point to v4.1.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.1...v4.1.2

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

v3.3.0

v3.2.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=4.1.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 0fdbdeaf4..88c5dffee 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -48,7 +48,7 @@ jobs: os: [ubuntu-latest, windows-latest] sdk: [3.2, dev] steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From c1e39ed29d384702f9fa928f0b4951db905320ae Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 9 Apr 2024 14:03:20 -0700 Subject: [PATCH 589/657] Bump lints, require Dart 3.3 (dart-lang/source_maps#88) --- .../.github/workflows/test-package.yml | 2 +- pkgs/source_maps/CHANGELOG.md | 2 +- pkgs/source_maps/lib/parser.dart | 17 +++++++++-------- pkgs/source_maps/lib/src/source_map_span.dart | 5 ++--- pkgs/source_maps/pubspec.yaml | 4 ++-- pkgs/source_maps/test/parser_test.dart | 3 +++ 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 3e522b91d..ed86d8fcd 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [3.0.0, dev] + sdk: [3.3.0, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 5afbb6c53..9c8e7b37e 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.10.13-wip -- Require Dart 3.0 +- Require Dart 3.3 ## 0.10.12 diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart index 701a63f1c..b699ac728 100644 --- a/pkgs/source_maps/lib/parser.dart +++ b/pkgs/source_maps/lib/parser.dart @@ -66,7 +66,7 @@ Mapping parseJson(Map map, if (map.containsKey('mappings') || map.containsKey('sources') || map.containsKey('names')) { - throw FormatException('map containing "sections" ' + throw const FormatException('map containing "sections" ' 'cannot contain "mappings", "sources", or "names".'); } return MultiSectionMapping.fromJson(map['sections'] as List, otherMaps, @@ -110,13 +110,13 @@ class MultiSectionMapping extends Mapping { {/*String|Uri*/ Object? mapUrl}) { for (var section in sections.cast()) { var offset = section['offset'] as Map?; - if (offset == null) throw FormatException('section missing offset'); + if (offset == null) throw const FormatException('section missing offset'); var line = offset['line'] as int?; - if (line == null) throw FormatException('offset missing line'); + if (line == null) throw const FormatException('offset missing line'); var column = offset['column'] as int?; - if (column == null) throw FormatException('offset missing column'); + if (column == null) throw const FormatException('offset missing column'); _lineStart.add(line); _columnStart.add(column); @@ -125,7 +125,8 @@ class MultiSectionMapping extends Mapping { var map = section['map'] as Map?; if (url != null && map != null) { - throw FormatException("section can't use both url and map entries"); + throw const FormatException( + "section can't use both url and map entries"); } else if (url != null) { var other = otherMaps?[url]; if (otherMaps == null || other == null) { @@ -137,11 +138,11 @@ class MultiSectionMapping extends Mapping { } else if (map != null) { _maps.add(parseJson(map, otherMaps: otherMaps, mapUrl: mapUrl)); } else { - throw FormatException('section missing url or map'); + throw const FormatException('section missing url or map'); } } if (_lineStart.isEmpty) { - throw FormatException('expected at least one section'); + throw const FormatException('expected at least one section'); } } @@ -342,7 +343,7 @@ class SingleMapping extends Mapping { urls.keys.toList(), names.keys.toList(), lines); } - SingleMapping.fromJson(Map map, {mapUrl}) + SingleMapping.fromJson(Map map, {Object? mapUrl}) : targetUrl = map['file'] as String?, urls = List.from(map['sources'] as List), names = List.from((map['names'] as List?) ?? []), diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart index 8ca12b96f..aad8a32c6 100644 --- a/pkgs/source_maps/lib/src/source_map_span.dart +++ b/pkgs/source_maps/lib/src/source_map_span.dart @@ -14,9 +14,8 @@ class SourceMapSpan extends SourceSpanBase { /// If this is `true`, [text] is the value of the identifier. final bool isIdentifier; - SourceMapSpan(SourceLocation start, SourceLocation end, String text, - {this.isIdentifier = false}) - : super(start, end, text); + SourceMapSpan(super.start, super.end, super.text, + {this.isIdentifier = false}); /// Creates a [SourceMapSpan] for an identifier with value [text] starting at /// [start]. diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 4180b8d72..fcc99252a 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -4,12 +4,12 @@ description: A library to programmatically manipulate source map files. repository: https://github.com/dart-lang/source_maps environment: - sdk: ^3.0.0 + sdk: ^3.3.0 dependencies: source_span: ^1.8.0 dev_dependencies: - dart_flutter_team_lints: ^1.0.0 + dart_flutter_team_lints: ^2.0.0 term_glyph: ^1.2.0 test: ^1.16.0 diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart index cf320b6ef..6cfe928f2 100644 --- a/pkgs/source_maps/test/parser_test.dart +++ b/pkgs/source_maps/test/parser_test.dart @@ -2,6 +2,9 @@ // 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. +// ignore_for_file: inference_failure_on_collection_literal +// ignore_for_file: inference_failure_on_instance_creation + import 'dart:convert'; import 'package:source_maps/source_maps.dart'; From e7f1750b1b6f2aedbc4f3481f8ffe49eceb1c6bd Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 9 Apr 2024 14:37:59 -0700 Subject: [PATCH 590/657] blast_repo fixes (dart-lang/source_maps#89) auto-publish, github-actions, no-response --- .../.github/workflows/no-response.yml | 37 +++++++++++++++++++ .../.github/workflows/publish.yaml | 5 ++- .../.github/workflows/test-package.yml | 4 +- 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 pkgs/source_maps/.github/workflows/no-response.yml diff --git a/pkgs/source_maps/.github/workflows/no-response.yml b/pkgs/source_maps/.github/workflows/no-response.yml new file mode 100644 index 000000000..ab1ac4984 --- /dev/null +++ b/pkgs/source_maps/.github/workflows/no-response.yml @@ -0,0 +1,37 @@ +# A workflow to close issues where the author hasn't responded to a request for +# more information; see https://github.com/actions/stale. + +name: No Response + +# Run as a daily cron. +on: + schedule: + # Every day at 8am + - cron: '0 8 * * *' + +# All permissions not specified are set to 'none'. +permissions: + issues: write + pull-requests: write + +jobs: + no-response: + runs-on: ubuntu-latest + if: ${{ github.repository_owner == 'dart-lang' }} + steps: + - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e + with: + # Don't automatically mark inactive issues+PRs as stale. + days-before-stale: -1 + # Close needs-info issues and PRs after 14 days of inactivity. + days-before-close: 14 + stale-issue-label: "needs-info" + close-issue-message: > + Without additional information we're not able to resolve this issue. + Feel free to add more info or respond to any questions above and we + can reopen the case. Thanks for your contribution! + stale-pr-label: "needs-info" + close-pr-message: > + Without additional information we're not able to resolve this PR. + Feel free to add more info or respond to any questions above. + Thanks for your contribution! diff --git a/pkgs/source_maps/.github/workflows/publish.yaml b/pkgs/source_maps/.github/workflows/publish.yaml index fcb7ccb89..27157a046 100644 --- a/pkgs/source_maps/.github/workflows/publish.yaml +++ b/pkgs/source_maps/.github/workflows/publish.yaml @@ -6,9 +6,12 @@ on: pull_request: branches: [ master ] push: - tags: [ 'v[0-9]+.[0-9]+.[0-9]+*' ] + tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] jobs: publish: if: ${{ github.repository_owner == 'dart-lang' }} uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main + permissions: + id-token: write # Required for authentication using OIDC + pull-requests: write # Required for writing the pull request note diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index ed86d8fcd..303cc0567 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@65c82982aa686933bf10d50aced7a27b2b63f2a6 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.3.0, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@65c82982aa686933bf10d50aced7a27b2b63f2a6 with: sdk: ${{ matrix.sdk }} - id: install From 84b8800af21e24663d24dfab239d5cac4fbe2984 Mon Sep 17 00:00:00 2001 From: "Lasse R.H. Nielsen" Date: Thu, 11 Apr 2024 08:56:47 +0200 Subject: [PATCH 591/657] Fix typos. (dart-lang/package_config#147) The wonders of in-IDE spell checking. Also ask for newest lints (no changes needed). --- pkgs/package_config/CHANGELOG.md | 2 +- pkgs/package_config/lib/src/discovery.dart | 8 ++++---- pkgs/package_config/lib/src/package_config.dart | 6 +++--- pkgs/package_config/lib/src/package_config_impl.dart | 2 +- pkgs/package_config/lib/src/packages_file.dart | 2 +- pkgs/package_config/lib/src/util.dart | 2 +- pkgs/package_config/pubspec.yaml | 2 +- pkgs/package_config/test/package_config_impl_test.dart | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index a682bc3a4..2870c8c08 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -53,7 +53,7 @@ - Based on new JSON file format with more content. - This version includes all the new functionality intended for a 2.0.0 version, as well as the, now deprecated, version 1 functionality. - When we release 2.0.0, the deprectated functionality will be removed. + When we release 2.0.0, the deprecated functionality will be removed. ## 1.1.0 diff --git a/pkgs/package_config/lib/src/discovery.dart b/pkgs/package_config/lib/src/discovery.dart index 352bed8ca..b67841099 100644 --- a/pkgs/package_config/lib/src/discovery.dart +++ b/pkgs/package_config/lib/src/discovery.dart @@ -33,7 +33,7 @@ final Uri parentPath = Uri(path: '..'); /// Returns `null` if no configuration was found. If a configuration /// is needed, then the caller can supply [PackageConfig.empty]. /// -/// If [minVersion] is greated than 1, `.packages` files are ignored. +/// If [minVersion] is greater than 1, `.packages` files are ignored. /// If [minVersion] is greater than the version read from the /// `package_config.json` file, it too is ignored. Future findPackageConfig(Directory baseDirectory, @@ -46,7 +46,7 @@ Future findPackageConfig(Directory baseDirectory, do { // Check for $cwd/.packages var packageConfig = - await findPackagConfigInDirectory(directory, minVersion, onError); + await findPackageConfigInDirectory(directory, minVersion, onError); if (packageConfig != null) return packageConfig; if (!recursive) break; // Check in parent directories. @@ -113,10 +113,10 @@ Future findPackageConfigUri( /// a best-effort attempt is made to return a package configuration. /// This may be the empty package configuration. /// -/// If [minVersion] is greated than 1, `.packages` files are ignored. +/// If [minVersion] is greater than 1, `.packages` files are ignored. /// If [minVersion] is greater than the version read from the /// `package_config.json` file, it too is ignored. -Future findPackagConfigInDirectory(Directory directory, +Future findPackageConfigInDirectory(Directory directory, int minVersion, void Function(Object error) onError) async { var packageConfigFile = await checkForPackageConfigJsonFile(directory); if (packageConfigFile != null) { diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 048555fc1..155dfc539 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -34,7 +34,7 @@ abstract class PackageConfig { /// /// The package's root ([Package.root]) and package-root /// ([Package.packageUriRoot]) paths must satisfy a number of constraints - /// We say that one path (which we know ends with a `/` charater) + /// We say that one path (which we know ends with a `/` character) /// is inside another path, if the latter path is a prefix of the former path, /// including the two paths being the same. /// @@ -159,7 +159,7 @@ abstract class PackageConfig { /// Look up a package by name. /// - /// Returns the [Package] fron [packages] with [packageName] as + /// Returns the [Package] from [packages] with [packageName] as /// [Package.name]. Returns `null` if the package is not available in the /// current configuration. Package? operator [](String packageName); @@ -377,7 +377,7 @@ abstract class LanguageVersion implements Comparable { /// An *invalid* language version. /// -/// Stored in a [Package] when the orginal language version string +/// Stored in a [Package] when the original language version string /// was invalid and a `onError` handler was passed to the parser /// which did not throw on an error. abstract class InvalidLanguageVersion implements LanguageVersion { diff --git a/pkgs/package_config/lib/src/package_config_impl.dart b/pkgs/package_config/lib/src/package_config_impl.dart index d8e8d495f..865e99a8e 100644 --- a/pkgs/package_config/lib/src/package_config_impl.dart +++ b/pkgs/package_config/lib/src/package_config_impl.dart @@ -436,7 +436,7 @@ class TriePackageTree implements PackageTree { } // For internal reasons we allow this (for now). One should still never do - // it thouh. + // it though. // 3) The new package is inside the packageUriRoot of existing package. if (_disallowPackagesInsidePackageUriRoot) { if (_beginsWith(0, existingPackage.packageUriRoot.toString(), diff --git a/pkgs/package_config/lib/src/packages_file.dart b/pkgs/package_config/lib/src/packages_file.dart index f84db1075..bf68f2c88 100644 --- a/pkgs/package_config/lib/src/packages_file.dart +++ b/pkgs/package_config/lib/src/packages_file.dart @@ -114,7 +114,7 @@ PackageConfig parse( } if (packageNames.contains(packageName)) { onError(PackageConfigFormatException( - 'Same package name occured more than once', source, start)); + 'Same package name occurred more than once', source, start)); continue; } var rootUri = packageLocation; diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index 3bf1bece3..f1fa20790 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -164,7 +164,7 @@ bool hasAbsolutePath(Uri uri) => /// the [baseUri], or if there is no overlap in the paths of the /// two URIs at all, the [uri] is returned as-is. /// -/// Otherwise the result is a path-only URI which satsifies +/// Otherwise the result is a path-only URI which satisfies /// `baseUri.resolveUri(result) == uri`, /// /// The `baseUri` must be absolute. diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 6ac7f54dd..9db82c64f 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -10,5 +10,5 @@ dependencies: path: ^1.8.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 + dart_flutter_team_lints: ^2.1.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 87d1fd413..0f399636f 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -126,7 +126,7 @@ void main() { }); group('package config', () { - test('emtpy', () { + test('empty', () { var empty = PackageConfig([], extraData: unique); expect(empty.version, 2); expect(empty.packages, isEmpty); From 98f8a511fe2fddada504ef181450541f1edd7ea6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 02:59:00 +0000 Subject: [PATCH 592/657] Bump dart-lang/setup-dart from 1.6.2 to 1.6.4 (dart-lang/pool#83) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.2 to 1.6.4.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.4

  • Rebuild JS code to include changes from v1.6.3

v1.6.3

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.2&new-version=1.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 7d9adb67b..53f1fe9e5 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install From 60b7a2ce9151bddec3411653728eb28ea4e0ce7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 15:26:07 +0000 Subject: [PATCH 593/657] Bump actions/checkout from 4.1.2 to 4.1.4 (dart-lang/pool#84) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.4.
Release notes

Sourced from actions/checkout's releases.

v4.1.4

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.3...v4.1.4

v4.1.3

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.2...v4.1.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.2&new-version=4.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 53f1fe9e5..9ff1a9574 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 024cb7f18a836f91d7ed7a9d4a58e5b648b269bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 16:13:05 +0000 Subject: [PATCH 594/657] Bump dart-lang/setup-dart from 1.6.2 to 1.6.4 (dart-lang/pub_semver#100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.2 to 1.6.4.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.4

  • Rebuild JS code to include changes from v1.6.3

v1.6.3

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.2&new-version=1.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 8f1b1a691..b14a4082a 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.0.0, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install From 08beee08466d0005308d1f28b06c2cc29b9a4bdf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 17:35:04 +0000 Subject: [PATCH 595/657] Bump actions/checkout from 4.1.2 to 4.1.4 (dart-lang/pub_semver#101) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.4.
Release notes

Sourced from actions/checkout's releases.

v4.1.4

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.3...v4.1.4

v4.1.3

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.2...v4.1.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.2&new-version=4.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index b14a4082a..97fdf914e 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 802e91d389cdaa48544229882e683fbaeb3ebb85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 17:43:04 +0000 Subject: [PATCH 596/657] Bump dart-lang/setup-dart from 1.6.3 to 1.6.4 (dart-lang/source_maps#90) Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.3 to 1.6.4.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.4

  • Rebuild JS code to include changes from v1.6.3
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.3&new-version=1.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 303cc0567..2c1a3c837 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@65c82982aa686933bf10d50aced7a27b2b63f2a6 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.3.0, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@65c82982aa686933bf10d50aced7a27b2b63f2a6 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install From cc2dd7e0d3eac10fd31c84139afb606c4d36d5af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 17:46:47 +0000 Subject: [PATCH 597/657] Bump actions/checkout from 4.1.2 to 4.1.4 (dart-lang/source_span#109) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.4.
Release notes

Sourced from actions/checkout's releases.

v4.1.4

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.3...v4.1.4

v4.1.3

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.2...v4.1.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.2&new-version=4.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 7ffd87247..700581b5d 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 with: sdk: ${{ matrix.sdk }} From ea65ec8d2328bdd20bdb210d5a335c524e5f9329 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 17:50:47 +0000 Subject: [PATCH 598/657] Bump actions/checkout from 4.1.2 to 4.1.4 (dart-lang/source_maps#91) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.4.
Release notes

Sourced from actions/checkout's releases.

v4.1.4

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.3...v4.1.4

v4.1.3

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.2...v4.1.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.2&new-version=4.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 2c1a3c837..c0ca0d7c4 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3.0, dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 04a0a06e8361e8821eac4c9cd2f59305d9a405bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 17:54:04 +0000 Subject: [PATCH 599/657] Bump dart-lang/setup-dart from 1.6.2 to 1.6.4 (dart-lang/source_span#110) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.2 to 1.6.4.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.4

  • Rebuild JS code to include changes from v1.6.3

v1.6.3

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.2&new-version=1.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 700581b5d..dd6bc2bf0 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.1.0, dev] steps: - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install From 1f2920db3e8b68eda3990e1607628d81b2554b47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 May 2024 20:46:46 +0000 Subject: [PATCH 600/657] Bump dart-lang/setup-dart from 1.6.2 to 1.6.4 (dart-lang/package_config#152) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.6.2 to 1.6.4.
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.4

  • Rebuild JS code to include changes from v1.6.3

v1.6.3

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

  • Automatically create OIDC token for pub.dev.
  • Add a reusable workflow for publishing.

v1.3.0

  • The install location of the Dart SDK is now available

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.2&new-version=1.6.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 88c5dffee..9196439e4 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,7 +49,7 @@ jobs: sdk: [3.2, dev] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - - uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3 + - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} - id: install From 709cf70e99fbae9fd38659f69d81e8823eab3bb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 May 2024 02:58:43 +0000 Subject: [PATCH 601/657] Bump actions/checkout from 4.1.2 to 4.1.4 (dart-lang/package_config#151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.4.
Release notes

Sourced from actions/checkout's releases.

v4.1.4

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.3...v4.1.4

v4.1.3

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.2...v4.1.3

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

v3.5.0

v3.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.2&new-version=4.1.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 9196439e4..2c2893435 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -48,7 +48,7 @@ jobs: os: [ubuntu-latest, windows-latest] sdk: [3.2, dev] steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 84d468b6f9fa47635864ba9574ac16266dc69220 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 9 May 2024 08:39:57 -0700 Subject: [PATCH 602/657] blast_repo fixes (dart-lang/pool#85) dependabot --- pkgs/pool/.github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/pool/.github/dependabot.yml b/pkgs/pool/.github/dependabot.yml index 725f03af2..cde02ad6a 100644 --- a/pkgs/pool/.github/dependabot.yml +++ b/pkgs/pool/.github/dependabot.yml @@ -9,3 +9,7 @@ updates: interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*" From d8e1a5e62ff78f24c271355123c24def035403b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 15:42:13 +0000 Subject: [PATCH 603/657] Bump actions/checkout from 4.1.4 to 4.1.5 in the github-actions group (dart-lang/pool#86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.4 to 4.1.5
Release notes

Sourced from actions/checkout's releases.

v4.1.5

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.4...v4.1.5

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.4&new-version=4.1.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 9ff1a9574..53338d55b 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From bc259463ae9bc33de667734b7d802eec7aeaec0e Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 9 May 2024 13:46:44 -0700 Subject: [PATCH 604/657] blast_repo fixes (dart-lang/package_config#153) dependabot --- pkgs/package_config/.github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/package_config/.github/dependabot.yml b/pkgs/package_config/.github/dependabot.yml index c84404dc9..a19a66adf 100644 --- a/pkgs/package_config/.github/dependabot.yml +++ b/pkgs/package_config/.github/dependabot.yml @@ -10,3 +10,7 @@ updates: interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*" From 926b830ea5db08162b62a4b94dceae948965e284 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 9 May 2024 13:46:52 -0700 Subject: [PATCH 605/657] blast_repo fixes (dart-lang/pub_semver#102) dependabot --- pkgs/pub_semver/.github/dependabot.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/pub_semver/.github/dependabot.yaml b/pkgs/pub_semver/.github/dependabot.yaml index 439e796b4..bf6b38a4d 100644 --- a/pkgs/pub_semver/.github/dependabot.yaml +++ b/pkgs/pub_semver/.github/dependabot.yaml @@ -8,3 +8,7 @@ updates: interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*" From 4031629a7ed3eaae045bab1a1b0313d9b2539a3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 20:53:27 +0000 Subject: [PATCH 606/657] Bump actions/checkout from 4.1.4 to 4.1.5 in the github-actions group (dart-lang/package_config#154) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.4 to 4.1.5
Release notes

Sourced from actions/checkout's releases.

v4.1.5

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.4...v4.1.5

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.4&new-version=4.1.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 2c2893435..c9d757965 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -48,7 +48,7 @@ jobs: os: [ubuntu-latest, windows-latest] sdk: [3.2, dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From fcd421b629605bf0e2ff028caa13c0773a1d4f81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 20:54:37 +0000 Subject: [PATCH 607/657] Bump actions/checkout from 4.1.4 to 4.1.5 in the github-actions group (dart-lang/pub_semver#103) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.4 to 4.1.5
Release notes

Sourced from actions/checkout's releases.

v4.1.5

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.4...v4.1.5

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.4&new-version=4.1.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 97fdf914e..05335028c 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 34ed8f101cc9fe9d1e1c1a2c95b07aeda729218f Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 13 May 2024 10:36:29 -0700 Subject: [PATCH 608/657] blast_repo fixes (dart-lang/source_maps#92) dependabot --- pkgs/source_maps/.github/dependabot.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/source_maps/.github/dependabot.yaml b/pkgs/source_maps/.github/dependabot.yaml index 439e796b4..bf6b38a4d 100644 --- a/pkgs/source_maps/.github/dependabot.yaml +++ b/pkgs/source_maps/.github/dependabot.yaml @@ -8,3 +8,7 @@ updates: interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*" From ac3a2874b0fc2219f6c2ffc6d064391cc248c345 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Mon, 13 May 2024 10:36:40 -0700 Subject: [PATCH 609/657] blast_repo fixes (dart-lang/source_span#111) dependabot --- pkgs/source_span/.github/dependabot.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/source_span/.github/dependabot.yml b/pkgs/source_span/.github/dependabot.yml index c6531d433..eeaa9d9f4 100644 --- a/pkgs/source_span/.github/dependabot.yml +++ b/pkgs/source_span/.github/dependabot.yml @@ -10,3 +10,7 @@ updates: interval: monthly labels: - autosubmit + groups: + github-actions: + patterns: + - "*" From 9e7493f33849e7a0e1785a5510a075f19bfb7b0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 17:38:27 +0000 Subject: [PATCH 610/657] Bump actions/checkout from 4.1.4 to 4.1.5 in the github-actions group (dart-lang/source_maps#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.4 to 4.1.5
Release notes

Sourced from actions/checkout's releases.

v4.1.5

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.4...v4.1.5

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.4&new-version=4.1.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index c0ca0d7c4..dd3d04b81 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3.0, dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 2f14bd5b44b7e58ccd061110cc056e57562cc8dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 17:39:19 +0000 Subject: [PATCH 611/657] Bump actions/checkout from 4.1.4 to 4.1.5 in the github-actions group (dart-lang/source_span#112) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.4 to 4.1.5
Release notes

Sourced from actions/checkout's releases.

v4.1.5

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.4...v4.1.5

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.4&new-version=4.1.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index dd6bc2bf0..3324cef9d 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From b79ef033b574645675cca056dc0bbb7bf9db6624 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 16:24:22 +0000 Subject: [PATCH 612/657] Bump actions/checkout from 4.1.5 to 4.1.6 in the github-actions group (dart-lang/pub_semver#104) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.5 to 4.1.6
Release notes

Sourced from actions/checkout's releases.

v4.1.6

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.5...v4.1.6

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.5&new-version=4.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 05335028c..58a2061ed 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From e3e471cfd3e2048b184a6b3e6c5b8f1f33e5e133 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 17:12:26 +0000 Subject: [PATCH 613/657] Bump actions/checkout from 4.1.5 to 4.1.6 in the github-actions group (dart-lang/source_maps#94) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.5 to 4.1.6
Release notes

Sourced from actions/checkout's releases.

v4.1.6

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.5...v4.1.6

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.5&new-version=4.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index dd3d04b81..b4952c406 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3.0, dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From e652540a39a6808d39268e4b4dd7686a21195be9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 17:28:04 +0000 Subject: [PATCH 614/657] Bump actions/checkout from 4.1.5 to 4.1.6 in the github-actions group (dart-lang/source_span#113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.5 to 4.1.6
Release notes

Sourced from actions/checkout's releases.

v4.1.6

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.5...v4.1.6

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.5&new-version=4.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 3324cef9d..a669c2886 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 80670e18721ea8f36b8fba01591cd416b94eaa20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 20:59:14 +0000 Subject: [PATCH 615/657] Bump actions/checkout from 4.1.5 to 4.1.6 in the github-actions group (dart-lang/package_config#155) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.5 to 4.1.6
Release notes

Sourced from actions/checkout's releases.

v4.1.6

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.5...v4.1.6

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.5&new-version=4.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index c9d757965..3fd2c820b 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -48,7 +48,7 @@ jobs: os: [ubuntu-latest, windows-latest] sdk: [3.2, dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From f541e0fc6431a1f28349e0408d64c4bdfe50e6b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Jun 2024 18:18:59 +0000 Subject: [PATCH 616/657] Bump actions/checkout from 4.1.5 to 4.1.6 in the github-actions group (dart-lang/pool#87) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.5 to 4.1.6
Release notes

Sourced from actions/checkout's releases.

v4.1.6

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.1.5...v4.1.6

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

v3.5.2

v3.5.1

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.5&new-version=4.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 53338d55b..be844e630 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} From 2655d2abe08d920d4c993e62452c0b934263abdf Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 20 Jun 2024 09:23:26 -0700 Subject: [PATCH 617/657] bump lints and SDK dep, test wasm (dart-lang/pub_semver#105) --- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- pkgs/pub_semver/CHANGELOG.md | 2 +- pkgs/pub_semver/pubspec.yaml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 58a2061ed..da7fb292b 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [3.0.0, dev] + sdk: [3.4, dev] steps: - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 @@ -60,5 +60,5 @@ jobs: run: dart test --platform vm if: always() && steps.install.outcome == 'success' - name: Run Chrome tests - run: dart test --platform chrome + run: dart test --platform chrome --compiler dart2js,dart2wasm if: always() && steps.install.outcome == 'success' diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 33899354f..83474d265 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,6 +1,6 @@ ## 2.1.5-wip -- Require Dart `3.0.0`. +- Require Dart `3.4.0`. ## 2.1.4 diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 9d23664d5..5a061bec7 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -9,12 +9,12 @@ topics: - semver environment: - sdk: ^3.0.0 + sdk: ^3.4.0 dependencies: collection: ^1.15.0 meta: ^1.3.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 + dart_flutter_team_lints: ^3.0.0 test: ^1.16.0 From dbfe2da00ecc026feee71b9c15dee387724daf3c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Thu, 20 Jun 2024 13:04:55 -0700 Subject: [PATCH 618/657] blast_repo fixes (dart-lang/pool#88) auto-publish, github-actions, no-response --- pkgs/pool/.github/workflows/ci.yml | 4 ++-- pkgs/pool/.github/workflows/publish.yaml | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index be844e630..63d902e4b 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.0.0, dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 with: sdk: ${{ matrix.sdk }} diff --git a/pkgs/pool/.github/workflows/publish.yaml b/pkgs/pool/.github/workflows/publish.yaml index fcb7ccb89..27157a046 100644 --- a/pkgs/pool/.github/workflows/publish.yaml +++ b/pkgs/pool/.github/workflows/publish.yaml @@ -6,9 +6,12 @@ on: pull_request: branches: [ master ] push: - tags: [ 'v[0-9]+.[0-9]+.[0-9]+*' ] + tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] jobs: publish: if: ${{ github.repository_owner == 'dart-lang' }} uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main + permissions: + id-token: write # Required for authentication using OIDC + pull-requests: write # Required for writing the pull request note From 6aaa80bc0ab2ab9cf54521031a847d2bcbae3bc8 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 21 Jun 2024 16:22:00 -0700 Subject: [PATCH 619/657] update lints, require Dart 3.4 (dart-lang/pool#89) --- pkgs/pool/.github/workflows/ci.yml | 2 +- pkgs/pool/CHANGELOG.md | 2 +- pkgs/pool/pubspec.yaml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 63d902e4b..a411e90e0 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: matrix: # Add macos-latest and/or windows-latest if relevant for this package. os: [ubuntu-latest] - sdk: [3.0.0, dev] + sdk: [3.4, dev] steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index e17e848cc..4c1e72ddd 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,6 +1,6 @@ ## 1.5.2-wip -* Require Dart 3.0. +* Require Dart 3.4. ## 1.5.1 diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 7fb5021d3..4ad49c264 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -6,13 +6,13 @@ description: >- repository: https://github.com/dart-lang/pool environment: - sdk: ^3.0.0 + sdk: ^3.4.0 dependencies: async: ^2.5.0 stack_trace: ^1.10.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 + dart_flutter_team_lints: ^3.0.0 fake_async: ^1.2.0 - test: ^1.16.0 + test: ^1.16.6 From 9a76bf4e3d49330db6056c295a238abf795fe9a9 Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 24 Jun 2024 10:03:16 -0700 Subject: [PATCH 620/657] bump lints (dart-lang/source_span#114) --- pkgs/source_span/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 45804e781..3a7624ba3 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -13,5 +13,5 @@ dependencies: term_glyph: ^1.2.0 dev_dependencies: - dart_flutter_team_lints: ^2.0.0 + dart_flutter_team_lints: ^3.0.0 test: ^1.16.0 From 1e12b0dd164afa4293f5ef018a6d56480059e862 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 02:23:00 +0000 Subject: [PATCH 621/657] Bump dart-lang/setup-dart in the github-actions group (dart-lang/pool#90) Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.4 to 1.6.5
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.5

dart-lang/pool#118: dart-lang/setup-dartdart-lang/pool#118

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.5

dart-lang/pool#118: dart-lang/setup-dartdart-lang/pool#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.4&new-version=1.6.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index a411e90e0..d99a64cd6 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.4, dev] steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install From e10cad5239dd2706a810530d55f9dbe62005e5c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:50:00 +0000 Subject: [PATCH 622/657] Bump the github-actions group with 2 updates (dart-lang/pub_semver#106) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `actions/checkout` from 4.1.6 to 4.1.7
Release notes

Sourced from actions/checkout's releases.

v4.1.7

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.6...v4.1.7

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

... (truncated)

Commits

Updates `dart-lang/setup-dart` from 1.6.4 to 1.6.5
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.5

dart-lang/pub_semver#118: dart-lang/setup-dartdart-lang/pub_semver#118

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.5

dart-lang/pub_semver#118: dart-lang/setup-dartdart-lang/pub_semver#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pub_semver/.github/workflows/test-package.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index da7fb292b..30b09ad7d 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [3.4, dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install From 23c8192219f3066b3065e7d8ba2e851ad409d605 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:09:52 +0000 Subject: [PATCH 623/657] Bump the github-actions group with 2 updates (dart-lang/source_span#115) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `actions/checkout` from 4.1.6 to 4.1.7
Release notes

Sourced from actions/checkout's releases.

v4.1.7

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.6...v4.1.7

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

... (truncated)

Commits

Updates `dart-lang/setup-dart` from 1.6.4 to 1.6.5
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.5

dart-lang/source_span#118: dart-lang/setup-dartdart-lang/source_span#118

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.5

dart-lang/source_span#118: dart-lang/setup-dartdart-lang/source_span#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_span/.github/workflows/test-package.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index a669c2886..a0116f708 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install From d904e93868f23ec0508d8e6d7d98b359d4002982 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:52:49 +0000 Subject: [PATCH 624/657] Bump the github-actions group with 2 updates (dart-lang/source_maps#95) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `actions/checkout` from 4.1.6 to 4.1.7
Release notes

Sourced from actions/checkout's releases.

v4.1.7

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.6...v4.1.7

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

... (truncated)

Commits

Updates `dart-lang/setup-dart` from 1.6.4 to 1.6.5
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.5

dart-lang/source_maps#118: dart-lang/setup-dartdart-lang/source_maps#118

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.5

dart-lang/source_maps#118: dart-lang/setup-dartdart-lang/source_maps#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_maps/.github/workflows/test-package.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index b4952c406..14bf0d49a 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,8 +49,8 @@ jobs: os: [ubuntu-latest] sdk: [3.3.0, dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install From 58f90e988ff570a86be87da2631fe345aed60d5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 20:38:26 +0000 Subject: [PATCH 625/657] Bump the github-actions group with 2 updates (dart-lang/package_config#156) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `actions/checkout` from 4.1.6 to 4.1.7
Release notes

Sourced from actions/checkout's releases.

v4.1.7

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.6...v4.1.7

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

v3.5.3

... (truncated)

Commits

Updates `dart-lang/setup-dart` from 1.6.4 to 1.6.5
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.6.5

dart-lang/package_config#118: dart-lang/setup-dartdart-lang/package_config#118

Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.6.5

dart-lang/package_config#118: dart-lang/setup-dartdart-lang/package_config#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

  • Re-wrote the implementation of the action into Dart.
  • Auto-detect the platform architecture (x64, ia32, arm, arm64).
  • Improved the caching and download resilience of the sdk.
  • Added a new action output: dart-version - the installed version of the sdk.

v1.4.0

... (truncated)

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/package_config/.github/workflows/test-package.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 3fd2c820b..33717105d 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,8 +22,8 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install @@ -48,8 +48,8 @@ jobs: os: [ubuntu-latest, windows-latest] sdk: [3.2, dev] steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 - - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} - id: install From 5bfdcd8e92db637a134f188e5204b970b306c79c Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Tue, 6 Aug 2024 09:04:47 -0700 Subject: [PATCH 626/657] Latest lints, require Dart 3.4 (dart-lang/package_config#157) --- pkgs/package_config/.github/workflows/test-package.yml | 2 +- pkgs/package_config/CHANGELOG.md | 2 +- pkgs/package_config/lib/package_config.dart | 2 +- pkgs/package_config/lib/package_config_types.dart | 2 +- pkgs/package_config/lib/src/util.dart | 2 +- pkgs/package_config/lib/src/util_io.dart | 2 +- pkgs/package_config/pubspec.yaml | 4 ++-- pkgs/package_config/test/discovery_test.dart | 2 +- pkgs/package_config/test/discovery_uri_test.dart | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 33717105d..704ee2e3c 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -46,7 +46,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - sdk: [3.2, dev] + sdk: [3.4, dev] steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 2870c8c08..f9fec1d00 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,6 +1,6 @@ ## 2.1.1-wip -- Require Dart 3.2 +- Require Dart 3.4 ## 2.1.0 diff --git a/pkgs/package_config/lib/package_config.dart b/pkgs/package_config/lib/package_config.dart index 194fe894e..074c97707 100644 --- a/pkgs/package_config/lib/package_config.dart +++ b/pkgs/package_config/lib/package_config.dart @@ -7,7 +7,7 @@ /// /// This package provides functionality to find, read and write package /// configurations in the [specified format](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md). -library package_config.package_config; +library; import 'dart:io' show Directory, File; import 'dart:typed_data' show Uint8List; diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart index 756be0518..825f7acec 100644 --- a/pkgs/package_config/lib/package_config_types.dart +++ b/pkgs/package_config/lib/package_config_types.dart @@ -10,7 +10,7 @@ /// {@canonicalFor package_config.Package} /// {@canonicalFor package_config.PackageConfig} /// {@canonicalFor errors.PackageConfigError} -library package_config.package_config_types; +library; export 'src/errors.dart' show PackageConfigError; export 'src/package_config.dart' diff --git a/pkgs/package_config/lib/src/util.dart b/pkgs/package_config/lib/src/util.dart index f1fa20790..4f0210cda 100644 --- a/pkgs/package_config/lib/src/util.dart +++ b/pkgs/package_config/lib/src/util.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. /// Utility methods used by more than one library in the package. -library package_config.util; +library; import 'errors.dart'; diff --git a/pkgs/package_config/lib/src/util_io.dart b/pkgs/package_config/lib/src/util_io.dart index 914ea384e..4680eefd4 100644 --- a/pkgs/package_config/lib/src/util_io.dart +++ b/pkgs/package_config/lib/src/util_io.dart @@ -4,7 +4,7 @@ /// Utility methods requiring dart:io and used by more than one library in the /// package. -library package_config.util_io; +library; import 'dart:io'; import 'dart:typed_data'; diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 9db82c64f..545701d6d 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -4,11 +4,11 @@ description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/package_config environment: - sdk: ^3.2.0 + sdk: ^3.4.0 dependencies: path: ^1.8.0 dev_dependencies: - dart_flutter_team_lints: ^2.1.0 + dart_flutter_team_lints: ^3.0.0 test: ^1.16.0 diff --git a/pkgs/package_config/test/discovery_test.dart b/pkgs/package_config/test/discovery_test.dart index 2ca337a19..6d1b65529 100644 --- a/pkgs/package_config/test/discovery_test.dart +++ b/pkgs/package_config/test/discovery_test.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('vm') -library package_config.discovery_test; +library; import 'dart:io'; diff --git a/pkgs/package_config/test/discovery_uri_test.dart b/pkgs/package_config/test/discovery_uri_test.dart index b71ed5172..542bf0a65 100644 --- a/pkgs/package_config/test/discovery_uri_test.dart +++ b/pkgs/package_config/test/discovery_uri_test.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('vm') -library package_config.discovery_test; +library; import 'package:package_config/package_config.dart'; import 'package:test/test.dart'; From dd0c0848f1b5749bae36aa72e03306182a077f21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 16:05:54 +0000 Subject: [PATCH 627/657] Bump actions/checkout from 4.1.7 to 4.2.0 in the github-actions group (dart-lang/pub_semver#107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.7 to 4.2.0
Release notes

Sourced from actions/checkout's releases.

v4.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.7...v4.2.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.7&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 30b09ad7d..3fe3185e0 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.4, dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 3e0f94661c29a5650c4b055cc84609e6402e99a2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:02:40 +0000 Subject: [PATCH 628/657] Bump actions/checkout from 4.1.7 to 4.2.0 in the github-actions group (dart-lang/source_maps#96) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.7 to 4.2.0
Release notes

Sourced from actions/checkout's releases.

v4.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.7...v4.2.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.7&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 14bf0d49a..f8606bf60 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3.0, dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From edadad0d06ef1b7cf1eeb1a27c096a5d2bc184ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:31:06 +0000 Subject: [PATCH 629/657] Bump actions/checkout from 4.1.7 to 4.2.0 in the github-actions group (dart-lang/source_span#117) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.7 to 4.2.0
Release notes

Sourced from actions/checkout's releases.

v4.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.7...v4.2.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.7&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index a0116f708..d0c373b13 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 3b5c3516779f6bec9bb5374966674841a46172f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 20:49:51 +0000 Subject: [PATCH 630/657] Bump actions/checkout from 4.1.7 to 4.2.0 in the github-actions group (dart-lang/package_config#159) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.7 to 4.2.0
Release notes

Sourced from actions/checkout's releases.

v4.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.7...v4.2.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.7&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 704ee2e3c..629a95d64 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -48,7 +48,7 @@ jobs: os: [ubuntu-latest, windows-latest] sdk: [3.4, dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From b6a8e6878181d537b3aa25851608f33a5c622305 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 22:20:50 +0000 Subject: [PATCH 631/657] Bump actions/checkout from 4.1.7 to 4.2.0 in the github-actions group (dart-lang/pool#91) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.1.7 to 4.2.0
Release notes

Sourced from actions/checkout's releases.

v4.2.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.1.7...v4.2.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

v4.0.0

v3.6.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.7&new-version=4.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index d99a64cd6..34a41d3d5 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.4, dev] steps: - - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 360c9446476b1ad968b540ab80f4bb303d8c001f Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 28 Oct 2024 14:50:55 -0700 Subject: [PATCH 632/657] blast_repo fixes (dart-lang/source_span#118) drop-lint --- pkgs/source_span/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/source_span/analysis_options.yaml b/pkgs/source_span/analysis_options.yaml index ae73fa5e9..d2ebdbfe8 100644 --- a/pkgs/source_span/analysis_options.yaml +++ b/pkgs/source_span/analysis_options.yaml @@ -22,7 +22,6 @@ linter: - literal_only_boolean_expressions - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - - package_api_docs - prefer_const_declarations - prefer_expression_function_bodies - prefer_final_locals From f49575eebe523185e9bd48e233e2b5652abab15a Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Mon, 28 Oct 2024 19:06:05 -0700 Subject: [PATCH 633/657] blast_repo fixes (dart-lang/pub_semver#108) drop-lint --- pkgs/pub_semver/analysis_options.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/pub_semver/analysis_options.yaml b/pkgs/pub_semver/analysis_options.yaml index 01270cd05..76380a006 100644 --- a/pkgs/pub_semver/analysis_options.yaml +++ b/pkgs/pub_semver/analysis_options.yaml @@ -23,7 +23,6 @@ linter: - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString - - package_api_docs - prefer_const_declarations - prefer_expression_function_bodies - unnecessary_await_in_return From ff6870b6b6bc77a53ac6fae3fc0fc699bb071d1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 02:23:07 +0000 Subject: [PATCH 634/657] Bump actions/checkout from 4.2.0 to 4.2.2 in the github-actions group (dart-lang/pool#92) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.2.0 to 4.2.2
Release notes

Sourced from actions/checkout's releases.

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index 34a41d3d5..a58ee8b89 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.4, dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 170c76f35233589668b7efd2501bfc7ff56409c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 16:05:24 +0000 Subject: [PATCH 635/657] Bump actions/checkout from 4.2.0 to 4.2.2 in the github-actions group (dart-lang/pub_semver#109) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.2.0 to 4.2.2
Release notes

Sourced from actions/checkout's releases.

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 3fe3185e0..057009dbe 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.4, dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 2f6ae72846656c52a13f6b14298ef003130f2322 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:11:48 +0000 Subject: [PATCH 636/657] Bump actions/checkout from 4.2.0 to 4.2.2 in the github-actions group (dart-lang/source_maps#97) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.2.0 to 4.2.2
Release notes

Sourced from actions/checkout's releases.

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index f8606bf60..730278bd1 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.3.0, dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 12a0c086e517cf313578574b67aa18d9e6b56060 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:36:26 +0000 Subject: [PATCH 637/657] Bump actions/checkout from 4.2.0 to 4.2.2 in the github-actions group (dart-lang/source_span#119) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.2.0 to 4.2.2
Release notes

Sourced from actions/checkout's releases.

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index d0c373b13..77622fa83 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -49,7 +49,7 @@ jobs: os: [ubuntu-latest] sdk: [3.1.0, dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From 34d75539e5838239d12b3d3b548c6c82d16465e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 20:39:05 +0000 Subject: [PATCH 638/657] Bump actions/checkout from 4.2.0 to 4.2.2 in the github-actions group (dart-lang/package_config#160) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 4.2.0 to 4.2.2
Release notes

Sourced from actions/checkout's releases.

v4.2.2

What's Changed

Full Changelog: https://github.com/actions/checkout/compare/v4.2.1...v4.2.2

v4.2.1

What's Changed

New Contributors

Full Changelog: https://github.com/actions/checkout/compare/v4.2.0...v4.2.1

Changelog

Sourced from actions/checkout's changelog.

Changelog

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

v4.1.5

v4.1.4

v4.1.3

v4.1.2

v4.1.1

v4.1.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.2.0&new-version=4.2.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 629a95d64..526e05593 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -22,7 +22,7 @@ jobs: matrix: sdk: [dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} @@ -48,7 +48,7 @@ jobs: os: [ubuntu-latest, windows-latest] sdk: [3.4, dev] steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: sdk: ${{ matrix.sdk }} From ecc44a110ae6ad676a8d2e018d44c7fe1a740066 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 03:02:14 +0000 Subject: [PATCH 639/657] Bump dart-lang/setup-dart in the github-actions group (dart-lang/pool#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.5 to 1.7.0
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.7.0

What's Changed

  • Install a Flutter SDK in the publish workflow allowing for publication of flutter packages.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.7.0

v1.6.5

dart-lang/pool#118: dart-lang/setup-dartdart-lang/pool#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.5&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pool/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/.github/workflows/ci.yml b/pkgs/pool/.github/workflows/ci.yml index a58ee8b89..cf5a84e83 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/pkgs/pool/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.4, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install From 7cb7ee070e4c423cd502c144759fe65a45a56013 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 16:59:18 +0000 Subject: [PATCH 640/657] Bump dart-lang/setup-dart in the github-actions group (dart-lang/pub_semver#110) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.5 to 1.7.0
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.7.0

What's Changed

  • Install a Flutter SDK in the publish workflow allowing for publication of flutter packages.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.7.0

v1.6.5

dart-lang/pub_semver#118: dart-lang/setup-dartdart-lang/pub_semver#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.5&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/pub_semver/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/pkgs/pub_semver/.github/workflows/test-package.yml index 057009dbe..5bf727c29 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/pkgs/pub_semver/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.4, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install From 217ca1846c9fcf70a227fd0be0eddf52cf599eca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 17:18:08 +0000 Subject: [PATCH 641/657] Bump dart-lang/setup-dart in the github-actions group (dart-lang/source_maps#98) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.5 to 1.7.0
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.7.0

What's Changed

  • Install a Flutter SDK in the publish workflow allowing for publication of flutter packages.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.7.0

v1.6.5

dart-lang/source_maps#118: dart-lang/setup-dartdart-lang/source_maps#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.5&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_maps/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/pkgs/source_maps/.github/workflows/test-package.yml index 730278bd1..e6f7c8608 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/pkgs/source_maps/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.3.0, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install From 4aec5835f0375e282b30462596102d79307b925c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 17:39:59 +0000 Subject: [PATCH 642/657] Bump dart-lang/setup-dart in the github-actions group (dart-lang/source_span#120) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.5 to 1.7.0
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.7.0

What's Changed

  • Install a Flutter SDK in the publish workflow allowing for publication of flutter packages.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.7.0

v1.6.5

dart-lang/source_span#118: dart-lang/setup-dartdart-lang/source_span#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.5&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/source_span/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/pkgs/source_span/.github/workflows/test-package.yml index 77622fa83..c8f1f52c7 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/pkgs/source_span/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install @@ -50,7 +50,7 @@ jobs: sdk: [3.1.0, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install From adca221376fef5545f3a997c8004aba8780ce0b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 20:07:57 +0000 Subject: [PATCH 643/657] Bump dart-lang/setup-dart in the github-actions group (dart-lang/package_config#161) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the github-actions group with 1 update: [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart). Updates `dart-lang/setup-dart` from 1.6.5 to 1.7.0
Release notes

Sourced from dart-lang/setup-dart's releases.

v1.7.0

What's Changed

  • Install a Flutter SDK in the publish workflow allowing for publication of flutter packages.
Changelog

Sourced from dart-lang/setup-dart's changelog.

v1.7.0

v1.6.5

dart-lang/package_config#118: dart-lang/setup-dartdart-lang/package_config#118

v1.6.4

  • Rebuild JS code.

v1.6.3

v1.6.2

v1.6.1

  • Updated the google storage url for main channel releases.

v1.6.0

  • Enable provisioning of the latest Dart SDK patch release by specifying just the major and minor version (e.g. 3.2).

v1.5.1

  • No longer test the setup-dart action on pre-2.12 SDKs.
  • Upgrade JS interop code to use extension types (the new name for inline classes).
  • The upcoming rename of the be channel to main is now supported with forward compatibility that switches when the rename happens.

v1.5.0

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dart-lang/setup-dart&package-manager=github_actions&previous-version=1.6.5&new-version=1.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--- pkgs/package_config/.github/workflows/test-package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/pkgs/package_config/.github/workflows/test-package.yml index 526e05593..718ec07b8 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/pkgs/package_config/.github/workflows/test-package.yml @@ -23,7 +23,7 @@ jobs: sdk: [dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install @@ -49,7 +49,7 @@ jobs: sdk: [3.4, dev] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 + - uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94 with: sdk: ${{ matrix.sdk }} - id: install From a9b1487e63fe99389ff269eaee7c5a9653566b9d Mon Sep 17 00:00:00 2001 From: Moritz Date: Mon, 9 Dec 2024 16:56:09 +0100 Subject: [PATCH 644/657] Add issue template and other fixes --- .github/ISSUE_TEMPLATE/package_config.md | 5 ++++ pkgs/package_config/CONTRIBUTING.md | 33 ------------------------ pkgs/package_config/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 34 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/package_config.md delete mode 100644 pkgs/package_config/CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/package_config.md b/.github/ISSUE_TEMPLATE/package_config.md new file mode 100644 index 000000000..f6322d0fa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/package_config.md @@ -0,0 +1,5 @@ +--- +name: "package:package_config" +about: "Create a bug or file a feature request against package:package_config." +labels: "package:package_config" +--- \ No newline at end of file diff --git a/pkgs/package_config/CONTRIBUTING.md b/pkgs/package_config/CONTRIBUTING.md deleted file mode 100644 index 8423ff94f..000000000 --- a/pkgs/package_config/CONTRIBUTING.md +++ /dev/null @@ -1,33 +0,0 @@ -Want to contribute? Great! First, read this page (including the small print at -the end). - -### Before you contribute -Before we can use your code, you must sign the -[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) -(CLA), which you can do online. The CLA is necessary mainly because you own the -copyright to your changes, even after your contribution becomes part of our -codebase, so we need your permission to use and distribute your code. We also -need to be sure of various other things—for instance that you'll tell us if you -know that your code infringes on other people's patents. You don't have to sign -the CLA until after you've submitted your code for review and a member has -approved it, but you must do it before we can put your code into our codebase. - -Before you start working on a larger contribution, you should get in touch with -us first through the issue tracker with your idea so that we can help out and -possibly guide you. Coordinating up front makes it much easier to avoid -frustration later on. - -### Code reviews -All submissions, including submissions by project members, require review. - -### File headers -All files in the project must start with the following header. - - // Copyright (c) 2019, 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. - -### The small print -Contributions made by corporations are covered by a different agreement than the -one above, the -[Software Grant and Corporate Contributor License Agreement](https://developers.google.com/open-source/cla/corporate). diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 545701d6d..5e1356b02 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,7 +1,7 @@ name: package_config version: 2.1.1-wip description: Support for reading and writing Dart Package Configuration files. -repository: https://github.com/dart-lang/package_config +repository: https://github.com/dart-lang/tools/tree/main/pkgs/package_config environment: sdk: ^3.4.0 From 3327cbf89b56b0234fd4da728f1f181394609b1a Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 11:33:46 +0100 Subject: [PATCH 645/657] Moving fixes --- .github/labeler.yml | 4 ++++ .../workflows/package_config.yaml | 17 ++++++++++++++--- README.md | 1 + pkgs/package_config/.github/dependabot.yml | 16 ---------------- pkgs/package_config/CHANGELOG.md | 1 + pkgs/package_config/README.md | 2 +- pkgs/package_config/pubspec.yaml | 2 +- 7 files changed, 22 insertions(+), 21 deletions(-) rename pkgs/package_config/.github/workflows/test-package.yml => .github/workflows/package_config.yaml (83%) delete mode 100644 pkgs/package_config/.github/dependabot.yml diff --git a/.github/labeler.yml b/.github/labeler.yml index 45c2239b1..31b8b4733 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -76,6 +76,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/oauth2/**' +'package:package_config': + - changed-files: + - any-glob-to-any-file: 'pkgs/package_config/**' + 'package:source_map_stack_trace': - changed-files: - any-glob-to-any-file: 'pkgs/source_map_stack_trace/**' diff --git a/pkgs/package_config/.github/workflows/test-package.yml b/.github/workflows/package_config.yaml similarity index 83% rename from pkgs/package_config/.github/workflows/test-package.yml rename to .github/workflows/package_config.yaml index 718ec07b8..416ea1a11 100644 --- a/pkgs/package_config/.github/workflows/test-package.yml +++ b/.github/workflows/package_config.yaml @@ -1,17 +1,28 @@ -name: Dart CI +name: package:package_config on: # Run on PRs and pushes to the default branch. push: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/package_config.yml' + - 'pkgs/package_config/**' pull_request: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/package_config.yml' + - 'pkgs/package_config/**' schedule: - cron: "0 0 * * 0" env: PUB_ENVIRONMENT: bot.github + +defaults: + run: + working-directory: pkgs/package_config/ + jobs: # Check code formatting and static analysis on a single OS (linux) # against Dart dev. diff --git a/README.md b/README.md index ed90416dd..01360e92b 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ don't naturally belong to other topic monorepos (like | [json_rpc_2](pkgs/json_rpc_2/) | Utilities to write a client or server using the JSON-RPC 2.0 spec. | [![package issues](https://img.shields.io/badge/package:json_rpc_2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Ajson_rpc_2) | [![pub package](https://img.shields.io/pub/v/json_rpc_2.svg)](https://pub.dev/packages/json_rpc_2) | | [mime](pkgs/mime/) | Utilities for handling media (MIME) types, including determining a type from a file extension and file contents. | [![package issues](https://img.shields.io/badge/package:mime-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Amime) | [![pub package](https://img.shields.io/pub/v/mime.svg)](https://pub.dev/packages/mime) | | [oauth2](pkgs/oauth2/) | A client library for authenticating with a remote service via OAuth2 on behalf of a user, and making authorized HTTP requests with the user's OAuth2 credentials. | [![package issues](https://img.shields.io/badge/package:oauth2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aoauth2) | [![pub package](https://img.shields.io/pub/v/oauth2.svg)](https://pub.dev/packages/oauth2) | +| [package_config](pkgs/package_config/) | Support for reading and writing Dart Package Configuration files. | [![package issues](https://img.shields.io/badge/package:package_config-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Apackage_config) | [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config) | | [source_map_stack_trace](pkgs/source_map_stack_trace/) | A package for applying source maps to stack traces. | [![package issues](https://img.shields.io/badge/package:source_map_stack_trace-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_map_stack_trace) | [![pub package](https://img.shields.io/pub/v/source_map_stack_trace.svg)](https://pub.dev/packages/source_map_stack_trace) | | [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [![package issues](https://img.shields.io/badge/package:unified_analytics-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [![pub package](https://img.shields.io/pub/v/unified_analytics.svg)](https://pub.dev/packages/unified_analytics) | diff --git a/pkgs/package_config/.github/dependabot.yml b/pkgs/package_config/.github/dependabot.yml deleted file mode 100644 index a19a66adf..000000000 --- a/pkgs/package_config/.github/dependabot.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Set update schedule for GitHub Actions -# See https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/keeping-your-actions-up-to-date-with-dependabot - -version: 2 -updates: - -- package-ecosystem: github-actions - directory: / - schedule: - interval: monthly - labels: - - autosubmit - groups: - github-actions: - patterns: - - "*" diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index f9fec1d00..93033ed6e 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,6 +1,7 @@ ## 2.1.1-wip - Require Dart 3.4 +- Move to `dart-lang/tools` monorepo. ## 2.1.0 diff --git a/pkgs/package_config/README.md b/pkgs/package_config/README.md index 9e2e41f0b..76fd3cbed 100644 --- a/pkgs/package_config/README.md +++ b/pkgs/package_config/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://github.com/dart-lang/package_config/workflows/Dart%20CI/badge.svg)](https://github.com/dart-lang/package_config/actions?query=workflow%3A"Dart+CI"+branch%3Amaster) +[![Build Status](https://github.com/dart-lang/tools/actions/workflows/package_config.yaml/badge.svg)](https://github.com/dart-lang/tools/actions/workflows/package_config.yaml) [![pub package](https://img.shields.io/pub/v/package_config.svg)](https://pub.dev/packages/package_config) [![package publisher](https://img.shields.io/pub/publisher/package_config.svg)](https://pub.dev/packages/package_config/publisher) diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 5e1356b02..28f3e1364 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.1.1-wip +version: 2.1.1 description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/tools/tree/main/pkgs/package_config From 3655677c5fa2af487a2d443282266cda0ef1f193 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 14:03:01 +0100 Subject: [PATCH 646/657] Remove wip --- pkgs/package_config/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 93033ed6e..101a0fe76 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.1.1-wip +## 2.1.1 - Require Dart 3.4 - Move to `dart-lang/tools` monorepo. From 92f34c920bb9d5bf47c01965ca994c2b5ed489f0 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 14:05:52 +0100 Subject: [PATCH 647/657] Add issue template and other fixes --- .github/ISSUE_TEMPLATE/pool.md | 5 +++++ pkgs/pool/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/pool.md diff --git a/.github/ISSUE_TEMPLATE/pool.md b/.github/ISSUE_TEMPLATE/pool.md new file mode 100644 index 000000000..7af32c4a6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/pool.md @@ -0,0 +1,5 @@ +--- +name: "package:pool" +about: "Create a bug or file a feature request against package:pool." +labels: "package:pool" +--- \ No newline at end of file diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 4ad49c264..a205b7494 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -3,7 +3,7 @@ version: 1.5.2-wip description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. -repository: https://github.com/dart-lang/pool +repository: https://github.com/dart-lang/tools/tree/main/pkgs/pool environment: sdk: ^3.4.0 From 8ab3ea92a5dc50dabf495fc8bf8215a52d8baee1 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 14:14:37 +0100 Subject: [PATCH 648/657] merge fixes --- .github/labeler.yml | 4 ++ .../ci.yml => .github/workflows/pool.yaml | 17 +++++++-- README.md | 1 + pkgs/pool/.github/dependabot.yml | 15 -------- pkgs/pool/.github/workflows/no-response.yml | 37 ------------------- pkgs/pool/.github/workflows/publish.yaml | 17 --------- pkgs/pool/CHANGELOG.md | 3 +- pkgs/pool/README.md | 2 +- pkgs/pool/benchmark/for_each_benchmark.dart | 20 ++++++---- pkgs/pool/pubspec.yaml | 2 +- 10 files changed, 36 insertions(+), 82 deletions(-) rename pkgs/pool/.github/workflows/ci.yml => .github/workflows/pool.yaml (88%) delete mode 100644 pkgs/pool/.github/dependabot.yml delete mode 100644 pkgs/pool/.github/workflows/no-response.yml delete mode 100644 pkgs/pool/.github/workflows/publish.yaml diff --git a/.github/labeler.yml b/.github/labeler.yml index eca80bbc2..88d513756 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -80,6 +80,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/oauth2/**' +'package:pool': + - changed-files: + - any-glob-to-any-file: 'pkgs/pool/**' + 'package:source_map_stack_trace': - changed-files: - any-glob-to-any-file: 'pkgs/source_map_stack_trace/**' diff --git a/pkgs/pool/.github/workflows/ci.yml b/.github/workflows/pool.yaml similarity index 88% rename from pkgs/pool/.github/workflows/ci.yml rename to .github/workflows/pool.yaml index cf5a84e83..6d64062a8 100644 --- a/pkgs/pool/.github/workflows/ci.yml +++ b/.github/workflows/pool.yaml @@ -1,17 +1,28 @@ -name: CI +name: package:pool on: # Run on PRs and pushes to the default branch. push: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/pool.yaml' + - 'pkgs/pool/**' pull_request: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/pool.yaml' + - 'pkgs/pool/**' schedule: - cron: "0 0 * * 0" env: PUB_ENVIRONMENT: bot.github + +defaults: + run: + working-directory: pkgs/pool/ + jobs: # Check code formatting and static analysis on a single OS (linux) # against Dart dev. diff --git a/README.md b/README.md index 50517c36e..9d938393f 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ don't naturally belong to other topic monorepos (like | [json_rpc_2](pkgs/json_rpc_2/) | Utilities to write a client or server using the JSON-RPC 2.0 spec. | [![package issues](https://img.shields.io/badge/package:json_rpc_2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Ajson_rpc_2) | [![pub package](https://img.shields.io/pub/v/json_rpc_2.svg)](https://pub.dev/packages/json_rpc_2) | | [mime](pkgs/mime/) | Utilities for handling media (MIME) types, including determining a type from a file extension and file contents. | [![package issues](https://img.shields.io/badge/package:mime-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Amime) | [![pub package](https://img.shields.io/pub/v/mime.svg)](https://pub.dev/packages/mime) | | [oauth2](pkgs/oauth2/) | A client library for authenticating with a remote service via OAuth2 on behalf of a user, and making authorized HTTP requests with the user's OAuth2 credentials. | [![package issues](https://img.shields.io/badge/package:oauth2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aoauth2) | [![pub package](https://img.shields.io/pub/v/oauth2.svg)](https://pub.dev/packages/oauth2) | +| [pool](pkgs/pool/) | Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. | [![package issues](https://img.shields.io/badge/package:pool-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Apool) | [![pub package](https://img.shields.io/pub/v/pool.svg)](https://pub.dev/packages/pool) | | [source_map_stack_trace](pkgs/source_map_stack_trace/) | A package for applying source maps to stack traces. | [![package issues](https://img.shields.io/badge/package:source_map_stack_trace-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_map_stack_trace) | [![pub package](https://img.shields.io/pub/v/source_map_stack_trace.svg)](https://pub.dev/packages/source_map_stack_trace) | | [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [![package issues](https://img.shields.io/badge/package:unified_analytics-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [![pub package](https://img.shields.io/pub/v/unified_analytics.svg)](https://pub.dev/packages/unified_analytics) | diff --git a/pkgs/pool/.github/dependabot.yml b/pkgs/pool/.github/dependabot.yml deleted file mode 100644 index cde02ad6a..000000000 --- a/pkgs/pool/.github/dependabot.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Dependabot configuration file. -# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates -version: 2 - -updates: - - package-ecosystem: github-actions - directory: / - schedule: - interval: monthly - labels: - - autosubmit - groups: - github-actions: - patterns: - - "*" diff --git a/pkgs/pool/.github/workflows/no-response.yml b/pkgs/pool/.github/workflows/no-response.yml deleted file mode 100644 index ab1ac4984..000000000 --- a/pkgs/pool/.github/workflows/no-response.yml +++ /dev/null @@ -1,37 +0,0 @@ -# A workflow to close issues where the author hasn't responded to a request for -# more information; see https://github.com/actions/stale. - -name: No Response - -# Run as a daily cron. -on: - schedule: - # Every day at 8am - - cron: '0 8 * * *' - -# All permissions not specified are set to 'none'. -permissions: - issues: write - pull-requests: write - -jobs: - no-response: - runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'dart-lang' }} - steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e - with: - # Don't automatically mark inactive issues+PRs as stale. - days-before-stale: -1 - # Close needs-info issues and PRs after 14 days of inactivity. - days-before-close: 14 - stale-issue-label: "needs-info" - close-issue-message: > - Without additional information we're not able to resolve this issue. - Feel free to add more info or respond to any questions above and we - can reopen the case. Thanks for your contribution! - stale-pr-label: "needs-info" - close-pr-message: > - Without additional information we're not able to resolve this PR. - Feel free to add more info or respond to any questions above. - Thanks for your contribution! diff --git a/pkgs/pool/.github/workflows/publish.yaml b/pkgs/pool/.github/workflows/publish.yaml deleted file mode 100644 index 27157a046..000000000 --- a/pkgs/pool/.github/workflows/publish.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# A CI configuration to auto-publish pub packages. - -name: Publish - -on: - pull_request: - branches: [ master ] - push: - tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] - -jobs: - publish: - if: ${{ github.repository_owner == 'dart-lang' }} - uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main - permissions: - id-token: write # Required for authentication using OIDC - pull-requests: write # Required for writing the pull request note diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index 4c1e72ddd..d7ab9abed 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,6 +1,7 @@ -## 1.5.2-wip +## 1.5.2 * Require Dart 3.4. +* Move to `dart-lang/tools` monorepo. ## 1.5.1 diff --git a/pkgs/pool/README.md b/pkgs/pool/README.md index b100ed35d..461e872b8 100644 --- a/pkgs/pool/README.md +++ b/pkgs/pool/README.md @@ -1,4 +1,4 @@ -[![Dart CI](https://github.com/dart-lang/pool/actions/workflows/ci.yml/badge.svg)](https://github.com/dart-lang/pool/actions/workflows/ci.yml) +[![Build Status](https://github.com/dart-lang/tools/actions/workflows/pool.yaml/badge.svg)](https://github.com/dart-lang/tools/actions/workflows/pool.yaml) [![pub package](https://img.shields.io/pub/v/pool.svg)](https://pub.dev/packages/pool) [![package publisher](https://img.shields.io/pub/publisher/pool.svg)](https://pub.dev/packages/pool/publisher) diff --git a/pkgs/pool/benchmark/for_each_benchmark.dart b/pkgs/pool/benchmark/for_each_benchmark.dart index 2973b2a36..8a0c7834a 100644 --- a/pkgs/pool/benchmark/for_each_benchmark.dart +++ b/pkgs/pool/benchmark/for_each_benchmark.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2024, 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:pool/pool.dart'; void main(List args) async { @@ -19,18 +23,20 @@ void main(List args) async { lastLog == null || now.difference(lastLog!) > const Duration(seconds: 1)) { lastLog = now; - print([ - now.difference(start), - i.toString().padLeft(10), - fastestIteration.toString().padLeft(7), - fastest!.inMicroseconds.toString().padLeft(9) - ].join(' ')); + print( + [ + now.difference(start), + i.toString().padLeft(10), + fastestIteration.toString().padLeft(7), + fastest!.inMicroseconds.toString().padLeft(9), + ].join(' '), + ); } } print(['Elapsed ', 'Iterations', 'Fastest', 'Time (us)'].join(' ')); - for (;; i++) { + for (; ; i++) { watch.reset(); var sum = await pool diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index a205b7494..4af8a71d2 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.2-wip +version: 1.5.2 description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. From 065fd6c8315671d29921eae62e37d346038b37d5 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 14:36:32 +0100 Subject: [PATCH 649/657] unformat --- pkgs/pool/benchmark/for_each_benchmark.dart | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/pkgs/pool/benchmark/for_each_benchmark.dart b/pkgs/pool/benchmark/for_each_benchmark.dart index 8a0c7834a..0cd2543e2 100644 --- a/pkgs/pool/benchmark/for_each_benchmark.dart +++ b/pkgs/pool/benchmark/for_each_benchmark.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2024, 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. @@ -23,20 +23,18 @@ void main(List args) async { lastLog == null || now.difference(lastLog!) > const Duration(seconds: 1)) { lastLog = now; - print( - [ - now.difference(start), - i.toString().padLeft(10), - fastestIteration.toString().padLeft(7), - fastest!.inMicroseconds.toString().padLeft(9), - ].join(' '), - ); + print([ + now.difference(start), + i.toString().padLeft(10), + fastestIteration.toString().padLeft(7), + fastest!.inMicroseconds.toString().padLeft(9) + ].join(' ')); } } print(['Elapsed ', 'Iterations', 'Fastest', 'Time (us)'].join(' ')); - for (; ; i++) { + for (;; i++) { watch.reset(); var sum = await pool From 6536814f80a0f128ba31019cd9d09fbda01193c9 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 14:40:48 +0100 Subject: [PATCH 650/657] Add issue template and other fixes --- .github/ISSUE_TEMPLATE/pub_semver.md | 5 +++++ pkgs/pub_semver/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/pub_semver.md diff --git a/.github/ISSUE_TEMPLATE/pub_semver.md b/.github/ISSUE_TEMPLATE/pub_semver.md new file mode 100644 index 000000000..c7db9b5c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/pub_semver.md @@ -0,0 +1,5 @@ +--- +name: "package:pub_semver" +about: "Create a bug or file a feature request against package:pub_semver." +labels: "package:pub_semver" +--- \ No newline at end of file diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 5a061bec7..192de00ef 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -3,7 +3,7 @@ version: 2.1.5-wip description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. -repository: https://github.com/dart-lang/pub_semver +repository: https://github.com/dart-lang/tools/tree/main/pkgs/pub_semver topics: - dart-pub - semver From 5a6d593b64bbc3435682fd929e00a59195536bae Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 14:46:57 +0100 Subject: [PATCH 651/657] merge fixes --- .github/labeler.yml | 4 ++++ .../workflows/pub_semver.yaml | 17 ++++++++++++++--- README.md | 1 + pkgs/pub_semver/.github/dependabot.yaml | 14 -------------- pkgs/pub_semver/CHANGELOG.md | 3 ++- pkgs/pub_semver/README.md | 4 ++-- pkgs/pub_semver/pubspec.yaml | 2 +- 7 files changed, 24 insertions(+), 21 deletions(-) rename pkgs/pub_semver/.github/workflows/test-package.yml => .github/workflows/pub_semver.yaml (86%) delete mode 100644 pkgs/pub_semver/.github/dependabot.yaml diff --git a/.github/labeler.yml b/.github/labeler.yml index eca80bbc2..6e7b9f95e 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -80,6 +80,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/oauth2/**' +'package:pub_semver': + - changed-files: + - any-glob-to-any-file: 'pkgs/pub_semver/**' + 'package:source_map_stack_trace': - changed-files: - any-glob-to-any-file: 'pkgs/source_map_stack_trace/**' diff --git a/pkgs/pub_semver/.github/workflows/test-package.yml b/.github/workflows/pub_semver.yaml similarity index 86% rename from pkgs/pub_semver/.github/workflows/test-package.yml rename to .github/workflows/pub_semver.yaml index 5bf727c29..ba0db18a3 100644 --- a/pkgs/pub_semver/.github/workflows/test-package.yml +++ b/.github/workflows/pub_semver.yaml @@ -1,17 +1,28 @@ -name: Dart CI +name: package:pub_semver on: # Run on PRs and pushes to the default branch. push: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/pub_semver.yaml' + - 'pkgs/pub_semver/**' pull_request: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/pub_semver.yaml' + - 'pkgs/pub_semver/**' schedule: - cron: "0 0 * * 0" env: PUB_ENVIRONMENT: bot.github + +defaults: + run: + working-directory: pkgs/pub_semver/ + jobs: # Check code formatting and static analysis on a single OS (linux) # against Dart dev. diff --git a/README.md b/README.md index 50517c36e..697a16cc7 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ don't naturally belong to other topic monorepos (like | [json_rpc_2](pkgs/json_rpc_2/) | Utilities to write a client or server using the JSON-RPC 2.0 spec. | [![package issues](https://img.shields.io/badge/package:json_rpc_2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Ajson_rpc_2) | [![pub package](https://img.shields.io/pub/v/json_rpc_2.svg)](https://pub.dev/packages/json_rpc_2) | | [mime](pkgs/mime/) | Utilities for handling media (MIME) types, including determining a type from a file extension and file contents. | [![package issues](https://img.shields.io/badge/package:mime-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Amime) | [![pub package](https://img.shields.io/pub/v/mime.svg)](https://pub.dev/packages/mime) | | [oauth2](pkgs/oauth2/) | A client library for authenticating with a remote service via OAuth2 on behalf of a user, and making authorized HTTP requests with the user's OAuth2 credentials. | [![package issues](https://img.shields.io/badge/package:oauth2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aoauth2) | [![pub package](https://img.shields.io/pub/v/oauth2.svg)](https://pub.dev/packages/oauth2) | +| [pub_semver](pkgs/pub_semver/) | Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. | [![package issues](https://img.shields.io/badge/package:pub_semver-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Apub_semver) | [![pub package](https://img.shields.io/pub/v/pub_semver.svg)](https://pub.dev/packages/pub_semver) | | [source_map_stack_trace](pkgs/source_map_stack_trace/) | A package for applying source maps to stack traces. | [![package issues](https://img.shields.io/badge/package:source_map_stack_trace-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_map_stack_trace) | [![pub package](https://img.shields.io/pub/v/source_map_stack_trace.svg)](https://pub.dev/packages/source_map_stack_trace) | | [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [![package issues](https://img.shields.io/badge/package:unified_analytics-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [![pub package](https://img.shields.io/pub/v/unified_analytics.svg)](https://pub.dev/packages/unified_analytics) | diff --git a/pkgs/pub_semver/.github/dependabot.yaml b/pkgs/pub_semver/.github/dependabot.yaml deleted file mode 100644 index bf6b38a4d..000000000 --- a/pkgs/pub_semver/.github/dependabot.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# Dependabot configuration file. -version: 2 - -updates: - - package-ecosystem: github-actions - directory: / - schedule: - interval: monthly - labels: - - autosubmit - groups: - github-actions: - patterns: - - "*" diff --git a/pkgs/pub_semver/CHANGELOG.md b/pkgs/pub_semver/CHANGELOG.md index 83474d265..a31fbb243 100644 --- a/pkgs/pub_semver/CHANGELOG.md +++ b/pkgs/pub_semver/CHANGELOG.md @@ -1,6 +1,7 @@ -## 2.1.5-wip +## 2.1.5 - Require Dart `3.4.0`. +- Move to `dart-lang/tools` monorepo. ## 2.1.4 diff --git a/pkgs/pub_semver/README.md b/pkgs/pub_semver/README.md index ad0740ce0..03c92a3c5 100644 --- a/pkgs/pub_semver/README.md +++ b/pkgs/pub_semver/README.md @@ -1,5 +1,5 @@ -[![Dart CI](https://github.com/dart-lang/pub_semver/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/pub_semver/actions/workflows/test-package.yml) -[![Pub](https://img.shields.io/pub/v/pub_semver.svg)](https://pub.dev/packages/pub_semver) +[![Build Status](https://github.com/dart-lang/tools/actions/workflows/pub_semver.yaml/badge.svg)](https://github.com/dart-lang/tools/actions/workflows/pub_semver.yaml) +[![pub package](https://img.shields.io/pub/v/pub_semver.svg)](https://pub.dev/packages/pub_semver) [![package publisher](https://img.shields.io/pub/publisher/pub_semver.svg)](https://pub.dev/packages/pub_semver/publisher) Handles version numbers and version constraints in the same way that [pub][] diff --git a/pkgs/pub_semver/pubspec.yaml b/pkgs/pub_semver/pubspec.yaml index 192de00ef..290fb9254 100644 --- a/pkgs/pub_semver/pubspec.yaml +++ b/pkgs/pub_semver/pubspec.yaml @@ -1,5 +1,5 @@ name: pub_semver -version: 2.1.5-wip +version: 2.1.5 description: >- Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases. From 3453d0edf2d02cf967a5e8e64a29a66b2531fbfb Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 15:52:17 +0100 Subject: [PATCH 652/657] Add issue template and other fixes --- .github/ISSUE_TEMPLATE/source_maps.md | 5 +++++ pkgs/source_maps/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/source_maps.md diff --git a/.github/ISSUE_TEMPLATE/source_maps.md b/.github/ISSUE_TEMPLATE/source_maps.md new file mode 100644 index 000000000..a1e390a75 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/source_maps.md @@ -0,0 +1,5 @@ +--- +name: "package:source_maps" +about: "Create a bug or file a feature request against package:source_maps." +labels: "package:source_maps" +--- \ No newline at end of file diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index fcc99252a..0c321dad9 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,7 +1,7 @@ name: source_maps version: 0.10.13-wip description: A library to programmatically manipulate source map files. -repository: https://github.com/dart-lang/source_maps +repository: https://github.com/dart-lang/tools/tree/main/pkgs/source_maps environment: sdk: ^3.3.0 From e9fad4a676a68a51302c5307e98ae053dec9b6a7 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 16:01:53 +0100 Subject: [PATCH 653/657] merge fixes --- .github/labeler.yml | 4 ++ .../workflows/source_maps.yaml | 17 +++++++-- README.md | 1 + pkgs/source_maps/.github/dependabot.yaml | 14 ------- .../.github/workflows/no-response.yml | 37 ------------------- .../.github/workflows/publish.yaml | 17 --------- pkgs/source_maps/CHANGELOG.md | 5 ++- pkgs/source_maps/README.md | 2 +- pkgs/source_maps/pubspec.yaml | 2 +- 9 files changed, 24 insertions(+), 75 deletions(-) rename pkgs/source_maps/.github/workflows/test-package.yml => .github/workflows/source_maps.yaml (84%) delete mode 100644 pkgs/source_maps/.github/dependabot.yaml delete mode 100644 pkgs/source_maps/.github/workflows/no-response.yml delete mode 100644 pkgs/source_maps/.github/workflows/publish.yaml diff --git a/.github/labeler.yml b/.github/labeler.yml index eca80bbc2..4ef83558a 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -84,6 +84,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/source_map_stack_trace/**' +'package:source_maps': + - changed-files: + - any-glob-to-any-file: 'pkgs/source_maps/**' + 'package:unified_analytics': - changed-files: - any-glob-to-any-file: 'pkgs/unified_analytics/**' diff --git a/pkgs/source_maps/.github/workflows/test-package.yml b/.github/workflows/source_maps.yaml similarity index 84% rename from pkgs/source_maps/.github/workflows/test-package.yml rename to .github/workflows/source_maps.yaml index e6f7c8608..2ae0f20c5 100644 --- a/pkgs/source_maps/.github/workflows/test-package.yml +++ b/.github/workflows/source_maps.yaml @@ -1,17 +1,28 @@ -name: Dart CI +name: package:source_maps on: # Run on PRs and pushes to the default branch. push: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/source_maps.yaml' + - 'pkgs/source_maps/**' pull_request: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/source_maps.yaml' + - 'pkgs/source_maps/**' schedule: - cron: "0 0 * * 0" env: PUB_ENVIRONMENT: bot.github + +defaults: + run: + working-directory: pkgs/source_maps/ + jobs: # Check code formatting and static analysis on a single OS (linux) # against Dart dev. diff --git a/README.md b/README.md index 50517c36e..84b357157 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ don't naturally belong to other topic monorepos (like | [mime](pkgs/mime/) | Utilities for handling media (MIME) types, including determining a type from a file extension and file contents. | [![package issues](https://img.shields.io/badge/package:mime-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Amime) | [![pub package](https://img.shields.io/pub/v/mime.svg)](https://pub.dev/packages/mime) | | [oauth2](pkgs/oauth2/) | A client library for authenticating with a remote service via OAuth2 on behalf of a user, and making authorized HTTP requests with the user's OAuth2 credentials. | [![package issues](https://img.shields.io/badge/package:oauth2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aoauth2) | [![pub package](https://img.shields.io/pub/v/oauth2.svg)](https://pub.dev/packages/oauth2) | | [source_map_stack_trace](pkgs/source_map_stack_trace/) | A package for applying source maps to stack traces. | [![package issues](https://img.shields.io/badge/package:source_map_stack_trace-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_map_stack_trace) | [![pub package](https://img.shields.io/pub/v/source_map_stack_trace.svg)](https://pub.dev/packages/source_map_stack_trace) | +| [source_maps](pkgs/source_maps/) | A library to programmatically manipulate source map files. | [![package issues](https://img.shields.io/badge/package:source_maps-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_maps) | [![pub package](https://img.shields.io/pub/v/source_maps.svg)](https://pub.dev/packages/source_maps) | | [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [![package issues](https://img.shields.io/badge/package:unified_analytics-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [![pub package](https://img.shields.io/pub/v/unified_analytics.svg)](https://pub.dev/packages/unified_analytics) | ## Publishing automation diff --git a/pkgs/source_maps/.github/dependabot.yaml b/pkgs/source_maps/.github/dependabot.yaml deleted file mode 100644 index bf6b38a4d..000000000 --- a/pkgs/source_maps/.github/dependabot.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# Dependabot configuration file. -version: 2 - -updates: - - package-ecosystem: github-actions - directory: / - schedule: - interval: monthly - labels: - - autosubmit - groups: - github-actions: - patterns: - - "*" diff --git a/pkgs/source_maps/.github/workflows/no-response.yml b/pkgs/source_maps/.github/workflows/no-response.yml deleted file mode 100644 index ab1ac4984..000000000 --- a/pkgs/source_maps/.github/workflows/no-response.yml +++ /dev/null @@ -1,37 +0,0 @@ -# A workflow to close issues where the author hasn't responded to a request for -# more information; see https://github.com/actions/stale. - -name: No Response - -# Run as a daily cron. -on: - schedule: - # Every day at 8am - - cron: '0 8 * * *' - -# All permissions not specified are set to 'none'. -permissions: - issues: write - pull-requests: write - -jobs: - no-response: - runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'dart-lang' }} - steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e - with: - # Don't automatically mark inactive issues+PRs as stale. - days-before-stale: -1 - # Close needs-info issues and PRs after 14 days of inactivity. - days-before-close: 14 - stale-issue-label: "needs-info" - close-issue-message: > - Without additional information we're not able to resolve this issue. - Feel free to add more info or respond to any questions above and we - can reopen the case. Thanks for your contribution! - stale-pr-label: "needs-info" - close-pr-message: > - Without additional information we're not able to resolve this PR. - Feel free to add more info or respond to any questions above. - Thanks for your contribution! diff --git a/pkgs/source_maps/.github/workflows/publish.yaml b/pkgs/source_maps/.github/workflows/publish.yaml deleted file mode 100644 index 27157a046..000000000 --- a/pkgs/source_maps/.github/workflows/publish.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# A CI configuration to auto-publish pub packages. - -name: Publish - -on: - pull_request: - branches: [ master ] - push: - tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] - -jobs: - publish: - if: ${{ github.repository_owner == 'dart-lang' }} - uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main - permissions: - id-token: write # Required for authentication using OIDC - pull-requests: write # Required for writing the pull request note diff --git a/pkgs/source_maps/CHANGELOG.md b/pkgs/source_maps/CHANGELOG.md index 9c8e7b37e..ae7711e57 100644 --- a/pkgs/source_maps/CHANGELOG.md +++ b/pkgs/source_maps/CHANGELOG.md @@ -1,6 +1,7 @@ -## 0.10.13-wip +## 0.10.13 -- Require Dart 3.3 +* Require Dart 3.3 +* Move to `dart-lang/tools` monorepo. ## 0.10.12 diff --git a/pkgs/source_maps/README.md b/pkgs/source_maps/README.md index 30da7f8cd..cf8029177 100644 --- a/pkgs/source_maps/README.md +++ b/pkgs/source_maps/README.md @@ -1,4 +1,4 @@ -[![Dart CI](https://github.com/dart-lang/source_maps/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/source_maps/actions/workflows/test-package.yml) +[![Build Status](https://github.com/dart-lang/tools/actions/workflows/source_maps.yaml/badge.svg)](https://github.com/dart-lang/tools/actions/workflows/source_maps.yaml) [![pub package](https://img.shields.io/pub/v/source_maps.svg)](https://pub.dev/packages/source_maps) [![package publisher](https://img.shields.io/pub/publisher/source_maps.svg)](https://pub.dev/packages/source_maps/publisher) diff --git a/pkgs/source_maps/pubspec.yaml b/pkgs/source_maps/pubspec.yaml index 0c321dad9..8518fa756 100644 --- a/pkgs/source_maps/pubspec.yaml +++ b/pkgs/source_maps/pubspec.yaml @@ -1,5 +1,5 @@ name: source_maps -version: 0.10.13-wip +version: 0.10.13 description: A library to programmatically manipulate source map files. repository: https://github.com/dart-lang/tools/tree/main/pkgs/source_maps From e62561bdcea9dfc1107d340837041233922767eb Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 16:07:01 +0100 Subject: [PATCH 654/657] Add issue template and other fixes --- .github/ISSUE_TEMPLATE/source_span.md | 5 +++++ pkgs/source_span/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/source_span.md diff --git a/.github/ISSUE_TEMPLATE/source_span.md b/.github/ISSUE_TEMPLATE/source_span.md new file mode 100644 index 000000000..7dbb3c4f8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/source_span.md @@ -0,0 +1,5 @@ +--- +name: "package:source_span" +about: "Create a bug or file a feature request against package:source_span." +labels: "package:source_span" +--- \ No newline at end of file diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 3a7624ba3..9c39d1488 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -2,7 +2,7 @@ name: source_span version: 1.10.1-wip description: >- Provides a standard representation for source code locations and spans. -repository: https://github.com/dart-lang/source_span +repository: https://github.com/dart-lang/tools/tree/main/pkgs/source_span environment: sdk: ^3.1.0 From 887264f8949ef2a0e14a7e8d86bda27d7e91d0c8 Mon Sep 17 00:00:00 2001 From: Moritz Date: Tue, 10 Dec 2024 16:17:53 +0100 Subject: [PATCH 655/657] merge fixes --- .github/labeler.yml | 4 ++++ .../workflows/source_span.yaml | 17 ++++++++++++++--- README.md | 1 + pkgs/source_span/.github/dependabot.yml | 16 ---------------- pkgs/source_span/.github/workflows/publish.yaml | 14 -------------- pkgs/source_span/CHANGELOG.md | 3 ++- pkgs/source_span/README.md | 2 +- pkgs/source_span/pubspec.yaml | 2 +- 8 files changed, 23 insertions(+), 36 deletions(-) rename pkgs/source_span/.github/workflows/test-package.yml => .github/workflows/source_span.yaml (85%) delete mode 100644 pkgs/source_span/.github/dependabot.yml delete mode 100644 pkgs/source_span/.github/workflows/publish.yaml diff --git a/.github/labeler.yml b/.github/labeler.yml index eca80bbc2..de033db30 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -84,6 +84,10 @@ - changed-files: - any-glob-to-any-file: 'pkgs/source_map_stack_trace/**' +'package:source_span': + - changed-files: + - any-glob-to-any-file: 'pkgs/source_span/**' + 'package:unified_analytics': - changed-files: - any-glob-to-any-file: 'pkgs/unified_analytics/**' diff --git a/pkgs/source_span/.github/workflows/test-package.yml b/.github/workflows/source_span.yaml similarity index 85% rename from pkgs/source_span/.github/workflows/test-package.yml rename to .github/workflows/source_span.yaml index c8f1f52c7..2c2ba0548 100644 --- a/pkgs/source_span/.github/workflows/test-package.yml +++ b/.github/workflows/source_span.yaml @@ -1,17 +1,28 @@ -name: Dart CI +name: package:source_span on: # Run on PRs and pushes to the default branch. push: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/source_span.yml' + - 'pkgs/source_span/**' pull_request: - branches: [ master ] + branches: [ main ] + paths: + - '.github/workflows/source_span.yml' + - 'pkgs/source_span/**' schedule: - cron: "0 0 * * 0" env: PUB_ENVIRONMENT: bot.github + +defaults: + run: + working-directory: pkgs/source_span/ + jobs: # Check code formatting and static analysis on a single OS (linux) # against Dart dev. diff --git a/README.md b/README.md index 50517c36e..6b4fcf8a2 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ don't naturally belong to other topic monorepos (like | [mime](pkgs/mime/) | Utilities for handling media (MIME) types, including determining a type from a file extension and file contents. | [![package issues](https://img.shields.io/badge/package:mime-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Amime) | [![pub package](https://img.shields.io/pub/v/mime.svg)](https://pub.dev/packages/mime) | | [oauth2](pkgs/oauth2/) | A client library for authenticating with a remote service via OAuth2 on behalf of a user, and making authorized HTTP requests with the user's OAuth2 credentials. | [![package issues](https://img.shields.io/badge/package:oauth2-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aoauth2) | [![pub package](https://img.shields.io/pub/v/oauth2.svg)](https://pub.dev/packages/oauth2) | | [source_map_stack_trace](pkgs/source_map_stack_trace/) | A package for applying source maps to stack traces. | [![package issues](https://img.shields.io/badge/package:source_map_stack_trace-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_map_stack_trace) | [![pub package](https://img.shields.io/pub/v/source_map_stack_trace.svg)](https://pub.dev/packages/source_map_stack_trace) | +| [source_span](pkgs/source_span/) | Provides a standard representation for source code locations and spans. | [![package issues](https://img.shields.io/badge/package:source_span-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Asource_span) | [![pub package](https://img.shields.io/pub/v/source_span.svg)](https://pub.dev/packages/source_span) | | [unified_analytics](pkgs/unified_analytics/) | A package for logging analytics for all Dart and Flutter related tooling to Google Analytics. | [![package issues](https://img.shields.io/badge/package:unified_analytics-4774bc)](https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Aunified_analytics) | [![pub package](https://img.shields.io/pub/v/unified_analytics.svg)](https://pub.dev/packages/unified_analytics) | ## Publishing automation diff --git a/pkgs/source_span/.github/dependabot.yml b/pkgs/source_span/.github/dependabot.yml deleted file mode 100644 index eeaa9d9f4..000000000 --- a/pkgs/source_span/.github/dependabot.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Set update schedule for GitHub Actions -# See https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot - -version: 2 -updates: - -- package-ecosystem: github-actions - directory: / - schedule: - interval: monthly - labels: - - autosubmit - groups: - github-actions: - patterns: - - "*" diff --git a/pkgs/source_span/.github/workflows/publish.yaml b/pkgs/source_span/.github/workflows/publish.yaml deleted file mode 100644 index 2239b63d3..000000000 --- a/pkgs/source_span/.github/workflows/publish.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# A CI configuration to auto-publish pub packages. - -name: Publish - -on: - pull_request: - branches: [ master ] - push: - tags: [ 'v[0-9]+.[0-9]+.[0-9]+' ] - -jobs: - publish: - if: ${{ github.repository_owner == 'dart-lang' }} - uses: dart-lang/ecosystem/.github/workflows/publish.yaml@main diff --git a/pkgs/source_span/CHANGELOG.md b/pkgs/source_span/CHANGELOG.md index f46c1614b..b8319d773 100644 --- a/pkgs/source_span/CHANGELOG.md +++ b/pkgs/source_span/CHANGELOG.md @@ -1,6 +1,7 @@ -## 1.10.1-wip +## 1.10.1 * Require Dart 3.1 +* Move to `dart-lang/tools` monorepo. ## 1.10.0 diff --git a/pkgs/source_span/README.md b/pkgs/source_span/README.md index 0faf0cbc4..b4ce25fcf 100644 --- a/pkgs/source_span/README.md +++ b/pkgs/source_span/README.md @@ -1,4 +1,4 @@ -[![Dart CI](https://github.com/dart-lang/source_span/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/source_span/actions/workflows/test-package.yml) +[![Build Status](https://github.com/dart-lang/tools/actions/workflows/source_span.yaml/badge.svg)](https://github.com/dart-lang/tools/actions/workflows/source_span.yaml) [![pub package](https://img.shields.io/pub/v/source_span.svg)](https://pub.dev/packages/source_span) [![package publisher](https://img.shields.io/pub/publisher/source_span.svg)](https://pub.dev/packages/source_span/publisher) diff --git a/pkgs/source_span/pubspec.yaml b/pkgs/source_span/pubspec.yaml index 9c39d1488..8757b2dee 100644 --- a/pkgs/source_span/pubspec.yaml +++ b/pkgs/source_span/pubspec.yaml @@ -1,5 +1,5 @@ name: source_span -version: 1.10.1-wip +version: 1.10.1 description: >- Provides a standard representation for source code locations and spans. repository: https://github.com/dart-lang/tools/tree/main/pkgs/source_span From 28160af6c894c14867a4a8b23e3c45205a079e09 Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 11 Dec 2024 10:13:42 +0100 Subject: [PATCH 656/657] Upgrade major version --- pkgs/pool/CHANGELOG.md | 2 +- pkgs/pool/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index d7ab9abed..e9f37916b 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,4 +1,4 @@ -## 1.5.2 +## 2.0.0 * Require Dart 3.4. * Move to `dart-lang/tools` monorepo. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 4af8a71d2..7e6271226 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 1.5.2 +version: 2.0.0 description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests. From 01ef2b8d4289edac4cc3a23da3d1d2f45ec4d54f Mon Sep 17 00:00:00 2001 From: Moritz Date: Wed, 11 Dec 2024 10:16:31 +0100 Subject: [PATCH 657/657] use wip instead --- pkgs/pool/CHANGELOG.md | 2 +- pkgs/pool/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgs/pool/CHANGELOG.md b/pkgs/pool/CHANGELOG.md index e9f37916b..56424fc6f 100644 --- a/pkgs/pool/CHANGELOG.md +++ b/pkgs/pool/CHANGELOG.md @@ -1,4 +1,4 @@ -## 2.0.0 +## 1.5.2-wip * Require Dart 3.4. * Move to `dart-lang/tools` monorepo. diff --git a/pkgs/pool/pubspec.yaml b/pkgs/pool/pubspec.yaml index 7e6271226..a205b7494 100644 --- a/pkgs/pool/pubspec.yaml +++ b/pkgs/pool/pubspec.yaml @@ -1,5 +1,5 @@ name: pool -version: 2.0.0 +version: 1.5.2-wip description: >- Manage a finite pool of resources. Useful for controlling concurrent file system or network requests.