Skip to content

Commit 41abb29

Browse files
kallentuCommit Queue
authored andcommitted
[cfe] Handle extension type declarations with dot shorthands.
This CL adds the work needed to be able to use dot shorthands with extension types. Also, there's some additional work to set `isSetter` to false for dot shorthands. Static setters don't work together with shorthands. Bug: #59758 Change-Id: I2c14606cf2970ee249f48189c686ea5cb963df0b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412784 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
1 parent f042e6e commit 41abb29

12 files changed

+147
-9
lines changed

pkg/front_end/lib/src/kernel/hierarchy/extension_type_members.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,18 @@ class ExtensionTypeMembersNode {
279279
}
280280
return result;
281281
}
282+
283+
ClassMember? getStaticMember(Name name, bool isSetter) {
284+
ClassMember? result = isSetter
285+
? (extensionTypeSetableMap?[name] ?? nonExtensionTypeSetableMap?[name])
286+
: (extensionTypeGetableMap?[name] ?? nonExtensionTypeGetableMap?[name]);
287+
if (result == null) {
288+
return null;
289+
} else if (result.isStatic) {
290+
return result;
291+
}
292+
return null;
293+
}
282294
}
283295

284296
class _Tuple {

pkg/front_end/lib/src/kernel/hierarchy/members_builder.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ class ClassMembersBuilder implements ClassHierarchyMembers {
190190
.getMember(name, setter);
191191
}
192192

193+
ClassMember? getExtensionTypeStaticClassMember(
194+
ExtensionTypeDeclaration extensionTypeDeclaration, Name name,
195+
{bool setter = false}) {
196+
return getNodeFromExtensionTypeDeclaration(extensionTypeDeclaration)
197+
.getStaticMember(name, setter);
198+
}
199+
193200
@override
194201
Member? getDispatchTarget(Class cls, Name name, {bool setter = false}) {
195202
return getNodeFromClass(cls)

pkg/front_end/lib/src/kernel/hierarchy/members_node.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,8 @@ class ClassMembersNode {
11891189
}
11901190

11911191
ClassMember? getStaticMember(Name name, bool isSetter) {
1192-
ClassMember? result = classMemberMap[name];
1192+
ClassMember? result =
1193+
isSetter ? classSetterMap[name] : classMemberMap[name];
11931194
if (result == null) {
11941195
return null;
11951196
} else if (result.isStatic) {

pkg/front_end/lib/src/type_inference/inference_visitor.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12120,9 +12120,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
1212012120
DartType cachedContext = getDotShorthandContext().unwrapTypeSchemaView();
1212112121
Member? member = findInterfaceMember(
1212212122
cachedContext, node.name, node.fileOffset,
12123-
includeExtensionMethods: false,
12124-
isSetter: false,
12125-
isDotShorthand: true)
12123+
isSetter: false, isDotShorthand: true)
1212612124
.member;
1212712125

1212812126
ExpressionInferenceResult expressionInferenceResult;

pkg/front_end/lib/src/type_inference/inference_visitor_base.dart

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -968,9 +968,14 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
968968

969969
ObjectAccessTarget? _findExtensionTypeMember(DartType receiverType,
970970
ExtensionType extensionType, Name name, int fileOffset,
971-
{required bool isSetter, required bool hasNonObjectMemberAccess}) {
972-
ClassMember? classMember = _getExtensionTypeMember(
973-
extensionType.extensionTypeDeclaration, name, isSetter);
971+
{required bool isSetter,
972+
required bool hasNonObjectMemberAccess,
973+
bool isDotShorthand = false}) {
974+
ClassMember? classMember = isDotShorthand
975+
? _getExtensionTypeStaticMember(
976+
extensionType.extensionTypeDeclaration, name, false)
977+
: _getExtensionTypeMember(
978+
extensionType.extensionTypeDeclaration, name, isSetter);
974979
if (classMember == null) {
975980
return null;
976981
}
@@ -3752,6 +3757,18 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
37523757
return member;
37533758
}
37543759

3760+
ClassMember? _getExtensionTypeStaticMember(
3761+
ExtensionTypeDeclaration extensionTypeDeclaration,
3762+
Name name,
3763+
bool setter) {
3764+
ClassMember? member = engine.membersBuilder
3765+
.getExtensionTypeStaticClassMember(extensionTypeDeclaration, name,
3766+
setter: setter);
3767+
TypeInferenceEngine.resolveInferenceNode(
3768+
member?.getMember(engine.membersBuilder), hierarchyBuilder);
3769+
return member;
3770+
}
3771+
37553772
bool _isLoweredSetLiteral(Expression expression) {
37563773
if (libraryBuilder.loader.target.backendTarget.supportsSetLiterals) {
37573774
return false;
@@ -4720,15 +4737,16 @@ class _ObjectAccessDescriptor {
47204737
ObjectAccessTarget? target = visitor._findExtensionTypeMember(
47214738
receiverType, receiverBound, name, fileOffset,
47224739
isSetter: isSetter,
4723-
hasNonObjectMemberAccess: hasNonObjectMemberAccess);
4740+
hasNonObjectMemberAccess: hasNonObjectMemberAccess,
4741+
isDotShorthand: isDotShorthand);
47244742
if (target != null) {
47254743
return target;
47264744
}
47274745
}
47284746

47294747
ObjectAccessTarget? target;
47304748
Member? interfaceMember = isDotShorthand
4731-
? visitor._getStaticMember(classNode, name, isSetter)
4749+
? visitor._getStaticMember(classNode, name, false)
47324750
: visitor._getInterfaceMember(classNode, name, isSetter);
47334751
if (interfaceMember != null) {
47344752
target = new ObjectAccessTarget.interfaceMember(
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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+
extension type IntegerExt(int integer) {
6+
static IntegerExt get one => IntegerExt(1);
7+
}
8+
9+
void main() {
10+
IntegerExt c = .one;
11+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
extension type IntegerExt(core::int integer) {
6+
abstract extension-type-member representation-field get integer() → core::int;
7+
static get one = get self::IntegerExt|one;
8+
constructor • = self::IntegerExt|constructor#;
9+
constructor tearoff • = self::IntegerExt|constructor#_#new#tearOff;
10+
}
11+
static extension-type-member method IntegerExt|constructor#(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */ {
12+
lowered final self::IntegerExt% /* erasure=core::int, declared=! */ #this = integer;
13+
return #this;
14+
}
15+
static extension-type-member method IntegerExt|constructor#_#new#tearOff(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */
16+
return self::IntegerExt|constructor#(integer);
17+
static extension-type-member get IntegerExt|one() → self::IntegerExt% /* erasure=core::int, declared=! */
18+
return self::IntegerExt|constructor#(1);
19+
static method main() → void {
20+
self::IntegerExt% /* erasure=core::int, declared=! */ c = self::IntegerExt|one;
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
extension type IntegerExt(core::int integer) {
6+
abstract extension-type-member representation-field get integer() → core::int;
7+
static get one = get self::IntegerExt|one;
8+
constructor • = self::IntegerExt|constructor#;
9+
constructor tearoff • = self::IntegerExt|constructor#_#new#tearOff;
10+
}
11+
static extension-type-member method IntegerExt|constructor#(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */ {
12+
lowered final self::IntegerExt% /* erasure=core::int, declared=! */ #this = integer;
13+
return #this;
14+
}
15+
static extension-type-member method IntegerExt|constructor#_#new#tearOff(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */
16+
return self::IntegerExt|constructor#(integer);
17+
static extension-type-member get IntegerExt|one() → self::IntegerExt% /* erasure=core::int, declared=! */
18+
return self::IntegerExt|constructor#(1);
19+
static method main() → void {
20+
self::IntegerExt% /* erasure=core::int, declared=! */ c = self::IntegerExt|one;
21+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
extension type IntegerExt(core::int integer) {
6+
abstract extension-type-member representation-field get integer() → core::int;
7+
static get one = get self::IntegerExt|one;
8+
constructor • = self::IntegerExt|constructor#;
9+
constructor tearoff • = self::IntegerExt|constructor#_#new#tearOff;
10+
}
11+
static extension-type-member method IntegerExt|constructor#(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */
12+
;
13+
static extension-type-member method IntegerExt|constructor#_#new#tearOff(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */
14+
return self::IntegerExt|constructor#(integer);
15+
static extension-type-member get IntegerExt|one() → self::IntegerExt% /* erasure=core::int, declared=! */
16+
;
17+
static method main() → void
18+
;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
extension type IntegerExt(core::int integer) {
6+
abstract extension-type-member representation-field get integer() → core::int;
7+
static get one = get self::IntegerExt|one;
8+
constructor • = self::IntegerExt|constructor#;
9+
constructor tearoff • = self::IntegerExt|constructor#_#new#tearOff;
10+
}
11+
static extension-type-member method IntegerExt|constructor#(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */ {
12+
lowered final self::IntegerExt% /* erasure=core::int, declared=! */ #this = integer;
13+
return #this;
14+
}
15+
static extension-type-member method IntegerExt|constructor#_#new#tearOff(core::int integer) → self::IntegerExt% /* erasure=core::int, declared=! */
16+
return self::IntegerExt|constructor#(integer);
17+
static extension-type-member get IntegerExt|one() → self::IntegerExt% /* erasure=core::int, declared=! */
18+
return self::IntegerExt|constructor#(1);
19+
static method main() → void {
20+
self::IntegerExt% /* erasure=core::int, declared=! */ c = self::IntegerExt|one;
21+
}

0 commit comments

Comments
 (0)