Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e0d7c13

Browse files
munificentCommit Queue
authored and
Commit Queue
committed
[private named parameters] Implement in CFE.
I'm not sure if this is the best approach, but it's pretty non-invasive and seems to do the right thing as far as I can tell. Let me know what you think. Change-Id: I171e2d628d24a525c9b2ea99c54ff6bd84a6337a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/461942 Auto-Submit: Bob Nystrom <rnystrom@google.com> Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Paul Berry <paulberry@google.com>
1 parent 3f3454c commit e0d7c13

27 files changed

+374
-10
lines changed

‎pkg/front_end/lib/src/builder/formal_parameter_builder.dart‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,20 @@ class FormalParameterBuilder extends NamedBuilderImpl
7272
@override
7373
final String name;
7474

75+
/// If this parameter is a private named parameter that refers to an instance
76+
/// field, then this is the corresponding public name for the parameter.
77+
///
78+
/// For example:
79+
///
80+
/// class C {
81+
/// int? _x;
82+
/// C({this._x});
83+
/// }
84+
///
85+
/// Here, [publicName] for `_x` will be `x`. If the formal parameter isn't a
86+
/// private named parameter that refers to a field, then this is `null`.
87+
final String? publicName;
88+
7589
@override
7690
final Uri fileUri;
7791

