[analyzer] Check conditional directive URIs are within the requested range

Change-Id: Icec5f864484a67dc3a64ace06704d8266d88c12b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/202772
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Danny Tuppeny 2021-06-08 20:32:09 +00:00 committed by commit-bot@chromium.org
parent 8357efa65c
commit eb2836872a
2 changed files with 59 additions and 8 deletions

View file

@ -139,6 +139,37 @@ main() {
expect(testTargets[0].kind, ElementKind.LIBRARY);
}
Future<void> test_importUri_configurations() async {
final ioFile = newFile(join(testFolder, 'io.dart'));
final htmlFile = newFile(join(testFolder, 'html.dart'));
addTestFile('''
import 'foo.dart'
if (dart.library.io) 'io.dart'
if (dart.library.html) 'html.dart';
main() {
}''');
await waitForTasksFinished();
// Request navigations for 'io.dart'
await _getNavigation(testFile, 41, 9);
expect(regions, hasLength(1));
assertHasRegionString("'io.dart'");
expect(testTargets, hasLength(1));
var target = testTargets.first;
expect(target.kind, ElementKind.LIBRARY);
expect(targetFiles[target.fileIndex], equals(ioFile.path));
// Request navigations for 'html.dart'
await _getNavigation(testFile, 76, 11);
expect(regions, hasLength(1));
assertHasRegionString("'html.dart'");
expect(testTargets, hasLength(1));
target = testTargets.first;
expect(target.kind, ElementKind.LIBRARY);
expect(targetFiles[target.fileIndex], equals(htmlFile.path));
}
Future<void> test_invalidFilePathFormat_notAbsolute() async {
var request = _createGetNavigationRequest('test.dart', 0, 0);
var response = await waitResponse(request);

View file

@ -68,9 +68,7 @@ class _DartNavigationCollector {
return;
}
// Discard elements that don't span the offset/range given (if provided).
if (requestedOffset != null &&
(offset > requestedOffset! + (requestedLength ?? 0) ||
offset + length < requestedOffset!)) {
if (!_isWithinRequestedRange(offset, length)) {
return;
}
var converter = AnalyzerConverter();
@ -154,6 +152,26 @@ class _DartNavigationCollector {
offset: codeOffset, length: codeLength);
}
/// Checks if offset/length intersect with the range the user requested
/// navigation regions for.
///
/// If the request did not specify a range, always returns true.
bool _isWithinRequestedRange(int offset, int length) {
final requestedOffset = this.requestedOffset;
if (requestedOffset == null) {
return true;
}
if (offset > requestedOffset + (requestedLength ?? 0)) {
// Starts after the requested range.
return false;
}
if (offset + length < requestedOffset) {
// Ends before the requested range.
return false;
}
return true;
}
static ElementDeclarationResult? _parsedDeclaration(Element element) {
var session = element.session;
if (session == null) {
@ -243,11 +261,13 @@ class _DartNavigationComputerVisitor extends RecursiveAstVisitor<void> {
// TODO(brianwilkerson) If the analyzer ever resolves the URI to a
// library, use that library element to create the region.
var uriNode = node.uri;
computer.collector.addRegion(
uriNode.offset,
uriNode.length,
protocol.ElementKind.LIBRARY,
protocol.Location(source.fullName, 0, 0, 0, 0, 0, 0));
if (computer._isWithinRequestedRange(uriNode.offset, uriNode.length)) {
computer.collector.addRegion(
uriNode.offset,
uriNode.length,
protocol.ElementKind.LIBRARY,
protocol.Location(source.fullName, 0, 0, 0, 0, 0, 0));
}
}
}
super.visitConfiguration(node);