mirror of
https://github.com/dart-lang/sdk
synced 2024-07-08 20:16:39 +00:00
[cfe] Record type fields can be wildcards.
Positional record type fields named `_` are wildcards. They are non-binding and will not collide with other wildcard fields. Bug: https://github.com/dart-lang/sdk/issues/55655 Change-Id: Ic6985da5bdb32564402d084a3282fa448ff28cbe Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371040 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Kallen Tu <kallentu@google.com>
This commit is contained in:
parent
d15a3963e7
commit
f141c97651
|
@ -149,6 +149,9 @@ abstract class RecordTypeBuilderImpl extends RecordTypeBuilder {
|
|||
positionalEntries.add(type);
|
||||
String? fieldName = field.name;
|
||||
if (fieldName != null) {
|
||||
if (library is SourceLibraryBuilder && field.isWildcard) {
|
||||
continue;
|
||||
}
|
||||
if (fieldName.startsWith("_")) {
|
||||
library.addProblem(messageRecordFieldsCantBePrivate,
|
||||
field.charOffset, fieldName.length, fileUri);
|
||||
|
@ -380,7 +383,10 @@ class RecordTypeFieldBuilder {
|
|||
|
||||
final int charOffset;
|
||||
|
||||
RecordTypeFieldBuilder(this.metadata, this.type, this.name, this.charOffset);
|
||||
final bool isWildcard;
|
||||
|
||||
RecordTypeFieldBuilder(this.metadata, this.type, this.name, this.charOffset,
|
||||
{this.isWildcard = false});
|
||||
|
||||
RecordTypeFieldBuilder clone(
|
||||
List<NamedTypeBuilder> newTypes,
|
||||
|
@ -392,7 +398,8 @@ class RecordTypeFieldBuilder {
|
|||
metadata,
|
||||
type.clone(newTypes, contextLibrary, contextDeclaration),
|
||||
name,
|
||||
charOffset);
|
||||
charOffset,
|
||||
isWildcard: isWildcard);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -5213,13 +5213,17 @@ class BodyBuilder extends StackListenerImpl
|
|||
Object? type = pop();
|
||||
// TODO(johnniwinther): How should we handle annotations?
|
||||
pop(NullValues.Metadata); // Annotations.
|
||||
|
||||
String? fieldName = name is Identifier ? name.name : null;
|
||||
push(new RecordTypeFieldBuilder(
|
||||
[],
|
||||
type is ParserRecovery
|
||||
? new InvalidTypeBuilderImpl(uri, type.charOffset)
|
||||
: type as TypeBuilder,
|
||||
name is Identifier ? name.name : null,
|
||||
name is Identifier ? name.nameOffset : TreeNode.noOffset));
|
||||
fieldName,
|
||||
name is Identifier ? name.nameOffset : TreeNode.noOffset,
|
||||
isWildcard:
|
||||
libraryFeatures.wildcardVariables.isEnabled && fieldName == '_'));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -3172,13 +3172,17 @@ class OutlineBuilder extends StackListenerImpl {
|
|||
Object? type = pop();
|
||||
List<MetadataBuilder>? metadata =
|
||||
pop(NullValues.Metadata) as List<MetadataBuilder>?;
|
||||
|
||||
String? fieldName = identifier is Identifier ? identifier.name : null;
|
||||
push(new RecordTypeFieldBuilder(
|
||||
metadata,
|
||||
type is ParserRecovery
|
||||
? new InvalidTypeBuilderImpl(uri, type.charOffset)
|
||||
: type as TypeBuilder,
|
||||
identifier is Identifier ? identifier.name : null,
|
||||
identifier is Identifier ? identifier.nameOffset : -1));
|
||||
fieldName,
|
||||
identifier is Identifier ? identifier.nameOffset : -1,
|
||||
isWildcard:
|
||||
libraryFeatures.wildcardVariables.isEnabled && fieldName == '_'));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
12
pkg/front_end/testcases/wildcard_variables/record_type.dart
Normal file
12
pkg/front_end/testcases/wildcard_variables/record_type.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
// 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.
|
||||
|
||||
typedef R = (String _, String _);
|
||||
(int _, int _) record = (1, 2);
|
||||
|
||||
main() {
|
||||
(int _, int _) localRecord = (1, 2);
|
||||
print(localRecord.$1);
|
||||
print(record.$1);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
typedef R = (core::String, core::String);
|
||||
static field (core::int, core::int) record = (1, 2);
|
||||
static method main() → dynamic {
|
||||
(core::int, core::int) localRecord = (1, 2);
|
||||
core::print(localRecord.$1{core::int});
|
||||
core::print(self::record.$1{core::int});
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
typedef R = (core::String, core::String);
|
||||
static field (core::int, core::int) record = (1, 2);
|
||||
static method main() → dynamic {
|
||||
(core::int, core::int) localRecord = (1, 2);
|
||||
core::print(localRecord.$1{core::int});
|
||||
core::print(self::record.$1{core::int});
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
typedef R = (core::String, core::String);
|
||||
static field (core::int, core::int) record;
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -0,0 +1,17 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
typedef R = (core::String, core::String);
|
||||
static field (core::int, core::int) record = (1, 2);
|
||||
static method main() → dynamic {
|
||||
(core::int, core::int) localRecord = (1, 2);
|
||||
core::print(localRecord.$1{core::int});
|
||||
core::print(self::record.$1{core::int});
|
||||
}
|
||||
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_type.dart:9:32 -> RecordConstant(const (1, 2))
|
||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///record_type.dart:6:25 -> RecordConstant(const (1, 2))
|
||||
Extra constant evaluation: evaluated: 8, effectively constant: 2
|
|
@ -0,0 +1,5 @@
|
|||
typedef R = (String _, String _);
|
||||
|
||||
(int _, int _) record = (1, 2);
|
||||
|
||||
main() {}
|
|
@ -0,0 +1,5 @@
|
|||
(int _, int _) record = (1, 2);
|
||||
|
||||
main() {}
|
||||
|
||||
typedef R = (String _, String _);
|
Loading…
Reference in New Issue
Block a user