Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b7b2047

Browse files
author
Dart CI
committed
Version 2.18.0-156.0.dev
Merge commit '83850ac5fa8cfd58a0dcbfe7103b6455a2a1d523' into 'dev'
2 parents 347e76f + 83850ac commit b7b2047

32 files changed

+441
-82
lines changed

CHANGELOG.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,52 @@ them, you must set the lower bound on the SDK constraint for your package to
5454
- Add `connectionState` attribute and `connectionstatechange` listener to
5555
`RtcPeerConnection`.
5656

57+
#### `dart:io`
58+
59+
- **Breaking Change** [#45630][]: The Dart VM no longer automatically restores
60+
the initial terminal settings upon exit. Programs that change the `Stdin`
61+
settings `lineMode` and `echoMode` are now responsible for restoring the
62+
settings upon program exit. E.g. a program disabling `echoMode` will now
63+
need to restore the setting itself and handle exiting by the appropriate
64+
signals if desired:
65+
66+
```dart
67+
import 'dart:io';
68+
import 'dart:async';
69+
70+
main() {
71+
bool echoWasEnabled = stdin.echoMode;
72+
try {
73+
late StreamSubscription subscription;
74+
subscription = ProcessSignal.sigint.watch().listen((ProcessSignal signal) {
75+
stdin.echoMode = echoWasEnabled;
76+
subscription.cancel();
77+
Process.killPid(pid, signal); /* Die by the signal. */
78+
});
79+
stdin.echoMode = false;
80+
} finally {
81+
stdin.echoMode = echoWasEnabled;
82+
}
83+
}
84+
```
85+
86+
This change is needed to fix [#36453][] where the dart programs not caring
87+
about the terminal settings can inadverently corrupt the terminal settings
88+
when e.g. piping into less.
89+
90+
Furthermore the `echoMode` setting now only controls the `echo` local mode
91+
and no longer sets the `echonl` local mode on POSIX systems (which controls
92+
whether newline are echoed even if the regular echo mode is disabled). The
93+
`echonl` local mode is usually turned off in common shell environments.
94+
Programs that wish to control the `echonl` local mode can use the new
95+
`echoNewlineMode` setting.
96+
97+
The Windows console code pages (if not UTF-8) and ANSI escape code support
98+
(if disabled) remain restored when the VM exits.
99+
100+
[#45630]: https://github.com/dart-lang/sdk/issues/45630
101+
[#36453]: https://github.com/dart-lang/sdk/issues/36453
102+
57103
#### `dart:js_util`
58104
59105
- Added `dartify` and a number of minor helper functions.

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3845,6 +3845,29 @@ const MessageCode messageExtensionDeclaresInstanceField = const MessageCode(
38453845
correctionMessage:
38463846
r"""Try removing the field declaration or making it a static field""");
38473847

3848+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3849+
const Template<Message Function(String name)>
3850+
templateExtensionInNullAwareReceiver =
3851+
const Template<Message Function(String name)>(
3852+
problemMessageTemplate: r"""The extension '#name' cannot be null.""",
3853+
correctionMessageTemplate: r"""Try replacing '?.' with '.'""",
3854+
withArguments: _withArgumentsExtensionInNullAwareReceiver);
3855+
3856+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3857+
const Code<Message Function(String name)> codeExtensionInNullAwareReceiver =
3858+
const Code<Message Function(String name)>("ExtensionInNullAwareReceiver",
3859+
severity: Severity.warning);
3860+
3861+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
3862+
Message _withArgumentsExtensionInNullAwareReceiver(String name) {
3863+
if (name.isEmpty) throw 'No name provided';
3864+
name = demangleMixinApplicationName(name);
3865+
return new Message(codeExtensionInNullAwareReceiver,
3866+
problemMessage: """The extension '${name}' cannot be null.""",
3867+
correctionMessage: """Try replacing '?.' with '.'""",
3868+
arguments: {'name': name});
3869+
}
3870+
38483871
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
38493872
const Template<Message Function(String name)>
38503873
templateExtensionMemberConflictsWithObjectMember =

pkg/front_end/lib/src/fasta/kernel/body_builder.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2947,7 +2947,7 @@ class BodyBuilder extends StackListenerImpl
29472947
assert(declaration.isStatic || declaration.isTopLevel);
29482948
MemberBuilder memberBuilder = declaration as MemberBuilder;
29492949
return new StaticAccessGenerator(
2950-
this, token, name, memberBuilder.member, null);
2950+
this, token, name, memberBuilder.parent, memberBuilder.member, null);
29512951
} else if (declaration is PrefixBuilder) {
29522952
assert(prefix == null);
29532953
return new PrefixUseGenerator(this, token, declaration);

pkg/front_end/lib/src/fasta/kernel/expression_generator.dart

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import '../builder/class_builder.dart';
2020
import '../builder/declaration_builder.dart';
2121
import '../builder/extension_builder.dart';
2222
import '../builder/invalid_type_declaration_builder.dart';
23+
import '../builder/library_builder.dart';
2324
import '../builder/member_builder.dart';
2425
import '../builder/named_type_builder.dart';
2526
import '../builder/nullability_builder.dart';
@@ -1386,12 +1387,18 @@ class StaticAccessGenerator extends Generator {
13861387
final int? typeOffset;
13871388
final bool isNullAware;
13881389

1390+
/// The builder for the parent of [readTarget] and [writeTarget]. This is
1391+
/// either the builder for the enclosing library, class, or extension.
1392+
final Builder? parentBuilder;
1393+
13891394
StaticAccessGenerator(ExpressionGeneratorHelper helper, Token token,
1390-
this.targetName, this.readTarget, this.writeTarget,
1395+
this.targetName, this.parentBuilder, this.readTarget, this.writeTarget,
13911396
{this.typeOffset, this.isNullAware: false})
13921397
// ignore: unnecessary_null_comparison
13931398
: assert(targetName != null),
13941399
assert(readTarget != null || writeTarget != null),
1400+
assert(parentBuilder is DeclarationBuilder ||
1401+
parentBuilder is LibraryBuilder),
13951402
super(helper, token);
13961403

13971404
factory StaticAccessGenerator.fromBuilder(
@@ -1402,19 +1409,44 @@ class StaticAccessGenerator extends Generator {
14021409
MemberBuilder? setterBuilder,
14031410
{int? typeOffset,
14041411
bool isNullAware: false}) {
1405-
return new StaticAccessGenerator(helper, token, targetName,
1406-
getterBuilder?.readTarget, setterBuilder?.writeTarget,
1407-
typeOffset: typeOffset, isNullAware: isNullAware);
1412+
// If both [getterBuilder] and [setterBuilder] exist, they must both be
1413+
// either top level (potentially from different libraries) or from the same
1414+
// class/extension.
1415+
assert(getterBuilder == null ||
1416+
setterBuilder == null ||
1417+
(getterBuilder.parent is LibraryBuilder &&
1418+
setterBuilder.parent is LibraryBuilder) ||
1419+
getterBuilder.parent == setterBuilder.parent);
1420+
return new StaticAccessGenerator(
1421+
helper,
1422+
token,
1423+
targetName,
1424+
getterBuilder?.parent ?? setterBuilder?.parent,
1425+
getterBuilder?.readTarget,
1426+
setterBuilder?.writeTarget,
1427+
typeOffset: typeOffset,
1428+
isNullAware: isNullAware);
14081429
}
14091430

14101431
void _reportNonNullableInNullAwareWarningIfNeeded() {
14111432
if (isNullAware && _helper.libraryBuilder.isNonNullableByDefault) {
1412-
String className = (readTarget ?? writeTarget)!.enclosingClass!.name;
1413-
_helper.libraryBuilder.addProblem(
1414-
templateClassInNullAwareReceiver.withArguments(className),
1415-
typeOffset ?? fileOffset,
1416-
typeOffset != null ? className.length : noLength,
1417-
_helper.uri);
1433+
DeclarationBuilder declarationBuilder =
1434+
parentBuilder as DeclarationBuilder;
1435+
if (declarationBuilder.isExtension) {
1436+
String extensionName = declarationBuilder.name;
1437+
_helper.libraryBuilder.addProblem(
1438+
templateExtensionInNullAwareReceiver.withArguments(extensionName),
1439+
typeOffset ?? fileOffset,
1440+
typeOffset != null ? extensionName.length : noLength,
1441+
_helper.uri);
1442+
} else {
1443+
String className = declarationBuilder.name;
1444+
_helper.libraryBuilder.addProblem(
1445+
templateClassInNullAwareReceiver.withArguments(className),
1446+
typeOffset ?? fileOffset,
1447+
typeOffset != null ? className.length : noLength,
1448+
_helper.uri);
1449+
}
14181450
}
14191451
}
14201452

pkg/front_end/messages.status

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ ExtendsVoid/example: Fail # Feature not yet enabled by default.
314314
ExtensionDeclaresAbstractMember/example: Fail
315315
ExtensionDeclaresConstructor/example: Fail
316316
ExtensionDeclaresInstanceField/example: Fail
317+
ExtensionInNullAwareReceiver/analyzerCode: Fail
317318
ExtensionMemberConflictsWithObjectMember/analyzerCode: Fail
318319
ExternalConstructorWithBody/part_wrapped_script1: Fail
319320
ExternalConstructorWithBody/script1: Fail

pkg/front_end/messages.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5223,6 +5223,19 @@ ClassInNullAwareReceiver:
52235223
C?.field;
52245224
}
52255225
5226+
ExtensionInNullAwareReceiver:
5227+
problemMessage: "The extension '#name' cannot be null."
5228+
correctionMessage: "Try replacing '?.' with '.'"
5229+
severity: WARNING
5230+
configuration: nnbd-strong
5231+
script: |
5232+
extension E on int {
5233+
static var field;
5234+
}
5235+
method() {
5236+
E?.field;
5237+
}
5238+
52265239
NonNullableNotAssignedError:
52275240
problemMessage: "Non-nullable variable '#name' must be assigned before it can be used."
52285241
configuration: nnbd-strong

pkg/front_end/test/fasta/generator_to_string_test.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ Future<void> main() async {
187187
"StaticAccessGenerator(offset: 4, targetName: foo,"
188188
" readTarget: $uri::myGetter,"
189189
" writeTarget: $uri::mySetter)",
190-
new StaticAccessGenerator(helper, token, 'foo', getter, setter));
190+
new StaticAccessGenerator(
191+
helper, token, 'foo', libraryBuilder, getter, setter));
191192
check(
192193
"LoadLibraryGenerator(offset: 4,"
193194
" builder: Instance of 'LoadLibraryBuilder')",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
extension E on int {
6+
static String s = "Lily was here";
7+
}
8+
9+
test() {
10+
E?.s;
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extension E on int {
2+
static String s = "Lily was here";
3+
}
4+
5+
test() {}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extension E on int {
2+
static String s = "Lily was here";
3+
}
4+
5+
test() {}

0 commit comments

Comments
 (0)