1
0
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:
Kallen Tu 2024-06-14 22:22:39 +00:00 committed by Commit Queue
parent d15a3963e7
commit f141c97651
10 changed files with 90 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View 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);
}

View File

@ -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});
}

View File

@ -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});
}

View File

@ -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
;

View File

@ -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

View File

@ -0,0 +1,5 @@
typedef R = (String _, String _);
(int _, int _) record = (1, 2);
main() {}

View File

@ -0,0 +1,5 @@
(int _, int _) record = (1, 2);
main() {}
typedef R = (String _, String _);