diff --git a/VM/private_named_parameters_t01.dart b/VM/private_named_parameters_t01.dart new file mode 100644 index 0000000000..567a815035 --- /dev/null +++ b/VM/private_named_parameters_t01.dart @@ -0,0 +1,188 @@ +// Copyright (c) 2025, 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. + +/// @assertion We let users use a private name in a named parameter when the +/// parameter also initializes or declares a field. The compiler removes the `_` +/// from the argument name but keeps it for the corresponding field. +/// +/// @description Check that private named parameters can be debugged. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=declaring-constructors,private-named-parameters + +import 'dart:developer'; +import 'package:vm_service/vm_service.dart'; + +import '../../../../pkg/vm_service/test/common/service_test_common.dart'; +import '../../../../pkg/vm_service/test/common/test_helper.dart'; +import '../Utils/expect.dart'; + +// AUTOGENERATED START +// +// Update these constants by running: +// +// dart pkg/vm_service/test/update_line_numbers.dart tests/co19/src/VM/private_named_parameters_t01.dart +// +const LINE_A = 37; +const LINE_B = 41; +const LINE_C = 45; +const LINE_D = 46; +const LINE_E = 47; +// AUTOGENERATED END + +class C1({var String _x}); // LINE_A + +class C2 { + String _x; + C2({required this._x}); // LINE_B +} + +class C3 { + int _x, _y; + C3({required this._x}) : _y = _x + 1; // LINE_C +} + +void testeeMain() { + debugger(); // LINE_D + C1(x: "xxx"); // LINE_E + C2(x: "yyy"); // LINE_F + C3(x: 1); // LINE_G +} + +final tests = [ + hasStoppedAtBreakpoint, + stoppedAtLine(LINE_D), + stepInto, + stoppedAtLine(LINE_E), + stepInto, + stoppedAtLine(LINE_A), + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + final xRef1 = + await service.evaluateInFrame(isolateId, 0, '_x') as InstanceRef; + Expect.equals("null", xRef1.valueAsString); + final xRef2 = + await service.evaluateInFrame(isolateId, 0, 'this._x') as InstanceRef; + Expect.equals("null", xRef2.valueAsString); + }, + stepInto, + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + final xRef1 = + await service.evaluateInFrame(isolateId, 0, '_x') as InstanceRef; + Expect.equals('xxx', xRef1.valueAsString); + final xRef2 = + await service.evaluateInFrame(isolateId, 0, 'this._x') as InstanceRef; + Expect.equals('xxx', xRef2.valueAsString); + final xRef3 = await service.evaluateInFrame(isolateId, 0, 'x'); + Expect.isTrue(xRef3 is ErrorRef); + final xRef4 = await service.evaluateInFrame(isolateId, 0, 'this.x'); + Expect.isTrue(xRef4 is ErrorRef); + }, + stepInto, + stoppedAtLine(LINE_F), + stepInto, + stoppedAtLine(LINE_B), + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + final xRef1 = + await service.evaluateInFrame(isolateId, 0, '_x') as InstanceRef; + Expect.equals("null", xRef1.valueAsString); + final xRef2 = + await service.evaluateInFrame(isolateId, 0, 'this._x') as InstanceRef; + Expect.equals("null", xRef2.valueAsString); + }, + stepInto, + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + final xRef1 = + await service.evaluateInFrame(isolateId, 0, '_x') as InstanceRef; + Expect.equals('yyy', xRef1.valueAsString); + final xRef2 = + await service.evaluateInFrame(isolateId, 0, 'this._x') as InstanceRef; + Expect.equals('yyy', xRef2.valueAsString); + final xRef3 = await service.evaluateInFrame(isolateId, 0, 'x'); + Expect.isTrue(xRef3 is ErrorRef); + final xRef4 = await service.evaluateInFrame(isolateId, 0, 'this.x'); + Expect.isTrue(xRef4 is ErrorRef); + }, + + stepInto, + stoppedAtLine(LINE_G), + stepInto, + stoppedAtLine(LINE_C), + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + final xRef1 = + await service.evaluateInFrame(isolateId, 0, '_x') as InstanceRef; + Expect.equals("null", xRef1.valueAsString); + final xRef2 = + await service.evaluateInFrame(isolateId, 0, 'this._x') as InstanceRef; + Expect.equals("null", xRef2.valueAsString); + final xRef3 = + await service.evaluateInFrame(isolateId, 0, '_y') as InstanceRef; + Expect.equals("null", xRef3.valueAsString); + final xRef4 = + await service.evaluateInFrame(isolateId, 0, 'this._y') as InstanceRef; + Expect.equals("null", xRef4.valueAsString); + }, + stepInto, + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + final xRef1 = + await service.evaluateInFrame(isolateId, 0, '_x') as InstanceRef; + Expect.equals('1', xRef1.valueAsString); + final xRef2 = + await service.evaluateInFrame(isolateId, 0, 'this._x') as InstanceRef; + Expect.equals('1', xRef2.valueAsString); + final xRef3 = + await service.evaluateInFrame(isolateId, 0, '_y') as InstanceRef; + Expect.equals('null', xRef3.valueAsString); + final xRef4 = + await service.evaluateInFrame(isolateId, 0, 'this._y') as InstanceRef; + Expect.equals('null', xRef3.valueAsString); + + final xRef5 = await service.evaluateInFrame(isolateId, 0, 'x'); + Expect.isTrue(xRef5 is ErrorRef); + final xRef6 = await service.evaluateInFrame(isolateId, 0, 'this.x'); + Expect.isTrue(xRef6 is ErrorRef); + final xRef7 = await service.evaluateInFrame(isolateId, 0, 'y'); + Expect.isTrue(xRef7 is ErrorRef); + final xRef8 = await service.evaluateInFrame(isolateId, 0, 'this.y'); + Expect.isTrue(xRef8 is ErrorRef); + }, + stepInto, + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + final xRef1 = + await service.evaluateInFrame(isolateId, 0, '_x') as InstanceRef; + Expect.equals('1', xRef1.valueAsString); + final xRef2 = + await service.evaluateInFrame(isolateId, 0, 'this._x') as InstanceRef; + Expect.equals('1', xRef2.valueAsString); + final xRef3 = + await service.evaluateInFrame(isolateId, 0, '_y') as InstanceRef; + Expect.equals('2', xRef3.valueAsString); + final xRef4 = + await service.evaluateInFrame(isolateId, 0, 'this._y') as InstanceRef; + Expect.equals('2', xRef3.valueAsString); + + final xRef5 = await service.evaluateInFrame(isolateId, 0, 'x'); + Expect.isTrue(xRef5 is ErrorRef); + final xRef6 = await service.evaluateInFrame(isolateId, 0, 'this.x'); + Expect.isTrue(xRef6 is ErrorRef); + final xRef7 = await service.evaluateInFrame(isolateId, 0, 'y'); + Expect.isTrue(xRef7 is ErrorRef); + final xRef8 = await service.evaluateInFrame(isolateId, 0, 'this.y'); + Expect.isTrue(xRef8 is ErrorRef); + }, +]; + +void main([args = const []]) => runIsolateTests( + args, + tests, + 'private_named_parameters_t01.dart', + pauseOnExit: true, + testeeConcurrent: testeeMain, +); diff --git a/VM/private_named_parameters_t02.dart b/VM/private_named_parameters_t02.dart new file mode 100644 index 0000000000..0cf618b501 --- /dev/null +++ b/VM/private_named_parameters_t02.dart @@ -0,0 +1,69 @@ +// Copyright (c) 2025, 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. + +/// @assertion We let users use a private name in a named parameter when the +/// parameter also initializes or declares a field. The compiler removes the `_` +/// from the argument name but keeps it for the corresponding field. +/// +/// @description Check that private named parameters are allowed in VM +/// expression evaluation. +/// @author sgrekhov22@gmail.com + +// SharedOptions=--enable-experiment=declaring-constructors,private-named-parameters + +import 'dart:developer'; + +import 'package:vm_service/vm_service.dart'; + +import '../../../../pkg/vm_service/test/common/service_test_common.dart'; +import '../../../../pkg/vm_service/test/common/test_helper.dart'; +import '../Utils/expect.dart'; + +class C1({var String _x}); + +class C2 { + String _x; + C2({required this._x}); +} + +void testeeMain() { + final c1 = C1(x: "one"); + final c2 = C2(x: "two"); + debugger(); +} + +final tests = [ + hasStoppedAtBreakpoint, + + // Test interaction of expression evaluation with private named parameters. + (VmService service, IsolateRef isolateRef) async { + final isolateId = isolateRef.id!; + + InstanceRef response = + await service.evaluateInFrame(isolateId, 0, 'c1._x') as InstanceRef; + Expect.equals('one', response.valueAsString); + + response = + await service.evaluateInFrame(isolateId, 0, 'c2._x') as InstanceRef; + Expect.equals('two', response.valueAsString); + + response = + await service.evaluateInFrame(isolateId, 0, 'C1(x: "zero")._x') + as InstanceRef; + Expect.equals('zero', response.valueAsString); + + response = + await service.evaluateInFrame(isolateId, 0, 'C2(x: "0")._x') + as InstanceRef; + Expect.equals('0', response.valueAsString); + }, +]; + +void main([args = const []]) => runIsolateTests( + args, + tests, + 'private_named_parameters_t02.dart', + pauseOnExit: true, + testeeConcurrent: testeeMain, +);