Skip to content

Commit e3fe4c3

Browse files
johnniwintherCommit Queue
authored andcommitted
[cfe] Separate ExtensionScope from LookupScope
This fully separates ExtensionScope from LookupScope and moves the collection of local extensions from NameSpace to a new Extensions interface. Change-Id: I3960194445adfd87eccbc6df0fec96c3cb031cbb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/453202 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]>
1 parent 4d7b159 commit e3fe4c3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+520
-243
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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+
import '../builder/compilation_unit.dart';
6+
import '../builder/declaration_builders.dart';
7+
import '../builder/prefix_builder.dart';
8+
import 'name_space.dart';
9+
10+
/// Interface for accessing extensions available in the current scope.
11+
///
12+
/// This available extensions come from the current library or from extensions
13+
/// imported into the current scope, possibly through prefixes, and through
14+
/// the extension scope of parent parts.
15+
abstract class ExtensionScope {
16+
void forEachExtension(void Function(ExtensionBuilder) f);
17+
}
18+
19+
/// Interface for accessing extensions directly declared or imported.
20+
///
21+
/// This is used as a base for computing the nested extension scope in
22+
/// [ExtensionScope].
23+
abstract class Extensions {
24+
void forEachLocalExtension(void Function(ExtensionBuilder member) f);
25+
}
26+
27+
class ExtensionsBuilder implements Extensions {
28+
Set<ExtensionBuilder>? _extensions;
29+
30+
/// Adds [builder] to the extensions in this name space.
31+
void addExtension(ExtensionBuilder builder) {
32+
(_extensions ??= {}).add(builder);
33+
}
34+
35+
@override
36+
void forEachLocalExtension(void Function(ExtensionBuilder member) f) {
37+
_extensions?.forEach(f);
38+
}
39+
}
40+
41+
final class LibraryExtensions implements Extensions {
42+
final Set<ExtensionBuilder>? _extensions;
43+
44+
LibraryExtensions({required Set<ExtensionBuilder> extensions})
45+
: _extensions = extensions;
46+
47+
@override
48+
void forEachLocalExtension(void Function(ExtensionBuilder member) f) {
49+
_extensions?.forEach(f);
50+
}
51+
}
52+
53+
abstract class BaseExtensionScope implements ExtensionScope {
54+
Extensions get _localExtensions;
55+
56+
ExtensionScope? get _parent;
57+
58+
@override
59+
void forEachExtension(void Function(ExtensionBuilder) f) {
60+
_localExtensions.forEachLocalExtension(f);
61+
_parent?.forEachExtension(f);
62+
}
63+
64+
@override
65+
String toString() => "$runtimeType()";
66+
}
67+
68+
/// Implementation of [ExtensionScope] that includes extensions from a given
69+
/// [Extensions] object.
70+
///
71+
/// This is used for expression compilation to give access to extensions
72+
/// declared in the library that the expression should be resolved in.
73+
// Coverage-ignore(suite): Not run.
74+
class ParentLibraryExtensionScope extends BaseExtensionScope {
75+
@override
76+
final Extensions _localExtensions;
77+
78+
@override
79+
final ExtensionScope? _parent;
80+
81+
ParentLibraryExtensionScope(this._localExtensions, {ExtensionScope? parent})
82+
: _parent = parent;
83+
}
84+
85+
class CompilationUnitImportExtensionScope extends BaseExtensionScope {
86+
final SourceCompilationUnit _compilationUnit;
87+
final Extensions _importNameSpace;
88+
89+
CompilationUnitImportExtensionScope(
90+
this._compilationUnit,
91+
this._importNameSpace,
92+
);
93+
94+
@override
95+
Extensions get _localExtensions => _importNameSpace;
96+
97+
@override
98+
ExtensionScope? get _parent =>
99+
_compilationUnit.parentCompilationUnit?.prefixExtensionScope ??
100+
_compilationUnit.libraryBuilder.parentExtensionScope;
101+
}
102+
103+
class CompilationUnitExtensionScope extends BaseExtensionScope {
104+
final SourceCompilationUnit _compilationUnit;
105+
106+
@override
107+
final ExtensionScope? _parent;
108+
109+
CompilationUnitExtensionScope(this._compilationUnit, {ExtensionScope? parent})
110+
: _parent = parent;
111+
112+
@override
113+
Extensions get _localExtensions =>
114+
_compilationUnit.libraryBuilder.libraryExtensions;
115+
116+
/// Set of extension declarations in scope. This is computed lazily in
117+
/// [forEachExtension].
118+
Set<ExtensionBuilder>? _extensions;
119+
120+
@override
121+
void forEachExtension(void Function(ExtensionBuilder) f) {
122+
if (_extensions == null) {
123+
Set<ExtensionBuilder> extensions = _extensions = <ExtensionBuilder>{};
124+
_parent?.forEachExtension(extensions.add);
125+
_localExtensions.forEachLocalExtension(extensions.add);
126+
}
127+
_extensions!.forEach(f);
128+
}
129+
}
130+
131+
class CompilationUnitPrefixExtensionScope implements ExtensionScope {
132+
final ComputedNameSpace _prefixNameSpace;
133+
134+
final ExtensionScope _parent;
135+
136+
CompilationUnitPrefixExtensionScope(
137+
this._prefixNameSpace, {
138+
required ExtensionScope parent,
139+
}) : _parent = parent;
140+
141+
/// Set of extension declarations in scope. This is computed lazily in
142+
/// [forEachExtension].
143+
Set<ExtensionBuilder>? _extensions;
144+
145+
@override
146+
void forEachExtension(void Function(ExtensionBuilder) f) {
147+
if (_extensions == null) {
148+
Set<ExtensionBuilder> extensions = _extensions = {};
149+
Iterator<PrefixBuilder> iterator = _prefixNameSpace.filteredIterator();
150+
while (iterator.moveNext()) {
151+
iterator.current.forEachExtension((e) {
152+
extensions.add(e);
153+
});
154+
}
155+
_parent.forEachExtension(extensions.add);
156+
}
157+
_extensions!.forEach(f);
158+
}
159+
160+
@override
161+
String toString() => "$runtimeType()";
162+
}

