preface
When LEARNING native development, I used various frameworks for compiling automatically generated template code, such as ARouter. These frameworks actually use JavaPoet to automatically generate code. JavaPoet can compile automatically generated template code in Flutter, There is also a framework for automatically generating code at compile time, and that framework is code_Builder.
code
Code_builder internally provides a set of apis for developers to use, with which we can create any code. Suppose we now need to create a User class as follows:
class User { User.User([this._name, this._age, this._sex]); String _name; int _age; int _sex; String get name => _name; int get age => _age; get sex => _sex; set name(String value) { _name = value; } set age(int value) { _age = value; } set sex(int value) { _sex = value; } @override String toString() { return "name = $_name; sex = $_sex; age = $_age"; }}Copy the code
So how do we call the API provided by Code_Builder to create such a class? This can be done, as shown in the following code:
Void getUser() {final user = Class((classBuild) => classBuild// Generate a Class.. Name = "User"// The class name is User.. Fields.add (Field((fieldBuild) => fieldBuild// Add member variables.. Name = "_name"// The variable is private and the variable name is _name.. Type = refer("String")// Variable type is String)).. fields.add(Field((fieldBuild) => fieldBuild .. name = "_age" .. type = refer("int") )) .. fields.add(Field((fieldBuild) => fieldBuild .. name = "_sex" .. type = refer("int") )) .. Constructors. Add (Constructor(constructorBuilder){// Add constructorBuilder. Name = "User"; . / / the name of the constructor for the User constructorBuilder optionalParameters. Add (Parameter ((parameterBuilder) {/ / add a Parameter to the constructor parameterBuilder.name = "_name"; // Add a parameter to the constructor: _name parameterBuilder.toThis = true; // assign parameter _name to member variable _name})); constructorBuilder.optionalParameters.add(Parameter((parameterBuilder) { parameterBuilder.name = "_age"; parameterBuilder.toThis = true; })); constructorBuilder.optionalParameters.add(Parameter((parameterBuilder) { parameterBuilder.name = "_sex"; parameterBuilder.toThis = true; })); })).. Methods.add (Method((methodBuild)) {// Create a Method methodbuild. type = methodtype. getter; // The method is methodbuild. name = "name"; // The name of the method is name methodbuild. returns = refer("String"); Lambda = true; // The method returns type String methodbuild. lambda = true; // The method is a lambda expression methodbuild. body = const Code("_name"); })).. methods.add(Method((methodBuild){ methodBuild.type = MethodType.getter; methodBuild.name = "age"; methodBuild.returns = refer("int"); methodBuild.lambda = true; methodBuild.body = const Code("_age"); })).. methods.add(Method((methodBuild){ methodBuild.type = MethodType.getter; methodBuild.name = "sex"; methodBuild.lambda = true; methodBuild.body = const Code("_sex"); })).. Methods.add (Method((methodBuild)) {// Create a Method methodbuild. type = methodtype. setter; // Method is a method of type set methodbuild. name = "name"; Lambda = false; / / not lambda expressions methodBuild. RequiredParameters. Add (Parameter ((parameterBuild) {/ / to add parameters parameterBuild. Name = "value"; // Value parameterbuild. type = refer("String"); // arguments like String})); methodBuild.body = const Code("_name = value;" ); // method body, assign value} to _name)).. methods.add(Method((methodBuild){ methodBuild.type = MethodType.setter; methodBuild.name = "age"; methodBuild.lambda = false; methodBuild.requiredParameters.add(Parameter((parameterBuild){ parameterBuild.name = "value"; parameterBuild.type = refer("int"); })); methodBuild.body = const Code("_age = value;" ); })).. methods.add(Method((methodBuild){ methodBuild.type = MethodType.setter; methodBuild.name = "sex"; methodBuild.lambda = false; methodBuild.requiredParameters.add(Parameter((parameterBuild){ parameterBuild.name = "value"; parameterBuild.type = refer("int"); })); methodBuild.body = const Code("_sex = value;" ); })).. methods.add(Method((methodBuild) { methodBuild.name = "toString"; methodBuild.lambda = false; methodBuild.returns = refer("String"); MethodBuild. Annotations. The add (TypeReference ((build) {/ / add annotations to method build. The symbol = "override"; // The annotation type is @override, which means this is an overridden method})); methodBuild.body = const Code("return \"name = \$_name; sex = \$_sex; age = \$_age\"; "); }))); final emitter = DartEmitter(); print(DartFormatter().format('${user.accept(emitter)}')); } void main() { getUser(); }Copy the code
Of course, code_Builder alone is not enough to generate a class that can be used in a real project, because it just creates code templates that need to be written to a DART file in the project directory, using source_gen. Source_gen can parse annotations at compile time, then generate code templates with code_Builder that are eventually written to one of the DART files in the project directory.
QQ communication group of
Group number: 770892444