Skip to content

Commit 44f99e1

Browse files
scheglovCommit Queue
authored and
Commit Queue
committed
Macro. Merge partial macro augmentations into one after linking.
Declarations generated to macros now go into augmentations. So, we can re-enable tests for them, updated. Change-Id: I119059253b3b147e661ea74955ec84afb8def34e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330243 Commit-Queue: Konstantin Shcheglov <[email protected]> Reviewed-by: Phil Quitslund <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent c8f8ae8 commit 44f99e1

File tree

11 files changed

+629
-309
lines changed

11 files changed

+629
-309
lines changed

pkg/analyzer/lib/src/dart/analysis/file_state.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,7 +1802,7 @@ class LibraryFileKind extends LibraryOrAugmentationFileKind {
18021802
/// results in separate augmentation libraries with names `foo.macroX.dart`.
18031803
/// For the merged augmentation we pass `null` here, so a single
18041804
/// `foo.macro.dart` is created.
1805-
AugmentationImportWithFile? addMacroAugmentation(
1805+
AugmentationImportWithFile addMacroAugmentation(
18061806
String code, {
18071807
required bool addLibraryAugmentDirective,
18081808
required int? partialIndex,
@@ -1839,9 +1839,7 @@ $code
18391839
final macroUri = uriCache.resolveRelative(file.uri, macroRelativeUri);
18401840

18411841
final macroFileResolution = file._fsState.getFileForUri(macroUri);
1842-
if (macroFileResolution is! UriResolutionFile) {
1843-
return null;
1844-
}
1842+
macroFileResolution as UriResolutionFile;
18451843
final macroFile = macroFileResolution.file;
18461844

18471845
final import = AugmentationImportWithFile(

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4173,9 +4173,8 @@ class LibraryElementImpl extends LibraryOrAugmentationElementImpl
41734173
/// See [fieldNameNonPromotabilityInfo].
41744174
Map<String, FieldNameNonPromotabilityInfo>? _fieldNameNonPromotabilityInfo;
41754175

4176-
/// All augmentations of this library, in the depth-first pre-order order.
4177-
late final List<LibraryAugmentationElementImpl> augmentations =
4178-
_computeAugmentations();
4176+
/// The cache for [augmentations].
4177+
List<LibraryAugmentationElementImpl>? _augmentations;
41794178

41804179
/// Initialize a newly created library element in the given [context] to have
41814180
/// the given [name] and [offset].
@@ -4193,6 +4192,17 @@ class LibraryElementImpl extends LibraryOrAugmentationElementImpl
41934192
return super.augmentationImports;
41944193
}
41954194

4195+
@override
4196+
set augmentationImports(List<AugmentationImportElementImpl> imports) {
4197+
super.augmentationImports = imports;
4198+
_augmentations = null;
4199+
}
4200+
4201+
/// All augmentations of this library, in the depth-first pre-order order.
4202+
List<LibraryAugmentationElementImpl> get augmentations {
4203+
return _augmentations ??= _computeAugmentations();
4204+
}
4205+
41964206
@override
41974207
List<Element> get children => [
41984208
...super.children,

pkg/analyzer/lib/src/summary2/library_builder.dart

Lines changed: 93 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
import 'package:_fe_analyzer_shared/src/field_promotability.dart';
66
import 'package:_fe_analyzer_shared/src/macros/executor.dart' as macro;
77
import 'package:analyzer/dart/analysis/features.dart';
8-
import 'package:analyzer/dart/analysis/utilities.dart';
98
import 'package:analyzer/dart/element/element.dart';
10-
import 'package:analyzer/dart/element/visitor.dart';
119
import 'package:analyzer/src/dart/analysis/file_state.dart' as file_state;
1210
import 'package:analyzer/src/dart/analysis/file_state.dart' hide DirectiveUri;
1311
import 'package:analyzer/src/dart/analysis/unlinked_data.dart';
@@ -17,14 +15,14 @@ import 'package:analyzer/src/dart/element/element.dart';
1715
import 'package:analyzer/src/dart/element/field_name_non_promotability_info.dart'
1816
as element_model;
1917
import 'package:analyzer/src/dart/resolver/scope.dart';
20-
import 'package:analyzer/src/generated/source.dart';
2118
import 'package:analyzer/src/summary2/combinator.dart';
2219
import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
2320
import 'package:analyzer/src/summary2/default_value_resolver.dart';
2421
import 'package:analyzer/src/summary2/element_builder.dart';
2522
import 'package:analyzer/src/summary2/export.dart';
2623
import 'package:analyzer/src/summary2/link.dart';
2724
import 'package:analyzer/src/summary2/macro_application.dart';
25+
import 'package:analyzer/src/summary2/macro_merge.dart';
2826
import 'package:analyzer/src/summary2/metadata_resolver.dart';
2927
import 'package:analyzer/src/summary2/reference.dart';
3028
import 'package:analyzer/src/summary2/reference_resolver.dart';
@@ -193,10 +191,6 @@ class LibraryBuilder {
193191
required this.units,
194192
});
195193

196-
SourceFactory get _sourceFactory {
197-
return linker.elementFactory.analysisContext.sourceFactory;
198-
}
199-
200194
void addExporters() {
201195
final containers = [element, ...element.augmentations];
202196
for (var containerIndex = 0;
@@ -374,79 +368,44 @@ class LibraryBuilder {
374368
},
375369
);
376370

377-
final augmentationLibrary = await macroApplier.executeDeclarationsPhase();
378-
if (augmentationLibrary == null) {
371+
final macroResults = await performance.runAsync(
372+
'executeDeclarationsPhase',
373+
(performance) async {
374+
return await macroApplier.executeDeclarationsPhase();
375+
},
376+
);
377+
if (macroResults.isEmpty) {
379378
return;
380379
}
380+
_macroResults.add(macroResults);
381381

382-
final parseResult = parseString(
383-
content: augmentationLibrary,
384-
featureSet: element.featureSet,
385-
throwIfDiagnostics: false,
382+
final augmentationCode = macroApplier.buildAugmentationLibraryCode(
383+
macroResults,
386384
);
387-
final unitNode = parseResult.unit as ast.CompilationUnitImpl;
385+
if (augmentationCode == null) {
386+
return;
387+
}
388388

389-
// We don't actually keep this unit, but we need it for now as a container.
390-
// Eventually we will use actual augmentation libraries.
391-
final unitUri = uri.resolve('_macro_declarations.dart');
392-
final unitReference = reference.getChild('@unit').getChild('$unitUri');
393-
final unitElement = CompilationUnitElementImpl(
394-
source: _sourceFactory.forUri2(unitUri)!,
395-
librarySource: element.source,
396-
lineInfo: parseResult.lineInfo,
397-
)
398-
..enclosingElement = element
399-
..isSynthetic = true
400-
..uri = unitUri.toString();
401-
402-
final elementBuilder = ElementBuilder(
403-
libraryBuilder: this,
404-
container: element,
405-
unitReference: unitReference,
406-
unitElement: unitElement,
389+
final importState = kind.addMacroAugmentation(
390+
augmentationCode,
391+
addLibraryAugmentDirective: true,
392+
partialIndex: _macroResults.length,
407393
);
408-
elementBuilder.buildDeclarationElements(unitNode);
409394

410-
// We move elements, so they don't have real offsets.
411-
unitElement.accept(_FlushElementOffsets());
395+
final augmentation = _addMacroAugmentation(importState);
396+
397+
final macroLinkingUnit = units.last;
398+
ElementBuilder(
399+
libraryBuilder: this,
400+
container: macroLinkingUnit.container,
401+
unitReference: macroLinkingUnit.reference,
402+
unitElement: macroLinkingUnit.element,
403+
).buildDeclarationElements(macroLinkingUnit.node);
412404

413405
final nodesToBuildType = NodesToBuildType();
414-
final resolver = ReferenceResolver(linker, nodesToBuildType, element);
415-
unitNode.accept(resolver);
406+
final resolver = ReferenceResolver(linker, nodesToBuildType, augmentation);
407+
macroLinkingUnit.node.accept(resolver);
416408
TypesBuilder(linker).build(nodesToBuildType);
417-
418-
// Transplant built elements as if the augmentation was applied.
419-
final augmentedUnitElement = element.definingCompilationUnit;
420-
for (final augmentation in unitElement.classes) {
421-
// TODO(scheglov) if augmentation
422-
final augmented = element.getClass(augmentation.name);
423-
if (augmented is ClassElementImpl) {
424-
augmented.accessors = [
425-
...augmented.accessors,
426-
...augmentation.accessors,
427-
];
428-
augmented.constructors = [
429-
...augmented.constructors,
430-
...augmentation.constructors.where((e) => !e.isSynthetic),
431-
];
432-
augmented.fields = [
433-
...augmented.fields,
434-
...augmentation.fields,
435-
];
436-
augmented.methods = [
437-
...augmented.methods,
438-
...augmentation.methods,
439-
];
440-
}
441-
}
442-
augmentedUnitElement.accessors = [
443-
...augmentedUnitElement.accessors,
444-
...unitElement.accessors,
445-
];
446-
augmentedUnitElement.topLevelVariables = [
447-
...augmentedUnitElement.topLevelVariables,
448-
...unitElement.topLevelVariables,
449-
];
450409
}
451410

452411
Future<void> executeMacroTypesPhase({
@@ -464,16 +423,6 @@ class LibraryBuilder {
464423
performance: performance,
465424
);
466425
}
467-
468-
// TODO(scheglov) do after all phases
469-
await performance.runAsync(
470-
'mergeMacroAugmentations',
471-
(performance) async {
472-
await mergeMacroAugmentations(
473-
performance: performance,
474-
);
475-
},
476-
);
477426
}
478427

479428
AugmentedInstanceDeclarationBuilder? getAugmentedBuilder(String name) {
@@ -499,29 +448,75 @@ class LibraryBuilder {
499448

500449
kind.disposeMacroAugmentations();
501450

451+
// Remove import for partial macro augmentations.
452+
element.augmentationImports = element.augmentationImports
453+
.take(element.augmentationImports.length - _macroResults.length)
454+
.toFixedList();
455+
456+
// Remove units with partial macro augmentations.
457+
final partialUnits = units.sublist(units.length - _macroResults.length);
458+
units.length -= _macroResults.length;
459+
502460
final importState = kind.addMacroAugmentation(
503461
augmentationCode,
504462
addLibraryAugmentDirective: true,
505463
partialIndex: null,
506464
);
507-
if (importState == null) {
508-
return;
509-
}
465+
final importedAugmentation = importState.importedAugmentation!;
466+
final importedFile = importedAugmentation.file;
510467

511-
element.augmentationImports = element.augmentationImports
512-
.take(element.augmentationImports.length - _macroResults.length)
513-
.toFixedList();
468+
final unitNode = importedFile.parse();
469+
final unitElement = CompilationUnitElementImpl(
470+
source: importedFile.source,
471+
librarySource: importedFile.source,
472+
lineInfo: unitNode.lineInfo,
473+
);
474+
unitElement.setCodeRange(0, unitNode.length);
514475

515-
_addMacroAugmentation(importState);
476+
final unitReference =
477+
reference.getChild('@augmentation').getChild(importedFile.uriStr);
478+
_bindReference(unitReference, unitElement);
516479

517-
// TODO(scheglov) Apply existing elements from partial augmentations.
518-
final macroLinkingUnit = units.last;
519-
ElementBuilder(
520-
libraryBuilder: this,
521-
container: macroLinkingUnit.container,
522-
unitReference: macroLinkingUnit.reference,
523-
unitElement: macroLinkingUnit.element,
524-
).buildDeclarationElements(macroLinkingUnit.node);
480+
final augmentation = LibraryAugmentationElementImpl(
481+
augmentationTarget: element,
482+
nameOffset: importedAugmentation.unlinked.libraryKeywordOffset,
483+
);
484+
augmentation.definingCompilationUnit = unitElement;
485+
augmentation.reference = unitReference;
486+
augmentation.macroGenerated = MacroGeneratedAugmentationLibrary(
487+
code: importedFile.content,
488+
informativeBytes: importedFile.unlinked2.informativeBytes,
489+
);
490+
491+
_buildDirectives(
492+
kind: importedAugmentation,
493+
container: augmentation,
494+
);
495+
496+
MacroElementsMerger(
497+
partialUnits: partialUnits,
498+
unitReference: unitReference,
499+
unitNode: unitNode,
500+
unitElement: unitElement,
501+
).perform();
502+
503+
final importUri = DirectiveUriWithAugmentationImpl(
504+
relativeUriString: importState.uri.relativeUriStr,
505+
relativeUri: importState.uri.relativeUri,
506+
source: importedFile.source,
507+
augmentation: augmentation,
508+
);
509+
510+
final import = AugmentationImportElementImpl(
511+
importKeywordOffset: importState.unlinked.importKeywordOffset,
512+
uri: importUri,
513+
);
514+
import.isSynthetic = true;
515+
516+
element.augmentationImports = [
517+
...element.augmentationImports,
518+
import,
519+
].toFixedList();
525520
}
526521

527522
void putAugmentedBuilder(
@@ -608,7 +603,7 @@ class LibraryBuilder {
608603
_augmentationTargets[name] = augmentation;
609604
}
610605

611-
LibraryAugmentationElementImpl? _addMacroAugmentation(
606+
LibraryAugmentationElementImpl _addMacroAugmentation(
612607
AugmentationImportWithFile state,
613608
) {
614609
final import = _buildAugmentationImport(element, state);
@@ -618,8 +613,8 @@ class LibraryBuilder {
618613
import,
619614
].toFixedList();
620615

621-
final augmentation = import.importedAugmentation;
622-
augmentation!.macroGenerated = MacroGeneratedAugmentationLibrary(
616+
final augmentation = import.importedAugmentation!;
617+
augmentation.macroGenerated = MacroGeneratedAugmentationLibrary(
623618
code: state.importedFile.content,
624619
informativeBytes: state.importedFile.unlinked2.informativeBytes,
625620
);
@@ -997,9 +992,6 @@ class LibraryBuilder {
997992
addLibraryAugmentDirective: true,
998993
partialIndex: _macroResults.length,
999994
);
1000-
if (importState == null) {
1001-
return null;
1002-
}
1003995

1004996
final augmentation = _addMacroAugmentation(importState);
1005997

@@ -1278,19 +1270,6 @@ class _FieldPromotability extends FieldPromotability<InterfaceElement,
12781270
}
12791271
}
12801272

1281-
class _FlushElementOffsets extends GeneralizingElementVisitor<void> {
1282-
@override
1283-
void visitElement(covariant ElementImpl element) {
1284-
element.isTempAugmentation = true;
1285-
element.nameOffset = -1;
1286-
if (element is ConstructorElementImpl) {
1287-
element.periodOffset = null;
1288-
element.nameEnd = null;
1289-
}
1290-
super.visitElement(element);
1291-
}
1292-
}
1293-
12941273
extension<T> on T? {
12951274
R? mapOrNull<R>(R Function(T) mapper) {
12961275
final self = this;

pkg/analyzer/lib/src/summary2/link.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ class Linker {
148148
_collectMixinSuperInvokedNames();
149149
_buildElementNameUnions();
150150
_detachNodes();
151+
152+
await performance.runAsync(
153+
'mergeMacroAugmentations',
154+
(performance) async {
155+
await _mergeMacroAugmentations(
156+
performance: performance,
157+
);
158+
},
159+
);
151160
}
152161

153162
void _collectMixinSuperInvokedNames() {
@@ -269,6 +278,16 @@ class Linker {
269278
}
270279
}
271280

281+
Future<void> _mergeMacroAugmentations({
282+
required OperationPerformanceImpl performance,
283+
}) async {
284+
for (final library in builders.values) {
285+
await library.mergeMacroAugmentations(
286+
performance: performance,
287+
);
288+
}
289+
}
290+
272291
void _performTopLevelInference() {
273292
TopLevelInference(this).infer();
274293
}

0 commit comments

Comments
 (0)