mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-23 21:13:35 +00:00
- Added comprehensive English documentation for all DI generator and support files: * inject_generator.dart — full class/method doc-comments, usage samples * module_generator.dart — doc-comments, feature explanation, complete example * src/annotation_validator.dart — class and detailed static method descriptions * src/type_parser.dart — doc, example for ParsedType and TypeParser, specific codegen notes * src/bind_spec.dart — interface, static factory, and codegen docs with DI scenarios * src/bind_parameters_spec.dart — details and samples for code generation logic * src/metadata_utils.dart — full doc and examples for annotation utilities * src/exceptions.dart — user- and contributor-friendly errors, structured output, category explanations * src/generated_class.dart — usage-centric doc-comments, example of resulting generated DI class - Removed Russian/duplicate comments for full clarity and maintainability - Ensured that new and existing contributors can easily extend and maintain DI code generation logic BREAKING CHANGE: All documentation now English-only; comments include usage examples for each principal structure or routine See #docs, #generator, #cherrypick
127 lines
4.2 KiB
Dart
127 lines
4.2 KiB
Dart
//
|
|
// 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
|
|
// https://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';
|
|
|
|
/// ---------------------------------------------------------------------------
|
|
/// GeneratedClass
|
|
///
|
|
/// Represents a processed DI module class with all its binding methods analyzed.
|
|
/// Stores:
|
|
/// - The original class name,
|
|
/// - The generated implementation class name (with $ prefix),
|
|
/// - The list of all BindSpec for the module methods,
|
|
/// - The source file name for reference or directive generation.
|
|
///
|
|
/// Provides static and instance methods to construct from a ClassElement
|
|
/// and generate Dart source code for the resulting DI registration class.
|
|
///
|
|
/// ## Example usage
|
|
/// ```dart
|
|
/// final gen = GeneratedClass.fromClassElement(myModuleClassElement);
|
|
/// print(gen.generate());
|
|
/// /*
|
|
/// Produces:
|
|
/// final class $MyModule extends MyModule {
|
|
/// @override
|
|
/// void builder(Scope currentScope) {
|
|
/// bind<Service>().toProvide(() => provideService(currentScope.resolve<Dep>()));
|
|
/// ...
|
|
/// }
|
|
/// }
|
|
/// */
|
|
/// ```
|
|
/// ---------------------------------------------------------------------------
|
|
class GeneratedClass {
|
|
/// Name of the original Dart module class.
|
|
final String className;
|
|
|
|
/// Name of the generated class, e.g. `$MyModule`
|
|
final String generatedClassName;
|
|
|
|
/// Binding specs for all provider/factory methods in the class.
|
|
final List<BindSpec> binds;
|
|
|
|
/// Source filename of the module class (for code references).
|
|
final String sourceFile;
|
|
|
|
GeneratedClass(
|
|
this.className,
|
|
this.generatedClassName,
|
|
this.binds,
|
|
this.sourceFile,
|
|
);
|
|
|
|
/// -------------------------------------------------------------------------
|
|
/// fromClassElement
|
|
///
|
|
/// Creates a [GeneratedClass] by analyzing a Dart [ClassElement].
|
|
/// Collects all public non-abstract methods, creates a [BindSpec] for each,
|
|
/// and infers the generated class name using a `$` prefix.
|
|
///
|
|
/// ## Example usage
|
|
/// ```dart
|
|
/// final gen = GeneratedClass.fromClassElement(classElement);
|
|
/// print(gen.generatedClassName); // e.g. $AppModule
|
|
/// ```
|
|
static GeneratedClass fromClassElement(ClassElement element) {
|
|
final className = element.displayName;
|
|
// Generated class name with '$' prefix (standard for generated Dart code).
|
|
final generatedClassName = r'$' + className;
|
|
// Get source file name
|
|
final sourceFile = element.source.shortName;
|
|
// Collect bindings for all non-abstract methods.
|
|
final binds = element.methods
|
|
.where((m) => !m.isAbstract)
|
|
.map(BindSpec.fromMethod)
|
|
.toList();
|
|
|
|
return GeneratedClass(className, generatedClassName, binds, sourceFile);
|
|
}
|
|
|
|
/// -------------------------------------------------------------------------
|
|
/// generate
|
|
///
|
|
/// Generates the Dart source code for the DI registration class.
|
|
/// The generated class extends the original module, and the `builder` method
|
|
/// registers all bindings (dependencies) into the DI scope.
|
|
///
|
|
/// ## Example output
|
|
/// ```dart
|
|
/// final class $UserModule extends UserModule {
|
|
/// @override
|
|
/// void builder(Scope currentScope) {
|
|
/// bind<Service>().toProvide(() => provideService(currentScope.resolve<Dep>()));
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
String generate() {
|
|
final buffer = StringBuffer()
|
|
..writeln('final class $generatedClassName extends $className {')
|
|
..writeln(' @override')
|
|
..writeln(' void builder(Scope currentScope) {');
|
|
|
|
// For each binding, generate bind<Type>() code string.
|
|
for (final bind in binds) {
|
|
buffer.writeln(bind.generateBind(4));
|
|
}
|
|
|
|
buffer
|
|
..writeln(' }')
|
|
..writeln('}');
|
|
|
|
return buffer.toString();
|
|
}
|
|
}
|