Skip to content

Yj dartdevembedder 2488 #2531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 3, 2024
1 change: 1 addition & 0 deletions dwds/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
to use the provided `name` in a `ModuleMetadata`. Metadata provided by DDC
when using the library bundle format does not provide a useful bundle name.
- Migrate to `package:web` v1.1.0.
- Added support for some debugging APIs with the DDC library bundle format. - [#2488](https://github.com/dart-lang/webdev/issues/2488)

## 24.1.0

Expand Down
86 changes: 86 additions & 0 deletions dwds/lib/src/debugging/dart_runtime_debugger.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:dwds/src/loaders/strategy.dart';

class DartRuntimeDebugger {
final LoadStrategy _loadStrategy;
final bool _useLibraryBundleExpression;

DartRuntimeDebugger({
required LoadStrategy loadStrategy,
required bool useLibraryBundleExpression,
}) : _loadStrategy = loadStrategy,
_useLibraryBundleExpression = useLibraryBundleExpression;

String _generateJsExpression(
String ddcExpression,
String libraryBundleExpression,
) {
return _useLibraryBundleExpression
? libraryBundleExpression
: ddcExpression;
}

String _wrapWithSdkLoader(String args, String functionCall) {
return '''
function($args) {
const sdk = ${_loadStrategy.loadModuleSnippet}("dart_sdk");
const dart = sdk.dart;
return dart.$functionCall;
}
''';
}

String _wrapWithBundleLoader(String args, String functionCall) {
return '''
function($args) {
return dartDevEmbedder.debugger.$functionCall;
}
''';
}

String _buildExpression(
String args,
String ddcFunction,
String libraryBundleFunction,
) {
return _generateJsExpression(
_wrapWithSdkLoader(args, ddcFunction),
_wrapWithBundleLoader(args, libraryBundleFunction),
);
}

String getObjectMetadataJsExpression() {
return _buildExpression(
'arg',
'getObjectMetadata(arg)',
'getObjectMetadata(arg)',
);
}

String getObjectFieldNamesJsExpression() {
return _buildExpression(
'',
'getObjectFieldNames(this)',
'getObjectFieldNames(this)',
);
}

String getFunctionMetadataJsExpression() {
return _buildExpression(
'',
'getFunctionMetadata(this)',
'getFunctionName(this)',
);
}

String getSubRangeJsExpression() {
return _buildExpression(
'offset, count',
'getSubRange(this, offset, count)',
'getSubRange(this, offset, count)',
);
}
}
9 changes: 2 additions & 7 deletions dwds/lib/src/debugging/inspector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -643,13 +643,8 @@ class AppInspector implements AppInspectorInterface {
// 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) {
const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}("dart_sdk");
const dart = sdk.dart;
return dart.getSubRange(this, offset, count);
}
''';
final expression = globalToolConfiguration.loadStrategy.dartRuntimeDebugger
.getSubRangeJsExpression();

return await jsCallFunctionOn(receiver, expression, args);
}
Expand Down
6 changes: 3 additions & 3 deletions dwds/lib/src/debugging/instance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -772,9 +772,9 @@ class InstanceHelper extends Domain {
//
// For maps and lists it's more complicated. Treat the actual SDK versions
// of these as special.
final fieldNameExpression =
_jsRuntimeFunctionCall('getObjectFieldNames(this)');

final fieldNameExpression = globalToolConfiguration
.loadStrategy.dartRuntimeDebugger
.getObjectFieldNamesJsExpression();
final result = await inspector.jsCallFunctionOn(
remoteObject,
fieldNameExpression,
Expand Down
10 changes: 3 additions & 7 deletions dwds/lib/src/debugging/metadata/class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,9 @@ class ClassMetaDataHelper {
/// Returns null if the [remoteObject] is not a Dart class.
Future<ClassMetaData?> metaDataFor(RemoteObject remoteObject) async {
try {
final evalExpression = '''
function(arg) {
const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk');
const dart = sdk.dart;
return dart.getObjectMetadata(arg);
}
''';
final evalExpression = globalToolConfiguration
.loadStrategy.dartRuntimeDebugger
.getObjectMetadataJsExpression();

final result = await _inspector.jsCallFunctionOn(
remoteObject,
Expand Down
10 changes: 3 additions & 7 deletions dwds/lib/src/debugging/metadata/function.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@ class FunctionMetaData {
RemoteDebugger remoteDebugger,
RemoteObject remoteObject,
) async {
final evalExpression = '''
function() {
const sdk = ${globalToolConfiguration.loadStrategy.loadModuleSnippet}('dart_sdk');
const dart = sdk.dart;
return dart.getFunctionMetadata(this);
}
''';
final evalExpression = globalToolConfiguration
.loadStrategy.dartRuntimeDebugger
.getFunctionMetadataJsExpression();

final response = await remoteDebugger.sendCommand(
'Runtime.callFunctionOn',
Expand Down
7 changes: 7 additions & 0 deletions dwds/lib/src/loaders/ddc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:convert';

import 'package:dwds/src/debugging/dart_runtime_debugger.dart';
import 'package:dwds/src/debugging/metadata/provider.dart';
import 'package:dwds/src/loaders/strategy.dart';
import 'package:dwds/src/readers/asset_reader.dart';
Expand Down Expand Up @@ -163,6 +164,12 @@ class DdcStrategy extends LoadStrategy {
@override
String get loadModuleSnippet => 'dart_library.import';

@override
late final DartRuntimeDebugger dartRuntimeDebugger = DartRuntimeDebugger(
loadStrategy: this,
useLibraryBundleExpression: false,
);

@override
BuildSettings get buildSettings => _buildSettings;

Expand Down
7 changes: 7 additions & 0 deletions dwds/lib/src/loaders/ddc_library_bundle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:convert';

import 'package:dwds/src/debugging/dart_runtime_debugger.dart';
import 'package:dwds/src/debugging/metadata/provider.dart';
import 'package:dwds/src/loaders/ddc.dart';
import 'package:dwds/src/loaders/strategy.dart';
Expand Down Expand Up @@ -140,6 +141,12 @@ class DdcLibraryBundleStrategy extends LoadStrategy {
"function() { throw new Error('LoadStrategy.loadModuleSnippet is used. "
"This is currently unsupported in the DDC library bundle format.'); }";

@override
late final DartRuntimeDebugger dartRuntimeDebugger = DartRuntimeDebugger(
loadStrategy: this,
useLibraryBundleExpression: true,
);

@override
BuildSettings get buildSettings => _buildSettings;

Expand Down
9 changes: 8 additions & 1 deletion dwds/lib/src/loaders/require.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:convert';

import 'package:dwds/src/debugging/dart_runtime_debugger.dart';
import 'package:dwds/src/debugging/metadata/provider.dart';
import 'package:dwds/src/loaders/strategy.dart';
import 'package:dwds/src/readers/asset_reader.dart';
Expand Down Expand Up @@ -164,6 +165,12 @@ class RequireStrategy extends LoadStrategy {
@override
String get loadModuleSnippet => 'require';

@override
late final DartRuntimeDebugger dartRuntimeDebugger = DartRuntimeDebugger(
loadStrategy: this,
useLibraryBundleExpression: false,
);

/// Require JS config for ddc.
///
/// Sets the base url to `/` so that all modules can be loaded using absolute
Expand All @@ -180,7 +187,7 @@ $_baseUrlScript;
require.config({
baseUrl: baseUrl,
waitSeconds: 0,
paths: modulePaths
paths: modulePaths
});
const modulesGraph = new Map();
requirejs.onResourceLoad = function (context, map, depArray) {
Expand Down
4 changes: 4 additions & 0 deletions dwds/lib/src/loaders/strategy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import 'dart:typed_data';

import 'package:dwds/src/debugging/dart_runtime_debugger.dart';
import 'package:dwds/src/debugging/metadata/provider.dart';
import 'package:dwds/src/readers/asset_reader.dart';
import 'package:dwds/src/services/expression_compiler.dart';
Expand Down Expand Up @@ -43,6 +44,9 @@ abstract class LoadStrategy {
/// argument which is the module name to load.
String get loadModuleSnippet;

/// Provides a runtime debugger for the Dart runtime.
DartRuntimeDebugger get dartRuntimeDebugger;

/// The relative root path for library paths. The current directory will be
/// used if this is not overridden.
String? get libraryRoot => null;
Expand Down
7 changes: 7 additions & 0 deletions dwds/test/fixtures/fakes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'dart:async';

import 'package:dwds/asset_reader.dart';
import 'package:dwds/src/debugging/dart_runtime_debugger.dart';
import 'package:dwds/src/debugging/execution_context.dart';
import 'package:dwds/src/debugging/inspector.dart';
import 'package:dwds/src/debugging/instance.dart';
Expand Down Expand Up @@ -362,6 +363,12 @@ class FakeStrategy extends LoadStrategy {
@override
String get loadModuleSnippet => '';

@override
late final DartRuntimeDebugger dartRuntimeDebugger = DartRuntimeDebugger(
loadStrategy: this,
useLibraryBundleExpression: false,
);

@override
ReloadConfiguration get reloadConfiguration => ReloadConfiguration.none;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
@Timeout(Duration(minutes: 5))
library;

import 'dart:io';

import 'package:dwds/expression_compiler.dart';
import 'package:test/test.dart';
import 'package:test_common/test_sdk_configuration.dart';
Expand Down Expand Up @@ -41,11 +43,9 @@ void main() async {
debug: debug,
);
},
// TODO(#2488): Restore the skip argument below, related to
// https://github.com/dart-lang/sdk/issues/49277, once
// https://github.com/dart-lang/webdev/issues/2488 is resolved.
// skip: indexBaseMode == IndexBaseMode.base && Platform.isWindows,
skip: 'https://github.com/dart-lang/webdev/issues/2488',
skip: indexBaseMode == IndexBaseMode.base && Platform.isWindows
? 'Skipped on Windows when indexBaseMode is base. See issue: https://github.com/dart-lang/sdk/issues/49277'
: null,
);
}
});
Expand Down
Loading