Skip to content

Commit

Permalink
Version 3.5.0-20.0.dev
Browse files Browse the repository at this point in the history
Merge eda91b4 into dev
  • Loading branch information
Dart CI committed Apr 4, 2024
2 parents 0ac840b + eda91b4 commit fc2842c
Show file tree
Hide file tree
Showing 35 changed files with 1,047 additions and 85 deletions.
5 changes: 5 additions & 0 deletions pkg/dds/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 4.1.0
- Internal change: removed static method `DevToolsUtils.initializeAnalytics`
and prepared DDS for using `unified_analytics` through the Dart Tooling Daemon.
- Internal change: removed `analytics` parameter from the DevTools server `defaultHandler` method.

# 4.0.0
- Updated DDS protocol to version 2.0.
- Added `readyToResume` and `requireUserPermissionToResume` RPCs.
Expand Down
1 change: 0 additions & 1 deletion pkg/dds/lib/devtools_server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ class DevToolsServer {
handler ??= await defaultHandler(
buildDir: customDevToolsPath!,
clientManager: clientManager,
analytics: DevToolsUtils.initializeAnalytics(),
dtd: (uri: dtdUri, secret: dtdSecret),
);

Expand Down
1 change: 1 addition & 0 deletions pkg/dds/lib/src/dap/adapters/dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ abstract class DartDebugAdapter<TL extends LaunchRequestArguments,
sendConsoleOutput('Connecting to VM Service at $uri');
final vmService = await _vmServiceConnectUri(uri.toString());
logger?.call('Connected to debugger at $uri!');
sendConsoleOutput('Connected to the VM Service.');

// Fetch DDS capabilities.
final supportedProtocols = await vmService.getSupportedProtocols();
Expand Down
5 changes: 3 additions & 2 deletions pkg/dds/lib/src/devtools/handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ FutureOr<Handler> defaultHandler({
DartDevelopmentServiceImpl? dds,
required String buildDir,
ClientManager? clientManager,
Analytics? analytics,
Handler? notFoundHandler,
DTDConnectionInfo? dtd,
}) {
Expand Down Expand Up @@ -149,7 +148,9 @@ FutureOr<Handler> defaultHandler({
extensionsManager: ExtensionsManager(buildDir: buildDir),
deeplinkManager: DeeplinkManager(),
dtd: dtd,
analytics: analytics ?? NoOpAnalytics(),
// TODO(https://github.com/flutter/devtools/issues/7496): remove this
// parameter when bringing in the breaking change from devtools_shared.
analytics: NoOpAnalytics(),
);
}

Expand Down
46 changes: 0 additions & 46 deletions pkg/dds/lib/src/devtools/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'dart:convert';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:unified_analytics/unified_analytics.dart';
import 'package:vm_service/utils.dart';
import 'package:vm_service/vm_service.dart';

Expand Down Expand Up @@ -40,51 +39,6 @@ abstract class DevToolsUtils {
}
}

/// Provides an instance of [Analytics] with the Dart SDK version and Flutter
/// version and channel if running the dart executable shipped with Flutter.
static Analytics initializeAnalytics() {
// Use helper method from package:unified_analytics to return
// a cleaned dart sdk verison
final dartVersion = parseDartSDKVersion(Platform.version);

// The location for the dart executable in the following path
// /path/to/dart-sdk/bin/dart
final dartExecutableFile = File(Platform.resolvedExecutable);

// The flutter version file can also be found if we are running the
// dart sdk that is shipped with flutter in the following path
// /path/to/flutter/bin/cache/dart-sdk/bin/dart
final flutterVersionFile = File(path.join(
dartExecutableFile.parent.path, '..', '..', 'flutter.version.json'));

// These fields are defined as nullable incase the dart sdk being run
// is not the sdk shipped with flutter
String? flutterChannel;
String? flutterVersion;

// If the dart sdk being used is vendored with the flutter sdk, we can
// expect this file to exist
if (flutterVersionFile.existsSync()) {
try {
final flutterObj = jsonDecode(flutterVersionFile.readAsStringSync())
as Map<String, Object?>;
flutterChannel = flutterObj['channel'] as String?;
flutterVersion = flutterObj['frameworkVersion'] as String?;
} catch (_) {
// Leave the flutter channel and version info null
}
}

return Analytics(
tool: DashTool.devtools,
dartVersion: dartVersion,
// TODO(eliasyishak): pass this information (https://github.com/flutter/devtools/issues/7230)
// clientIde: 'TBD',
flutterChannel: flutterChannel,
flutterVersion: flutterVersion,
);
}

static void printOutput(
String? message,
Object json, {
Expand Down
6 changes: 4 additions & 2 deletions pkg/dds/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: dds
version: 4.0.0
version: 4.1.0
description: >-
A library used to spawn the Dart Developer Service, used to communicate with
a Dart VM Service instance.
Expand Down Expand Up @@ -29,9 +29,11 @@ dependencies:
sse: ^4.0.0
stack_trace: ^1.10.0
stream_channel: ^2.0.0
# TODO(https://github.com/flutter/devtools/issues/7496): remove this dep
# when making the breaking change to devtools_shared.
unified_analytics: ^6.0.0
vm_service: ^14.0.0
web_socket_channel: ^2.0.0
unified_analytics: ^6.0.0

# We use 'any' version constraints here as we get our package versions from
# the dart-lang/sdk repo's DEPS file. Note that this is a special case; the
Expand Down
4 changes: 2 additions & 2 deletions pkg/dds/test/dap/integration/debug_attach_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ main() {

// Expect the normal applications output.
final output = outputEvents
.skip(1)
.skip(2)
.map((e) => e.output)
// The stdout also contains the VM Service+DevTools banners.
.where(
Expand Down Expand Up @@ -98,7 +98,7 @@ main() {

// Expect the normal applications output.
final output = outputEvents
.skip(1)
.skip(2)
.map((e) => e.output)
// The stdout also contains the VM Service+DevTools banners.
.where(
Expand Down
4 changes: 2 additions & 2 deletions pkg/dds/test/dap/integration/debug_logging_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ void main(List<String> args) async {

var outputEvents = await dap.client.collectOutput(file: testFile);

// Skip the first line because it's the VM Service connection info.
final output = outputEvents.skip(1).map((e) => e.output).join();
// Skip the first two lines because it's the VM Service connection info.
final output = outputEvents.skip(2).map((e) => e.output).join();
expectLines(output, [
'[log] this is a test',
' across two lines',
Expand Down
4 changes: 2 additions & 2 deletions pkg/dds/test/dap/integration/debug_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ main() {
expect(vmConnection.category, anyOf('console', isNull));

// Expect the normal applications output.
final output = outputEvents.skip(1).map((e) => e.output).join();
final output = outputEvents.skip(2).map((e) => e.output).join();
expectLines(output, [
'Hello!',
'World!',
Expand Down Expand Up @@ -119,7 +119,7 @@ main() {
// Expect the normal applications output. This means we set up the
// debugger without crashing, even though we imported files with commas
// in the name.
final output = outputEvents.skip(1).map((e) => e.output).join();
final output = outputEvents.skip(2).map((e) => e.output).join();
expectLines(output, [
'Hello!',
'World!',
Expand Down
4 changes: 2 additions & 2 deletions pkg/dds/test/dap/integration/test_support.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import 'test_server.dart';

/// A [RegExp] that matches the "Connecting to VM Service" banner that is sent
/// by the DAP adapter as the first output event for a debug session.
final dapVmServiceBannerPattern =
RegExp(r'Connecting to VM Service at ([^\s]+)\s');
final dapVmServiceBannerPattern = RegExp(
r'Connecting to VM Service at ([^\s]+)\s|Connected to the VM Service');

/// Whether to run the DAP server in-process with the tests, or externally in
/// another process.
Expand Down
54 changes: 46 additions & 8 deletions pkg/dev_compiler/lib/src/kernel/compiler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4899,7 +4899,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
// Otherwise generate this as a normal typed property get.
var jsMemberName =
_emitMemberName(memberName, member: node.interfaceTarget);
return js_ast.PropertyAccess(jsReceiver, jsMemberName);
var instanceGet = js_ast.PropertyAccess(jsReceiver, jsMemberName);
return _isNullCheckableJsInterop(node.interfaceTarget)
? _wrapWithJsInteropNullCheck(instanceGet)
: instanceGet;
}

@override
Expand Down Expand Up @@ -4943,7 +4946,8 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
}
var jsPropertyAccess = js_ast.PropertyAccess(jsReceiver, jsMemberName);
return isJsMember(member)
? runtimeCall('tearoffInterop(#)', [jsPropertyAccess])
? runtimeCall('tearoffInterop(#, #)',
[jsPropertyAccess, js.boolean(_isNullCheckableJsInterop(member))])
: jsPropertyAccess;
}

Expand Down Expand Up @@ -5011,6 +5015,26 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
return false;
}

/// Returns [expression] wrapped in an optional null check.
///
/// The null check is enabled by setting a flag during the application
/// bootstrap via `jsInteropNonNullAsserts(true)` in the SDK runtime library.
js_ast.Expression _wrapWithJsInteropNullCheck(js_ast.Expression expression) =>
runtimeCall('jsInteropNullCheck(#)', [expression]);

/// Returns `true` when [member] is a JavaScript interop API that should be
/// checked to be not null when the runtime flag `--interop-null-assertions`
/// is enabled.
///
/// These APIs are defined using the non-static package:js interop library and
/// are typed to be non-nullable.
bool _isNullCheckableJsInterop(Member member) {
var type =
member is Procedure ? member.function.returnType : member.getterType;
return type.nullability == Nullability.nonNullable &&
isNonStaticJsInterop(member);
}

/// Return whether [member] returns a native object whose type needs to be
/// null-checked in sound null-safety.
///
Expand Down Expand Up @@ -5097,7 +5121,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
return runtimeCall('global');
}
}
return _emitStaticGet(target);
var staticGet = _emitStaticGet(target);
return _isNullCheckableJsInterop(target)
? _wrapWithJsInteropNullCheck(staticGet)
: staticGet;
}

@override
Expand Down Expand Up @@ -5138,15 +5165,21 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>

@override
js_ast.Expression visitInstanceInvocation(InstanceInvocation node) {
return _emitMethodCall(
var invocation = _emitMethodCall(
node.receiver, node.interfaceTarget, node.arguments, node);
return _isNullCheckableJsInterop(node.interfaceTarget)
? _wrapWithJsInteropNullCheck(invocation)
: invocation;
}

@override
js_ast.Expression visitInstanceGetterInvocation(
InstanceGetterInvocation node) {
return _emitMethodCall(
var getterInvocation = _emitMethodCall(
node.receiver, node.interfaceTarget, node.arguments, node);
return _isNullCheckableJsInterop(node.interfaceTarget)
? _wrapWithJsInteropNullCheck(getterInvocation)
: getterInvocation;
}

@override
Expand Down Expand Up @@ -6152,7 +6185,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>

var fn = _emitStaticTarget(target);
var args = _emitArgumentList(node.arguments, target: target);
return js_ast.Call(fn, args);
var staticCall = js_ast.Call(fn, args);
return _isNullCheckableJsInterop(target)
? _wrapWithJsInteropNullCheck(staticCall)
: staticCall;
}

js_ast.Expression _emitJSObjectGetPrototypeOf(js_ast.Expression obj,
Expand Down Expand Up @@ -7171,8 +7207,10 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
return _emitStaticTarget(node.target);
}
if (node.target.isExternal && !isSdk) {
return runtimeCall(
'tearoffInterop(#)', [_emitStaticTarget(node.target)]);
return runtimeCall('tearoffInterop(#, #)', [
_emitStaticTarget(node.target),
js.boolean(_isNullCheckableJsInterop(node.target))
]);
}
}
if (node is TypeLiteralConstant) {
Expand Down
3 changes: 3 additions & 0 deletions pkg/dtd/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2.2.0
- Added new response types `Success`, `StringResponse`, `BoolResponse`, and `StringListResponse`.

## 2.1.0
- Added `getProjectRoots` API.
- Expose constant values from `dtd.dart`.
Expand Down
3 changes: 2 additions & 1 deletion pkg/dtd/lib/dtd.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
/// Support for communicating with the Dart Tooling Daemon.
library;

export 'src/constants.dart';
export 'src/dart_tooling_daemon.dart';
export 'src/file_system/constants.dart';
export 'src/file_system/types.dart';
export 'src/response_types.dart';
export 'src/rpc_error_codes.dart';
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// Service name for the DTD-hosted file system service.
const String kFileSystemServiceName = 'FileSystem';

/// The default value for the `depth` parameter in the
Expand All @@ -12,3 +13,6 @@ const String kFileSystemServiceName = 'FileSystem';
/// the workspace roots being searched are large directories; for example, if
/// a user opened their home directory in their IDE.
const int defaultGetProjectRootsDepth = 4;

/// Service name for the DTD-hosted unified analytics service.
const String kUnifiedAnalyticsServiceName = 'UnifiedAnalytics';
Loading

0 comments on commit fc2842c

Please sign in to comment.