blob: 48f920818b60ded4d28779978839b71dae6a6a9f [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/snippets/snippet.dart';
import 'package:analysis_server/src/services/snippets/snippet_producer.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
/// Produces a [Snippet] that creates a Flutter StatefulWidget with a
/// AnimationController and related State class.
class FlutterStatefulWidgetWithAnimationController
extends FlutterSnippetProducer with FlutterWidgetSnippetProducerMixin {
static const prefix = 'stanim';
static const label = 'Flutter Widget with AnimationController';
late ClassElement? classStatefulWidget;
late ClassElement? classState;
@override
late ClassElement? classBuildContext;
@override
late ClassElement? classKey;
late ClassElement? classAnimationController;
late ClassElement? classSingleTickerProviderStateMixin;
FlutterStatefulWidgetWithAnimationController(super.request);
@override
Future<Snippet> compute() async {
final builder = ChangeBuilder(session: request.analysisSession);
// Checked by isValid().
final classStatefulWidget = this.classStatefulWidget!;
final classState = this.classState!;
final classAnimationController = this.classAnimationController!;
final classSingleTickerProviderStateMixin =
this.classSingleTickerProviderStateMixin!;
await builder.addDartFileEdit(request.filePath, (builder) {
builder.addReplacement(request.replacementRange, (builder) {
// Write the StatefulWidget class
builder.writeClassDeclaration(
widgetClassName,
nameGroupName: 'name',
superclass: getType(classStatefulWidget),
membersWriter: () {
writeWidgetConstructor(builder);
builder.writeln();
builder.writeln();
writeCreateStateMethod(builder);
},
);
builder.writeln();
builder.writeln();
// Write the State class.
builder.write('class _');
builder.addSimpleLinkedEdit('name', widgetClassName);
builder.write('State extends ');
builder.writeReference(classState);
builder.write('<');
builder.addSimpleLinkedEdit('name', widgetClassName);
builder.writeln('>');
builder.write(' with ');
builder.writeReference(classSingleTickerProviderStateMixin);
builder.writeln(' {');
builder.write(' late ');
builder.writeReference(classAnimationController);
builder.writeln(' _controller;');
builder.writeln();
{
// Add the initState method.
builder.writeln(' @override');
builder.write(' ');
builder.writeFunctionDeclaration(
'initState',
returnType: VoidTypeImpl.instance,
bodyWriter: () {
builder.writeln('{');
builder.writeln(' super.initState();');
builder.write(' _controller = ');
builder.writeReference(classAnimationController);
builder.writeln('(vsync: this);');
builder.writeln(' }');
},
);
}
builder.writeln();
{
// Add the dispose method.
builder.writeln(' @override');
builder.write(' ');
builder.writeFunctionDeclaration(
'dispose',
returnType: VoidTypeImpl.instance,
bodyWriter: () {
builder.writeln('{');
builder.writeln(' _controller.dispose();');
builder.writeln(' super.dispose();');
builder.writeln(' }');
},
);
}
builder.writeln();
{
writeBuildMethod(builder);
}
builder.write('}');
});
});
return Snippet(
prefix,
label,
'Insert a Flutter StatefulWidget with an AnimationController.',
builder.sourceChange,
);
}
@override
Future<bool> isValid() async {
if (!await super.isValid()) {
return false;
}
if ((classStatefulWidget = await getClass('StatefulWidget')) == null ||
(classState = await getClass('State')) == null ||
(classBuildContext = await getClass('BuildContext')) == null ||
(classKey = await getClass('Key')) == null ||
(classAnimationController = await getClass('AnimationController')) ==
null ||
(classSingleTickerProviderStateMixin =
await getClass('SingleTickerProviderStateMixin')) ==
null) {
return false;
}
return true;
}
}