fb22849379
Follow-up from https://dart-review.googlesource.com/c/sdk/+/441840. Change-Id: I085099fde59fce052b01fd06a8cc41a83f55ac24 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/441941 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Auto-Submit: Danny Tuppeny <danny@tuppeny.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
100 lines
3.7 KiB
Dart
100 lines
3.7 KiB
Dart
// Copyright (c) 2022, 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:analysis_server/lsp_protocol/protocol.dart'
|
|
show Position, Range;
|
|
import 'package:analysis_server/src/lsp/mapping.dart';
|
|
import 'package:analyzer/source/line_info.dart';
|
|
import 'package:analyzer/src/test_utilities/test_code_format.dart';
|
|
import 'package:collection/collection.dart';
|
|
import 'package:test/test.dart' show expect;
|
|
|
|
extension ListTestCodePositionExtension on List<TestCodePosition> {
|
|
/// Return the LSP [Position]s of the markers.
|
|
///
|
|
/// Positions are based on [TestCode.code], with all parsed markers removed.
|
|
List<Position> get positions => map((position) => position.position).toList();
|
|
}
|
|
|
|
extension ListTestCodeRangeExtension on List<TestCodeRange> {
|
|
/// The LSP [Range]s indicated by the markers.
|
|
///
|
|
/// Ranges are based on [TestCode.code], with all parsed markers removed.
|
|
List<Range> get ranges => map((range) => range.range).toList();
|
|
}
|
|
|
|
extension TestCodeExtension on TestCode {
|
|
/// Return the offsets of all [positions].
|
|
List<int> get positionOffsets => positions.map((p) => p.offset).toList();
|
|
|
|
/// Verifies that [actualRanges] match with the marked ranges in [code].
|
|
///
|
|
/// This is done by taking the resulting code (without markers) and then
|
|
/// inserting the range markers from [actualRanges] and performing a string
|
|
/// comparison.
|
|
///
|
|
/// This can result in a simpler failure message/diff than having the JSON of
|
|
/// a large [List<Range>] dumped.
|
|
void verifyRanges(Iterable<Range> actualRanges) {
|
|
// First rewrite the marked code to have only ranges, and using the indexed
|
|
// markers. This removes any `^` we won't be verifing and changes any
|
|
// range shorthand to indexed tokens.
|
|
var expected = _withRanges(ranges.map((range) => range.range));
|
|
|
|
// Now build the same with the actual result ranges.
|
|
var actual = _withRanges(actualRanges);
|
|
|
|
expect(actual, expected);
|
|
}
|
|
|
|
/// Replaces all marked positions and ranges with [ranges].
|
|
String _withRanges(Iterable<Range> newRanges) {
|
|
var insertedCharacters = 0;
|
|
var rangeIndex = 0;
|
|
var newContent = code; // Start from the unmarked code.
|
|
var lineInfo = LineInfo.fromContent(newContent);
|
|
|
|
/// Helper to insert the markers for [range] into the content.
|
|
void markRange(Range range) {
|
|
/// Helper to insert [text] at [offset] in the content.
|
|
void insertText(int offset, String text) {
|
|
var adjustedOffset = insertedCharacters + offset;
|
|
newContent = newContent.replaceRange(
|
|
adjustedOffset,
|
|
adjustedOffset,
|
|
text,
|
|
);
|
|
insertedCharacters += text.length;
|
|
}
|
|
|
|
var startOffset = toOffset(lineInfo, range.start).result;
|
|
var endOffset = toOffset(lineInfo, range.end).result;
|
|
insertText(startOffset, '/*[$rangeIndex*/');
|
|
insertText(endOffset, '/*$rangeIndex]*/');
|
|
rangeIndex++;
|
|
}
|
|
|
|
var sortedRanges = newRanges.sortedBy(
|
|
(range) => toOffset(lineInfo, range.start).result,
|
|
);
|
|
sortedRanges.forEach(markRange);
|
|
|
|
return newContent;
|
|
}
|
|
}
|
|
|
|
extension TestCodePositionExtension on TestCodePosition {
|
|
/// Return the LSP [Position] of the marker.
|
|
///
|
|
/// Positions are based on [TestCode.code], with all parsed markers removed.
|
|
Position get position => toPosition(lineInfo.getLocation(offset));
|
|
}
|
|
|
|
extension TestCodeRangeExtension on TestCodeRange {
|
|
/// The LSP [Range] indicated by the markers.
|
|
///
|
|
/// Ranges are based on [TestCode.code], with all parsed markers removed.
|
|
Range get range => toRange(lineInfo, sourceRange.offset, sourceRange.length);
|
|
}
|