@@ -113,6 +127,7 @@ class FormalParameterBuilder extends NamedBuilderImpl
113127
Token? initializerToken,
114128
required this.hasImmediatelyDeclaredInitializer,
115129
this.isWildcard = false,
130+
this.publicName,
116131
}) : this.hasDeclaredInitializer = hasImmediatelyDeclaredInitializer,
117132
this._initializerToken = initializerToken {
118133
type.registerInferredTypeListener(this);
@@ -172,10 +187,18 @@ class FormalParameterBuilder extends NamedBuilderImpl
172187
if (variable == null) {
173188
bool isTypeOmitted = type is OmittedTypeBuilder;
174189
DartType? builtType = type.build(library, TypeUse.parameterType);
190+
191+
String? variableName = switch (name) {
192+
noNameSentinel => null,
193+
// If the parameter is a private named parameter, use the public name
194+
// for the corresponding variable.
195+
_ when publicName != null => publicName,
196+
_ => name,
197+
};
198+
175199
variable = new VariableDeclarationImpl(
176-
name == noNameSentinel ? null : name,
177-
// `null` is used in [VariableDeclarationImpl] to signal an omitted
178-
// type.
200+
variableName,
201+
// [VariableDeclarationImpl] uses `null` to signal an omitted type.
179202
type: isTypeOmitted ? null : builtType,
180203
isFinal: modifiers.isFinal,
181204
isConst: false,
@@ -210,6 +233,7 @@ class FormalParameterBuilder extends NamedBuilderImpl
210233
isExtensionThis: isExtensionThis,
211234
initializerToken: _takeInitializerToken(),
212235
hasImmediatelyDeclaredInitializer: hasImmediatelyDeclaredInitializer,
236+
publicName: publicName,
213237
)..variable = variable;
214238
}
215239

@@ -224,6 +248,7 @@ class FormalParameterBuilder extends NamedBuilderImpl
224248
fileUri: fileUri,
225249
isExtensionThis: isExtensionThis,
226250
hasImmediatelyDeclaredInitializer: hasImmediatelyDeclaredInitializer,
251+
publicName: publicName,
227252
)..variable = variable;
228253
} else if (isSuperInitializingFormal) {
229254
return new FormalParameterBuilder(
@@ -235,6 +260,7 @@ class FormalParameterBuilder extends NamedBuilderImpl
235260
fileUri: fileUri,
236261
isExtensionThis: isExtensionThis,
237262
hasImmediatelyDeclaredInitializer: hasImmediatelyDeclaredInitializer,
263+
publicName: publicName,
238264
)..variable = variable;
239265
} else {
240266
return this;

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5406,17 +5406,21 @@ class BodyBuilderImpl extends StackListenerImpl
54065406
Identifier? name = nameNode as Identifier?;
54075407

54085408
// If it's a private named parameter, handle the public name.
5409+
String? publicName;
54095410
if (libraryFeatures.privateNamedParameters.isEnabled &&
54105411
kind.isNamed &&
54115412
name != null &&
54125413
name.name.startsWith('_')) {
54135414
// TODO(rnystrom): Also handle declaring field parameters.
54145415
bool refersToField = thisKeyword != null;
54155416

5416-
// If you can't even use a private named parameter here at all, the
5417-
// parser has already reported an error about that. Don't bother reporting
5418-
// a second error about it being a bad private name.
5419-
if (refersToField && correspondingPublicName(name.name) == null) {
5417+
publicName = correspondingPublicName(name.name);
5418+
5419+
// Only report the error for no corresponding public name if this is a
5420+
// parameter that could be private and named. Otherwise, that's already
5421+
// an error (which has been reported by the parser), so don't report a
5422+
// second error on top.
5423+
if (refersToField && publicName == null) {
54205424
handleRecoverableError(
54215425
cfe.codePrivateNamedParameterWithoutPublicName,
54225426
nameToken,
@@ -5466,6 +5470,7 @@ class BodyBuilderImpl extends StackListenerImpl
54665470
fileUri: uri,
54675471
hasImmediatelyDeclaredInitializer: initializerStart != null,
54685472
isWildcard: isWildcard,
5473+
publicName: publicName,
54695474
);
54705475
}
54715476
VariableDeclaration variable = parameter.build(libraryBuilder);

‎pkg/front_end/lib/src/source/fragment_factory.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ abstract class FragmentFactory {
464464
Modifiers modifiers,
465465
TypeBuilder type,
466466
String name,
467+
String? publicName,
467468
bool hasThis,
468469
bool hasSuper,
469470
int charOffset,

‎pkg/front_end/lib/src/source/fragment_factory_impl.dart‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2151,6 +2151,7 @@ class FragmentFactoryImpl implements FragmentFactory {
21512151
Modifiers modifiers,
21522152
TypeBuilder type,
21532153
String name,
2154+
String? publicName,
21542155
bool hasThis,
21552156
bool hasSuper,
21562157
int charOffset,
@@ -2184,6 +2185,7 @@ class FragmentFactoryImpl implements FragmentFactory {
21842185
initializerToken: initializerToken,
21852186
hasImmediatelyDeclaredInitializer: initializerToken != null,
21862187
isWildcard: isWildcard,
2188+
publicName: publicName,
21872189
);
21882190
return formal;
21892191
}

‎pkg/front_end/lib/src/source/outline_builder.dart‎

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import 'package:_fe_analyzer_shared/src/parser/parser.dart'
1515
import 'package:_fe_analyzer_shared/src/parser/quote.dart' show unescapeString;
1616
import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart'
1717
show FixedNullableList, NullValues, ParserRecovery;
18+
import 'package:_fe_analyzer_shared/src/scanner/token_impl.dart'
19+
show correspondingPublicName;
1820
import 'package:_fe_analyzer_shared/src/scanner/token.dart'
1921
show Keyword, Token, TokenIsAExtension, TokenType;
2022
import 'package:_fe_analyzer_shared/src/types/shared_type.dart' show Variance;
@@ -3052,6 +3054,24 @@ class OutlineBuilder extends StackListenerImpl {
30523054
push(name);
30533055
} else {
30543056
Identifier? identifier = name as Identifier?;
3057+
3058+
String parameterName = identifier == null
3059+
? FormalParameterBuilder.noNameSentinel
3060+
: identifier.name;
3061+
3062+
// If we're building a private named parameter, then calculate the
3063+
// corresponding public name. The variable declared by the parameter will
3064+
// use that name instead.
3065+
String? publicName;
3066+
// TODO(rnystrom): Also handle declaring field parameters.
3067+
bool refersToField = thisKeyword != null;
3068+
if (refersToField &&
3069+
libraryFeatures.privateNamedParameters.isEnabled &&
3070+
kind.isNamed &&
3071+
parameterName.startsWith('_')) {
3072+
publicName = correspondingPublicName(parameterName);
3073+
}
3074+
30553075
push(
30563076
_builderFactory.addFormalParameter(
30573077
metadata,
@@ -3061,9 +3081,8 @@ class OutlineBuilder extends StackListenerImpl {
30613081
(memberKind.isParameterInferable
30623082
? _builderFactory.addInferableType()
30633083
: const ImplicitTypeBuilder()),
3064-
identifier == null
3065-
? FormalParameterBuilder.noNameSentinel
3066-
: identifier.name,
3084+
parameterName,
3085+
publicName,
30673086
thisKeyword != null,
30683087
superKeyword != null,
30693088
identifier?.nameOffset ?? nameToken.charOffset,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2025, 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+
class C {
6+
int? _x;
7+
int? _y;
8+
C({this._x}) : _y = _x;
9+
}
10+
11+
main() {
12+
var c = C(x: 1);
13+
print(c._y);
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::int? _x;
7+
field core::int? _y;
8+
constructor •({core::int? x = #C1}) → self::C
9+
: self::C::_x = x, self::C::_y = x, super core::Object::•()
10+
;
11+
}
12+
static method main() → dynamic {
13+
self::C c = new self::C::•(x: 1);
14+
core::print(c.{self::C::_y}{core::int?});
15+
}
16+
17+
constants {
18+
#C1 = null
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::int? _x;
7+
field core::int? _y;
8+
constructor •({core::int? x = #C1}) → self::C
9+
: self::C::_x = x, self::C::_y = x, super core::Object::•()
10+
;
11+
}
12+
static method main() → dynamic {
13+
self::C c = new self::C::•(x: 1);
14+
core::print(c.{self::C::_y}{core::int?});
15+
}
16+
17+
constants {
18+
#C1 = null
19+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::int? _x;
7+
field core::int? _y;
8+
constructor •({core::int? x = null}) → self::C
9+
;
10+
}
11+
static method main() → dynamic
12+
;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class C extends core::Object {
6+
field core::int? _x;
7+
field core::int? _y;
8+
constructor •({core::int? x = #C1}) → self::C
9+
: self::C::_x = x, self::C::_y = x, super core::Object::•()
10+
;
11+
}
12+
static method main() → dynamic {
13+
self::C c = new self::C::•(x: 1);
14+
core::print(c.{self::C::_y}{core::int?});
15+
}
16+
17+
constants {
18+
#C1 = null
19+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /