前言
之前學(xué)習(xí)原生開發(fā)的時(shí)候使用過各種編譯自動(dòng)生成模板代碼的框架桶雀,例如ARouter,這些框架其實(shí)是借助了JavaPoet 這個(gè)框架來自動(dòng)生成代碼的儒喊,JavaPoet 可以在編譯自動(dòng)生成模板代碼祠肥,在flutter纸镊,也有這樣的框架可以在編譯時(shí)自動(dòng)生成代碼鸵闪,這個(gè)框架就是 code_builder檐晕。
代碼
code_builder內(nèi)部提供了一系列的api給開發(fā)人員使用,憑借這些api蚌讼,我們可以創(chuàng)建任何代碼棉姐。假如我們現(xiàn)在需要?jiǎng)?chuàng)建一個(gè)User類屠列,代碼如下:
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";
}
}
那我們?cè)撊绾握{(diào)用code_builder提供的api去創(chuàng)建這樣一個(gè)類呢?可以這么做伞矩,如下代碼所示:
void getUser() {
final user = Class((classBuild) => classBuild//生成一個(gè)類
..name = "User"http://這個(gè)類的名字叫User
..fields.add(Field((fieldBuild) => fieldBuild//添加成員變量
..name = "_name"http://該變量為私有變量,變量名為_name
..type = refer("String")//變量類型為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){//添加構(gòu)造函數(shù)
constructorBuilder.name = "User";//構(gòu)造函數(shù)的名字為User
constructorBuilder.optionalParameters.add(Parameter((parameterBuilder) {//給構(gòu)造函數(shù)添加一個(gè)參數(shù)
parameterBuilder.name = "_name";// 給構(gòu)造函數(shù)添加一個(gè)參數(shù)_name
parameterBuilder.toThis = true;// 將參數(shù)_name賦值給成員變量_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) {// 創(chuàng)建一個(gè)方法
methodBuild.type = MethodType.getter;// 方法是get類型的方法
methodBuild.name = "name";// 方法名是name
methodBuild.returns = refer("String");//方法返回類型是String
methodBuild.lambda = true;// 方法是一個(gè)lambda表達(dá)式
methodBuild.body = const Code("_name");// 創(chuàng)建方法體內(nèi)的代碼
}))
..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) { //創(chuàng)建一個(gè)方法
methodBuild.type = MethodType.setter; // 方法是set類型的方法
methodBuild.name = "name"; // 方法名是name
methodBuild.lambda = false; // 不是lambda表達(dá)式
methodBuild.requiredParameters.add(Parameter((parameterBuild) { // 給方法添加參數(shù)
parameterBuild.name = "value"; // 參數(shù)名是value
parameterBuild.type = refer("String"); // 參數(shù)類似是String
}));
methodBuild.body = const Code("_name = value;"); // 方法體夏志,對(duì)_name賦值為value
}))
..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.add(TypeReference((build) {// 給方法添加注解
build.symbol = "override";//注解類型是@override乃坤,表示這是一個(gè)重寫的方法
}));
methodBuild.body = const Code("return \"name = \$_name; sex = \$_sex; age = \$_age\"; ");
}))
);
final emitter = DartEmitter();
print(DartFormatter().format('${user.accept(emitter)}'));
}
void main() {
getUser();
}
當(dāng)然,光靠code_builder是不足以生成可以在實(shí)際項(xiàng)目中可以使用的類的沟蔑,因?yàn)樗皇莿?chuàng)建了代碼模板而已湿诊,我們還需要將這些代碼模板寫入到工程目錄的某一個(gè)dart文件中,這個(gè)就需要借助source_gen了瘦材,source_gen可以在編譯時(shí)解析注解厅须,然后借助code_builder生成代碼模板,最終將這些代碼模板寫入到工程目錄的某一個(gè)dart文件中食棕。
QQ交流群
群號(hào)碼:770892444