mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-23 21:13:35 +00:00
feat: implement InjectGenerator
This commit is contained in:
@@ -21,3 +21,4 @@ export 'src/named.dart';
|
|||||||
export 'src/params.dart';
|
export 'src/params.dart';
|
||||||
export 'src/inject.dart';
|
export 'src/inject.dart';
|
||||||
export 'src/injectable.dart';
|
export 'src/injectable.dart';
|
||||||
|
export 'src/scope.dart';
|
||||||
|
|||||||
18
cherrypick_annotations/lib/src/scope.dart
Normal file
18
cherrypick_annotations/lib/src/scope.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2021 Sergey Penkovsky (sergey.penkovsky@gmail.com)
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
// ignore: camel_case_types
|
||||||
|
final class scope {
|
||||||
|
final String? name;
|
||||||
|
const scope(this.name);
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'package:analyzer/dart/constant/value.dart';
|
||||||
import 'package:build/build.dart';
|
import 'package:build/build.dart';
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:source_gen/source_gen.dart';
|
import 'package:source_gen/source_gen.dart';
|
||||||
import 'package:analyzer/dart/element/element.dart';
|
import 'package:analyzer/dart/element/element.dart';
|
||||||
import 'package:cherrypick_annotations/cherrypick_annotations.dart' as ann;
|
import 'package:cherrypick_annotations/cherrypick_annotations.dart' as ann;
|
||||||
@@ -11,8 +11,6 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
|
|||||||
@override
|
@override
|
||||||
FutureOr<String> generateForAnnotatedElement(
|
FutureOr<String> generateForAnnotatedElement(
|
||||||
Element element, ConstantReader annotation, BuildStep buildStep) {
|
Element element, ConstantReader annotation, BuildStep buildStep) {
|
||||||
// Only classes are supported for @module() annotation
|
|
||||||
// Обрабатываются только классы (другие элементы — ошибка)
|
|
||||||
if (element is! ClassElement) {
|
if (element is! ClassElement) {
|
||||||
throw InvalidGenerationSourceError(
|
throw InvalidGenerationSourceError(
|
||||||
'@injectable() can only be applied to classes.',
|
'@injectable() can only be applied to classes.',
|
||||||
@@ -28,30 +26,36 @@ class InjectGenerator extends GeneratorForAnnotation<ann.injectable> {
|
|||||||
.any((m) =>
|
.any((m) =>
|
||||||
m.computeConstantValue()?.type?.getDisplayString() == 'inject'));
|
m.computeConstantValue()?.type?.getDisplayString() == 'inject'));
|
||||||
|
|
||||||
// Генерируем инициализацию для каждого поля с аннотацией @inject()
|
|
||||||
final buffer = StringBuffer();
|
final buffer = StringBuffer();
|
||||||
buffer.writeln('mixin $mixinName {');
|
buffer.writeln('mixin $mixinName {');
|
||||||
buffer.writeln(' void _inject($className instance) {');
|
buffer.writeln(' void _inject($className instance) {');
|
||||||
|
|
||||||
for (final field in injectedFields) {
|
for (final field in injectedFields) {
|
||||||
// Получаем имя типа
|
String? scopeName;
|
||||||
final fieldType = field.type.getDisplayString();
|
String? namedValue;
|
||||||
// Ищем аннотацию @named
|
|
||||||
final namedAnnotation = field.metadata.firstWhereOrNull(
|
for (final m in field.metadata) {
|
||||||
(m) => m.computeConstantValue()?.type?.getDisplayString() == 'named',
|
final DartObject? obj = m.computeConstantValue();
|
||||||
);
|
final type = obj?.type?.getDisplayString();
|
||||||
String namedParam = '';
|
if (type == 'scope') {
|
||||||
if (namedAnnotation != null) {
|
scopeName = obj?.getField('name')?.toStringValue();
|
||||||
final namedValue = namedAnnotation
|
} else if (type == 'named') {
|
||||||
.computeConstantValue()
|
namedValue = obj?.getField('value')?.toStringValue();
|
||||||
?.getField('value')
|
|
||||||
?.toStringValue();
|
|
||||||
if (namedValue != null) {
|
|
||||||
namedParam = "(named: '$namedValue')";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer.writeln(
|
|
||||||
" instance.${field.name} = CherryPick.openRootScope().resolve<$fieldType>$namedParam;");
|
final String fieldType = field.type.getDisplayString();
|
||||||
|
|
||||||
|
String accessor = (scopeName != null && scopeName.isNotEmpty)
|
||||||
|
? "CherryPick.openScope(scopeName: '$scopeName').resolve"
|
||||||
|
: "CherryPick.openRootScope().resolve";
|
||||||
|
|
||||||
|
String generic = fieldType != 'dynamic' ? '<$fieldType>' : '';
|
||||||
|
String params = (namedValue != null && namedValue.isNotEmpty)
|
||||||
|
? "(named: '$namedValue')"
|
||||||
|
: '()';
|
||||||
|
|
||||||
|
buffer.writeln(" instance.${field.name} = $accessor$generic$params;");
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.writeln(' }');
|
buffer.writeln(' }');
|
||||||
|
|||||||
@@ -11,14 +11,22 @@ part 'app.inject.cherrypick.g.dart';
|
|||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
class MyApp extends StatelessWidget with _$MyApp {
|
class MyApp extends StatelessWidget with _$MyApp {
|
||||||
final Scope scope;
|
|
||||||
final _appRouter = AppRouter();
|
final _appRouter = AppRouter();
|
||||||
|
|
||||||
|
@scope('authZone')
|
||||||
|
@inject()
|
||||||
|
late final String text;
|
||||||
|
|
||||||
|
@scope('authZone')
|
||||||
|
@named('timeout')
|
||||||
|
@inject()
|
||||||
|
late final int timeout;
|
||||||
|
|
||||||
@named('repo')
|
@named('repo')
|
||||||
@inject()
|
@inject()
|
||||||
late final PostRepository repository;
|
late final PostRepository repository;
|
||||||
|
|
||||||
MyApp({super.key, required this.scope});
|
MyApp({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import 'package:postly/app.dart';
|
|||||||
import 'di/app_module.dart';
|
import 'di/app_module.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
final scope = CherryPick.openRootScope();
|
CherryPick.openRootScope().installModules([$AppModule()]);
|
||||||
scope.installModules([$AppModule()]);
|
runApp(MyApp());
|
||||||
|
|
||||||
runApp(MyApp(scope: scope));
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user