Skip to content

Commit e9a9d94

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Build extension methods as toplevel members
+ add an 'isExtensionMethod' property to Procedure. Change-Id: I8fb1af1802570c827bf3ccbbb9d710eb2a6981ab Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112081 Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
1 parent 7bde331 commit e9a9d94

25 files changed

+291
-190
lines changed

pkg/front_end/lib/src/fasta/builder/procedure_builder.dart

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,15 @@ class ProcedureBuilder extends FunctionBuilder {
488488
return false;
489489
}
490490

491+
/// Returns `true` if this procedure is declared in an extension declaration.
492+
bool get isExtensionMethod {
493+
if (parent is ClassBuilder) {
494+
ClassBuilder cls = parent;
495+
return cls.isExtension;
496+
}
497+
return false;
498+
}
499+
491500
Procedure build(SourceLibraryBuilder library) {
492501
// TODO(ahe): I think we may call this twice on parts. Investigate.
493502
if (procedure.name == null) {
@@ -496,10 +505,18 @@ class ProcedureBuilder extends FunctionBuilder {
496505
procedure.function.fileOffset = charOpenParenOffset;
497506
procedure.function.fileEndOffset = procedure.fileEndOffset;
498507
procedure.isAbstract = isAbstract;
499-
procedure.isStatic = isStatic;
500508
procedure.isExternal = isExternal;
501509
procedure.isConst = isConst;
502-
procedure.name = new Name(name, library.target);
510+
if (isExtensionMethod) {
511+
ClassBuilder extension = parent;
512+
procedure.isStatic = false;
513+
procedure.isExtensionMethod = true;
514+
procedure.kind = ProcedureKind.Method;
515+
procedure.name = new Name('${extension.name}|${name}', library.target);
516+
} else {
517+
procedure.isStatic = isStatic;
518+
procedure.name = new Name(name, library.target);
519+
}
503520
}
504521
return procedure;
505522
}

pkg/front_end/lib/src/fasta/source/source_class_builder.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,13 @@ class SourceClassBuilder extends ClassBuilder
130130
}
131131
} else if (declaration is FunctionBuilder) {
132132
Member function = declaration.build(library);
133-
function.parent = cls;
134-
if (!declaration.isPatch && declaration.next == null) {
135-
cls.addMember(function);
133+
if (isExtension) {
134+
library.target.addMember(function);
135+
} else {
136+
function.parent = cls;
137+
if (!declaration.isPatch && declaration.next == null) {
138+
cls.addMember(function);
139+
}
136140
}
137141
} else {
138142
unhandled("${declaration.runtimeType}", "buildBuilders",

pkg/front_end/lib/src/testing/id_testing_utils.dart

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,36 @@ ClassBuilder lookupClassBuilder(CompilerResult compilerResult, Class cls,
104104
return clsBuilder;
105105
}
106106

107+
/// Look up the [MemberBuilder] for [member] through the [ClassBuilder] for
108+
/// [cls] using [memberName] as its name.
109+
MemberBuilder lookupClassMemberBuilder(
110+
CompilerResult compilerResult, Class cls, Member member, String memberName,
111+
{bool required: true}) {
112+
ClassBuilder classBuilder =
113+
lookupClassBuilder(compilerResult, cls, required: required);
114+
MemberBuilder memberBuilder;
115+
if (classBuilder != null) {
116+
if (member is Constructor) {
117+
memberBuilder = classBuilder.constructors.local[memberName];
118+
} else if (member is Procedure && member.isSetter) {
119+
memberBuilder = classBuilder.scope.setters[memberName];
120+
} else {
121+
memberBuilder = classBuilder.scope.local[memberName];
122+
}
123+
}
124+
if (memberBuilder == null && required) {
125+
throw new ArgumentError("MemberBuilder for $member not found.");
126+
}
127+
return memberBuilder;
128+
}
129+
107130
MemberBuilder lookupMemberBuilder(CompilerResult compilerResult, Member member,
108131
{bool required: true}) {
109132
MemberBuilder memberBuilder;
110133
if (member.enclosingClass != null) {
111-
ClassBuilder classBuilder = lookupClassBuilder(
112-
compilerResult, member.enclosingClass,
134+
memberBuilder = lookupClassMemberBuilder(
135+
compilerResult, member.enclosingClass, member, member.name.name,
113136
required: required);
114-
if (classBuilder != null) {
115-
if (member is Constructor) {
116-
memberBuilder = classBuilder.constructors.local[member.name.name];
117-
} else if (member is Procedure && member.isSetter) {
118-
memberBuilder = classBuilder.scope.setters[member.name.name];
119-
} else {
120-
memberBuilder = classBuilder.scope.local[member.name.name];
121-
}
122-
}
123137
} else {
124138
DeclarationBuilder libraryBuilder = lookupLibraryDeclarationBuilder(
125139
compilerResult, member.enclosingLibrary);

pkg/front_end/test/extensions/data/explicit_this.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,26 @@ class A1 {
1515
cls-supertype=Object
1616
*/
1717
extension A2 on A1 {
18-
/*member: A2.method2:
18+
/*member: A2|method2:
1919
builder-name=method2,
2020
builder-params=[#this],
21-
member-name=method2,
21+
member-name=A2|method2,
2222
member-params=[#this]
2323
*/
2424
void method2() => this.method1();
2525

26-
/*member: A2.method3:
26+
/*member: A2|method3:
2727
builder-name=method3,
2828
builder-params=[#this],
29-
member-name=method3,
29+
member-name=A2|method3,
3030
member-params=[#this]
3131
*/
3232
Object method3() => this.field;
3333

34-
/*member: A2.method4:
34+
/*member: A2|method4:
3535
builder-name=method4,
3636
builder-params=[#this,o],
37-
member-name=method4,
37+
member-name=A2|method4,
3838
member-params=[#this,o]
3939
*/
4040
void method4(Object o) {

pkg/front_end/test/extensions/data/extension_on_type_variable.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
cls-type-params=[T]
1313
*/
1414
extension GeneralGeneric<T> on T {
15-
/*member: GeneralGeneric.method:
15+
/*member: GeneralGeneric|method:
1616
builder-name=method,
1717
builder-params=[#this],
1818
builder-type-params=[T],
19-
member-name=method,
19+
member-name=GeneralGeneric|method,
2020
member-params=[#this],
2121
member-type-params=[#T]
2222
*/

pkg/front_end/test/extensions/data/implicit_this.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,26 @@ class A1 {
1515
cls-supertype=Object
1616
*/
1717
extension A2 on A1 {
18-
/*member: A2.method2:
18+
/*member: A2|method2:
1919
builder-name=method2,
2020
builder-params=[#this],
21-
member-name=method2,
21+
member-name=A2|method2,
2222
member-params=[#this]
2323
*/
2424
void method2() => method1();
2525

26-
/*member: A2.method3:
26+
/*member: A2|method3:
2727
builder-name=method3,
2828
builder-params=[#this],
29-
member-name=method3,
29+
member-name=A2|method3,
3030
member-params=[#this]
3131
*/
3232
Object method3() => field;
3333

34-
/*member: A2.method4:
34+
/*member: A2|method4:
3535
builder-name=method4,
3636
builder-params=[#this,o],
37-
member-name=method4,
37+
member-name=A2|method4,
3838
member-params=[#this,o]
3939
*/
4040
void method4(Object o) {

pkg/front_end/test/extensions/data/instance_members.dart

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ class A1 {}
1212
cls-supertype=Object
1313
*/
1414
extension A2 on A1 {
15-
/*member: A2.method1:
15+
/*member: A2|method1:
1616
builder-name=method1,
1717
builder-params=[#this],
18-
member-name=method1,
18+
member-name=A2|method1,
1919
member-params=[#this]
2020
*/
2121
A1 method1() {
2222
return this;
2323
}
2424

25-
/*member: A2.method2:
25+
/*member: A2|method2:
2626
builder-name=method2,
2727
builder-params=[#this,o],
2828
builder-type-params=[T],
29-
member-name=method2,
29+
member-name=A2|method2,
3030
member-params=[#this,o],
3131
member-type-params=[T]
3232
*/
@@ -35,12 +35,12 @@ extension A2 on A1 {
3535
return this;
3636
}
3737

38-
/*member: A2.method3:
38+
/*member: A2|method3:
3939
builder-name=method3,
4040
builder-params=[#this],
4141
builder-pos-params=[o],
4242
builder-type-params=[T],
43-
member-name=method3,
43+
member-name=A2|method3,
4444
member-params=[#this],
4545
member-pos-params=[o],
4646
member-type-params=[T]
@@ -50,12 +50,12 @@ extension A2 on A1 {
5050
return this;
5151
}
5252

53-
/*member: A2.method4:
53+
/*member: A2|method4:
5454
builder-name=method4,
5555
builder-params=[#this],
5656
builder-named-params=[o],
5757
builder-type-params=[T],
58-
member-name=method4,
58+
member-name=A2|method4,
5959
member-params=[#this],
6060
member-named-params=[o],
6161
member-type-params=[T]
@@ -78,23 +78,23 @@ class B1<T> {}
7878
cls-type-params=[T]
7979
*/
8080
extension B2<T> on B1<T> {
81-
/*member: B2.method1:
81+
/*member: B2|method1:
8282
builder-name=method1,
8383
builder-params=[#this],
8484
builder-type-params=[T],
85-
member-name=method1,
85+
member-name=B2|method1,
8686
member-params=[#this],
8787
member-type-params=[#T]
8888
*/
8989
B1<T> method1() {
9090
return this;
9191
}
9292

93-
/*member: B2.method2:
93+
/*member: B2|method2:
9494
builder-name=method2,
9595
builder-params=[#this,o],
9696
builder-type-params=[T,S],
97-
member-name=method2,
97+
member-name=B2|method2,
9898
member-params=[#this,o],
9999
member-type-params=[#T,S]
100100
*/

pkg/front_end/test/extensions/data/static_members.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@ class A1 {}
1212
cls-supertype=Object
1313
*/
1414
extension A2 on A1 {
15-
/*member: A2.method1:
15+
/*member: A2|method1:
1616
builder-name=method1,
1717
builder-params=[o],
18-
member-name=method1,
18+
member-name=A2|method1,
1919
member-params=[o]
2020
*/
2121
static A1 method1(A1 o) => o;
2222

23-
/*member: A2.method2:
23+
/*member: A2|method2:
2424
builder-name=method2,
2525
builder-params=[o],
2626
builder-type-params=[T],
27-
member-name=method2,
27+
member-name=A2|method2,
2828
member-params=[o],
2929
member-type-params=[T]
3030
*/
@@ -43,19 +43,19 @@ class B1<T> {}
4343
cls-type-params=[T]
4444
*/
4545
extension B2<T> on B1<T> {
46-
/*member: B2.method1:
46+
/*member: B2|method1:
4747
builder-name=method1,
4848
builder-params=[o],
49-
member-name=method1,
49+
member-name=B2|method1,
5050
member-params=[o]
5151
*/
5252
static B1 method1(B1 o) => o;
5353

54-
/*member: B2.method2:
54+
/*member: B2|method2:
5555
builder-name=method2,
5656
builder-params=[o],
5757
builder-type-params=[S],
58-
member-name=method2,
58+
member-name=B2|method2,
5959
member-params=[o],
6060
member-type-params=[S]
6161
*/

pkg/front_end/test/extensions/data/super.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ class A1 {
1414
cls-supertype=Object
1515
*/
1616
extension A2 on A1 {
17-
/*member: A2.method2:
17+
/*member: A2|method2:
1818
builder-name=method2,
1919
builder-params=[#this],
20-
member-name=method2,
20+
member-name=A2|method2,
2121
member-params=[#this]
2222
*/
2323
method2() {

pkg/front_end/test/extensions/data/type_variables.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@ class A1<T> {}
1414
cls-type-params=[T]
1515
*/
1616
extension A2<T> on A1<T> {
17-
/*member: A2.method1:
17+
/*member: A2|method1:
1818
builder-name=method1,
1919
builder-params=[#this],
2020
builder-type-params=[T,S extends T],
21-
member-name=method1,
21+
member-name=A2|method1,
2222
member-params=[#this],
2323
member-type-params=[#T,S extends #T]
2424
*/
2525
A1<T> method1<S extends T>() {
2626
return this;
2727
}
2828

29-
/*member: A2.method2:
29+
/*member: A2|method2:
3030
builder-name=method2,
3131
builder-params=[#this,o],
3232
builder-type-params=[T,S extends A1<T>],
33-
member-name=method2,
33+
member-name=A2|method2,
3434
member-params=[#this,o],
3535
member-type-params=[#T,S extends A1<#T>]
3636
*/

0 commit comments

Comments
 (0)