pkg/front_end/lib/src/base/incremental_compiler.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1986,7 +1986,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
19861986
// If the name looks like an unnamed extension, try to find if we
19871987
// can find such a builder.
19881988
ExtensionBuilder? foundExtensionBuilder;
1989-
libraryBuilder.libraryNameSpace.forEachLocalExtension((
1989+
libraryBuilder.libraryExtensions.forEachLocalExtension((
19901990
ExtensionBuilder extension,
19911991
) {
19921992
if (extension.name == beforeDot) {
@@ -2147,6 +2147,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
21472147
loader: lastGoodKernelTarget.loader,
21482148
resolveInLibrary: libraryBuilder,
21492149
parentScope: debugCompilationUnit.compilationUnitScope,
2150+
parentExtensionScope: debugCompilationUnit.extensionScope,
21502151
isUnsupported: libraryBuilder.isUnsupported,
21512152
forAugmentationLibrary: false,
21522153
forPatchLibrary: false,

pkg/front_end/lib/src/base/local_scope.dart

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,6 @@ mixin LocalScopeMixin implements LocalScope {
144144
}
145145

146146
void _recordUse(String name, int charOffset) {}
147-
148-
@override
149-
void forEachExtension(void Function(ExtensionBuilder) f) {
150-
_parent?.forEachExtension(f);
151-
}
152147
}
153148

154149
final class LocalScopeImpl extends BaseLocalScope
@@ -231,12 +226,6 @@ final class LocalTypeParameterScope extends BaseLocalScope
231226
// Coverage-ignore(suite): Not run.
232227
VariableBuilder? lookupLocalVariable(String name) => null;
233228

234-
@override
235-
// Coverage-ignore(suite): Not run.
236-
void forEachExtension(void Function(ExtensionBuilder) f) {
237-
_parent?.forEachExtension(f);
238-
}
239-
240229
@override
241230
String toString() => "$runtimeType(${kind}, ${_local?.keys})";
242231
}
@@ -304,11 +293,6 @@ final class EnclosingLocalScope extends BaseLocalScope
304293
// Coverage-ignore(suite): Not run.
305294
VariableBuilder? lookupLocalVariable(String name) => null;
306295

307-
@override
308-
void forEachExtension(void Function(ExtensionBuilder) f) {
309-
_scope.forEachExtension(f);
310-
}
311-
312296
@override
313297
String toString() => "$runtimeType(${kind},$_scope)";
314298
}

pkg/front_end/lib/src/base/name_space.dart

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

55
import '../builder/builder.dart';
6-
import '../builder/declaration_builders.dart';
76
import '../builder/library_builder.dart';
87
import 'lookup_result.dart';
98
import 'scope.dart';
@@ -13,8 +12,6 @@ abstract class NameSpace {
1312
/// Returns the [LookupResult] for the [Builder]s of the given [name] in the
1413
/// name space.
1514
LookupResult? lookup(String name);
16-
17-
void forEachLocalExtension(void Function(ExtensionBuilder member) f);
1815
}
1916

2017
abstract class MutableNameSpace implements NameSpace {
@@ -33,9 +30,6 @@ abstract class ComputedMutableNameSpace
3330
implements MutableNameSpace, ComputedNameSpace {
3431
factory ComputedMutableNameSpace() = ComputedMutableNameSpaceImpl._;
3532

36-
/// Adds [builder] to the extensions in this name space.
37-
void addExtension(ExtensionBuilder builder);
38-
3933
void replaceLocalMember(
4034
String name,
4135
NamedBuilder member, {
@@ -53,9 +47,6 @@ abstract class DeclarationNameSpace implements NameSpace {
5347
}) : _content = content,
5448
_constructors = constructors;
5549

56-
@override
57-
void forEachLocalExtension(void Function(ExtensionBuilder member) f) {}
58-
5950
@override
6051
MemberLookupResult? lookup(String name) => _content[name];
6152

@@ -64,7 +55,6 @@ abstract class DeclarationNameSpace implements NameSpace {
6455

6556
base class ComputedMutableNameSpaceImpl implements ComputedMutableNameSpace {
6657
Map<String, LookupResult>? _content;
67-
Set<ExtensionBuilder>? _extensions;
6858

6959
ComputedMutableNameSpaceImpl._();
7060

@@ -155,42 +145,23 @@ base class ComputedMutableNameSpaceImpl implements ComputedMutableNameSpace {
155145
}
156146
}
157147

158-
@override
159-
void addExtension(ExtensionBuilder builder) {
160-
(_extensions ??= {}).add(builder);
161-
}
162-
163148
@override
164149
Iterator<T> filteredIterator<T extends NamedBuilder>() {
165150
return new FilteredIterator<T>(
166-
new LookupResultIterator(
167-
_content?.values.iterator,
168-
_extensions
169-
// Coverage-ignore(suite): Not run.
170-
?.iterator,
171-
),
151+
new LookupResultIterator(_content?.values.iterator),
172152
includeDuplicates: false,
173153
);
174154
}
175155

176-
@override
177-
void forEachLocalExtension(void Function(ExtensionBuilder member) f) {
178-
_extensions?.forEach(f);
179-
}
180-
181156
@override
182157
LookupResult? lookup(String name) => _content?[name];
183158
}
184159

185160
final class LibraryNameSpace implements NameSpace {
186161
final Map<String, LookupResult> _content;
187-
final Set<ExtensionBuilder>? _extensions;
188162

189-
LibraryNameSpace({
190-
required Map<String, LookupResult> content,
191-
required Set<ExtensionBuilder> extensions,
192-
}) : _content = content,
193-
_extensions = extensions;
163+
LibraryNameSpace({required Map<String, LookupResult> content})
164+
: _content = content;
194165

195166
void addLocalMember(String name, LookupResult member) {
196167
assert(
@@ -200,11 +171,6 @@ final class LibraryNameSpace implements NameSpace {
200171
_content[name] = member;
201172
}
202173

203-
@override
204-
void forEachLocalExtension(void Function(ExtensionBuilder member) f) {
205-
_extensions?.forEach(f);
206-
}
207-
208174
@override
209175
LookupResult? lookup(String name) => _content[name];
210176
}
@@ -394,45 +360,5 @@ final class DillExportNameSpace extends ComputedMutableNameSpaceImpl {
394360
}
395361
}
396362
}
397-
398-
if (_extensions != null) {
399-
// Coverage-ignore-block(suite): Not run.
400-
bool needsPatching = false;
401-
for (ExtensionBuilder extensionBuilder in _extensions!) {
402-
if (replacementNameSpaceMap.containsKey(
403-
extensionBuilder.libraryBuilder,
404-
)) {
405-
needsPatching = true;
406-
break;
407-
}
408-
}
409-
if (needsPatching) {
410-
Set<ExtensionBuilder> extensionsReplacement =
411-
new Set<ExtensionBuilder>();
412-
for (ExtensionBuilder extensionBuilder in _extensions!) {
413-
if (replacementNameSpaceMap.containsKey(
414-
extensionBuilder.libraryBuilder,
415-
)) {
416-
assert(
417-
replacementNameSpaceMap[extensionBuilder.libraryBuilder]!
418-
.lookup(extensionBuilder.name)!
419-
.getable !=
420-
null,
421-
);
422-
extensionsReplacement.add(
423-
replacementNameSpaceMap[extensionBuilder.libraryBuilder]!
424-
.lookup(extensionBuilder.name)!
425-
.getable
426-
as ExtensionBuilder,
427-
);
428-
break;
429-
} else {
430-
extensionsReplacement.add(extensionBuilder);
431-
}
432-
}
433-
_extensions!.clear();
434-
extensionsReplacement.addAll(extensionsReplacement);
435-
}
436-
}
437363
}
438364
}

0 commit comments

Comments
 (0)