Skip to content

Commit 1bf5482

Browse files
kallentuCommit Queue
authored and
Commit Queue
committed
Enable 'wildcard-variables' feature flag.
This CL enables the wildcard variables feature by default in Dart 3.7. Local variables and parameters named `_` are now non-binding and they can be declared multiple times without collisions. All wildcard variable declaration types that have this behavior are described in the wildcard variables specification: https://github.com/dart-lang/language/blob/main/accepted/future-releases/wildcard-variables/feature-specification.md. Top-level variables, top-level function names, type names, member names, etc. are unchanged. They can be named `_` and used as they are today. These are a few examples of where wildcard variables can be used: ```dart Foo(_, this._, super._, void _()) {} typedef T = void Function(String _, String _); main() { var _ = 1; int _ = 2; list.where((_) => true); } ``` Bug: #55673 Fixes: #55654 Change-Id: I80e904d39b364f5e54b8406b4db02ec40ecc9db0 TEST=Existing tests, language tests for wildcards. Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381311 Reviewed-by: Mark Zhou <[email protected]> Reviewed-by: Mayank Patke <[email protected]> Reviewed-by: Ben Konyi <[email protected]> Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Siva Annamalai <[email protected]> Commit-Queue: Kallen Tu <[email protected]> Reviewed-by: Phil Quitslund <[email protected]> Reviewed-by: Bob Nystrom <[email protected]>
1 parent d2a32e5 commit 1bf5482

File tree

313 files changed

+1159
-897
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

313 files changed

+1159
-897
lines changed

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
## 3.7.0
22

3+
### Language
4+
5+
Dart 3.7 adds [wildcard variables] to the language. To use them, set your
6+
package's [SDK constraint][language version] lower bound to 3.7 or greater
7+
(`sdk: '^3.7.0'`).
8+
9+
#### Wildcard Variables
10+
11+
[wildcard variables]: https://github.com/dart-lang/language/issues/3712
12+
13+
Local variables and parameters named `_` are now non-binding and they can
14+
be declared multiple times without collisions. You will no longer be able to use
15+
these variables nor access their values. All wildcard variable declaration types
16+
that have this behavior are described in the
17+
[wildcard variables specification](https://github.com/dart-lang/language/blob/main/accepted/future-releases/wildcard-variables/feature-specification.md).
18+
19+
Top-level variables, top-level function names, type names, member names, etc.
20+
are unchanged. They can be named `_` and used as they are today.
21+
22+
These are a few examples of where wildcard variables can be used:
23+
```dart
24+
Foo(_, this._, super._, void _()) {}
25+
26+
main() {
27+
var _ = 1;
28+
int _ = 2;
29+
30+
list.where((_) => true);
31+
}
32+
```
33+
334
###### Dart to Javascript Compiler (dart2js)
435

536
- The dart2js compiler which is invoked when the command

pkg/_fe_analyzer_shared/lib/src/experiments/flags.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,10 @@ enum ExperimentalFlag {
257257

258258
wildcardVariables(
259259
name: 'wildcard-variables',
260-
isEnabledByDefault: false,
260+
isEnabledByDefault: true,
261261
isExpired: false,
262-
experimentEnabledVersion: defaultLanguageVersion,
263-
experimentReleasedVersion: defaultLanguageVersion),
262+
experimentEnabledVersion: const Version(3, 7),
263+
experimentReleasedVersion: const Version(3, 7)),
264264
;
265265

266266
final String name;

pkg/analyzer/lib/src/dart/analysis/experiments.g.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ class ExperimentalFeatures {
536536
documentation:
537537
'Local declarations and parameters named `_` are non-binding.',
538538
experimentalReleaseVersion: null,
539-
releaseVersion: null,
539+
releaseVersion: Version.parse('3.7.0'),
540540
);
541541
}
542542

@@ -649,7 +649,7 @@ class IsEnabledByDefault {
649649
static const bool variance = false;
650650

651651
/// Default state of the experiment "wildcard-variables"
652-
static const bool wildcard_variables = false;
652+
static const bool wildcard_variables = true;
653653
}
654654

655655
/// Constant bools indicating whether each experimental flag is currently

pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ analysisOptions
418418
triple-shift
419419
unnamed-libraries
420420
variance
421+
wildcard-variables
421422
workspaces
422423
workspace_0: PackageConfigWorkspace
423424
root: /home/test
@@ -493,6 +494,7 @@ analysisOptions
493494
triple-shift
494495
unnamed-libraries
495496
variance
497+
wildcard-variables
496498
workspaces
497499
workspace_0: PackageConfigWorkspace
498500
root: /home/test

pkg/analyzer/tool/diagnostics/diagnostics.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26404,6 +26404,7 @@ The following code produces this diagnostic because the name of the
2640426404
parameter consists of two underscores:
2640526405

