extractRepeatedWidgetsToComponent method
void
extractRepeatedWidgetsToComponent({
- required String componentName,
- required List<
BrownfieldPatternOccurrence> occurrences,
Extracts repeated existing widgets into a shared project component and replaces each occurrence with a component instance.
Use this for reuse-first refactors once repeated patterns are known.
Implementation
void extractRepeatedWidgetsToComponent({
required String componentName,
required List<BrownfieldPatternOccurrence> occurrences,
}) {
if (occurrences.length < 2) {
throw ArgumentError(
'extractRepeatedWidgetsToComponent(...) requires at least two occurrences.',
);
}
raw((project) {
final sourceOccurrence = occurrences.first;
final sourceWidgetClass = _findWidgetClassByName(
project,
sourceOccurrence.widgetClassName,
);
final sourceSnapshot = _snapshotForWidgetClass(
project,
sourceWidgetClass,
);
final sourceRef =
sourceSnapshot.findByName(sourceOccurrence.widgetName).expectOne();
final sourceNode = findByKey(sourceWidgetClass.node, sourceRef.key);
if (sourceNode == null) {
throw StateError(
'Widget "${sourceOccurrence.widgetName}" was not found on '
'"${sourceOccurrence.widgetClassName}".',
);
}
if (project_helpers.findComponent(project, name: componentName) == null) {
project_helpers.addComponent(
project,
name: componentName,
description: 'DSL extracted component $componentName',
body: UI.container(name: componentName),
);
}
final componentBody =
sourceNode.type == FFWidgetType.Container
? sourceNode.deepCopy()
: UI.container(child: sourceNode.deepCopy(), name: componentName);
project_helpers.updateComponentBody(
project,
name: componentName,
body: componentBody,
);
final componentClass =
project_helpers.findComponent(project, name: componentName)!;
for (final occurrence in occurrences) {
final widgetClass = _findWidgetClassByName(
project,
occurrence.widgetClassName,
);
final snapshot = _snapshotForWidgetClass(project, widgetClass);
final targetRef =
snapshot.findByName(occurrence.widgetName).expectOne();
final replacement = UI.component(
componentClass,
name: occurrence.widgetName,
);
if (!replaceByKey(widgetClass.node, targetRef.key, replacement)) {
throw StateError(
'Failed to replace repeated widget "${occurrence.widgetName}" on '
'"${occurrence.widgetClassName}".',
);
}
}
});
}