[vm] Pass offset and script uri for expression compilation

This CL passes the offset and uri of the file (here called a script uri
as opposed to a library uri, the two will be different if we're in a
part) when doing expression compilation.

This CL only passes the data, but doesn't actually use it.
Future CL(s) will use this data to calculate the static type of
available variables which is needed for an upcomming feature.

TEST=Existing tests.
CoreLibraryReviewExempt: Not changing SDK APIs.
Change-Id: I67ead461ab4bb9341424e693946f3e4afe35ce92
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/329322
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Jens Johansen 2023-10-12 10:22:38 +00:00 committed by Commit Queue
parent cdc16e7d3d
commit 73466729f3
14 changed files with 120 additions and 19 deletions

View file

@ -91,6 +91,7 @@ class ExpressionEvaluator {
'libraryUri': buildScopeResponseResult['libraryUri'],
'klass': buildScopeResponseResult['klass'],
'method': buildScopeResponseResult['method'],
'tokenPos': buildScopeResponseResult['tokenPos'],
'isStatic': buildScopeResponseResult['isStatic'],
};
@ -98,6 +99,10 @@ class ExpressionEvaluator {
if (klass != null) {
compileParams['klass'] = klass;
}
final scriptUri = buildScopeResponseResult['scriptUri'];
if (scriptUri != null) {
compileParams['scriptUri'] = scriptUri;
}
try {
return (await externalClient.sendRequest(
'compileExpression',

View file

@ -135,6 +135,8 @@ abstract class IncrementalKernelGenerator {
Uri libraryUri,
{String? className,
String? methodName,
int offset = -1,
String? scriptUri,
bool isStatic = false});
/// Sets experimental features.

View file

@ -1837,14 +1837,17 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
@override
Future<Procedure?> compileExpression(
String expression,
Map<String, DartType> definitions,
List<TypeParameter> typeDefinitions,
String syntheticProcedureName,
Uri libraryUri,
{String? className,
String? methodName,
bool isStatic = false}) async {
String expression,
Map<String, DartType> definitions,
List<TypeParameter> typeDefinitions,
String syntheticProcedureName,
Uri libraryUri, {
String? className,
String? methodName,
int offset = -1,
String? scriptUri,
bool isStatic = false,
}) async {
IncrementalKernelTarget? lastGoodKernelTarget = this._lastGoodKernelTarget;
assert(_dillLoadedData != null && lastGoodKernelTarget != null);

View file

@ -333,6 +333,8 @@ abstract class CompilerInterface {
String libraryUri,
String? klass,
String? method,
int offset,
String? scriptUri,
bool isStatic);
/// Compiles [expression] in [libraryUri] at [line]:[column] to JavaScript
@ -982,6 +984,8 @@ class FrontendCompiler implements CompilerInterface {
String libraryUri,
String? klass,
String? method,
int offset,
String? scriptUri,
bool isStatic) async {
final String boundaryKey = Uuid().generateV4();
_outputStream.writeln('result $boundaryKey');
@ -995,6 +999,8 @@ class FrontendCompiler implements CompilerInterface {
libraryUri,
klass,
method,
offset,
scriptUri,
isStatic);
if (procedure != null) {
Component component = createExpressionEvaluationComponent(procedure);
@ -1281,6 +1287,8 @@ class _CompileExpressionRequest {
late String library;
String? klass;
String? method;
int offset = -1;
String? scriptUri;
late bool isStatic;
}
@ -1466,6 +1474,8 @@ StreamSubscription<String> listenAndCompile(CompilerInterface compiler,
compileExpressionRequest.library,
compileExpressionRequest.klass,
compileExpressionRequest.method,
compileExpressionRequest.offset,
compileExpressionRequest.scriptUri,
compileExpressionRequest.isStatic);
} else {
compiler

View file

@ -525,12 +525,14 @@ Future _processExpressionCompilationRequest(request) async {
final String? klass = request[11];
final String? method = request[12];
final bool isStatic = request[13];
final List<List<int>> dillData = request[14].cast<List<int>>();
final int blobLoadCount = request[15];
final bool enableAsserts = request[16];
final int offset = request[14];
final String? scriptUri = request[15];
final List<List<int>> dillData = request[16].cast<List<int>>();
final int blobLoadCount = request[17];
final bool enableAsserts = request[18];
final List<String>? experimentalFlags =
request[17] != null ? request[17].cast<String>() : null;
final bool enableMirrors = request[18];
request[17] != null ? request[19].cast<String>() : null;
final bool enableMirrors = request[20];
IncrementalCompilerWrapper? compiler = isolateCompilers[isolateGroupId];
@ -652,6 +654,8 @@ Future _processExpressionCompilationRequest(request) async {
libraryUri,
klass,
method,
offset,
scriptUri,
isStatic);
if (procedure == null) {

View file

@ -215,6 +215,8 @@ class IncrementalCompiler {
String libraryUri,
String? klass,
String? method,
int offset,
String? scriptUri,
bool isStatic) {
ClassHierarchy? classHierarchy =
(_lastKnownGood ?? _combinePendingDeltas(false)).classHierarchy;
@ -249,8 +251,17 @@ class IncrementalCompiler {
Uri library = Uri.parse(libraryUri);
return _generator.compileExpression(expression, completeDefinitions,
typeParameters, kDebugProcedureName, library,
className: klass, methodName: method, isStatic: isStatic);
return _generator.compileExpression(
expression,
completeDefinitions,
typeParameters,
kDebugProcedureName,
library,
className: klass,
methodName: method,
offset: offset,
scriptUri: scriptUri,
isStatic: isStatic,
);
}
}

View file

@ -128,6 +128,8 @@ main() {
main.uri.toString(),
null,
null,
-1,
null,
true);
expect(procedure, isNotNull);
expect(errorsReported, equals(0));
@ -143,6 +145,8 @@ main() {
main.uri.toString(),
null,
null,
-1,
null,
true);
expect(procedure, isNotNull);
expect(errorsReported, equals(1));
@ -1092,6 +1096,8 @@ main() {
'package:foo/bar.dart',
'A',
null,
-1,
null,
true);
expect(procedure, isNotNull);
}
@ -1118,6 +1124,8 @@ main() {
'package:foo/bar.dart',
'A',
null,
-1,
null,
true);
expect(procedure, isNotNull);
}
@ -1177,6 +1185,8 @@ main() {
barUri.toString(),
'A',
null,
-1,
null,
true))!;
// Verify that the expression only has links to the only bar we know
// about.
@ -1233,6 +1243,8 @@ main() {
barUri.toString(),
'A',
null,
-1,
null,
true))!;
// Verify that the expression only has links to the original bar.
final LibraryReferenceCollector lrc = new LibraryReferenceCollector();
@ -1289,6 +1301,8 @@ main() {
v1Uri.toString(),
null,
null,
-1,
null,
false);
expect(procedure, isNotNull);
ReturnStatement returnStmt =
@ -1312,6 +1326,8 @@ main() {
v1Uri.toString(),
null,
null,
-1,
null,
false);
expect(procedure, isNotNull);
ReturnStatement returnStmt =

View file

@ -211,6 +211,8 @@ TEST_CASE(EvalExpression) {
Array::empty_array(), Array::empty_array(), Array::empty_array(),
String::Handle(lib_handle.url()).ToCString(), "A",
/* method= */ nullptr,
/* token_pos= */ TokenPosition::kNoSource,
/* script_uri= */ String::Handle(lib_handle.url()).ToCString(),
/* is_static= */ false);
EXPECT_EQ(Dart_KernelCompilationStatus_Ok, compilation_result.status);

View file

@ -186,6 +186,8 @@ Dart_Handle Dart_EvaluateStaticExpr(Dart_Handle lib_handle,
String::Handle(lib.url()).ToCString(),
/* klass= */ nullptr,
/* method= */ nullptr,
/* token_pos= */ TokenPosition::kNoSource,
/* script_uri= */ String::Handle(lib.url()).ToCString(),
/* is_static= */ true);
if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
return Api::NewError("Failed to compile expression.");

View file

@ -463,6 +463,8 @@ class KernelCompilationRequest : public ValueObject {
char const* library_uri,
char const* klass,
char const* method,
int64_t token_pos,
char const* script_uri,
bool is_static,
const MallocGrowableArray<char*>* experimental_flags) {
if (port_ == ILLEGAL_PORT) {
@ -605,6 +607,18 @@ class KernelCompilationRequest : public ValueObject {
is_static_object.type = Dart_CObject_kBool;
is_static_object.value.as_bool = is_static;
Dart_CObject token_pos_object;
token_pos_object.type = Dart_CObject_kInt64;
token_pos_object.value.as_int64 = token_pos;
Dart_CObject script_uri_object;
if (script_uri != nullptr) {
script_uri_object.type = Dart_CObject_kString;
script_uri_object.value.as_string = const_cast<char*>(script_uri);
} else {
script_uri_object.type = Dart_CObject_kNull;
}
auto isolate_group = thread->isolate_group();
auto source = isolate_group->source();
@ -699,6 +713,8 @@ class KernelCompilationRequest : public ValueObject {
&class_object,
&method_object,
&is_static_object,
&token_pos_object,
&script_uri_object,
&dills_object,
&num_blob_loads,
&enable_asserts,
@ -1206,6 +1222,8 @@ Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
const char* library_url,
const char* klass,
const char* method,
TokenPosition token_pos,
const char* script_uri,
bool is_static) {
Dart_Port kernel_port = WaitForKernelPort();
if (kernel_port == ILLEGAL_PORT) {
@ -1215,14 +1233,19 @@ Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
return result;
}
intptr_t token_pos_int = -1;
if (token_pos.IsReal()) {
token_pos_int = token_pos.Pos();
}
TransitionVMToNative transition(Thread::Current());
KernelCompilationRequest request;
ASSERT(is_static || (klass != nullptr));
return request.SendAndWaitForResponse(
kernel_port, platform_kernel, platform_kernel_size, expression,
definitions, definition_types, type_definitions, type_bounds,
type_defaults, library_url, klass, method, is_static,
experimental_flags_);
type_defaults, library_url, klass, method, token_pos_int, script_uri,
is_static, experimental_flags_);
}
Dart_KernelCompilationResult KernelIsolate::UpdateInMemorySources(

View file

@ -93,6 +93,8 @@ class KernelIsolate : public AllStatic {
const char* library_url,
const char* klass,
const char* method,
TokenPosition token_pos,
char const* script_uri,
bool is_static);
static Dart_KernelCompilationResult ListDependencies();

View file

@ -2989,6 +2989,8 @@ static void BuildExpressionEvaluationScope(Thread* thread, JSONStream* js) {
String& method_name = String::Handle(zone);
String& library_uri = String::Handle(zone);
bool isStatic = false;
String& script_uri = String::Handle(zone);
TokenPosition token_pos = TokenPosition::kNoSource;
if (BuildScope(thread, js, param_names, param_values)) {
return;
@ -3004,6 +3006,8 @@ static void BuildExpressionEvaluationScope(Thread* thread, JSONStream* js) {
}
ActivationFrame* frame = stack->FrameAt(framePos);
script_uri = frame->SourceUrl();
token_pos = frame->TokenPos();
frame->BuildParameters(param_names, param_values, type_params_names,
type_params_bounds, type_params_defaults);
@ -3155,6 +3159,10 @@ static void BuildExpressionEvaluationScope(Thread* thread, JSONStream* js) {
if (!method_name.IsNull()) {
report.AddProperty("method", method_name.ToCString());
}
report.AddProperty("tokenPos", token_pos);
if (!script_uri.IsNull()) {
report.AddProperty("scriptUri", script_uri.ToCString());
}
report.AddProperty("isStatic", isStatic);
}
@ -3207,6 +3215,10 @@ static const MethodParameter* const compile_expression_params[] = {
new StringParameter("klass", false),
new BoolParameter("isStatic", false),
new StringParameter("method", false),
new Int64Parameter("tokenPos", false),
// TODO(jensj): Uncomment this line when DDS has rolled into flutter
// (https://dart-review.googlesource.com/c/sdk/+/329322).
// new StringParameter("scriptUri", false),
nullptr,
};
@ -3229,6 +3241,7 @@ static void CompileExpression(Thread* thread, JSONStream* js) {
const char* klass = js->LookupParam("klass");
bool is_static =
BoolParameter::Parse(js->LookupParam("isStatic"), (klass == nullptr));
int64_t token_pos = Int64Parameter::Parse(js->LookupParam("tokenPos"));
const GrowableObjectArray& params =
GrowableObjectArray::Handle(thread->zone(), GrowableObjectArray::New());
@ -3274,7 +3287,8 @@ static void CompileExpression(Thread* thread, JSONStream* js) {
Array::Handle(Array::MakeFixedLength(type_bounds)),
Array::Handle(Array::MakeFixedLength(type_defaults)),
js->LookupParam("libraryUri"), js->LookupParam("klass"),
js->LookupParam("method"), is_static);
js->LookupParam("method"), TokenPosition::Deserialize(token_pos),
js->LookupParam("scriptUri"), is_static);
if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
js->PrintError(kExpressionCompilationError, "%s", compilation_result.error);

View file

@ -661,6 +661,8 @@ Dart_Handle TestCase::EvaluateExpression(const Library& lib,
String::Handle(lib.url()).ToCString(),
/* klass= */ nullptr,
/* method= */ nullptr,
/* token_pos= */ TokenPosition::kNoSource,
/* script_uri= */ String::Handle(lib.url()).ToCString(),
/* is_static= */ true);
if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
return Api::NewError("%s", compilation_result.error);

View file

@ -134,12 +134,17 @@ class _Evaluator {
'typeBounds': buildScopeResponseResult['type_params_bounds']!,
'typeDefaults': buildScopeResponseResult['type_params_defaults']!,
'libraryUri': buildScopeResponseResult['libraryUri']!,
'tokenPos': buildScopeResponseResult['tokenPos']!,
'isStatic': buildScopeResponseResult['isStatic']!,
};
final klass = buildScopeResponseResult['klass'];
if (klass != null) {
compileParams['klass'] = klass;
}
final scriptUri = buildScopeResponseResult['scriptUri'];
if (scriptUri != null) {
compileParams['scriptUri'] = scriptUri;
}
final method = buildScopeResponseResult['method'];
if (method != null) {
compileParams['method'] = method;