Version 2.12.0-18.0.dev
Merge commit '172647612080b72c07a5f48c439215d11db880d0' into 'dev'
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 392a4b1..5ee814d 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -613,7 +613,8 @@
@override
void visitPostfixExpression(PostfixExpression node) {
_deprecatedVerifier.postfixExpression(node);
- if (node.operand.staticType?.isDartCoreNull ?? false) {
+ if (node.operator.type == TokenType.BANG &&
+ node.operand.staticType.isDartCoreNull) {
_errorReporter.reportErrorForNode(HintCode.NULL_CHECK_ALWAYS_FAILS, node);
}
super.visitPostfixExpression(node);
@@ -1641,9 +1642,12 @@
class _InvalidAccessVerifier {
static final _templateExtension = '.template';
- static final _testDir = '${path.separator}test${path.separator}';
- static final _testDriverDir = '${path.separator}test_driver${path.separator}';
- static final _testingDir = '${path.separator}testing${path.separator}';
+ static final _testDirectories = [
+ '${path.separator}test${path.separator}',
+ '${path.separator}integration_test${path.separator}',
+ '${path.separator}test_driver${path.separator}',
+ '${path.separator}testing${path.separator}',
+ ];
final ErrorReporter _errorReporter;
final LibraryElement _library;
@@ -1658,9 +1662,7 @@
this._errorReporter, this._library, this._workspacePackage) {
var path = _library.source.fullName;
_inTemplateSource = path.contains(_templateExtension);
- _inTestDirectory = path.contains(_testDir) ||
- path.contains(_testDriverDir) ||
- path.contains(_testingDir);
+ _inTestDirectory = _testDirectories.any(path.contains);
}
/// Produces a hint if [identifier] is accessed from an invalid location.
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 9772a68..8e9e71c 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -491,6 +491,8 @@
int toInt();
}
+abstract class Match {}
+
class Object {
const Object();
@@ -503,7 +505,9 @@
external dynamic noSuchMethod(Invocation invocation);
}
-abstract class Pattern {}
+abstract class Pattern {
+ Iterable<Match> allMatches(String string, [int start = 0]);
+}
abstract class RegExp implements Pattern {
external factory RegExp(String source);
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
index 9cbadeb..998e775 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
@@ -39,6 +39,25 @@
await _resolveFile('$testPackageRootPath/lib2.dart');
}
+ test_fromIntegrationTestDirectory() async {
+ newFile('$testPackageRootPath/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+ @visibleForTesting
+ void a(){ }
+}
+''');
+ newFile('$testPackageRootPath/integration_test/test.dart', content: r'''
+import '../lib1.dart';
+class B {
+ void b() => new A().a();
+}
+''');
+
+ await _resolveFile('$testPackageRootPath/lib1.dart');
+ await _resolveFile('$testPackageRootPath/integration_test/test.dart');
+ }
+
test_fromTestDirectory() async {
newFile('$testPackageRootPath/lib1.dart', content: r'''
import 'package:meta/meta.dart';
@@ -58,6 +77,25 @@
await _resolveFile('$testPackageRootPath/test/test.dart');
}
+ test_fromTestDriverDirectory() async {
+ newFile('$testPackageRootPath/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+ @visibleForTesting
+ void a(){ }
+}
+''');
+ newFile('$testPackageRootPath/test_driver/test.dart', content: r'''
+import '../lib1.dart';
+class B {
+ void b() => new A().a();
+}
+''');
+
+ await _resolveFile('$testPackageRootPath/lib1.dart');
+ await _resolveFile('$testPackageRootPath/test_driver/test.dart');
+ }
+
test_fromTestingDirectory() async {
newFile('$testPackageRootPath/lib1.dart', content: r'''
import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart b/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart
index e21d37c..ce1298b 100644
--- a/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_check_always_fails_test.dart
@@ -37,10 +37,10 @@
test_nullLiteral_parenthesized() async {
await assertErrorsInCode(r'''
void f() {
- null!;
+ (null)!;
}
''', [
- error(HintCode.NULL_CHECK_ALWAYS_FAILS, 13, 5),
+ error(HintCode.NULL_CHECK_ALWAYS_FAILS, 13, 7),
]);
}
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 34f07a4..6b7cfdc 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -6,7 +6,6 @@
import 'dart:io' as io hide exit;
import 'dart:isolate';
-import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:cli_util/cli_logging.dart';
@@ -172,8 +171,6 @@
argParser.addFlag('disable-analytics',
negatable: false, help: 'Disable anonymous analytics.');
- addExperimentalFlags(argParser, verbose);
-
argParser.addFlag('diagnostics',
negatable: false, help: 'Show tool diagnostic output.', hide: !verbose);
@@ -189,7 +186,7 @@
addCommand(AnalyzeCommand());
addCommand(CreateCommand(verbose: verbose));
- addCommand(CompileCommand());
+ addCommand(CompileCommand(verbose: verbose));
addCommand(FixCommand());
addCommand(FormatCommand(verbose: verbose));
addCommand(MigrateCommand(verbose: verbose));
@@ -206,26 +203,6 @@
String get invocation =>
'dart [<vm-flags>] <command|dart-file> [<arguments>]';
- void addExperimentalFlags(ArgParser argParser, bool verbose) {
- List<ExperimentalFeature> features = experimentalFeatures;
-
- Map<String, String> allowedHelp = {};
- for (ExperimentalFeature feature in features) {
- String suffix =
- feature.isEnabledByDefault ? ' (no-op - enabled by default)' : '';
- allowedHelp[feature.enableString] = '${feature.documentation}$suffix';
- }
-
- argParser.addMultiOption(
- experimentFlagName,
- valueHelp: 'experiment',
- allowedHelp: verbose ? allowedHelp : null,
- help: 'Enable one or more experimental features '
- '(see dart.dev/go/experiments).',
- hide: !verbose,
- );
- }
-
@override
Future<int> runCommand(ArgResults topLevelResults) async {
final stopwatch = Stopwatch()..start();
@@ -250,18 +227,6 @@
? Logger.verbose(ansi: ansi)
: Logger.standard(ansi: ansi);
- if (topLevelResults.wasParsed(experimentFlagName)) {
- List<String> experimentIds = topLevelResults[experimentFlagName];
- for (ExperimentalFeature feature in experimentalFeatures) {
- // We allow default true flags, but complain when they are passed in.
- if (feature.isEnabledByDefault &&
- experimentIds.contains(feature.enableString)) {
- print("'${feature.enableString}' is now enabled by default; this "
- 'flag is no longer required.');
- }
- }
- }
-
var command = topLevelResults.command;
final commandNames = [];
while (command != null) {
@@ -276,10 +241,6 @@
analyticsInstance.sendScreenView(path),
);
- final topLevelCommand = topLevelResults.command == null
- ? null
- : commands[topLevelResults.command.name];
-
try {
final exitCode = await super.runCommand(topLevelResults);
@@ -299,7 +260,7 @@
//
// Note that this will also conflate short-options and long-options.
command?.options?.where(command.wasParsed)?.toList(),
- specifiedExperiments: topLevelCommand?.specifiedExperiments,
+ specifiedExperiments: topLevelResults.enabledExperiments,
),
);
}
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 024bea8..c0fdea3 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -9,6 +9,7 @@
import 'package:path/path.dart' as path;
import '../core.dart';
+import '../experiments.dart';
import '../sdk.dart';
import '../vm_interop_handler.dart';
@@ -45,7 +46,8 @@
class CompileJSCommand extends CompileSubcommandCommand {
static const String cmdName = 'js';
- CompileJSCommand() : super(cmdName, 'Compile Dart to JavaScript.') {
+ CompileJSCommand({bool verbose})
+ : super(cmdName, 'Compile Dart to JavaScript.') {
argParser
..addOption(
commonOptions['outputFile'].flag,
@@ -58,6 +60,7 @@
abbr: 'm',
negatable: false,
);
+ addExperimentalFlags(argParser, verbose);
}
@override
@@ -91,6 +94,8 @@
VmInteropHandler.run(sdk.dart2jsSnapshot, [
'--libraries-spec=$librariesPath',
+ if (argResults.enabledExperiments.isNotEmpty)
+ "--enable-experiment=${argResults.enabledExperiments.join(',')}",
...argResults.arguments,
]);
@@ -112,6 +117,7 @@
this.help,
this.fileExt,
this.formatName,
+ bool verbose,
}) : super(commandName, 'Compile Dart $help') {
argParser
..addOption(
@@ -119,6 +125,7 @@
help: commonOptions['outputFile'].help,
abbr: commonOptions['outputFile'].abbr,
);
+ addExperimentalFlags(argParser, verbose);
}
@override
@@ -144,10 +151,14 @@
outputFile = '$inputWithoutDart.$fileExt';
}
+ final enabledExperiments = argResults.enabledExperiments;
// Build arguments.
List<String> args = [];
args.add('--snapshot-kind=$formatName');
args.add('--snapshot=${path.canonicalize(outputFile)}');
+ if (enabledExperiments.isNotEmpty) {
+ args.add("--enable-experiment=${enabledExperiments.join(',')}");
+ }
if (verbose) {
args.add('-v');
}
@@ -173,6 +184,7 @@
this.commandName,
this.format,
this.help,
+ bool verbose,
}) : super(commandName, 'Compile Dart $help') {
argParser
..addOption(
@@ -195,6 +207,8 @@
..addOption('save-debugging-info', abbr: 'S', valueHelp: 'path', help: '''
Remove debugging information from the output and save it separately to the specified file.
<path> can be relative or absolute.''');
+
+ addExperimentalFlags(argParser, verbose);
}
@override
@@ -225,6 +239,7 @@
defines: argResults['define'],
packages: argResults['packages'],
enableAsserts: argResults['enable-asserts'],
+ enableExperiment: argResults.enabledExperiments.join(','),
debugFile: argResults['save-debugging-info'],
verbose: verbose,
);
@@ -245,30 +260,36 @@
class CompileCommand extends DartdevCommand {
static const String cmdName = 'compile';
-
- CompileCommand() : super(cmdName, 'Compile Dart to various formats.') {
- addSubcommand(CompileJSCommand());
+ CompileCommand({bool verbose = false})
+ : super(cmdName, 'Compile Dart to various formats.') {
+ addSubcommand(CompileJSCommand(
+ verbose: verbose,
+ ));
addSubcommand(CompileSnapshotCommand(
commandName: CompileSnapshotCommand.jitSnapshotCmdName,
help: 'to a JIT snapshot.',
fileExt: 'jit',
formatName: 'app-jit',
+ verbose: verbose,
));
addSubcommand(CompileSnapshotCommand(
commandName: CompileSnapshotCommand.kernelCmdName,
help: 'to a kernel snapshot.',
fileExt: 'dill',
formatName: 'kernel',
+ verbose: verbose,
));
addSubcommand(CompileNativeCommand(
commandName: CompileNativeCommand.exeCmdName,
help: 'to a self-contained executable.',
format: 'exe',
+ verbose: verbose,
));
addSubcommand(CompileNativeCommand(
commandName: CompileNativeCommand.aotSnapshotCmdName,
help: 'to an AOT snapshot.',
format: 'aot',
+ verbose: verbose,
));
}
}
diff --git a/pkg/dartdev/lib/src/commands/pub.dart b/pkg/dartdev/lib/src/commands/pub.dart
index d77dce6..9f18a82 100644
--- a/pkg/dartdev/lib/src/commands/pub.dart
+++ b/pkg/dartdev/lib/src/commands/pub.dart
@@ -63,20 +63,19 @@
final command = sdk.pubSnapshot;
var args = argResults.arguments;
+ final enabledExperiments = argResults.enabledExperiments;
// Pass any --enable-experiment options along.
- if (args.isNotEmpty && wereExperimentsSpecified) {
- List<String> experimentIds = specifiedExperiments;
-
+ if (args.isNotEmpty && enabledExperiments.isNotEmpty) {
if (args.first == 'run') {
args = [
...args.sublist(0, 1),
- '--$experimentFlagName=${experimentIds.join(',')}',
+ '--$experimentFlagName=${enabledExperiments.join(',')}',
...args.sublist(1),
];
} else if (args.length > 1 && args[0] == 'global' && args[0] == 'run') {
args = [
...args.sublist(0, 2),
- '--$experimentFlagName=${experimentIds.join(',')}',
+ '--$experimentFlagName=${enabledExperiments.join(',')}',
...args.sublist(2),
];
}
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index 52dab76..b350b38 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -145,6 +145,7 @@
negatable: false,
help: 'Enables tracing of library and script loading.',
);
+ addExperimentalFlags(argParser, verbose);
}
@override
@@ -216,15 +217,6 @@
}
}
- // Pass any --enable-experiment options along.
- if (args.isNotEmpty && wereExperimentsSpecified) {
- List<String> experimentIds = specifiedExperiments;
- args = [
- '--$experimentFlagName=${experimentIds.join(',')}',
- ...args,
- ];
- }
-
// If the user wants to start a debugging session we need to do some extra
// work and spawn a Dart Development Service (DDS) instance. DDS is a VM
// service intermediary which implements the VM service protocol and
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index 43117fa..b4fe29c 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -58,11 +58,14 @@
_printMissingDepInstructions(isHelpCommand);
return 65;
}
-
+ List<String> enabledExperiments = [];
+ if (!(testArgs.length == 1 && testArgs[0] == '-h')) {
+ enabledExperiments = argResults.enabledExperiments;
+ }
final args = [
'run',
- if (wereExperimentsSpecified)
- '--$experimentFlagName=${specifiedExperiments.join(',')}',
+ if (enabledExperiments.isNotEmpty)
+ '--$experimentFlagName=${enabledExperiments.join(',')}',
'test',
...testArgs,
];
diff --git a/pkg/dartdev/lib/src/events.dart b/pkg/dartdev/lib/src/events.dart
index 29395dc..b2c936a 100644
--- a/pkg/dartdev/lib/src/events.dart
+++ b/pkg/dartdev/lib/src/events.dart
@@ -56,7 +56,8 @@
/// pattern from the flutter cli tool which always passes 'flutter' as the
/// category.
final category = _dartdev;
- commandFlags = commandFlags?.toList() ?? [];
+ commandFlags =
+ commandFlags?.where((e) => e != 'enable-experiment')?.toList() ?? [];
specifiedExperiments = specifiedExperiments?.toList() ?? [];
// Sort the flag lists to slightly reduce the explosion of possibilities.
diff --git a/pkg/dartdev/lib/src/experiments.dart b/pkg/dartdev/lib/src/experiments.dart
index 3921900..ebbff07 100644
--- a/pkg/dartdev/lib/src/experiments.dart
+++ b/pkg/dartdev/lib/src/experiments.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:args/args.dart';
const experimentFlagName = 'enable-experiment';
@@ -14,3 +15,53 @@
features.sort((a, b) => a.enableString.compareTo(b.enableString));
return features;
}
+
+void addExperimentalFlags(ArgParser argParser, bool verbose) {
+ List<ExperimentalFeature> features = experimentalFeatures;
+
+ Map<String, String> allowedHelp = {};
+ for (ExperimentalFeature feature in features) {
+ String suffix =
+ feature.isEnabledByDefault ? ' (no-op - enabled by default)' : '';
+ allowedHelp[feature.enableString] = '${feature.documentation}$suffix';
+ }
+
+ argParser.addMultiOption(
+ experimentFlagName,
+ valueHelp: 'experiment',
+ allowedHelp: verbose ? allowedHelp : null,
+ help: 'Enable one or more experimental features '
+ '(see dart.dev/go/experiments).',
+ hide: !verbose,
+ );
+}
+
+extension EnabledExperimentsArg on ArgResults {
+ List<String> get enabledExperiments {
+ List<String> enabledExperiments = [];
+ if (options.contains(experimentFlagName)) {
+ if (wasParsed(experimentFlagName)) {
+ enabledExperiments = this[experimentFlagName];
+ }
+ } else {
+ String experiments = arguments.firstWhere(
+ (e) => e.startsWith('--enable-experiment'),
+ orElse: () => null,
+ );
+ if (experiments == null) {
+ return [];
+ }
+ enabledExperiments = experiments.split('=')[1].split(',');
+ }
+
+ for (ExperimentalFeature feature in experimentalFeatures) {
+ // We allow default true flags, but complain when they are passed in.
+ if (feature.isEnabledByDefault &&
+ enabledExperiments.contains(feature.enableString)) {
+ print("'${feature.enableString}' is now enabled by default; this "
+ 'flag is no longer required.');
+ }
+ }
+ return enabledExperiments;
+ }
+}
diff --git a/pkg/dartdev/test/analytics_test.dart b/pkg/dartdev/test/analytics_test.dart
index df4359d..cb25407 100644
--- a/pkg/dartdev/test/analytics_test.dart
+++ b/pkg/dartdev/test/analytics_test.dart
@@ -182,10 +182,10 @@
test('run --enable-experiments', () {
final p = project(
- mainSrc: 'void main(List<String> args) => print(args)',
+ mainSrc: 'void main(List<String> args) => print(args);',
logAnalytics: true);
- final result = p.runSync('--enable-experiment=non-nullable', [
- 'run',
+ final result = p.runSync('run', [
+ '--enable-experiment=non-nullable',
'lib/main.dart',
]);
expect(extractAnalytics(result), [
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 1e887b1..70660b4 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -4,7 +4,6 @@
import 'dart:io';
-import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:dartdev/dartdev.dart';
import 'package:test/test.dart';
@@ -48,17 +47,6 @@
}
});
});
-
- test('enable experiments flag is supported', () {
- final args = [
- '--disable-dartdev-analytics',
- '--enable-experiment=non-nullable'
- ];
- final runner = DartdevRunner(args);
- ArgResults results = runner.parse(args);
- expect(results['enable-experiment'], isNotEmpty);
- expect(results['enable-experiment'].first, 'non-nullable');
- });
}
void help() {
diff --git a/pkg/dartdev/test/commands/pub_test.dart b/pkg/dartdev/test/commands/pub_test.dart
index e5a1a86..14db6be 100644
--- a/pkg/dartdev/test/commands/pub_test.dart
+++ b/pkg/dartdev/test/commands/pub_test.dart
@@ -69,20 +69,20 @@
test('run --enable-experiment', () {
p = project();
p.file('bin/main.dart',
- "void main() { int a; a = null; print('a is \$a.'); }");
+ "void main() { int? a; a = null; print('a is \$a.'); }");
// run 'pub get'
p.runSync('pub', ['get']);
var result = p.runSync(
- 'pub', ['run', '--enable-experiment=non-nullable', 'main.dart']);
+ 'pub', ['run', '--enable-experiment=no-non-nullable', 'main.dart']);
expect(result.exitCode, 254);
expect(result.stdout, isEmpty);
expect(
result.stderr,
- contains("A value of type 'Null' can't be assigned to a variable of "
- "type 'int'"));
+ contains('bin/main.dart:1:18: Error: This requires the \'non-nullable\''
+ ' language feature to be enabled.\n'));
});
test('failure', () {
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index f33cb83..4c0a9c1 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -145,7 +145,7 @@
expect(
result.stdout,
matches(
- r'Observatory listening on http:\/\/127.0.0.1:8181\/[a-zA-Z0-9]+=\/\n.*'),
+ r'Observatory listening on http:\/\/127.0.0.1:8181\/[a-zA-Z0-9_-]+=\/\n.*'),
);
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index ef2ae06..93aa6b1 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -85,6 +85,8 @@
test('has package:test dependency', () {
p = project(mainSrc: 'int get foo => 1;\n');
p.file('test/foo_test.dart', '''
+$dartVersionFilePrefix2_9
+
import 'package:test/test.dart';
void main() {
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 32be6a6..f959b95 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,8 +1,3 @@
-# 1.5.0
-- Added event caching for `Stdout`, `Stderr`, and `Extension` streams. When a
-client subscribes to one of these streams, they will be sent up to 10,000
-historical events from the stream.
-
# 1.4.1
- Fixed issue where `evaluate` and `evaluateInFrame` requests were not being
forwarded to the VM service properly when no external compilation service
diff --git a/pkg/dds/dds_protocol.md b/pkg/dds/dds_protocol.md
index 253ef99..be9da7e 100644
--- a/pkg/dds/dds_protocol.md
+++ b/pkg/dds/dds_protocol.md
@@ -47,22 +47,6 @@
See the corresponding section in the VM Service protocol [here][service-protocol-ids-and-names].
-## Streams
-
-For a list of core VM service streams, see [streamListen][service-protocol-streams].
-
-DDS will keep a history of events on certain streams and send historical events
-when a client first subscribes to a stream with history. These streams currently
-consist of the following:
-
-- `Logging`
-- `Stdout`
-- `Stderr`
-- `Extension`
-
-In addition, subscribing to the `Service` stream will result in a `ServiceRegistered`
-event being sent to the subscribing client for each existing service extension.
-
## Public RPCs
The DDS Protocol supports all [public RPCs defined in the VM Service protocol][service-protocol-public-rpcs].
@@ -203,7 +187,6 @@
[service-protocol]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md
[service-protocol-rpcs-requests-and-responses]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#rpcs-requests-and-responses
[service-protocol-events]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#events
-[service-protocol-streams]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#streamlisten
[service-protocol-binary-events]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#binary-events
[service-protocol-types]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#types
[service-protocol-ids-and-names]: https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md#ids-and-names
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 2c85aae..79e4233 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -140,9 +140,7 @@
'getLogHistorySize',
(parameters) => {
'type': 'Size',
- 'size': _StreamManager
- .loggingRepositories[_StreamManager.kLoggingStream]
- .bufferSize,
+ 'size': dds.loggingRepository.bufferSize,
});
_clientPeer.registerMethod('setLogHistorySize', (parameters) {
@@ -152,8 +150,7 @@
"'size' must be greater or equal to zero",
);
}
- _StreamManager.loggingRepositories[_StreamManager.kLoggingStream]
- .resize(size);
+ dds.loggingRepository.resize(size);
return _RPCResponses.success;
});
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index d2a6dcb..06327a8 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -10,6 +10,7 @@
_clientManager = _ClientManager(this);
_expressionEvaluator = _ExpressionEvaluator(this);
_isolateManager = _IsolateManager(this);
+ _loggingRepository = _LoggingRepository();
_streamManager = _StreamManager(this);
_authCode = _authCodesEnabled ? _makeAuthToken() : '';
}
@@ -269,6 +270,9 @@
_IsolateManager get isolateManager => _isolateManager;
_IsolateManager _isolateManager;
+ _LoggingRepository get loggingRepository => _loggingRepository;
+ _LoggingRepository _loggingRepository;
+
_StreamManager get streamManager => _streamManager;
_StreamManager _streamManager;
diff --git a/pkg/dds/lib/src/stream_manager.dart b/pkg/dds/lib/src/stream_manager.dart
index 542fe91..abb233c 100644
--- a/pkg/dds/lib/src/stream_manager.dart
+++ b/pkg/dds/lib/src/stream_manager.dart
@@ -91,14 +91,7 @@
// The _IsolateManager requires information from both the Debug and
// Isolate streams, so they must always be subscribed to by DDS.
for (final stream in ddsCoreStreams) {
- try {
- await streamListen(null, stream);
- if (loggingRepositoryStreams.contains(stream)) {
- loggingRepositories[stream] = _LoggingRepository();
- }
- } on json_rpc.RpcException {
- // Stdout and Stderr streams may not exist.
- }
+ await streamListen(null, stream);
}
dds._vmServiceClient.registerMethod(
'streamNotify',
@@ -108,10 +101,10 @@
if (isolateManagerStreams.contains(streamId)) {
dds.isolateManager.handleIsolateEvent(parameters);
}
- // Keep a history of messages to send to clients when they first
- // subscribe to a stream with an event history.
- if (loggingRepositories.containsKey(streamId)) {
- loggingRepositories[streamId].add(parameters.asMap);
+ // Keep a history of log messages to send to clients when they first
+ // subscribe to the Logging stream.
+ if (streamId == kLoggingStream) {
+ dds.loggingRepository.add(parameters.asMap);
}
streamNotify(streamId, parameters.value);
},
@@ -144,8 +137,8 @@
}
if (client != null) {
streamListeners[stream].add(client);
- if (loggingRepositories.containsKey(stream)) {
- loggingRepositories[stream].sendHistoricalLogs(client);
+ if (stream == kLoggingStream) {
+ dds.loggingRepository.sendHistoricalLogs(client);
} else if (stream == kServiceStream) {
// Send all previously registered service extensions when a client
// subscribes to the Service stream.
@@ -230,13 +223,8 @@
);
static const kDebugStream = 'Debug';
- static const kExtensionStream = 'Extension';
static const kIsolateStream = 'Isolate';
static const kLoggingStream = 'Logging';
- static const kStderrStream = 'Stderr';
- static const kStdoutStream = 'Stdout';
-
- static Map<String, _LoggingRepository> loggingRepositories = {};
// Never cancel the Debug or Isolate stream as `_IsolateManager` requires
// them for isolate state notifications.
@@ -245,13 +233,10 @@
kIsolateStream,
};
- // Never cancel the logging and extension event streams as `_LoggingRepository`
- // requires them keep history.
+ // Never cancel the Logging stream as `_LoggingRepository` requires it to
+ // keep a log history.
static const loggingRepositoryStreams = <String>{
- kExtensionStream,
kLoggingStream,
- kStderrStream,
- kStdoutStream,
};
// The set of streams that DDS requires to function.
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index d2fdbdb..a7ae669 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
A library used to spawn the Dart Developer Service, used to communicate with
a Dart VM Service instance.
-version: 1.5.0
+version: 1.4.1
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
diff --git a/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart b/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
index 7bc0288..067ee7d 100644
--- a/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/where_or_null_transformer.dart
@@ -61,12 +61,20 @@
WhereOrNullTransformer(this._typeProvider, this._typeSystem);
- /// If [expression] is the `orElse` argument of a call that can be
- /// transformed, returns information about the transformable call; otherwise
- /// returns `null`.
+ /// If [expression] is the expression part of the `orElse` argument of a call
+ /// that can be transformed, returns information about the transformable call;
+ /// otherwise returns `null`.
WhereOrNullTransformationInfo tryTransformOrElseArgument(
- Expression expression) =>
- _tryTransformMethodInvocation(expression?.parent?.parent?.parent);
+ Expression expression) {
+ var transformationInfo =
+ _tryTransformMethodInvocation(expression?.parent?.parent?.parent);
+ if (transformationInfo != null &&
+ identical(transformationInfo.orElseArgument.expression, expression)) {
+ return transformationInfo;
+ } else {
+ return null;
+ }
+ }
/// Searches [argumentList] for a named argument with the name "orElse". If
/// such an argument is found, and no other named arguments are found, it is
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index a822486..b0ba46d 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -2757,6 +2757,29 @@
await _checkSingleFileChanges(content, expected);
}
+ Future<void> test_firstWhere_complex_target() async {
+ // See https://github.com/dart-lang/sdk/issues/43956
+ var content = '''
+Iterable<Match> allMatches(String str) => 'x'.allMatches(str);
+
+Match matchAsPrefix(String str, [int start = 0]) {
+ return allMatches(str)
+ .firstWhere((match) => match.start == start, orElse: () => null);
+}
+''';
+ var expected = '''
+import 'package:collection/collection.dart' show IterableExtension;
+
+Iterable<Match> allMatches(String str) => 'x'.allMatches(str);
+
+Match? matchAsPrefix(String str, [int start = 0]) {
+ return allMatches(str)
+ .firstWhereOrNull((match) => match.start == start);
+}
+''';
+ await _checkSingleFileChanges(content, expected);
+ }
+
Future<void> test_firstWhere_non_nullable() async {
var content = '''
int firstEven(Iterable<int> x)
diff --git a/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart b/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart
index 27e7033..8360432 100644
--- a/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart
+++ b/pkg/nnbd_migration/test/utilities/where_or_null_transformer_test.dart
@@ -133,6 +133,15 @@
isNull);
}
+ Future<void> test_mismatch_other_subexpression() async {
+ await analyze('''
+List<int> f(List<int> x) => x;
+g(List<int> x) => f(x).firstWhere((i) => i.isEven, orElse: () => null);
+''');
+ var xExpression = findNode.simple('x).firstWhere');
+ expect(transformer.tryTransformOrElseArgument(xExpression), isNull);
+ }
+
Future<void> test_mismatch_unrelated_type() async {
await analyze('''
abstract class C {
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index e644202..a4f3270 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -557,44 +557,6 @@
vm_options->AddArguments(vm_argv, vm_argc);
-#if !defined(DART_PRECOMPILED_RUNTIME)
- if (!enabled_experiments_.is_empty()) {
- intptr_t num_experiments = enabled_experiments_.length();
- if (!(Options::disable_dart_dev() || run_script)) {
- const char* kEnableExperiment = "--enable-experiment=";
- int option_size = strlen(kEnableExperiment);
- for (intptr_t i = 0; i < num_experiments; ++i) {
- const char* flag = enabled_experiments_.At(i);
- option_size += strlen(flag);
- if (i + 1 != num_experiments) {
- // Account for comma if there's more experiments to add.
- ++option_size;
- }
- }
- // Make room for null terminator
- ++option_size;
-
- char* enabled_experiments_arg = new char[option_size];
- int offset = snprintf(enabled_experiments_arg, option_size, "%s",
- kEnableExperiment);
- for (intptr_t i = 0; i < num_experiments; ++i) {
- const char* flag = enabled_experiments_.At(i);
- const char* kFormat = (i + 1 != num_experiments) ? "%s," : "%s";
- offset += snprintf(enabled_experiments_arg + offset,
- option_size - offset, kFormat, flag);
- free(const_cast<char*>(flag));
- ASSERT(offset < option_size);
- }
- DartDevIsolate::set_should_run_dart_dev(true);
- dart_options->AddArgument(enabled_experiments_arg);
- } else {
- for (intptr_t i = 0; i < num_experiments; ++i) {
- free(const_cast<char*>(enabled_experiments_.At(i)));
- }
- }
- }
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
-
// If running with dartdev, attempt to parse VM flags which are part of the
// dartdev command (e.g., --enable-vm-service, --observe, etc).
if (!run_script) {
diff --git a/runtime/observatory/tests/service/dds_extension_event_history_test.dart b/runtime/observatory/tests/service/dds_extension_event_history_test.dart
deleted file mode 100644
index 0c3d165..0000000
--- a/runtime/observatory/tests/service/dds_extension_event_history_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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.
-
-import 'dart:async';
-import 'dart:developer';
-
-import 'package:observatory/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
- // Post a total of 9 events
- for (int i = 1; i <= 9; ++i) {
- postEvent('Test', {
- 'id': i,
- });
- }
-}
-
-var tests = <IsolateTest>[
- isPausedAtStart,
- resumeIsolate,
- (Isolate isolate) async {
- final completer = Completer<void>();
- int i = 1;
- await subscribeToStream(isolate.vm, 'Extension', (event) async {
- expect(event.extensionKind, 'Test');
- expect(event.extensionData!['id'], i);
- i++;
-
- if (i == 10) {
- await cancelStreamSubscription('Extension');
- completer.complete();
- } else if (i > 10) {
- fail('Too many log messages');
- }
- });
- await completer.future;
- },
-];
-
-main(args) => runIsolateTests(
- args,
- tests,
- enableService: false, // DDS specific feature
- testeeConcurrent: testMain,
- pause_on_start: true,
- pause_on_exit: true,
- );
diff --git a/runtime/observatory/tests/service/dds_stdout_stderr_history_test.dart b/runtime/observatory/tests/service/dds_stdout_stderr_history_test.dart
deleted file mode 100644
index c0d6ba5..0000000
--- a/runtime/observatory/tests/service/dds_stdout_stderr_history_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:observatory/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
- // Log a total of 9 messages
- for (int i = 1; i <= 9; ++i) {
- print('Stdout log$i');
- stderr.writeln('Stderr log$i');
- }
-}
-
-Future streamHistoryTest(Isolate isolate, String stream) async {
- final completer = Completer<void>();
- int i = 1;
- await subscribeToStream(isolate.vm, stream, (event) async {
- // Newlines are sent as separate events for some reason. Ignore them.
- if (!event.bytesAsString!.startsWith(stream)) {
- return;
- }
- expect(event.bytesAsString, '$stream log$i');
- i++;
-
- if (i == 10) {
- await cancelStreamSubscription(stream);
- completer.complete();
- } else if (i > 10) {
- fail('Too many log messages');
- }
- });
- await completer.future;
-}
-
-var tests = <IsolateTest>[
- isPausedAtStart,
- resumeIsolate,
- (Isolate isolate) async {
- await streamHistoryTest(isolate, 'Stdout');
- },
- (Isolate isolate) async {
- await streamHistoryTest(isolate, 'Stderr');
- },
-];
-
-main(args) => runIsolateTests(
- args,
- tests,
- enableService: false, // DDS specific feature
- testeeConcurrent: testMain,
- pause_on_start: true,
- pause_on_exit: true,
- );
diff --git a/runtime/observatory/tests/service/network_profiling_test.dart b/runtime/observatory/tests/service/network_profiling_test.dart
index 3a318ca..d68fbeb 100644
--- a/runtime/observatory/tests/service/network_profiling_test.dart
+++ b/runtime/observatory/tests/service/network_profiling_test.dart
@@ -56,14 +56,11 @@
postEvent('socketTest', {'socket': 'test'});
}
-bool checkFinishEvent(ServiceEvent event) {
+void checkFinishEvent(ServiceEvent event) {
expect(event.kind, equals(ServiceEvent.kExtension));
- if (event.extensionKind != 'socketTest') {
- return false;
- }
+ expect(event.extensionKind, equals('socketTest'));
expect(event.extensionData, isA<Map>());
expect(event.extensionData!['socket'], equals('test'));
- return true;
}
var tests = <IsolateTest>[
@@ -105,10 +102,9 @@
var sub;
sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
(ServiceEvent event) {
- if (checkFinishEvent(event)) {
- sub.cancel();
- completer.complete();
- }
+ checkFinishEvent(event);
+ sub.cancel();
+ completer.complete();
});
dynamic result = await isolate.invokeRpc("invoke",
@@ -154,10 +150,9 @@
completer = Completer();
sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
(ServiceEvent event) {
- if (checkFinishEvent(event)) {
- sub.cancel();
- completer.complete();
- }
+ checkFinishEvent(event);
+ sub.cancel();
+ completer.complete();
});
dynamic result = await isolate.invokeRpc("invoke",
{"targetId": lib.id, "selector": "socketTest", "argumentIds": []});
@@ -202,10 +197,9 @@
var sub;
sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
(ServiceEvent event) {
- if (checkFinishEvent(event)) {
- sub.cancel();
- completer.complete();
- }
+ checkFinishEvent(event);
+ sub.cancel();
+ completer.complete();
});
dynamic result = await isolate.invokeRpc("invoke",
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 9e721f2..f8d96f8 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -111,6 +111,7 @@
get_object_rpc_test: SkipByDesign
get_source_report_test: Skip, Timeout
get_source_report_with_mixin_test: Skip, Timeout
+get_stack_limit_test: Skip, Timeout
get_stack_rpc_test: Skip, Timeout
implicit_getter_setter_test: SkipByDesign
invoke_test: Skip, Timeout
diff --git a/runtime/observatory_2/tests/service_2/dds_extension_event_history_test.dart b/runtime/observatory_2/tests/service_2/dds_extension_event_history_test.dart
deleted file mode 100644
index ea8ab07..0000000
--- a/runtime/observatory_2/tests/service_2/dds_extension_event_history_test.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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.
-
-import 'dart:async';
-import 'dart:developer';
-
-import 'package:observatory_2/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
- // Post a total of 9 events
- for (int i = 1; i <= 9; ++i) {
- postEvent('Test', {
- 'id': i,
- });
- }
-}
-
-var tests = <IsolateTest>[
- isPausedAtStart,
- resumeIsolate,
- (Isolate isolate) async {
- final completer = Completer<void>();
- int i = 1;
- await subscribeToStream(isolate.vm, 'Extension', (event) async {
- expect(event.extensionKind, 'Test');
- expect(event.extensionData['id'], i);
- i++;
-
- if (i == 10) {
- await cancelStreamSubscription('Extension');
- completer.complete();
- } else if (i > 10) {
- fail('Too many log messages');
- }
- });
- await completer.future;
- },
-];
-
-main(args) => runIsolateTests(
- args,
- tests,
- enableService: false, // DDS specific feature
- testeeConcurrent: testMain,
- pause_on_start: true,
- pause_on_exit: true,
- );
diff --git a/runtime/observatory_2/tests/service_2/dds_stdout_stderr_history_test.dart b/runtime/observatory_2/tests/service_2/dds_stdout_stderr_history_test.dart
deleted file mode 100644
index 9fc0b7a..0000000
--- a/runtime/observatory_2/tests/service_2/dds_stdout_stderr_history_test.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// 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.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:observatory_2/service_io.dart';
-import 'package:test/test.dart';
-import 'client_resume_approvals_common.dart';
-import 'service_test_common.dart';
-import 'test_helper.dart';
-
-Future testMain() async {
- // Log a total of 9 messages
- for (int i = 1; i <= 9; ++i) {
- print('Stdout log$i');
- stderr.writeln('Stderr log$i');
- }
-}
-
-Future streamHistoryTest(Isolate isolate, String stream) async {
- final completer = Completer<void>();
- int i = 1;
- await subscribeToStream(isolate.vm, stream, (event) async {
- // Newlines are sent as separate events for some reason. Ignore them.
- if (!event.bytesAsString.startsWith(stream)) {
- return;
- }
- expect(event.bytesAsString, '$stream log$i');
- i++;
-
- if (i == 10) {
- await cancelStreamSubscription(stream);
- completer.complete();
- } else if (i > 10) {
- fail('Too many log messages');
- }
- });
- await completer.future;
-}
-
-var tests = <IsolateTest>[
- isPausedAtStart,
- resumeIsolate,
- (Isolate isolate) async {
- await streamHistoryTest(isolate, 'Stdout');
- },
- (Isolate isolate) async {
- await streamHistoryTest(isolate, 'Stderr');
- },
-];
-
-main(args) => runIsolateTests(
- args,
- tests,
- enableService: false, // DDS specific feature
- testeeConcurrent: testMain,
- pause_on_start: true,
- pause_on_exit: true,
- );
diff --git a/runtime/observatory_2/tests/service_2/network_profiling_test.dart b/runtime/observatory_2/tests/service_2/network_profiling_test.dart
index 8ba995f..5c27795 100644
--- a/runtime/observatory_2/tests/service_2/network_profiling_test.dart
+++ b/runtime/observatory_2/tests/service_2/network_profiling_test.dart
@@ -56,14 +56,11 @@
postEvent('socketTest', {'socket': 'test'});
}
-bool checkFinishEvent(ServiceEvent event) {
+Future<void> checkFinishEvent(ServiceEvent event) {
expect(event.kind, equals(ServiceEvent.kExtension));
- if (event.extensionKind != 'socketTest') {
- return false;
- }
+ expect(event.extensionKind, equals('socketTest'));
expect(event.extensionData, isA<Map>());
expect(event.extensionData['socket'], equals('test'));
- return true;
}
var tests = <IsolateTest>[
@@ -105,10 +102,9 @@
var sub;
sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
(ServiceEvent event) {
- if (checkFinishEvent(event)) {
- sub.cancel();
- completer.complete();
- }
+ checkFinishEvent(event);
+ sub.cancel();
+ completer.complete();
});
dynamic result = await isolate.invokeRpc("invoke",
@@ -154,10 +150,9 @@
completer = Completer();
sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
(ServiceEvent event) {
- if (checkFinishEvent(event)) {
- sub.cancel();
- completer.complete();
- }
+ checkFinishEvent(event);
+ sub.cancel();
+ completer.complete();
});
dynamic result = await isolate.invokeRpc("invoke",
{"targetId": lib.id, "selector": "socketTest", "argumentIds": []});
@@ -202,10 +197,9 @@
var sub;
sub = await isolate.vm.listenEventStream(Isolate.kExtensionStream,
(ServiceEvent event) {
- if (checkFinishEvent(event)) {
- sub.cancel();
- completer.complete();
- }
+ checkFinishEvent(event);
+ sub.cancel();
+ completer.complete();
});
dynamic result = await isolate.invokeRpc("invoke",
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index 9e721f2..8c09f06 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -111,6 +111,7 @@
get_object_rpc_test: SkipByDesign
get_source_report_test: Skip, Timeout
get_source_report_with_mixin_test: Skip, Timeout
+get_stack_limit_rpc_test: Skip, Timeout
get_stack_rpc_test: Skip, Timeout
implicit_getter_setter_test: SkipByDesign
invoke_test: Skip, Timeout
diff --git a/runtime/tests/vm/dart/regress_44026_main.dart b/runtime/tests/vm/dart/regress_44026_main.dart
new file mode 100644
index 0000000..e4278bd
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44026_main.dart
@@ -0,0 +1,12 @@
+// 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.
+
+// Main script for regress_44026_test.dart.
+// @dart=2.12
+
+import 'regress_44026_opt_out_lib.dart';
+
+void main() {
+ sayHello(true);
+}
diff --git a/runtime/tests/vm/dart/regress_44026_opt_out_lib.dart b/runtime/tests/vm/dart/regress_44026_opt_out_lib.dart
new file mode 100644
index 0000000..b036fba
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44026_opt_out_lib.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Opted-out library for regress_44026_test.dart.
+// @dart = 2.7
+
+void sayHello(bool t) {
+ String s;
+ if (t) {
+ s = 'hello';
+ }
+ print(s);
+}
diff --git a/runtime/tests/vm/dart/regress_44026_test.dart b/runtime/tests/vm/dart/regress_44026_test.dart
new file mode 100644
index 0000000..5d14bf9
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_44026_test.dart
@@ -0,0 +1,44 @@
+// 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.
+
+// OtherResources=regress_44026_main.dart
+// OtherResources=regress_44026_opt_out_lib.dart
+
+// Tests that compile-time error is issued if NNBD opted-out library is used
+// from opted-in entry point (with null safety auto-detection).
+// Regression test for https://github.com/dart-lang/sdk/issues/44026.
+
+import 'dart:io' show File, Platform, Process;
+
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+import 'snapshot_test_helper.dart';
+
+const int kCompilationErrorExitCode = 254;
+
+main() async {
+ await withTempDir((String temp) async {
+ // Need to copy test scripts out of Dart SDK to avoid hardcoded
+ // opted-in/opted-out status for Dart SDK tests.
+ for (String script in [
+ 'regress_44026_main.dart',
+ 'regress_44026_opt_out_lib.dart'
+ ]) {
+ final scriptInTemp = path.join(temp, script);
+ File.fromUri(Platform.script.resolve(script)).copySync(scriptInTemp);
+ }
+
+ // Do not add Platform.executableArguments into arguments to avoid passing
+ // --sound-null-safety / --no-sound-null-safety arguments.
+ final result = await Process.run(Platform.executable, [
+ path.join(temp, 'regress_44026_main.dart'),
+ ]);
+ print('stdout: ${result.stdout}');
+ print('stderr: ${result.stderr}');
+ Expect.equals(kCompilationErrorExitCode, result.exitCode);
+ Expect.stringContainsInOrder(result.stderr, [
+ "Error: A library can't opt out of null safety by default, when using sound null safety."
+ ]);
+ });
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index ad2333e..16ee403 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -256,6 +256,7 @@
dart/kernel_determinism_test: SkipByDesign # Test needs to run from source
dart/minimal_kernel_test: SkipByDesign # Test needs to run from source
dart/null_safety_autodetection_in_kernel_compiler_test: SkipByDesign # Test needs to run from source
+dart/regress_44026_test: SkipByDesign # Test needs to run from source
dart/snapshot_depfile_test: SkipByDesign # Test needs to run from source
dart/type_casts_with_null_safety_autodetection_test: SkipByDesign # Test needs to run from source
dart_2/appjit*: SkipByDesign # Test needs to run from source
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index dac8c18..5d7112a 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -806,7 +806,7 @@
}
// If we are loading from source, figure out the mode from the source.
- if (KernelIsolate::GetExperimentalFlag("non-nullable")) {
+ if (!KernelIsolate::GetExperimentalFlag("no-non-nullable")) {
return KernelIsolate::DetectNullSafety(script_uri, package_config,
original_working_directory);
}
diff --git a/tests/lib/isolate/detect_nullsafety_1_test.dart b/tests/lib/isolate/detect_nullsafety_1_test.dart
index 1fecd54..fc7ae94 100644
--- a/tests/lib/isolate/detect_nullsafety_1_test.dart
+++ b/tests/lib/isolate/detect_nullsafety_1_test.dart
@@ -21,8 +21,8 @@
try {
// Running from Source.
testNullSafetyMode(sourcePath, 'Strong Mode');
- // Without the enable experiment option it will be in weak mode.
- testNullSafetyMode1(sourcePath, 'Weak Mode');
+ // Without the enable experiment option it will be in strong mode.
+ testNullSafetyMode1(sourcePath, 'Strong Mode');
// Running from Kernel File.
testNullSafetyMode(dillPath, 'Strong Mode');
diff --git a/tools/VERSION b/tools/VERSION
index ead15d6..52a2514 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 17
+PRERELEASE 18
PRERELEASE_PATCH 0
\ No newline at end of file