From b0ebf4027ac67af71ac030d2c379d0bba82106a1 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 23 Jun 2023 10:07:35 -0700 Subject: [PATCH 01/24] Use DDC debugger API --- dwds/lib/src/debugging/classes.dart | 27 ++- dwds/lib/src/debugging/inspector.dart | 22 +- dwds/lib/src/debugging/instance.dart | 125 ++++++++-- dwds/lib/src/debugging/libraries.dart | 35 ++- dwds/lib/src/debugging/metadata/class.dart | 202 +++++++++++---- dwds/lib/src/loaders/strategy.dart | 9 +- .../services/expression_compiler_service.dart | 5 + dwds/test/fixtures/context.dart | 25 +- dwds/test/fixtures/project.dart | 13 + .../instances/instance_inspection_common.dart | 62 +++-- .../instances/instance_inspection_test.dart | 48 ++-- dwds/test/instances/instance_test.dart | 81 +++++-- .../instances/patterns_inspection_test.dart | 229 +++++++++--------- .../instances/record_inspection_test.dart | 36 ++- .../record_type_inspection_test.dart | 36 ++- dwds/test/instances/type_inspection_test.dart | 49 ++-- fixtures/_webdevSoundSmoke/web/main.dart | 12 + .../lib/src/asset_server.dart | 4 +- frontend_server_common/lib/src/devfs.dart | 11 +- .../lib/src/frontend_server_client.dart | 3 + .../lib/src/resident_runner.dart | 3 + test_common/lib/sdk_asset_generator.dart | 18 +- test_common/lib/test_sdk_configuration.dart | 8 +- .../test/sdk_asset_generator_test.dart | 7 +- 24 files changed, 766 insertions(+), 304 deletions(-) diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index bc425141a..027d5a622 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -7,11 +7,14 @@ import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/services/chrome_debug_exception.dart'; import 'package:dwds/src/utilities/domain.dart'; import 'package:dwds/src/utilities/shared.dart'; +import 'package:logging/logging.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; /// Keeps track of Dart classes available in the running application. class ClassHelper extends Domain { + final _logger = Logger('ClassHelper'); + /// Map of class ID to [Class]. final _classes = {}; @@ -77,15 +80,23 @@ class ClassHelper extends Domain { if (libraryUri == null || classId == null || className == null) return null; - final rawName = className.split('<').first; + //final rawName = className.split('<').first; final expression = ''' + (function() { + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.getClassMetadata('$libraryUri', '$className'); + })() + '''; + + /*final expression = ''' (function() { ${globalLoadStrategy.loadLibrarySnippet(libraryUri)} var result = {}; var clazz = library["$rawName"]; var descriptor = { 'name': clazz.name, - 'dartName': sdkUtils.typeName(clazz) + 'dartName': dart.typeName(clazz) }; // TODO(grouma) - we display all inherited methods since we don't provide @@ -112,7 +123,7 @@ class ClassHelper extends Domain { } } - var fields = sdkUtils.getFields(clazz); + var fields = dart.getFields(clazz); var fieldNames = fields ? Object.keys(fields) : []; descriptor['fields'] = {}; for (var name of fieldNames) { @@ -125,7 +136,7 @@ class ClassHelper extends Domain { "isFinal": field.isFinal, "isStatic": false, "classRefName": fields[name]["type"]["name"], - "classRefDartName": sdkUtils.typeName(fields[name]["type"]), + "classRefDartName": dart.typeName(fields[name]["type"]), "classRefLibraryId" : field["type"][libraryUri], } } @@ -135,7 +146,7 @@ class ClassHelper extends Domain { // https://github.com/dart-lang/sdk/issues/40273): descriptor['staticFields'] = {}; - var staticFieldNames = sdkUtils.getStaticFields(clazz) ?? []; + var staticFieldNames = dart.getStaticFields(clazz) ?? []; for (const name of staticFieldNames) { descriptor['staticFields'][name] = { "isStatic": true, @@ -147,7 +158,7 @@ class ClassHelper extends Domain { } descriptor['staticMethods'] = {}; - var staticMethodNames = sdkUtils.getStaticMethods(clazz) ?? []; + var staticMethodNames = dart.getStaticMethods(clazz) ?? []; for (var name of staticMethodNames) { descriptor['methods'][name] = { // DDC only provides names of static members, we set isConst @@ -159,7 +170,7 @@ class ClassHelper extends Domain { return descriptor; })() - '''; + ''';*/ RemoteObject result; try { @@ -172,6 +183,8 @@ class ClassHelper extends Domain { throw ChromeDebugException(e.json, evalContents: expression); } + _logger.severe('Result: ${result.json}'); + final classDescriptor = result.value as Map; final methodRefs = []; final methodDescriptors = diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 7d0c75027..a9331dff3 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -644,20 +644,34 @@ class AppInspector implements AppInspectorInterface { // avoid doing a toList on a large map using skip/take to get the section we // want. To make those alternatives easier in JS, pass both count and end. final expression = ''' - function (offset, count, end) { + function (offset, count, end) { + const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); + const dart = sdk.dart; + return dart.getSubRange(this, offset, count, end); + } + '''; +/* function (offset, count, end) { const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); - if (sdk.core.Map.is(this)) { + const dart_rti = sdk.dart_rti; + const dart = sdk.dart; + + const _is = dart.privateName(dart_rti, "_is"); + if (dart_rti.findType("core|Map<@,@>")[_is](this)) { + + //if (sdk.core.Map.is(this)) { const entries = sdk.dart.dload(this, "entries"); const skipped = sdk.dart.dsend(entries, "skip", [offset]) const taken = sdk.dart.dsend(skipped, "take", [count]); return sdk.dart.dsend(taken, "toList", []); - } else if (sdk.core.List.is(this)) { + + } else if (dart_rti.findType("core|List<@>")[_is](this)) { + //} else if (sdk.core.List.is(this)) { return sdk.dart.dsendRepl(this, "sublist", [offset, end]); } else { return this; } } - '''; + ''';*/ return await jsCallFunctionOn(receiver, expression, args); } diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index 23c95b2ba..05d3dce43 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -286,6 +286,12 @@ class InstanceHelper extends Domain { // 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 = ''' + function() { + var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; + return sdkUtils.getMapElements(this); + } + '''; + /*final expression = ''' function() { var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; var entries = sdkUtils.dloadRepl(this, "entries"); @@ -301,7 +307,7 @@ class InstanceHelper extends Domain { values: entries.map(asValue) }; } - '''; + ''';*/ final keysAndValues = await inspector.jsCallFunctionOn(map, expression, []); final keys = await inspector.loadField(keysAndValues, 'keys'); final values = await inspector.loadField(keysAndValues, 'values'); @@ -518,6 +524,12 @@ class InstanceHelper extends Domain { // 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 = ''' + function() { + var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; + return sdkUtils.getRecordFields(this); + } + '''; + /*final expression = ''' function() { var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; var shape = sdkUtils.dloadRepl(this, "shape"); @@ -533,7 +545,7 @@ class InstanceHelper extends Domain { values: values }; } - '''; + ''';*/ final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = await _recordShapeFields(result, offset: offset, count: count); @@ -662,23 +674,50 @@ class InstanceHelper extends Domain { // values that we need to be RemoteObject, e.g. a List of int. final expression = ''' function() { - var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - var type = sdkUtils.dloadRepl(this, "_type"); - var shape = sdkUtils.dloadRepl(type, "shape"); - var positionalCount = sdkUtils.dloadRepl(shape, "positionals"); - var named = sdkUtils.dloadRepl(shape, "named"); - named = named == null? null: sdkUtils.dsendRepl(named, "toList", []); - var types = sdkUtils.dloadRepl(type, "types"); - types = types.map(t => sdkUtils.wrapType(t)); - types = sdkUtils.dsendRepl(types, "toList", []); + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.getRecordTypeFields(this); + } + '''; + /* + final expression = ''' + function() { + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart_rti = sdk.dart_rti; + const dart = sdk.dart; + + var type = null; + var shape = null; + var types = null; + if (type == null) { // new types + type = dart.dloadRepl(this, "_rti"); + types = dart.dloadRepl(type, "_rest"); + types = types.map(t => dart_rti.createRuntimeType(t)); + var length = types['length']; + var recipe = dart.dloadRepl(type, "_primary"); + var shapeKey = `\${length};\${recipe}`; + console.log(`shapeKey: \${shapeKey}`); + shape = dart.shapes.get(shapeKey); + console.log(`shape: \${shape}`); + } else { // old types + var type = dart.dloadRepl(this, "_type"); + shape = dart.dloadRepl(type, "shape"); + types = dart.dloadRepl(type, "types"); + types = types.map(t => dart.wrapType(t)); + types = dart.dsendRepl(types, "toList", []); + } + var positionalCount = dart.dloadRepl(shape, "positionals"); + var named = dart.dloadRepl(shape, "named"); + named = named == null? null: dart.dsendRepl(named, "toList", []); + return { positionalCount: positionalCount, named: named, types: types }; } - '''; + ''';*/ final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = await _recordShapeFields(result, offset: offset, count: count); @@ -704,13 +743,17 @@ class InstanceHelper extends Domain { final expression = ''' function() { const sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; + return sdkUtils.getSetElements(this); + } + '''; + /* const jsSet = sdkUtils.dloadRepl(this, "_map"); const entries = [...jsSet.values()]; return { entries: entries }; } - '''; + ''';*/ final result = await inspector.jsCallFunctionOn(remoteObject, expression, []); @@ -784,16 +827,24 @@ class InstanceHelper extends Domain { // hide the internal implementation. final expression = ''' function() { - var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - var hashCode = sdkUtils.dloadRepl(this, "hashCode"); - var runtimeType = sdkUtils.dloadRepl(this, "runtimeType"); + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.getTypeFields(this); + } + '''; + /* final expression = ''' + function() { + var sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + var dart = sdk.dart; + var hashCode = dart.dloadRepl(this, "hashCode"); + var runtimeType = dart.dloadRepl(this, "runtimeType"); return { hashCode: hashCode, runtimeType: runtimeType }; } - '''; + ''';*/ final result = await inspector.jsCallFunctionOn(type, expression, []); final hashCodeObject = await inspector.loadField(result, 'hashCode'); @@ -844,19 +895,36 @@ class InstanceHelper extends Domain { // of these as special. final fieldNameExpression = '''function() { const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); - const sdk_utils = sdk.dart; - const fields = sdk_utils.getFields(sdk_utils.getType(this)) || []; - if (!fields && (dart_sdk._interceptors.JSArray.is(this) || - dart_sdk._js_helper.InternalMap.is(this))) { + const dart = sdk.dart; + return dart.getObjectFieldNames(this); + } + '''; + + /*'''function() { + const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); + const dart_rti = sdk.dart_rti; + const dart = sdk.dart; + + const fields = dart.getFields(dart.getType(this)) || []; + //if (!fields && (dart_sdk._interceptors.JSArray.is(this) || + // dart_sdk._js_helper.InternalMap.is(this))) { + + + const _is = dart.privateName(dart_rti, "_is"); + if (!fields && + (dart_rti.findType("core|List<@>")[_is](this)) || + (dart_rti.findType("core|Map<@,@>")[_is](this)) + ) { + // Trim off the 'length' property. const fields = allJsProperties.slice(0, allJsProperties.length -1); return fields.join(','); } - const privateFields = sdk_utils.getOwnPropertySymbols(fields); + const privateFields = dart.getOwnPropertySymbols(fields); const nonSymbolNames = privateFields .map(sym => sym.description .split('#').slice(-1)[0]); - const publicFieldNames = sdk_utils.getOwnPropertyNames(fields); + const publicFieldNames = dart.getOwnPropertyNames(fields); const symbolNames = Object.getOwnPropertySymbols(this) .map(sym => sym.description .split('#').slice(-1)[0] @@ -865,7 +933,7 @@ class InstanceHelper extends Domain { .concat(publicFieldNames) .concat(symbolNames).join(','); } - '''; + ''';*/ final allNames = (await inspector .jsCallFunctionOn(remoteObject, fieldNameExpression, [])) .value as String; @@ -874,6 +942,15 @@ class InstanceHelper extends Domain { return allJsProperties .where((property) => names.contains(property.name)) .toList(); +/* + final names = (await inspector + .jsCallFunctionOn(remoteObject, fieldNameExpression, [])) + .value as List; + + // TODO(#761): Better support for large collections. + return allJsProperties + .where((property) => names.contains(property.name)) + .toList();*/ } /// Create an InstanceRef for an object, which may be a RemoteObject, or may diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index b50eef16d..dbc617f60 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -82,26 +82,50 @@ 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 = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.getLibraryMetadata('$libraryUri'); + })() + '''; + // Fetch information about all the classes in this library. + /*final expression = ''' (function() { ${globalLoadStrategy.loadLibrarySnippet(libraryUri)} + var result = {}; var classes = Object.values(Object.getOwnPropertyDescriptors(library)) .filter((p) => 'value' in p) .map((p) => p.value) - .filter((l) => l && sdkUtils.isType(l)); + .filter((l) => l && (l.prototype instanceof core.Object)); var classList = classes.map(function(clazz) { - var descriptor = { + var descriptor = { 'name': clazz.name, - 'dartName': sdkUtils.typeName(clazz) + 'dartName': dart.typeName(dart.getReifiedType(clazz.prototype)) }; return descriptor; }); result['classes'] = classList; return result; + + + // var result = {}; + // var classes = Object.values(Object.getOwnPropertyDescriptors(library)) + // .filter((p) => 'value' in p) + // .map((p) => p.value) + // .filter((l) => l && dart.isType(l)); + // var classList = classes.map(function(clazz) { + // var descriptor = { + // 'name': clazz.name, + // 'dartName': dart.typeName(clazz) + // }; + // return descriptor; + // }); + // result['classes'] = classList; + // return result; })() - '''; + ''';*/ RemoteObject? result; try { result = await inspector.jsEvaluate(expression, returnByValue: true); @@ -112,6 +136,7 @@ class LibraryHelper extends Domain { // TODO: Collect library and class information from debug symbols. _logger.warning('Library ${libraryRef.uri} is not loaded. ' 'This can happen for unreferenced libraries.'); + rethrow; } final classRefs = []; if (result != null) { diff --git a/dwds/lib/src/debugging/metadata/class.dart b/dwds/lib/src/debugging/metadata/class.dart index 7cde9989d..2b4be4a65 100644 --- a/dwds/lib/src/debugging/metadata/class.dart +++ b/dwds/lib/src/debugging/metadata/class.dart @@ -163,73 +163,148 @@ class ClassMetaDataHelper { /// TODO(annagrin): this breaks on changes to internal /// type representation in DDC. Replace by runtime API. /// https://github.com/dart-lang/sdk/issues/51583 + final evalExpression = ''' + function(arg) { + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.getObjectMetadata(arg); + } + '''; + /* final evalExpression = ''' function(arg) { const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart_rti = sdk.dart_rti; const dart = sdk.dart; const core = sdk.core; const interceptors = sdk._interceptors; + const jsHelper = sdk._js_helper; + const collection = sdk.collection; const reifiedType = dart.getReifiedType(arg); - const name = reifiedType.name; + const name = reifiedType.name; // this is always null + + const dartName = dart.typeName(reifiedType); + const rtiKind = dart.dloadRepl(reifiedType, "_kind"); + + var libraryId = null; + if (arg.constructor != null) { + libraryId = dart.getLibraryUri(arg.constructor); + } + + //const libraryId = dart.getLibraryUri(reifiedType); + const result = {}; result['name'] = name; - result['libraryId'] = dart.getLibraryUri(reifiedType); - result['dartName'] = dart.typeName(reifiedType); + result['libraryId'] = libraryId; + result['dartName'] = dartName; result['length'] = arg['length']; - result['runtimeKind'] = '${RuntimeObjectKind.object.name}'; + result['runtimeKind'] = 'object'; - if (name == '_HashSet') { - result['runtimeKind'] = '${RuntimeObjectKind.set.name}'; - } - else if (name == 'JSArray') { - result['runtimeKind'] = '${RuntimeObjectKind.list.name}'; + //console.log(`library: \${libraryId}, dart name: \${dartName}, arg: \${arg}`); + + const _is = dart.privateName(dart_rti, "_is"); + if (dart_rti.findType("core|List<@>")[_is](arg)) { + result['runtimeKind'] = 'list'; } - else if (name == 'LinkedMap' || name == 'IdentityMap') { - result['runtimeKind'] = '${RuntimeObjectKind.map.name}'; + else if (dart_rti.findType("core|Map<@,@>")[_is](arg)) { + result['runtimeKind'] = 'map'; } - else if (reifiedType instanceof dart.AbstractFunctionType) { - result['runtimeKind'] = '${RuntimeObjectKind.function.name}'; - result['name'] = 'Function'; + else if (dart_rti.findType("core|Set<@>")[_is](arg)) { + result['runtimeKind'] = 'set'; } - else if (reifiedType instanceof dart.RecordType) { - result['runtimeKind'] = '${RuntimeObjectKind.record.name}'; - result['libraryId'] = 'dart:core'; - result['name'] = 'Record'; - result['dartName'] = 'Record'; - var shape = reifiedType.shape; - var positionalCount = shape.positionals; - var namedCount = shape.named == null ? 0 : shape.named.length; - result['length'] = positionalCount + namedCount; + //if (name == '_HashSet') { + // result['runtimeKind'] = 'set'; + //} + //else if (name == 'JSArray') { + // result['runtimeKind'] = 'list'; + //} + //else if (name == 'LinkedMap' || name == 'IdentityMap') { + // result['runtimeKind'] = 'map'; + //} + //else if (reifiedType instanceof dart.AbstractFunctionType) { + // result['runtimeKind'] = 'function'; + // result['name'] = 'Function'; + //} + else if (rtiKind == ${RtiKind.kindFunction}) { + result['runtimeKind'] = 'function'; + result['name'] = 'Function'; } - else if (arg instanceof dart._Type) { - var object = dart.dloadRepl(arg, "_type"); - if (object instanceof dart.RecordType) { - result['libraryId'] = 'dart:_runtime'; - result['name'] = 'RecordType'; - result['dartName'] = 'RecordType'; - result['runtimeKind'] = '${RuntimeObjectKind.recordType.name}'; - result['length'] = object.types.length; - } - else if (dart.is(object, core.Type)) { + else if (arg instanceof dart.RecordImpl) { + result['runtimeKind'] = 'record'; result['libraryId'] = 'dart:core'; - result['name'] = 'Type'; - result['dartName'] = 'Type'; - result['runtimeKind'] = '${RuntimeObjectKind.type.name}'; - result['typeName'] = dart.dsendRepl(arg, "toString", []); - result['length'] = object['length']; - } + result['name'] = 'Record'; + result['dartName'] = 'Record'; + var shape = arg.shape; + var positionalCount = shape.positionals; + var namedCount = shape.named == null ? 0 : shape.named.length; + result['length'] = positionalCount + namedCount; + } + // else if (arg instanceof dart._Type) { + // var typeImpl = dart.dloadRepl(arg, "_type"); + // if (typeImpl instanceof dart.RecordType) { + // result['libraryId'] = 'dart:_runtime'; + // result['name'] = 'RecordType'; + // result['dartName'] = 'RecordType'; + // result['runtimeKind'] = 'recordType'; + // result['length'] = typeImpl.types.length; + // } + // else if (dart.is(typeImpl, core.Type)) { + // result['libraryId'] = 'dart:core'; + // result['name'] = 'Type'; + // result['dartName'] = 'Type'; + // result['runtimeKind'] = 'type'; + // result['typeName'] = dart.dsendRepl(arg, "toString", []); + // } + // } + else if (arg instanceof dart_rti._Type) { + var typeRti = dart.dloadRepl(arg, "_rti"); + var typeKind = dart.dloadRepl(typeRti, "_kind"); + if (typeKind == ${RtiKind.kindRecord}) { + var elements = dart.dloadRepl(typeRti, "_rest"); + result['libraryId'] = 'dart:_runtime'; + result['name'] = 'RecordType'; + result['dartName'] = 'RecordType'; + result['runtimeKind'] = 'recordType'; + result['length'] = elements['length']; + } + else { + result['libraryId'] = 'dart:core'; + result['name'] = 'Type'; + result['dartName'] = 'Type'; + result['runtimeKind'] = 'type'; + result['typeName'] = dart.dsendRepl(arg, "toString", []); + } + } + else if (arg instanceof interceptors.NativeError) { + result['runtimeKind'] = 'nativeError'; + } + else if (arg instanceof interceptors.JavaScriptObject) { + result['runtimeKind'] = 'nativeObject'; } - else if (dart.is(arg, interceptors.NativeError)) { - result['runtimeKind'] = '${RuntimeObjectKind.nativeError.name}'; + else if (arg instanceof dart.DartError) { // TODO: how is DartError different from NativeError? + result['dartName'] = 'DartError'; + result['libraryId'] = 'dart:_runtime'; + result['runtimeKind'] = 'nativeError'; } - else if (dart.is(arg, interceptors.JavaScriptObject)) { - result['runtimeKind'] = '${RuntimeObjectKind.nativeObject.name}'; + else if (dartName == 'LegacyJavaScriptObject') { + // unknown JS object - no dart metadata. + // TODO(annagrin): dart.typeName returns 'LegacyJavaScriptObject' but + // the arg is not of type interceptors.LegacyJavaScriptObject. + // This happens for the main library `this` object, for example. + // Should it return something else? + return {}; } + //else if (dart.is(arg, interceptors.NativeError)) { + // result['runtimeKind'] = 'nativeError'; + //} + //else if (dart.is(arg, interceptors.JavaScriptObject)) { + // result['runtimeKind'] = 'nativeObject'; + //} return result; - } + } '''; - +*/ final result = await _inspector.jsCallFunctionOn( remoteObject, evalExpression, @@ -237,13 +312,26 @@ class ClassMetaDataHelper { returnByValue: true, ); final metadata = result.value as Map; - final jsName = metadata['name']; + final jsName = metadata['dartName']; + + _logger.severe('Keys: ${metadata.keys}'); + + _logger.severe( + 'Dart metadata for remote $remoteObject: $metadata (${result.value.runtimeType}), name: $jsName'); + + if (jsName == null) { + return null; + } + final typeName = metadata['typeName']; final dartName = metadata['dartName']; final library = metadata['libraryId']; final runtimeKind = RuntimeObjectKind.parse(metadata['runtimeKind']); final length = metadata['length']; + _logger.severe( + 'Name: $dartName, library: $library, runtime kind: $runtimeKind'); + final classRef = classRefFor(library, dartName); _addRuntimeObjectKind(classRef, runtimeKind); @@ -290,3 +378,25 @@ class ClassMetaDataHelper { _runtimeObjectKinds[id] == RuntimeObjectKind.nativeError; } } + +/// Runtime type kinds, from rti.dart +class RtiKind { + // Terminal terms. + static const int kindNever = 1; + static const int kindDynamic = 2; + static const int kindVoid = 3; // TODO(sra): Use `dynamic` instead? + static const int kindAny = 4; // Dart1-style 'dynamic' for JS-interop. + static const int kindErased = 5; + // Unary terms. + static const int kindStar = 6; + static const int kindQuestion = 7; + static const int kindFutureOr = 8; + // More complex terms. + static const int kindInterface = 9; + // A vector of type parameters from enclosing functions and closures. + static const int kindBinding = 10; + static const int kindRecord = 11; + static const int kindFunction = 12; + static const int kindGenericFunction = 13; + static const int kindGenericFunctionParameter = 14; +} diff --git a/dwds/lib/src/loaders/strategy.dart b/dwds/lib/src/loaders/strategy.dart index 453e2dd2b..66057023a 100644 --- a/dwds/lib/src/loaders/strategy.dart +++ b/dwds/lib/src/loaders/strategy.dart @@ -64,9 +64,12 @@ abstract class LoadStrategy { /// parameter should be one of these Dart-specific scheme URIs, and we set /// `library` the corresponding library. String loadLibrarySnippet(String libraryUri) => ''' - var sdkUtils = $loadModuleSnippet('dart_sdk').dart; - var library = sdkUtils.getLibrary('$libraryUri'); - if (!library) throw 'cannot find library for $libraryUri'; + var sdk = $loadModuleSnippet('dart_sdk'); + var dart = sdk.dart; + var dart_rti = sdk.dart_rti; + var core = sdk.core; + var library = dart.getLibrary('$libraryUri'); + if (!library) throw 'cannot find library for $libraryUri'; '''; /// Returns the bootstrap required for this [LoadStrategy]. diff --git a/dwds/lib/src/services/expression_compiler_service.dart b/dwds/lib/src/services/expression_compiler_service.dart index 848a45164..9f08ccce2 100644 --- a/dwds/lib/src/services/expression_compiler_service.dart +++ b/dwds/lib/src/services/expression_compiler_service.dart @@ -68,6 +68,7 @@ class _Compiler { bool soundNullSafety, SdkConfiguration sdkConfiguration, List experiments, + bool canaryFeatures, bool verbose, ) async { sdkConfiguration.validateSdkDir(); @@ -95,6 +96,7 @@ class _Compiler { if (verbose) '--verbose', soundNullSafety ? '--sound-null-safety' : '--no-sound-null-safety', for (final experiment in experiments) '--enable-experiment=$experiment', + if (canaryFeatures) '--canary', ]; _logger.info('Starting...'); @@ -240,6 +242,7 @@ class ExpressionCompilerService implements ExpressionCompiler { final String _address; final FutureOr _port; final List experiments; + final bool canaryFeatures; final bool _verbose; final SdkConfigurationProvider sdkConfigurationProvider; @@ -250,6 +253,7 @@ class ExpressionCompilerService implements ExpressionCompiler { bool verbose = false, required this.sdkConfigurationProvider, this.experiments = const [], + this.canaryFeatures = false, }) : _verbose = verbose; @override @@ -287,6 +291,7 @@ class ExpressionCompilerService implements ExpressionCompiler { soundNullSafety, await sdkConfigurationProvider.configuration, experiments, + canaryFeatures, _verbose, ); diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index 53c165da2..257760ec0 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -148,15 +148,22 @@ class TestContext { bool isFlutterApp = false, bool isInternalBuild = false, List experiments = const [], + bool canaryFeatures = false, }) async { + if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { + throw StateError('DDC canary mode is not supported with build daemon'); + } + final sdkLayout = sdkConfigurationProvider.sdkLayout; try { // Make sure configuration was created correctly. final configuration = await sdkConfigurationProvider.configuration; configuration.validate(); + await project.cleanUp(); DartUri.currentDirectory = project.absolutePackageDirectory; + configureLogWriter(); _client = IOClient( @@ -211,6 +218,7 @@ class TestContext { Stream buildResults; RequireStrategy requireStrategy; String basePath = ''; + String index = project.filePathToServe; _port = await findUnusedPort(); switch (compilationMode) { @@ -263,6 +271,7 @@ class TestContext { verbose: verboseCompiler, sdkConfigurationProvider: sdkConfigurationProvider, experiments: experiments, + canaryFeatures: canaryFeatures, ); expressionCompiler = ddcService; } @@ -279,7 +288,14 @@ class TestContext { break; case CompilationMode.frontendServer: { - _logger.info('Index: ${project.filePathToServe}'); + index = webCompatiblePath([ + project.directoryToServe, + project.filePathToServe, + ]); + + _logger.info('Directory: ${project.directoryToServe}'); + _logger.info('Index: $index'); + _logger.info('WebAssetPath: ${project.webAssetsPath}'); final entry = p.toUri( p.join(project.webAssetsPath, project.dartEntryFileName), @@ -302,6 +318,7 @@ class TestContext { outputPath: outputDir.path, soundNullSafety: nullSafety == NullSafety.sound, experiments: experiments, + canaryFeatures: canaryFeatures, verbose: verboseCompiler, sdkLayout: sdkLayout, ); @@ -311,7 +328,7 @@ class TestContext { fileSystem, hostname, assetServerPort, - p.join(project.directoryToServe, project.filePathToServe), + index, ); if (enableExpressionEvaluation) { @@ -393,8 +410,8 @@ class TestContext { ); _appUrl = basePath.isEmpty - ? 'http://localhost:$port/${project.filePathToServe}' - : 'http://localhost:$port/$basePath/${project.filePathToServe}'; + ? 'http://localhost:$port/$index' + : 'http://localhost:$port/$basePath/$index'; if (launchChrome) { await _webDriver?.get(appUrl); diff --git a/dwds/test/fixtures/project.dart b/dwds/test/fixtures/project.dart index dea432657..0d5458b92 100644 --- a/dwds/test/fixtures/project.dart +++ b/dwds/test/fixtures/project.dart @@ -2,6 +2,8 @@ // 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. +import 'dart:io'; + import 'package:path/path.dart' as p; import 'package:test_common/utilities.dart'; @@ -221,4 +223,15 @@ class TestProject { // Verify that the web assets path has no starting slash: assert(!webAssetsPath.startsWith('/')); } + + /// Clean up the project. + /// Called when we need to rebuild sdk and the app from + /// previous test configurations. + Future cleanUp() async { + await Process.run( + 'dart', + ['run', 'build_runner', 'clean'], + workingDirectory: absolutePackageDirectory, + ); + } } diff --git a/dwds/test/instances/instance_inspection_common.dart b/dwds/test/instances/instance_inspection_common.dart index 64a6d03ee..687b05d40 100644 --- a/dwds/test/instances/instance_inspection_common.dart +++ b/dwds/test/instances/instance_inspection_common.dart @@ -150,8 +150,9 @@ class TestInspector { }; final instances = {}; for (final p in refs.entries) { - instances[p.key] = + final instance = await service.getObject(isolateId, p.value.id!) as Instance; + instances[p.key] = instance; } return instances; } @@ -223,9 +224,9 @@ Matcher matchRecordTypeInstanceRef({required int length}) => isA() .having((e) => e.length, 'length', length) .having((e) => e.classRef!, 'classRef', matchRecordTypeClassRef); -Matcher matchTypeInstanceRef(String name) => isA() +Matcher matchTypeInstanceRef(dynamic name) => isA() .having((e) => e.kind, 'kind', InstanceKind.kType) - .having((e) => e.name, 'name', name) + .having((e) => e.name, 'type ref name', name) .having((e) => e.classRef, 'classRef', matchTypeClassRef); Matcher matchPrimitiveInstanceRef({ @@ -250,7 +251,7 @@ Matcher matchPlainInstance({required libraryId, required String type}) => matchClassRef(name: type, libraryId: libraryId), ); -Matcher matchListInstance({required String type}) => isA() +Matcher matchListInstance({required dynamic type}) => isA() .having((e) => e.kind, 'kind', InstanceKind.kList) .having((e) => e.classRef, 'classRef', matchListClassRef(type)); @@ -272,44 +273,44 @@ Matcher matchRecordTypeInstance({required int length}) => isA() .having((e) => e.length, 'length', length) .having((e) => e.classRef, 'classRef', matchRecordTypeClassRef); -Matcher matchTypeStringInstance(String name) => +Matcher matchTypeStringInstance(dynamic name) => matchPrimitiveInstance(kind: InstanceKind.kString, value: name); -Matcher matchTypeInstance(String name) => isA() +Matcher matchTypeInstance(dynamic name) => isA() .having((e) => e.kind, 'kind', InstanceKind.kType) - .having((e) => e.name, 'name', name) + .having((e) => e.name, 'type name', name) .having((e) => e.classRef, 'classRef', matchTypeClassRef); Matcher matchRecordClass = - matchClass(name: _recordClass, libraryId: _dartCoreLibrary); + matchClass(name: matchRecordClassName, libraryId: _dartCoreLibrary); Matcher matchRecordTypeClass = - matchClass(name: _recordTypeClass, libraryId: _dartRuntimeLibrary); + matchClass(name: matchRecordTypeClassName, libraryId: _dartRuntimeLibrary); Matcher matchTypeClass = - matchClass(name: _typeClass, libraryId: _dartCoreLibrary); + matchClass(name: matchTypeClassName, libraryId: _dartCoreLibrary); -Matcher matchClass({String? name, String? libraryId}) => isA() - .having((e) => e.name, 'name', name) +Matcher matchClass({dynamic name, String? libraryId}) => isA() + .having((e) => e.name, 'class name', name) .having((e) => e.library, 'library', matchLibraryRef(libraryId)); Matcher matchRecordClassRef = - matchClassRef(name: _recordClass, libraryId: _dartCoreLibrary); -Matcher matchRecordTypeClassRef = - matchClassRef(name: _recordTypeClass, libraryId: _dartRuntimeLibrary); + matchClassRef(name: matchRecordClassName, libraryId: _dartCoreLibrary); +Matcher matchRecordTypeClassRef = matchClassRef( + name: matchRecordTypeClassName, libraryId: _dartRuntimeLibrary); Matcher matchTypeClassRef = - matchClassRef(name: _typeClass, libraryId: _dartCoreLibrary); -Matcher matchListClassRef(String type) => - matchClassRef(name: type, libraryId: _dartInterceptorsLibrary); + matchClassRef(name: matchTypeClassName, libraryId: _dartCoreLibrary); +Matcher matchListClassRef(dynamic type) => + matchClassRef(name: type, libraryId: _matchListLibraryName); Matcher matchMapClassRef(String type) => matchClassRef(name: type, libraryId: _dartJsHelperLibrary); Matcher matchSetClassRef(String type) => matchClassRef(name: type, libraryId: _dartCollectionLibrary); -Matcher matchClassRef({String? name, String? libraryId}) => isA() - .having((e) => e.name, 'class name', name) +Matcher matchClassRef({dynamic name, dynamic libraryId}) => isA() + .having((e) => e.name, 'class ref name', name) .having((e) => e.library, 'library', matchLibraryRef(libraryId)); -Matcher matchLibraryRef(String? libraryId) => isA() - .having((e) => e.name, 'name', libraryId) +Matcher matchLibraryRef(dynamic libraryId) => isA() + .having((e) => e.name, 'library name', libraryId) .having((e) => e.id, 'id', libraryId) .having((e) => e.uri, 'uri', libraryId); @@ -333,6 +334,17 @@ final _dartInterceptorsLibrary = 'dart:_interceptors'; final _dartJsHelperLibrary = 'dart:_js_helper'; final _dartCollectionLibrary = 'dart:collection'; -final _recordClass = 'Record'; -final _recordTypeClass = 'RecordType'; -final _typeClass = 'Type'; +final matchRecordClassName = 'Record'; +final matchRecordTypeClassName = 'RecordType'; + +/// Match types for old and new type systems. +/// - Old type system has `dart:core|List` and `dart:_runtime|_Type`. +/// - New type system has `dart:_interceptors|JSArray` and `dart:core|Type`. +/// TODO(annagrin): update when DDC enables new type system. +final matchTypeClassName = anyOf(['Type', '_Type']); + +Matcher matchListClassName(String elementType) => + anyOf(['JSArray<$elementType>', 'List<$elementType>']); + +final _matchListLibraryName = + anyOf([_dartInterceptorsLibrary, _dartCoreLibrary]); diff --git a/dwds/test/instances/instance_inspection_test.dart b/dwds/test/instances/instance_inspection_test.dart index 9be7dc107..9b8df58ae 100644 --- a/dwds/test/instances/instance_inspection_test.dart +++ b/dwds/test/instances/instance_inspection_test.dart @@ -14,31 +14,48 @@ import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'instance_inspection_common.dart'; -void main() async { +void main() { // Enable verbose logging for debugging. final debug = false; - final provider = TestSdkConfigurationProvider(verbose: debug); - tearDownAll(provider.dispose); + for (var canaryFeatures in [false, true]) { + _runAllTests(canaryFeatures, debug); + } +} - for (var compilationMode in CompilationMode.values) { - for (var nullSafetyMode in NullSafety.values) { - await _runTests( - provider: provider, - compilationMode: compilationMode, - nullSafetyMode: nullSafetyMode, - debug: debug, - ); +void _runAllTests(bool canaryFeatures, bool debug) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, + ); + tearDownAll(provider.dispose); + + for (var compilationMode in CompilationMode.values) { + for (var nullSafetyMode in NullSafety.values) { + // TODO:(annagrin) support canary mode in build daemon mode. + if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { + continue; + } + _runTests( + provider: provider, + compilationMode: compilationMode, + nullSafetyMode: nullSafetyMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } } - } + }); } -Future _runTests({ +void _runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, required NullSafety nullSafetyMode, + required bool canaryFeatures, required bool debug, -}) async { +}) { final testPackage = nullSafetyMode == NullSafety.sound ? TestProject.testPackageWithSoundNullSafety() : TestProject.testPackageWithWeakNullSafety(); @@ -78,6 +95,7 @@ Future _runTests({ enableExpressionEvaluation: true, verboseCompiler: debug, experiments: ['records'], + canaryFeatures: canaryFeatures, ); service = context.debugConnection.vmService; @@ -170,7 +188,7 @@ Future _runTests({ final instanceId = instanceRef.id!; expect( await getObject(instanceId), - matchListInstance(type: 'List'), + matchListInstance(type: matchListClassName('int')), ); expect(await getFields(instanceRef), [0, 1, 2]); diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index 2fe80d7be..4397730fa 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -14,21 +14,46 @@ import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; +import 'instance_inspection_common.dart'; -void main() { +void main() async { // Enable verbose logging for debugging. final debug = false; - final provider = TestSdkConfigurationProvider(); - tearDownAll(provider.dispose); - final context = - TestContext(TestProject.testScopesWithSoundNullSafety, provider); + for (var canaryFeatures in [false, true]) { + _runAllTests(canaryFeatures, debug); + } +} + +void _runAllTests(bool canaryFeatures, bool debug) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = + TestSdkConfigurationProvider(canaryFeatures: canaryFeatures); + tearDownAll(provider.dispose); + + _runTests( + provider: provider, + canaryFeatures: canaryFeatures, + debug: debug, + ); + }); +} +void _runTests({ + required TestSdkConfigurationProvider provider, + bool canaryFeatures = false, + required bool debug, +}) { late AppInspector inspector; + final context = + TestContext(TestProject.testScopesWithSoundNullSafety, provider); setUpAll(() async { setCurrentLogWriter(debug: debug); - await context.setUp(); + await context.setUp( + canaryFeatures: canaryFeatures, + compilationMode: CompilationMode.frontendServer, + ); final chromeProxyService = context.service; inspector = chromeProxyService.inspector; }); @@ -40,11 +65,13 @@ void main() { final url = 'org-dartlang-app:///example/scopes/main.dart'; String libraryVariableExpression(String variable) => - '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.getModuleLibraries("example/scopes/main")' + '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.getModuleLibraries("example/scopes/main.dart")' '["$url"]["$variable"];'; - String interceptorsNewExpression(String type) => - "require('dart_sdk')._interceptors.$type['_#new#tearOff']()"; + String newInterceptorsExpression(String type) => + 'new (require("dart_sdk")._interceptors.$type).new()'; + + final String newDartError = 'new (require("dart_sdk").dart).DartError'; /// A reference to the the variable `libraryPublicFinal`, an instance of /// `MyTestClass`. @@ -116,7 +143,7 @@ void main() { final ref = await inspector.instanceRefFor(remoteObject); expect(ref!.length, greaterThan(0)); expect(ref.kind, InstanceKind.kList); - expect(ref.classRef!.name, 'List'); + expect(ref.classRef!.name, matchListClassName('String')); expect(inspector.isDisplayableObject(ref), isTrue); }); @@ -140,9 +167,19 @@ void main() { expect(inspector.isDisplayableObject(ref), isTrue); }); + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + test('for a native JavaScript error', () async { final remoteObject = - await inspector.jsEvaluate(interceptorsNewExpression('NativeError')); + await inspector.jsEvaluate(newInterceptorsExpression('NativeError')); final ref = await inspector.instanceRefFor(remoteObject); expect(ref!.kind, InstanceKind.kPlainInstance); expect(ref.classRef!.name, 'NativeError'); @@ -153,7 +190,7 @@ void main() { test('for a native JavaScript type error', () async { final remoteObject = await inspector - .jsEvaluate(interceptorsNewExpression('JSNoSuchMethodError')); + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); final ref = await inspector.instanceRefFor(remoteObject); expect(ref!.kind, InstanceKind.kPlainInstance); expect(ref.classRef!.name, 'JSNoSuchMethodError'); @@ -164,7 +201,7 @@ void main() { test('for a native JavaScript object', () async { final remoteObject = await inspector - .jsEvaluate(interceptorsNewExpression('LegacyJavaScriptObject')); + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); final ref = await inspector.instanceRefFor(remoteObject); expect(ref!.kind, InstanceKind.kPlainInstance); expect(ref.classRef!.name, 'LegacyJavaScriptObject'); @@ -234,7 +271,7 @@ void main() { expect(instance!.kind, InstanceKind.kList); final classRef = instance.classRef!; expect(classRef, isNotNull); - expect(classRef.name, 'List'); + expect(classRef.name, matchListClassName('String')); final first = instance.elements![0]; expect(first.valueAsString, 'library'); expect(inspector.isDisplayableObject(instance), isTrue); @@ -280,11 +317,21 @@ void main() { final field = instance.fields!.first; expect(field.decl!.name, '_internal'); expect(inspector.isDisplayableObject(instance), isTrue); + }, skip: true); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); }); test('for a native JavaScript error', () async { final remoteObject = - await inspector.jsEvaluate(interceptorsNewExpression('NativeError')); + await inspector.jsEvaluate(newInterceptorsExpression('NativeError')); final instance = await inspector.instanceFor(remoteObject); expect(instance!.kind, InstanceKind.kPlainInstance); expect(instance.classRef!.name, 'NativeError'); @@ -295,7 +342,7 @@ void main() { test('for a native JavaScript type error', () async { final remoteObject = await inspector - .jsEvaluate(interceptorsNewExpression('JSNoSuchMethodError')); + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); final instance = await inspector.instanceFor(remoteObject); expect(instance!.kind, InstanceKind.kPlainInstance); expect(instance.classRef!.name, 'JSNoSuchMethodError'); @@ -306,7 +353,7 @@ void main() { test('for a native JavaScript object', () async { final remoteObject = await inspector - .jsEvaluate(interceptorsNewExpression('LegacyJavaScriptObject')); + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); final instance = await inspector.instanceFor(remoteObject); expect(instance!.kind, InstanceKind.kPlainInstance); expect(instance.classRef!.name, 'LegacyJavaScriptObject'); diff --git a/dwds/test/instances/patterns_inspection_test.dart b/dwds/test/instances/patterns_inspection_test.dart index 1aa2eb891..41c42d298 100644 --- a/dwds/test/instances/patterns_inspection_test.dart +++ b/dwds/test/instances/patterns_inspection_test.dart @@ -5,9 +5,6 @@ @TestOn('vm') @Timeout(Duration(minutes: 2)) -import 'dart:io'; - -import 'package:pub_semver/pub_semver.dart' as semver; import 'package:test/test.dart'; import 'package:test_common/logging.dart'; import 'package:test_common/test_sdk_configuration.dart'; @@ -17,25 +14,42 @@ import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'instance_inspection_common.dart'; -void main() async { +void main() { // Enable verbose logging for debugging. final debug = false; - final provider = TestSdkConfigurationProvider(verbose: debug); - tearDownAll(provider.dispose); + for (var canaryFeatures in [false, true]) { + _runAllTests(canaryFeatures, debug); + } +} - for (var compilationMode in CompilationMode.values) { - await _runTests( - provider: provider, - compilationMode: compilationMode, - debug: debug, +void _runAllTests(bool canaryFeatures, bool debug) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, ); - } + tearDownAll(provider.dispose); + + for (var compilationMode in CompilationMode.values) { + // TODO:(annagrin) support canary mode in build daemon mode. + if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { + continue; + } + _runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } + }); } Future _runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, + required bool canaryFeatures, required bool debug, }) async { final context = @@ -64,126 +78,121 @@ Future _runTests({ getFrameVariables(Frame frame) => testInspector.getFrameVariables(isolateId, frame); - group( - '$compilationMode |', - () { - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - compilationMode: compilationMode, - enableExpressionEvaluation: true, - verboseCompiler: debug, - experiments: ['records', 'patterns'], - ); - service = context.debugConnection.vmService; + group('$compilationMode |', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + compilationMode: compilationMode, + enableExpressionEvaluation: true, + verboseCompiler: debug, + experiments: ['records', 'patterns'], + canaryFeatures: canaryFeatures, + ); + service = context.debugConnection.vmService; - final vm = await service.getVM(); - isolateId = vm.isolates!.first.id!; - final scripts = await service.getScripts(isolateId); + final vm = await service.getVM(); + isolateId = vm.isolates!.first.id!; + final scripts = await service.getScripts(isolateId); - await service.streamListen('Debug'); - stream = service.onEvent('Debug'); + await service.streamListen('Debug'); + stream = service.onEvent('Debug'); - mainScript = scripts.scripts! - .firstWhere((each) => each.uri!.contains('main.dart')); - }); + mainScript = scripts.scripts! + .firstWhere((each) => each.uri!.contains('main.dart')); + }); - tearDownAll(() async { - await context.tearDown(); - }); + tearDownAll(() async { + await context.tearDown(); + }); - setUp(() => setCurrentLogWriter(debug: debug)); - tearDown(() => service.resume(isolateId)); + setUp(() => setCurrentLogWriter(debug: debug)); + tearDown(() => service.resume(isolateId)); - test('pattern match case 1', () async { - await onBreakPoint('testPatternCase1', (event) async { - final frame = event.topFrame!; + test('pattern match case 1', () async { + await onBreakPoint('testPatternCase1', (event) async { + final frame = event.topFrame!; - expect(await getFrameVariables(frame), { - 'obj': matchListInstance(type: 'List'), - 'a': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'a'), - 'n': matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), - }); + expect(await getFrameVariables(frame), { + 'obj': matchListInstance(type: matchListClassName('Object')), + 'a': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'a'), + 'n': matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), }); }); + }); - test('pattern match case 2', () async { - await onBreakPoint('testPatternCase2', (event) async { - final frame = event.topFrame!; + test('pattern match case 2', () async { + await onBreakPoint('testPatternCase2', (event) async { + final frame = event.topFrame!; - expect(await getFrameVariables(frame), { - 'obj': matchListInstance(type: 'List'), - 'a': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'b'), - 'n': - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3.14), - }); + expect(await getFrameVariables(frame), { + 'obj': matchListInstance(type: matchListClassName('Object')), + 'a': matchPrimitiveInstance(kind: InstanceKind.kString, value: 'b'), + 'n': matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3.14), }); }); + }); - test('pattern match default case', () async { - await onBreakPoint('testPatternDefault', (event) async { - final frame = event.topFrame!; - final frameIndex = frame.index!; - final instanceRef = await getInstanceRef(frameIndex, 'obj'); - expect(await getFields(instanceRef), [0, 1]); + test('pattern match default case', () async { + await onBreakPoint('testPatternDefault', (event) async { + final frame = event.topFrame!; + final frameIndex = frame.index!; + final instanceRef = await getInstanceRef(frameIndex, 'obj'); + expect(await getFields(instanceRef), [0, 1]); - expect(await getFrameVariables(frame), { - 'obj': matchListInstance(type: 'List'), - }); + expect(await getFrameVariables(frame), { + 'obj': matchListInstance(type: matchListClassName('int')), }); }); - - test('stepping through pattern match', () async { - await onBreakPoint('callTestPattern1', (Event event) async { - var previousLocation = event.topFrame!.location; - for (var step in [ - // Make sure we step into the callee. - for (var i = 0; i < 4; i++) 'Into', - // Make a few steps inside the callee. - for (var i = 0; i < 4; i++) 'Over', - ]) { - await service.resume(isolateId, step: step); - - event = await stream - .firstWhere((e) => e.kind == EventKind.kPauseInterrupted); - - if (step == 'Over') { - expect(event.topFrame!.code!.name, 'testPattern'); - } - - final location = event.topFrame!.location; - expect(location, isNot(equals(previousLocation))); - previousLocation = location; + }); + + test('stepping through pattern match', () async { + await onBreakPoint('callTestPattern1', (Event event) async { + var previousLocation = event.topFrame!.location; + for (var step in [ + // Make sure we step into the callee. + for (var i = 0; i < 4; i++) 'Into', + // Make a few steps inside the callee. + for (var i = 0; i < 4; i++) 'Over', + ]) { + await service.resume(isolateId, step: step); + + event = await stream + .firstWhere((e) => e.kind == EventKind.kPauseInterrupted); + + if (step == 'Over') { + expect(event.topFrame!.code!.name, 'testPattern'); } - }); + + final location = event.topFrame!.location; + expect(location, isNot(equals(previousLocation))); + previousLocation = location; + } }); + }); - test('before instantiation of pattern-matching variables', () async { - await onBreakPoint('testPattern2Case1', (event) async { - final frame = event.topFrame!; + test('before instantiation of pattern-matching variables', () async { + await onBreakPoint('testPattern2Case1', (event) async { + final frame = event.topFrame!; - expect( - await getFrameVariables(frame), - {'dog': matchPrimitiveInstance(kind: 'String', value: 'Prismo')}, - ); - }); + expect( + await getFrameVariables(frame), + {'dog': matchPrimitiveInstance(kind: 'String', value: 'Prismo')}, + ); }); - - test('after instantiation of pattern-matching variables', () async { - await onBreakPoint('testPattern2Case2', (event) async { - final frame = event.topFrame!; - - expect(await getFrameVariables(frame), { - 'dog': matchPrimitiveInstance(kind: 'String', value: 'Prismo'), - 'cats': matchListInstance(type: 'List'), - 'firstCat': - matchPrimitiveInstance(kind: 'String', value: 'Garfield'), - 'secondCat': matchPrimitiveInstance(kind: 'String', value: 'Tom'), - }); + }); + + test('after instantiation of pattern-matching variables', () async { + await onBreakPoint('testPattern2Case2', (event) async { + final frame = event.topFrame!; + + final vars = await getFrameVariables(frame); + expect(vars, { + 'dog': matchPrimitiveInstance(kind: 'String', value: 'Prismo'), + 'cats': matchListInstance(type: matchListClassName('String')), + 'firstCat': matchPrimitiveInstance(kind: 'String', value: 'Garfield'), + 'secondCat': matchPrimitiveInstance(kind: 'String', value: 'Tom'), }); }); - }, // TODO(annagrin): Remove when dart 3.0 is stable. - skip: semver.Version.parse(Platform.version.split(' ')[0]) < - semver.Version.parse('3.0.0-351.0.dev'), - ); + }); + }); } diff --git a/dwds/test/instances/record_inspection_test.dart b/dwds/test/instances/record_inspection_test.dart index f78337d6e..f8d4e1d0c 100644 --- a/dwds/test/instances/record_inspection_test.dart +++ b/dwds/test/instances/record_inspection_test.dart @@ -14,25 +14,42 @@ import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'instance_inspection_common.dart'; -void main() async { +void main() { // Enable verbose logging for debugging. final debug = false; - final provider = TestSdkConfigurationProvider(verbose: debug); - tearDownAll(provider.dispose); + for (var canaryFeatures in [false, true]) { + _runAllTests(canaryFeatures, debug); + } +} - for (var compilationMode in CompilationMode.values) { - await _runTests( - provider: provider, - compilationMode: compilationMode, - debug: debug, +void _runAllTests(bool canaryFeatures, bool debug) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, ); - } + tearDownAll(provider.dispose); + + for (var compilationMode in CompilationMode.values) { + // TODO:(annagrin) support canary mode in build daemon mode. + if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { + continue; + } + _runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } + }); } Future _runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, + required bool canaryFeatures, required bool debug, }) async { final context = @@ -77,6 +94,7 @@ Future _runTests({ enableExpressionEvaluation: true, verboseCompiler: debug, experiments: ['records', 'patterns'], + canaryFeatures: canaryFeatures, ); service = context.debugConnection.vmService; diff --git a/dwds/test/instances/record_type_inspection_test.dart b/dwds/test/instances/record_type_inspection_test.dart index d3e6254a0..569f8d24e 100644 --- a/dwds/test/instances/record_type_inspection_test.dart +++ b/dwds/test/instances/record_type_inspection_test.dart @@ -14,25 +14,42 @@ import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'instance_inspection_common.dart'; -void main() async { +void main() { // Enable verbose logging for debugging. final debug = false; - final provider = TestSdkConfigurationProvider(verbose: debug); - tearDownAll(provider.dispose); + for (var canaryFeatures in [false, true]) { + _runAllTests(canaryFeatures, debug); + } +} - for (var compilationMode in CompilationMode.values) { - await _runTests( - provider: provider, - compilationMode: compilationMode, - debug: debug, +void _runAllTests(bool canaryFeatures, bool debug) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, ); - } + tearDownAll(provider.dispose); + + for (var compilationMode in CompilationMode.values) { + // TODO:(annagrin) support canary mode in build daemon mode. + if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { + continue; + } + _runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } + }); } Future _runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, + required bool canaryFeatures, required bool debug, }) async { final context = @@ -71,6 +88,7 @@ Future _runTests({ enableExpressionEvaluation: true, verboseCompiler: debug, experiments: ['records', 'patterns'], + canaryFeatures: canaryFeatures, ); service = context.debugConnection.vmService; diff --git a/dwds/test/instances/type_inspection_test.dart b/dwds/test/instances/type_inspection_test.dart index af3a9b625..4f6f8ada5 100644 --- a/dwds/test/instances/type_inspection_test.dart +++ b/dwds/test/instances/type_inspection_test.dart @@ -14,27 +14,44 @@ import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'instance_inspection_common.dart'; -void main() async { +void main() { // Enable verbose logging for debugging. final debug = false; - final provider = TestSdkConfigurationProvider(verbose: debug); - tearDownAll(provider.dispose); + for (var canaryFeatures in [false, true]) { + _runAllTests(canaryFeatures, debug); + } +} - for (var compilationMode in CompilationMode.values) { - await _runTests( - provider: provider, - compilationMode: compilationMode, - debug: debug, +void _runAllTests(bool canaryFeatures, bool debug) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, ); - } + tearDownAll(provider.dispose); + + for (var compilationMode in CompilationMode.values) { + // TODO:(annagrin) support canary mode in build daemon mode. + if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { + continue; + } + _runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } + }); } -Future _runTests({ +void _runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, + required bool canaryFeatures, required bool debug, -}) async { +}) { final context = TestContext(TestProject.testExperimentWithSoundNullSafety, provider); final testInspector = TestInspector(context); @@ -74,14 +91,13 @@ Future _runTests({ final matchTypeObject = { 'hashCode': matchPrimitiveInstanceRef(kind: InstanceKind.kDouble), - 'runtimeType': matchTypeInstanceRef('Type'), + 'runtimeType': matchTypeInstanceRef(matchTypeClassName), }; final matchDisplayedTypeObject = [ matches('[0-9]*'), - 'Type', + matchTypeClassName, ]; - group('$compilationMode |', () { setUpAll(() async { setCurrentLogWriter(debug: debug); @@ -90,6 +106,7 @@ Future _runTests({ enableExpressionEvaluation: true, verboseCompiler: debug, experiments: ['records', 'patterns'], + canaryFeatures: canaryFeatures, ); service = context.debugConnection.vmService; @@ -123,7 +140,9 @@ Future _runTests({ final classId = instanceRef.classRef!.id; expect(await getObject(classId), matchTypeClass); - expect(await getFields(instanceRef, depth: 1), matchTypeObject); + + final fields = await getFields(instanceRef, depth: 1); + expect(fields, matchTypeObject); expect(await getDisplayedFields(instanceRef), matchDisplayedTypeObject); }); }); diff --git a/fixtures/_webdevSoundSmoke/web/main.dart b/fixtures/_webdevSoundSmoke/web/main.dart index 907bfdbba..d2e8d6291 100644 --- a/fixtures/_webdevSoundSmoke/web/main.dart +++ b/fixtures/_webdevSoundSmoke/web/main.dart @@ -19,5 +19,17 @@ void main() { var count = 0; Timer.periodic(const Duration(seconds: 1), (_) { print('Counter is: ${++count}'); // Breakpoint: printCounter + + print('${Mine(0)}'); }); } + +class Mine { + static int y = 0; + int x; + Mine(this.x); +} + +void foo() { + print('foo'); +} diff --git a/frontend_server_common/lib/src/asset_server.dart b/frontend_server_common/lib/src/asset_server.dart index 2731d1d30..d43d459e9 100644 --- a/frontend_server_common/lib/src/asset_server.dart +++ b/frontend_server_common/lib/src/asset_server.dart @@ -90,7 +90,7 @@ class TestAssetServer implements AssetReader { var headers = {}; - if (request.url.path.endsWith('index.html')) { + if (request.url.path.endsWith('.html')) { var indexFile = _fileSystem.file(index); if (indexFile.existsSync()) { headers[HttpHeaders.contentTypeHeader] = 'text/html'; @@ -101,6 +101,8 @@ class TestAssetServer implements AssetReader { return shelf.Response.notFound(''); } + // TODO: main.dart.js is sometimes requested as scopes/main.dart.js - update the request url so we can find it. + // If this is a JavaScript file, it must be in the in-memory cache. // Attempt to look up the file by URI. if (hasFile(requestPath)) { diff --git a/frontend_server_common/lib/src/devfs.dart b/frontend_server_common/lib/src/devfs.dart index 1c1c71db5..d7ef54bbd 100644 --- a/frontend_server_common/lib/src/devfs.dart +++ b/frontend_server_common/lib/src/devfs.dart @@ -63,13 +63,16 @@ class WebDevFS { final outputDirectoryPath = fileSystem.file(mainPath).parent.path; final entryPoint = mainUri.toString(); + final directory = p.dirname(entryPoint); + assetServer.writeFile( entryPoint, fileSystem.file(mainPath).readAsStringSync()); - assetServer.writeFile('require.js', requireJS.readAsStringSync()); assetServer.writeFile( - 'stack_trace_mapper.js', stackTraceMapper.readAsStringSync()); + p.join(directory, 'require.js'), requireJS.readAsStringSync()); + assetServer.writeFile(p.join(directory, 'stack_trace_mapper.js'), + stackTraceMapper.readAsStringSync()); assetServer.writeFile( - 'main.dart.js', + p.join(directory, 'main.dart.js'), generateBootstrapScript( requireUrl: 'require.js', mapperUrl: 'stack_trace_mapper.js', @@ -77,7 +80,7 @@ class WebDevFS { ), ); assetServer.writeFile( - 'main_module.bootstrap.js', + p.join(directory, 'main_module.bootstrap.js'), generateMainModule( entrypoint: entryPoint, ), diff --git a/frontend_server_common/lib/src/frontend_server_client.dart b/frontend_server_common/lib/src/frontend_server_client.dart index 3a5300d23..630b51f6b 100644 --- a/frontend_server_common/lib/src/frontend_server_client.dart +++ b/frontend_server_common/lib/src/frontend_server_client.dart @@ -258,6 +258,7 @@ class ResidentCompiler { required this.platformDill, required this.soundNullSafety, this.experiments = const [], + this.canaryFeatures = false, required this.sdkLayout, this.verbose = false, CompilerMessageConsumer compilerMessageConsumer = defaultConsumer, @@ -271,6 +272,7 @@ class ResidentCompiler { final String platformDill; final bool soundNullSafety; final List experiments; + final bool canaryFeatures; final TestSdkLayout sdkLayout; final bool verbose; @@ -391,6 +393,7 @@ class ResidentCompiler { '--experimental-emit-debug-metadata', soundNullSafety ? '--sound-null-safety' : '--no-sound-null-safety', for (final experiment in experiments) '--enable-experiment=$experiment', + if (canaryFeatures) '--canary', if (verbose) '--verbose', ]; diff --git a/frontend_server_common/lib/src/resident_runner.dart b/frontend_server_common/lib/src/resident_runner.dart index 826fc6a38..ba63e4396 100644 --- a/frontend_server_common/lib/src/resident_runner.dart +++ b/frontend_server_common/lib/src/resident_runner.dart @@ -30,6 +30,7 @@ class ResidentWebRunner { required this.outputPath, required this.soundNullSafety, this.experiments = const [], + this.canaryFeatures = false, required this.sdkLayout, bool verbose = false, }) { @@ -47,6 +48,7 @@ class ResidentWebRunner { fileSystemScheme: fileSystemScheme, soundNullSafety: soundNullSafety, experiments: experiments, + canaryFeatures: canaryFeatures, sdkLayout: sdkLayout, verbose: verbose, ); @@ -63,6 +65,7 @@ class ResidentWebRunner { final String fileSystemScheme; final bool soundNullSafety; final List experiments; + final bool canaryFeatures; final TestSdkLayout sdkLayout; late ResidentCompiler generator; diff --git a/test_common/lib/sdk_asset_generator.dart b/test_common/lib/sdk_asset_generator.dart index e9584e24d..16dc7be8e 100644 --- a/test_common/lib/sdk_asset_generator.dart +++ b/test_common/lib/sdk_asset_generator.dart @@ -17,6 +17,7 @@ class SdkAssetGenerator { final _logger = Logger('SdkAssetGenerator'); final FileSystem fileSystem; + final bool canaryFeatures; final bool verbose; late final TestSdkLayout sdkLayout; @@ -24,6 +25,7 @@ class SdkAssetGenerator { SdkAssetGenerator({ this.fileSystem = const LocalFileSystem(), required this.sdkLayout, + required this.canaryFeatures, this.verbose = false, }); @@ -36,15 +38,24 @@ class SdkAssetGenerator { // normally generated by setup tools and their builds, // i.e. flutter SDK or build_web_compilers. // Generate missing files for tests if needed. - await _generateSdkJavaScript(soundNullSafety: true); + await _generateSdkJavaScript( + soundNullSafety: true, + canaryFeatures: canaryFeatures, + ); // SDK does not contain any weak assets, generate them. - await _generateSdkJavaScript(soundNullSafety: false); + await _generateSdkJavaScript( + soundNullSafety: false, + canaryFeatures: canaryFeatures, + ); await _generateSdkSummary(soundNullSafety: false); } } - Future _generateSdkJavaScript({required bool soundNullSafety}) async { + Future _generateSdkJavaScript({ + required bool soundNullSafety, + required bool canaryFeatures, + }) async { Directory? outputDir; try { // Files to copy generated files to. @@ -92,6 +103,7 @@ class SdkAssetGenerator { 'dart:core', '-o', jsPath, + if (canaryFeatures) '--canary', ]; final output = []; diff --git a/test_common/lib/test_sdk_configuration.dart b/test_common/lib/test_sdk_configuration.dart index b80c9d967..a4ef44b95 100644 --- a/test_common/lib/test_sdk_configuration.dart +++ b/test_common/lib/test_sdk_configuration.dart @@ -24,12 +24,17 @@ class TestSdkConfigurationProvider extends SdkConfigurationProvider { final _logger = Logger('TestSdkConfigurationProvider'); final bool _verbose; + final bool _canaryFeatures; late final Directory _sdkDirectory; SdkConfiguration? _configuration; late final TestSdkLayout sdkLayout; - TestSdkConfigurationProvider({bool verbose = false}) : _verbose = verbose { + TestSdkConfigurationProvider({ + bool verbose = false, + bool canaryFeatures = false, + }) : _verbose = verbose, + _canaryFeatures = canaryFeatures { _sdkDirectory = Directory.systemTemp.createTempSync('sdk copy'); sdkLayout = TestSdkLayout.createDefault(_sdkDirectory.path); } @@ -56,6 +61,7 @@ class TestSdkConfigurationProvider extends SdkConfigurationProvider { try { final assetGenerator = SdkAssetGenerator( sdkLayout: sdkLayout, + canaryFeatures: _canaryFeatures, verbose: _verbose, ); diff --git a/test_common/test/sdk_asset_generator_test.dart b/test_common/test/sdk_asset_generator_test.dart index 79c98df22..97a8adb78 100644 --- a/test_common/test/sdk_asset_generator_test.dart +++ b/test_common/test/sdk_asset_generator_test.dart @@ -75,8 +75,11 @@ void main() { final sdkLayout = TestSdkLayout.createDefault(sdkDirectory); final configuration = TestSdkLayout.createConfiguration(sdkLayout); - final assetGenerator = - SdkAssetGenerator(sdkLayout: sdkLayout, verbose: true); + final assetGenerator = SdkAssetGenerator( + sdkLayout: sdkLayout, + verbose: true, + canaryFeatures: false, + ); await assetGenerator.generateSdkAssets(); // Make sure SDK configuration and asset generator agree on the file paths. From 00beecb78d3bd569fd95b5ed1a93300e2ff72f25 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 23 Jun 2023 15:34:41 -0700 Subject: [PATCH 02/24] Fix analyzer warnings --- dwds/lib/src/debugging/classes.dart | 86 +-------------------------- dwds/lib/src/debugging/libraries.dart | 40 +------------ 2 files changed, 3 insertions(+), 123 deletions(-) diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index 027d5a622..23c3a9fb1 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -23,7 +23,7 @@ class ClassHelper extends Domain { final staticClasses = [ classRefForClosure, classRefForString, - classRefForUnknown + classRefForUnknown, ]; for (var classRef in staticClasses) { final classId = classRef.id; @@ -80,7 +80,6 @@ class ClassHelper extends Domain { if (libraryUri == null || classId == null || className == null) return null; - //final rawName = className.split('<').first; final expression = ''' (function() { const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); @@ -89,89 +88,6 @@ class ClassHelper extends Domain { })() '''; - /*final expression = ''' - (function() { - ${globalLoadStrategy.loadLibrarySnippet(libraryUri)} - var result = {}; - var clazz = library["$rawName"]; - var descriptor = { - 'name': clazz.name, - 'dartName': dart.typeName(clazz) - }; - - // TODO(grouma) - we display all inherited methods since we don't provide - // the superClass information. This is technically not correct. - var proto = clazz.prototype; - var methodNames = []; - for (; proto != null; proto = Object.getPrototypeOf(proto)) { - var methods = Object.getOwnPropertyNames(proto); - for (var i = 0; i < methods.length; i++) { - if (methodNames.indexOf(methods[i]) == -1 - && methods[i] != 'constructor') { - methodNames.push(methods[i]); - } - } - if (proto.constructor.name == 'Object') break; - } - - descriptor['methods'] = {}; - for (var name of methodNames) { - descriptor['methods'][name] = { - // TODO(jakemac): how can we get actual const info? - "isConst": false, - "isStatic": false, - } - } - - var fields = dart.getFields(clazz); - var fieldNames = fields ? Object.keys(fields) : []; - descriptor['fields'] = {}; - for (var name of fieldNames) { - var field = fields[name]; - var libraryUri = Object.getOwnPropertySymbols(fields[name]["type"]) - .find(x => x.description == "libraryUri"); - descriptor['fields'][name] = { - // TODO(jakemac): how can we get actual const info? - "isConst": false, - "isFinal": field.isFinal, - "isStatic": false, - "classRefName": fields[name]["type"]["name"], - "classRefDartName": dart.typeName(fields[name]["type"]), - "classRefLibraryId" : field["type"][libraryUri], - } - } - - // TODO(elliette): The following static member information is minimal and - // should be replaced once DDC provides full symbol information (see - // https://github.com/dart-lang/sdk/issues/40273): - - descriptor['staticFields'] = {}; - var staticFieldNames = dart.getStaticFields(clazz) ?? []; - for (const name of staticFieldNames) { - descriptor['staticFields'][name] = { - "isStatic": true, - // DDC only provides names of static members, we set isConst/isFinal - // to false even though they could be true. - "isConst": false, - "isFinal": false, - } - } - - descriptor['staticMethods'] = {}; - var staticMethodNames = dart.getStaticMethods(clazz) ?? []; - for (var name of staticMethodNames) { - descriptor['methods'][name] = { - // DDC only provides names of static members, we set isConst - // to false even though it could be true. - "isConst": false, - "isStatic": true, - } - } - - return descriptor; - })() - ''';*/ - RemoteObject result; try { result = await inspector.remoteDebugger.evaluate( diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index dbc617f60..7ce8997ad 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -81,7 +81,7 @@ class LibraryHelper extends Domain { final libraryId = libraryRef.id; 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 = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); @@ -89,43 +89,7 @@ class LibraryHelper extends Domain { return dart.getLibraryMetadata('$libraryUri'); })() '''; - // Fetch information about all the classes in this library. - /*final expression = ''' - (function() { - ${globalLoadStrategy.loadLibrarySnippet(libraryUri)} - - var result = {}; - var classes = Object.values(Object.getOwnPropertyDescriptors(library)) - .filter((p) => 'value' in p) - .map((p) => p.value) - .filter((l) => l && (l.prototype instanceof core.Object)); - var classList = classes.map(function(clazz) { - var descriptor = { - 'name': clazz.name, - 'dartName': dart.typeName(dart.getReifiedType(clazz.prototype)) - }; - return descriptor; - }); - result['classes'] = classList; - return result; - - // var result = {}; - // var classes = Object.values(Object.getOwnPropertyDescriptors(library)) - // .filter((p) => 'value' in p) - // .map((p) => p.value) - // .filter((l) => l && dart.isType(l)); - // var classList = classes.map(function(clazz) { - // var descriptor = { - // 'name': clazz.name, - // 'dartName': dart.typeName(clazz) - // }; - // return descriptor; - // }); - // result['classes'] = classList; - // return result; - })() - ''';*/ RemoteObject? result; try { result = await inspector.jsEvaluate(expression, returnByValue: true); @@ -136,7 +100,7 @@ class LibraryHelper extends Domain { // TODO: Collect library and class information from debug symbols. _logger.warning('Library ${libraryRef.uri} is not loaded. ' 'This can happen for unreferenced libraries.'); - rethrow; + //rethrow; } final classRefs = []; if (result != null) { From 463c5d12fdc9ac639e9d11010e11e7dff44d801e Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 23 Jun 2023 16:02:38 -0700 Subject: [PATCH 03/24] Cleanup --- dwds/lib/src/debugging/classes.dart | 3 +- dwds/lib/src/debugging/inspector.dart | 23 +-- dwds/lib/src/debugging/instance.dart | 138 +------------ dwds/lib/src/debugging/libraries.dart | 1 - dwds/lib/src/debugging/metadata/class.dart | 182 +----------------- .../instances/instance_inspection_common.dart | 4 +- dwds/test/instances/instance_test.dart | 30 +-- 7 files changed, 27 insertions(+), 354 deletions(-) diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index 23c3a9fb1..2fca2d4d0 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -99,7 +99,7 @@ class ClassHelper extends Domain { throw ChromeDebugException(e.json, evalContents: expression); } - _logger.severe('Result: ${result.json}'); + _logger.fine('Class info: ${result.json}'); final classDescriptor = result.value as Map; final methodRefs = []; @@ -127,7 +127,6 @@ class ClassHelper extends Domain { final fieldDescriptors = classDescriptor['fields'] as Map; fieldDescriptors.forEach((name, descriptor) { final classMetaData = ClassMetaData( - jsName: descriptor['classRefName'], runtimeKind: RuntimeObjectKind.type, classRef: classRefFor( descriptor['classRefLibraryId'], diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 7a7316012..215b00f9d 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -650,28 +650,7 @@ class AppInspector implements AppInspectorInterface { return dart.getSubRange(this, offset, count, end); } '''; -/* function (offset, count, end) { - const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); - const dart_rti = sdk.dart_rti; - const dart = sdk.dart; - - const _is = dart.privateName(dart_rti, "_is"); - if (dart_rti.findType("core|Map<@,@>")[_is](this)) { - - //if (sdk.core.Map.is(this)) { - const entries = sdk.dart.dload(this, "entries"); - const skipped = sdk.dart.dsend(entries, "skip", [offset]) - const taken = sdk.dart.dsend(skipped, "take", [count]); - return sdk.dart.dsend(taken, "toList", []); - - } else if (dart_rti.findType("core|List<@>")[_is](this)) { - //} else if (sdk.core.List.is(this)) { - return sdk.dart.dsendRepl(this, "sublist", [offset, end]); - } else { - return this; - } - } - ''';*/ + return await jsCallFunctionOn(receiver, expression, args); } diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index c37b891d0..cdc13232d 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -291,23 +291,7 @@ class InstanceHelper extends Domain { return sdkUtils.getMapElements(this); } '''; - /*final expression = ''' - function() { - var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - var entries = sdkUtils.dloadRepl(this, "entries"); - entries = sdkUtils.dsendRepl(entries, "toList", []); - function asKey(entry) { - return sdkUtils.dloadRepl(entry, "key"); - } - function asValue(entry) { - return sdkUtils.dloadRepl(entry, "value"); - } - return { - keys: entries.map(asKey), - values: entries.map(asValue) - }; - } - ''';*/ + final keysAndValues = await inspector.jsCallFunctionOn(map, expression, []); final keys = await inspector.loadField(keysAndValues, 'keys'); final values = await inspector.loadField(keysAndValues, 'values'); @@ -529,23 +513,7 @@ class InstanceHelper extends Domain { return sdkUtils.getRecordFields(this); } '''; - /*final expression = ''' - function() { - var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - var shape = sdkUtils.dloadRepl(this, "shape"); - var positionalCount = sdkUtils.dloadRepl(shape, "positionals"); - var named = sdkUtils.dloadRepl(shape, "named"); - named = named == null? null: sdkUtils.dsendRepl(named, "toList", []); - var values = sdkUtils.dloadRepl(this, "values"); - values = sdkUtils.dsendRepl(values, "toList", []); - - return { - positionalCount: positionalCount, - named: named, - values: values - }; - } - ''';*/ + final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = await _recordShapeFields(result, offset: offset, count: count); @@ -680,44 +648,6 @@ class InstanceHelper extends Domain { } '''; - /* - final expression = ''' - function() { - const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); - const dart_rti = sdk.dart_rti; - const dart = sdk.dart; - - var type = null; - var shape = null; - var types = null; - if (type == null) { // new types - type = dart.dloadRepl(this, "_rti"); - types = dart.dloadRepl(type, "_rest"); - types = types.map(t => dart_rti.createRuntimeType(t)); - var length = types['length']; - var recipe = dart.dloadRepl(type, "_primary"); - var shapeKey = `\${length};\${recipe}`; - console.log(`shapeKey: \${shapeKey}`); - shape = dart.shapes.get(shapeKey); - console.log(`shape: \${shape}`); - } else { // old types - var type = dart.dloadRepl(this, "_type"); - shape = dart.dloadRepl(type, "shape"); - types = dart.dloadRepl(type, "types"); - types = types.map(t => dart.wrapType(t)); - types = dart.dsendRepl(types, "toList", []); - } - var positionalCount = dart.dloadRepl(shape, "positionals"); - var named = dart.dloadRepl(shape, "named"); - named = named == null? null: dart.dsendRepl(named, "toList", []); - - return { - positionalCount: positionalCount, - named: named, - types: types - }; - } - ''';*/ final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = await _recordShapeFields(result, offset: offset, count: count); @@ -746,14 +676,6 @@ class InstanceHelper extends Domain { return sdkUtils.getSetElements(this); } '''; - /* - const jsSet = sdkUtils.dloadRepl(this, "_map"); - const entries = [...jsSet.values()]; - return { - entries: entries - }; - } - ''';*/ final result = await inspector.jsCallFunctionOn(remoteObject, expression, []); @@ -832,19 +754,6 @@ class InstanceHelper extends Domain { return dart.getTypeFields(this); } '''; - /* final expression = ''' - function() { - var sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); - var dart = sdk.dart; - var hashCode = dart.dloadRepl(this, "hashCode"); - var runtimeType = dart.dloadRepl(this, "runtimeType"); - - return { - hashCode: hashCode, - runtimeType: runtimeType - }; - } - ''';*/ final result = await inspector.jsCallFunctionOn(type, expression, []); final hashCodeObject = await inspector.loadField(result, 'hashCode'); @@ -900,40 +809,6 @@ class InstanceHelper extends Domain { } '''; - /*'''function() { - const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); - const dart_rti = sdk.dart_rti; - const dart = sdk.dart; - - const fields = dart.getFields(dart.getType(this)) || []; - //if (!fields && (dart_sdk._interceptors.JSArray.is(this) || - // dart_sdk._js_helper.InternalMap.is(this))) { - - - const _is = dart.privateName(dart_rti, "_is"); - if (!fields && - (dart_rti.findType("core|List<@>")[_is](this)) || - (dart_rti.findType("core|Map<@,@>")[_is](this)) - ) { - - // Trim off the 'length' property. - const fields = allJsProperties.slice(0, allJsProperties.length -1); - return fields.join(','); - } - const privateFields = dart.getOwnPropertySymbols(fields); - const nonSymbolNames = privateFields - .map(sym => sym.description - .split('#').slice(-1)[0]); - const publicFieldNames = dart.getOwnPropertyNames(fields); - const symbolNames = Object.getOwnPropertySymbols(this) - .map(sym => sym.description - .split('#').slice(-1)[0] - .split('.').slice(-1)[0]); - return nonSymbolNames - .concat(publicFieldNames) - .concat(symbolNames).join(','); - } - ''';*/ final allNames = (await inspector .jsCallFunctionOn(remoteObject, fieldNameExpression, [])) .value as String; @@ -942,15 +817,6 @@ class InstanceHelper extends Domain { return allJsProperties .where((property) => names.contains(property.name)) .toList(); -/* - final names = (await inspector - .jsCallFunctionOn(remoteObject, fieldNameExpression, [])) - .value as List; - - // TODO(#761): Better support for large collections. - return allJsProperties - .where((property) => names.contains(property.name)) - .toList();*/ } /// Create an InstanceRef for an object, which may be a RemoteObject, or may diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index 7ce8997ad..ea3ef056a 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -109,7 +109,6 @@ class LibraryHelper extends Domain { List>.from(jsonValues['classes'] ?? []); for (final classDescriptor in classDescriptors) { final classMetaData = ClassMetaData( - jsName: classDescriptor['name'], runtimeKind: RuntimeObjectKind.type, classRef: classRefFor( libraryRef.id, diff --git a/dwds/lib/src/debugging/metadata/class.dart b/dwds/lib/src/debugging/metadata/class.dart index 2b4be4a65..ff18a836c 100644 --- a/dwds/lib/src/debugging/metadata/class.dart +++ b/dwds/lib/src/debugging/metadata/class.dart @@ -39,7 +39,8 @@ ClassRef classRefFor(Object? libraryId, Object? dartName) { } String classIdFor(String libraryId, String? name) => 'classes|$libraryId|$name'; -String classMetaDataIdFor(String library, String? jsName) => '$library:$jsName'; +String classMetaDataIdFor(ClassRef classRef) => + '${classRef.library!.id!}:${classRef.name}'; /// DDC runtime object kind. /// @@ -87,12 +88,6 @@ class ClassMetaData { /// Takes the form of 'libraryId:name'. final String id; - /// The name of the JS constructor for the object. - /// - /// This may be a constructor for a Dart, but it's still a JS name. For - /// example, 'Number', 'JSArray', 'Object'. - final String? jsName; - /// Type name for Type instances. /// /// For example, 'int', 'String', 'MyClass', 'List'. @@ -113,17 +108,15 @@ class ClassMetaData { String get kind => runtimeKind.toInstanceKind(); factory ClassMetaData({ - Object? jsName, Object? typeName, Object? length, required RuntimeObjectKind runtimeKind, required ClassRef classRef, }) { - final id = classMetaDataIdFor(classRef.library!.id!, jsName as String?); + final id = classMetaDataIdFor(classRef); return ClassMetaData._( id, classRef, - jsName, typeName as String?, int.tryParse('$length'), runtimeKind, @@ -133,7 +126,6 @@ class ClassMetaData { ClassMetaData._( this.id, this.classRef, - this.jsName, this.typeName, this.length, this.runtimeKind, @@ -160,9 +152,6 @@ class ClassMetaDataHelper { /// Returns null if the [remoteObject] is not a Dart class. Future metaDataFor(RemoteObject remoteObject) async { try { - /// TODO(annagrin): this breaks on changes to internal - /// type representation in DDC. Replace by runtime API. - /// https://github.com/dart-lang/sdk/issues/51583 final evalExpression = ''' function(arg) { const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); @@ -170,141 +159,7 @@ class ClassMetaDataHelper { return dart.getObjectMetadata(arg); } '''; - /* - final evalExpression = ''' - function(arg) { - const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); - const dart_rti = sdk.dart_rti; - const dart = sdk.dart; - const core = sdk.core; - const interceptors = sdk._interceptors; - const jsHelper = sdk._js_helper; - const collection = sdk.collection; - const reifiedType = dart.getReifiedType(arg); - const name = reifiedType.name; // this is always null - - const dartName = dart.typeName(reifiedType); - const rtiKind = dart.dloadRepl(reifiedType, "_kind"); - - var libraryId = null; - if (arg.constructor != null) { - libraryId = dart.getLibraryUri(arg.constructor); - } - - //const libraryId = dart.getLibraryUri(reifiedType); - - - const result = {}; - result['name'] = name; - result['libraryId'] = libraryId; - result['dartName'] = dartName; - result['length'] = arg['length']; - result['runtimeKind'] = 'object'; - //console.log(`library: \${libraryId}, dart name: \${dartName}, arg: \${arg}`); - - const _is = dart.privateName(dart_rti, "_is"); - if (dart_rti.findType("core|List<@>")[_is](arg)) { - result['runtimeKind'] = 'list'; - } - else if (dart_rti.findType("core|Map<@,@>")[_is](arg)) { - result['runtimeKind'] = 'map'; - } - else if (dart_rti.findType("core|Set<@>")[_is](arg)) { - result['runtimeKind'] = 'set'; - } - //if (name == '_HashSet') { - // result['runtimeKind'] = 'set'; - //} - //else if (name == 'JSArray') { - // result['runtimeKind'] = 'list'; - //} - //else if (name == 'LinkedMap' || name == 'IdentityMap') { - // result['runtimeKind'] = 'map'; - //} - //else if (reifiedType instanceof dart.AbstractFunctionType) { - // result['runtimeKind'] = 'function'; - // result['name'] = 'Function'; - //} - else if (rtiKind == ${RtiKind.kindFunction}) { - result['runtimeKind'] = 'function'; - result['name'] = 'Function'; - } - else if (arg instanceof dart.RecordImpl) { - result['runtimeKind'] = 'record'; - result['libraryId'] = 'dart:core'; - result['name'] = 'Record'; - result['dartName'] = 'Record'; - var shape = arg.shape; - var positionalCount = shape.positionals; - var namedCount = shape.named == null ? 0 : shape.named.length; - result['length'] = positionalCount + namedCount; - } - // else if (arg instanceof dart._Type) { - // var typeImpl = dart.dloadRepl(arg, "_type"); - // if (typeImpl instanceof dart.RecordType) { - // result['libraryId'] = 'dart:_runtime'; - // result['name'] = 'RecordType'; - // result['dartName'] = 'RecordType'; - // result['runtimeKind'] = 'recordType'; - // result['length'] = typeImpl.types.length; - // } - // else if (dart.is(typeImpl, core.Type)) { - // result['libraryId'] = 'dart:core'; - // result['name'] = 'Type'; - // result['dartName'] = 'Type'; - // result['runtimeKind'] = 'type'; - // result['typeName'] = dart.dsendRepl(arg, "toString", []); - // } - // } - else if (arg instanceof dart_rti._Type) { - var typeRti = dart.dloadRepl(arg, "_rti"); - var typeKind = dart.dloadRepl(typeRti, "_kind"); - if (typeKind == ${RtiKind.kindRecord}) { - var elements = dart.dloadRepl(typeRti, "_rest"); - result['libraryId'] = 'dart:_runtime'; - result['name'] = 'RecordType'; - result['dartName'] = 'RecordType'; - result['runtimeKind'] = 'recordType'; - result['length'] = elements['length']; - } - else { - result['libraryId'] = 'dart:core'; - result['name'] = 'Type'; - result['dartName'] = 'Type'; - result['runtimeKind'] = 'type'; - result['typeName'] = dart.dsendRepl(arg, "toString", []); - } - } - else if (arg instanceof interceptors.NativeError) { - result['runtimeKind'] = 'nativeError'; - } - else if (arg instanceof interceptors.JavaScriptObject) { - result['runtimeKind'] = 'nativeObject'; - } - else if (arg instanceof dart.DartError) { // TODO: how is DartError different from NativeError? - result['dartName'] = 'DartError'; - result['libraryId'] = 'dart:_runtime'; - result['runtimeKind'] = 'nativeError'; - } - else if (dartName == 'LegacyJavaScriptObject') { - // unknown JS object - no dart metadata. - // TODO(annagrin): dart.typeName returns 'LegacyJavaScriptObject' but - // the arg is not of type interceptors.LegacyJavaScriptObject. - // This happens for the main library `this` object, for example. - // Should it return something else? - return {}; - } - //else if (dart.is(arg, interceptors.NativeError)) { - // result['runtimeKind'] = 'nativeError'; - //} - //else if (dart.is(arg, interceptors.JavaScriptObject)) { - // result['runtimeKind'] = 'nativeObject'; - //} - return result; - } - '''; -*/ final result = await _inspector.jsCallFunctionOn( remoteObject, evalExpression, @@ -314,11 +169,6 @@ class ClassMetaDataHelper { final metadata = result.value as Map; final jsName = metadata['dartName']; - _logger.severe('Keys: ${metadata.keys}'); - - _logger.severe( - 'Dart metadata for remote $remoteObject: $metadata (${result.value.runtimeType}), name: $jsName'); - if (jsName == null) { return null; } @@ -329,14 +179,10 @@ class ClassMetaDataHelper { final runtimeKind = RuntimeObjectKind.parse(metadata['runtimeKind']); final length = metadata['length']; - _logger.severe( - 'Name: $dartName, library: $library, runtime kind: $runtimeKind'); - final classRef = classRefFor(library, dartName); _addRuntimeObjectKind(classRef, runtimeKind); return ClassMetaData( - jsName: jsName, typeName: typeName, length: length, runtimeKind: runtimeKind, @@ -378,25 +224,3 @@ class ClassMetaDataHelper { _runtimeObjectKinds[id] == RuntimeObjectKind.nativeError; } } - -/// Runtime type kinds, from rti.dart -class RtiKind { - // Terminal terms. - static const int kindNever = 1; - static const int kindDynamic = 2; - static const int kindVoid = 3; // TODO(sra): Use `dynamic` instead? - static const int kindAny = 4; // Dart1-style 'dynamic' for JS-interop. - static const int kindErased = 5; - // Unary terms. - static const int kindStar = 6; - static const int kindQuestion = 7; - static const int kindFutureOr = 8; - // More complex terms. - static const int kindInterface = 9; - // A vector of type parameters from enclosing functions and closures. - static const int kindBinding = 10; - static const int kindRecord = 11; - static const int kindFunction = 12; - static const int kindGenericFunction = 13; - static const int kindGenericFunctionParameter = 14; -} diff --git a/dwds/test/instances/instance_inspection_common.dart b/dwds/test/instances/instance_inspection_common.dart index 958aab16a..812fa6d55 100644 --- a/dwds/test/instances/instance_inspection_common.dart +++ b/dwds/test/instances/instance_inspection_common.dart @@ -295,7 +295,9 @@ Matcher matchClass({dynamic name, String? libraryId}) => isA() Matcher matchRecordClassRef = matchClassRef(name: matchRecordClassName, libraryId: _dartCoreLibrary); Matcher matchRecordTypeClassRef = matchClassRef( - name: matchRecordTypeClassName, libraryId: _dartRuntimeLibrary); + name: matchRecordTypeClassName, + libraryId: _dartRuntimeLibrary, +); Matcher matchTypeClassRef = matchClassRef(name: matchTypeClassName, libraryId: _dartCoreLibrary); Matcher matchListClassRef(dynamic type) => diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index c4ea71544..0560d949c 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -306,19 +306,23 @@ void _runTests({ expect(inspector.isDisplayableObject(instance), isTrue); }); - test('for a class that implements List', () async { - // The VM only uses kind List for SDK lists, and we follow that. - final remote = - await inspector.jsEvaluate(libraryVariableExpression('notAList')); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef.name, 'NotReallyAList'); - expect(instance.elements, isNull); - final field = instance.fields!.first; - expect(field.decl!.name, '_internal'); - expect(inspector.isDisplayableObject(instance), isTrue); - }, skip: true); + test( + 'for a class that implements List', + () async { + // The VM only uses kind List for SDK lists, and we follow that. + final remote = + await inspector.jsEvaluate(libraryVariableExpression('notAList')); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef.name, 'NotReallyAList'); + expect(instance.elements, isNull); + final field = instance.fields!.first; + expect(field.decl!.name, '_internal'); + expect(inspector.isDisplayableObject(instance), isTrue); + }, + skip: true, + ); test('for a Dart error', () async { final remoteObject = await inspector.jsEvaluate(newDartError); From f711135ad8f784f58e88e66634a405eda355b055 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 27 Jun 2023 08:41:04 -0700 Subject: [PATCH 04/24] Run instance tests with frontend server and build daemon --- dwds/test/fixtures/context.dart | 10 +- .../instances/instance_inspection_test.dart | 4 - dwds/test/instances/instance_test.dart | 652 +++++++++--------- .../instances/patterns_inspection_test.dart | 4 - .../instances/record_inspection_test.dart | 4 - .../record_type_inspection_test.dart | 4 - dwds/test/instances/type_inspection_test.dart | 4 - fixtures/_testSound/pubspec.yaml | 4 + fixtures/_webdevSoundSmoke/pubspec.yaml | 4 + 9 files changed, 354 insertions(+), 336 deletions(-) diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index c231648a9..02b2fb105 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -150,10 +150,6 @@ class TestContext { List experiments = const [], bool canaryFeatures = false, }) async { - if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { - throw StateError('DDC canary mode is not supported with build daemon'); - } - final sdkLayout = sdkConfigurationProvider.sdkLayout; try { @@ -229,6 +225,12 @@ class TestContext { '--define', 'build_web_compilers|ddc=generate-full-dill=true', ], + if (canaryFeatures) ...[ + '--define', + 'build_web_compilers|ddc=canary=true', + '--define', + 'build_web_compilers|sdk_js=canary=true', + ], for (final experiment in experiments) '--enable-experiment=$experiment', '--verbose', diff --git a/dwds/test/instances/instance_inspection_test.dart b/dwds/test/instances/instance_inspection_test.dart index 0ed8b26a9..57aaa1325 100644 --- a/dwds/test/instances/instance_inspection_test.dart +++ b/dwds/test/instances/instance_inspection_test.dart @@ -34,10 +34,6 @@ void _runAllTests(bool canaryFeatures, bool debug) { for (var compilationMode in CompilationMode.values) { for (var nullSafetyMode in NullSafety.values) { - // TODO:(annagrin) support canary mode in build daemon mode. - if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { - continue; - } _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index 0560d949c..07e80fe53 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -17,7 +17,7 @@ import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'instance_inspection_common.dart'; -void main() async { +void main() { // Enable verbose logging for debugging. final debug = false; @@ -28,343 +28,371 @@ void main() async { void _runAllTests(bool canaryFeatures, bool debug) { group('canaryFeatures: $canaryFeatures |', () { - final provider = - TestSdkConfigurationProvider(canaryFeatures: canaryFeatures); - tearDownAll(provider.dispose); - - _runTests( - provider: provider, + final provider = TestSdkConfigurationProvider( + verbose: debug, canaryFeatures: canaryFeatures, - debug: debug, ); + tearDownAll(provider.dispose); + + for (var compilationMode in CompilationMode.values) { + _runTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } }); } void _runTests({ required TestSdkConfigurationProvider provider, - bool canaryFeatures = false, + required CompilationMode compilationMode, + required bool canaryFeatures, required bool debug, }) { late AppInspector inspector; final context = TestContext(TestProject.testScopesWithSoundNullSafety, provider); - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - canaryFeatures: canaryFeatures, - compilationMode: CompilationMode.frontendServer, - ); - final chromeProxyService = context.service; - inspector = chromeProxyService.inspector; - }); - - tearDownAll(() async { - await context.tearDown(); - }); - - final url = 'org-dartlang-app:///example/scopes/main.dart'; - - String libraryVariableExpression(String variable) => - '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.getModuleLibraries("example/scopes/main.dart")' - '["$url"]["$variable"];'; - - String newInterceptorsExpression(String type) => - 'new (require("dart_sdk")._interceptors.$type).new()'; - - final String newDartError = 'new (require("dart_sdk").dart).DartError'; - - /// A reference to the the variable `libraryPublicFinal`, an instance of - /// `MyTestClass`. - Future libraryPublicFinal() => - inspector.jsEvaluate(libraryVariableExpression('libraryPublicFinal')); - - /// A reference to the the variable `libraryPublic`, a List of Strings. - Future libraryPublic() => - inspector.jsEvaluate(libraryVariableExpression('libraryPublic')); - - group('instanceRef', () { - setUp(() => setCurrentLogWriter(debug: debug)); - - test('for a null', () async { - final remoteObject = await libraryPublicFinal(); - final nullVariable = await inspector.loadField(remoteObject, 'notFinal'); - final ref = await inspector.instanceRefFor(nullVariable); - expect(ref!.valueAsString, 'null'); - expect(ref.kind, InstanceKind.kNull); - final classRef = ref.classRef!; - expect(classRef.name, 'Null'); - expect(classRef.id, 'classes|dart:core|Null'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a double', () async { - final remoteObject = await libraryPublicFinal(); - final count = await inspector.loadField(remoteObject, 'count'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.valueAsString, '0'); - expect(ref.kind, InstanceKind.kDouble); - final classRef = ref.classRef!; - expect(classRef.name, 'Double'); - expect(classRef.id, 'classes|dart:core|Double'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a class', () async { - final remoteObject = await libraryPublicFinal(); - final count = await inspector.loadField(remoteObject, 'myselfField'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.kind, InstanceKind.kPlainInstance); - final classRef = ref.classRef!; - expect(classRef.name, 'MyTestClass'); - expect( - classRef.id, - 'classes|org-dartlang-app:///example/scopes/main.dart' - '|MyTestClass'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for closure', () async { - final remoteObject = await libraryPublicFinal(); - final properties = await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final ref = await inspector.instanceRefFor(closure.value!); - final functionName = ref!.closureFunction!.name; - // Older SDKs do not contain function names - if (functionName != 'Closure') { - expect(functionName, 'someFunction'); - } - expect(ref.kind, InstanceKind.kClosure); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a list', () async { - final remoteObject = await libraryPublic(); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, greaterThan(0)); - expect(ref.kind, InstanceKind.kList); - expect(ref.classRef!.name, matchListClassName('String')); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for map', () async { - final remoteObject = - await inspector.jsEvaluate(libraryVariableExpression('map')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'LinkedMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for an IdentityMap', () async { - final remoteObject = - await inspector.jsEvaluate(libraryVariableExpression('identityMap')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'IdentityMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript error', () async { - final remoteObject = - await inspector.jsEvaluate(newInterceptorsExpression('NativeError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); + group('$compilationMode |', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + canaryFeatures: canaryFeatures, + compilationMode: compilationMode, + ); + final chromeProxyService = context.service; + inspector = chromeProxyService.inspector; }); - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isFalse); - expect(inspector.isNativeJsObject(ref), isTrue); + tearDownAll(() async { + await context.tearDown(); }); - }); - group('instance', () { - setUp(() => setCurrentLogWriter(debug: debug)); - test('for class object', () async { - final remoteObject = await libraryPublicFinal(); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - final boundFieldNames = - instance.fields!.map((boundField) => boundField.decl!.name).toList(); - expect(boundFieldNames, [ - '_privateField', - 'abstractField', - 'closure', - 'count', - 'message', - 'myselfField', - 'notFinal', - 'tornOff', - ]); - final fieldNames = - instance.fields!.map((boundField) => boundField.name).toList(); - expect(boundFieldNames, fieldNames); - for (var field in instance.fields!) { - expect(field.name, isNotNull); - expect(field.decl!.declaredType, isNotNull); - } - expect(inspector.isDisplayableObject(instance), isTrue); + final url = 'org-dartlang-app:///example/scopes/main.dart'; + + String libraryName(CompilationMode compilationMode) => + compilationMode == CompilationMode.frontendServer + ? "example/scopes/main.dart" + : "example/scopes/main"; + + String libraryVariableExpression( + String variable, + CompilationMode compilationMode, + ) => + '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.' + 'getModuleLibraries("${libraryName(compilationMode)}")' + '["$url"]["$variable"];'; + + String newInterceptorsExpression(String type) => + 'new (require("dart_sdk")._interceptors.$type).new()'; + + final String newDartError = 'new (require("dart_sdk").dart).DartError'; + + /// A reference to the the variable `libraryPublicFinal`, an instance of + /// `MyTestClass`. + Future libraryPublicFinal(CompilationMode compilationMode) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublicFinal', compilationMode), + ); + + /// A reference to the the variable `libraryPublic`, a List of Strings. + Future libraryPublic(CompilationMode compilationMode) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublic', compilationMode), + ); + + group('instanceRef', () { + setUp(() => setCurrentLogWriter(debug: debug)); + + test('for a null', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final nullVariable = + await inspector.loadField(remoteObject, 'notFinal'); + final ref = await inspector.instanceRefFor(nullVariable); + expect(ref!.valueAsString, 'null'); + expect(ref.kind, InstanceKind.kNull); + final classRef = ref.classRef!; + expect(classRef.name, 'Null'); + expect(classRef.id, 'classes|dart:core|Null'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a double', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'count'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.valueAsString, '0'); + expect(ref.kind, InstanceKind.kDouble); + final classRef = ref.classRef!; + expect(classRef.name, 'Double'); + expect(classRef.id, 'classes|dart:core|Double'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a class', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'myselfField'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.kind, InstanceKind.kPlainInstance); + final classRef = ref.classRef!; + expect(classRef.name, 'MyTestClass'); + expect( + classRef.id, + 'classes|org-dartlang-app:///example/scopes/main.dart' + '|MyTestClass'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final ref = await inspector.instanceRefFor(closure.value!); + final functionName = ref!.closureFunction!.name; + // Older SDKs do not contain function names + if (functionName != 'Closure') { + expect(functionName, 'someFunction'); + } + expect(ref.kind, InstanceKind.kClosure); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a list', () async { + final remoteObject = await libraryPublic(compilationMode); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, greaterThan(0)); + expect(ref.kind, InstanceKind.kList); + expect(ref.classRef!.name, matchListClassName('String')); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for map', () async { + final remoteObject = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'LinkedMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for an IdentityMap', () async { + final remoteObject = await inspector.jsEvaluate( + libraryVariableExpression('identityMap', compilationMode), + ); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'IdentityMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isFalse); + expect(inspector.isNativeJsObject(ref), isTrue); + }); }); - test('for closure', () async { - final remoteObject = await libraryPublicFinal(); - final properties = await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final instance = await inspector.instanceFor(closure.value!); - expect(instance!.kind, InstanceKind.kClosure); - expect(instance.classRef!.name, 'Closure'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a nested class', () async { - final libraryRemoteObject = await libraryPublicFinal(); - final fieldRemoteObject = - await inspector.loadField(libraryRemoteObject, 'myselfField'); - final instance = await inspector.instanceFor(fieldRemoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a list', () async { - final remote = await libraryPublic(); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kList); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, matchListClassName('String')); - final first = instance.elements![0]; - expect(first.valueAsString, 'library'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a map', () async { - final remote = - await inspector.jsEvaluate(libraryVariableExpression('map')); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'LinkedMap'); - final first = instance.associations![0].value as InstanceRef; - expect(first.kind, InstanceKind.kList); - expect(first.length, 3); - final second = instance.associations![1].value as InstanceRef; - expect(second.kind, InstanceKind.kString); - expect(second.valueAsString, 'something'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for an identityMap', () async { - final remote = - await inspector.jsEvaluate(libraryVariableExpression('identityMap')); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'IdentityMap'); - final first = instance.associations![0].value; - expect(first.valueAsString, '1'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test( - 'for a class that implements List', - () async { - // The VM only uses kind List for SDK lists, and we follow that. - final remote = - await inspector.jsEvaluate(libraryVariableExpression('notAList')); - final instance = await inspector.instanceFor(remote); + group('instance', () { + setUp(() => setCurrentLogWriter(debug: debug)); + test('for class object', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final instance = await inspector.instanceFor(remoteObject); expect(instance!.kind, InstanceKind.kPlainInstance); final classRef = instance.classRef!; - expect(classRef.name, 'NotReallyAList'); - expect(instance.elements, isNull); - final field = instance.fields!.first; - expect(field.decl!.name, '_internal'); + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + final boundFieldNames = instance.fields! + .map((boundField) => boundField.decl!.name) + .toList(); + expect(boundFieldNames, [ + '_privateField', + 'abstractField', + 'closure', + 'count', + 'message', + 'myselfField', + 'notFinal', + 'tornOff', + ]); + final fieldNames = + instance.fields!.map((boundField) => boundField.name).toList(); + expect(boundFieldNames, fieldNames); + for (var field in instance.fields!) { + expect(field.name, isNotNull); + expect(field.decl!.declaredType, isNotNull); + } expect(inspector.isDisplayableObject(instance), isTrue); - }, - skip: true, - ); + }); + + test('for closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final instance = await inspector.instanceFor(closure.value!); + expect(instance!.kind, InstanceKind.kClosure); + expect(instance.classRef!.name, 'Closure'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); + test('for a nested class', () async { + final libraryRemoteObject = await libraryPublicFinal(compilationMode); + final fieldRemoteObject = + await inspector.loadField(libraryRemoteObject, 'myselfField'); + final instance = await inspector.instanceFor(fieldRemoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test('for a native JavaScript error', () async { - final remoteObject = - await inspector.jsEvaluate(newInterceptorsExpression('NativeError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); + test('for a list', () async { + final remote = await libraryPublic(compilationMode); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kList); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, matchListClassName('String')); + final first = instance.elements![0]; + expect(first.valueAsString, 'library'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); + test('for a map', () async { + final remote = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; + expect(classRef.name, 'LinkedMap'); + final first = instance.associations![0].value as InstanceRef; + expect(first.kind, InstanceKind.kList); + expect(first.length, 3); + final second = instance.associations![1].value as InstanceRef; + expect(second.kind, InstanceKind.kString); + expect(second.valueAsString, 'something'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isFalse); - expect(inspector.isNativeJsObject(instance), isTrue); + test('for an identityMap', () async { + final remote = await inspector.jsEvaluate( + libraryVariableExpression('identityMap', compilationMode), + ); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; + expect(classRef.name, 'IdentityMap'); + final first = instance.associations![0].value; + expect(first.valueAsString, '1'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test( + 'for a class that implements List', + () async { + // The VM only uses kind List for SDK lists, and we follow that. + final remote = await inspector.jsEvaluate( + libraryVariableExpression('notAList', compilationMode), + ); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef.name, 'NotReallyAList'); + expect(instance.elements, isNull); + final field = instance.fields!.first; + expect(field.decl!.name, '_internal'); + expect(inspector.isDisplayableObject(instance), isTrue); + }, + skip: true, + ); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isFalse); + expect(inspector.isNativeJsObject(instance), isTrue); + }); }); }); } diff --git a/dwds/test/instances/patterns_inspection_test.dart b/dwds/test/instances/patterns_inspection_test.dart index 8c65d62da..29692aa24 100644 --- a/dwds/test/instances/patterns_inspection_test.dart +++ b/dwds/test/instances/patterns_inspection_test.dart @@ -33,10 +33,6 @@ void _runAllTests(bool canaryFeatures, bool debug) { tearDownAll(provider.dispose); for (var compilationMode in CompilationMode.values) { - // TODO:(annagrin) support canary mode in build daemon mode. - if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { - continue; - } _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/record_inspection_test.dart b/dwds/test/instances/record_inspection_test.dart index 83047c0f4..7d8321c91 100644 --- a/dwds/test/instances/record_inspection_test.dart +++ b/dwds/test/instances/record_inspection_test.dart @@ -33,10 +33,6 @@ void _runAllTests(bool canaryFeatures, bool debug) { tearDownAll(provider.dispose); for (var compilationMode in CompilationMode.values) { - // TODO:(annagrin) support canary mode in build daemon mode. - if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { - continue; - } _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/record_type_inspection_test.dart b/dwds/test/instances/record_type_inspection_test.dart index c5ed5e646..081fa5907 100644 --- a/dwds/test/instances/record_type_inspection_test.dart +++ b/dwds/test/instances/record_type_inspection_test.dart @@ -33,10 +33,6 @@ void _runAllTests(bool canaryFeatures, bool debug) { tearDownAll(provider.dispose); for (var compilationMode in CompilationMode.values) { - // TODO:(annagrin) support canary mode in build daemon mode. - if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { - continue; - } _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/type_inspection_test.dart b/dwds/test/instances/type_inspection_test.dart index f7deadd65..ac146302f 100644 --- a/dwds/test/instances/type_inspection_test.dart +++ b/dwds/test/instances/type_inspection_test.dart @@ -33,10 +33,6 @@ void _runAllTests(bool canaryFeatures, bool debug) { tearDownAll(provider.dispose); for (var compilationMode in CompilationMode.values) { - // TODO:(annagrin) support canary mode in build daemon mode. - if (canaryFeatures && compilationMode == CompilationMode.buildDaemon) { - continue; - } _runTests( provider: provider, compilationMode: compilationMode, diff --git a/fixtures/_testSound/pubspec.yaml b/fixtures/_testSound/pubspec.yaml index 6f161e844..2028f0fd9 100644 --- a/fixtures/_testSound/pubspec.yaml +++ b/fixtures/_testSound/pubspec.yaml @@ -15,3 +15,7 @@ dev_dependencies: build_runner: ^2.4.0 build_web_compilers: ^4.0.0 +dependency_overrides: + build_web_compilers: + path: ../../../build/build_web_compilers + diff --git a/fixtures/_webdevSoundSmoke/pubspec.yaml b/fixtures/_webdevSoundSmoke/pubspec.yaml index 9a69fc6bf..ec3dbbfc7 100644 --- a/fixtures/_webdevSoundSmoke/pubspec.yaml +++ b/fixtures/_webdevSoundSmoke/pubspec.yaml @@ -9,3 +9,7 @@ environment: dev_dependencies: build_runner: ^2.4.0 build_web_compilers: ^4.0.0 + +dependency_overrides: + build_web_compilers: + path: ../../../build/build_web_compilers \ No newline at end of file From c7c646e9331fc5918554a59f4ff12469f58cf70e Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Wed, 28 Jun 2023 07:49:46 -0700 Subject: [PATCH 05/24] Add canary option to webdev and expression compiler worker --- .../services/expression_compiler_service.dart | 4 +++- fixtures/_webdevSoundSmoke/build.yaml | 7 +++++++ fixtures/_webdevSoundSmoke/web/main.dart | 3 +++ webdev/lib/src/command/configuration.dart | 16 ++++++++++++++-- webdev/lib/src/command/shared.dart | 6 ++++++ webdev/lib/src/serve/webdev_server.dart | 1 + 6 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 fixtures/_webdevSoundSmoke/build.yaml diff --git a/dwds/lib/src/services/expression_compiler_service.dart b/dwds/lib/src/services/expression_compiler_service.dart index efd2dcde7..34f52bf90 100644 --- a/dwds/lib/src/services/expression_compiler_service.dart +++ b/dwds/lib/src/services/expression_compiler_service.dart @@ -254,7 +254,9 @@ class ExpressionCompilerService implements ExpressionCompiler { required this.sdkConfigurationProvider, this.experiments = const [], this.canaryFeatures = false, - }) : _verbose = verbose; + }) : _verbose = verbose { + print('ExpressionCompilerService: canary: $canaryFeatures'); + } @override Future compileExpressionToJs( diff --git a/fixtures/_webdevSoundSmoke/build.yaml b/fixtures/_webdevSoundSmoke/build.yaml new file mode 100644 index 000000000..797d391ad --- /dev/null +++ b/fixtures/_webdevSoundSmoke/build.yaml @@ -0,0 +1,7 @@ +global_options: + build_web_compilers:ddc: + options: + canary: true + build_web_compilers:sdk_js: + options: + canary: true \ No newline at end of file diff --git a/fixtures/_webdevSoundSmoke/web/main.dart b/fixtures/_webdevSoundSmoke/web/main.dart index d2e8d6291..67211da9a 100644 --- a/fixtures/_webdevSoundSmoke/web/main.dart +++ b/fixtures/_webdevSoundSmoke/web/main.dart @@ -21,6 +21,9 @@ void main() { print('Counter is: ${++count}'); // Breakpoint: printCounter print('${Mine(0)}'); + + var x = () => true; + print(x); }); } diff --git a/webdev/lib/src/command/configuration.dart b/webdev/lib/src/command/configuration.dart index ffd1c2fe0..193da166e 100644 --- a/webdev/lib/src/command/configuration.dart +++ b/webdev/lib/src/command/configuration.dart @@ -36,6 +36,7 @@ const nullSafetyUnsound = 'unsound'; const nullSafetyAuto = 'auto'; const disableDdsFlag = 'disable-dds'; const enableExperimentOption = 'enable-experiment'; +const canaryFeaturesFlag = 'canary'; ReloadConfiguration _parseReloadConfiguration(ArgResults argResults) { var auto = argResults.options.contains(autoOption) @@ -105,6 +106,7 @@ class Configuration { final bool? _disableDds; final String? _nullSafety; final List? _experiments; + final bool? _canaryFeatures; Configuration({ bool? autoRun, @@ -130,6 +132,7 @@ class Configuration { bool? disableDds, String? nullSafety, List? experiments, + bool? canaryFeatures, }) : _autoRun = autoRun, _chromeDebugPort = chromeDebugPort, _debugExtension = debugExtension, @@ -150,7 +153,8 @@ class Configuration { _enableExpressionEvaluation = enableExpressionEvaluation, _verbose = verbose, _nullSafety = nullSafety, - _experiments = experiments { + _experiments = experiments, + _canaryFeatures = canaryFeatures { _validateConfiguration(); } @@ -224,7 +228,8 @@ class Configuration { other._enableExpressionEvaluation ?? _enableExpressionEvaluation, verbose: other._verbose ?? _verbose, nullSafety: other._nullSafety ?? _nullSafety, - experiments: other._experiments ?? _experiments); + experiments: other._experiments ?? _experiments, + canaryFeatures: other._canaryFeatures ?? _canaryFeatures); factory Configuration.noInjectedClientDefaults() => Configuration(autoRun: false, debug: false, debugExtension: false); @@ -277,6 +282,8 @@ class Configuration { List get experiments => _experiments ?? []; + bool get canaryFeatures => _canaryFeatures ?? false; + /// Returns a new configuration with values updated from the parsed args. static Configuration fromArgs(ArgResults? argResults, {Configuration? defaultConfiguration}) { @@ -397,6 +404,10 @@ class Configuration { ? argResults[enableExperimentOption] as List? : defaultConfiguration.experiments; + var canaryFeatures = argResults.options.contains(canaryFeaturesFlag) + ? argResults[canaryFeaturesFlag] as bool? + : defaultConfiguration.canaryFeatures; + return Configuration( autoRun: defaultConfiguration.autoRun, chromeDebugPort: chromeDebugPort, @@ -421,6 +432,7 @@ class Configuration { verbose: verbose, nullSafety: nullSafety, experiments: experiments, + canaryFeatures: canaryFeatures, ); } } diff --git a/webdev/lib/src/command/shared.dart b/webdev/lib/src/command/shared.dart index f286ee7c5..71989fed3 100644 --- a/webdev/lib/src/command/shared.dart +++ b/webdev/lib/src/command/shared.dart @@ -63,6 +63,12 @@ void addSharedArgs(ArgParser argParser, defaultsTo: null, hide: true, help: 'Enable experiment features in the debugger.') + ..addFlag(canaryFeaturesFlag, + abbr: 'c', + defaultsTo: false, + negatable: true, + hide: true, + help: 'Enables DDC canary features.') ..addFlag(verboseFlag, abbr: 'v', defaultsTo: false, diff --git a/webdev/lib/src/serve/webdev_server.dart b/webdev/lib/src/serve/webdev_server.dart index 79718b33c..0f6ffa6df 100644 --- a/webdev/lib/src/serve/webdev_server.dart +++ b/webdev/lib/src/serve/webdev_server.dart @@ -138,6 +138,7 @@ class WebDevServer { options.port, verbose: options.configuration.verbose, experiments: options.configuration.experiments, + canaryFeatures: options.configuration.canaryFeatures, sdkConfigurationProvider: const DefaultSdkConfigurationProvider(), ); } From 64126899e046f6b5a1fe79215dc9b9743429750e Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 7 Jul 2023 14:45:45 -0700 Subject: [PATCH 06/24] Update for latest sdk changes --- dwds/lib/src/debugging/classes.dart | 33 +- dwds/lib/src/debugging/inspector.dart | 14 +- dwds/lib/src/debugging/instance.dart | 12 +- dwds/lib/src/debugging/libraries.dart | 9 +- dwds/test/instances/instance_test.dart | 652 +++++++++++++------------ 5 files changed, 372 insertions(+), 348 deletions(-) diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index 2fca2d4d0..17b5de95d 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -105,9 +105,9 @@ class ClassHelper extends Domain { final methodRefs = []; final methodDescriptors = classDescriptor['methods'] as Map; - final staticMethodDescriptors = - classDescriptor['staticMethods'] as Map; - methodDescriptors.addAll(staticMethodDescriptors); + //final staticMethodDescriptors = + // classDescriptor['staticMethods'] as Map; + //methodDescriptors.addAll(staticMethodDescriptors); methodDescriptors.forEach((name, descriptor) { final methodId = 'methods|$classId|$name'; methodRefs.add( @@ -126,13 +126,17 @@ class ClassHelper extends Domain { final fieldRefs = []; final fieldDescriptors = classDescriptor['fields'] as Map; fieldDescriptors.forEach((name, descriptor) { - final classMetaData = ClassMetaData( - runtimeKind: RuntimeObjectKind.type, - classRef: classRefFor( - descriptor['classRefLibraryId'], - descriptor['classRefDartName'], - ), - ); + final classMetaData = descriptor.containsKey('classRefLibraryId') && + descriptor.containsKey('classRefDartName') + ? ClassMetaData( + runtimeKind: RuntimeObjectKind.type, + classRef: classRefFor( + descriptor['classRefLibraryId'], + descriptor['classRefDartName'], + ), + ) + : _classMetadataForUnknown; + fieldRefs.add( FieldRef( name: name, @@ -150,7 +154,7 @@ class ClassHelper extends Domain { ), ); }); - +/* final staticFieldDescriptors = classDescriptor['staticFields'] as Map; staticFieldDescriptors.forEach((name, descriptor) { @@ -170,7 +174,7 @@ class ClassHelper extends Domain { id: createId(), ), ); - }); + });*/ // TODO: Implement the rest of these // https://github.com/dart-lang/webdev/issues/176. @@ -188,3 +192,8 @@ class ClassHelper extends Domain { ); } } + +final _classMetadataForUnknown = ClassMetaData( + runtimeKind: RuntimeObjectKind.object, + classRef: classRefForUnknown, +); diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 215b00f9d..9f3a26b60 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -634,20 +634,22 @@ class AppInspector implements AppInspectorInterface { // TODO(#809): Sometimes we already know the type of the object, and // we could take advantage of that to short-circuit. final receiver = remoteObjectFor(id); - final end = - _calculateRangeEnd(count: count, offset: offset, length: length); + //final end = + // _calculateRangeEnd(count: count, offset: offset, length: length); final rangeCount = _calculateRangeCount(count: count, offset: offset, length: length); - final args = - [offset, rangeCount, end].map(dartIdFor).map(remoteObjectFor).toList(); + final args = [offset, rangeCount /*, end*/] + .map(dartIdFor) + .map(remoteObjectFor) + .toList(); // If this is a List, just call sublist. If it's a Map, get the entries, but // avoid doing a toList on a large map using skip/take to get the section we // want. To make those alternatives easier in JS, pass both count and end. final expression = ''' - function (offset, count, end) { + function (offset, count) { const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); const dart = sdk.dart; - return dart.getSubRange(this, offset, count, end); + return dart.getSubRange(this, offset, count); } '''; diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index cdc13232d..fd9d5c54d 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -809,10 +809,14 @@ class InstanceHelper extends Domain { } '''; - final allNames = (await inspector - .jsCallFunctionOn(remoteObject, fieldNameExpression, [])) - .value as String; - final names = allNames.split(','); + final result = await inspector.jsCallFunctionOn( + remoteObject, + fieldNameExpression, + [], + returnByValue: true, + ); + final names = List.from(result.value as List); + // TODO(#761): Better support for large collections. return allJsProperties .where((property) => names.contains(property.name)) diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index ea3ef056a..a0871503b 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -104,15 +104,14 @@ class LibraryHelper extends Domain { } final classRefs = []; if (result != null) { - final jsonValues = result.value as Map; - final classDescriptors = - List>.from(jsonValues['classes'] ?? []); - for (final classDescriptor in classDescriptors) { + final classNames = result.value as List; + + for (final className in classNames) { final classMetaData = ClassMetaData( runtimeKind: RuntimeObjectKind.type, classRef: classRefFor( libraryRef.id, - classDescriptor['dartName'], + className, ), ); classRefs.add(classMetaData.classRef); diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index 16d35fe2e..73a7fb58b 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -17,366 +17,376 @@ import '../fixtures/context.dart'; import '../fixtures/project.dart'; import 'instance_inspection_common.dart'; -void main() { +void main() async { // Enable verbose logging for debugging. final debug = false; - final provider = TestSdkConfigurationProvider(verbose: debug); - tearDownAll(provider.dispose); - for (var compilationMode in [CompilationMode.frontendServer]) { - _runTests( - provider: provider, + await _runTests( compilationMode: compilationMode, + canaryFeatures: true, debug: debug, ); } } -void _runTests({ - required TestSdkConfigurationProvider provider, +Future _runTests({ required CompilationMode compilationMode, + required bool canaryFeatures, required bool debug, -}) { - final context = - TestContext(TestProject.testScopesWithSoundNullSafety, provider); - - late AppInspector inspector; - - group('$compilationMode |', () { - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp(compilationMode: compilationMode); - final chromeProxyService = context.service; - inspector = chromeProxyService.inspector; - }); - - tearDownAll(() async { - await context.tearDown(); - }); - - final url = 'org-dartlang-app:///example/scopes/main.dart'; - - String libraryName(CompilationMode compilationMode) => - compilationMode == CompilationMode.frontendServer - ? "example/scopes/main.dart" - : "example/scopes/main"; - - String libraryVariableExpression( - String variable, - CompilationMode compilationMode, - ) => - '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.' - 'getModuleLibraries("${libraryName(compilationMode)}")' - '["$url"]["$variable"];'; - - String newInterceptorsExpression(String type) => - 'new (require("dart_sdk")._interceptors.$type).new()'; +}) async { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + canaryFeatures: true, + verbose: debug, + ); + final project = TestProject.testScopesWithSoundNullSafety; + final context = TestContext(project, provider); - final String newDartError = 'new (require("dart_sdk").dart).DartError'; + setUpAll(project.cleanUp); + tearDownAll(provider.dispose); - /// A reference to the the variable `libraryPublicFinal`, an instance of - /// `MyTestClass`. - Future libraryPublicFinal(CompilationMode compilationMode) => - inspector.jsEvaluate( - libraryVariableExpression('libraryPublicFinal', compilationMode), - ); + late AppInspector inspector; - /// A reference to the the variable `libraryPublic`, a List of Strings. - Future libraryPublic(CompilationMode compilationMode) => - inspector.jsEvaluate( - libraryVariableExpression('libraryPublic', compilationMode), + group('$compilationMode |', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, ); - - group('instanceRef', () { - setUp(() => setCurrentLogWriter(debug: debug)); - - test('for a null', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final nullVariable = - await inspector.loadField(remoteObject, 'notFinal'); - final ref = await inspector.instanceRefFor(nullVariable); - expect(ref!.valueAsString, 'null'); - expect(ref.kind, InstanceKind.kNull); - final classRef = ref.classRef!; - expect(classRef.name, 'Null'); - expect(classRef.id, 'classes|dart:core|Null'); - expect(inspector.isDisplayableObject(ref), isTrue); + final chromeProxyService = context.service; + inspector = chromeProxyService.inspector; }); - test('for a double', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final count = await inspector.loadField(remoteObject, 'count'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.valueAsString, '0'); - expect(ref.kind, InstanceKind.kDouble); - final classRef = ref.classRef!; - expect(classRef.name, 'Double'); - expect(classRef.id, 'classes|dart:core|Double'); - expect(inspector.isDisplayableObject(ref), isTrue); + tearDownAll(() async { + await context.tearDown(); }); - test('for a class', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final count = await inspector.loadField(remoteObject, 'myselfField'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.kind, InstanceKind.kPlainInstance); - final classRef = ref.classRef!; - expect(classRef.name, 'MyTestClass'); - expect( - classRef.id, - 'classes|org-dartlang-app:///example/scopes/main.dart' - '|MyTestClass'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); + final url = 'org-dartlang-app:///example/scopes/main.dart'; - test('for closure', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final properties = - await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final ref = await inspector.instanceRefFor(closure.value!); - final functionName = ref!.closureFunction!.name; - // Older SDKs do not contain function names - if (functionName != 'Closure') { - expect(functionName, 'someFunction'); - } - expect(ref.kind, InstanceKind.kClosure); - expect(inspector.isDisplayableObject(ref), isTrue); - }); + String libraryName(CompilationMode compilationMode) => + compilationMode == CompilationMode.frontendServer + ? "example/scopes/main.dart" + : "example/scopes/main"; - test('for a list', () async { - final remoteObject = await libraryPublic(compilationMode); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, greaterThan(0)); - expect(ref.kind, InstanceKind.kList); - expect(ref.classRef!.name, matchListClassName('String')); - expect(inspector.isDisplayableObject(ref), isTrue); - }); + String libraryVariableExpression( + String variable, + CompilationMode compilationMode, + ) => + '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.' + 'getModuleLibraries("${libraryName(compilationMode)}")' + '["$url"]["$variable"];'; - test('for map', () async { - final remoteObject = await inspector - .jsEvaluate(libraryVariableExpression('map', compilationMode)); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'LinkedMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); + String newInterceptorsExpression(String type) => + 'new (require("dart_sdk")._interceptors.$type).new()'; - test('for an IdentityMap', () async { - final remoteObject = await inspector.jsEvaluate( - libraryVariableExpression('identityMap', compilationMode), - ); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'IdentityMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('NativeError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); + final String newDartError = 'new (require("dart_sdk").dart).DartError'; - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isFalse); - expect(inspector.isNativeJsObject(ref), isTrue); - }); - }); + /// A reference to the the variable `libraryPublicFinal`, an instance of + /// `MyTestClass`. + Future libraryPublicFinal( + CompilationMode compilationMode) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublicFinal', compilationMode), + ); - group('instance', () { - setUp(() => setCurrentLogWriter(debug: debug)); - test('for class object', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - final boundFieldNames = instance.fields! - .map((boundField) => boundField.decl!.name) - .toList(); - expect(boundFieldNames, [ - '_privateField', - 'abstractField', - 'closure', - 'count', - 'message', - 'myselfField', - 'notFinal', - 'tornOff', - ]); - final fieldNames = - instance.fields!.map((boundField) => boundField.name).toList(); - expect(boundFieldNames, fieldNames); - for (var field in instance.fields!) { - expect(field.name, isNotNull); - expect(field.decl!.declaredType, isNotNull); - } - expect(inspector.isDisplayableObject(instance), isTrue); - }); + /// A reference to the the variable `libraryPublic`, a List of Strings. + Future libraryPublic(CompilationMode compilationMode) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublic', compilationMode), + ); - test('for closure', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final properties = - await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final instance = await inspector.instanceFor(closure.value!); - expect(instance!.kind, InstanceKind.kClosure); - expect(instance.classRef!.name, 'Closure'); - expect(inspector.isDisplayableObject(instance), isTrue); + group('instanceRef', () { + setUp(() => setCurrentLogWriter(debug: debug)); + + test('for a null', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final nullVariable = + await inspector.loadField(remoteObject, 'notFinal'); + final ref = await inspector.instanceRefFor(nullVariable); + expect(ref!.valueAsString, 'null'); + expect(ref.kind, InstanceKind.kNull); + final classRef = ref.classRef!; + expect(classRef.name, 'Null'); + expect(classRef.id, 'classes|dart:core|Null'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a double', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'count'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.valueAsString, '0'); + expect(ref.kind, InstanceKind.kDouble); + final classRef = ref.classRef!; + expect(classRef.name, 'Double'); + expect(classRef.id, 'classes|dart:core|Double'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a class', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'myselfField'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.kind, InstanceKind.kPlainInstance); + final classRef = ref.classRef!; + expect(classRef.name, 'MyTestClass'); + expect( + classRef.id, + 'classes|org-dartlang-app:///example/scopes/main.dart' + '|MyTestClass'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final ref = await inspector.instanceRefFor(closure.value!); + final functionName = ref!.closureFunction!.name; + // Older SDKs do not contain function names + if (functionName != 'Closure') { + expect(functionName, 'someFunction'); + } + expect(ref.kind, InstanceKind.kClosure); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a list', () async { + final remoteObject = await libraryPublic(compilationMode); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, greaterThan(0)); + expect(ref.kind, InstanceKind.kList); + expect(ref.classRef!.name, matchListClassName('String')); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for map', () async { + final remoteObject = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'LinkedMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for an IdentityMap', () async { + final remoteObject = await inspector.jsEvaluate( + libraryVariableExpression('identityMap', compilationMode), + ); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'IdentityMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isFalse); + expect(inspector.isNativeJsObject(ref), isTrue); + }); }); - test('for a nested class', () async { - final libraryRemoteObject = await libraryPublicFinal(compilationMode); - final fieldRemoteObject = - await inspector.loadField(libraryRemoteObject, 'myselfField'); - final instance = await inspector.instanceFor(fieldRemoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); + group('instance', () { + setUp(() => setCurrentLogWriter(debug: debug)); + test('for class object', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + final boundFieldNames = instance.fields! + .map((boundField) => boundField.decl!.name) + .toList(); + expect(boundFieldNames, [ + '_privateField', + 'abstractField', + 'closure', + 'count', + 'message', + 'myselfField', + 'notFinal', + 'tornOff', + ]); + final fieldNames = + instance.fields!.map((boundField) => boundField.name).toList(); + expect(boundFieldNames, fieldNames); + for (var field in instance.fields!) { + expect(field.name, isNotNull); + expect(field.decl!.declaredType, isNotNull); + } + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final instance = await inspector.instanceFor(closure.value!); + expect(instance!.kind, InstanceKind.kClosure); + expect(instance.classRef!.name, 'Closure'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test('for a list', () async { - final remote = await libraryPublic(compilationMode); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kList); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, matchListClassName('String')); - final first = instance.elements![0]; - expect(first.valueAsString, 'library'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); + test('for a nested class', () async { + final libraryRemoteObject = await libraryPublicFinal(compilationMode); + final fieldRemoteObject = + await inspector.loadField(libraryRemoteObject, 'myselfField'); + final instance = await inspector.instanceFor(fieldRemoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test('for a map', () async { - final remote = await inspector - .jsEvaluate(libraryVariableExpression('map', compilationMode)); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'LinkedMap'); - final first = instance.associations![0].value as InstanceRef; - expect(first.kind, InstanceKind.kList); - expect(first.length, 3); - final second = instance.associations![1].value as InstanceRef; - expect(second.kind, InstanceKind.kString); - expect(second.valueAsString, 'something'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); + test('for a list', () async { + final remote = await libraryPublic(compilationMode); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kList); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, matchListClassName('String')); + final first = instance.elements![0]; + expect(first.valueAsString, 'library'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test('for an identityMap', () async { - final remote = await inspector.jsEvaluate( - libraryVariableExpression('identityMap', compilationMode), - ); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'IdentityMap'); - final first = instance.associations![0].value; - expect(first.valueAsString, '1'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); + test('for a map', () async { + final remote = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; + expect(classRef.name, 'LinkedMap'); + final first = instance.associations![0].value as InstanceRef; + expect(first.kind, InstanceKind.kList); + expect(first.length, 3); + final second = instance.associations![1].value as InstanceRef; + expect(second.kind, InstanceKind.kString); + expect(second.valueAsString, 'something'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); - test( - 'for a class that implements List', - () async { - // The VM only uses kind List for SDK lists, and we follow that. + test('for an identityMap', () async { final remote = await inspector.jsEvaluate( - libraryVariableExpression('notAList', compilationMode), + libraryVariableExpression('identityMap', compilationMode), ); final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance!.kind, InstanceKind.kMap); final classRef = instance.classRef!; - expect(classRef.name, 'NotReallyAList'); - expect(instance.elements, isNull); - final field = instance.fields!.first; - expect(field.decl!.name, '_internal'); + expect(classRef.name, 'IdentityMap'); + final first = instance.associations![0].value; + expect(first.valueAsString, '1'); expect(inspector.isDisplayableObject(instance), isTrue); - }, - skip: true, - ); - - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('NativeError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); + }); + + test( + 'for a class that implements List', + () async { + // The VM only uses kind List for SDK lists, and we follow that. + final remote = await inspector.jsEvaluate( + libraryVariableExpression('notAList', compilationMode), + ); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef.name, 'NotReallyAList'); + expect(instance.elements, isNull); + final field = instance.fields!.first; + expect(field.decl!.name, '_internal'); + expect(inspector.isDisplayableObject(instance), isTrue); + }, + skip: true, + ); - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isFalse); - expect(inspector.isNativeJsObject(instance), isTrue); + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isFalse); + expect(inspector.isNativeJsObject(instance), isTrue); + }); }); }); }); From 9052993f992d306fe805584e3cc312ee6b5011f7 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 7 Jul 2023 16:30:49 -0700 Subject: [PATCH 07/24] cleanup and add tests --- dwds/CHANGELOG.md | 1 + dwds/lib/src/debugging/classes.dart | 39 +- dwds/lib/src/debugging/instance.dart | 53 +-- dwds/lib/src/debugging/libraries.dart | 1 - dwds/lib/src/debugging/metadata/class.dart | 5 +- dwds/lib/src/loaders/strategy.dart | 10 +- .../services/expression_compiler_service.dart | 4 +- dwds/test/instances/instance_canary_test.dart | 110 ++--- dwds/test/instances/instance_common.dart | 379 ++++++++++++++++++ .../instances/instance_inspection_common.dart | 3 +- .../instances/instance_inspection_test.dart | 9 +- dwds/test/instances/instance_test.dart | 379 +----------------- .../instances/patterns_inspection_test.dart | 3 +- .../instances/record_inspection_test.dart | 3 +- .../record_type_inspection_test.dart | 3 +- dwds/test/instances/type_inspection_test.dart | 3 +- 16 files changed, 483 insertions(+), 522 deletions(-) create mode 100644 dwds/test/instances/instance_common.dart diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 122e1a900..9cc14f43f 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -2,6 +2,7 @@ - Require clients to specify the `basePath` on `AssetReader`. - [#2160](https://github.com/dart-lang/webdev/pull/2160) - Update SDK constraint to `>=3.1.0-254.0.dev <4.0.0`. - [#2169](https://github.com/dart-lang/webdev/pull/2169) +- Switch to using new debugging API from DDC to support new type system. - []() ## 19.0.2 diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index 17b5de95d..250e3cd62 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -7,14 +7,16 @@ import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/services/chrome_debug_exception.dart'; import 'package:dwds/src/utilities/domain.dart'; import 'package:dwds/src/utilities/shared.dart'; -import 'package:logging/logging.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; +final _classMetadataForUnknown = ClassMetaData( + runtimeKind: RuntimeObjectKind.object, + classRef: classRefForUnknown, +); + /// Keeps track of Dart classes available in the running application. class ClassHelper extends Domain { - final _logger = Logger('ClassHelper'); - /// Map of class ID to [Class]. final _classes = {}; @@ -99,15 +101,10 @@ class ClassHelper extends Domain { throw ChromeDebugException(e.json, evalContents: expression); } - _logger.fine('Class info: ${result.json}'); - final classDescriptor = result.value as Map; final methodRefs = []; final methodDescriptors = classDescriptor['methods'] as Map; - //final staticMethodDescriptors = - // classDescriptor['staticMethods'] as Map; - //methodDescriptors.addAll(staticMethodDescriptors); methodDescriptors.forEach((name, descriptor) { final methodId = 'methods|$classId|$name'; methodRefs.add( @@ -154,27 +151,6 @@ class ClassHelper extends Domain { ), ); }); -/* - final staticFieldDescriptors = - classDescriptor['staticFields'] as Map; - staticFieldDescriptors.forEach((name, descriptor) { - fieldRefs.add( - FieldRef( - name: name, - owner: classRef, - declaredType: InstanceRef( - identityHashCode: createId().hashCode, - id: createId(), - kind: InstanceKind.kType, - classRef: classRef, - ), - isConst: descriptor['isConst'] as bool, - isFinal: descriptor['isFinal'] as bool, - isStatic: descriptor['isStatic'] as bool, - id: createId(), - ), - ); - });*/ // TODO: Implement the rest of these // https://github.com/dart-lang/webdev/issues/176. @@ -192,8 +168,3 @@ class ClassHelper extends Domain { ); } } - -final _classMetadataForUnknown = ClassMetaData( - runtimeKind: RuntimeObjectKind.object, - classRef: classRefForUnknown, -); diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index fd9d5c54d..9a3b753d8 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -285,12 +285,7 @@ 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 = ''' - function() { - var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - return sdkUtils.getMapElements(this); - } - '''; + final expression = _jsRuntimeFunctionCall('getMapElements(this)'); final keysAndValues = await inspector.jsCallFunctionOn(map, expression, []); final keys = await inspector.loadField(keysAndValues, 'keys'); @@ -507,12 +502,7 @@ 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 = ''' - function() { - var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - return sdkUtils.getRecordFields(this); - } - '''; + final expression = _jsRuntimeFunctionCall('getRecordFields(this)'); final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = @@ -640,13 +630,7 @@ 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 = ''' - function() { - const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); - const dart = sdk.dart; - return dart.getRecordTypeFields(this); - } - '''; + final expression = _jsRuntimeFunctionCall('getRecordTypeFields(this)'); final result = await inspector.jsCallFunctionOn(record, expression, []); final fieldNameElements = @@ -670,12 +654,7 @@ class InstanceHelper extends Domain { final objectId = remoteObject.objectId; if (objectId == null) return null; - final expression = ''' - function() { - const sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - return sdkUtils.getSetElements(this); - } - '''; + final expression = _jsRuntimeFunctionCall('getSetElements(this)'); final result = await inspector.jsCallFunctionOn(remoteObject, expression, []); @@ -747,13 +726,7 @@ class InstanceHelper extends Domain { ) async { // Present the type as an instance of `core.Type` class and // hide the internal implementation. - final expression = ''' - function() { - const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); - const dart = sdk.dart; - return dart.getTypeFields(this); - } - '''; + final expression = _jsRuntimeFunctionCall('getTypeFields(this)'); final result = await inspector.jsCallFunctionOn(type, expression, []); final hashCodeObject = await inspector.loadField(result, 'hashCode'); @@ -802,12 +775,8 @@ class InstanceHelper extends Domain { // // For maps and lists it's more complicated. Treat the actual SDK versions // of these as special. - final fieldNameExpression = '''function() { - const sdk = ${globalLoadStrategy.loadModuleSnippet}("dart_sdk"); - const dart = sdk.dart; - return dart.getObjectFieldNames(this); - } - '''; + final fieldNameExpression = + _jsRuntimeFunctionCall('getObjectFieldNames(this)'); final result = await inspector.jsCallFunctionOn( remoteObject, @@ -920,3 +889,11 @@ class InstanceHelper extends Domain { } } } + +String _jsRuntimeFunctionCall(String expression) => ''' + function() { + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.$expression; + } +'''; diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index a0871503b..cd357ebf4 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -100,7 +100,6 @@ class LibraryHelper extends Domain { // TODO: Collect library and class information from debug symbols. _logger.warning('Library ${libraryRef.uri} is not loaded. ' 'This can happen for unreferenced libraries.'); - //rethrow; } final classRefs = []; if (result != null) { diff --git a/dwds/lib/src/debugging/metadata/class.dart b/dwds/lib/src/debugging/metadata/class.dart index ff18a836c..7ee6733ee 100644 --- a/dwds/lib/src/debugging/metadata/class.dart +++ b/dwds/lib/src/debugging/metadata/class.dart @@ -167,14 +167,13 @@ class ClassMetaDataHelper { returnByValue: true, ); final metadata = result.value as Map; - final jsName = metadata['dartName']; + final dartName = metadata['dartName']; - if (jsName == null) { + if (dartName == null) { return null; } final typeName = metadata['typeName']; - final dartName = metadata['dartName']; final library = metadata['libraryId']; final runtimeKind = RuntimeObjectKind.parse(metadata['runtimeKind']); final length = metadata['length']; diff --git a/dwds/lib/src/loaders/strategy.dart b/dwds/lib/src/loaders/strategy.dart index 66057023a..05c82c208 100644 --- a/dwds/lib/src/loaders/strategy.dart +++ b/dwds/lib/src/loaders/strategy.dart @@ -64,11 +64,11 @@ abstract class LoadStrategy { /// parameter should be one of these Dart-specific scheme URIs, and we set /// `library` the corresponding library. String loadLibrarySnippet(String libraryUri) => ''' - var sdk = $loadModuleSnippet('dart_sdk'); - var dart = sdk.dart; - var dart_rti = sdk.dart_rti; - var core = sdk.core; - var library = dart.getLibrary('$libraryUri'); + const sdk = $loadModuleSnippet('dart_sdk'); + const dart = sdk.dart; + const dart_rti = sdk.dart_rti; + const core = sdk.core; + const library = dart.getLibrary('$libraryUri'); if (!library) throw 'cannot find library for $libraryUri'; '''; diff --git a/dwds/lib/src/services/expression_compiler_service.dart b/dwds/lib/src/services/expression_compiler_service.dart index 34f52bf90..efd2dcde7 100644 --- a/dwds/lib/src/services/expression_compiler_service.dart +++ b/dwds/lib/src/services/expression_compiler_service.dart @@ -254,9 +254,7 @@ class ExpressionCompilerService implements ExpressionCompiler { required this.sdkConfigurationProvider, this.experiments = const [], this.canaryFeatures = false, - }) : _verbose = verbose { - print('ExpressionCompilerService: canary: $canaryFeatures'); - } + }) : _verbose = verbose; @override Future compileExpressionToJs( diff --git a/dwds/test/instances/instance_canary_test.dart b/dwds/test/instances/instance_canary_test.dart index fd73561de..1a7b37750 100644 --- a/dwds/test/instances/instance_canary_test.dart +++ b/dwds/test/instances/instance_canary_test.dart @@ -13,68 +13,69 @@ import 'package:test_common/test_sdk_configuration.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; +import 'instance_common.dart'; void main() { // Enable verbose logging for debugging. final debug = false; - _runAllTests( - canaryFeatures: true, - compilationMode: CompilationMode.frontendServer, - debug: debug, - ); + // TODO: build daemon as well + for (var compilationMode in [CompilationMode.frontendServer]) { + _runCanaryModeVerificationTests( + compilationMode: compilationMode, + debug: debug, + ); + + runTests( + compilationMode: compilationMode, + canaryFeatures: true, + debug: debug, + ); + } } -void _runAllTests({ - required bool canaryFeatures, +void _runCanaryModeVerificationTests({ required CompilationMode compilationMode, required bool debug, }) { - group('canaryFeatures: $canaryFeatures |', () { - final provider = TestSdkConfigurationProvider( - canaryFeatures: canaryFeatures, - verbose: debug, - ); + final provider = TestSdkConfigurationProvider( + canaryFeatures: true, + verbose: debug, + ); + + final project = TestProject.testScopesWithSoundNullSafety; + tearDownAll(provider.dispose); - final project = TestProject.testScopesWithSoundNullSafety; + group('$compilationMode |', () { + final context = TestContext(project, provider); + late AppInspector inspector; setUpAll(() async { setCurrentLogWriter(debug: debug); - // Cleanup project including compiled dart sdk. - await project.cleanUp(); + await context.setUp( + canaryFeatures: true, + compilationMode: compilationMode, + ); + final chromeProxyService = context.service; + inspector = chromeProxyService.inspector; }); - tearDownAll(provider.dispose); - group('$compilationMode |', () { - final context = TestContext(project, provider); - late AppInspector inspector; - - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - canaryFeatures: canaryFeatures, - compilationMode: compilationMode, - ); - final chromeProxyService = context.service; - inspector = chromeProxyService.inspector; - }); - - tearDownAll(() async { - await context.tearDown(); - }); + tearDownAll(() async { + await context.tearDown(); + }); - final url = 'org-dartlang-app:///example/scopes/main.dart'; + final url = 'org-dartlang-app:///example/scopes/main.dart'; - String libraryName(CompilationMode compilationMode) => - compilationMode == CompilationMode.frontendServer - ? "example/scopes/main.dart" - : "example/scopes/main"; + String libraryName(CompilationMode compilationMode) => + compilationMode == CompilationMode.frontendServer + ? "example/scopes/main.dart" + : "example/scopes/main"; - String libraryVariableTypeExpression( - String variable, - CompilationMode compilationMode, - ) => - ''' + String libraryVariableTypeExpression( + String variable, + CompilationMode compilationMode, + ) => + ''' (function() { var dart = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; var libraryName = '${libraryName(compilationMode)}'; @@ -84,18 +85,17 @@ void _runAllTests({ })(); '''; - group('compiler', () { - setUp(() => setCurrentLogWriter(debug: debug)); - - test('uses new type system', () async { - final remoteObject = await inspector.jsEvaluate( - libraryVariableTypeExpression( - 'libraryPublicFinal', - compilationMode, - ), - ); - expect(remoteObject.json['className'], 'dart_rti.Rti.new'); - }); + group('compiler', () { + setUp(() => setCurrentLogWriter(debug: debug)); + + test('uses new type system', () async { + final remoteObject = await inspector.jsEvaluate( + libraryVariableTypeExpression( + 'libraryPublicFinal', + compilationMode, + ), + ); + expect(remoteObject.json['className'], 'dart_rti.Rti.new'); }); }); }); diff --git a/dwds/test/instances/instance_common.dart b/dwds/test/instances/instance_common.dart new file mode 100644 index 000000000..c31b84070 --- /dev/null +++ b/dwds/test/instances/instance_common.dart @@ -0,0 +1,379 @@ +// Copyright (c) 2019, 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']) +@Timeout(Duration(minutes: 2)) + +import 'package:dwds/src/debugging/inspector.dart'; +import 'package:dwds/src/loaders/strategy.dart'; +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 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; + +import '../fixtures/context.dart'; +import '../fixtures/project.dart'; +import 'instance_inspection_common.dart'; + +void runTests({ + required CompilationMode compilationMode, + required bool canaryFeatures, + required bool debug, +}) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + canaryFeatures: canaryFeatures, + verbose: debug, + ); + final project = TestProject.testScopesWithSoundNullSafety; + final context = TestContext(project, provider); + + tearDownAll(provider.dispose); + + late AppInspector inspector; + + group('$compilationMode |', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + ); + final chromeProxyService = context.service; + inspector = chromeProxyService.inspector; + }); + + tearDownAll(() async { + await context.tearDown(); + }); + + final url = 'org-dartlang-app:///example/scopes/main.dart'; + + String libraryName(CompilationMode compilationMode) => + compilationMode == CompilationMode.frontendServer + ? "example/scopes/main.dart" + : "example/scopes/main"; + + String libraryVariableExpression( + String variable, + CompilationMode compilationMode, + ) => + '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.' + 'getModuleLibraries("${libraryName(compilationMode)}")' + '["$url"]["$variable"];'; + + String newInterceptorsExpression(String type) => + 'new (require("dart_sdk")._interceptors.$type).new()'; + + final String newDartError = 'new (require("dart_sdk").dart).DartError'; + + /// A reference to the the variable `libraryPublicFinal`, an instance of + /// `MyTestClass`. + Future libraryPublicFinal( + CompilationMode compilationMode) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublicFinal', compilationMode), + ); + + /// A reference to the the variable `libraryPublic`, a List of Strings. + Future libraryPublic(CompilationMode compilationMode) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublic', compilationMode), + ); + + group('instanceRef', () { + setUp(() => setCurrentLogWriter(debug: debug)); + + test('for a null', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final nullVariable = + await inspector.loadField(remoteObject, 'notFinal'); + final ref = await inspector.instanceRefFor(nullVariable); + expect(ref!.valueAsString, 'null'); + expect(ref.kind, InstanceKind.kNull); + final classRef = ref.classRef!; + expect(classRef.name, 'Null'); + expect(classRef.id, 'classes|dart:core|Null'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a double', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'count'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.valueAsString, '0'); + expect(ref.kind, InstanceKind.kDouble); + final classRef = ref.classRef!; + expect(classRef.name, 'Double'); + expect(classRef.id, 'classes|dart:core|Double'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a class', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'myselfField'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.kind, InstanceKind.kPlainInstance); + final classRef = ref.classRef!; + expect(classRef.name, 'MyTestClass'); + expect( + classRef.id, + 'classes|org-dartlang-app:///example/scopes/main.dart' + '|MyTestClass'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final ref = await inspector.instanceRefFor(closure.value!); + final functionName = ref!.closureFunction!.name; + // Older SDKs do not contain function names + if (functionName != 'Closure') { + expect(functionName, 'someFunction'); + } + expect(ref.kind, InstanceKind.kClosure); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a list', () async { + final remoteObject = await libraryPublic(compilationMode); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, greaterThan(0)); + expect(ref.kind, InstanceKind.kList); + expect(ref.classRef!.name, matchListClassName('String')); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for map', () async { + final remoteObject = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'LinkedMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for an IdentityMap', () async { + final remoteObject = await inspector.jsEvaluate( + libraryVariableExpression('identityMap', compilationMode), + ); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'IdentityMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isFalse); + expect(inspector.isNativeJsObject(ref), isTrue); + }); + }); + + group('instance', () { + setUp(() => setCurrentLogWriter(debug: debug)); + test('for class object', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + final boundFieldNames = instance.fields! + .map((boundField) => boundField.decl!.name) + .toList(); + expect(boundFieldNames, [ + '_privateField', + 'abstractField', + 'closure', + 'count', + 'message', + 'myselfField', + 'notFinal', + 'tornOff', + ]); + final fieldNames = + instance.fields!.map((boundField) => boundField.name).toList(); + expect(boundFieldNames, fieldNames); + for (var field in instance.fields!) { + expect(field.name, isNotNull); + expect(field.decl!.declaredType, isNotNull); + } + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final instance = await inspector.instanceFor(closure.value!); + expect(instance!.kind, InstanceKind.kClosure); + expect(instance.classRef!.name, 'Closure'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for a nested class', () async { + final libraryRemoteObject = await libraryPublicFinal(compilationMode); + final fieldRemoteObject = + await inspector.loadField(libraryRemoteObject, 'myselfField'); + final instance = await inspector.instanceFor(fieldRemoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for a list', () async { + final remote = await libraryPublic(compilationMode); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kList); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, matchListClassName('String')); + final first = instance.elements![0]; + expect(first.valueAsString, 'library'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for a map', () async { + final remote = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; + expect(classRef.name, 'LinkedMap'); + final first = instance.associations![0].value as InstanceRef; + expect(first.kind, InstanceKind.kList); + expect(first.length, 3); + final second = instance.associations![1].value as InstanceRef; + expect(second.kind, InstanceKind.kString); + expect(second.valueAsString, 'something'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for an identityMap', () async { + final remote = await inspector.jsEvaluate( + libraryVariableExpression('identityMap', compilationMode), + ); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; + expect(classRef.name, 'IdentityMap'); + final first = instance.associations![0].value; + expect(first.valueAsString, '1'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test( + 'for a class that implements List', + () async { + // The VM only uses kind List for SDK lists, and we follow that. + final remote = await inspector.jsEvaluate( + libraryVariableExpression('notAList', compilationMode), + ); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef.name, 'NotReallyAList'); + expect(instance.elements, isNull); + final field = instance.fields!.first; + expect(field.decl!.name, '_internal'); + expect(inspector.isDisplayableObject(instance), isTrue); + }, + skip: true, + ); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); + }); + + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isFalse); + expect(inspector.isNativeJsObject(instance), isTrue); + }); + }); + }); + }); +} diff --git a/dwds/test/instances/instance_inspection_common.dart b/dwds/test/instances/instance_inspection_common.dart index 812fa6d55..c1f9cbcd9 100644 --- a/dwds/test/instances/instance_inspection_common.dart +++ b/dwds/test/instances/instance_inspection_common.dart @@ -150,9 +150,8 @@ class TestInspector { }; final instances = {}; for (final p in refs.entries) { - final instance = + instances[p.key] = await service.getObject(isolateId, p.value.id!) as Instance; - instances[p.key] = instance; } return instances; } diff --git a/dwds/test/instances/instance_inspection_test.dart b/dwds/test/instances/instance_inspection_test.dart index 57aaa1325..85e6b293b 100644 --- a/dwds/test/instances/instance_inspection_test.dart +++ b/dwds/test/instances/instance_inspection_test.dart @@ -19,6 +19,7 @@ void main() { // Enable verbose logging for debugging. final debug = false; + // TODO: split out canary tests for (var canaryFeatures in [false, true]) { _runAllTests(canaryFeatures, debug); } @@ -32,7 +33,8 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - for (var compilationMode in CompilationMode.values) { + // TODO: build daemon also + for (var compilationMode in [CompilationMode.frontendServer]) { for (var nullSafetyMode in NullSafety.values) { _runTests( provider: provider, @@ -53,10 +55,11 @@ void _runTests({ required bool canaryFeatures, required bool debug, }) { - final testPackage = nullSafetyMode == NullSafety.sound + final testProject = nullSafetyMode == NullSafety.sound ? TestProject.testPackageWithSoundNullSafety() : TestProject.testPackageWithWeakNullSafety(); - final context = TestContext(testPackage, provider); + final context = TestContext(testProject, provider); + late VmServiceInterface service; late Stream stream; late String isolateId; diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index 73a7fb58b..cfcb45443 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -5,389 +5,20 @@ @Tags(['daily']) @Timeout(Duration(minutes: 2)) -import 'package:dwds/src/debugging/inspector.dart'; -import 'package:dwds/src/loaders/strategy.dart'; 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 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import '../fixtures/context.dart'; -import '../fixtures/project.dart'; -import 'instance_inspection_common.dart'; +import 'instance_common.dart'; -void main() async { +void main() { // Enable verbose logging for debugging. final debug = false; - for (var compilationMode in [CompilationMode.frontendServer]) { - await _runTests( + for (var compilationMode in CompilationMode.values) { + runTests( compilationMode: compilationMode, - canaryFeatures: true, + canaryFeatures: false, debug: debug, ); } } - -Future _runTests({ - required CompilationMode compilationMode, - required bool canaryFeatures, - required bool debug, -}) async { - group('canaryFeatures: $canaryFeatures |', () { - final provider = TestSdkConfigurationProvider( - canaryFeatures: true, - verbose: debug, - ); - final project = TestProject.testScopesWithSoundNullSafety; - final context = TestContext(project, provider); - - setUpAll(project.cleanUp); - tearDownAll(provider.dispose); - - late AppInspector inspector; - - group('$compilationMode |', () { - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - compilationMode: compilationMode, - canaryFeatures: canaryFeatures, - ); - final chromeProxyService = context.service; - inspector = chromeProxyService.inspector; - }); - - tearDownAll(() async { - await context.tearDown(); - }); - - final url = 'org-dartlang-app:///example/scopes/main.dart'; - - String libraryName(CompilationMode compilationMode) => - compilationMode == CompilationMode.frontendServer - ? "example/scopes/main.dart" - : "example/scopes/main"; - - String libraryVariableExpression( - String variable, - CompilationMode compilationMode, - ) => - '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.' - 'getModuleLibraries("${libraryName(compilationMode)}")' - '["$url"]["$variable"];'; - - String newInterceptorsExpression(String type) => - 'new (require("dart_sdk")._interceptors.$type).new()'; - - final String newDartError = 'new (require("dart_sdk").dart).DartError'; - - /// A reference to the the variable `libraryPublicFinal`, an instance of - /// `MyTestClass`. - Future libraryPublicFinal( - CompilationMode compilationMode) => - inspector.jsEvaluate( - libraryVariableExpression('libraryPublicFinal', compilationMode), - ); - - /// A reference to the the variable `libraryPublic`, a List of Strings. - Future libraryPublic(CompilationMode compilationMode) => - inspector.jsEvaluate( - libraryVariableExpression('libraryPublic', compilationMode), - ); - - group('instanceRef', () { - setUp(() => setCurrentLogWriter(debug: debug)); - - test('for a null', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final nullVariable = - await inspector.loadField(remoteObject, 'notFinal'); - final ref = await inspector.instanceRefFor(nullVariable); - expect(ref!.valueAsString, 'null'); - expect(ref.kind, InstanceKind.kNull); - final classRef = ref.classRef!; - expect(classRef.name, 'Null'); - expect(classRef.id, 'classes|dart:core|Null'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a double', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final count = await inspector.loadField(remoteObject, 'count'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.valueAsString, '0'); - expect(ref.kind, InstanceKind.kDouble); - final classRef = ref.classRef!; - expect(classRef.name, 'Double'); - expect(classRef.id, 'classes|dart:core|Double'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a class', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final count = await inspector.loadField(remoteObject, 'myselfField'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.kind, InstanceKind.kPlainInstance); - final classRef = ref.classRef!; - expect(classRef.name, 'MyTestClass'); - expect( - classRef.id, - 'classes|org-dartlang-app:///example/scopes/main.dart' - '|MyTestClass'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for closure', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final properties = - await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final ref = await inspector.instanceRefFor(closure.value!); - final functionName = ref!.closureFunction!.name; - // Older SDKs do not contain function names - if (functionName != 'Closure') { - expect(functionName, 'someFunction'); - } - expect(ref.kind, InstanceKind.kClosure); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a list', () async { - final remoteObject = await libraryPublic(compilationMode); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, greaterThan(0)); - expect(ref.kind, InstanceKind.kList); - expect(ref.classRef!.name, matchListClassName('String')); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for map', () async { - final remoteObject = await inspector - .jsEvaluate(libraryVariableExpression('map', compilationMode)); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'LinkedMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for an IdentityMap', () async { - final remoteObject = await inspector.jsEvaluate( - libraryVariableExpression('identityMap', compilationMode), - ); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'IdentityMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('NativeError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isFalse); - expect(inspector.isNativeJsObject(ref), isTrue); - }); - }); - - group('instance', () { - setUp(() => setCurrentLogWriter(debug: debug)); - test('for class object', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - final boundFieldNames = instance.fields! - .map((boundField) => boundField.decl!.name) - .toList(); - expect(boundFieldNames, [ - '_privateField', - 'abstractField', - 'closure', - 'count', - 'message', - 'myselfField', - 'notFinal', - 'tornOff', - ]); - final fieldNames = - instance.fields!.map((boundField) => boundField.name).toList(); - expect(boundFieldNames, fieldNames); - for (var field in instance.fields!) { - expect(field.name, isNotNull); - expect(field.decl!.declaredType, isNotNull); - } - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for closure', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final properties = - await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final instance = await inspector.instanceFor(closure.value!); - expect(instance!.kind, InstanceKind.kClosure); - expect(instance.classRef!.name, 'Closure'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a nested class', () async { - final libraryRemoteObject = await libraryPublicFinal(compilationMode); - final fieldRemoteObject = - await inspector.loadField(libraryRemoteObject, 'myselfField'); - final instance = await inspector.instanceFor(fieldRemoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a list', () async { - final remote = await libraryPublic(compilationMode); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kList); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, matchListClassName('String')); - final first = instance.elements![0]; - expect(first.valueAsString, 'library'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a map', () async { - final remote = await inspector - .jsEvaluate(libraryVariableExpression('map', compilationMode)); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'LinkedMap'); - final first = instance.associations![0].value as InstanceRef; - expect(first.kind, InstanceKind.kList); - expect(first.length, 3); - final second = instance.associations![1].value as InstanceRef; - expect(second.kind, InstanceKind.kString); - expect(second.valueAsString, 'something'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for an identityMap', () async { - final remote = await inspector.jsEvaluate( - libraryVariableExpression('identityMap', compilationMode), - ); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'IdentityMap'); - final first = instance.associations![0].value; - expect(first.valueAsString, '1'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test( - 'for a class that implements List', - () async { - // The VM only uses kind List for SDK lists, and we follow that. - final remote = await inspector.jsEvaluate( - libraryVariableExpression('notAList', compilationMode), - ); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef.name, 'NotReallyAList'); - expect(instance.elements, isNull); - final field = instance.fields!.first; - expect(field.decl!.name, '_internal'); - expect(inspector.isDisplayableObject(instance), isTrue); - }, - skip: true, - ); - - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('NativeError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isFalse); - expect(inspector.isNativeJsObject(instance), isTrue); - }); - }); - }); - }); -} diff --git a/dwds/test/instances/patterns_inspection_test.dart b/dwds/test/instances/patterns_inspection_test.dart index 29692aa24..dea466f3e 100644 --- a/dwds/test/instances/patterns_inspection_test.dart +++ b/dwds/test/instances/patterns_inspection_test.dart @@ -32,7 +32,8 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - for (var compilationMode in CompilationMode.values) { + // TODO: build daemon also + for (var compilationMode in [CompilationMode.frontendServer]) { _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/record_inspection_test.dart b/dwds/test/instances/record_inspection_test.dart index 7d8321c91..589da1dd6 100644 --- a/dwds/test/instances/record_inspection_test.dart +++ b/dwds/test/instances/record_inspection_test.dart @@ -32,7 +32,8 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - for (var compilationMode in CompilationMode.values) { + // TODO: build daemon also + for (var compilationMode in [CompilationMode.frontendServer]) { _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/record_type_inspection_test.dart b/dwds/test/instances/record_type_inspection_test.dart index 081fa5907..3330468eb 100644 --- a/dwds/test/instances/record_type_inspection_test.dart +++ b/dwds/test/instances/record_type_inspection_test.dart @@ -32,7 +32,8 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - for (var compilationMode in CompilationMode.values) { + // TODO: build daemon also + for (var compilationMode in [CompilationMode.frontendServer]) { _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/type_inspection_test.dart b/dwds/test/instances/type_inspection_test.dart index ac146302f..00b19594f 100644 --- a/dwds/test/instances/type_inspection_test.dart +++ b/dwds/test/instances/type_inspection_test.dart @@ -32,7 +32,8 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - for (var compilationMode in CompilationMode.values) { + // TODO: build daemon also + for (var compilationMode in [CompilationMode.frontendServer]) { _runTests( provider: provider, compilationMode: compilationMode, From 19bf1bca4f2afecb9885c1ee7c20a29ca81e7695 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 10 Jul 2023 09:44:24 -0700 Subject: [PATCH 08/24] Updated issue reference --- dwds/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index 213bd705f..338e0a89e 100644 --- a/dwds/CHANGELOG.md +++ b/dwds/CHANGELOG.md @@ -3,7 +3,7 @@ - Require clients to specify the `basePath` on `AssetReader`. - [#2160](https://github.com/dart-lang/webdev/pull/2160) - Update SDK constraint to `>=3.1.0-254.0.dev <4.0.0`. - [#2169](https://github.com/dart-lang/webdev/pull/2169) - Require min `build_web_compilers` version `4.0.4` - [#2171](https://github.com/dart-lang/webdev/pull/2171) -- Switch to using new debugging API from DDC to support new type system. - []() +- Switch to using new debugging API from DDC to support new type system. - [#2159](https://github.com/dart-lang/webdev/pull/2159) ## 19.0.2 From 5d0c20149ebe36d22705a9016e58cf3de0b92660 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 10 Jul 2023 10:13:03 -0700 Subject: [PATCH 09/24] Remove unused API --- dwds/lib/src/debugging/inspector.dart | 17 ++--------------- dwds/lib/src/loaders/legacy.dart | 7 ------- dwds/lib/src/loaders/require.dart | 4 ---- dwds/lib/src/loaders/strategy.dart | 4 ---- dwds/test/fixtures/fakes.dart | 3 --- 5 files changed, 2 insertions(+), 33 deletions(-) diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 9f3a26b60..762e1a614 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -601,15 +601,6 @@ class AppInspector implements AppInspectorInterface { .toList(); } - /// Compute the last possible element index in the range of [offset]..end - /// that includes [count] elements, if available. - static int? _calculateRangeEnd({ - int? count, - required int offset, - required int length, - }) => - count == null ? null : math.min(offset + count, length); - /// Calculate the number of available elements in the range. static int _calculateRangeCount({ int? count, @@ -634,14 +625,10 @@ class AppInspector implements AppInspectorInterface { // TODO(#809): Sometimes we already know the type of the object, and // we could take advantage of that to short-circuit. final receiver = remoteObjectFor(id); - //final end = - // _calculateRangeEnd(count: count, offset: offset, length: length); final rangeCount = _calculateRangeCount(count: count, offset: offset, length: length); - final args = [offset, rangeCount /*, end*/] - .map(dartIdFor) - .map(remoteObjectFor) - .toList(); + final args = + [offset, rangeCount].map(dartIdFor).map(remoteObjectFor).toList(); // If this is a List, just call sublist. If it's a Map, get the entries, but // avoid doing a toList on a large map using skip/take to get the section we // want. To make those alternatives easier in JS, pass both count and end. diff --git a/dwds/lib/src/loaders/legacy.dart b/dwds/lib/src/loaders/legacy.dart index ec14560ab..f2cb18970 100644 --- a/dwds/lib/src/loaders/legacy.dart +++ b/dwds/lib/src/loaders/legacy.dart @@ -91,13 +91,6 @@ class LegacyStrategy extends LoadStrategy { @override String get loadLibrariesModule => 'dart_library.ddk.js'; - @override - String get loadLibrariesSnippet => - 'for(let module of dart_library.libraries()) {\n' - 'dart_library.import(module)[module];\n' - '}\n' - 'let libs = $loadModuleSnippet("dart_sdk").dart.getLibraries();\n'; - @override String get loadModuleSnippet => 'dart_library.import'; diff --git a/dwds/lib/src/loaders/require.dart b/dwds/lib/src/loaders/require.dart index 5d9d8f78b..5298bd0e4 100644 --- a/dwds/lib/src/loaders/require.dart +++ b/dwds/lib/src/loaders/require.dart @@ -161,10 +161,6 @@ class RequireStrategy extends LoadStrategy { @override String get loadLibrariesModule => 'require.js'; - @override - String get loadLibrariesSnippet => - 'let libs = $loadModuleSnippet("dart_sdk").dart.getLibraries();\n'; - @override String get loadModuleSnippet => 'require'; diff --git a/dwds/lib/src/loaders/strategy.dart b/dwds/lib/src/loaders/strategy.dart index 05c82c208..763472b43 100644 --- a/dwds/lib/src/loaders/strategy.dart +++ b/dwds/lib/src/loaders/strategy.dart @@ -35,10 +35,6 @@ abstract class LoadStrategy { /// Used for preventing stepping into the library loading code. String get loadLibrariesModule; - /// Returns a snippet of JS code that loads all Dart libraries into a `libs` - /// variable. - String get loadLibrariesSnippet; - /// Returns a snippet of JS code that can be used to load a JS module. /// /// The snippet should be a reference to a function that takes a single diff --git a/dwds/test/fixtures/fakes.dart b/dwds/test/fixtures/fakes.dart index 5274a06af..7b8544d77 100644 --- a/dwds/test/fixtures/fakes.dart +++ b/dwds/test/fixtures/fakes.dart @@ -330,9 +330,6 @@ class FakeStrategy implements LoadStrategy { @override String get loadLibrariesModule => ''; - @override - String get loadLibrariesSnippet => ''; - @override String loadLibrarySnippet(String libraryUri) => ''; From c90127c500990569a0843dfebc04ed0a855a0e81 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 14 Jul 2023 11:57:28 -0700 Subject: [PATCH 10/24] Try making it work with current sdk changes --- dwds/lib/src/debugging/classes.dart | 49 ++++--- dwds/lib/src/debugging/debugger.dart | 4 + dwds/lib/src/debugging/inspector.dart | 22 ++- dwds/lib/src/debugging/instance.dart | 7 + dwds/lib/src/debugging/libraries.dart | 7 +- dwds/lib/src/debugging/metadata/class.dart | 6 +- dwds/lib/src/debugging/runtime.dart | 132 ++++++++++++++++++ dwds/lib/src/loaders/strategy.dart | 20 --- dwds/lib/src/utilities/domain.dart | 4 + dwds/lib/src/utilities/objects.dart | 2 +- dwds/test/chrome_proxy_service_test.dart | 80 +++++++---- dwds/test/fixtures/context.dart | 6 - dwds/test/fixtures/fakes.dart | 3 - dwds/test/instances/instance_canary_test.dart | 2 +- dwds/test/instances/instance_common.dart | 27 +--- .../instances/instance_inspection_test.dart | 3 +- dwds/test/instances/instance_test.dart | 2 +- .../instances/patterns_inspection_test.dart | 3 +- .../instances/record_inspection_test.dart | 3 +- .../record_type_inspection_test.dart | 3 +- dwds/test/instances/type_inspection_test.dart | 3 +- fixtures/_webdevSoundSmoke/build.yaml | 14 +- fixtures/_webdevSoundSmoke/web/main.dart | 18 ++- webdev/lib/src/serve/webdev_server.dart | 1 - 24 files changed, 280 insertions(+), 141 deletions(-) create mode 100644 dwds/lib/src/debugging/runtime.dart diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index 250e3cd62..a00e55d74 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -7,16 +7,14 @@ import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/services/chrome_debug_exception.dart'; import 'package:dwds/src/utilities/domain.dart'; import 'package:dwds/src/utilities/shared.dart'; +import 'package:logging/logging.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; -final _classMetadataForUnknown = ClassMetaData( - runtimeKind: RuntimeObjectKind.object, - classRef: classRefForUnknown, -); - /// Keeps track of Dart classes available in the running application. class ClassHelper extends Domain { + final _logger = Logger('ClassHelper'); + /// Map of class ID to [Class]. final _classes = {}; @@ -81,6 +79,7 @@ class ClassHelper extends Domain { final classId = classRef.id; if (libraryUri == null || classId == null || className == null) return null; + _logger.severe('Constructing class: $className, library: $libraryUri'); final expression = ''' (function() { @@ -102,6 +101,7 @@ class ClassHelper extends Domain { } final classDescriptor = result.value as Map; + _logger.severe('Class descriptor for $className: $classDescriptor'); final methodRefs = []; final methodDescriptors = classDescriptor['methods'] as Map; @@ -112,27 +112,23 @@ class ClassHelper extends Domain { id: methodId, name: name, owner: classRef, - isConst: descriptor['isConst'] as bool, - isStatic: descriptor['isStatic'] as bool, - // TODO(annagrin): get information about getters and setters from symbols. - // https://github.com/dart-lang/sdk/issues/46723 - implicit: false, + isConst: descriptor['isConst'] as bool? ?? false, + isStatic: descriptor['isStatic'] as bool? ?? false, + implicit: descriptor['isImplicit'] as bool? ?? false, ), ); }); final fieldRefs = []; + final fieldDescriptors = classDescriptor['fields'] as Map; fieldDescriptors.forEach((name, descriptor) { - final classMetaData = descriptor.containsKey('classRefLibraryId') && - descriptor.containsKey('classRefDartName') - ? ClassMetaData( - runtimeKind: RuntimeObjectKind.type, - classRef: classRefFor( - descriptor['classRefLibraryId'], - descriptor['classRefDartName'], - ), - ) - : _classMetadataForUnknown; + final classMetaData = ClassMetaData( + runtimeKind: RuntimeObjectKind.type, + classRef: classRefFor( + descriptor['classLibraryId'], + descriptor['className'], + ), + ); fieldRefs.add( FieldRef( @@ -144,14 +140,20 @@ class ClassHelper extends Domain { kind: classMetaData.kind, classRef: classMetaData.classRef, ), - isConst: descriptor['isConst'] as bool, - isFinal: descriptor['isFinal'] as bool, - isStatic: descriptor['isStatic'] as bool, + isConst: descriptor['isConst'] as bool? ?? false, + isFinal: descriptor['isFinal'] as bool? ?? false, + isStatic: descriptor['isStatic'] as bool? ?? false, id: createId(), ), ); }); + final superClassLibraryId = classDescriptor['superClassLibraryId']; + final superClassName = classDescriptor['superClassName']; + final superClassRef = superClassName == null + ? null + : classRefFor(superClassLibraryId, superClassName); + // TODO: Implement the rest of these // https://github.com/dart-lang/webdev/issues/176. return Class( @@ -165,6 +167,7 @@ class ClassHelper extends Domain { subclasses: [], id: classId, traceAllocations: false, + superClass: superClassRef, ); } } diff --git a/dwds/lib/src/debugging/debugger.dart b/dwds/lib/src/debugging/debugger.dart index 27e4c1b54..55b9ff6b3 100644 --- a/dwds/lib/src/debugging/debugger.dart +++ b/dwds/lib/src/debugging/debugger.dart @@ -712,6 +712,10 @@ Future sendCommandAndValidateResult( }) async { final response = await remoteDebugger.sendCommand(method, params: params); final result = response.result?[resultField]; + final internalProperties = response.result?['internalProperties']; + if (internalProperties != null) { + Logger.root.severe('Properties: $result'); + } if (result == null) { throw RPCError( method, diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index 762e1a614..e107f8ade 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -349,11 +349,14 @@ class AppInspector implements AppInspectorInterface { throwInvalidParam('invoke', 'library uri is null'); } final findLibrary = ''' -(function() { - ${globalLoadStrategy.loadLibrarySnippet(libraryUri)}; - return library; -})(); -'''; + (function() { + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + const library = dart.getLibrary('$libraryUri'); + if (!library) throw 'cannot find library for $libraryUri'; + return library; + })(); + '''; final remoteLibrary = await jsEvaluate(findLibrary); return jsCallFunctionOn(remoteLibrary, jsFunction, arguments); } @@ -570,6 +573,10 @@ class AppInspector implements AppInspectorInterface { int? offset, int? count, int? length, + bool ownProperties = false, + bool accessorPropertiesOnly = false, + bool generatePreview = true, + bool nonIndexedPropertiesOnly = false, }) async { String rangeId = objectId; // Ignore offset/count if there is no length: @@ -593,7 +600,10 @@ class AppInspector implements AppInspectorInterface { resultField: 'result', params: { 'objectId': rangeId, - 'ownProperties': true, + 'ownProperties': ownProperties, + 'accessorPropertiesOnly': accessorPropertiesOnly, + 'generatePreview': generatePreview, + 'nonIndexedPropertiesOnly': nonIndexedPropertiesOnly, }, ); return jsProperties diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index 9a3b753d8..d4d3a7b1d 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -242,6 +242,10 @@ class InstanceHelper extends Domain { offset: offset, count: count, length: metaData.length, + ownProperties: false, + accessorPropertiesOnly: false, + generatePreview: true, + nonIndexedPropertiesOnly: true, ); final dartProperties = await _dartFieldsFor(properties, remoteObject); var boundFields = await Future.wait( @@ -786,6 +790,9 @@ class InstanceHelper extends Domain { ); final names = List.from(result.value as List); + _logger.severe('Fieldnames: $names'); + _logger.severe('Properties: $allJsProperties'); + // TODO(#761): Better support for large collections. return allJsProperties .where((property) => names.contains(property.name)) diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index cd357ebf4..6a6b1d6c7 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -4,6 +4,7 @@ import 'package:collection/collection.dart'; import 'package:dwds/src/debugging/metadata/class.dart'; +import 'package:dwds/src/debugging/runtime.dart'; import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/services/chrome_debug_exception.dart'; import 'package:dwds/src/utilities/domain.dart'; @@ -90,6 +91,10 @@ class LibraryHelper extends Domain { })() '''; + //final runtime = DebuggerRuntime(inspector); + //final result = await runtime.getLibraryMetadata(libraryUri); + //print('Library metadata: $result'); + RemoteObject? result; try { result = await inspector.jsEvaluate(expression, returnByValue: true); @@ -103,7 +108,7 @@ class LibraryHelper extends Domain { } final classRefs = []; if (result != null) { - final classNames = result.value as List; + final classNames = result.value as List; for (final className in classNames) { final classMetaData = ClassMetaData( diff --git a/dwds/lib/src/debugging/metadata/class.dart b/dwds/lib/src/debugging/metadata/class.dart index 7ee6733ee..ed92e0648 100644 --- a/dwds/lib/src/debugging/metadata/class.dart +++ b/dwds/lib/src/debugging/metadata/class.dart @@ -167,9 +167,9 @@ class ClassMetaDataHelper { returnByValue: true, ); final metadata = result.value as Map; - final dartName = metadata['dartName']; + final className = metadata['className']; - if (dartName == null) { + if (className == null) { return null; } @@ -178,7 +178,7 @@ class ClassMetaDataHelper { final runtimeKind = RuntimeObjectKind.parse(metadata['runtimeKind']); final length = metadata['length']; - final classRef = classRefFor(library, dartName); + final classRef = classRefFor(library, className); _addRuntimeObjectKind(classRef, runtimeKind); return ClassMetaData( diff --git a/dwds/lib/src/debugging/runtime.dart b/dwds/lib/src/debugging/runtime.dart new file mode 100644 index 000000000..c31b290d9 --- /dev/null +++ b/dwds/lib/src/debugging/runtime.dart @@ -0,0 +1,132 @@ +// 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. + +import 'package:dwds/src/loaders/strategy.dart'; +import 'package:dwds/src/services/chrome_debug_exception.dart'; +import 'package:dwds/src/utilities/domain.dart'; +import 'package:logging/logging.dart'; +import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; + +class DebuggerRuntime { + final _logger = Logger('DebuggerRuntime'); + final AppInspectorInterface _inspector; + + DebuggerRuntime(this._inspector); + + static String _jsRuntimeCall( + String call, { + List params = const [], + }) => + ''' + function(${params.join(', ')}) { + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.$call; + } + '''; + + Future getLibraryMetadata(String libraryUri) async { + final call = _jsRuntimeCall('getLibraryMetadata("$libraryUri")'); + print('Runtime call: $call'); + RemoteObject? result; + try { + result = await _inspector.jsEvaluate(call, returnByValue: true); + } on ChromeDebugException catch (_) { + // Unreferenced libraries are not loaded at runtime, + // return empty library object for consistency among + // VM Service implementations. + // TODO: Collect library and class information from debug symbols. + _logger.warning('Library $libraryUri is not loaded. ' + 'This can happen for unreferenced libraries.'); + } + return result; + } + + Future getClassMetadata( + String libraryUri, + String className, + ) async { + final call = _jsRuntimeCall( + "getClassMetadata('$libraryUri', '$className')", + ); + return _inspector.jsEvaluate(call, returnByValue: true); + + // TODO: can we use _inspector.jsEvaluate? + /* RemoteObject result; + try { + result = await _inspector.remoteDebugger.evaluate( + call, + returnByValue: true, + contextId: await _inspector.contextId, + ); + } on ExceptionDetails catch (e) { + throw ChromeDebugException(e.json, evalContents: call); + } + return result;*/ + } + + Future getFunctionName(RemoteObject object) { + final call = _jsRuntimeCall("getFunctionName(this)"); + return _inspector.jsCallFunctionOn(object, call, [], returnByValue: true); + } + + Future getObjectMetadata(RemoteObject object) { + final call = _jsRuntimeCall("getObjectMetadata(this)"); + return _inspector.jsCallFunctionOn(object, call, [], returnByValue: true); + } + + Future getLibrary(String libraryUri) { + final call = _jsRuntimeCall("getLibrary('$libraryUri')"); + return _inspector.jsEvaluate(call); + } + + Future getMapElements(RemoteObject map) { + final call = _jsRuntimeCall("getMapElements(this)"); + return _inspector.jsCallFunctionOn(map, call, []); + } + + Future getSetElements(RemoteObject set) { + final call = _jsRuntimeCall("getSetElements(this)"); + return _inspector.jsCallFunctionOn(set, call, []); + } + + Future getRecordFields( + RemoteObject record, + ) { + final call = _jsRuntimeCall("getRecordFields(this)"); + return _inspector.jsCallFunctionOn(record, call, []); + } + + Future getTypeFields(RemoteObject type) { + final call = _jsRuntimeCall("getTypeFields(this)"); + return _inspector.jsCallFunctionOn(type, call, []); + } + + Future getRecordTypeFields(RemoteObject recordType) { + final call = _jsRuntimeCall("getRecordTypeFields(this)"); + return _inspector.jsCallFunctionOn(recordType, call, []); + } + + Future getObjectFieldNames(RemoteObject object) { + final call = _jsRuntimeCall("getObjectFieldNames(this)"); + return _inspector.jsCallFunctionOn(object, call, [], returnByValue: true); + } + + Future loadField(RemoteObject receiver, String fieldName) { + final call = _jsRuntimeCall("dloadRepl(this, '$fieldName')"); + return _inspector.jsCallFunctionOn(receiver, call, []); + } + + Future subRange( + RemoteObject object, + RemoteObject offset, + RemoteObject count, + ) { + final call = _jsRuntimeCall( + 'getSubRange(this, offset, count)', + params: ['offset', 'count'], + ); + return _inspector.jsCallFunctionOn(object, call, [offset, count]); + } +} diff --git a/dwds/lib/src/loaders/strategy.dart b/dwds/lib/src/loaders/strategy.dart index 763472b43..73801a7a0 100644 --- a/dwds/lib/src/loaders/strategy.dart +++ b/dwds/lib/src/loaders/strategy.dart @@ -48,26 +48,6 @@ abstract class LoadStrategy { /// should be a package URI, e.g. `package:myapp/main.dart`. Uri? get appEntrypoint; - /// Returns a snippet of JS code that initializes a `library` variable that - /// has the actual library object in DDC for [libraryUri]. - /// - /// In DDC we have module libraries indexed by names of the form - /// 'packages/package/mainFile' with no .dart suffix on the file, or - /// 'directory/packageName/mainFile', also with no .dart suffix, and relative - /// to the serving root, normally /web within the package. These modules have - /// a map from the URI with a Dart-specific scheme - /// (package: or org-dartlang-app:) to the library objects. The [libraryUri] - /// parameter should be one of these Dart-specific scheme URIs, and we set - /// `library` the corresponding library. - String loadLibrarySnippet(String libraryUri) => ''' - const sdk = $loadModuleSnippet('dart_sdk'); - const dart = sdk.dart; - const dart_rti = sdk.dart_rti; - const core = sdk.core; - const library = dart.getLibrary('$libraryUri'); - if (!library) throw 'cannot find library for $libraryUri'; - '''; - /// Returns the bootstrap required for this [LoadStrategy]. /// /// The bootstrap is appended to the end of the entry point module. diff --git a/dwds/lib/src/utilities/domain.dart b/dwds/lib/src/utilities/domain.dart index bfb19204e..c3d5ca379 100644 --- a/dwds/lib/src/utilities/domain.dart +++ b/dwds/lib/src/utilities/domain.dart @@ -103,6 +103,10 @@ abstract class AppInspectorInterface { int? offset, int? count, int? length, + bool ownProperties = true, + bool accessorPropertiesOnly = false, + bool generatePreview = false, + bool nonIndexedPropertiesOnly = false, }); bool isDisplayableObject(Object? object); diff --git a/dwds/lib/src/utilities/objects.dart b/dwds/lib/src/utilities/objects.dart index 4b3444e91..05aedd52c 100644 --- a/dwds/lib/src/utilities/objects.dart +++ b/dwds/lib/src/utilities/objects.dart @@ -63,5 +63,5 @@ class Property { } @override - String toString() => '$name $value'; + String toString() => '$name: $value'; } diff --git a/dwds/test/chrome_proxy_service_test.dart b/dwds/test/chrome_proxy_service_test.dart index 988a5977e..abdde3a26 100644 --- a/dwds/test/chrome_proxy_service_test.dart +++ b/dwds/test/chrome_proxy_service_test.dart @@ -39,6 +39,7 @@ void main() { await context.setUp( enableExpressionEvaluation: true, verboseCompiler: false, + canaryFeatures: false, ); }); @@ -598,16 +599,7 @@ void main() { testClass.functions, unorderedEquals([ predicate((FuncRef f) => f.name == 'staticHello' && f.isStatic!), - predicate((FuncRef f) => f.name == 'message' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'notFinal' && !f.isStatic!), predicate((FuncRef f) => f.name == 'hello' && !f.isStatic!), - predicate((FuncRef f) => f.name == '_equals' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'hashCode' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'toString' && !f.isStatic!), - predicate( - (FuncRef f) => f.name == 'noSuchMethod' && !f.isStatic!, - ), - predicate((FuncRef f) => f.name == 'runtimeType' && !f.isStatic!), ]), ); expect( @@ -637,6 +629,22 @@ void main() { !f.isConst! && !f.isFinal!, ), + predicate( + (FieldRef f) => + f.name == 'hashCode' && + f.declaredType != null && + !f.isStatic! && + !f.isConst! && + !f.isFinal!, + ), + predicate( + (FieldRef f) => + f.name == 'runtimeType' && + f.declaredType != null && + !f.isStatic! && + !f.isConst! && + !f.isFinal!, + ), ]), ); }); @@ -1088,18 +1096,7 @@ void main() { predicate( (FuncRef f) => f.name == 'staticHello' && f.isStatic!, ), - predicate((FuncRef f) => f.name == 'message' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'notFinal' && !f.isStatic!), predicate((FuncRef f) => f.name == 'hello' && !f.isStatic!), - predicate((FuncRef f) => f.name == '_equals' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'hashCode' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'toString' && !f.isStatic!), - predicate( - (FuncRef f) => f.name == 'noSuchMethod' && !f.isStatic!, - ), - predicate( - (FuncRef f) => f.name == 'runtimeType' && !f.isStatic!, - ), ]), ); expect( @@ -1129,6 +1126,22 @@ void main() { !f.isConst! && !f.isFinal!, ), + predicate( + (FieldRef f) => + f.name == 'hashCode' && + f.declaredType != null && + !f.isStatic! && + !f.isConst! && + !f.isFinal!, + ), + predicate( + (FieldRef f) => + f.name == 'runtimeType' && + f.declaredType != null && + !f.isStatic! && + !f.isConst! && + !f.isFinal!, + ), ]), ); }); @@ -1147,18 +1160,7 @@ void main() { predicate( (FuncRef f) => f.name == 'staticHello' && f.isStatic!, ), - predicate((FuncRef f) => f.name == 'message' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'notFinal' && !f.isStatic!), predicate((FuncRef f) => f.name == 'hello' && !f.isStatic!), - predicate((FuncRef f) => f.name == '_equals' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'hashCode' && !f.isStatic!), - predicate((FuncRef f) => f.name == 'toString' && !f.isStatic!), - predicate( - (FuncRef f) => f.name == 'noSuchMethod' && !f.isStatic!, - ), - predicate( - (FuncRef f) => f.name == 'runtimeType' && !f.isStatic!, - ), ]), ); expect( @@ -1188,6 +1190,22 @@ void main() { !f.isConst! && !f.isFinal!, ), + predicate( + (FieldRef f) => + f.name == 'hashCode' && + f.declaredType != null && + !f.isStatic! && + !f.isConst! && + !f.isFinal!, + ), + predicate( + (FieldRef f) => + f.name == 'runtimeType' && + f.declaredType != null && + !f.isStatic! && + !f.isConst! && + !f.isFinal!, + ), ]), ); }); diff --git a/dwds/test/fixtures/context.dart b/dwds/test/fixtures/context.dart index a5565f8ec..f2f27a6dc 100644 --- a/dwds/test/fixtures/context.dart +++ b/dwds/test/fixtures/context.dart @@ -225,12 +225,6 @@ class TestContext { '--define', 'build_web_compilers|ddc=generate-full-dill=true', ], - if (canaryFeatures) ...[ - '--define', - 'build_web_compilers|ddc=canary=true', - '--define', - 'build_web_compilers|sdk_js=canary=true', - ], for (final experiment in experiments) '--enable-experiment=$experiment', if (canaryFeatures) ...[ diff --git a/dwds/test/fixtures/fakes.dart b/dwds/test/fixtures/fakes.dart index 7b8544d77..7982416d6 100644 --- a/dwds/test/fixtures/fakes.dart +++ b/dwds/test/fixtures/fakes.dart @@ -330,9 +330,6 @@ class FakeStrategy implements LoadStrategy { @override String get loadLibrariesModule => ''; - @override - String loadLibrarySnippet(String libraryUri) => ''; - @override String get loadModuleSnippet => ''; diff --git a/dwds/test/instances/instance_canary_test.dart b/dwds/test/instances/instance_canary_test.dart index d583a8c63..6af65d71e 100644 --- a/dwds/test/instances/instance_canary_test.dart +++ b/dwds/test/instances/instance_canary_test.dart @@ -17,7 +17,7 @@ import 'instance_common.dart'; void main() { // Enable verbose logging for debugging. - final debug = false; + final debug = true; for (var compilationMode in CompilationMode.values) { _runCanaryModeVerificationTests( diff --git a/dwds/test/instances/instance_common.dart b/dwds/test/instances/instance_common.dart index c31b84070..001d6d066 100644 --- a/dwds/test/instances/instance_common.dart +++ b/dwds/test/instances/instance_common.dart @@ -111,7 +111,7 @@ void runTests({ expect(inspector.isDisplayableObject(ref), isTrue); }); - test('for a class', () async { + test('for an object', () async { final remoteObject = await libraryPublicFinal(compilationMode); final count = await inspector.loadField(remoteObject, 'myselfField'); final ref = await inspector.instanceRefFor(count); @@ -125,7 +125,7 @@ void runTests({ expect(inspector.isDisplayableObject(ref), isTrue); }); - test('for closure', () async { + test('for a closure', () async { final remoteObject = await libraryPublicFinal(compilationMode); final properties = await inspector.getProperties(remoteObject.objectId!); @@ -217,7 +217,7 @@ void runTests({ group('instance', () { setUp(() => setCurrentLogWriter(debug: debug)); - test('for class object', () async { + test('for an object', () async { final remoteObject = await libraryPublicFinal(compilationMode); final instance = await inspector.instanceFor(remoteObject); expect(instance!.kind, InstanceKind.kPlainInstance); @@ -259,7 +259,7 @@ void runTests({ expect(inspector.isDisplayableObject(instance), isTrue); }); - test('for a nested class', () async { + test('for a nested object', () async { final libraryRemoteObject = await libraryPublicFinal(compilationMode); final fieldRemoteObject = await inspector.loadField(libraryRemoteObject, 'myselfField'); @@ -312,25 +312,6 @@ void runTests({ expect(inspector.isDisplayableObject(instance), isTrue); }); - test( - 'for a class that implements List', - () async { - // The VM only uses kind List for SDK lists, and we follow that. - final remote = await inspector.jsEvaluate( - libraryVariableExpression('notAList', compilationMode), - ); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef.name, 'NotReallyAList'); - expect(instance.elements, isNull); - final field = instance.fields!.first; - expect(field.decl!.name, '_internal'); - expect(inspector.isDisplayableObject(instance), isTrue); - }, - skip: true, - ); - test('for a Dart error', () async { final remoteObject = await inspector.jsEvaluate(newDartError); final instance = await inspector.instanceFor(remoteObject); diff --git a/dwds/test/instances/instance_inspection_test.dart b/dwds/test/instances/instance_inspection_test.dart index 85e6b293b..13c12168e 100644 --- a/dwds/test/instances/instance_inspection_test.dart +++ b/dwds/test/instances/instance_inspection_test.dart @@ -33,8 +33,7 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - // TODO: build daemon also - for (var compilationMode in [CompilationMode.frontendServer]) { + for (var compilationMode in CompilationMode.values) { for (var nullSafetyMode in NullSafety.values) { _runTests( provider: provider, diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index cfcb45443..44c08f9ea 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -12,7 +12,7 @@ import 'instance_common.dart'; void main() { // Enable verbose logging for debugging. - final debug = false; + final debug = true; for (var compilationMode in CompilationMode.values) { runTests( diff --git a/dwds/test/instances/patterns_inspection_test.dart b/dwds/test/instances/patterns_inspection_test.dart index dea466f3e..29692aa24 100644 --- a/dwds/test/instances/patterns_inspection_test.dart +++ b/dwds/test/instances/patterns_inspection_test.dart @@ -32,8 +32,7 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - // TODO: build daemon also - for (var compilationMode in [CompilationMode.frontendServer]) { + for (var compilationMode in CompilationMode.values) { _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/record_inspection_test.dart b/dwds/test/instances/record_inspection_test.dart index 589da1dd6..7d8321c91 100644 --- a/dwds/test/instances/record_inspection_test.dart +++ b/dwds/test/instances/record_inspection_test.dart @@ -32,8 +32,7 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - // TODO: build daemon also - for (var compilationMode in [CompilationMode.frontendServer]) { + for (var compilationMode in CompilationMode.values) { _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/record_type_inspection_test.dart b/dwds/test/instances/record_type_inspection_test.dart index 3330468eb..081fa5907 100644 --- a/dwds/test/instances/record_type_inspection_test.dart +++ b/dwds/test/instances/record_type_inspection_test.dart @@ -32,8 +32,7 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - // TODO: build daemon also - for (var compilationMode in [CompilationMode.frontendServer]) { + for (var compilationMode in CompilationMode.values) { _runTests( provider: provider, compilationMode: compilationMode, diff --git a/dwds/test/instances/type_inspection_test.dart b/dwds/test/instances/type_inspection_test.dart index 00b19594f..ac146302f 100644 --- a/dwds/test/instances/type_inspection_test.dart +++ b/dwds/test/instances/type_inspection_test.dart @@ -32,8 +32,7 @@ void _runAllTests(bool canaryFeatures, bool debug) { ); tearDownAll(provider.dispose); - // TODO: build daemon also - for (var compilationMode in [CompilationMode.frontendServer]) { + for (var compilationMode in CompilationMode.values) { _runTests( provider: provider, compilationMode: compilationMode, diff --git a/fixtures/_webdevSoundSmoke/build.yaml b/fixtures/_webdevSoundSmoke/build.yaml index 797d391ad..1f4374a04 100644 --- a/fixtures/_webdevSoundSmoke/build.yaml +++ b/fixtures/_webdevSoundSmoke/build.yaml @@ -1,7 +1,7 @@ -global_options: - build_web_compilers:ddc: - options: - canary: true - build_web_compilers:sdk_js: - options: - canary: true \ No newline at end of file +# global_options: +# build_web_compilers:ddc: +# options: +# canary: false +# build_web_compilers:sdk_js: +# options: +# canary: false \ No newline at end of file diff --git a/fixtures/_webdevSoundSmoke/web/main.dart b/fixtures/_webdevSoundSmoke/web/main.dart index 67211da9a..9e50e52a7 100644 --- a/fixtures/_webdevSoundSmoke/web/main.dart +++ b/fixtures/_webdevSoundSmoke/web/main.dart @@ -20,19 +20,29 @@ void main() { Timer.periodic(const Duration(seconds: 1), (_) { print('Counter is: ${++count}'); // Breakpoint: printCounter - print('${Mine(0)}'); + var m = Mine(0); + print(m.x2); + print(m); var x = () => true; print(x); }); } -class Mine { +class Mine extends A { static int y = 0; int x; + int _x = 15; + + //late final x3 = 14; + + int get x2 => x; Mine(this.x); } -void foo() { - print('foo'); +class A { + int x1 = 1; + void foo() { + print('foo'); + } } diff --git a/webdev/lib/src/serve/webdev_server.dart b/webdev/lib/src/serve/webdev_server.dart index 8826b3af0..0f6ffa6df 100644 --- a/webdev/lib/src/serve/webdev_server.dart +++ b/webdev/lib/src/serve/webdev_server.dart @@ -140,7 +140,6 @@ class WebDevServer { experiments: options.configuration.experiments, canaryFeatures: options.configuration.canaryFeatures, sdkConfigurationProvider: const DefaultSdkConfigurationProvider(), - canaryFeatures: options.configuration.canaryFeatures, ); } var shouldServeDevTools = From 7a6b4ff4ab292f3fc537bb2684510c9ad3d526a8 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Wed, 19 Jul 2023 09:03:03 -0700 Subject: [PATCH 11/24] Cleanup --- dwds/lib/src/debugging/debugger.dart | 4 - dwds/lib/src/debugging/inspector.dart | 9 +- dwds/lib/src/debugging/instance.dart | 8 - dwds/lib/src/debugging/libraries.dart | 5 - dwds/lib/src/debugging/metadata/function.dart | 17 +- dwds/lib/src/debugging/runtime.dart | 132 ---- dwds/lib/src/utilities/domain.dart | 4 - dwds/test/chrome_proxy_service_test.dart | 68 +- dwds/test/instances/instance_common.dart | 2 +- .../instance_inspection_canary_test.dart | 41 ++ .../instances/instance_inspection_common.dart | 636 +++++++++--------- .../instances/instance_inspection_test.dart | 277 +------- .../instances/patterns_inspection_test.dart | 2 +- .../instances/record_inspection_test.dart | 2 +- .../record_type_inspection_test.dart | 2 +- dwds/test/instances/test_inspector.dart | 351 ++++++++++ dwds/test/instances/type_inspection_test.dart | 2 +- fixtures/_webdevSoundSmoke/build.yaml | 14 +- fixtures/_webdevSoundSmoke/web/main.dart | 28 +- 19 files changed, 737 insertions(+), 867 deletions(-) delete mode 100644 dwds/lib/src/debugging/runtime.dart create mode 100644 dwds/test/instances/instance_inspection_canary_test.dart create mode 100644 dwds/test/instances/test_inspector.dart diff --git a/dwds/lib/src/debugging/debugger.dart b/dwds/lib/src/debugging/debugger.dart index 55b9ff6b3..27e4c1b54 100644 --- a/dwds/lib/src/debugging/debugger.dart +++ b/dwds/lib/src/debugging/debugger.dart @@ -712,10 +712,6 @@ Future sendCommandAndValidateResult( }) async { final response = await remoteDebugger.sendCommand(method, params: params); final result = response.result?[resultField]; - final internalProperties = response.result?['internalProperties']; - if (internalProperties != null) { - Logger.root.severe('Properties: $result'); - } if (result == null) { throw RPCError( method, diff --git a/dwds/lib/src/debugging/inspector.dart b/dwds/lib/src/debugging/inspector.dart index e107f8ade..2e2d56147 100644 --- a/dwds/lib/src/debugging/inspector.dart +++ b/dwds/lib/src/debugging/inspector.dart @@ -573,10 +573,6 @@ class AppInspector implements AppInspectorInterface { int? offset, int? count, int? length, - bool ownProperties = false, - bool accessorPropertiesOnly = false, - bool generatePreview = true, - bool nonIndexedPropertiesOnly = false, }) async { String rangeId = objectId; // Ignore offset/count if there is no length: @@ -600,10 +596,7 @@ class AppInspector implements AppInspectorInterface { resultField: 'result', params: { 'objectId': rangeId, - 'ownProperties': ownProperties, - 'accessorPropertiesOnly': accessorPropertiesOnly, - 'generatePreview': generatePreview, - 'nonIndexedPropertiesOnly': nonIndexedPropertiesOnly, + 'ownProperties': true, }, ); return jsProperties diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index d4d3a7b1d..4b33a0981 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -242,10 +242,6 @@ class InstanceHelper extends Domain { offset: offset, count: count, length: metaData.length, - ownProperties: false, - accessorPropertiesOnly: false, - generatePreview: true, - nonIndexedPropertiesOnly: true, ); final dartProperties = await _dartFieldsFor(properties, remoteObject); var boundFields = await Future.wait( @@ -789,10 +785,6 @@ class InstanceHelper extends Domain { returnByValue: true, ); final names = List.from(result.value as List); - - _logger.severe('Fieldnames: $names'); - _logger.severe('Properties: $allJsProperties'); - // TODO(#761): Better support for large collections. return allJsProperties .where((property) => names.contains(property.name)) diff --git a/dwds/lib/src/debugging/libraries.dart b/dwds/lib/src/debugging/libraries.dart index 6a6b1d6c7..5f3570a95 100644 --- a/dwds/lib/src/debugging/libraries.dart +++ b/dwds/lib/src/debugging/libraries.dart @@ -4,7 +4,6 @@ import 'package:collection/collection.dart'; import 'package:dwds/src/debugging/metadata/class.dart'; -import 'package:dwds/src/debugging/runtime.dart'; import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/services/chrome_debug_exception.dart'; import 'package:dwds/src/utilities/domain.dart'; @@ -91,10 +90,6 @@ class LibraryHelper extends Domain { })() '''; - //final runtime = DebuggerRuntime(inspector); - //final result = await runtime.getLibraryMetadata(libraryUri); - //print('Library metadata: $result'); - RemoteObject? result; try { result = await inspector.jsEvaluate(expression, returnByValue: true); diff --git a/dwds/lib/src/debugging/metadata/function.dart b/dwds/lib/src/debugging/metadata/function.dart index 1650548b6..b0fb7b6b7 100644 --- a/dwds/lib/src/debugging/metadata/function.dart +++ b/dwds/lib/src/debugging/metadata/function.dart @@ -18,24 +18,17 @@ class FunctionMetaData { RemoteObject remoteObject, ) async { final evalExpression = ''' - function(remoteObject) { - var sdkUtils = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - var name = remoteObject.name; - if(remoteObject._boundObject) { - name = sdkUtils.getType(remoteObject._boundObject).name + - '.' + remoteObject._boundMethod.name; - } - return name; + function() { + const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); + const dart = sdk.dart; + return dart.getFunctionMetadata(this); } '''; - final arguments = [ - {'objectId': remoteObject.objectId}, - ]; + final response = await remoteDebugger.sendCommand( 'Runtime.callFunctionOn', params: { 'functionDeclaration': evalExpression, - 'arguments': arguments, 'objectId': remoteObject.objectId, 'returnByValue': true, }, diff --git a/dwds/lib/src/debugging/runtime.dart b/dwds/lib/src/debugging/runtime.dart deleted file mode 100644 index c31b290d9..000000000 --- a/dwds/lib/src/debugging/runtime.dart +++ /dev/null @@ -1,132 +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. - -import 'package:dwds/src/loaders/strategy.dart'; -import 'package:dwds/src/services/chrome_debug_exception.dart'; -import 'package:dwds/src/utilities/domain.dart'; -import 'package:logging/logging.dart'; -import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; - -class DebuggerRuntime { - final _logger = Logger('DebuggerRuntime'); - final AppInspectorInterface _inspector; - - DebuggerRuntime(this._inspector); - - static String _jsRuntimeCall( - String call, { - List params = const [], - }) => - ''' - function(${params.join(', ')}) { - const sdk = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk'); - const dart = sdk.dart; - return dart.$call; - } - '''; - - Future getLibraryMetadata(String libraryUri) async { - final call = _jsRuntimeCall('getLibraryMetadata("$libraryUri")'); - print('Runtime call: $call'); - RemoteObject? result; - try { - result = await _inspector.jsEvaluate(call, returnByValue: true); - } on ChromeDebugException catch (_) { - // Unreferenced libraries are not loaded at runtime, - // return empty library object for consistency among - // VM Service implementations. - // TODO: Collect library and class information from debug symbols. - _logger.warning('Library $libraryUri is not loaded. ' - 'This can happen for unreferenced libraries.'); - } - return result; - } - - Future getClassMetadata( - String libraryUri, - String className, - ) async { - final call = _jsRuntimeCall( - "getClassMetadata('$libraryUri', '$className')", - ); - return _inspector.jsEvaluate(call, returnByValue: true); - - // TODO: can we use _inspector.jsEvaluate? - /* RemoteObject result; - try { - result = await _inspector.remoteDebugger.evaluate( - call, - returnByValue: true, - contextId: await _inspector.contextId, - ); - } on ExceptionDetails catch (e) { - throw ChromeDebugException(e.json, evalContents: call); - } - return result;*/ - } - - Future getFunctionName(RemoteObject object) { - final call = _jsRuntimeCall("getFunctionName(this)"); - return _inspector.jsCallFunctionOn(object, call, [], returnByValue: true); - } - - Future getObjectMetadata(RemoteObject object) { - final call = _jsRuntimeCall("getObjectMetadata(this)"); - return _inspector.jsCallFunctionOn(object, call, [], returnByValue: true); - } - - Future getLibrary(String libraryUri) { - final call = _jsRuntimeCall("getLibrary('$libraryUri')"); - return _inspector.jsEvaluate(call); - } - - Future getMapElements(RemoteObject map) { - final call = _jsRuntimeCall("getMapElements(this)"); - return _inspector.jsCallFunctionOn(map, call, []); - } - - Future getSetElements(RemoteObject set) { - final call = _jsRuntimeCall("getSetElements(this)"); - return _inspector.jsCallFunctionOn(set, call, []); - } - - Future getRecordFields( - RemoteObject record, - ) { - final call = _jsRuntimeCall("getRecordFields(this)"); - return _inspector.jsCallFunctionOn(record, call, []); - } - - Future getTypeFields(RemoteObject type) { - final call = _jsRuntimeCall("getTypeFields(this)"); - return _inspector.jsCallFunctionOn(type, call, []); - } - - Future getRecordTypeFields(RemoteObject recordType) { - final call = _jsRuntimeCall("getRecordTypeFields(this)"); - return _inspector.jsCallFunctionOn(recordType, call, []); - } - - Future getObjectFieldNames(RemoteObject object) { - final call = _jsRuntimeCall("getObjectFieldNames(this)"); - return _inspector.jsCallFunctionOn(object, call, [], returnByValue: true); - } - - Future loadField(RemoteObject receiver, String fieldName) { - final call = _jsRuntimeCall("dloadRepl(this, '$fieldName')"); - return _inspector.jsCallFunctionOn(receiver, call, []); - } - - Future subRange( - RemoteObject object, - RemoteObject offset, - RemoteObject count, - ) { - final call = _jsRuntimeCall( - 'getSubRange(this, offset, count)', - params: ['offset', 'count'], - ); - return _inspector.jsCallFunctionOn(object, call, [offset, count]); - } -} diff --git a/dwds/lib/src/utilities/domain.dart b/dwds/lib/src/utilities/domain.dart index c3d5ca379..bfb19204e 100644 --- a/dwds/lib/src/utilities/domain.dart +++ b/dwds/lib/src/utilities/domain.dart @@ -103,10 +103,6 @@ abstract class AppInspectorInterface { int? offset, int? count, int? length, - bool ownProperties = true, - bool accessorPropertiesOnly = false, - bool generatePreview = false, - bool nonIndexedPropertiesOnly = false, }); bool isDisplayableObject(Object? object); diff --git a/dwds/test/chrome_proxy_service_test.dart b/dwds/test/chrome_proxy_service_test.dart index abdde3a26..1065f21e5 100644 --- a/dwds/test/chrome_proxy_service_test.dart +++ b/dwds/test/chrome_proxy_service_test.dart @@ -600,6 +600,8 @@ void main() { unorderedEquals([ predicate((FuncRef f) => f.name == 'staticHello' && f.isStatic!), predicate((FuncRef f) => f.name == 'hello' && !f.isStatic!), + predicate((FuncRef f) => f.name == 'hashCode' && !f.isStatic!), + predicate((FuncRef f) => f.name == 'runtimeType' && !f.isStatic!), ]), ); expect( @@ -611,7 +613,7 @@ void main() { f.declaredType != null && !f.isStatic! && !f.isConst! && - f.isFinal!, + !f.isFinal!, ), predicate( (FieldRef f) => @@ -629,22 +631,6 @@ void main() { !f.isConst! && !f.isFinal!, ), - predicate( - (FieldRef f) => - f.name == 'hashCode' && - f.declaredType != null && - !f.isStatic! && - !f.isConst! && - !f.isFinal!, - ), - predicate( - (FieldRef f) => - f.name == 'runtimeType' && - f.declaredType != null && - !f.isStatic! && - !f.isConst! && - !f.isFinal!, - ), ]), ); }); @@ -1093,10 +1079,10 @@ void main() { expect( testClass.functions, unorderedEquals([ - predicate( - (FuncRef f) => f.name == 'staticHello' && f.isStatic!, - ), + predicate((FuncRef f) => f.name == 'staticHello' && f.isStatic!), predicate((FuncRef f) => f.name == 'hello' && !f.isStatic!), + predicate((FuncRef f) => f.name == 'hashCode' && !f.isStatic!), + predicate((FuncRef f) => f.name == 'runtimeType' && !f.isStatic!), ]), ); expect( @@ -1108,7 +1094,7 @@ void main() { f.declaredType != null && !f.isStatic! && !f.isConst! && - f.isFinal!, + !f.isFinal!, ), predicate( (FieldRef f) => @@ -1126,22 +1112,6 @@ void main() { !f.isConst! && !f.isFinal!, ), - predicate( - (FieldRef f) => - f.name == 'hashCode' && - f.declaredType != null && - !f.isStatic! && - !f.isConst! && - !f.isFinal!, - ), - predicate( - (FieldRef f) => - f.name == 'runtimeType' && - f.declaredType != null && - !f.isStatic! && - !f.isConst! && - !f.isFinal!, - ), ]), ); }); @@ -1157,10 +1127,10 @@ void main() { expect( testClass.functions, unorderedEquals([ - predicate( - (FuncRef f) => f.name == 'staticHello' && f.isStatic!, - ), + predicate((FuncRef f) => f.name == 'staticHello' && f.isStatic!), predicate((FuncRef f) => f.name == 'hello' && !f.isStatic!), + predicate((FuncRef f) => f.name == 'hashCode' && !f.isStatic!), + predicate((FuncRef f) => f.name == 'runtimeType' && !f.isStatic!), ]), ); expect( @@ -1172,7 +1142,7 @@ void main() { f.declaredType != null && !f.isStatic! && !f.isConst! && - f.isFinal!, + !f.isFinal!, ), predicate( (FieldRef f) => @@ -1190,22 +1160,6 @@ void main() { !f.isConst! && !f.isFinal!, ), - predicate( - (FieldRef f) => - f.name == 'hashCode' && - f.declaredType != null && - !f.isStatic! && - !f.isConst! && - !f.isFinal!, - ), - predicate( - (FieldRef f) => - f.name == 'runtimeType' && - f.declaredType != null && - !f.isStatic! && - !f.isConst! && - !f.isFinal!, - ), ]), ); }); diff --git a/dwds/test/instances/instance_common.dart b/dwds/test/instances/instance_common.dart index 001d6d066..346617499 100644 --- a/dwds/test/instances/instance_common.dart +++ b/dwds/test/instances/instance_common.dart @@ -15,7 +15,7 @@ import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; -import 'instance_inspection_common.dart'; +import 'test_inspector.dart'; void runTests({ required CompilationMode compilationMode, diff --git a/dwds/test/instances/instance_inspection_canary_test.dart b/dwds/test/instances/instance_inspection_canary_test.dart new file mode 100644 index 000000000..533b76b11 --- /dev/null +++ b/dwds/test/instances/instance_inspection_canary_test.dart @@ -0,0 +1,41 @@ +// 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)) + +import 'package:test/test.dart'; +import 'package:test_common/test_sdk_configuration.dart'; + +import '../fixtures/context.dart'; +import '../fixtures/project.dart'; +import 'instance_inspection_common.dart'; + +void main() { + // Enable verbose logging for debugging. + final debug = false; + + _runAllTests(canaryFeatures: true, debug: debug); +} + +void _runAllTests({bool canaryFeatures = false, bool debug = false}) { + group('canaryFeatures: $canaryFeatures |', () { + final provider = TestSdkConfigurationProvider( + verbose: debug, + canaryFeatures: canaryFeatures, + ); + tearDownAll(provider.dispose); + + for (var compilationMode in CompilationMode.values) { + runTests( + provider: provider, + compilationMode: compilationMode, + nullSafetyMode: NullSafety.sound, + canaryFeatures: canaryFeatures, + debug: debug, + ); + } + }); +} diff --git a/dwds/test/instances/instance_inspection_common.dart b/dwds/test/instances/instance_inspection_common.dart index c1f9cbcd9..da169e00e 100644 --- a/dwds/test/instances/instance_inspection_common.dart +++ b/dwds/test/instances/instance_inspection_common.dart @@ -1,351 +1,317 @@ -// Copyright (c) 2020, 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. -@TestOn('vm') -@Timeout(Duration(minutes: 2)) - 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'; - -class TestInspector { - TestInspector(this.context); - TestContext context; - - VmServiceInterface get service => context.debugConnection.vmService; - - Future onBreakPoint( - Stream stream, - String isolateId, - ScriptRef script, - String breakPointId, - Future Function(Event event) body, - ) async { - Breakpoint? bp; - try { - final line = - await context.findBreakpointLine(breakPointId, isolateId, script); - bp = await service.addBreakpointWithScriptUri( +import '../fixtures/project.dart'; +import 'test_inspector.dart'; + +const _mainLibraryUri = 'org-dartlang-app:///web/main.dart'; + +void runTests({ + required TestSdkConfigurationProvider provider, + required CompilationMode compilationMode, + required NullSafety nullSafetyMode, + required bool canaryFeatures, + required bool debug, +}) { + final testProject = nullSafetyMode == NullSafety.sound + ? TestProject.testPackageWithSoundNullSafety() + : TestProject.testPackageWithWeakNullSafety(); + final context = TestContext(testProject, provider); + + late VmServiceInterface service; + late Stream stream; + late String isolateId; + late ScriptRef mainScript; + + final testInspector = TestInspector(context); + + onBreakPoint(breakPointId, body) => testInspector.onBreakPoint( + stream, isolateId, - script.uri!, - line, + mainScript, + breakPointId, + body, ); - final event = - await stream.firstWhere((e) => e.kind == EventKind.kPauseBreakpoint); - - await body(event); - } finally { - // Remove breakpoint so it doesn't impact other tests or retries. - if (bp != null) { - await service.removeBreakpoint(isolateId, bp.id!); - } - } - } - - Future getFields( - String isolateId, - InstanceRef instanceRef, { - int? offset, - int? count, - int depth = -1, - }) async { - final instanceId = instanceRef.id!; - - final result = await service.getObject( - isolateId, - instanceId, - offset: offset, - count: count, - ); - - expect(result, isA()); - final instance = result as Instance; - - expect( - instance.kind, - instanceRef.kind, - reason: 'object $instanceId with ref kind ${instanceRef.kind} ' - 'has an instance kind ${instance.kind}', - ); - - final fields = instance.fields; - final associations = instance.associations; - final elements = instance.elements; - - Map? fieldRefs; - if (fields != null) { - fieldRefs = _boundFieldsToMap(fields); - } else if (associations != null) { - fieldRefs = _associationsToMap(associations); - } else if (elements != null) { - fieldRefs = _elementsToMap(elements); - } else { - fieldRefs = {}; - } - - if (depth > 0) { - depth--; - } - if (depth == 0) { - return elements == null ? fieldRefs : fieldRefs.values.toList(); - } - - final fieldValues = {}; - for (var p in fieldRefs.entries) { - fieldValues[p.key] = _getValue(p.value) ?? - await getFields( - isolateId, - p.value, - depth: depth, - ); - } - return elements == null ? fieldValues : fieldValues.values.toList(); - } - - Future getInstanceRef( - String isolateId, - int frame, - String expression, - ) async { - final result = await service.evaluateInFrame( - isolateId, - frame, - expression, - ); - expect(result, isA()); - return result as InstanceRef; - } - - Future getInstance( - String isolateId, - int frame, - String expression, - ) async { - final instanceRef = await getInstanceRef( - isolateId, - frame, - expression, - ); - - expect(instanceRef.id, isNotNull); - final result = await service.getObject( - isolateId, - instanceRef.id!, - ); - - expect(result, isA()); - return result as Instance; - } - - Future> getFrameVariables( - String isolateId, - Frame frame, - ) async { - final refs = { - for (var variable in frame.vars!) - variable.name!: variable.value as InstanceRef, - }; - final instances = {}; - for (final p in refs.entries) { - instances[p.key] = - await service.getObject(isolateId, p.value.id!) as Instance; - } - return instances; - } - - Future getDisplayedRef( - String isolateId, - String instanceId, - ) async => - await service.invoke(isolateId, instanceId, 'toString', []) - as InstanceRef; - - Future> getDisplayedFields( - String isolateId, - InstanceRef ref, - ) async { - final fieldRefs = - await getFields(isolateId, ref, depth: 1) as Map; - - Future toStringValue(InstanceRef ref) async => - ref.valueAsString ?? - (await getDisplayedRef(isolateId, ref.id!)).valueAsString; - - final fields = await Future.wait(fieldRefs.values.map(toStringValue)); - return fields.toList(); - } - - Future> getElements( - String isolateId, - String instanceId, - ) async { - final instance = await service.getObject(isolateId, instanceId) as Instance; - return Future.wait( - instance.fields!.map( - (e) async => await service.getObject( - isolateId, - (e.value as InstanceRef).id!, - ) as Instance, - ), - ); - } -} - -Map _associationsToMap( - Iterable associations, -) => - Map.fromEntries( - associations.map((e) => MapEntry(e.key.valueAsString, e.value)), - ); - -Map _boundFieldsToMap(Iterable fields) => - Map.fromEntries( - fields.where((e) => e.name != null).map((e) => MapEntry(e.name, e.value)), - ); - -Map _elementsToMap(List fields) => - Map.fromEntries( - fields - .where((e) => e != null) - .map((e) => MapEntry(fields.indexOf(e), e!)), - ); - -Matcher matchRecordInstanceRef({required int length}) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kRecord) - .having((e) => e.length, 'length', length) - .having((e) => e.classRef!, 'classRef', matchRecordClassRef); - -Matcher matchRecordTypeInstanceRef({required int length}) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kRecordType) - .having((e) => e.length, 'length', length) - .having((e) => e.classRef!, 'classRef', matchRecordTypeClassRef); - -Matcher matchTypeInstanceRef(dynamic name) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kType) - .having((e) => e.name, 'type ref name', name) - .having((e) => e.classRef, 'classRef', matchTypeClassRef); - -Matcher matchPrimitiveInstanceRef({ - required String kind, -}) => - isA().having((e) => e.kind, 'kind', kind); - -Matcher matchPrimitiveInstance({ - required String kind, - required dynamic value, -}) => - isA() - .having((e) => e.kind, 'kind', kind) - .having(_getValue, 'value', value); - -Matcher matchPlainInstance({required libraryId, required String type}) => - isA() - .having((e) => e.kind, 'kind', InstanceKind.kPlainInstance) - .having( - (e) => e.classRef, - 'classRef', - matchClassRef(name: type, libraryId: libraryId), - ); + getInstance(frame, expression) => + testInspector.getInstance(isolateId, frame, expression); -Matcher matchListInstance({required dynamic type}) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kList) - .having((e) => e.classRef, 'classRef', matchListClassRef(type)); - -Matcher matchMapInstance({required String type}) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kMap) - .having((e) => e.classRef, 'classRef', matchMapClassRef(type)); - -Matcher matchSetInstance({required String type}) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kSet) - .having((e) => e.classRef, 'classRef', matchSetClassRef(type)); - -Matcher matchRecordInstance({required int length}) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kRecord) - .having((e) => e.length, 'length', length) - .having((e) => e.classRef, 'classRef', matchRecordClassRef); - -Matcher matchRecordTypeInstance({required int length}) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kRecordType) - .having((e) => e.length, 'length', length) - .having((e) => e.classRef, 'classRef', matchRecordTypeClassRef); - -Matcher matchTypeStringInstance(dynamic name) => - matchPrimitiveInstance(kind: InstanceKind.kString, value: name); - -Matcher matchTypeInstance(dynamic name) => isA() - .having((e) => e.kind, 'kind', InstanceKind.kType) - .having((e) => e.name, 'type name', name) - .having((e) => e.classRef, 'classRef', matchTypeClassRef); - -Matcher matchRecordClass = - matchClass(name: matchRecordClassName, libraryId: _dartCoreLibrary); -Matcher matchRecordTypeClass = - matchClass(name: matchRecordTypeClassName, libraryId: _dartRuntimeLibrary); -Matcher matchTypeClass = - matchClass(name: matchTypeClassName, libraryId: _dartCoreLibrary); - -Matcher matchClass({dynamic name, String? libraryId}) => isA() - .having((e) => e.name, 'class name', name) - .having((e) => e.library, 'library', matchLibraryRef(libraryId)); - -Matcher matchRecordClassRef = - matchClassRef(name: matchRecordClassName, libraryId: _dartCoreLibrary); -Matcher matchRecordTypeClassRef = matchClassRef( - name: matchRecordTypeClassName, - libraryId: _dartRuntimeLibrary, -); -Matcher matchTypeClassRef = - matchClassRef(name: matchTypeClassName, libraryId: _dartCoreLibrary); -Matcher matchListClassRef(dynamic type) => - matchClassRef(name: type, libraryId: _matchListLibraryName); -Matcher matchMapClassRef(String type) => - matchClassRef(name: type, libraryId: _dartJsHelperLibrary); -Matcher matchSetClassRef(String type) => - matchClassRef(name: type, libraryId: _dartCollectionLibrary); - -Matcher matchClassRef({dynamic name, dynamic libraryId}) => isA() - .having((e) => e.name, 'class ref name', name) - .having((e) => e.library, 'library', matchLibraryRef(libraryId)); - -Matcher matchLibraryRef(dynamic libraryId) => isA() - .having((e) => e.name, 'library name', libraryId) - .having((e) => e.id, 'id', libraryId) - .having((e) => e.uri, 'uri', libraryId); - -Object? _getValue(InstanceRef instanceRef) { - switch (instanceRef.kind) { - case InstanceKind.kBool: - return instanceRef.valueAsString == 'true'; - case InstanceKind.kDouble: - case InstanceKind.kInt: - return double.parse(instanceRef.valueAsString!); - case InstanceKind.kString: - return instanceRef.valueAsString; - default: - return null; - } -} + getObject(instanceId) => service.getObject(isolateId, instanceId); -final _dartCoreLibrary = 'dart:core'; -final _dartRuntimeLibrary = 'dart:_runtime'; -final _dartInterceptorsLibrary = 'dart:_interceptors'; -final _dartJsHelperLibrary = 'dart:_js_helper'; -final _dartCollectionLibrary = 'dart:collection'; + getInstanceRef(frame, expression) => + testInspector.getInstanceRef(isolateId, frame, expression); -final matchRecordClassName = 'Record'; -final matchRecordTypeClassName = 'RecordType'; + getFields(instanceRef, {offset, count}) => testInspector + .getFields(isolateId, instanceRef, offset: offset, count: count); -/// Match types for old and new type systems. -/// - Old type system has `dart:core|List` and `dart:_runtime|_Type`. -/// - New type system has `dart:_interceptors|JSArray` and `dart:core|Type`. -/// TODO(annagrin): update when DDC enables new type system. -final matchTypeClassName = anyOf(['Type', '_Type']); + group('$nullSafetyMode |', () { + group('$compilationMode |', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + compilationMode: compilationMode, + enableExpressionEvaluation: true, + verboseCompiler: debug, + experiments: ['records'], + canaryFeatures: canaryFeatures, + ); + 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(context.tearDown); + + setUp(() => setCurrentLogWriter(debug: debug)); + tearDown(() async { + try { + await service.resume(isolateId); + } catch (_) {} + }); + + group('Library |', () { + test('class names', () async { + final library = await service.getObject(isolateId, _mainLibraryUri); + + expect( + library, + isA() + .having((l) => l.name, 'library name', endsWith('main.dart')) + .having((l) => l.classes!.map((e) => e.name), 'class names', [ + 'MainClass', + 'EnclosedClass', + 'ClassWithMethod', + 'EnclosingClass', + ]), + ); + }); + }); -Matcher matchListClassName(String elementType) => - anyOf(['JSArray<$elementType>', 'List<$elementType>']); + group('Class |', () { + test('name', () async { + final cls = await service.getObject( + isolateId, + 'classes|$_mainLibraryUri|MainClass', + ); -final _matchListLibraryName = - anyOf([_dartInterceptorsLibrary, _dartCoreLibrary]); + expect( + cls, + matchClass(name: 'MainClass', libraryId: _mainLibraryUri), + ); + }); + }); + + group('Object |', () { + test('type and fields', () async { + await onBreakPoint('printFieldMain', (event) async { + final frame = event.topFrame!.index!; + final instanceRef = await getInstanceRef(frame, 'instance'); + + final instanceId = instanceRef.id!; + expect( + await getObject(instanceId), + matchPlainInstance( + libraryId: _mainLibraryUri, + type: 'MainClass', + ), + ); + + expect(await getFields(instanceRef), {'_field': 1, 'field': 2}); + + // Offsets and counts are ignored for plain object fields. + + // DevTools calls [VmServiceInterface.getObject] with offset=0 + // and count=0 and expects all fields to be returned. + expect( + await getFields(instanceRef, offset: 0, count: 0), + {'_field': 1, 'field': 2}, + ); + expect( + await getFields(instanceRef, offset: 0), + {'_field': 1, 'field': 2}, + ); + expect( + await getFields(instanceRef, offset: 0, count: 1), + {'_field': 1, 'field': 2}, + ); + expect( + await getFields(instanceRef, offset: 1), + {'_field': 1, 'field': 2}, + ); + expect( + await getFields(instanceRef, offset: 1, count: 0), + {'_field': 1, 'field': 2}, + ); + expect( + await getFields(instanceRef, offset: 1, count: 3), + {'_field': 1, 'field': 2}, + ); + }); + }); + + test('field access', () async { + await onBreakPoint('printFieldMain', (event) async { + final frame = event.topFrame!.index!; + expect( + await getInstance(frame, r'instance.field'), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 2), + ); + + expect( + await getInstance(frame, r'instance._field'), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), + ); + }); + }); + }); + + group('List |', () { + test('type and fields', () async { + await onBreakPoint('printList', (event) async { + final frame = event.topFrame!.index!; + final instanceRef = await getInstanceRef(frame, 'list'); + + final instanceId = instanceRef.id!; + expect( + await getObject(instanceId), + matchListInstance(type: matchListClassName('int')), + ); + + expect(await getFields(instanceRef), [0, 1, 2]); + expect(await getFields(instanceRef, offset: 1, count: 0), []); + expect(await getFields(instanceRef, offset: 0), [0, 1, 2]); + expect(await getFields(instanceRef, offset: 0, count: 1), [0]); + expect(await getFields(instanceRef, offset: 1), [1, 2]); + expect(await getFields(instanceRef, offset: 1, count: 1), [1]); + expect(await getFields(instanceRef, offset: 1, count: 3), [1, 2]); + expect(await getFields(instanceRef, offset: 3, count: 3), []); + }); + }); + + test('Element access', () async { + await onBreakPoint('printList', (event) async { + final frame = event.topFrame!.index!; + expect( + await getInstance(frame, r'list[0]'), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 0), + ); + + expect( + await getInstance(frame, r"list[1]"), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), + ); + + expect( + await getInstance(frame, r"list[2]"), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 2), + ); + }); + }); + }); + + group('Map |', () { + test('type and fields', () async { + await onBreakPoint('printMap', (event) async { + final frame = event.topFrame!.index!; + final instanceRef = await getInstanceRef(frame, 'map'); + + final instanceId = instanceRef.id!; + expect( + await getObject(instanceId), + matchMapInstance(type: 'IdentityMap'), + ); + + expect(await getFields(instanceRef), {'a': 1, 'b': 2, 'c': 3}); + + expect(await getFields(instanceRef, offset: 1, count: 0), {}); + expect( + await getFields(instanceRef, offset: 0), + {'a': 1, 'b': 2, 'c': 3}, + ); + expect(await getFields(instanceRef, offset: 0, count: 1), {'a': 1}); + expect(await getFields(instanceRef, offset: 1), {'b': 2, 'c': 3}); + expect(await getFields(instanceRef, offset: 1, count: 1), {'b': 2}); + expect( + await getFields(instanceRef, offset: 1, count: 3), + {'b': 2, 'c': 3}, + ); + expect(await getFields(instanceRef, offset: 3, count: 3), {}); + }); + }); + + test('Element access', () async { + await onBreakPoint('printMap', (event) async { + final frame = event.topFrame!.index!; + expect( + await getInstance(frame, r"map['a']"), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), + ); + + expect( + await getInstance(frame, r"map['b']"), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 2), + ); + + expect( + await getInstance(frame, r"map['c']"), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3), + ); + }); + }); + }); + + group('Set |', () { + test('type and fields', () async { + await onBreakPoint('printSet', (event) async { + final frame = event.topFrame!.index!; + final instanceRef = await getInstanceRef(frame, 'mySet'); + + final instanceId = instanceRef.id!; + expect( + await getObject(instanceId), + matchSetInstance(type: '_HashSet'), + ); + + expect(await getFields(instanceRef), [1, 4, 5, 7]); + expect(await getFields(instanceRef, offset: 0), [1, 4, 5, 7]); + expect(await getFields(instanceRef, offset: 1, count: 2), [4, 5]); + expect(await getFields(instanceRef, offset: 2), [5, 7]); + expect(await getFields(instanceRef, offset: 2, count: 10), [5, 7]); + expect(await getFields(instanceRef, offset: 1, count: 0), []); + expect(await getFields(instanceRef, offset: 10, count: 2), []); + }); + }); + + test('Element access', () async { + await onBreakPoint('printSet', (event) async { + final frame = event.topFrame!.index!; + expect( + await getInstance(frame, r"mySet.first"), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), + ); + expect( + await getInstance(frame, r"mySet.last"), + matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 7), + ); + }); + }); + }); + }); + }); +} diff --git a/dwds/test/instances/instance_inspection_test.dart b/dwds/test/instances/instance_inspection_test.dart index 13c12168e..21fcad5ba 100644 --- a/dwds/test/instances/instance_inspection_test.dart +++ b/dwds/test/instances/instance_inspection_test.dart @@ -7,9 +7,7 @@ @Timeout(Duration(minutes: 2)) 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'; @@ -19,13 +17,10 @@ void main() { // Enable verbose logging for debugging. final debug = false; - // TODO: split out canary tests - for (var canaryFeatures in [false, true]) { - _runAllTests(canaryFeatures, debug); - } + _runAllTests(canaryFeatures: false, debug: debug); } -void _runAllTests(bool canaryFeatures, bool debug) { +void _runAllTests({bool canaryFeatures = false, bool debug = false}) { group('canaryFeatures: $canaryFeatures |', () { final provider = TestSdkConfigurationProvider( verbose: debug, @@ -35,7 +30,7 @@ void _runAllTests(bool canaryFeatures, bool debug) { for (var compilationMode in CompilationMode.values) { for (var nullSafetyMode in NullSafety.values) { - _runTests( + runTests( provider: provider, compilationMode: compilationMode, nullSafetyMode: nullSafetyMode, @@ -46,269 +41,3 @@ void _runAllTests(bool canaryFeatures, bool debug) { } }); } - -void _runTests({ - required TestSdkConfigurationProvider provider, - required CompilationMode compilationMode, - required NullSafety nullSafetyMode, - required bool canaryFeatures, - required bool debug, -}) { - final testProject = nullSafetyMode == NullSafety.sound - ? TestProject.testPackageWithSoundNullSafety() - : TestProject.testPackageWithWeakNullSafety(); - final context = TestContext(testProject, provider); - - late VmServiceInterface service; - late Stream stream; - late String isolateId; - late ScriptRef mainScript; - - final testInspector = TestInspector(context); - - onBreakPoint(breakPointId, body) => testInspector.onBreakPoint( - stream, - isolateId, - mainScript, - breakPointId, - body, - ); - - getInstance(frame, expression) => - testInspector.getInstance(isolateId, frame, expression); - - getObject(instanceId) => service.getObject(isolateId, instanceId); - - getInstanceRef(frame, expression) => - testInspector.getInstanceRef(isolateId, frame, expression); - - getFields(instanceRef, {offset, count}) => testInspector - .getFields(isolateId, instanceRef, offset: offset, count: count); - - group('$nullSafetyMode |', () { - group('$compilationMode |', () { - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - compilationMode: compilationMode, - enableExpressionEvaluation: true, - verboseCompiler: debug, - experiments: ['records'], - canaryFeatures: canaryFeatures, - ); - 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(context.tearDown); - - setUp(() => setCurrentLogWriter(debug: debug)); - tearDown(() => service.resume(isolateId)); - - group('Object |', () { - test('type and fields', () async { - await onBreakPoint('printFieldMain', (event) async { - final frame = event.topFrame!.index!; - final instanceRef = await getInstanceRef(frame, 'instance'); - - final instanceId = instanceRef.id!; - expect( - await getObject(instanceId), - matchPlainInstance( - libraryId: 'org-dartlang-app:///web/main.dart', - type: 'MainClass', - ), - ); - - expect(await getFields(instanceRef), {'_field': 1, 'field': 2}); - - // Offsets and counts are ignored for plain object fields. - - // DevTools calls [VmServiceInterface.getObject] with offset=0 - // and count=0 and expects all fields to be returned. - expect( - await getFields(instanceRef, offset: 0, count: 0), - {'_field': 1, 'field': 2}, - ); - expect( - await getFields(instanceRef, offset: 0), - {'_field': 1, 'field': 2}, - ); - expect( - await getFields(instanceRef, offset: 0, count: 1), - {'_field': 1, 'field': 2}, - ); - expect( - await getFields(instanceRef, offset: 1), - {'_field': 1, 'field': 2}, - ); - expect( - await getFields(instanceRef, offset: 1, count: 0), - {'_field': 1, 'field': 2}, - ); - expect( - await getFields(instanceRef, offset: 1, count: 3), - {'_field': 1, 'field': 2}, - ); - }); - }); - - test('field access', () async { - await onBreakPoint('printFieldMain', (event) async { - final frame = event.topFrame!.index!; - expect( - await getInstance(frame, r'instance.field'), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 2), - ); - - expect( - await getInstance(frame, r'instance._field'), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), - ); - }); - }); - }); - - group('List |', () { - test('type and fields', () async { - await onBreakPoint('printList', (event) async { - final frame = event.topFrame!.index!; - final instanceRef = await getInstanceRef(frame, 'list'); - - final instanceId = instanceRef.id!; - expect( - await getObject(instanceId), - matchListInstance(type: matchListClassName('int')), - ); - - expect(await getFields(instanceRef), [0, 1, 2]); - expect(await getFields(instanceRef, offset: 1, count: 0), []); - expect(await getFields(instanceRef, offset: 0), [0, 1, 2]); - expect(await getFields(instanceRef, offset: 0, count: 1), [0]); - expect(await getFields(instanceRef, offset: 1), [1, 2]); - expect(await getFields(instanceRef, offset: 1, count: 1), [1]); - expect(await getFields(instanceRef, offset: 1, count: 3), [1, 2]); - expect(await getFields(instanceRef, offset: 3, count: 3), []); - }); - }); - - test('Element access', () async { - await onBreakPoint('printList', (event) async { - final frame = event.topFrame!.index!; - expect( - await getInstance(frame, r'list[0]'), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 0), - ); - - expect( - await getInstance(frame, r"list[1]"), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), - ); - - expect( - await getInstance(frame, r"list[2]"), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 2), - ); - }); - }); - }); - - group('Map |', () { - test('type and fields', () async { - await onBreakPoint('printMap', (event) async { - final frame = event.topFrame!.index!; - final instanceRef = await getInstanceRef(frame, 'map'); - - final instanceId = instanceRef.id!; - expect( - await getObject(instanceId), - matchMapInstance(type: 'IdentityMap'), - ); - - expect(await getFields(instanceRef), {'a': 1, 'b': 2, 'c': 3}); - - expect(await getFields(instanceRef, offset: 1, count: 0), {}); - expect( - await getFields(instanceRef, offset: 0), - {'a': 1, 'b': 2, 'c': 3}, - ); - expect(await getFields(instanceRef, offset: 0, count: 1), {'a': 1}); - expect(await getFields(instanceRef, offset: 1), {'b': 2, 'c': 3}); - expect(await getFields(instanceRef, offset: 1, count: 1), {'b': 2}); - expect( - await getFields(instanceRef, offset: 1, count: 3), - {'b': 2, 'c': 3}, - ); - expect(await getFields(instanceRef, offset: 3, count: 3), {}); - }); - }); - - test('Element access', () async { - await onBreakPoint('printMap', (event) async { - final frame = event.topFrame!.index!; - expect( - await getInstance(frame, r"map['a']"), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), - ); - - expect( - await getInstance(frame, r"map['b']"), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 2), - ); - - expect( - await getInstance(frame, r"map['c']"), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 3), - ); - }); - }); - }); - - group('Set |', () { - test('type and fields', () async { - await onBreakPoint('printSet', (event) async { - final frame = event.topFrame!.index!; - final instanceRef = await getInstanceRef(frame, 'mySet'); - - final instanceId = instanceRef.id!; - expect( - await getObject(instanceId), - matchSetInstance(type: '_HashSet'), - ); - - expect(await getFields(instanceRef), [1, 4, 5, 7]); - expect(await getFields(instanceRef, offset: 0), [1, 4, 5, 7]); - expect(await getFields(instanceRef, offset: 1, count: 2), [4, 5]); - expect(await getFields(instanceRef, offset: 2), [5, 7]); - expect(await getFields(instanceRef, offset: 2, count: 10), [5, 7]); - expect(await getFields(instanceRef, offset: 1, count: 0), []); - expect(await getFields(instanceRef, offset: 10, count: 2), []); - }); - }); - - test('Element access', () async { - await onBreakPoint('printSet', (event) async { - final frame = event.topFrame!.index!; - expect( - await getInstance(frame, r"mySet.first"), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 1), - ); - expect( - await getInstance(frame, r"mySet.last"), - matchPrimitiveInstance(kind: InstanceKind.kDouble, value: 7), - ); - }); - }); - }); - }); - }); -} diff --git a/dwds/test/instances/patterns_inspection_test.dart b/dwds/test/instances/patterns_inspection_test.dart index 29692aa24..7dc5cef48 100644 --- a/dwds/test/instances/patterns_inspection_test.dart +++ b/dwds/test/instances/patterns_inspection_test.dart @@ -13,7 +13,7 @@ import 'package:vm_service/vm_service.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; -import 'instance_inspection_common.dart'; +import 'test_inspector.dart'; void main() { // Enable verbose logging for debugging. diff --git a/dwds/test/instances/record_inspection_test.dart b/dwds/test/instances/record_inspection_test.dart index 7d8321c91..12d8e99b2 100644 --- a/dwds/test/instances/record_inspection_test.dart +++ b/dwds/test/instances/record_inspection_test.dart @@ -13,7 +13,7 @@ import 'package:vm_service/vm_service.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; -import 'instance_inspection_common.dart'; +import 'test_inspector.dart'; void main() { // Enable verbose logging for debugging. diff --git a/dwds/test/instances/record_type_inspection_test.dart b/dwds/test/instances/record_type_inspection_test.dart index 081fa5907..95b01fff4 100644 --- a/dwds/test/instances/record_type_inspection_test.dart +++ b/dwds/test/instances/record_type_inspection_test.dart @@ -13,7 +13,7 @@ import 'package:vm_service/vm_service.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; -import 'instance_inspection_common.dart'; +import 'test_inspector.dart'; void main() { // Enable verbose logging for debugging. diff --git a/dwds/test/instances/test_inspector.dart b/dwds/test/instances/test_inspector.dart new file mode 100644 index 000000000..c1f9cbcd9 --- /dev/null +++ b/dwds/test/instances/test_inspector.dart @@ -0,0 +1,351 @@ +// Copyright (c) 2020, 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. + +@TestOn('vm') +@Timeout(Duration(minutes: 2)) + +import 'package:test/test.dart'; +import 'package:vm_service/vm_service.dart'; + +import '../fixtures/context.dart'; + +class TestInspector { + TestInspector(this.context); + TestContext context; + + VmServiceInterface get service => context.debugConnection.vmService; + + Future onBreakPoint( + Stream stream, + String isolateId, + ScriptRef script, + String breakPointId, + Future Function(Event event) body, + ) async { + Breakpoint? bp; + try { + final line = + await context.findBreakpointLine(breakPointId, isolateId, script); + bp = await service.addBreakpointWithScriptUri( + isolateId, + script.uri!, + line, + ); + + final event = + await stream.firstWhere((e) => e.kind == EventKind.kPauseBreakpoint); + + await body(event); + } finally { + // Remove breakpoint so it doesn't impact other tests or retries. + if (bp != null) { + await service.removeBreakpoint(isolateId, bp.id!); + } + } + } + + Future getFields( + String isolateId, + InstanceRef instanceRef, { + int? offset, + int? count, + int depth = -1, + }) async { + final instanceId = instanceRef.id!; + + final result = await service.getObject( + isolateId, + instanceId, + offset: offset, + count: count, + ); + + expect(result, isA()); + final instance = result as Instance; + + expect( + instance.kind, + instanceRef.kind, + reason: 'object $instanceId with ref kind ${instanceRef.kind} ' + 'has an instance kind ${instance.kind}', + ); + + final fields = instance.fields; + final associations = instance.associations; + final elements = instance.elements; + + Map? fieldRefs; + if (fields != null) { + fieldRefs = _boundFieldsToMap(fields); + } else if (associations != null) { + fieldRefs = _associationsToMap(associations); + } else if (elements != null) { + fieldRefs = _elementsToMap(elements); + } else { + fieldRefs = {}; + } + + if (depth > 0) { + depth--; + } + if (depth == 0) { + return elements == null ? fieldRefs : fieldRefs.values.toList(); + } + + final fieldValues = {}; + for (var p in fieldRefs.entries) { + fieldValues[p.key] = _getValue(p.value) ?? + await getFields( + isolateId, + p.value, + depth: depth, + ); + } + return elements == null ? fieldValues : fieldValues.values.toList(); + } + + Future getInstanceRef( + String isolateId, + int frame, + String expression, + ) async { + final result = await service.evaluateInFrame( + isolateId, + frame, + expression, + ); + expect(result, isA()); + return result as InstanceRef; + } + + Future getInstance( + String isolateId, + int frame, + String expression, + ) async { + final instanceRef = await getInstanceRef( + isolateId, + frame, + expression, + ); + + expect(instanceRef.id, isNotNull); + final result = await service.getObject( + isolateId, + instanceRef.id!, + ); + + expect(result, isA()); + return result as Instance; + } + + Future> getFrameVariables( + String isolateId, + Frame frame, + ) async { + final refs = { + for (var variable in frame.vars!) + variable.name!: variable.value as InstanceRef, + }; + final instances = {}; + for (final p in refs.entries) { + instances[p.key] = + await service.getObject(isolateId, p.value.id!) as Instance; + } + return instances; + } + + Future getDisplayedRef( + String isolateId, + String instanceId, + ) async => + await service.invoke(isolateId, instanceId, 'toString', []) + as InstanceRef; + + Future> getDisplayedFields( + String isolateId, + InstanceRef ref, + ) async { + final fieldRefs = + await getFields(isolateId, ref, depth: 1) as Map; + + Future toStringValue(InstanceRef ref) async => + ref.valueAsString ?? + (await getDisplayedRef(isolateId, ref.id!)).valueAsString; + + final fields = await Future.wait(fieldRefs.values.map(toStringValue)); + return fields.toList(); + } + + Future> getElements( + String isolateId, + String instanceId, + ) async { + final instance = await service.getObject(isolateId, instanceId) as Instance; + return Future.wait( + instance.fields!.map( + (e) async => await service.getObject( + isolateId, + (e.value as InstanceRef).id!, + ) as Instance, + ), + ); + } +} + +Map _associationsToMap( + Iterable associations, +) => + Map.fromEntries( + associations.map((e) => MapEntry(e.key.valueAsString, e.value)), + ); + +Map _boundFieldsToMap(Iterable fields) => + Map.fromEntries( + fields.where((e) => e.name != null).map((e) => MapEntry(e.name, e.value)), + ); + +Map _elementsToMap(List fields) => + Map.fromEntries( + fields + .where((e) => e != null) + .map((e) => MapEntry(fields.indexOf(e), e!)), + ); + +Matcher matchRecordInstanceRef({required int length}) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kRecord) + .having((e) => e.length, 'length', length) + .having((e) => e.classRef!, 'classRef', matchRecordClassRef); + +Matcher matchRecordTypeInstanceRef({required int length}) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kRecordType) + .having((e) => e.length, 'length', length) + .having((e) => e.classRef!, 'classRef', matchRecordTypeClassRef); + +Matcher matchTypeInstanceRef(dynamic name) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kType) + .having((e) => e.name, 'type ref name', name) + .having((e) => e.classRef, 'classRef', matchTypeClassRef); + +Matcher matchPrimitiveInstanceRef({ + required String kind, +}) => + isA().having((e) => e.kind, 'kind', kind); + +Matcher matchPrimitiveInstance({ + required String kind, + required dynamic value, +}) => + isA() + .having((e) => e.kind, 'kind', kind) + .having(_getValue, 'value', value); + +Matcher matchPlainInstance({required libraryId, required String type}) => + isA() + .having((e) => e.kind, 'kind', InstanceKind.kPlainInstance) + .having( + (e) => e.classRef, + 'classRef', + matchClassRef(name: type, libraryId: libraryId), + ); + +Matcher matchListInstance({required dynamic type}) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kList) + .having((e) => e.classRef, 'classRef', matchListClassRef(type)); + +Matcher matchMapInstance({required String type}) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kMap) + .having((e) => e.classRef, 'classRef', matchMapClassRef(type)); + +Matcher matchSetInstance({required String type}) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kSet) + .having((e) => e.classRef, 'classRef', matchSetClassRef(type)); + +Matcher matchRecordInstance({required int length}) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kRecord) + .having((e) => e.length, 'length', length) + .having((e) => e.classRef, 'classRef', matchRecordClassRef); + +Matcher matchRecordTypeInstance({required int length}) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kRecordType) + .having((e) => e.length, 'length', length) + .having((e) => e.classRef, 'classRef', matchRecordTypeClassRef); + +Matcher matchTypeStringInstance(dynamic name) => + matchPrimitiveInstance(kind: InstanceKind.kString, value: name); + +Matcher matchTypeInstance(dynamic name) => isA() + .having((e) => e.kind, 'kind', InstanceKind.kType) + .having((e) => e.name, 'type name', name) + .having((e) => e.classRef, 'classRef', matchTypeClassRef); + +Matcher matchRecordClass = + matchClass(name: matchRecordClassName, libraryId: _dartCoreLibrary); +Matcher matchRecordTypeClass = + matchClass(name: matchRecordTypeClassName, libraryId: _dartRuntimeLibrary); +Matcher matchTypeClass = + matchClass(name: matchTypeClassName, libraryId: _dartCoreLibrary); + +Matcher matchClass({dynamic name, String? libraryId}) => isA() + .having((e) => e.name, 'class name', name) + .having((e) => e.library, 'library', matchLibraryRef(libraryId)); + +Matcher matchRecordClassRef = + matchClassRef(name: matchRecordClassName, libraryId: _dartCoreLibrary); +Matcher matchRecordTypeClassRef = matchClassRef( + name: matchRecordTypeClassName, + libraryId: _dartRuntimeLibrary, +); +Matcher matchTypeClassRef = + matchClassRef(name: matchTypeClassName, libraryId: _dartCoreLibrary); +Matcher matchListClassRef(dynamic type) => + matchClassRef(name: type, libraryId: _matchListLibraryName); +Matcher matchMapClassRef(String type) => + matchClassRef(name: type, libraryId: _dartJsHelperLibrary); +Matcher matchSetClassRef(String type) => + matchClassRef(name: type, libraryId: _dartCollectionLibrary); + +Matcher matchClassRef({dynamic name, dynamic libraryId}) => isA() + .having((e) => e.name, 'class ref name', name) + .having((e) => e.library, 'library', matchLibraryRef(libraryId)); + +Matcher matchLibraryRef(dynamic libraryId) => isA() + .having((e) => e.name, 'library name', libraryId) + .having((e) => e.id, 'id', libraryId) + .having((e) => e.uri, 'uri', libraryId); + +Object? _getValue(InstanceRef instanceRef) { + switch (instanceRef.kind) { + case InstanceKind.kBool: + return instanceRef.valueAsString == 'true'; + case InstanceKind.kDouble: + case InstanceKind.kInt: + return double.parse(instanceRef.valueAsString!); + case InstanceKind.kString: + return instanceRef.valueAsString; + default: + return null; + } +} + +final _dartCoreLibrary = 'dart:core'; +final _dartRuntimeLibrary = 'dart:_runtime'; +final _dartInterceptorsLibrary = 'dart:_interceptors'; +final _dartJsHelperLibrary = 'dart:_js_helper'; +final _dartCollectionLibrary = 'dart:collection'; + +final matchRecordClassName = 'Record'; +final matchRecordTypeClassName = 'RecordType'; + +/// Match types for old and new type systems. +/// - Old type system has `dart:core|List` and `dart:_runtime|_Type`. +/// - New type system has `dart:_interceptors|JSArray` and `dart:core|Type`. +/// TODO(annagrin): update when DDC enables new type system. +final matchTypeClassName = anyOf(['Type', '_Type']); + +Matcher matchListClassName(String elementType) => + anyOf(['JSArray<$elementType>', 'List<$elementType>']); + +final _matchListLibraryName = + anyOf([_dartInterceptorsLibrary, _dartCoreLibrary]); diff --git a/dwds/test/instances/type_inspection_test.dart b/dwds/test/instances/type_inspection_test.dart index ac146302f..7306d6775 100644 --- a/dwds/test/instances/type_inspection_test.dart +++ b/dwds/test/instances/type_inspection_test.dart @@ -13,7 +13,7 @@ import 'package:vm_service/vm_service.dart'; import '../fixtures/context.dart'; import '../fixtures/project.dart'; -import 'instance_inspection_common.dart'; +import 'test_inspector.dart'; void main() { // Enable verbose logging for debugging. diff --git a/fixtures/_webdevSoundSmoke/build.yaml b/fixtures/_webdevSoundSmoke/build.yaml index 1f4374a04..797d391ad 100644 --- a/fixtures/_webdevSoundSmoke/build.yaml +++ b/fixtures/_webdevSoundSmoke/build.yaml @@ -1,7 +1,7 @@ -# global_options: -# build_web_compilers:ddc: -# options: -# canary: false -# build_web_compilers:sdk_js: -# options: -# canary: false \ No newline at end of file +global_options: + build_web_compilers:ddc: + options: + canary: true + build_web_compilers:sdk_js: + options: + canary: true \ No newline at end of file diff --git a/fixtures/_webdevSoundSmoke/web/main.dart b/fixtures/_webdevSoundSmoke/web/main.dart index 9e50e52a7..ba446532f 100644 --- a/fixtures/_webdevSoundSmoke/web/main.dart +++ b/fixtures/_webdevSoundSmoke/web/main.dart @@ -20,29 +20,25 @@ void main() { Timer.periodic(const Duration(seconds: 1), (_) { print('Counter is: ${++count}'); // Breakpoint: printCounter - var m = Mine(0); - print(m.x2); - print(m); + var b = B(); + print(b); var x = () => true; print(x); }); } -class Mine extends A { - static int y = 0; - int x; - int _x = 15; +class A { + int _x1 = 0; + int x2 = 1; +} - //late final x3 = 14; +class B extends A { + int x3 = 2; + int get x4 => x3; - int get x2 => x; - Mine(this.x); -} + int f() => 0; + static int sf() => 1; -class A { - int x1 = 1; - void foo() { - print('foo'); - } + int Function() f2 = sf; } From 7eb5144a72c7901c50b7a47f5b02ede6b6dc416c Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Wed, 19 Jul 2023 12:52:28 -0700 Subject: [PATCH 12/24] Cleanup --- dwds/lib/src/debugging/classes.dart | 8 +++---- dwds/test/chrome_proxy_service_test.dart | 8 +++---- dwds/test/instances/instance_common.dart | 3 ++- fixtures/_testSound/pubspec.yaml | 4 ---- .../{build.yaml => canary_build.yaml} | 4 ++-- fixtures/_webdevSoundSmoke/web/main.dart | 21 ------------------- .../lib/src/asset_server.dart | 2 -- webdev/lib/src/serve/webdev_server.dart | 2 +- 8 files changed, 12 insertions(+), 40 deletions(-) rename fixtures/_webdevSoundSmoke/{build.yaml => canary_build.yaml} (71%) diff --git a/dwds/lib/src/debugging/classes.dart b/dwds/lib/src/debugging/classes.dart index a00e55d74..8154b7ee5 100644 --- a/dwds/lib/src/debugging/classes.dart +++ b/dwds/lib/src/debugging/classes.dart @@ -7,14 +7,11 @@ import 'package:dwds/src/loaders/strategy.dart'; import 'package:dwds/src/services/chrome_debug_exception.dart'; import 'package:dwds/src/utilities/domain.dart'; import 'package:dwds/src/utilities/shared.dart'; -import 'package:logging/logging.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; /// Keeps track of Dart classes available in the running application. class ClassHelper extends Domain { - final _logger = Logger('ClassHelper'); - /// Map of class ID to [Class]. final _classes = {}; @@ -79,7 +76,6 @@ class ClassHelper extends Domain { final classId = classRef.id; if (libraryUri == null || classId == null || className == null) return null; - _logger.severe('Constructing class: $className, library: $libraryUri'); final expression = ''' (function() { @@ -101,7 +97,6 @@ class ClassHelper extends Domain { } final classDescriptor = result.value as Map; - _logger.severe('Class descriptor for $className: $classDescriptor'); final methodRefs = []; final methodDescriptors = classDescriptor['methods'] as Map; @@ -115,6 +110,9 @@ class ClassHelper extends Domain { isConst: descriptor['isConst'] as bool? ?? false, isStatic: descriptor['isStatic'] as bool? ?? false, implicit: descriptor['isImplicit'] as bool? ?? false, + isAbstract: descriptor['isAbstract'] as bool? ?? false, + isGetter: descriptor['isGetter'] as bool? ?? false, + isSetter: descriptor['isSetter'] as bool? ?? false, ), ); }); diff --git a/dwds/test/chrome_proxy_service_test.dart b/dwds/test/chrome_proxy_service_test.dart index 1065f21e5..de89b2d1f 100644 --- a/dwds/test/chrome_proxy_service_test.dart +++ b/dwds/test/chrome_proxy_service_test.dart @@ -39,7 +39,7 @@ void main() { await context.setUp( enableExpressionEvaluation: true, verboseCompiler: false, - canaryFeatures: false, + canaryFeatures: true, ); }); @@ -613,7 +613,7 @@ void main() { f.declaredType != null && !f.isStatic! && !f.isConst! && - !f.isFinal!, + f.isFinal!, ), predicate( (FieldRef f) => @@ -1094,7 +1094,7 @@ void main() { f.declaredType != null && !f.isStatic! && !f.isConst! && - !f.isFinal!, + f.isFinal!, ), predicate( (FieldRef f) => @@ -1142,7 +1142,7 @@ void main() { f.declaredType != null && !f.isStatic! && !f.isConst! && - !f.isFinal!, + f.isFinal!, ), predicate( (FieldRef f) => diff --git a/dwds/test/instances/instance_common.dart b/dwds/test/instances/instance_common.dart index 346617499..cd5b97696 100644 --- a/dwds/test/instances/instance_common.dart +++ b/dwds/test/instances/instance_common.dart @@ -72,7 +72,8 @@ void runTests({ /// A reference to the the variable `libraryPublicFinal`, an instance of /// `MyTestClass`. Future libraryPublicFinal( - CompilationMode compilationMode) => + CompilationMode compilationMode, + ) => inspector.jsEvaluate( libraryVariableExpression('libraryPublicFinal', compilationMode), ); diff --git a/fixtures/_testSound/pubspec.yaml b/fixtures/_testSound/pubspec.yaml index 61fc5c93e..677a9e4f3 100644 --- a/fixtures/_testSound/pubspec.yaml +++ b/fixtures/_testSound/pubspec.yaml @@ -15,7 +15,3 @@ dev_dependencies: build_runner: ^2.4.0 build_web_compilers: ^4.0.4 -dependency_overrides: - build_web_compilers: - path: ../../../build/build_web_compilers - diff --git a/fixtures/_webdevSoundSmoke/build.yaml b/fixtures/_webdevSoundSmoke/canary_build.yaml similarity index 71% rename from fixtures/_webdevSoundSmoke/build.yaml rename to fixtures/_webdevSoundSmoke/canary_build.yaml index 797d391ad..7c766235d 100644 --- a/fixtures/_webdevSoundSmoke/build.yaml +++ b/fixtures/_webdevSoundSmoke/canary_build.yaml @@ -1,7 +1,7 @@ global_options: build_web_compilers:ddc: options: - canary: true + canary: false build_web_compilers:sdk_js: options: - canary: true \ No newline at end of file + canary: false \ No newline at end of file diff --git a/fixtures/_webdevSoundSmoke/web/main.dart b/fixtures/_webdevSoundSmoke/web/main.dart index ba446532f..907bfdbba 100644 --- a/fixtures/_webdevSoundSmoke/web/main.dart +++ b/fixtures/_webdevSoundSmoke/web/main.dart @@ -19,26 +19,5 @@ void main() { var count = 0; Timer.periodic(const Duration(seconds: 1), (_) { print('Counter is: ${++count}'); // Breakpoint: printCounter - - var b = B(); - print(b); - - var x = () => true; - print(x); }); } - -class A { - int _x1 = 0; - int x2 = 1; -} - -class B extends A { - int x3 = 2; - int get x4 => x3; - - int f() => 0; - static int sf() => 1; - - int Function() f2 = sf; -} diff --git a/frontend_server_common/lib/src/asset_server.dart b/frontend_server_common/lib/src/asset_server.dart index f484efc8c..784e634f9 100644 --- a/frontend_server_common/lib/src/asset_server.dart +++ b/frontend_server_common/lib/src/asset_server.dart @@ -103,8 +103,6 @@ class TestAssetServer implements AssetReader { return shelf.Response.notFound(''); } - // TODO: main.dart.js is sometimes requested as scopes/main.dart.js - update the request url so we can find it. - // If this is a JavaScript file, it must be in the in-memory cache. // Attempt to look up the file by URI. if (hasFile(requestPath)) { diff --git a/webdev/lib/src/serve/webdev_server.dart b/webdev/lib/src/serve/webdev_server.dart index 0f6ffa6df..b4ef287a1 100644 --- a/webdev/lib/src/serve/webdev_server.dart +++ b/webdev/lib/src/serve/webdev_server.dart @@ -138,8 +138,8 @@ class WebDevServer { options.port, verbose: options.configuration.verbose, experiments: options.configuration.experiments, - canaryFeatures: options.configuration.canaryFeatures, sdkConfigurationProvider: const DefaultSdkConfigurationProvider(), + canaryFeatures: options.configuration.canaryFeatures, ); } var shouldServeDevTools = From a8d3437e5c8c92d88cdada0e667b7ca58d97c757 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Wed, 19 Jul 2023 12:59:54 -0700 Subject: [PATCH 13/24] Cleanup --- dwds/test/instances/type_inspection_test.dart | 3 +-- fixtures/_webdevSoundSmoke/canary_build.yaml | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dwds/test/instances/type_inspection_test.dart b/dwds/test/instances/type_inspection_test.dart index 7306d6775..1544368ee 100644 --- a/dwds/test/instances/type_inspection_test.dart +++ b/dwds/test/instances/type_inspection_test.dart @@ -138,8 +138,7 @@ void _runTests({ final classId = instanceRef.classRef!.id; expect(await getObject(classId), matchTypeClass); - final fields = await getFields(instanceRef, depth: 1); - expect(fields, matchTypeObject); + expect(await getFields(instanceRef, depth: 1), matchTypeObject); expect(await getDisplayedFields(instanceRef), matchDisplayedTypeObject); }); }); diff --git a/fixtures/_webdevSoundSmoke/canary_build.yaml b/fixtures/_webdevSoundSmoke/canary_build.yaml index 7c766235d..5b9378c37 100644 --- a/fixtures/_webdevSoundSmoke/canary_build.yaml +++ b/fixtures/_webdevSoundSmoke/canary_build.yaml @@ -4,4 +4,4 @@ global_options: canary: false build_web_compilers:sdk_js: options: - canary: false \ No newline at end of file + canary: false From ec28d0550de506041cbff8caa303d94b27d73333 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Fri, 21 Jul 2023 09:59:42 -0700 Subject: [PATCH 14/24] Cleanup --- .../instances/common/instance_common.dart | 638 +++++++++--------- fixtures/_webdevSoundSmoke/web/main.dart | 75 +- 2 files changed, 320 insertions(+), 393 deletions(-) diff --git a/dwds/test/instances/common/instance_common.dart b/dwds/test/instances/common/instance_common.dart index bdfbf305e..2d18ba6c3 100644 --- a/dwds/test/instances/common/instance_common.dart +++ b/dwds/test/instances/common/instance_common.dart @@ -20,333 +20,331 @@ void runTests({ required bool canaryFeatures, required bool debug, }) { - group('canaryFeatures: $canaryFeatures |', () { - final project = TestProject.testScopesWithSoundNullSafety; - final context = TestContext(project, provider); - - late AppInspector inspector; - - group('$compilationMode |', () { - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - compilationMode: compilationMode, - canaryFeatures: canaryFeatures, + final project = TestProject.testScopesWithSoundNullSafety; + final context = TestContext(project, provider); + + late AppInspector inspector; + + group('$compilationMode |', () { + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + ); + final chromeProxyService = context.service; + inspector = chromeProxyService.inspector; + }); + + tearDownAll(() async { + await context.tearDown(); + }); + + final url = 'org-dartlang-app:///example/scopes/main.dart'; + + String libraryName(CompilationMode compilationMode) => + compilationMode == CompilationMode.frontendServer + ? "example/scopes/main.dart" + : "example/scopes/main"; + + String libraryVariableExpression( + String variable, + CompilationMode compilationMode, + ) => + '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.' + 'getModuleLibraries("${libraryName(compilationMode)}")' + '["$url"]["$variable"];'; + + String newInterceptorsExpression(String type) => + 'new (require("dart_sdk")._interceptors.$type).new()'; + + final String newDartError = 'new (require("dart_sdk").dart).DartError'; + + /// A reference to the the variable `libraryPublicFinal`, an instance of + /// `MyTestClass`. + Future libraryPublicFinal( + CompilationMode compilationMode, + ) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublicFinal', compilationMode), + ); + + /// A reference to the the variable `libraryPublic`, a List of Strings. + Future libraryPublic(CompilationMode compilationMode) => + inspector.jsEvaluate( + libraryVariableExpression('libraryPublic', compilationMode), + ); + + group('instanceRef', () { + setUp(() => setCurrentLogWriter(debug: debug)); + + test('for a null', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final nullVariable = + await inspector.loadField(remoteObject, 'notFinal'); + final ref = await inspector.instanceRefFor(nullVariable); + expect(ref!.valueAsString, 'null'); + expect(ref.kind, InstanceKind.kNull); + final classRef = ref.classRef!; + expect(classRef.name, 'Null'); + expect(classRef.id, 'classes|dart:core|Null'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a double', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'count'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.valueAsString, '0'); + expect(ref.kind, InstanceKind.kDouble); + final classRef = ref.classRef!; + expect(classRef.name, 'Double'); + expect(classRef.id, 'classes|dart:core|Double'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for an object', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final count = await inspector.loadField(remoteObject, 'myselfField'); + final ref = await inspector.instanceRefFor(count); + expect(ref!.kind, InstanceKind.kPlainInstance); + final classRef = ref.classRef!; + expect(classRef.name, 'MyTestClass'); + expect( + classRef.id, + 'classes|org-dartlang-app:///example/scopes/main.dart' + '|MyTestClass'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final ref = await inspector.instanceRefFor(closure.value!); + final functionName = ref!.closureFunction!.name; + // Older SDKs do not contain function names + if (functionName != 'Closure') { + expect(functionName, 'someFunction'); + } + expect(ref.kind, InstanceKind.kClosure); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a list', () async { + final remoteObject = await libraryPublic(compilationMode); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, greaterThan(0)); + expect(ref.kind, InstanceKind.kList); + expect(ref.classRef!.name, matchListClassName('String')); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for map', () async { + final remoteObject = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'LinkedMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for an IdentityMap', () async { + final remoteObject = await inspector.jsEvaluate( + libraryVariableExpression('identityMap', compilationMode), + ); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.length, 2); + expect(ref.kind, InstanceKind.kMap); + expect(ref.classRef!.name, 'IdentityMap'); + expect(inspector.isDisplayableObject(ref), isTrue); + }); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isTrue); + expect(inspector.isNativeJsObject(ref), isFalse); + }); + + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final ref = await inspector.instanceRefFor(remoteObject); + expect(ref!.kind, InstanceKind.kPlainInstance); + expect(ref.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(ref), isFalse); + expect(inspector.isNativeJsError(ref), isFalse); + expect(inspector.isNativeJsObject(ref), isTrue); + }); + }); + + group('instance', () { + setUp(() => setCurrentLogWriter(debug: debug)); + test('for an object', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + final boundFieldNames = instance.fields! + .map((boundField) => boundField.decl!.name) + .toList(); + expect(boundFieldNames, [ + '_privateField', + 'abstractField', + 'closure', + 'count', + 'message', + 'myselfField', + 'notFinal', + 'tornOff', + ]); + final fieldNames = + instance.fields!.map((boundField) => boundField.name).toList(); + expect(boundFieldNames, fieldNames); + for (var field in instance.fields!) { + expect(field.name, isNotNull); + expect(field.decl!.declaredType, isNotNull); + } + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for closure', () async { + final remoteObject = await libraryPublicFinal(compilationMode); + final properties = + await inspector.getProperties(remoteObject.objectId!); + final closure = + properties.firstWhere((property) => property.name == 'closure'); + final instance = await inspector.instanceFor(closure.value!); + expect(instance!.kind, InstanceKind.kClosure); + expect(instance.classRef!.name, 'Closure'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for a nested object', () async { + final libraryRemoteObject = await libraryPublicFinal(compilationMode); + final fieldRemoteObject = + await inspector.loadField(libraryRemoteObject, 'myselfField'); + final instance = await inspector.instanceFor(fieldRemoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, 'MyTestClass'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for a list', () async { + final remote = await libraryPublic(compilationMode); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kList); + final classRef = instance.classRef!; + expect(classRef, isNotNull); + expect(classRef.name, matchListClassName('String')); + final first = instance.elements![0]; + expect(first.valueAsString, 'library'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for a map', () async { + final remote = await inspector + .jsEvaluate(libraryVariableExpression('map', compilationMode)); + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; + expect(classRef.name, 'LinkedMap'); + final first = instance.associations![0].value as InstanceRef; + expect(first.kind, InstanceKind.kList); + expect(first.length, 3); + final second = instance.associations![1].value as InstanceRef; + expect(second.kind, InstanceKind.kString); + expect(second.valueAsString, 'something'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for an identityMap', () async { + final remote = await inspector.jsEvaluate( + libraryVariableExpression('identityMap', compilationMode), ); - final chromeProxyService = context.service; - inspector = chromeProxyService.inspector; + final instance = await inspector.instanceFor(remote); + expect(instance!.kind, InstanceKind.kMap); + final classRef = instance.classRef!; + expect(classRef.name, 'IdentityMap'); + final first = instance.associations![0].value; + expect(first.valueAsString, '1'); + expect(inspector.isDisplayableObject(instance), isTrue); + }); + + test('for a Dart error', () async { + final remoteObject = await inspector.jsEvaluate(newDartError); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); }); - tearDownAll(() async { - await context.tearDown(); + test('for a native JavaScript error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('NativeError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'NativeError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); }); - final url = 'org-dartlang-app:///example/scopes/main.dart'; - - String libraryName(CompilationMode compilationMode) => - compilationMode == CompilationMode.frontendServer - ? "example/scopes/main.dart" - : "example/scopes/main"; - - String libraryVariableExpression( - String variable, - CompilationMode compilationMode, - ) => - '${globalLoadStrategy.loadModuleSnippet}("dart_sdk").dart.' - 'getModuleLibraries("${libraryName(compilationMode)}")' - '["$url"]["$variable"];'; - - String newInterceptorsExpression(String type) => - 'new (require("dart_sdk")._interceptors.$type).new()'; - - final String newDartError = 'new (require("dart_sdk").dart).DartError'; - - /// A reference to the the variable `libraryPublicFinal`, an instance of - /// `MyTestClass`. - Future libraryPublicFinal( - CompilationMode compilationMode, - ) => - inspector.jsEvaluate( - libraryVariableExpression('libraryPublicFinal', compilationMode), - ); - - /// A reference to the the variable `libraryPublic`, a List of Strings. - Future libraryPublic(CompilationMode compilationMode) => - inspector.jsEvaluate( - libraryVariableExpression('libraryPublic', compilationMode), - ); - - group('instanceRef', () { - setUp(() => setCurrentLogWriter(debug: debug)); - - test('for a null', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final nullVariable = - await inspector.loadField(remoteObject, 'notFinal'); - final ref = await inspector.instanceRefFor(nullVariable); - expect(ref!.valueAsString, 'null'); - expect(ref.kind, InstanceKind.kNull); - final classRef = ref.classRef!; - expect(classRef.name, 'Null'); - expect(classRef.id, 'classes|dart:core|Null'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a double', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final count = await inspector.loadField(remoteObject, 'count'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.valueAsString, '0'); - expect(ref.kind, InstanceKind.kDouble); - final classRef = ref.classRef!; - expect(classRef.name, 'Double'); - expect(classRef.id, 'classes|dart:core|Double'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for an object', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final count = await inspector.loadField(remoteObject, 'myselfField'); - final ref = await inspector.instanceRefFor(count); - expect(ref!.kind, InstanceKind.kPlainInstance); - final classRef = ref.classRef!; - expect(classRef.name, 'MyTestClass'); - expect( - classRef.id, - 'classes|org-dartlang-app:///example/scopes/main.dart' - '|MyTestClass'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a closure', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final properties = - await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final ref = await inspector.instanceRefFor(closure.value!); - final functionName = ref!.closureFunction!.name; - // Older SDKs do not contain function names - if (functionName != 'Closure') { - expect(functionName, 'someFunction'); - } - expect(ref.kind, InstanceKind.kClosure); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a list', () async { - final remoteObject = await libraryPublic(compilationMode); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, greaterThan(0)); - expect(ref.kind, InstanceKind.kList); - expect(ref.classRef!.name, matchListClassName('String')); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for map', () async { - final remoteObject = await inspector - .jsEvaluate(libraryVariableExpression('map', compilationMode)); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'LinkedMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for an IdentityMap', () async { - final remoteObject = await inspector.jsEvaluate( - libraryVariableExpression('identityMap', compilationMode), - ); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.length, 2); - expect(ref.kind, InstanceKind.kMap); - expect(ref.classRef!.name, 'IdentityMap'); - expect(inspector.isDisplayableObject(ref), isTrue); - }); - - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('NativeError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isTrue); - expect(inspector.isNativeJsObject(ref), isFalse); - }); - - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final ref = await inspector.instanceRefFor(remoteObject); - expect(ref!.kind, InstanceKind.kPlainInstance); - expect(ref.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(ref), isFalse); - expect(inspector.isNativeJsError(ref), isFalse); - expect(inspector.isNativeJsObject(ref), isTrue); - }); + test('for a native JavaScript type error', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'JSNoSuchMethodError'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isTrue); + expect(inspector.isNativeJsObject(instance), isFalse); }); - group('instance', () { - setUp(() => setCurrentLogWriter(debug: debug)); - test('for an object', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - final boundFieldNames = instance.fields! - .map((boundField) => boundField.decl!.name) - .toList(); - expect(boundFieldNames, [ - '_privateField', - 'abstractField', - 'closure', - 'count', - 'message', - 'myselfField', - 'notFinal', - 'tornOff', - ]); - final fieldNames = - instance.fields!.map((boundField) => boundField.name).toList(); - expect(boundFieldNames, fieldNames); - for (var field in instance.fields!) { - expect(field.name, isNotNull); - expect(field.decl!.declaredType, isNotNull); - } - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for closure', () async { - final remoteObject = await libraryPublicFinal(compilationMode); - final properties = - await inspector.getProperties(remoteObject.objectId!); - final closure = - properties.firstWhere((property) => property.name == 'closure'); - final instance = await inspector.instanceFor(closure.value!); - expect(instance!.kind, InstanceKind.kClosure); - expect(instance.classRef!.name, 'Closure'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a nested object', () async { - final libraryRemoteObject = await libraryPublicFinal(compilationMode); - final fieldRemoteObject = - await inspector.loadField(libraryRemoteObject, 'myselfField'); - final instance = await inspector.instanceFor(fieldRemoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, 'MyTestClass'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a list', () async { - final remote = await libraryPublic(compilationMode); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kList); - final classRef = instance.classRef!; - expect(classRef, isNotNull); - expect(classRef.name, matchListClassName('String')); - final first = instance.elements![0]; - expect(first.valueAsString, 'library'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a map', () async { - final remote = await inspector - .jsEvaluate(libraryVariableExpression('map', compilationMode)); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'LinkedMap'); - final first = instance.associations![0].value as InstanceRef; - expect(first.kind, InstanceKind.kList); - expect(first.length, 3); - final second = instance.associations![1].value as InstanceRef; - expect(second.kind, InstanceKind.kString); - expect(second.valueAsString, 'something'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for an identityMap', () async { - final remote = await inspector.jsEvaluate( - libraryVariableExpression('identityMap', compilationMode), - ); - final instance = await inspector.instanceFor(remote); - expect(instance!.kind, InstanceKind.kMap); - final classRef = instance.classRef!; - expect(classRef.name, 'IdentityMap'); - final first = instance.associations![0].value; - expect(first.valueAsString, '1'); - expect(inspector.isDisplayableObject(instance), isTrue); - }); - - test('for a Dart error', () async { - final remoteObject = await inspector.jsEvaluate(newDartError); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('NativeError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'NativeError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript type error', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('JSNoSuchMethodError')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'JSNoSuchMethodError'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isTrue); - expect(inspector.isNativeJsObject(instance), isFalse); - }); - - test('for a native JavaScript object', () async { - final remoteObject = await inspector - .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); - final instance = await inspector.instanceFor(remoteObject); - expect(instance!.kind, InstanceKind.kPlainInstance); - expect(instance.classRef!.name, 'LegacyJavaScriptObject'); - expect(inspector.isDisplayableObject(instance), isFalse); - expect(inspector.isNativeJsError(instance), isFalse); - expect(inspector.isNativeJsObject(instance), isTrue); - }); + test('for a native JavaScript object', () async { + final remoteObject = await inspector + .jsEvaluate(newInterceptorsExpression('LegacyJavaScriptObject')); + final instance = await inspector.instanceFor(remoteObject); + expect(instance!.kind, InstanceKind.kPlainInstance); + expect(instance.classRef!.name, 'LegacyJavaScriptObject'); + expect(inspector.isDisplayableObject(instance), isFalse); + expect(inspector.isNativeJsError(instance), isFalse); + expect(inspector.isNativeJsObject(instance), isTrue); }); }); }); diff --git a/fixtures/_webdevSoundSmoke/web/main.dart b/fixtures/_webdevSoundSmoke/web/main.dart index 39fa7f845..907bfdbba 100644 --- a/fixtures/_webdevSoundSmoke/web/main.dart +++ b/fixtures/_webdevSoundSmoke/web/main.dart @@ -7,31 +7,6 @@ import 'dart:convert'; import 'dart:developer'; import 'dart:html'; -class A {} - -class B extends A {} - -extension AExt on A { - void foo() { - print('AExt'); - } -} - -extension BExt on B { - void foo() { - print('BExt'); - } -} - -class Node { - Node? next; - Node([Node? n]) : next = n; - - static Node? create() { - return Node(Node()); - } -} - void main() { print('Initial Print'); @@ -41,54 +16,8 @@ void main() { }); document.body?.append(SpanElement()..text = 'Hello World!!'); + var count = 0; Timer.periodic(const Duration(seconds: 1), (_) { - A a = B(); - a.foo(); // vm: 'BExt' (incorrect), web: 'AExt' (correct) - if (a is B) { - a.foo(); // vm: 'BExt' (correct), web: 'AExt' (incorrect) - } - Node? node = Node.create(); - for (var n = node; n != null; n = n.next) { - print('hello'); - } + print('Counter is: ${++count}'); // Breakpoint: printCounter }); } - -// current eval function for web -// Gives incorrect result of 'AExt; -dynamic evalCurrent(A a) { - return a.foo(); -} - -// current eval function for vm -// Gives incorrect result of 'AExt; -dynamic evalCurrentVM(dynamic a) { - return a.foo(); -} - -dynamic evalSuggested(B a) { - return a.foo(); -} - -// for null safety -void nullSafetyExample(Node? node) { - // hovering over 'n.next' gives a compilation error because we pass 'Node?' - // type for n to the eval function - for (var n = node; n != null; n = n.next) { - print('hello'); - } -} - -// What needs to be done: -// For expression evaluation: -// - collect correct current types for the eval function arguments and pass them to the eval function -// -// For variable display of views: -// option 1: implement in dap -// - for each view getter of the object, eval '(object as View).getter' -// -// option 2: implement in vm_service protocol (might be faster) -// - vm service protocol new API -// getObjectView(isolateId, objectId, typeId); -// returns a fake object of type with 'typeId' and getters filled with eval '(object as View).getter' -// - backends to implement this (can ddc add a runtime function for this to skip expression compilation?) \ No newline at end of file From 53dfd4137afe976a8b7181e18261efe5a7e9f93f Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 24 Jul 2023 08:24:35 -0700 Subject: [PATCH 15/24] Update SDK min consrraint to require new debugger runtime API --- dwds/debug_extension/pubspec.yaml | 2 +- dwds/debug_extension_mv3/pubspec.yaml | 2 +- dwds/lib/src/debugging/instance.dart | 7 +++---- dwds/pubspec.yaml | 2 +- dwds/test/chrome_proxy_service_test.dart | 1 - example/pubspec.yaml | 2 +- fixtures/_test/pubspec.yaml | 2 +- fixtures/_testCircular1/pubspec.yaml | 2 +- fixtures/_testCircular1Sound/pubspec.yaml | 2 +- fixtures/_testCircular2/pubspec.yaml | 2 +- fixtures/_testCircular2Sound/pubspec.yaml | 2 +- fixtures/_testPackageSound/pubspec.yaml | 2 +- fixtures/_testSound/pubspec.yaml | 2 +- fixtures/_webdevSmoke/pubspec.yaml | 2 +- fixtures/_webdevSoundSmoke/pubspec.yaml | 2 +- webdev/CHANGELOG.md | 1 + webdev/pubspec.yaml | 2 +- 17 files changed, 18 insertions(+), 19 deletions(-) diff --git a/dwds/debug_extension/pubspec.yaml b/dwds/debug_extension/pubspec.yaml index 8dd6ddeda..07cf7ad41 100644 --- a/dwds/debug_extension/pubspec.yaml +++ b/dwds/debug_extension/pubspec.yaml @@ -6,7 +6,7 @@ description: >- A chrome extension for Dart debugging. environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: async: ^2.3.0 diff --git a/dwds/debug_extension_mv3/pubspec.yaml b/dwds/debug_extension_mv3/pubspec.yaml index f0421f511..2cb77c4f1 100644 --- a/dwds/debug_extension_mv3/pubspec.yaml +++ b/dwds/debug_extension_mv3/pubspec.yaml @@ -6,7 +6,7 @@ description: >- A Chrome extension for Dart debugging. environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: built_value: ^8.3.0 diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index 4b33a0981..9c1ad3a54 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -868,17 +868,16 @@ class InstanceHelper extends Domain { id: objectId, identityHashCode: objectId.hashCode, classRef: classRefForClosure, - // TODO(grouma) - fill this in properly. + // TODO(annagrin) - fill this in properly. closureFunction: FuncRef( name: functionMetaData.name, id: createId(), - // TODO(alanknight): The right ClassRef owner: classRefForUnknown, isConst: false, isStatic: false, - // TODO(annagrin): get information about getters and setters from symbols. - // https://github.com/dart-lang/sdk/issues/46723 implicit: false, + isGetter: false, + isSetter: false, ), closureContext: ContextRef(length: 0, id: createId()), ); diff --git a/dwds/pubspec.yaml b/dwds/pubspec.yaml index 3cd46cbd0..11676531b 100644 --- a/dwds/pubspec.yaml +++ b/dwds/pubspec.yaml @@ -6,7 +6,7 @@ description: >- service protocol. repository: https://github.com/dart-lang/webdev/tree/master/dwds environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: async: ^2.9.0 diff --git a/dwds/test/chrome_proxy_service_test.dart b/dwds/test/chrome_proxy_service_test.dart index de89b2d1f..8fa93fa1c 100644 --- a/dwds/test/chrome_proxy_service_test.dart +++ b/dwds/test/chrome_proxy_service_test.dart @@ -39,7 +39,6 @@ void main() { await context.setUp( enableExpressionEvaluation: true, verboseCompiler: false, - canaryFeatures: true, ); }); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 9f1797838..747180c44 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -4,7 +4,7 @@ description: A web app example for webdev CLI. publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dev_dependencies: build_runner: ^2.4.0 diff --git a/fixtures/_test/pubspec.yaml b/fixtures/_test/pubspec.yaml index 5969c1891..ca7044b90 100644 --- a/fixtures/_test/pubspec.yaml +++ b/fixtures/_test/pubspec.yaml @@ -9,7 +9,7 @@ description: >- publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: intl: ^0.17.0 diff --git a/fixtures/_testCircular1/pubspec.yaml b/fixtures/_testCircular1/pubspec.yaml index 8fc4b93ee..ce209823c 100644 --- a/fixtures/_testCircular1/pubspec.yaml +++ b/fixtures/_testCircular1/pubspec.yaml @@ -9,7 +9,7 @@ description: >- publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: intl: ^0.17.0 diff --git a/fixtures/_testCircular1Sound/pubspec.yaml b/fixtures/_testCircular1Sound/pubspec.yaml index a09869900..b1e07e8ac 100644 --- a/fixtures/_testCircular1Sound/pubspec.yaml +++ b/fixtures/_testCircular1Sound/pubspec.yaml @@ -5,7 +5,7 @@ description: >- publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: intl: ^0.17.0 diff --git a/fixtures/_testCircular2/pubspec.yaml b/fixtures/_testCircular2/pubspec.yaml index 8c67a6ec2..153ccb245 100644 --- a/fixtures/_testCircular2/pubspec.yaml +++ b/fixtures/_testCircular2/pubspec.yaml @@ -9,7 +9,7 @@ description: >- publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: _test_circular1: diff --git a/fixtures/_testCircular2Sound/pubspec.yaml b/fixtures/_testCircular2Sound/pubspec.yaml index 26200812a..51f768ab8 100644 --- a/fixtures/_testCircular2Sound/pubspec.yaml +++ b/fixtures/_testCircular2Sound/pubspec.yaml @@ -5,7 +5,7 @@ description: >- publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: _test_circular1_sound: diff --git a/fixtures/_testPackageSound/pubspec.yaml b/fixtures/_testPackageSound/pubspec.yaml index 882e291f1..6a41aa485 100644 --- a/fixtures/_testPackageSound/pubspec.yaml +++ b/fixtures/_testPackageSound/pubspec.yaml @@ -5,7 +5,7 @@ description: >- publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: _test_sound: diff --git a/fixtures/_testSound/pubspec.yaml b/fixtures/_testSound/pubspec.yaml index 677a9e4f3..bb4ae18de 100644 --- a/fixtures/_testSound/pubspec.yaml +++ b/fixtures/_testSound/pubspec.yaml @@ -5,7 +5,7 @@ description: >- publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: intl: ^0.17.0 diff --git a/fixtures/_webdevSmoke/pubspec.yaml b/fixtures/_webdevSmoke/pubspec.yaml index 493debe0e..fefa22f7b 100644 --- a/fixtures/_webdevSmoke/pubspec.yaml +++ b/fixtures/_webdevSmoke/pubspec.yaml @@ -14,7 +14,7 @@ publish_to: none # and build_web_compilers constraint should match those defined # in pubspec.dart. environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dev_dependencies: build_runner: '>=1.6.2 <3.0.0' diff --git a/fixtures/_webdevSoundSmoke/pubspec.yaml b/fixtures/_webdevSoundSmoke/pubspec.yaml index 3192915df..5657b84ec 100644 --- a/fixtures/_webdevSoundSmoke/pubspec.yaml +++ b/fixtures/_webdevSoundSmoke/pubspec.yaml @@ -4,7 +4,7 @@ description: A test fixture for webdev testing with sound support. publish_to: none environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dev_dependencies: build_runner: ^2.4.0 diff --git a/webdev/CHANGELOG.md b/webdev/CHANGELOG.md index 00ce7cd03..c57d81209 100644 --- a/webdev/CHANGELOG.md +++ b/webdev/CHANGELOG.md @@ -1,6 +1,7 @@ ## 3.0.7-wip - Update `build_web_compilers` constraint to `^4.0.4`. +- Update SDK constraint to `>=3.1.0-340.0.dev <4.0.0`. ## 3.0.6 diff --git a/webdev/pubspec.yaml b/webdev/pubspec.yaml index 1a4af99fc..02e8d502e 100644 --- a/webdev/pubspec.yaml +++ b/webdev/pubspec.yaml @@ -8,7 +8,7 @@ description: >- features for users and tools to build and deploy web applications with Dart. repository: https://github.com/dart-lang/webdev/tree/master/webdev environment: - sdk: ">=3.1.0-254.0.dev <4.0.0" + sdk: ">=3.1.0-340.0.dev <4.0.0" dependencies: args: ^2.3.1 From bfcea4c33fd56d6b650fae0524d2830b34f4d4a4 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 24 Jul 2023 08:58:19 -0700 Subject: [PATCH 16/24] Cleanup --- dwds/lib/src/debugging/instance.dart | 6 ++++-- dwds/test/instances/common/test_inspector.dart | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dwds/lib/src/debugging/instance.dart b/dwds/lib/src/debugging/instance.dart index 9c1ad3a54..e3c310cb6 100644 --- a/dwds/lib/src/debugging/instance.dart +++ b/dwds/lib/src/debugging/instance.dart @@ -204,6 +204,8 @@ class InstanceHelper extends Domain { /// Create a bound field for [property] in an instance of [classRef]. Future _fieldFor(Property property, ClassRef classRef) async { final instance = await _instanceRefForRemote(property.value); + // TODO(annagrin): convert JS name to dart and fill missing information. + //https://github.com/dart-lang/sdk/issues/46723 return BoundField( name: property.name, decl: FieldRef( @@ -216,7 +218,6 @@ class InstanceHelper extends Domain { id: createId(), ), owner: classRef, - // TODO(grouma) - Fill these in. isConst: false, isFinal: false, isStatic: false, @@ -863,12 +864,13 @@ class InstanceHelper extends Domain { inspector.remoteDebugger, remoteObject, ); + // TODO(annagrin) - fill missing information. + // https://github.com/dart-lang/sdk/issues/46723 return InstanceRef( kind: InstanceKind.kClosure, id: objectId, identityHashCode: objectId.hashCode, classRef: classRefForClosure, - // TODO(annagrin) - fill this in properly. closureFunction: FuncRef( name: functionMetaData.name, id: createId(), diff --git a/dwds/test/instances/common/test_inspector.dart b/dwds/test/instances/common/test_inspector.dart index 3319c9416..e9ee70e40 100644 --- a/dwds/test/instances/common/test_inspector.dart +++ b/dwds/test/instances/common/test_inspector.dart @@ -338,7 +338,7 @@ final matchRecordClassName = 'Record'; final matchRecordTypeClassName = 'RecordType'; /// Match types for old and new type systems. -/// - Old type system has `dart:core|List` and `dart:_runtime|_Type`. +/// - Old type system has `dart:_interceptors|List` and `dart:_runtime|_Type`. /// - New type system has `dart:_interceptors|JSArray` and `dart:core|Type`. /// TODO(annagrin): update when DDC enables new type system. final matchTypeClassName = anyOf(['Type', '_Type']); From 50411ad1a06b1af4cd7df3ed0e7a8e52c8764fbe Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 24 Jul 2023 09:39:40 -0700 Subject: [PATCH 17/24] Temporarily only test on main --- .github/workflows/dart.yml | 644 ++++++++----------------------------- dwds/mono_pkg.yaml | 13 +- tool/ci.sh | 2 +- webdev/mono_pkg.yaml | 7 +- 4 files changed, 145 insertions(+), 521 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 864753df1..1c0b9f9ed 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -1,4 +1,4 @@ -# Created with package:mono_repo v6.5.7 +# Created with package:mono_repo v6.4.3 name: Dart CI on: push: @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:stable" @@ -30,60 +30,22 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: stable - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - name: mono_repo self validate - run: dart pub global activate mono_repo 6.5.7 + run: dart pub global activate mono_repo 6.4.3 - name: mono_repo self validate run: dart pub global run mono_repo generate --validate job_002: - name: "analyzer_and_format; linux; Dart dev; PKG: dwds; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_version_test.dart`" - runs-on: ubuntu-latest - steps: - - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 - with: - path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:format-analyze_0-test_0" - restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds - os:ubuntu-latest;pub-cache-hosted;sdk:dev - os:ubuntu-latest;pub-cache-hosted - os:ubuntu-latest - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - - name: dwds; dart test test/build/ensure_version_test.dart - run: dart test test/build/ensure_version_test.dart - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - job_003: name: "analyzer_and_format; linux; Dart dev; PKGS: example, fixtures/_webdevSoundSmoke, frontend_server_client, frontend_server_common, test_common; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-fixtures/_webdevSoundSmoke-frontend_server_client-frontend_server_common-test_common;commands:format-analyze_0" @@ -93,12 +55,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: dev - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: example_pub_upgrade name: example; dart pub upgrade run: dart pub upgrade @@ -164,194 +126,88 @@ jobs: run: dart analyze --fatal-infos . if: "always() && steps.test_common_pub_upgrade.conclusion == 'success'" working-directory: test_common - job_004: - name: "analyzer_and_format; linux; Dart dev; PKG: webdev; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_build_test.dart`" - runs-on: ubuntu-latest - steps: - - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 - with: - path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev;commands:format-analyze_0-test_7" - restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev - os:ubuntu-latest;pub-cache-hosted;sdk:dev - os:ubuntu-latest;pub-cache-hosted - os:ubuntu-latest - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: webdev_pub_upgrade - name: webdev; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: webdev - - name: "webdev; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - - name: "webdev; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - - name: webdev; dart test test/build/ensure_build_test.dart - run: dart test test/build/ensure_build_test.dart - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - job_005: - name: "unit_test; linux; Dart dev; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --tags=extension`" + job_003: + name: "analyzer_and_format; linux; Dart main; PKG: dwds; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_version_test.dart`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:command-test_1" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds;commands:format-analyze_0-test_0" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds - os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds + os:ubuntu-latest;pub-cache-hosted;sdk:main os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: - sdk: dev + sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade if: "always() && steps.checkout.conclusion == 'success'" working-directory: dwds - - name: "dwds; Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" - run: "Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --tags=extension" - run: "dart test --tags=extension" + - name: "dwds; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_006: - name: "unit_test; linux; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" - runs-on: ubuntu-latest - steps: - - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 - with: - path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:test_2" - restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds - os:ubuntu-latest;pub-cache-hosted;sdk:dev - os:ubuntu-latest;pub-cache-hosted - os:ubuntu-latest - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" - run: "dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" + - name: "dwds; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_007: - name: "unit_test; linux; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" - runs-on: ubuntu-latest - steps: - - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 - with: - path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:test_3" - restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds - os:ubuntu-latest;pub-cache-hosted;sdk:dev - os:ubuntu-latest;pub-cache-hosted - os:ubuntu-latest - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" - run: "dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" + - name: dwds; dart test test/build/ensure_version_test.dart + run: dart test test/build/ensure_version_test.dart if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_008: - name: "unit_test; linux; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" + job_004: + name: "analyzer_and_format; linux; Dart main; PKG: webdev; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_build_test.dart`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:test_4" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:webdev;commands:format-analyze_0-test_7" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds - os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:webdev + os:ubuntu-latest;pub-cache-hosted;sdk:main os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: - sdk: dev + sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: webdev_pub_upgrade + name: webdev; dart pub upgrade run: dart pub upgrade if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" - run: "dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_009: + working-directory: webdev + - name: "webdev; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + - name: "webdev; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + - name: webdev; dart test test/build/ensure_build_test.dart + run: dart test test/build/ensure_build_test.dart + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + job_005: name: "unit_test; linux; Dart dev; PKG: frontend_server_client; `dart test -j 1`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:frontend_server_client;commands:test_5" @@ -361,12 +217,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: dev - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: frontend_server_client_pub_upgrade name: frontend_server_client; dart pub upgrade run: dart pub upgrade @@ -381,12 +237,12 @@ jobs: - job_002 - job_003 - job_004 - job_010: + job_006: name: "unit_test; linux; Dart dev; PKG: test_common; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --exclude-tags=release`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:test_common;commands:command-test_6" @@ -396,12 +252,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: dev - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: test_common_pub_upgrade name: test_common; dart pub upgrade run: dart pub upgrade @@ -420,51 +276,12 @@ jobs: - job_002 - job_003 - job_004 - job_011: - name: "unit_test; linux; Dart dev; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" - runs-on: ubuntu-latest - steps: - - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 - with: - path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev;commands:command-test_5" - restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev - os:ubuntu-latest;pub-cache-hosted;sdk:dev - os:ubuntu-latest;pub-cache-hosted - os:ubuntu-latest - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: webdev_pub_upgrade - name: webdev; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: webdev - - name: "webdev; Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" - run: "Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - - name: "webdev; dart test -j 1" - run: dart test -j 1 - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_012: + job_007: name: "unit_test; linux; Dart main; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --tags=extension`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds;commands:command-test_1" @@ -474,12 +291,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -498,12 +315,12 @@ jobs: - job_002 - job_003 - job_004 - job_013: + job_008: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds;commands:test_2" @@ -513,12 +330,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -533,12 +350,12 @@ jobs: - job_002 - job_003 - job_004 - job_014: + job_009: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds;commands:test_3" @@ -548,12 +365,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -568,12 +385,12 @@ jobs: - job_002 - job_003 - job_004 - job_015: + job_010: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds;commands:test_4" @@ -583,12 +400,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -603,12 +420,12 @@ jobs: - job_002 - job_003 - job_004 - job_016: + job_011: name: "unit_test; linux; Dart main; PKG: frontend_server_client; `dart test -j 1`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:frontend_server_client;commands:test_5" @@ -618,12 +435,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: frontend_server_client_pub_upgrade name: frontend_server_client; dart pub upgrade run: dart pub upgrade @@ -638,12 +455,12 @@ jobs: - job_002 - job_003 - job_004 - job_017: + job_012: name: "unit_test; linux; Dart main; PKG: test_common; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --exclude-tags=release`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:test_common;commands:command-test_6" @@ -653,12 +470,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: test_common_pub_upgrade name: test_common; dart pub upgrade run: dart pub upgrade @@ -677,12 +494,12 @@ jobs: - job_002 - job_003 - job_004 - job_018: + job_013: name: "unit_test; linux; Dart main; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:webdev;commands:command-test_5" @@ -692,12 +509,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: webdev_pub_upgrade name: webdev; dart pub upgrade run: dart pub upgrade @@ -716,117 +533,17 @@ jobs: - job_002 - job_003 - job_004 - job_019: - name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --tags=extension`" - runs-on: windows-latest - steps: - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --tags=extension" - run: "dart test --tags=extension" - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_020: - name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" - runs-on: windows-latest - steps: - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" - run: "dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_021: - name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" - runs-on: windows-latest - steps: - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" - run: "dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_022: - name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" - runs-on: windows-latest - steps: - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: dwds_pub_upgrade - name: dwds; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" - run: "dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_023: + job_014: name: "unit_test; windows; Dart dev; PKG: frontend_server_client; `dart test -j 1`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: dev - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: frontend_server_client_pub_upgrade name: frontend_server_client; dart pub upgrade run: dart pub upgrade @@ -841,42 +558,17 @@ jobs: - job_002 - job_003 - job_004 - job_024: - name: "unit_test; windows; Dart dev; PKG: webdev; `dart test -j 1`" - runs-on: windows-latest - steps: - - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f - with: - sdk: dev - - id: checkout - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 - - id: webdev_pub_upgrade - name: webdev; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: webdev - - name: "webdev; dart test -j 1" - run: dart test -j 1 - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - needs: - - job_001 - - job_002 - - job_003 - - job_004 - job_025: + job_015: name: "unit_test; windows; Dart dev; PKG: test_common; `dart test --exclude-tags=release`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: dev - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: test_common_pub_upgrade name: test_common; dart pub upgrade run: dart pub upgrade @@ -891,17 +583,17 @@ jobs: - job_002 - job_003 - job_004 - job_026: + job_016: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --tags=extension`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -916,17 +608,17 @@ jobs: - job_002 - job_003 - job_004 - job_027: + job_017: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -941,17 +633,17 @@ jobs: - job_002 - job_003 - job_004 - job_028: + job_018: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -966,17 +658,17 @@ jobs: - job_002 - job_003 - job_004 - job_029: + job_019: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -991,17 +683,17 @@ jobs: - job_002 - job_003 - job_004 - job_030: + job_020: name: "unit_test; windows; Dart main; PKG: frontend_server_client; `dart test -j 1`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: frontend_server_client_pub_upgrade name: frontend_server_client; dart pub upgrade run: dart pub upgrade @@ -1016,17 +708,17 @@ jobs: - job_002 - job_003 - job_004 - job_031: + job_021: name: "unit_test; windows; Dart main; PKG: webdev; `dart test -j 1`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: webdev_pub_upgrade name: webdev; dart pub upgrade run: dart pub upgrade @@ -1041,17 +733,17 @@ jobs: - job_002 - job_003 - job_004 - job_032: + job_022: name: "unit_test; windows; Dart main; PKG: test_common; `dart test --exclude-tags=release`" runs-on: windows-latest steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: main - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: test_common_pub_upgrade name: test_common; dart pub upgrade run: dart pub upgrade @@ -1066,13 +758,13 @@ jobs: - job_002 - job_003 - job_004 - job_033: + job_023: name: "beta_cron; linux; Dart beta; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:beta;packages:dwds;commands:command-test_5" @@ -1082,12 +774,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: beta - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -1124,23 +816,13 @@ jobs: - job_020 - job_021 - job_022 - - job_023 - - job_024 - - job_025 - - job_026 - - job_027 - - job_028 - - job_029 - - job_030 - - job_031 - - job_032 - job_034: + job_024: name: "beta_cron; linux; Dart beta; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:beta;packages:webdev;commands:command-test_5" @@ -1150,12 +832,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: beta - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: webdev_pub_upgrade name: webdev; dart pub upgrade run: dart pub upgrade @@ -1192,23 +874,13 @@ jobs: - job_020 - job_021 - job_022 - - job_023 - - job_024 - - job_025 - - job_026 - - job_027 - - job_028 - - job_029 - - job_030 - - job_031 - - job_032 - job_035: + job_025: name: "beta_cron; linux; Dart beta; PKG: dwds; `dart analyze .`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:beta;packages:dwds;commands:analyze_1" @@ -1218,12 +890,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: beta - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -1256,23 +928,13 @@ jobs: - job_020 - job_021 - job_022 - - job_023 - - job_024 - - job_025 - - job_026 - - job_027 - - job_028 - - job_029 - - job_030 - - job_031 - - job_032 - job_036: + job_026: name: "beta_cron; linux; Dart beta; PKG: webdev; `dart analyze .`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" steps: - name: Cache Pub hosted dependencies - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" key: "os:ubuntu-latest;pub-cache-hosted;sdk:beta;packages:webdev;commands:analyze_1" @@ -1282,12 +944,12 @@ jobs: os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: beta - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: webdev_pub_upgrade name: webdev; dart pub upgrade run: dart pub upgrade @@ -1320,28 +982,18 @@ jobs: - job_020 - job_021 - job_022 - - job_023 - - job_024 - - job_025 - - job_026 - - job_027 - - job_028 - - job_029 - - job_030 - - job_031 - - job_032 - job_037: + job_027: name: "beta_cron; windows; Dart beta; PKG: dwds; `dart test -j 1`" runs-on: windows-latest if: "github.event_name == 'schedule'" steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: beta - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: dwds_pub_upgrade name: dwds; dart pub upgrade run: dart pub upgrade @@ -1374,28 +1026,18 @@ jobs: - job_020 - job_021 - job_022 - - job_023 - - job_024 - - job_025 - - job_026 - - job_027 - - job_028 - - job_029 - - job_030 - - job_031 - - job_032 - job_038: + job_028: name: "beta_cron; windows; Dart beta; PKG: webdev; `dart test -j 1`" runs-on: windows-latest if: "github.event_name == 'schedule'" steps: - name: Setup Dart SDK - uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: sdk: beta - id: checkout name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - id: webdev_pub_upgrade name: webdev; dart pub upgrade run: dart pub upgrade @@ -1428,17 +1070,7 @@ jobs: - job_020 - job_021 - job_022 - - job_023 - - job_024 - - job_025 - - job_026 - - job_027 - - job_028 - - job_029 - - job_030 - - job_031 - - job_032 - job_039: + job_029: name: Notify failure runs-on: ubuntu-latest if: "(github.event_name == 'push' || github.event_name == 'schedule') && failure()" @@ -1478,13 +1110,3 @@ jobs: - job_026 - job_027 - job_028 - - job_029 - - job_030 - - job_031 - - job_032 - - job_033 - - job_034 - - job_035 - - job_036 - - job_037 - - job_038 diff --git a/dwds/mono_pkg.yaml b/dwds/mono_pkg.yaml index 15b55041f..e3ae564ea 100644 --- a/dwds/mono_pkg.yaml +++ b/dwds/mono_pkg.yaml @@ -5,7 +5,8 @@ stages: - format - analyze: --fatal-infos . - test: test/build/ensure_version_test.dart - sdk: dev + # sdk: dev + sdk: main - unit_test: # Linux extension tests: # Note: `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &` must be @@ -14,7 +15,7 @@ stages: - command: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - test: --tags=extension sdk: - - dev + # -dev - main os: - linux @@ -22,7 +23,7 @@ stages: - group: - test: --tags=extension sdk: - - dev + # -dev - main os: - windows @@ -30,7 +31,7 @@ stages: - group: - test: --total-shards 3 --shard-index 0 --exclude-tags=extension sdk: - - dev + # -dev - main os: - linux @@ -39,7 +40,7 @@ stages: - group: - test: --total-shards 3 --shard-index 1 --exclude-tags=extension sdk: - - dev + # -dev - main os: - linux @@ -48,7 +49,7 @@ stages: - group: - test: --total-shards 3 --shard-index 2 --exclude-tags=extension sdk: - - dev + # -dev - main os: - linux diff --git a/tool/ci.sh b/tool/ci.sh index b834a526b..b7b7e66f1 100755 --- a/tool/ci.sh +++ b/tool/ci.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Created with package:mono_repo v6.5.7 +# Created with package:mono_repo v6.4.3 # Support built in commands on windows out of the box. # When it is a flutter repo (check the pubspec.yaml for "sdk: flutter") diff --git a/webdev/mono_pkg.yaml b/webdev/mono_pkg.yaml index 8fd305797..d526dcc0a 100644 --- a/webdev/mono_pkg.yaml +++ b/webdev/mono_pkg.yaml @@ -5,18 +5,19 @@ stages: - format - analyze: --fatal-infos . - test: test/build/ensure_build_test.dart - sdk: dev + # sdk: dev + sdk: main - unit_test: - group: - command: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - test: -j 1 sdk: - - dev + # - dev - main - test: -j 1 os: windows sdk: - - dev + # - dev - main - beta_cron: - analyze: . From 8e0b80666606d2c41d0df54ec8012adafe852842 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 24 Jul 2023 09:45:34 -0700 Subject: [PATCH 18/24] More running on main --- .github/workflows/dart.yml | 128 +++++++++++++++-------- fixtures/_webdevSoundSmoke/mono_pkg.yaml | 3 +- 2 files changed, 89 insertions(+), 42 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 1c0b9f9ed..677cedf07 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -41,16 +41,16 @@ jobs: - name: mono_repo self validate run: dart pub global run mono_repo generate --validate job_002: - name: "analyzer_and_format; linux; Dart dev; PKGS: example, fixtures/_webdevSoundSmoke, frontend_server_client, frontend_server_common, test_common; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" + name: "analyzer_and_format; linux; Dart dev; PKGS: example, frontend_server_client, frontend_server_common, test_common; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-fixtures/_webdevSoundSmoke-frontend_server_client-frontend_server_common-test_common;commands:format-analyze_0" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-frontend_server_client-frontend_server_common-test_common;commands:format-analyze_0" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-fixtures/_webdevSoundSmoke-frontend_server_client-frontend_server_common-test_common + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-frontend_server_client-frontend_server_common-test_common os:ubuntu-latest;pub-cache-hosted;sdk:dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest @@ -74,19 +74,6 @@ jobs: run: dart analyze --fatal-infos . if: "always() && steps.example_pub_upgrade.conclusion == 'success'" working-directory: example - - id: fixtures__webdevSoundSmoke_pub_upgrade - name: fixtures/_webdevSoundSmoke; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: fixtures/_webdevSoundSmoke - - name: "fixtures/_webdevSoundSmoke; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" - working-directory: fixtures/_webdevSoundSmoke - - name: "fixtures/_webdevSoundSmoke; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . - if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" - working-directory: fixtures/_webdevSoundSmoke - id: frontend_server_client_pub_upgrade name: frontend_server_client; dart pub upgrade run: dart pub upgrade @@ -165,6 +152,40 @@ jobs: if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" working-directory: dwds job_004: + name: "analyzer_and_format; linux; Dart main; PKG: fixtures/_webdevSoundSmoke; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:fixtures/_webdevSoundSmoke;commands:format-analyze_0" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:fixtures/_webdevSoundSmoke + os:ubuntu-latest;pub-cache-hosted;sdk:main + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: main + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: fixtures__webdevSoundSmoke_pub_upgrade + name: fixtures/_webdevSoundSmoke; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: fixtures/_webdevSoundSmoke + - name: "fixtures/_webdevSoundSmoke; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." + if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" + working-directory: fixtures/_webdevSoundSmoke + - name: "fixtures/_webdevSoundSmoke; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . + if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" + working-directory: fixtures/_webdevSoundSmoke + job_005: name: "analyzer_and_format; linux; Dart main; PKG: webdev; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_build_test.dart`" runs-on: ubuntu-latest steps: @@ -202,7 +223,7 @@ jobs: run: dart test test/build/ensure_build_test.dart if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" working-directory: webdev - job_005: + job_006: name: "unit_test; linux; Dart dev; PKG: frontend_server_client; `dart test -j 1`" runs-on: ubuntu-latest steps: @@ -237,7 +258,8 @@ jobs: - job_002 - job_003 - job_004 - job_006: + - job_005 + job_007: name: "unit_test; linux; Dart dev; PKG: test_common; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --exclude-tags=release`" runs-on: ubuntu-latest steps: @@ -276,7 +298,8 @@ jobs: - job_002 - job_003 - job_004 - job_007: + - job_005 + job_008: name: "unit_test; linux; Dart main; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --tags=extension`" runs-on: ubuntu-latest steps: @@ -315,7 +338,8 @@ jobs: - job_002 - job_003 - job_004 - job_008: + - job_005 + job_009: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" runs-on: ubuntu-latest steps: @@ -350,7 +374,8 @@ jobs: - job_002 - job_003 - job_004 - job_009: + - job_005 + job_010: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" runs-on: ubuntu-latest steps: @@ -385,7 +410,8 @@ jobs: - job_002 - job_003 - job_004 - job_010: + - job_005 + job_011: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" runs-on: ubuntu-latest steps: @@ -420,7 +446,8 @@ jobs: - job_002 - job_003 - job_004 - job_011: + - job_005 + job_012: name: "unit_test; linux; Dart main; PKG: frontend_server_client; `dart test -j 1`" runs-on: ubuntu-latest steps: @@ -455,7 +482,8 @@ jobs: - job_002 - job_003 - job_004 - job_012: + - job_005 + job_013: name: "unit_test; linux; Dart main; PKG: test_common; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --exclude-tags=release`" runs-on: ubuntu-latest steps: @@ -494,7 +522,8 @@ jobs: - job_002 - job_003 - job_004 - job_013: + - job_005 + job_014: name: "unit_test; linux; Dart main; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest steps: @@ -533,7 +562,8 @@ jobs: - job_002 - job_003 - job_004 - job_014: + - job_005 + job_015: name: "unit_test; windows; Dart dev; PKG: frontend_server_client; `dart test -j 1`" runs-on: windows-latest steps: @@ -558,7 +588,8 @@ jobs: - job_002 - job_003 - job_004 - job_015: + - job_005 + job_016: name: "unit_test; windows; Dart dev; PKG: test_common; `dart test --exclude-tags=release`" runs-on: windows-latest steps: @@ -583,7 +614,8 @@ jobs: - job_002 - job_003 - job_004 - job_016: + - job_005 + job_017: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --tags=extension`" runs-on: windows-latest steps: @@ -608,7 +640,8 @@ jobs: - job_002 - job_003 - job_004 - job_017: + - job_005 + job_018: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" runs-on: windows-latest steps: @@ -633,7 +666,8 @@ jobs: - job_002 - job_003 - job_004 - job_018: + - job_005 + job_019: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" runs-on: windows-latest steps: @@ -658,7 +692,8 @@ jobs: - job_002 - job_003 - job_004 - job_019: + - job_005 + job_020: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" runs-on: windows-latest steps: @@ -683,7 +718,8 @@ jobs: - job_002 - job_003 - job_004 - job_020: + - job_005 + job_021: name: "unit_test; windows; Dart main; PKG: frontend_server_client; `dart test -j 1`" runs-on: windows-latest steps: @@ -708,7 +744,8 @@ jobs: - job_002 - job_003 - job_004 - job_021: + - job_005 + job_022: name: "unit_test; windows; Dart main; PKG: webdev; `dart test -j 1`" runs-on: windows-latest steps: @@ -733,7 +770,8 @@ jobs: - job_002 - job_003 - job_004 - job_022: + - job_005 + job_023: name: "unit_test; windows; Dart main; PKG: test_common; `dart test --exclude-tags=release`" runs-on: windows-latest steps: @@ -758,7 +796,8 @@ jobs: - job_002 - job_003 - job_004 - job_023: + - job_005 + job_024: name: "beta_cron; linux; Dart beta; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -816,7 +855,8 @@ jobs: - job_020 - job_021 - job_022 - job_024: + - job_023 + job_025: name: "beta_cron; linux; Dart beta; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -874,7 +914,8 @@ jobs: - job_020 - job_021 - job_022 - job_025: + - job_023 + job_026: name: "beta_cron; linux; Dart beta; PKG: dwds; `dart analyze .`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -928,7 +969,8 @@ jobs: - job_020 - job_021 - job_022 - job_026: + - job_023 + job_027: name: "beta_cron; linux; Dart beta; PKG: webdev; `dart analyze .`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -982,7 +1024,8 @@ jobs: - job_020 - job_021 - job_022 - job_027: + - job_023 + job_028: name: "beta_cron; windows; Dart beta; PKG: dwds; `dart test -j 1`" runs-on: windows-latest if: "github.event_name == 'schedule'" @@ -1026,7 +1069,8 @@ jobs: - job_020 - job_021 - job_022 - job_028: + - job_023 + job_029: name: "beta_cron; windows; Dart beta; PKG: webdev; `dart test -j 1`" runs-on: windows-latest if: "github.event_name == 'schedule'" @@ -1070,7 +1114,8 @@ jobs: - job_020 - job_021 - job_022 - job_029: + - job_023 + job_030: name: Notify failure runs-on: ubuntu-latest if: "(github.event_name == 'push' || github.event_name == 'schedule') && failure()" @@ -1110,3 +1155,4 @@ jobs: - job_026 - job_027 - job_028 + - job_029 diff --git a/fixtures/_webdevSoundSmoke/mono_pkg.yaml b/fixtures/_webdevSoundSmoke/mono_pkg.yaml index 12cfc8524..19f6ef916 100644 --- a/fixtures/_webdevSoundSmoke/mono_pkg.yaml +++ b/fixtures/_webdevSoundSmoke/mono_pkg.yaml @@ -4,7 +4,8 @@ stages: - group: - format - analyze: --fatal-infos . - sdk: dev + # sdk: dev + sdk: main cache: directories: From 65aaffdbd57b2dd546585efdb2fffe86eb5bf29b Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 24 Jul 2023 09:47:58 -0700 Subject: [PATCH 19/24] More running on main --- example/mono_pkg.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/mono_pkg.yaml b/example/mono_pkg.yaml index 12cfc8524..19f6ef916 100644 --- a/example/mono_pkg.yaml +++ b/example/mono_pkg.yaml @@ -4,7 +4,8 @@ stages: - group: - format - analyze: --fatal-infos . - sdk: dev + # sdk: dev + sdk: main cache: directories: From af8aff151dc5d5cf9e4383ef6165266cadbb5e8b Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 24 Jul 2023 09:49:34 -0700 Subject: [PATCH 20/24] More running on main --- .github/workflows/dart.yml | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 677cedf07..a86ab74f7 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -41,16 +41,16 @@ jobs: - name: mono_repo self validate run: dart pub global run mono_repo generate --validate job_002: - name: "analyzer_and_format; linux; Dart dev; PKGS: example, frontend_server_client, frontend_server_common, test_common; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" + name: "analyzer_and_format; linux; Dart dev; PKGS: frontend_server_client, frontend_server_common, test_common; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-frontend_server_client-frontend_server_common-test_common;commands:format-analyze_0" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:frontend_server_client-frontend_server_common-test_common;commands:format-analyze_0" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-frontend_server_client-frontend_server_common-test_common + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:frontend_server_client-frontend_server_common-test_common os:ubuntu-latest;pub-cache-hosted;sdk:dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest @@ -61,19 +61,6 @@ jobs: - id: checkout name: Checkout repository uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - id: example_pub_upgrade - name: example; dart pub upgrade - run: dart pub upgrade - if: "always() && steps.checkout.conclusion == 'success'" - working-directory: example - - name: "example; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.example_pub_upgrade.conclusion == 'success'" - working-directory: example - - name: "example; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . - if: "always() && steps.example_pub_upgrade.conclusion == 'success'" - working-directory: example - id: frontend_server_client_pub_upgrade name: frontend_server_client; dart pub upgrade run: dart pub upgrade @@ -152,16 +139,16 @@ jobs: if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" working-directory: dwds job_004: - name: "analyzer_and_format; linux; Dart main; PKG: fixtures/_webdevSoundSmoke; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" + name: "analyzer_and_format; linux; Dart main; PKGS: example, fixtures/_webdevSoundSmoke; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:fixtures/_webdevSoundSmoke;commands:format-analyze_0" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:example-fixtures/_webdevSoundSmoke;commands:format-analyze_0" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:fixtures/_webdevSoundSmoke + os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:example-fixtures/_webdevSoundSmoke os:ubuntu-latest;pub-cache-hosted;sdk:main os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest @@ -172,6 +159,19 @@ jobs: - id: checkout name: Checkout repository uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: example_pub_upgrade + name: example; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: example + - name: "example; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." + if: "always() && steps.example_pub_upgrade.conclusion == 'success'" + working-directory: example + - name: "example; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . + if: "always() && steps.example_pub_upgrade.conclusion == 'success'" + working-directory: example - id: fixtures__webdevSoundSmoke_pub_upgrade name: fixtures/_webdevSoundSmoke; dart pub upgrade run: dart pub upgrade From c25defd1a6dcc7b6656c2fb0cfbb2a41de2991ac Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Mon, 24 Jul 2023 13:49:35 -0700 Subject: [PATCH 21/24] Fix failing webdev test --- fixtures/_webdevSoundSmoke/build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fixtures/_webdevSoundSmoke/build.yaml b/fixtures/_webdevSoundSmoke/build.yaml index a35b98719..5b9378c37 100644 --- a/fixtures/_webdevSoundSmoke/build.yaml +++ b/fixtures/_webdevSoundSmoke/build.yaml @@ -1,7 +1,7 @@ global_options: build_web_compilers:ddc: options: - canary: true + canary: false build_web_compilers:sdk_js: options: - canary: true + canary: false From eac89b373e3a3d62ea4793107fc080a453da6f05 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 25 Jul 2023 08:10:32 -0700 Subject: [PATCH 22/24] Remove unnecessary asyncs --- dwds/test/instances/common/patterns_inspection_common.dart | 4 ++-- dwds/test/instances/common/record_inspection_common.dart | 4 ++-- dwds/test/instances/common/record_type_inspection_common.dart | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dwds/test/instances/common/patterns_inspection_common.dart b/dwds/test/instances/common/patterns_inspection_common.dart index a29dbfaa3..7d98003e0 100644 --- a/dwds/test/instances/common/patterns_inspection_common.dart +++ b/dwds/test/instances/common/patterns_inspection_common.dart @@ -11,12 +11,12 @@ import '../../fixtures/context.dart'; import '../../fixtures/project.dart'; import 'test_inspector.dart'; -Future runTests({ +void runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, required bool canaryFeatures, required bool debug, -}) async { +}) { final context = TestContext(TestProject.testExperimentWithSoundNullSafety, provider); final testInspector = TestInspector(context); diff --git a/dwds/test/instances/common/record_inspection_common.dart b/dwds/test/instances/common/record_inspection_common.dart index a8862a253..c243291ed 100644 --- a/dwds/test/instances/common/record_inspection_common.dart +++ b/dwds/test/instances/common/record_inspection_common.dart @@ -11,12 +11,12 @@ import '../../fixtures/context.dart'; import '../../fixtures/project.dart'; import 'test_inspector.dart'; -Future runTests({ +void runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, required bool canaryFeatures, required bool debug, -}) async { +}) { final context = TestContext(TestProject.testExperimentWithSoundNullSafety, provider); final testInspector = TestInspector(context); diff --git a/dwds/test/instances/common/record_type_inspection_common.dart b/dwds/test/instances/common/record_type_inspection_common.dart index 0b9e607ca..fdcb6ecef 100644 --- a/dwds/test/instances/common/record_type_inspection_common.dart +++ b/dwds/test/instances/common/record_type_inspection_common.dart @@ -11,12 +11,12 @@ import '../../fixtures/context.dart'; import '../../fixtures/project.dart'; import 'test_inspector.dart'; -Future runTests({ +void runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, required bool canaryFeatures, required bool debug, -}) async { +}) { final context = TestContext(TestProject.testExperimentWithSoundNullSafety, provider); final testInspector = TestInspector(context); From d48b456cc0ef747a95498f61f31dbdd3a5ce9c96 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Tue, 25 Jul 2023 08:23:09 -0700 Subject: [PATCH 23/24] Run type system verification tests for non-canary mode as well --- .../instances/common/instance_common.dart | 66 ++++++++++++++++++ dwds/test/instances/instance_canary_test.dart | 69 +------------------ dwds/test/instances/instance_test.dart | 7 ++ 3 files changed, 75 insertions(+), 67 deletions(-) diff --git a/dwds/test/instances/common/instance_common.dart b/dwds/test/instances/common/instance_common.dart index ce52a4f3c..ebd2395fc 100644 --- a/dwds/test/instances/common/instance_common.dart +++ b/dwds/test/instances/common/instance_common.dart @@ -14,6 +14,72 @@ import '../../fixtures/context.dart'; import '../../fixtures/project.dart'; import 'test_inspector.dart'; +void runTypeSystemVerificationTests({ + required TestSdkConfigurationProvider provider, + required CompilationMode compilationMode, + required bool canaryFeatures, + required bool debug, +}) { + final project = TestProject.testScopesWithSoundNullSafety; + + group('$compilationMode |', () { + final context = TestContext(project, provider); + late AppInspector inspector; + + setUpAll(() async { + setCurrentLogWriter(debug: debug); + await context.setUp( + canaryFeatures: canaryFeatures, + compilationMode: compilationMode, + ); + final chromeProxyService = context.service; + inspector = chromeProxyService.inspector; + }); + + tearDownAll(() async { + await context.tearDown(); + }); + + final url = 'org-dartlang-app:///example/scopes/main.dart'; + + String libraryName(CompilationMode compilationMode) => + compilationMode == CompilationMode.frontendServer + ? "example/scopes/main.dart" + : "example/scopes/main"; + + String libraryVariableTypeExpression( + String variable, + CompilationMode compilationMode, + ) => + ''' + (function() { + var dart = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; + var libraryName = '${libraryName(compilationMode)}'; + var library = dart.getModuleLibraries(libraryName)['$url']; + var x = library['$variable']; + return dart.getReifiedType(x); + })(); + '''; + + group('compiler', () { + setUp(() => setCurrentLogWriter(debug: debug)); + + test('uses correct type system', () async { + final remoteObject = await inspector.jsEvaluate( + libraryVariableTypeExpression( + 'libraryPublicFinal', + compilationMode, + ), + ); + expect( + remoteObject.json['className'], + canaryFeatures ? 'dart_rti.Rti.new' : 'Function', + ); + }); + }); + }); +} + void runTests({ required TestSdkConfigurationProvider provider, required CompilationMode compilationMode, diff --git a/dwds/test/instances/instance_canary_test.dart b/dwds/test/instances/instance_canary_test.dart index f1f7d4159..22944e911 100644 --- a/dwds/test/instances/instance_canary_test.dart +++ b/dwds/test/instances/instance_canary_test.dart @@ -5,14 +5,10 @@ @Tags(['daily']) @Timeout(Duration(minutes: 2)) -import 'package:dwds/src/debugging/inspector.dart'; -import 'package:dwds/src/loaders/strategy.dart'; import 'package:test/test.dart'; -import 'package:test_common/logging.dart'; import 'package:test_common/test_sdk_configuration.dart'; import '../fixtures/context.dart'; -import '../fixtures/project.dart'; import 'common/instance_common.dart'; void main() { @@ -28,9 +24,10 @@ void main() { tearDownAll(provider.dispose); for (var compilationMode in CompilationMode.values) { - _runCanaryModeVerificationTests( + runTypeSystemVerificationTests( provider: provider, compilationMode: compilationMode, + canaryFeatures: canaryFeatures, debug: debug, ); @@ -43,65 +40,3 @@ void main() { } }); } - -void _runCanaryModeVerificationTests({ - required TestSdkConfigurationProvider provider, - required CompilationMode compilationMode, - required bool debug, -}) { - final project = TestProject.testScopesWithSoundNullSafety; - - group('$compilationMode |', () { - final context = TestContext(project, provider); - late AppInspector inspector; - - setUpAll(() async { - setCurrentLogWriter(debug: debug); - await context.setUp( - canaryFeatures: true, - compilationMode: compilationMode, - ); - final chromeProxyService = context.service; - inspector = chromeProxyService.inspector; - }); - - tearDownAll(() async { - await context.tearDown(); - }); - - final url = 'org-dartlang-app:///example/scopes/main.dart'; - - String libraryName(CompilationMode compilationMode) => - compilationMode == CompilationMode.frontendServer - ? "example/scopes/main.dart" - : "example/scopes/main"; - - String libraryVariableTypeExpression( - String variable, - CompilationMode compilationMode, - ) => - ''' - (function() { - var dart = ${globalLoadStrategy.loadModuleSnippet}('dart_sdk').dart; - var libraryName = '${libraryName(compilationMode)}'; - var library = dart.getModuleLibraries(libraryName)['$url']; - var x = library['$variable']; - return dart.getReifiedType(x); - })(); - '''; - - group('compiler', () { - setUp(() => setCurrentLogWriter(debug: debug)); - - test('uses new type system', () async { - final remoteObject = await inspector.jsEvaluate( - libraryVariableTypeExpression( - 'libraryPublicFinal', - compilationMode, - ), - ); - expect(remoteObject.json['className'], 'dart_rti.Rti.new'); - }); - }); - }); -} diff --git a/dwds/test/instances/instance_test.dart b/dwds/test/instances/instance_test.dart index d57795479..be95dd443 100644 --- a/dwds/test/instances/instance_test.dart +++ b/dwds/test/instances/instance_test.dart @@ -24,6 +24,13 @@ void main() { tearDownAll(provider.dispose); for (var compilationMode in CompilationMode.values) { + runTypeSystemVerificationTests( + provider: provider, + compilationMode: compilationMode, + canaryFeatures: canaryFeatures, + debug: debug, + ); + runTests( provider: provider, compilationMode: compilationMode, From 42b3427172e04a866df513ba27e0aad1c7da56e2 Mon Sep 17 00:00:00 2001 From: Anna Gringauze Date: Thu, 27 Jul 2023 15:25:58 -0700 Subject: [PATCH 24/24] Now run CI on dev --- .github/workflows/dart.yml | 550 ++++++++++++++++++----- dwds/mono_pkg.yaml | 13 +- example/mono_pkg.yaml | 3 +- fixtures/_webdevSoundSmoke/mono_pkg.yaml | 3 +- webdev/mono_pkg.yaml | 7 +- 5 files changed, 452 insertions(+), 124 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index a86ab74f7..98c48d6b0 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -41,16 +41,16 @@ jobs: - name: mono_repo self validate run: dart pub global run mono_repo generate --validate job_002: - name: "analyzer_and_format; linux; Dart dev; PKGS: frontend_server_client, frontend_server_common, test_common; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" + name: "analyzer_and_format; linux; Dart dev; PKG: dwds; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_version_test.dart`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:frontend_server_client-frontend_server_common-test_common;commands:format-analyze_0" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:format-analyze_0-test_0" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:frontend_server_client-frontend_server_common-test_common + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds os:ubuntu-latest;pub-cache-hosted;sdk:dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest @@ -61,6 +61,70 @@ jobs: - id: checkout name: Checkout repository uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: dwds + - name: "dwds; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + - name: "dwds; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + - name: dwds; dart test test/build/ensure_version_test.dart + run: dart test test/build/ensure_version_test.dart + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + job_003: + name: "analyzer_and_format; linux; Dart dev; PKGS: example, fixtures/_webdevSoundSmoke, frontend_server_client, frontend_server_common, test_common; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-fixtures/_webdevSoundSmoke-frontend_server_client-frontend_server_common-test_common;commands:format-analyze_0" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:example-fixtures/_webdevSoundSmoke-frontend_server_client-frontend_server_common-test_common + os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: example_pub_upgrade + name: example; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: example + - name: "example; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." + if: "always() && steps.example_pub_upgrade.conclusion == 'success'" + working-directory: example + - name: "example; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . + if: "always() && steps.example_pub_upgrade.conclusion == 'success'" + working-directory: example + - id: fixtures__webdevSoundSmoke_pub_upgrade + name: fixtures/_webdevSoundSmoke; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: fixtures/_webdevSoundSmoke + - name: "fixtures/_webdevSoundSmoke; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." + if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" + working-directory: fixtures/_webdevSoundSmoke + - name: "fixtures/_webdevSoundSmoke; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . + if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" + working-directory: fixtures/_webdevSoundSmoke - id: frontend_server_client_pub_upgrade name: frontend_server_client; dart pub upgrade run: dart pub upgrade @@ -100,24 +164,62 @@ jobs: run: dart analyze --fatal-infos . if: "always() && steps.test_common_pub_upgrade.conclusion == 'success'" working-directory: test_common - job_003: - name: "analyzer_and_format; linux; Dart main; PKG: dwds; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_version_test.dart`" + job_004: + name: "analyzer_and_format; linux; Dart dev; PKG: webdev; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_build_test.dart`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds;commands:format-analyze_0-test_0" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev;commands:format-analyze_0-test_7" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:dwds - os:ubuntu-latest;pub-cache-hosted;sdk:main + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev + os:ubuntu-latest;pub-cache-hosted;sdk:dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: - sdk: main + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: webdev_pub_upgrade + name: webdev; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: webdev + - name: "webdev; dart format --output=none --set-exit-if-changed ." + run: "dart format --output=none --set-exit-if-changed ." + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + - name: "webdev; dart analyze --fatal-infos ." + run: dart analyze --fatal-infos . + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + - name: webdev; dart test test/build/ensure_build_test.dart + run: dart test test/build/ensure_build_test.dart + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + job_005: + name: "unit_test; linux; Dart dev; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --tags=extension`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:command-test_1" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds + os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev - id: checkout name: Checkout repository uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b @@ -126,104 +228,125 @@ jobs: run: dart pub upgrade if: "always() && steps.checkout.conclusion == 'success'" working-directory: dwds - - name: "dwds; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" - working-directory: dwds - - name: "dwds; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . + - name: "dwds; Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" + run: "Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" working-directory: dwds - - name: dwds; dart test test/build/ensure_version_test.dart - run: dart test test/build/ensure_version_test.dart + - name: "dwds; dart test --tags=extension" + run: "dart test --tags=extension" if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" working-directory: dwds - job_004: - name: "analyzer_and_format; linux; Dart main; PKGS: example, fixtures/_webdevSoundSmoke; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`" + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_006: + name: "unit_test; linux; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:example-fixtures/_webdevSoundSmoke;commands:format-analyze_0" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:test_2" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:example-fixtures/_webdevSoundSmoke - os:ubuntu-latest;pub-cache-hosted;sdk:main + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds + os:ubuntu-latest;pub-cache-hosted;sdk:dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: - sdk: main + sdk: dev - id: checkout name: Checkout repository uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - id: example_pub_upgrade - name: example; dart pub upgrade + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade run: dart pub upgrade if: "always() && steps.checkout.conclusion == 'success'" - working-directory: example - - name: "example; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.example_pub_upgrade.conclusion == 'success'" - working-directory: example - - name: "example; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . - if: "always() && steps.example_pub_upgrade.conclusion == 'success'" - working-directory: example - - id: fixtures__webdevSoundSmoke_pub_upgrade - name: fixtures/_webdevSoundSmoke; dart pub upgrade + working-directory: dwds + - name: "dwds; dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" + run: "dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_007: + name: "unit_test; linux; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:test_3" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds + os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade run: dart pub upgrade if: "always() && steps.checkout.conclusion == 'success'" - working-directory: fixtures/_webdevSoundSmoke - - name: "fixtures/_webdevSoundSmoke; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" - working-directory: fixtures/_webdevSoundSmoke - - name: "fixtures/_webdevSoundSmoke; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . - if: "always() && steps.fixtures__webdevSoundSmoke_pub_upgrade.conclusion == 'success'" - working-directory: fixtures/_webdevSoundSmoke - job_005: - name: "analyzer_and_format; linux; Dart main; PKG: webdev; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos .`, `dart test test/build/ensure_build_test.dart`" + working-directory: dwds + - name: "dwds; dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" + run: "dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_008: + name: "unit_test; linux; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:webdev;commands:format-analyze_0-test_7" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds;commands:test_4" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:main;packages:webdev - os:ubuntu-latest;pub-cache-hosted;sdk:main + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:dwds + os:ubuntu-latest;pub-cache-hosted;sdk:dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d with: - sdk: main + sdk: dev - id: checkout name: Checkout repository uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b - - id: webdev_pub_upgrade - name: webdev; dart pub upgrade + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade run: dart pub upgrade if: "always() && steps.checkout.conclusion == 'success'" - working-directory: webdev - - name: "webdev; dart format --output=none --set-exit-if-changed ." - run: "dart format --output=none --set-exit-if-changed ." - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - - name: "webdev; dart analyze --fatal-infos ." - run: dart analyze --fatal-infos . - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - - name: webdev; dart test test/build/ensure_build_test.dart - run: dart test test/build/ensure_build_test.dart - if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" - working-directory: webdev - job_006: + working-directory: dwds + - name: "dwds; dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" + run: "dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_009: name: "unit_test; linux; Dart dev; PKG: frontend_server_client; `dart test -j 1`" runs-on: ubuntu-latest steps: @@ -258,8 +381,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_007: + job_010: name: "unit_test; linux; Dart dev; PKG: test_common; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --exclude-tags=release`" runs-on: ubuntu-latest steps: @@ -298,8 +420,46 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_008: + job_011: + name: "unit_test; linux; Dart dev; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" + runs-on: ubuntu-latest + steps: + - name: Cache Pub hosted dependencies + uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d + with: + path: "~/.pub-cache/hosted" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev;commands:command-test_5" + restore-keys: | + os:ubuntu-latest;pub-cache-hosted;sdk:dev;packages:webdev + os:ubuntu-latest;pub-cache-hosted;sdk:dev + os:ubuntu-latest;pub-cache-hosted + os:ubuntu-latest + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: webdev_pub_upgrade + name: webdev; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: webdev + - name: "webdev; Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" + run: "Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &" + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + - name: "webdev; dart test -j 1" + run: dart test -j 1 + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_012: name: "unit_test; linux; Dart main; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --tags=extension`" runs-on: ubuntu-latest steps: @@ -338,8 +498,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_009: + job_013: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" runs-on: ubuntu-latest steps: @@ -374,8 +533,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_010: + job_014: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" runs-on: ubuntu-latest steps: @@ -410,8 +568,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_011: + job_015: name: "unit_test; linux; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" runs-on: ubuntu-latest steps: @@ -446,8 +603,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_012: + job_016: name: "unit_test; linux; Dart main; PKG: frontend_server_client; `dart test -j 1`" runs-on: ubuntu-latest steps: @@ -482,8 +638,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_013: + job_017: name: "unit_test; linux; Dart main; PKG: test_common; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test --exclude-tags=release`" runs-on: ubuntu-latest steps: @@ -522,8 +677,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_014: + job_018: name: "unit_test; linux; Dart main; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest steps: @@ -562,8 +716,107 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_015: + job_019: + name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --tags=extension`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: dwds + - name: "dwds; dart test --tags=extension" + run: "dart test --tags=extension" + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_020: + name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: dwds + - name: "dwds; dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" + run: "dart test --total-shards 3 --shard-index 0 --exclude-tags=extension" + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_021: + name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: dwds + - name: "dwds; dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" + run: "dart test --total-shards 3 --shard-index 1 --exclude-tags=extension" + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_022: + name: "unit_test; windows; Dart dev; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: dwds_pub_upgrade + name: dwds; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: dwds + - name: "dwds; dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" + run: "dart test --total-shards 3 --shard-index 2 --exclude-tags=extension" + if: "always() && steps.dwds_pub_upgrade.conclusion == 'success'" + working-directory: dwds + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_023: name: "unit_test; windows; Dart dev; PKG: frontend_server_client; `dart test -j 1`" runs-on: windows-latest steps: @@ -588,8 +841,32 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_016: + job_024: + name: "unit_test; windows; Dart dev; PKG: webdev; `dart test -j 1`" + runs-on: windows-latest + steps: + - name: Setup Dart SDK + uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d + with: + sdk: dev + - id: checkout + name: Checkout repository + uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b + - id: webdev_pub_upgrade + name: webdev; dart pub upgrade + run: dart pub upgrade + if: "always() && steps.checkout.conclusion == 'success'" + working-directory: webdev + - name: "webdev; dart test -j 1" + run: dart test -j 1 + if: "always() && steps.webdev_pub_upgrade.conclusion == 'success'" + working-directory: webdev + needs: + - job_001 + - job_002 + - job_003 + - job_004 + job_025: name: "unit_test; windows; Dart dev; PKG: test_common; `dart test --exclude-tags=release`" runs-on: windows-latest steps: @@ -614,8 +891,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_017: + job_026: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --tags=extension`" runs-on: windows-latest steps: @@ -640,8 +916,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_018: + job_027: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 0 --exclude-tags=extension`" runs-on: windows-latest steps: @@ -666,8 +941,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_019: + job_028: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 1 --exclude-tags=extension`" runs-on: windows-latest steps: @@ -692,8 +966,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_020: + job_029: name: "unit_test; windows; Dart main; PKG: dwds; `dart test --total-shards 3 --shard-index 2 --exclude-tags=extension`" runs-on: windows-latest steps: @@ -718,8 +991,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_021: + job_030: name: "unit_test; windows; Dart main; PKG: frontend_server_client; `dart test -j 1`" runs-on: windows-latest steps: @@ -744,8 +1016,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_022: + job_031: name: "unit_test; windows; Dart main; PKG: webdev; `dart test -j 1`" runs-on: windows-latest steps: @@ -770,8 +1041,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_023: + job_032: name: "unit_test; windows; Dart main; PKG: test_common; `dart test --exclude-tags=release`" runs-on: windows-latest steps: @@ -796,8 +1066,7 @@ jobs: - job_002 - job_003 - job_004 - - job_005 - job_024: + job_033: name: "beta_cron; linux; Dart beta; PKG: dwds; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -856,7 +1125,16 @@ jobs: - job_021 - job_022 - job_023 - job_025: + - job_024 + - job_025 + - job_026 + - job_027 + - job_028 + - job_029 + - job_030 + - job_031 + - job_032 + job_034: name: "beta_cron; linux; Dart beta; PKG: webdev; `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &`, `dart test -j 1`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -915,7 +1193,16 @@ jobs: - job_021 - job_022 - job_023 - job_026: + - job_024 + - job_025 + - job_026 + - job_027 + - job_028 + - job_029 + - job_030 + - job_031 + - job_032 + job_035: name: "beta_cron; linux; Dart beta; PKG: dwds; `dart analyze .`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -970,7 +1257,16 @@ jobs: - job_021 - job_022 - job_023 - job_027: + - job_024 + - job_025 + - job_026 + - job_027 + - job_028 + - job_029 + - job_030 + - job_031 + - job_032 + job_036: name: "beta_cron; linux; Dart beta; PKG: webdev; `dart analyze .`" runs-on: ubuntu-latest if: "github.event_name == 'schedule'" @@ -1025,7 +1321,16 @@ jobs: - job_021 - job_022 - job_023 - job_028: + - job_024 + - job_025 + - job_026 + - job_027 + - job_028 + - job_029 + - job_030 + - job_031 + - job_032 + job_037: name: "beta_cron; windows; Dart beta; PKG: dwds; `dart test -j 1`" runs-on: windows-latest if: "github.event_name == 'schedule'" @@ -1070,7 +1375,16 @@ jobs: - job_021 - job_022 - job_023 - job_029: + - job_024 + - job_025 + - job_026 + - job_027 + - job_028 + - job_029 + - job_030 + - job_031 + - job_032 + job_038: name: "beta_cron; windows; Dart beta; PKG: webdev; `dart test -j 1`" runs-on: windows-latest if: "github.event_name == 'schedule'" @@ -1115,7 +1429,16 @@ jobs: - job_021 - job_022 - job_023 - job_030: + - job_024 + - job_025 + - job_026 + - job_027 + - job_028 + - job_029 + - job_030 + - job_031 + - job_032 + job_039: name: Notify failure runs-on: ubuntu-latest if: "(github.event_name == 'push' || github.event_name == 'schedule') && failure()" @@ -1156,3 +1479,12 @@ jobs: - job_027 - job_028 - job_029 + - job_030 + - job_031 + - job_032 + - job_033 + - job_034 + - job_035 + - job_036 + - job_037 + - job_038 diff --git a/dwds/mono_pkg.yaml b/dwds/mono_pkg.yaml index e3ae564ea..15b55041f 100644 --- a/dwds/mono_pkg.yaml +++ b/dwds/mono_pkg.yaml @@ -5,8 +5,7 @@ stages: - format - analyze: --fatal-infos . - test: test/build/ensure_version_test.dart - # sdk: dev - sdk: main + sdk: dev - unit_test: # Linux extension tests: # Note: `Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &` must be @@ -15,7 +14,7 @@ stages: - command: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - test: --tags=extension sdk: - # -dev + - dev - main os: - linux @@ -23,7 +22,7 @@ stages: - group: - test: --tags=extension sdk: - # -dev + - dev - main os: - windows @@ -31,7 +30,7 @@ stages: - group: - test: --total-shards 3 --shard-index 0 --exclude-tags=extension sdk: - # -dev + - dev - main os: - linux @@ -40,7 +39,7 @@ stages: - group: - test: --total-shards 3 --shard-index 1 --exclude-tags=extension sdk: - # -dev + - dev - main os: - linux @@ -49,7 +48,7 @@ stages: - group: - test: --total-shards 3 --shard-index 2 --exclude-tags=extension sdk: - # -dev + - dev - main os: - linux diff --git a/example/mono_pkg.yaml b/example/mono_pkg.yaml index 19f6ef916..12cfc8524 100644 --- a/example/mono_pkg.yaml +++ b/example/mono_pkg.yaml @@ -4,8 +4,7 @@ stages: - group: - format - analyze: --fatal-infos . - # sdk: dev - sdk: main + sdk: dev cache: directories: diff --git a/fixtures/_webdevSoundSmoke/mono_pkg.yaml b/fixtures/_webdevSoundSmoke/mono_pkg.yaml index 19f6ef916..12cfc8524 100644 --- a/fixtures/_webdevSoundSmoke/mono_pkg.yaml +++ b/fixtures/_webdevSoundSmoke/mono_pkg.yaml @@ -4,8 +4,7 @@ stages: - group: - format - analyze: --fatal-infos . - # sdk: dev - sdk: main + sdk: dev cache: directories: diff --git a/webdev/mono_pkg.yaml b/webdev/mono_pkg.yaml index d526dcc0a..8fd305797 100644 --- a/webdev/mono_pkg.yaml +++ b/webdev/mono_pkg.yaml @@ -5,19 +5,18 @@ stages: - format - analyze: --fatal-infos . - test: test/build/ensure_build_test.dart - # sdk: dev - sdk: main + sdk: dev - unit_test: - group: - command: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - test: -j 1 sdk: - # - dev + - dev - main - test: -j 1 os: windows sdk: - # - dev + - dev - main - beta_cron: - analyze: .