From 7caa65225b2100422247e56ef41b20100339022b Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Thu, 5 Dec 2024 12:13:34 -0500 Subject: [PATCH 1/8] Added support for getClassMetadata with the DDc library bundle format --- dwds/CHANGELOG.md | 2 +- dwds/lib/src/debugging/classes.dart | 10 +- .../src/debugging/dart_runtime_debugger.dart | 26 +++- .../instances/class_inspection_amd_test.dart | 35 +++++ ...ss_inspection_ddc_library_bundle_test.dart | 37 +++++ .../test/instances/class_inspection_test.dart | 127 ------------------ .../common/class_inspection_common.dart | 121 +++++++++++++++++ 7 files changed, 221 insertions(+), 137 deletions(-) create mode 100644 dwds/test/instances/class_inspection_amd_test.dart create mode 100644 dwds/test/instances/class_inspection_ddc_library_bundle_test.dart delete mode 100644 dwds/test/instances/class_inspection_test.dart create mode 100644 dwds/test/instances/common/class_inspection_common.dart diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 35ab4ea1e..3ba030af7 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -11,7 +11,7 @@ to use the provided `name` in a `ModuleMetadata`. Metadata provided by DDC when using the library bundle format does not provide a useful bundle name. - Migrate to `package:web` v1.1.0. -- Added support for some debugging APIs with the DDC library bundle format. - [#2488](https://github.com/dart-lang/webdev/issues/2488) +- Added support for some debugging APIs with the DDC library bundle format. - [#2488](https://github.com/dart-lang/webdev/issues/2488), [#2534](https://github.com/dart-lang/webdev/issues/2534) ## 24.1.0 diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index 3cfe3eed7..72d2f467d 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -77,14 +77,8 @@ class ClassHelper extends Domain { if (libraryUri == null || classId == null || className == null) return null; - final expression = ''' - (function() { - const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk'); - const dart = sdk.dart; - return dart.getClassMetadata('$libraryUri', '$className'); - })() - '''; - + final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .getClassMetadataJsExpression(libraryUri, className); RemoteObject result; try { result = await inspector.remoteDebugger.evaluate( diff --git a/dwds/lib/src/debugging/dart_runtime_debugger.dart b/dwds/lib/src/debugging/dart_runtime_debugger.dart index 76f2cc06a..beb2f6520 100644 --- a/dwds/lib/src/debugging/dart_runtime_debugger.dart +++ b/dwds/lib/src/debugging/dart_runtime_debugger.dart @@ -14,6 +14,7 @@ class DartRuntimeDebugger { }) : _loadStrategy = loadStrategy, _useLibraryBundleExpression = useLibraryBundleExpression; + /// Generates a JS expression based on DDC module format. String _generateJsExpression( String ddcExpression, String libraryBundleExpression, @@ -23,16 +24,18 @@ class DartRuntimeDebugger { : ddcExpression; } + /// Wraps a JS function call with SDK loader logic. String _wrapWithSdkLoader(String args, String functionCall) { return ''' function($args) { - const sdk = ${_loadStrategy.loadModuleSnippet}("dart_sdk"); + const sdk = ${_loadStrategy.loadModuleSnippet}('dart_sdk'); const dart = sdk.dart; return dart.$functionCall; } '''; } + /// Wraps a JS function call with DDC library bundle loader logic. String _wrapWithBundleLoader(String args, String functionCall) { return ''' function($args) { @@ -41,6 +44,12 @@ class DartRuntimeDebugger { '''; } + /// Wraps an expression in an Immediately Invoked Function Expression (IIFE). + String _wrapInIIFE(String expression) { + return '($expression)()'; + } + + /// Builds a JS expression based on the loading strategy. String _buildExpression( String args, String ddcFunction, @@ -52,6 +61,7 @@ class DartRuntimeDebugger { ); } + /// Generates a JS expression for retrieving object metadata. String getObjectMetadataJsExpression() { return _buildExpression( 'arg', @@ -60,6 +70,7 @@ class DartRuntimeDebugger { ); } + /// Generates a JS expression for retrieving object field names. String getObjectFieldNamesJsExpression() { return _buildExpression( '', @@ -68,6 +79,7 @@ class DartRuntimeDebugger { ); } + /// Generates a JS expression for retrieving function metadata. String getFunctionMetadataJsExpression() { return _buildExpression( '', @@ -76,6 +88,7 @@ class DartRuntimeDebugger { ); } + /// Generates a JS expression for retrieving a subrange of elements. String getSubRangeJsExpression() { return _buildExpression( 'offset, count', @@ -83,4 +96,15 @@ class DartRuntimeDebugger { 'getSubRange(this, offset, count)', ); } + + /// Generates a JS expression for retrieving class metadata. + String getClassMetadataJsExpression(String libraryUri, String className) { + final expression = _buildExpression( + '', + "getClassMetadata('$libraryUri', '$className')", + "getClassMetadata('$libraryUri', '$className')", + ); + // Use the helper method to wrap this in an IIFE + return _wrapInIIFE(expression); + } } diff --git a/dwds/test/instances/class_inspection_amd_test.dart b/dwds/test/instances/class_inspection_amd_test.dart new file mode 100644 index 000000000..1815be2e3 --- /dev/null +++ b/dwds/test/instances/class_inspection_amd_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2023, 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. + +@Tags(['daily']) +@TestOn('vm') +@Timeout(Duration(minutes: 2)) +library; + +import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; + +import '../fixtures/context.dart'; +import 'common/class_inspection_common.dart'; + +void main() { + // Enable verbose logging for debugging. + final debug = false; + final canaryFeatures = false; + + group('Class |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + ); + tearDownAll(provider.dispose); + for (final compilationMode in CompilationMode.values) { + runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } + }); +} diff --git a/dwds/test/instances/class_inspection_ddc_library_bundle_test.dart b/dwds/test/instances/class_inspection_ddc_library_bundle_test.dart new file mode 100644 index 000000000..2f54f5fbc --- /dev/null +++ b/dwds/test/instances/class_inspection_ddc_library_bundle_test.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2024, 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. + +@Tags(['daily']) +@TestOn('vm') +@Timeout(Duration(minutes: 2)) +library; + +import 'package:dwds/expression_compiler.dart'; +import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; + +import '../fixtures/context.dart'; +import 'common/class_inspection_common.dart'; + +void main() { + // Enable verbose logging for debugging. + final debug = false; + final canaryFeatures = true; + final compilationMode = CompilationMode.frontendServer; + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.ddc, + ); + + group('Class |', () { + tearDownAll(provider.dispose); + runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + }); +} diff --git a/dwds/test/instances/class_inspection_test.dart b/dwds/test/instances/class_inspection_test.dart deleted file mode 100644 index a54afc7d9..000000000 --- a/dwds/test/instances/class_inspection_test.dart +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) 2023, 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. - -@Tags(['daily']) -@TestOn('vm') -@Timeout(Duration(minutes: 2)) -library; - -import 'package:test/test.dart'; -import 'package:test_common/logging.dart'; -import 'package:test_common/test_sdk_configuration.dart'; -import 'package:vm_service/vm_service.dart'; - -import '../fixtures/context.dart'; -import '../fixtures/project.dart'; -import '../fixtures/utilities.dart'; -import 'common/test_inspector.dart'; - -void main() { - // Enable verbose logging for debugging. - final debug = false; - - final provider = TestSdkConfigurationProvider( - verbose: debug, - ); - - final context = TestContext(TestProject.testExperiment, provider); - final testInspector = TestInspector(context); - - late VmService service; - late Stream stream; - late String isolateId; - late ScriptRef mainScript; - - Future onBreakPoint(breakPointId, body) => testInspector.onBreakPoint( - stream, - isolateId, - mainScript, - breakPointId, - body, - ); - - Future getObject(instanceId) => service.getObject(isolateId, instanceId); - - group('Class |', () { - tearDownAll(provider.dispose); - - for (final compilationMode in CompilationMode.values) { - group('$compilationMode |', () { - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - testSettings: TestSettings( - compilationMode: compilationMode, - enableExpressionEvaluation: true, - verboseCompiler: debug, - ), - ); - service = context.debugConnection.vmService; - - final vm = await service.getVM(); - isolateId = vm.isolates!.first.id!; - final scripts = await service.getScripts(isolateId); - - await service.streamListen('Debug'); - stream = service.onEvent('Debug'); - - mainScript = scripts.scripts! - .firstWhere((each) => each.uri!.contains('main.dart')); - }); - - tearDownAll(() async { - await context.tearDown(); - }); - - setUp(() => setCurrentLogWriter(debug: debug)); - tearDown(() => service.resume(isolateId)); - - group('calling getObject for an existent class', () { - test('returns the correct class representation', () async { - await onBreakPoint('testClass1Case1', (event) async { - // classes|dart:core|Object_Diagnosticable - final result = await getObject( - 'classes|org-dartlang-app:///web/main.dart|GreeterClass', - ); - final clazz = result as Class?; - expect(clazz!.name, equals('GreeterClass')); - expect( - clazz.fields!.map((field) => field.name), - unorderedEquals([ - 'greeteeName', - 'useFrench', - ]), - ); - expect( - clazz.functions!.map((fn) => fn.name), - containsAll([ - 'sayHello', - 'greetInEnglish', - 'greetInFrench', - ]), - ); - }); - }); - }); - - group('calling getObject for a non-existent class', () { - // TODO(https://github.com/dart-lang/webdev/issues/2297): Ideally we - // should throw an error in this case for the client to catch instead - // of returning an empty class. - test('returns an empty class representation', () async { - await onBreakPoint('testClass1Case1', (event) async { - final result = await getObject( - 'classes|dart:core|Object_Diagnosticable', - ); - final clazz = result as Class?; - expect(clazz!.name, equals('Object_Diagnosticable')); - expect(clazz.fields, isEmpty); - expect(clazz.functions, isEmpty); - }); - }); - }); - }); - } - }); -} diff --git a/dwds/test/instances/common/class_inspection_common.dart b/dwds/test/instances/common/class_inspection_common.dart new file mode 100644 index 000000000..f3c7f2b7d --- /dev/null +++ b/dwds/test/instances/common/class_inspection_common.dart @@ -0,0 +1,121 @@ +// Copyright (c) 2023, 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. + +@Tags(['daily']) +@TestOn('vm') +@Timeout(Duration(minutes: 2)) +library; + +import 'package:test/test.dart'; +import 'package:test_common/logging.dart'; +import 'package:test_common/test_sdk_configuration.dart'; +import 'package:vm_service/vm_service.dart'; + +import '../../fixtures/context.dart'; +import '../../fixtures/project.dart'; +import '../../fixtures/utilities.dart'; +import '../common/test_inspector.dart'; + +void runTests({ + required TestSdkConfigurationProvider provider, + required CompilationMode compilationMode, + required bool canaryFeatures, + required bool debug, +}) { + final context = TestContext(TestProject.testExperiment, provider); + final testInspector = TestInspector(context); + + late VmService service; + late Stream stream; + late String isolateId; + late ScriptRef mainScript; + + Future onBreakPoint(breakPointId, body) => testInspector.onBreakPoint( + stream, + isolateId, + mainScript, + breakPointId, + body, + ); + + Future getObject(instanceId) => service.getObject(isolateId, instanceId); + + group('$compilationMode |', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + testSettings: TestSettings( + compilationMode: compilationMode, + enableExpressionEvaluation: true, + verboseCompiler: debug, + canaryFeatures: canaryFeatures, + moduleFormat: provider.ddcModuleFormat, + ), + ); + service = context.debugConnection.vmService; + + final vm = await service.getVM(); + isolateId = vm.isolates!.first.id!; + final scripts = await service.getScripts(isolateId); + + await service.streamListen('Debug'); + stream = service.onEvent('Debug'); + + mainScript = scripts.scripts! + .firstWhere((each) => each.uri!.contains('main.dart')); + }); + + tearDownAll(() async { + await context.tearDown(); + }); + + setUp(() => setCurrentLogWriter(debug: debug)); + tearDown(() => service.resume(isolateId)); + + group('calling getObject for an existent class', () { + test('returns the correct class representation', () async { + await onBreakPoint('testClass1Case1', (event) async { + // classes|dart:core|Object_Diagnosticable + final result = await getObject( + 'classes|org-dartlang-app:///web/main.dart|GreeterClass', + ); + final clazz = result as Class?; + expect(clazz!.name, equals('GreeterClass')); + expect( + clazz.fields!.map((field) => field.name), + unorderedEquals([ + 'greeteeName', + 'useFrench', + ]), + ); + expect( + clazz.functions!.map((fn) => fn.name), + containsAll([ + 'sayHello', + 'greetInEnglish', + 'greetInFrench', + ]), + ); + }); + }); + }); + + group('calling getObject for a non-existent class', () { + // TODO(https://github.com/dart-lang/webdev/issues/2297): Ideally we + // should throw an error in this case for the client to catch instead + // of returning an empty class. + test('returns an empty class representation', () async { + await onBreakPoint('testClass1Case1', (event) async { + final result = await getObject( + 'classes|dart:core|Object_Diagnosticable', + ); + final clazz = result as Class?; + expect(clazz!.name, equals('Object_Diagnosticable')); + expect(clazz.fields, isEmpty); + expect(clazz.functions, isEmpty); + }); + }); + }); + }); +} From f3b2bd7b4305108525502a4208348376d5bd9449 Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Thu, 12 Dec 2024 12:17:43 -0500 Subject: [PATCH 2/8] Added support for some debugging APIs with the DDC library bundle format. --- dwds/CHANGELOG.md | 1 + .../src/debugging/dart_runtime_debugger.dart | 49 +++++++++++++++++++ dwds/lib/src/debugging/inspector.dart | 11 ++--- dwds/lib/src/debugging/instance.dart | 7 +-- dwds/lib/src/debugging/libraries.dart | 9 +--- .../common/instance_inspection_common.dart | 3 +- ... instance_inspection_amd_canary_test.dart} | 4 +- ...dart => instance_inspection_amd_test.dart} | 4 +- ...ce_inspection_ddc_library_bundle_test.dart | 37 ++++++++++++++ 9 files changed, 105 insertions(+), 20 deletions(-) rename dwds/test/instances/{instance_inspection_canary_test.dart => instance_inspection_amd_canary_test.dart} (83%) rename dwds/test/instances/{instance_inspection_test.dart => instance_inspection_amd_test.dart} (83%) create mode 100644 dwds/test/instances/instance_inspection_ddc_library_bundle_test.dart diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 3ad574c28..12955ec7a 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -1,6 +1,7 @@ ## 24.2.1-wip - Update to be forward compatible with changes to `package:shelf_web_socket`. +- Added support for some debugging APIs with the DDC library bundle format. - [#2537](https://github.com/dart-lang/webdev/issues/2537) ## 24.2.0 diff --git a/dwds/lib/src/debugging/dart_runtime_debugger.dart b/dwds/lib/src/debugging/dart_runtime_debugger.dart index beb2f6520..2363621bc 100644 --- a/dwds/lib/src/debugging/dart_runtime_debugger.dart +++ b/dwds/lib/src/debugging/dart_runtime_debugger.dart @@ -107,4 +107,53 @@ class DartRuntimeDebugger { // Use the helper method to wrap this in an IIFE return _wrapInIIFE(expression); } + + /// Generates a JS expression for retrieving extension names. + String getExtensionNamesJsExpression() { + return _generateJsExpression( + "${_loadStrategy.loadModuleSnippet}('dart_sdk').developer._extensions.keys.toList();", + 'dartDevEmbedder.debugger.extensionNames', + ); + } + + /// Generates a JS expression for retrieving library metadata. + String getLibraryMetadataJsExpression(String libraryUri) { + final expression = _buildExpression( + '', + "getLibraryMetadata('$libraryUri')", + "getClassesInLibrary('$libraryUri')", + ); + // Use the helper method to wrap this in an IIFE + return _wrapInIIFE(expression); + } + + /// Generates a JS expression for retrieving map elements. + String getMapElementsJsExpression() { + return _buildExpression( + '', + 'getMapElements(this)', + 'getMapElements(this)', + ); + } + + /// Generates a JS expression for dynamically loading an object's field. + String dloadReplJsExpression(String fieldName) { + return _generateJsExpression( + _wrapWithSdkLoader('', 'dloadRepl(this, "$fieldName")'), + ''' + function() { + return this["$fieldName"]; + } + ''', + ); + } + + /// Generates a JS expression for retrieving set elements. + String getSetElementsJsExpression() { + return _buildExpression( + '', + 'getSetElements(this)', + 'getSetElements(this)', + ); + } } diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 49a3b443a..1bfc4beec 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -192,11 +192,8 @@ class AppInspector implements AppInspectorInterface { /// Get the value of the field named [fieldName] from [receiver]. @override Future loadField(RemoteObject receiver, String fieldName) { - final load = ''' - function() { - return ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk").dart.dloadRepl(this, "$fieldName"); - } - '''; + final load = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .dloadReplJsExpression(fieldName); return jsCallFunctionOn(receiver, load, []); } @@ -748,8 +745,8 @@ class AppInspector implements AppInspectorInterface { /// Runs an eval on the page to compute all existing registered extensions. Future> _getExtensionRpcs() async { - final expression = - "${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk').developer._extensions.keys.toList();"; + final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .getExtensionNamesJsExpression(); final extensionRpcs = []; final params = { 'expression': expression, diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index e11e9dda5..35c8698f9 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -306,7 +306,8 @@ class InstanceHelper extends Domain { // We do this in in awkward way because we want the keys and values, but we // can't return things by value or some Dart objects will come back as // values that we need to be RemoteObject, e.g. a List of int. - final expression = _jsRuntimeFunctionCall('getMapElements(this)'); + final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .getMapElementsJsExpression(); final keysAndValues = await inspector.jsCallFunctionOn(map, expression, []); final keys = await inspector.loadField(keysAndValues, 'keys'); @@ -674,8 +675,8 @@ class InstanceHelper extends Domain { final length = metaData.length; final objectId = remoteObject.objectId; if (objectId == null) return null; - - final expression = _jsRuntimeFunctionCall('getSetElements(this)'); + final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .getSetElementsJsExpression(); final result = await inspector.jsCallFunctionOn(remoteObject, expression, []); diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index f36e11e6a..841194cdf 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -82,13 +82,8 @@ class LibraryHelper extends Domain { final libraryUri = libraryRef.uri; if (libraryId == null || libraryUri == null) return null; // Fetch information about all the classes in this library. - final expression = ''' - (function() { - const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk'); - const dart = sdk.dart; - return dart.getLibraryMetadata('$libraryUri'); - })() - '''; + final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .getLibraryMetadataJsExpression(libraryUri); RemoteObject? result; try { diff --git a/dwds/test/instances/common/instance_inspection_common.dart b/dwds/test/instances/common/instance_inspection_common.dart index 099d326cf..170c9292b 100644 --- a/dwds/test/instances/common/instance_inspection_common.dart +++ b/dwds/test/instances/common/instance_inspection_common.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2023-2024, 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. @@ -62,6 +62,7 @@ void runTests({ verboseCompiler: debug, canaryFeatures: canaryFeatures, experiments: ['records'], + moduleFormat: provider.ddcModuleFormat, ), ); service = context.debugConnection.vmService; diff --git a/dwds/test/instances/instance_inspection_canary_test.dart b/dwds/test/instances/instance_inspection_amd_canary_test.dart similarity index 83% rename from dwds/test/instances/instance_inspection_canary_test.dart rename to dwds/test/instances/instance_inspection_amd_canary_test.dart index 68e36b829..60bb04635 100644 --- a/dwds/test/instances/instance_inspection_canary_test.dart +++ b/dwds/test/instances/instance_inspection_amd_canary_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2020-2024, 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. @@ -7,6 +7,7 @@ @Timeout(Duration(minutes: 2)) library; +import 'package:dwds/src/services/expression_compiler.dart'; import 'package:test/test.dart'; import 'package:test_common/test_sdk_configuration.dart'; @@ -22,6 +23,7 @@ void main() { final provider = TestSdkConfigurationProvider( verbose: debug, canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.amd, ); tearDownAll(provider.dispose); diff --git a/dwds/test/instances/instance_inspection_test.dart b/dwds/test/instances/instance_inspection_amd_test.dart similarity index 83% rename from dwds/test/instances/instance_inspection_test.dart rename to dwds/test/instances/instance_inspection_amd_test.dart index 8765583e8..3c3d2e128 100644 --- a/dwds/test/instances/instance_inspection_test.dart +++ b/dwds/test/instances/instance_inspection_amd_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2020-2024, 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. @@ -7,6 +7,7 @@ @Timeout(Duration(minutes: 2)) library; +import 'package:dwds/src/services/expression_compiler.dart'; import 'package:test/test.dart'; import 'package:test_common/test_sdk_configuration.dart'; @@ -22,6 +23,7 @@ void main() { final provider = TestSdkConfigurationProvider( verbose: debug, canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.amd, ); tearDownAll(provider.dispose); diff --git a/dwds/test/instances/instance_inspection_ddc_library_bundle_test.dart b/dwds/test/instances/instance_inspection_ddc_library_bundle_test.dart new file mode 100644 index 000000000..bfca2b3c7 --- /dev/null +++ b/dwds/test/instances/instance_inspection_ddc_library_bundle_test.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2024, 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. + +@Tags(['daily']) +@TestOn('vm') +@Timeout(Duration(minutes: 2)) +library; + +import 'package:dwds/expression_compiler.dart'; +import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; + +import '../fixtures/context.dart'; +import 'common/instance_inspection_common.dart'; + +void main() { + // Enable verbose logging for debugging. + final debug = false; + final canaryFeatures = true; + final compilationMode = CompilationMode.frontendServer; + + group('canary: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.ddc, + ); + tearDownAll(provider.dispose); + runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + }); +} From a1f017c3bea5b4ce02b5fa506c0b452a15c86a64 Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Fri, 13 Dec 2024 10:58:32 -0500 Subject: [PATCH 3/8] Update pattern test to account for new DDC JS variable naming --- dwds/test/instances/common/patterns_inspection_common.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dwds/test/instances/common/patterns_inspection_common.dart b/dwds/test/instances/common/patterns_inspection_common.dart index 935ab91d8..d2bf17ec2 100644 --- a/dwds/test/instances/common/patterns_inspection_common.dart +++ b/dwds/test/instances/common/patterns_inspection_common.dart @@ -98,8 +98,10 @@ void runTests({ expect(await getFrameVariables(frame), { 'obj': matchListInstance(type: 'Object'), - 'a': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'b'), - 'n': matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3.14), + // Renamed to avoid shadowing variables from previous case. + 'a\$': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'b'), + 'n\$': + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3.14), }); }); }); From 58b8762a54f79fe1e7c30cccae63332b33f6c8a8 Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Fri, 13 Dec 2024 12:19:59 -0500 Subject: [PATCH 4/8] reverting change to pattern test --- dwds/test/instances/common/patterns_inspection_common.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dwds/test/instances/common/patterns_inspection_common.dart b/dwds/test/instances/common/patterns_inspection_common.dart index d2bf17ec2..935ab91d8 100644 --- a/dwds/test/instances/common/patterns_inspection_common.dart +++ b/dwds/test/instances/common/patterns_inspection_common.dart @@ -98,10 +98,8 @@ void runTests({ expect(await getFrameVariables(frame), { 'obj': matchListInstance(type: 'Object'), - // Renamed to avoid shadowing variables from previous case. - 'a\$': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'b'), - 'n\$': - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3.14), + 'a': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'b'), + 'n': matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3.14), }); }); }); From c781e5ffded553ac4864cd463020059d85f726d4 Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Fri, 13 Dec 2024 14:30:57 -0500 Subject: [PATCH 5/8] Added support for debugging API with the DDC library bundle format. --- dwds/CHANGELOG.md | 2 +- .../src/debugging/dart_runtime_debugger.dart | 8 ++++ dwds/lib/src/debugging/instance.dart | 3 +- .../common/record_inspection_common.dart | 1 + ...=> record_inspection_amd_canary_test.dart} | 4 +- ...t.dart => record_inspection_amd_test.dart} | 4 +- ...rd_inspection_ddc_library_bundle_test.dart | 37 +++++++++++++++++++ 7 files changed, 55 insertions(+), 4 deletions(-) rename dwds/test/instances/{record_inspection_canary_test.dart => record_inspection_amd_canary_test.dart} (83%) rename dwds/test/instances/{record_inspection_test.dart => record_inspection_amd_test.dart} (83%) create mode 100644 dwds/test/instances/record_inspection_ddc_library_bundle_test.dart diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 12955ec7a..55eb577d2 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -1,7 +1,7 @@ ## 24.2.1-wip - Update to be forward compatible with changes to `package:shelf_web_socket`. -- Added support for some debugging APIs with the DDC library bundle format. - [#2537](https://github.com/dart-lang/webdev/issues/2537) +- Added support for some debugging APIs with the DDC library bundle format. - [#2537](https://github.com/dart-lang/webdev/issues/2537),[#2544](https://github.com/dart-lang/webdev/issues/2544) ## 24.2.0 diff --git a/dwds/lib/src/debugging/dart_runtime_debugger.dart b/dwds/lib/src/debugging/dart_runtime_debugger.dart index 2363621bc..951fd531b 100644 --- a/dwds/lib/src/debugging/dart_runtime_debugger.dart +++ b/dwds/lib/src/debugging/dart_runtime_debugger.dart @@ -156,4 +156,12 @@ class DartRuntimeDebugger { 'getSetElements(this)', ); } + + String getRecordFieldsJsExpression() { + return _buildExpression( + '', + 'getRecordFields(this)', + 'getRecordFields(this)', + ); + } } diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index 35c8698f9..2815b255a 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -524,7 +524,8 @@ class InstanceHelper extends Domain { // We do this in in awkward way because we want the keys and values, but we // can't return things by value or some Dart objects will come back as // values that we need to be RemoteObject, e.g. a List of int. - final expression = _jsRuntimeFunctionCall('getRecordFields(this)'); + final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .getRecordFieldsJsExpression(); final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = diff --git a/dwds/test/instances/common/record_inspection_common.dart b/dwds/test/instances/common/record_inspection_common.dart index a5e6e837d..a1bbdd161 100644 --- a/dwds/test/instances/common/record_inspection_common.dart +++ b/dwds/test/instances/common/record_inspection_common.dart @@ -66,6 +66,7 @@ void runTests({ verboseCompiler: debug, experiments: ['records', 'patterns'], canaryFeatures: canaryFeatures, + moduleFormat: provider.ddcModuleFormat, ), ); service = context.debugConnection.vmService; diff --git a/dwds/test/instances/record_inspection_canary_test.dart b/dwds/test/instances/record_inspection_amd_canary_test.dart similarity index 83% rename from dwds/test/instances/record_inspection_canary_test.dart rename to dwds/test/instances/record_inspection_amd_canary_test.dart index c1b79e7cb..37a649b70 100644 --- a/dwds/test/instances/record_inspection_canary_test.dart +++ b/dwds/test/instances/record_inspection_amd_canary_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2023-2024, 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. @@ -7,6 +7,7 @@ @Timeout(Duration(minutes: 2)) library; +import 'package:dwds/src/services/expression_compiler.dart'; import 'package:test/test.dart'; import 'package:test_common/test_sdk_configuration.dart'; @@ -22,6 +23,7 @@ void main() { final provider = TestSdkConfigurationProvider( verbose: debug, canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.amd, ); tearDownAll(provider.dispose); diff --git a/dwds/test/instances/record_inspection_test.dart b/dwds/test/instances/record_inspection_amd_test.dart similarity index 83% rename from dwds/test/instances/record_inspection_test.dart rename to dwds/test/instances/record_inspection_amd_test.dart index a8af90b88..726a1d988 100644 --- a/dwds/test/instances/record_inspection_test.dart +++ b/dwds/test/instances/record_inspection_amd_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2023-2024, 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. @@ -7,6 +7,7 @@ @Timeout(Duration(minutes: 2)) library; +import 'package:dwds/src/services/expression_compiler.dart'; import 'package:test/test.dart'; import 'package:test_common/test_sdk_configuration.dart'; @@ -22,6 +23,7 @@ void main() { final provider = TestSdkConfigurationProvider( verbose: debug, canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.amd, ); tearDownAll(provider.dispose); diff --git a/dwds/test/instances/record_inspection_ddc_library_bundle_test.dart b/dwds/test/instances/record_inspection_ddc_library_bundle_test.dart new file mode 100644 index 000000000..deb18060a --- /dev/null +++ b/dwds/test/instances/record_inspection_ddc_library_bundle_test.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2024, 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. + +@Tags(['daily']) +@TestOn('vm') +@Timeout(Duration(minutes: 2)) +library; + +import 'package:dwds/src/services/expression_compiler.dart'; +import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; + +import '../fixtures/context.dart'; +import 'common/record_inspection_common.dart'; + +void main() { + // Enable verbose logging for debugging. + final debug = false; + final canaryFeatures = true; + final compilationMode = CompilationMode.frontendServer; + + group('canary: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.ddc, + ); + tearDownAll(provider.dispose); + runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + }); +} From 0b235e6fda66614b05768bf989301e9b105ce52c Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Tue, 17 Dec 2024 13:40:44 -0500 Subject: [PATCH 6/8] updated licenses --- dwds/test/instances/record_inspection_amd_canary_test.dart | 2 +- dwds/test/instances/record_inspection_amd_test.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dwds/test/instances/record_inspection_amd_canary_test.dart b/dwds/test/instances/record_inspection_amd_canary_test.dart index 37a649b70..7c2c5c0a8 100644 --- a/dwds/test/instances/record_inspection_amd_canary_test.dart +++ b/dwds/test/instances/record_inspection_amd_canary_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2024, 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. diff --git a/dwds/test/instances/record_inspection_amd_test.dart b/dwds/test/instances/record_inspection_amd_test.dart index 726a1d988..afee36510 100644 --- a/dwds/test/instances/record_inspection_amd_test.dart +++ b/dwds/test/instances/record_inspection_amd_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2024, 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. From 607c7e41619c0000d7901a3a38d54995da73a193 Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Tue, 17 Dec 2024 13:43:08 -0500 Subject: [PATCH 7/8] updated licenses and remove new line from changelog --- dwds/CHANGELOG.md | 1 - dwds/test/instances/common/instance_inspection_common.dart | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 16c076010..55eb577d2 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -3,7 +3,6 @@ - Update to be forward compatible with changes to `package:shelf_web_socket`. - Added support for some debugging APIs with the DDC library bundle format. - [#2537](https://github.com/dart-lang/webdev/issues/2537),[#2544](https://github.com/dart-lang/webdev/issues/2544) - ## 24.2.0 - Consolidate `FrontendServerDdcStrategyProvider` and `FrontendServerRequireStrategyProvider` under a shared parent class. - [#2517](https://github.com/dart-lang/webdev/issues/2517) diff --git a/dwds/test/instances/common/instance_inspection_common.dart b/dwds/test/instances/common/instance_inspection_common.dart index 170c9292b..c0d57ed76 100644 --- a/dwds/test/instances/common/instance_inspection_common.dart +++ b/dwds/test/instances/common/instance_inspection_common.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023-2024, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2023, 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. From b9a8c2fe683f10f3233446905af76b756cd88f63 Mon Sep 17 00:00:00 2001 From: Jessy Yameogo Date: Wed, 18 Dec 2024 13:12:17 -0500 Subject: [PATCH 8/8] Added support for some debugging APIs with the DDC library bundle format - getRecordTypeFieldsJsExpression, callInstanceMethodJsExpression --- dwds/CHANGELOG.md | 2 +- .../src/debugging/dart_runtime_debugger.dart | 30 +++++++++++++++ dwds/lib/src/debugging/inspector.dart | 8 +--- dwds/lib/src/debugging/instance.dart | 11 +----- .../common/record_type_inspection_common.dart | 1 + ...cord_type_inspection_amd_canary_test.dart} | 4 +- ...t => record_type_inspection_amd_test.dart} | 4 +- ...pe_inspection_ddc_library_bundle_test.dart | 37 +++++++++++++++++++ 8 files changed, 79 insertions(+), 18 deletions(-) rename dwds/test/instances/{record_type_inspection_canary_test.dart => record_type_inspection_amd_canary_test.dart} (86%) rename dwds/test/instances/{record_type_inspection_test.dart => record_type_inspection_amd_test.dart} (86%) create mode 100644 dwds/test/instances/record_type_inspection_ddc_library_bundle_test.dart diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 55eb577d2..3aa5919d9 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -1,7 +1,7 @@ ## 24.2.1-wip - Update to be forward compatible with changes to `package:shelf_web_socket`. -- Added support for some debugging APIs with the DDC library bundle format. - [#2537](https://github.com/dart-lang/webdev/issues/2537),[#2544](https://github.com/dart-lang/webdev/issues/2544) +- Added support for some debugging APIs with the DDC library bundle format. - [#2537](https://github.com/dart-lang/webdev/issues/2537),[#2544](https://github.com/dart-lang/webdev/issues/2544),[#2548](https://github.com/dart-lang/webdev/issues/2548) ## 24.2.0 diff --git a/dwds/lib/src/debugging/dart_runtime_debugger.dart b/dwds/lib/src/debugging/dart_runtime_debugger.dart index 90b47d581..e09c86e5d 100644 --- a/dwds/lib/src/debugging/dart_runtime_debugger.dart +++ b/dwds/lib/src/debugging/dart_runtime_debugger.dart @@ -169,4 +169,34 @@ class DartRuntimeDebugger { 'getRecordFields(this)', ); } + + /// Generates a JS expression for retrieving the fields of a record type. + String getRecordTypeFieldsJsExpression() { + return _buildExpression( + '', + 'getRecordTypeFields(this)', + 'getRecordTypeFields(this)', + ); + } + + /// Generates a JS expression for calling an instance method on an object. + String callInstanceMethodJsExpression(String methodName) { + String generateInstanceMethodJsExpression(String functionCall) { + return ''' + function () { + if (!Object.getPrototypeOf(this)) { return 'Instance of PlainJavaScriptObject'; } + return $functionCall; + } + '''; + } + + return _generateJsExpression( + generateInstanceMethodJsExpression( + '${_loadStrategy.loadModuleSnippet}("dart_sdk").dart.dsendRepl(this, "$methodName", arguments)', + ), + generateInstanceMethodJsExpression( + 'dartDevEmbedder.debugger.callInstanceMethod(this, "$methodName", arguments)', + ), + ); + } } diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 23f47504d..4ce408b3d 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -210,12 +210,8 @@ class AppInspector implements AppInspectorInterface { throw UnsupportedError('Named arguments are not yet supported'); } // We use the JS pseudo-variable 'arguments' to get the list of all arguments. - final send = ''' - function () { - if (!Object.getPrototypeOf(this)) { return 'Instance of PlainJavaScriptObject';} - return ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk").dart.dsendRepl(this, "$methodName", arguments); - } - '''; + final send = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .callInstanceMethodJsExpression(methodName); final remote = await jsCallFunctionOn(receiver, send, positionalArgs); return remote; } diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index 2815b255a..0db74d5ae 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -653,7 +653,8 @@ class InstanceHelper extends Domain { // We do this in in awkward way because we want the names and types, but we // can't return things by value or some Dart objects will come back as // values that we need to be RemoteObject, e.g. a List of int. - final expression = _jsRuntimeFunctionCall('getRecordTypeFields(this)'); + final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger + .getRecordTypeFieldsJsExpression(); final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = @@ -887,11 +888,3 @@ class InstanceHelper extends Domain { } } } - -String _jsRuntimeFunctionCall(String expression) => ''' - function() { - const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk'); - const dart = sdk.dart; - return dart.$expression; - } -'''; diff --git a/dwds/test/instances/common/record_type_inspection_common.dart b/dwds/test/instances/common/record_type_inspection_common.dart index 2d51bee26..241195da5 100644 --- a/dwds/test/instances/common/record_type_inspection_common.dart +++ b/dwds/test/instances/common/record_type_inspection_common.dart @@ -64,6 +64,7 @@ void runTests({ verboseCompiler: debug, experiments: ['records', 'patterns'], canaryFeatures: canaryFeatures, + moduleFormat: provider.ddcModuleFormat, ), ); service = context.debugConnection.vmService; diff --git a/dwds/test/instances/record_type_inspection_canary_test.dart b/dwds/test/instances/record_type_inspection_amd_canary_test.dart similarity index 86% rename from dwds/test/instances/record_type_inspection_canary_test.dart rename to dwds/test/instances/record_type_inspection_amd_canary_test.dart index 2bc861f58..02d5f826b 100644 --- a/dwds/test/instances/record_type_inspection_canary_test.dart +++ b/dwds/test/instances/record_type_inspection_amd_canary_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2024, 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. @@ -7,6 +7,7 @@ @Timeout(Duration(minutes: 2)) library; +import 'package:dwds/expression_compiler.dart'; import 'package:test/test.dart'; import 'package:test_common/test_sdk_configuration.dart'; @@ -22,6 +23,7 @@ void main() { final provider = TestSdkConfigurationProvider( verbose: debug, canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.amd, ); tearDownAll(provider.dispose); diff --git a/dwds/test/instances/record_type_inspection_test.dart b/dwds/test/instances/record_type_inspection_amd_test.dart similarity index 86% rename from dwds/test/instances/record_type_inspection_test.dart rename to dwds/test/instances/record_type_inspection_amd_test.dart index 342d75b4e..d471b0769 100644 --- a/dwds/test/instances/record_type_inspection_test.dart +++ b/dwds/test/instances/record_type_inspection_amd_test.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// Copyright (c) 2024, 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. @@ -7,6 +7,7 @@ @Timeout(Duration(minutes: 2)) library; +import 'package:dwds/expression_compiler.dart'; import 'package:test/test.dart'; import 'package:test_common/test_sdk_configuration.dart'; @@ -22,6 +23,7 @@ void main() { final provider = TestSdkConfigurationProvider( verbose: debug, canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.amd, ); tearDownAll(provider.dispose); diff --git a/dwds/test/instances/record_type_inspection_ddc_library_bundle_test.dart b/dwds/test/instances/record_type_inspection_ddc_library_bundle_test.dart new file mode 100644 index 000000000..9e5cb3c11 --- /dev/null +++ b/dwds/test/instances/record_type_inspection_ddc_library_bundle_test.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2024, 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. + +@Tags(['daily']) +@TestOn('vm') +@Timeout(Duration(minutes: 2)) +library; + +import 'package:dwds/expression_compiler.dart'; +import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; + +import '../fixtures/context.dart'; +import 'common/record_type_inspection_common.dart'; + +void main() { + // Enable verbose logging for debugging. + final debug = false; + final canaryFeatures = true; + final compilationMode = CompilationMode.frontendServer; + + group('canary: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, + ddcModuleFormat: ModuleFormat.ddc, + ); + tearDownAll(provider.dispose); + runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + }); +}