Initial project
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import 'package:analyzer/dart/element/element.dart';
|
||||
import 'package:analyzer/dart/element/type.dart';
|
||||
import 'package:networks_sdk/src/annotations/api_request.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
import 'package:build/build.dart';
|
||||
|
||||
|
||||
/// @ApiRequest 代码生成器
|
||||
///
|
||||
/// 为标注了 `@ApiRequest` 的类自动生成 mixin,提供:
|
||||
/// - `path`, `method`, `requestType`, `includeToken` 协议实现
|
||||
/// - 自动注册响应类型的 `fromJson`(在 `parameters` getter 中触发,
|
||||
/// 保证首次请求前完成注册,无需手动调用 `registerApiResponses()`)
|
||||
///
|
||||
/// 生成的 mixin 命名规则:`_$<ClassName>Api`
|
||||
///
|
||||
/// 示例输出:
|
||||
/// ```dart
|
||||
/// mixin _$LoginRequestApi on ApiRequestable<LoginData> {
|
||||
/// @override String get path => '/auth/login';
|
||||
/// @override HttpMethod get method => HttpMethod.post;
|
||||
/// @override ApiRequestType get requestType => ApiRequestType.login;
|
||||
/// @override bool get includeToken => false;
|
||||
/// @override
|
||||
/// Map<String, dynamic>? get parameters {
|
||||
/// registerResponse<LoginData>(LoginData.fromJson);
|
||||
/// return super.parameters;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
class ApiRequestGenerator extends GeneratorForAnnotation<ApiRequest>
|
||||
{
|
||||
@override
|
||||
String generateForAnnotatedElement(Element element, ConstantReader annotation, BuildStep buildStep,)
|
||||
{
|
||||
if (element is! ClassElement) {
|
||||
throw InvalidGenerationSourceError(
|
||||
'@ApiRequest can only be applied to classes.',
|
||||
element: element,
|
||||
);
|
||||
}
|
||||
|
||||
final className = element.name;
|
||||
final path = annotation.read('path').stringValue;
|
||||
|
||||
// 读取 HttpMethod 枚举值
|
||||
final methodName = _readEnumName(
|
||||
annotation.read('method').objectValue,
|
||||
'post',
|
||||
);
|
||||
|
||||
// 读取 responseType(用于泛型绑定 + 自动注册 fromJson)
|
||||
final responseType = annotation.read('responseType').typeValue;
|
||||
final responseTypeName = responseType.getDisplayString();
|
||||
|
||||
// 读取 ApiRequestType 枚举值
|
||||
final requestTypeName = _readEnumName(
|
||||
annotation.read('requestType').objectValue,
|
||||
'request',
|
||||
);
|
||||
|
||||
// 读取 includeToken(默认根据 requestType 推断:login → false,其余 → true)
|
||||
final includeTokenReader = annotation.peek('includeToken');
|
||||
final bool includeToken;
|
||||
if (includeTokenReader != null && !includeTokenReader.isNull) {
|
||||
includeToken = includeTokenReader.boolValue;
|
||||
} else {
|
||||
includeToken = requestTypeName != 'login';
|
||||
}
|
||||
|
||||
return '''
|
||||
/// Generated by @ApiRequest for [$className]
|
||||
mixin _\$${className}Api on ApiRequestable<$responseTypeName> {
|
||||
@override
|
||||
String get path => '$path';
|
||||
@override
|
||||
HttpMethod get method => HttpMethod.$methodName;
|
||||
@override
|
||||
ApiRequestType get requestType => ApiRequestType.$requestTypeName;
|
||||
@override
|
||||
bool get includeToken => $includeToken;
|
||||
@override
|
||||
Map<String, dynamic>? get parameters {
|
||||
registerResponse<$responseTypeName>($responseTypeName.fromJson);
|
||||
return super.parameters;
|
||||
}
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
/// 从 DartObject 提取枚举常量名称
|
||||
String _readEnumName(dynamic dartObject, String defaultValue) {
|
||||
final index = dartObject.getField('index')?.toIntValue();
|
||||
if (index == null) return defaultValue;
|
||||
|
||||
final type = dartObject.type;
|
||||
if (type is InterfaceType) {
|
||||
final constants = type.element.fields
|
||||
.where((f) => f.isEnumConstant)
|
||||
.toList();
|
||||
if (index < constants.length) {
|
||||
return constants[index].name ?? defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
12
packages/networks_sdk/lib/src/generator/builder.dart
Normal file
12
packages/networks_sdk/lib/src/generator/builder.dart
Normal file
@@ -0,0 +1,12 @@
|
||||
import 'package:build/build.dart';
|
||||
import 'package:source_gen/source_gen.dart';
|
||||
|
||||
import 'api_request_generator.dart';
|
||||
|
||||
/// @ApiRequest 代码生成器入口
|
||||
///
|
||||
/// 在 `build.yaml` 中注册此 builder,配合 `build_runner` 使用。
|
||||
/// 生成的代码通过 `SharedPartBuilder` 合并到 `.g.dart` 文件中,
|
||||
/// 与 `json_serializable` 等生成器共存。
|
||||
Builder apiRequestBuilder(BuilderOptions options) =>
|
||||
SharedPartBuilder([ApiRequestGenerator()], 'api_request');
|
||||
Reference in New Issue
Block a user