Skip to content

Commit 11755e5

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Add tests for extension members
+ Avoid creating default constructors. Change-Id: Ie0ed967d9be4cf31a2eb6991767887de1f88149a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109702 Reviewed-by: Dan Rubel <[email protected]>
1 parent 610183d commit 11755e5

File tree

6 files changed

+249
-42
lines changed

6 files changed

+249
-42
lines changed

pkg/front_end/lib/src/fasta/kernel/kernel_target.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,11 @@ class KernelTarget extends TargetImplementation {
392392
Class objectClass = this.objectClass;
393393
for (SourceClassBuilder builder in builders) {
394394
if (builder.target != objectClass && !builder.isPatch) {
395-
if (builder.isPatch || builder.isMixinDeclaration) continue;
395+
if (builder.isPatch ||
396+
builder.isMixinDeclaration ||
397+
builder.isExtension) {
398+
continue;
399+
}
396400
if (builder.isMixinApplication) {
397401
installForwardingConstructors(builder);
398402
} else {
@@ -410,6 +414,7 @@ class KernelTarget extends TargetImplementation {
410414
/// If [builder] doesn't have a constructors, install the defaults.
411415
void installDefaultConstructor(SourceClassBuilder builder) {
412416
assert(!builder.isMixinApplication);
417+
assert(!builder.isExtension);
413418
// TODO(askesc): Make this check light-weight in the absence of patches.
414419
if (builder.target.constructors.isNotEmpty) return;
415420
if (builder.target.redirectingFactoryConstructors.isNotEmpty) return;

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,22 @@ class CfeCompiledData<T> extends CompiledData<T> {
9595
if (id is MemberId) {
9696
Library library = lookupLibrary(compilerResult.component, uri);
9797
Member member;
98+
int offset;
9899
if (id.className != null) {
99100
Class cls = lookupClass(library, id.className);
100101
member = lookupClassMember(cls, id.memberName);
102+
offset = member.fileOffset;
103+
if (offset == -1) {
104+
offset = cls.fileOffset;
105+
}
101106
} else {
102107
member = lookupLibraryMember(library, id.memberName);
108+
offset = member.fileOffset;
109+
}
110+
if (offset == -1) {
111+
offset = 0;
103112
}
104-
return member.fileOffset;
113+
return offset;
105114
} else if (id is ClassId) {
106115
Library library = lookupLibrary(compilerResult.component, uri);
107116
Class cls = lookupClass(library, id.className);

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

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:front_end/src/fasta/builder/builder.dart';
6-
7-
/// Helper methods to use on annotated tests.
8-
6+
import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
7+
import 'package:front_end/src/fasta/source/source_library_builder.dart';
8+
import 'package:front_end/src/fasta/source/source_loader.dart';
9+
import 'package:front_end/src/kernel_generator_impl.dart';
910
import 'package:kernel/ast.dart';
1011

12+
/// Helper methods to use in annotated tests.
13+
1114
/// Returns a canonical simple name for [member].
1215
String getMemberName(Member member) {
1316
if (member is Procedure && member.isSetter) return '${member.name.name}=';
@@ -77,6 +80,61 @@ Member lookupClassMember(Class cls, String memberName, {bool required: true}) {
7780
});
7881
}
7982

83+
DeclarationBuilder<TypeBuilder> lookupLibraryDeclarationBuilder(
84+
CompilerResult compilerResult, Library library,
85+
{bool required: true}) {
86+
SourceLoader loader = compilerResult.kernelTargetForTesting.loader;
87+
KernelLibraryBuilder builder = loader.builders[library.importUri];
88+
if (builder == null && required) {
89+
throw new ArgumentError("DeclarationBuilder for $library not found.");
90+
}
91+
return builder.libraryDeclaration;
92+
}
93+
94+
ClassBuilder lookupClassBuilder(CompilerResult compilerResult, Class cls,
95+
{bool required: true}) {
96+
DeclarationBuilder<TypeBuilder> libraryBuilder =
97+
lookupLibraryDeclarationBuilder(compilerResult, cls.enclosingLibrary,
98+
required: required);
99+
ClassBuilder clsBuilder = libraryBuilder.members[cls.name];
100+
if (clsBuilder == null && required) {
101+
throw new ArgumentError("ClassBuilder for $cls not found.");
102+
}
103+
return clsBuilder;
104+
}
105+
106+
MemberBuilder lookupMemberBuilder(CompilerResult compilerResult, Member member,
107+
{bool required: true}) {
108+
MemberBuilder memberBuilder;
109+
if (member.enclosingClass != null) {
110+
ClassBuilder classBuilder = lookupClassBuilder(
111+
compilerResult, member.enclosingClass,
112+
required: required);
113+
if (classBuilder != null) {
114+
if (member is Constructor) {
115+
memberBuilder = classBuilder.constructors.local[member.name.name];
116+
} else if (member is Procedure && member.isSetter) {
117+
memberBuilder = classBuilder.scope.setters[member.name.name];
118+
} else {
119+
memberBuilder = classBuilder.scope.local[member.name.name];
120+
}
121+
}
122+
} else {
123+
DeclarationBuilder<TypeBuilder> libraryBuilder =
124+
lookupLibraryDeclarationBuilder(
125+
compilerResult, member.enclosingLibrary);
126+
if (member is Procedure && member.isSetter) {
127+
memberBuilder = libraryBuilder.members[member.name.name];
128+
} else {
129+
memberBuilder = libraryBuilder.setters[member.name.name];
130+
}
131+
}
132+
if (memberBuilder == null && required) {
133+
throw new ArgumentError("MemberBuilder for $member not found.");
134+
}
135+
return memberBuilder;
136+
}
137+
80138
/// Returns a textual representation of the constant [node] to be used in
81139
/// testing.
82140
String constantToText(Constant node) {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2019, 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 A1 {}
6+
7+
/*class: A2:
8+
builder-name=A2,
9+
builder-onTypes=[A1],
10+
builder-supertype=Object,
11+
cls-name=A2,
12+
cls-supertype=Object
13+
*/
14+
extension A2 on A1 {
15+
/*member: A2.method1:
16+
builder-name=method1,
17+
member-name=method1
18+
*/
19+
void method1() {}
20+
21+
/*member: A2.method2:
22+
builder-name=method2,
23+
builder-type-params=[T],
24+
member-name=method2,
25+
member-type-params=[T]
26+
*/
27+
void method2<T>() {}
28+
}
29+
30+
class B1<T> {}
31+
32+
/*class: B2:
33+
builder-name=B2,
34+
builder-onTypes=[B1<T>],
35+
builder-supertype=Object,
36+
builder-type-params=[T],
37+
cls-name=B2,
38+
cls-supertype=Object,
39+
cls-type-params=[T]
40+
*/
41+
extension B2<T> on B1<T> {
42+
/*member: B2.method1:
43+
builder-name=method1,
44+
member-name=method1
45+
*/
46+
void method1() {}
47+
48+
/*member: B2.method2:
49+
builder-name=method2,
50+
builder-type-params=[S],
51+
member-name=method2,
52+
member-type-params=[S]
53+
*/
54+
void method2<S>() {}
55+
}
56+
57+
main() {}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) 2019, 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 A1 {}
6+
7+
/*class: A2:
8+
builder-name=A2,
9+
builder-onTypes=[A1],
10+
builder-supertype=Object,
11+
cls-name=A2,
12+
cls-supertype=Object
13+
*/
14+
extension A2 on A1 {
15+
/*member: A2.method1:
16+
builder-name=method1,
17+
member-name=method1
18+
*/
19+
static void method1() {}
20+
21+
/*member: A2.method2:
22+
builder-name=method2,
23+
builder-type-params=[T],
24+
member-name=method2,
25+
member-type-params=[T]
26+
*/
27+
static void method2<T>() {}
28+
}
29+
30+
class B1<T> {}
31+
32+
/*class: B2:
33+
builder-name=B2,
34+
builder-onTypes=[B1<T>],
35+
builder-supertype=Object,
36+
builder-type-params=[T],
37+
cls-name=B2,
38+
cls-supertype=Object,
39+
cls-type-params=[T]
40+
*/
41+
extension B2<T> on B1<T> {
42+
/*member: B2.method1:
43+
builder-name=method1,
44+
member-name=method1
45+
*/
46+
static void method1() {}
47+
48+
/*member: B2.method2:
49+
builder-name=method2,
50+
builder-type-params=[S],
51+
member-name=method2,
52+
member-type-params=[S]
53+
*/
54+
static void method2<S>() {}
55+
}
56+
57+
main() {}

pkg/front_end/test/extensions/extensions_test.dart

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
import 'dart:io' show Directory, Platform;
66
import 'package:front_end/src/fasta/builder/builder.dart';
77
import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
8-
import 'package:front_end/src/fasta/kernel/kernel_library_builder.dart';
9-
import 'package:front_end/src/fasta/source/source_library_builder.dart';
10-
import 'package:front_end/src/fasta/source/source_loader.dart';
118
import 'package:front_end/src/testing/id.dart' show ActualData, Id;
129
import 'package:front_end/src/testing/features.dart';
1310
import 'package:front_end/src/testing/id_testing.dart'
@@ -70,6 +67,9 @@ class Tags {
7067
static const String clsTypeParameters = 'cls-type-params';
7168
static const String clsSupertype = 'cls-supertype';
7269
static const String clsInterfaces = 'cls-interfaces';
70+
71+
static const String memberName = 'member-name';
72+
static const String memberTypeParameters = 'member-type-params';
7373
}
7474

7575
class ExtensionsDataExtractor extends CfeDataExtractor<Features> {
@@ -79,45 +79,41 @@ class ExtensionsDataExtractor extends CfeDataExtractor<Features> {
7979

8080
@override
8181
Features computeClassValue(Id id, Class cls) {
82-
SourceLoader loader = compilerResult.kernelTargetForTesting.loader;
83-
KernelLibraryBuilder builder =
84-
loader.builders[cls.enclosingLibrary.importUri];
85-
DeclarationBuilder<TypeBuilder> libraryBuilder = builder.libraryDeclaration;
86-
ClassBuilder clsBuilder = libraryBuilder.members[cls.name];
87-
if (clsBuilder.isExtension) {
88-
Features features = new Features();
89-
features[Tags.builderName] = clsBuilder.name;
90-
if (clsBuilder.typeVariables != null) {
91-
for (TypeVariableBuilder typeVariable in clsBuilder.typeVariables) {
92-
features.addElement(Tags.builderTypeParameters,
93-
typeVariableBuilderToText(typeVariable));
94-
}
82+
ClassBuilder clsBuilder = lookupClassBuilder(compilerResult, cls);
83+
if (!clsBuilder.isExtension) {
84+
return null;
85+
}
86+
Features features = new Features();
87+
features[Tags.builderName] = clsBuilder.name;
88+
if (clsBuilder.typeVariables != null) {
89+
for (TypeVariableBuilder typeVariable in clsBuilder.typeVariables) {
90+
features.addElement(Tags.builderTypeParameters,
91+
typeVariableBuilderToText(typeVariable));
9592
}
93+
}
9694

97-
features[Tags.builderSupertype] = clsBuilder.supertype?.name;
98-
if (clsBuilder.interfaces != null) {
99-
for (TypeBuilder superinterface in clsBuilder.interfaces) {
100-
features.addElement(Tags.builderInterfaces, superinterface.name);
101-
}
95+
features[Tags.builderSupertype] = clsBuilder.supertype?.name;
96+
if (clsBuilder.interfaces != null) {
97+
for (TypeBuilder superinterface in clsBuilder.interfaces) {
98+
features.addElement(Tags.builderInterfaces, superinterface.name);
10299
}
103-
if (clsBuilder.onTypes != null) {
104-
for (TypeBuilder onType in clsBuilder.onTypes) {
105-
features.addElement(Tags.builderOnTypes, typeBuilderToText(onType));
106-
}
100+
}
101+
if (clsBuilder.onTypes != null) {
102+
for (TypeBuilder onType in clsBuilder.onTypes) {
103+
features.addElement(Tags.builderOnTypes, typeBuilderToText(onType));
107104
}
105+
}
108106

109-
features[Tags.clsName] = cls.name;
110-
for (TypeParameter typeParameter in cls.typeParameters) {
111-
features.addElement(
112-
Tags.clsTypeParameters, typeParameterToText(typeParameter));
113-
}
114-
features[Tags.clsSupertype] = cls.supertype?.classNode?.name;
115-
for (Supertype superinterface in cls.implementedTypes) {
116-
features.addElement(Tags.clsInterfaces, superinterface.classNode.name);
117-
}
118-
return features;
107+
features[Tags.clsName] = cls.name;
108+
for (TypeParameter typeParameter in cls.typeParameters) {
109+
features.addElement(
110+
Tags.clsTypeParameters, typeParameterToText(typeParameter));
119111
}
120-
return null;
112+
features[Tags.clsSupertype] = cls.supertype?.classNode?.name;
113+
for (Supertype superinterface in cls.implementedTypes) {
114+
features.addElement(Tags.clsInterfaces, superinterface.classNode.name);
115+
}
116+
return features;
121117
}
122118

123119
@override
@@ -127,6 +123,31 @@ class ExtensionsDataExtractor extends CfeDataExtractor<Features> {
127123

128124
@override
129125
Features computeMemberValue(Id id, Member member) {
130-
return null;
126+
if (member.enclosingClass == null) {
127+
return null;
128+
}
129+
ClassBuilder clsBuilder =
130+
lookupClassBuilder(compilerResult, member.enclosingClass);
131+
if (!clsBuilder.isExtension) {
132+
return null;
133+
}
134+
MemberBuilder memberBuilder = lookupMemberBuilder(compilerResult, member);
135+
Features features = new Features();
136+
features[Tags.builderName] = memberBuilder.name;
137+
if (memberBuilder is ProcedureBuilder &&
138+
memberBuilder.typeVariables != null) {
139+
for (TypeVariableBuilder typeVariable in memberBuilder.typeVariables) {
140+
features.addElement(Tags.builderTypeParameters,
141+
typeVariableBuilderToText(typeVariable));
142+
}
143+
}
144+
features[Tags.memberName] = getMemberName(member);
145+
if (member.function != null) {
146+
for (TypeParameter typeParameter in member.function.typeParameters) {
147+
features.addElement(
148+
Tags.memberTypeParameters, typeParameterToText(typeParameter));
149+
}
150+
}
151+
return features;
131152
}
132153
}

0 commit comments

Comments
 (0)