2640626406
```dart
26407+
// @dart = 3.6
2640726408
void f(int __) {
2640826409
print([!__!]);
2640926410
}
@@ -26413,6 +26414,7 @@ The following code produces this diagnostic because the name of the
2641326414
local variable consists of a single underscore:
2641426415

2641526416
```dart
26417+
// @dart = 3.6
2641626418
void f() {
2641726419
int _ = 0;
2641826420
print([!_!]);

pkg/analyzer_utilities/lib/test/experiments/experiments.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,4 @@ List<String> experimentsForTests = [
1919
Feature.enhanced_parts.enableString,
2020
Feature.macros.enableString,
2121
Feature.null_aware_elements.enableString,
22-
Feature.wildcard_variables.enableString,
2322
];

pkg/compiler/test/dump_info/data/deferred/main.dart

Lines changed: 193 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,125 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
/*library:
5+
/*spec.library:
6+
constant=[
7+
{
8+
"id": "constant/B.C_Deferred = A.lib__funky$closure();\n",
9+
"kind": "constant",
10+
"name": "",
11+
"size": 39,
12+
"outputUnit": "outputUnit/1",
13+
"code": "B.C_Deferred = A.lib__funky$closure();\n"
14+
},
15+
{
16+
"id": "constant/B.C_JS_CONST = function getTagFallback(o) {\n var s = Object.prototype.toString.call(o);\n return s.substring(8, s.length - 1);\n};\n",
17+
"kind": "constant",
18+
"name": "",
19+
"size": 131,
20+
"outputUnit": "outputUnit/main",
21+
"code": "B.C_JS_CONST = function getTagFallback(o) {\n var s = Object.prototype.toString.call(o);\n return s.substring(8, s.length - 1);\n};\n"
22+
},
23+
{
24+
"id": "constant/B.C__RootZone = new A._RootZone();\n",
25+
"kind": "constant",
26+
"name": "",
27+
"size": 35,
28+
"outputUnit": "outputUnit/main",
29+
"code": "B.C__RootZone = new A._RootZone();\n"
30+
},
31+
{
32+
"id": "constant/B.C__StringStackTrace = new A._StringStackTrace();\n",
33+
"kind": "constant",
34+
"name": "",
35+
"size": 51,
36+
"outputUnit": "outputUnit/main",
37+
"code": "B.C__StringStackTrace = new A._StringStackTrace();\n"
38+
},
39+
{
40+
"id": "constant/B.Interceptor_methods = J.Interceptor.prototype;\n",
41+
"kind": "constant",
42+
"name": "",
43+
"size": 49,
44+
"outputUnit": "outputUnit/main",
45+
"code": "B.Interceptor_methods = J.Interceptor.prototype;\n"
46+
},
47+
{
48+
"id": "constant/B.JSArray_methods = J.JSArray.prototype;\n",
49+
"kind": "constant",
50+
"name": "",
51+
"size": 41,
52+
"outputUnit": "outputUnit/main",
53+
"code": "B.JSArray_methods = J.JSArray.prototype;\n"
54+
},
55+
{
56+
"id": "constant/B.JSInt_methods = J.JSInt.prototype;\n",
57+
"kind": "constant",
58+
"name": "",
59+
"size": 37,
60+
"outputUnit": "outputUnit/main",
61+
"code": "B.JSInt_methods = J.JSInt.prototype;\n"
62+
},
63+
{
64+
"id": "constant/B.JSString_methods = J.JSString.prototype;\n",
65+
"kind": "constant",
66+
"name": "",
67+
"size": 43,
68+
"outputUnit": "outputUnit/main",
69+
"code": "B.JSString_methods = J.JSString.prototype;\n"
70+
},
71+
{
72+
"id": "constant/B.JavaScriptObject_methods = J.JavaScriptObject.prototype;\n",
73+
"kind": "constant",
74+
"name": "",
75+
"size": 59,
76+
"outputUnit": "outputUnit/main",
77+
"code": "B.JavaScriptObject_methods = J.JavaScriptObject.prototype;\n"
78+
}],
79+
deferredFiles=[{
80+
"main.dart": {
81+
"name": "<unnamed>",
82+
"imports": {
83+
"lib": [
84+
"out_1.part.js"
85+
]
86+
},
87+
"importPrefixToLoadId": {
88+
"lib": "lib"
89+
}
90+
}
91+
}],
92+
dependencies=[{}],
93+
library=[{
94+
"id": "library/memory:sdk/tests/web/native/main.dart::",
95+
"kind": "library",
96+
"name": "<unnamed>",
97+
"size": 316,
98+
"children": [
99+
"function/memory:sdk/tests/web/native/main.dart::main"
100+
],
101+
"canonicalUri": "memory:sdk/tests/web/native/main.dart"
102+
}],
103+
outputUnits=[
104+
{
105+
"id": "outputUnit/1",
106+
"kind": "outputUnit",
107+
"name": "1",
108+
"size": 1204,
109+
"filename": "out_1.part.js",
110+
"imports": [
111+
"lib"
112+
]
113+
},
114+
{
115+
"id": "outputUnit/main",
116+
"kind": "outputUnit",
117+
"name": "main",
118+
"filename": "out",
119+
"imports": []
120+
}]
121+
*/
122+
123+
/*kernel.library:
6124
constant=[
7125
{
8126
"id": "constant/B.C_Deferred = A.lib__funky$closure();\n",
@@ -122,7 +240,80 @@
122240

123241
import 'lib.dart' deferred as lib;
124242

125-
/*member: main:
243+
/*spec.member: main:
244+
closure=[{
245+
"id": "closure/memory:sdk/tests/web/native/main.dart::main.main_closure",
246+
"kind": "closure",
247+
"name": "main_closure",
248+
"size": 212,
249+
"outputUnit": "outputUnit/main",
250+
"parent": "function/memory:sdk/tests/web/native/main.dart::main",
251+
"function": "function/memory:sdk/tests/web/native/main.dart::main.main_closure.call"
252+
}],
253+
function=[
254+
{
255+
"id": "function/memory:sdk/tests/web/native/main.dart::main",
256+
"kind": "function",
257+
"name": "main",
258+
"size": 316,
259+
"outputUnit": "outputUnit/main",
260+
"parent": "library/memory:sdk/tests/web/native/main.dart::",
261+
"children": [
262+
"closure/memory:sdk/tests/web/native/main.dart::main.main_closure"
263+
],
264+
"modifiers": {
265+
"static": false,
266+
"const": false,
267+
"factory": false,
268+
"external": false
269+
},
270+
"returnType": "dynamic",
271+
"inferredReturnType": "[exact=_Future]",
272+
"parameters": [],
273+
"sideEffects": "SideEffects(reads anything; writes anything)",
274+
"inlinedCount": 0,
275+
"code": "main() {\n return A.loadDeferredLibrary(\"lib\", \"\").then$1$1(new A.main_closure(), type$.Null);\n }",
276+
"type": "dynamic Function()",
277+
"functionKind": 0
278+
},
279+
{
280+
"id": "function/memory:sdk/tests/web/native/main.dart::main.main_closure.call",
281+
"kind": "function",
282+
"name": "call",
283+
"size": 95,
284+
"outputUnit": "outputUnit/main",
285+
"parent": "closure/memory:sdk/tests/web/native/main.dart::main.main_closure",
286+
"children": [],
287+
"modifiers": {
288+
"static": false,
289+
"const": false,
290+
"factory": false,
291+
"external": false
292+
},
293+
"returnType": "Null",
294+
"inferredReturnType": "[null]",
295+
"parameters": [
296+
{
297+
"name": "_#wc0#formal",
298+
"type": "[null|subclass=Object]",
299+
"declaredType": "dynamic"
300+
}
301+
],
302+
"sideEffects": "SideEffects(reads anything; writes anything)",
303+
"inlinedCount": 0,
304+
"code": "call$1(__wc0_formal) {\n A.checkDeferredIsLoaded(\"lib\");\n C.C_Deferred.call$0();\n }",
305+
"type": "Null Function(dynamic)",
306+
"functionKind": 2
307+
}],
308+
holding=[
309+
{"id":"function/dart:_js_helper::loadDeferredLibrary"},
310+
{"id":"function/dart:_rti::_setArrayType"},
311+
{"id":"function/dart:_rti::findType"},
312+
{"id":"function/dart:async::_Future.then","mask":"[exact=_Future]"},
313+
{"id":"function/memory:sdk/tests/web/native/main.dart::main.main_closure.call"},
314+
{"id":"function/memory:sdk/tests/web/native/main.dart::main.main_closure.call"}]
315+
*/
316+
/*kernel.member: main:
126317
closure=[{
127318
"id": "closure/memory:sdk/tests/web/native/main.dart::main.main_closure",
128319
"kind": "closure",

pkg/front_end/lib/src/api_prototype/experimental_flags_generated.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,11 +341,11 @@ class ExperimentalFlag {
341341

342342
static const ExperimentalFlag wildcardVariables = const ExperimentalFlag(
343343
name: 'wildcard-variables',
344-
isEnabledByDefault: false,
344+
isEnabledByDefault: true,
345345
isExpired: false,
346-
enabledVersion: defaultLanguageVersion,
347-
experimentEnabledVersion: defaultLanguageVersion,
348-
experimentReleasedVersion: defaultLanguageVersion);
346+
enabledVersion: const Version(3, 7),
347+
experimentEnabledVersion: const Version(3, 7),
348+
experimentReleasedVersion: const Version(3, 7));
349349
}
350350

351351
/// Interface for accessing the global state of experimental features.

0 commit comments

Comments
 (0)