2025-05-21 15:50:24 +03:00
|
|
|
|
//
|
|
|
|
|
|
// 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.
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
import 'package:analyzer/dart/element/element.dart';
|
|
|
|
|
|
|
|
|
|
|
|
import 'bind_spec.dart';
|
|
|
|
|
|
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// ---------------------------------------------------------------------------
|
|
|
|
|
|
/// GeneratedClass -- represents the result of processing a single module class.
|
2025-05-21 15:50:24 +03:00
|
|
|
|
///
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// ENGLISH
|
|
|
|
|
|
/// Encapsulates all the information produced from analyzing a DI module class:
|
|
|
|
|
|
/// - The original class name,
|
|
|
|
|
|
/// - Its generated class name (e.g., `$SomeModule`),
|
|
|
|
|
|
/// - The collection of bindings (BindSpec) for all implemented provider methods.
|
2025-05-21 15:50:24 +03:00
|
|
|
|
///
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// Also provides code generation functionality, allowing to generate the source
|
|
|
|
|
|
/// code for the derived DI module class, including all binding registrations.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// RUSSIAN
|
|
|
|
|
|
/// Описывает результат обработки одного класса-модуля DI:
|
|
|
|
|
|
/// - Имя оригинального класса,
|
|
|
|
|
|
/// - Имя генерируемого класса (например, `$SomeModule`),
|
|
|
|
|
|
/// - Список всех бидингов (BindSpec) — по публичным методам модуля.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Также содержит функцию генерации исходного кода для этого класса и
|
|
|
|
|
|
/// регистрации всех зависимостей через bind(...).
|
|
|
|
|
|
/// ---------------------------------------------------------------------------
|
2025-05-21 15:50:24 +03:00
|
|
|
|
class GeneratedClass {
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// The name of the original module class.
|
2025-05-21 15:50:24 +03:00
|
|
|
|
/// Имя исходного класса-модуля
|
|
|
|
|
|
final String className;
|
|
|
|
|
|
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// The name of the generated class (e.g., $SomeModule).
|
2025-05-21 15:50:24 +03:00
|
|
|
|
/// Имя генерируемого класса (например, $SomeModule)
|
|
|
|
|
|
final String generatedClassName;
|
|
|
|
|
|
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// List of all discovered bindings for the class.
|
2025-05-21 15:50:24 +03:00
|
|
|
|
/// Список всех обнаруженных биндингов
|
|
|
|
|
|
final List<BindSpec> binds;
|
|
|
|
|
|
|
2025-07-25 11:58:56 +03:00
|
|
|
|
/// Source file name for the part directive
|
|
|
|
|
|
/// Имя исходного файла для part директивы
|
|
|
|
|
|
final String sourceFile;
|
|
|
|
|
|
|
2025-05-21 15:50:24 +03:00
|
|
|
|
GeneratedClass(
|
|
|
|
|
|
this.className,
|
|
|
|
|
|
this.generatedClassName,
|
|
|
|
|
|
this.binds,
|
2025-07-25 11:58:56 +03:00
|
|
|
|
this.sourceFile,
|
2025-05-21 15:50:24 +03:00
|
|
|
|
);
|
|
|
|
|
|
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// -------------------------------------------------------------------------
|
|
|
|
|
|
/// fromClassElement
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ENGLISH
|
|
|
|
|
|
/// Static factory: creates a GeneratedClass from a Dart ClassElement (AST representation).
|
|
|
|
|
|
/// Discovers all non-abstract methods, builds BindSpec for each, and computes the
|
|
|
|
|
|
/// generated class name by prefixing `$`.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// RUSSIAN
|
|
|
|
|
|
/// Строит объект класса по элементу AST (ClassElement): имя класса,
|
|
|
|
|
|
/// сгенерированное имя, список BindSpec по всем не абстрактным методам.
|
|
|
|
|
|
/// Имя ген-класса строится с префиксом `$`.
|
|
|
|
|
|
/// -------------------------------------------------------------------------
|
2025-05-21 15:50:24 +03:00
|
|
|
|
static GeneratedClass fromClassElement(ClassElement element) {
|
|
|
|
|
|
final className = element.displayName;
|
2025-05-22 16:05:09 +03:00
|
|
|
|
// Generated class name with '$' prefix (standard for generated Dart code).
|
2025-05-21 15:50:24 +03:00
|
|
|
|
final generatedClassName = r'$' + className;
|
2025-07-25 11:58:56 +03:00
|
|
|
|
// Get source file name
|
|
|
|
|
|
final sourceFile = element.source.shortName;
|
2025-05-22 16:05:09 +03:00
|
|
|
|
// Collect bindings for all non-abstract methods.
|
2025-05-21 15:50:24 +03:00
|
|
|
|
final binds = element.methods
|
|
|
|
|
|
.where((m) => !m.isAbstract)
|
|
|
|
|
|
.map(BindSpec.fromMethod)
|
|
|
|
|
|
.toList();
|
|
|
|
|
|
|
2025-07-25 11:58:56 +03:00
|
|
|
|
return GeneratedClass(className, generatedClassName, binds, sourceFile);
|
2025-05-21 15:50:24 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// -------------------------------------------------------------------------
|
|
|
|
|
|
/// generate
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ENGLISH
|
|
|
|
|
|
/// Generates Dart source code for the DI module class. The generated class
|
|
|
|
|
|
/// inherits from the original, overrides the 'builder' method, and registers
|
|
|
|
|
|
/// all bindings in the DI scope.
|
2025-05-21 15:50:24 +03:00
|
|
|
|
///
|
2025-05-22 16:05:09 +03:00
|
|
|
|
/// RUSSIAN
|
|
|
|
|
|
/// Генерирует исходный Dart-код для класса-модуля DI.
|
|
|
|
|
|
/// Новая версия класса наследует оригинальный, переопределяет builder(Scope),
|
|
|
|
|
|
/// и регистрирует все зависимости через методы bind<Type>()...
|
|
|
|
|
|
/// -------------------------------------------------------------------------
|
2025-05-21 15:50:24 +03:00
|
|
|
|
String generate() {
|
2025-07-25 11:58:56 +03:00
|
|
|
|
final buffer = StringBuffer()
|
|
|
|
|
|
..writeln('final class $generatedClassName extends $className {')
|
|
|
|
|
|
..writeln(' @override')
|
|
|
|
|
|
..writeln(' void builder(Scope currentScope) {');
|
2025-05-21 15:50:24 +03:00
|
|
|
|
|
2025-05-22 16:05:09 +03:00
|
|
|
|
// For each binding, generate bind<Type>() code string.
|
2025-05-21 15:50:24 +03:00
|
|
|
|
// Для каждого биндинга — генерируем строку bind<Type>()...
|
|
|
|
|
|
for (final bind in binds) {
|
|
|
|
|
|
buffer.writeln(bind.generateBind(4));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-25 11:58:56 +03:00
|
|
|
|
buffer
|
|
|
|
|
|
..writeln(' }')
|
|
|
|
|
|
..writeln('}');
|
2025-05-21 15:50:24 +03:00
|
|
|
|
|
|
|
|
|
|
return buffer.toString();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|