[VM Service] Fix Windows expression evaluation type crash in experimental service

Correctly define `kRootLibraryUri` constant and forward `rootLibraryUri`
to the resident frontend compiler.

TAG=agy
CONV=ae3a29f5-e2c8-499c-b221-ff61e40f5f1f

Change-Id: Ie4c87857744d9b32165ea7d0f8004d6d6c337886
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505161
Auto-Submit: Ben Konyi <bkonyi@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi
2026-05-29 13:18:35 -07:00
committed by dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent d6889ba492
commit 85da4dfd46
3 changed files with 24 additions and 4 deletions
@@ -53,6 +53,7 @@ final class VmExpressionEvaluator extends ExpressionEvaluator {
static const kKlass = 'klass';
static const kMethod = 'method';
static const kScriptUri = 'scriptUri';
static const kRootLibraryUri = 'rootLibraryUri';
// Keys for scope response.
static const kParamNames = 'param_names';
@@ -250,6 +251,7 @@ final class VmExpressionEvaluator extends ExpressionEvaluator {
offset: scope[kTokenPos] as int,
scriptUri: scriptUri,
isStatic: isStatic,
rootLibraryUri: scope[kRootLibraryUri] as String?,
serverInfoFile: backend.residentCompilerInfoFile!,
);
return {kKernelBytes: result.kernelBytes};
@@ -247,6 +247,7 @@ Future<CompileExpressionResult> invokeCompileExpression({
required int offset,
required String? scriptUri,
required bool isStatic,
String? rootLibraryUri,
required File serverInfoFile,
}) async {
final Map<String, Object?> response = await sendAndReceiveResponse(
@@ -264,6 +265,7 @@ Future<CompileExpressionResult> invokeCompileExpression({
'offset': offset,
if (scriptUri != null) 'scriptUri': scriptUri,
'isStatic': isStatic,
if (rootLibraryUri != null) 'rootLibraryUri': rootLibraryUri,
'useCachedCompilerOptionsAsBase': true,
}),
serverInfoFile,
@@ -48,6 +48,22 @@ extension on DateTime {
}
}
/// Safely converts [maybeUri] to a local file path.
///
/// Returns [maybeUri] as-is if it is already a raw path (e.g. `C:\foo.dart`
/// or `/foo.dart`) or a non-file URI. This avoids crashes on Windows where
/// drive letters (like `C:`) are incorrectly interpreted as URI schemes by
/// [Uri.parse].
String _maybeUriToFilename(String maybeUri) {
final Uri? uri = Uri.tryParse(maybeUri);
if (uri != null && (uri.scheme == 'file' || uri.scheme == '')) {
try {
return uri.toFilePath();
} catch (_) {}
}
return maybeUri;
}
enum _ResidentState { waitingForFirstCompile, compiling, waitingForRecompile }
/// A wrapper around the FrontendCompiler, along with all the state needed
@@ -520,16 +536,16 @@ class ResidentFrontendServer {
// evaluation is taking place to compute [canonicalizedLibraryPath]
// instead.
canonicalizedLibraryPath = path.canonicalize(
Uri.parse(request[_rootLibraryUriString]).toFilePath(),
_maybeUriToFilename(request[_rootLibraryUriString]),
);
} else {
canonicalizedLibraryPath = path.canonicalize(
Uri.parse(request[_libraryUriString]).toFilePath(),
_maybeUriToFilename(request[_libraryUriString]),
);
}
} catch (e) {
} catch (e, st) {
return _encodeErrorMessage(
"Request contains invalid '$_libraryUriString' property",
"Request contains invalid '$_libraryUriString' property: $e\n$st",
);
}