[ Service ] Allow for case insensitive URI mappings on Windows and MacOS

The Windows and MacOS file system can be case insensitive, so the following
two URIs can be equivalent:

 - file:///c:/foo/bar
 - file:///C:/Foo/Bar

Since it's possible for tooling to request a mapping for a URI that
isn't an exact case-sensitive match to that found in the URI mappings
cache, requesting a mapping for the inexact match will fail even though
the paths are potentially equivalent.

This change allows for lookupPackageUris and lookupResolvedPackageUris
to correctly handle paths that are not case-sensitive matches to entries
in the URI mappings cache on Windows and MacOS.

TEST=uri_mappings_lookup_test.dart

Change-Id: I35134c47bf3bd04bc452373b31b4eb5893ba1435
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/288821
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Helin Shiah <helinx@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi 2023-03-20 17:21:27 +00:00 committed by Commit Queue
parent 4faf18deaf
commit a62bfec074
3 changed files with 41 additions and 5 deletions

View file

@ -18,6 +18,7 @@ final tests = <IsolateTest>[
'dart:io', // dart:io -> org-dartlang-sdk:///sdk/lib/io/io.dart
'package:pool/pool.dart', // package:pool/pool.dart -> file:///some_dir/pool/lib/pool.dart
scriptUri, // file:///abc.dart -> file:///abc.dart
if (Platform.isWindows || Platform.isMacOS) scriptUri.toUpperCase(),
];
var result = await isolate.invokeRpcNoUpgrade('lookupResolvedPackageUris', {
@ -25,26 +26,33 @@ final tests = <IsolateTest>[
});
expect(result['uris'], isNotNull);
var uris = result['uris'].cast<String?>();
expect(uris.length, 4);
expect(uris.length, unresolvedUris.length);
expect(uris[0], isNull);
expect(uris[1], 'org-dartlang-sdk:///sdk/lib/io/io.dart');
expect(uris[2], startsWith('file:///'));
expect(uris[2], endsWith('third_party/pkg/pool/lib/pool.dart'));
expect(uris[3], scriptUri);
if (Platform.isWindows || Platform.isMacOS) {
expect(uris[4], scriptUri);
}
result = await isolate.invokeRpcNoUpgrade('lookupPackageUris', {
'uris': [
'does_not_exist.dart',
...uris.sublist(1, 4),
if (Platform.isWindows || Platform.isMacOS) scriptUri.toUpperCase(),
]
});
expect(result['uris'], isNotNull);
uris = result['uris'].cast<String?>();
expect(uris.length, 4);
expect(uris.length, unresolvedUris.length);
expect(uris[0], isNull);
expect(uris[1], unresolvedUris[1]);
expect(uris[2], unresolvedUris[2]);
expect(uris[3], unresolvedUris[3]);
if (Platform.isWindows || Platform.isMacOS) {
expect(uris[4], scriptUri);
}
},
];

View file

@ -18,6 +18,7 @@ final tests = <IsolateTest>[
'dart:io', // dart:io -> org-dartlang-sdk:///sdk/lib/io/io.dart
'package:pool/pool.dart', // package:pool/pool.dart -> file:///some_dir/pool/lib/pool.dart
scriptUri, // file:///abc.dart -> file:///abc.dart
if (Platform.isWindows || Platform.isMacOS) scriptUri.toUpperCase(),
];
var result = await isolate.invokeRpcNoUpgrade('lookupResolvedPackageUris', {
@ -25,26 +26,33 @@ final tests = <IsolateTest>[
});
expect(result['uris'], isNotNull);
var uris = result['uris'].cast<String>();
expect(uris.length, 4);
expect(uris.length, unresolvedUris.length);
expect(uris[0], isNull);
expect(uris[1], 'org-dartlang-sdk:///sdk/lib/io/io.dart');
expect(uris[2], startsWith('file:///'));
expect(uris[2], endsWith('third_party/pkg/pool/lib/pool.dart'));
expect(uris[3], scriptUri);
if (Platform.isWindows || Platform.isMacOS) {
expect(uris[4], scriptUri);
}
result = await isolate.invokeRpcNoUpgrade('lookupPackageUris', {
'uris': [
'does_not_exist.dart',
...uris.sublist(1, 4),
if (Platform.isWindows || Platform.isMacOS) scriptUri.toUpperCase(),
]
});
expect(result['uris'], isNotNull);
uris = result['uris'].cast<String>();
expect(uris.length, 4);
expect(uris.length, unresolvedUris.length);
expect(uris[0], isNull);
expect(uris[1], unresolvedUris[1]);
expect(uris[2], unresolvedUris[2]);
expect(uris[3], unresolvedUris[3]);
if (Platform.isWindows || Platform.isMacOS) {
expect(uris[4], scriptUri);
}
},
];

View file

@ -5230,7 +5230,9 @@ static void PopulateUriMappings(Thread* thread) {
Array& scripts = Array::Handle(zone);
String& uri = String::Handle(zone);
String& resolved_uri = String::Handle(zone);
#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_MACOS)
String& tmp = thread->StringHandle();
#endif
for (intptr_t i = 0; i < num_libs; ++i) {
lib ^= libs.At(i);
scripts ^= lib.LoadedScripts();
@ -5241,6 +5243,15 @@ static void PopulateUriMappings(Thread* thread) {
resolved_uri ^= script.resolved_url();
uri_to_resolved_uri.UpdateOrInsert(uri, resolved_uri);
resolved_uri_to_uri.UpdateOrInsert(resolved_uri, uri);
#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_MACOS)
// Allow for case insensitive matching on platforms that might allow for
// case insensitive paths.
tmp = String::ToLowerCase(uri);
uri_to_resolved_uri.UpdateOrInsert(tmp, resolved_uri);
tmp = String::ToLowerCase(resolved_uri);
resolved_uri_to_uri.UpdateOrInsert(tmp, uri);
#endif
}
}
@ -5291,6 +5302,15 @@ static void LookupScriptUrisImpl(Thread* thread,
for (intptr_t i = 0; i < uris.Length(); ++i) {
uri ^= uris.At(i);
res ^= map.GetOrNull(uri);
#if defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_MACOS)
// Windows and MacOS paths can be case insensitive, so we should allow for
// case insensitive URI mappings on Windows and MacOS.
if (res.IsNull()) {
String& lower_case_uri = thread->StringHandle();
lower_case_uri = String::ToLowerCase(uri);
res ^= map.GetOrNull(lower_case_uri);
}
#endif // defined(DART_HOST_OS_WINDOWS) || defined(DART_HOST_OS_MACOS)
if (res.IsNull()) {
uris_array.AddValueNull();
} else {