diff --git a/packages/nameof/example/bin/example.dart b/packages/nameof/example/bin/example.dart index 91739ba..f75f5e3 100644 --- a/packages/nameof/example/bin/example.dart +++ b/packages/nameof/example/bin/example.dart @@ -1,5 +1,5 @@ import 'models/sample.dart'; void main(List arguments) { - print('Hello nameof! ' + NameofSample.className); + print('Hello nameof! ${NameofSample.className}'); } diff --git a/packages/nameof/example/bin/models/sample.dart b/packages/nameof/example/bin/models/sample.dart index affa1a8..e68816c 100644 --- a/packages/nameof/example/bin/models/sample.dart +++ b/packages/nameof/example/bin/models/sample.dart @@ -33,7 +33,7 @@ class Car { : this(price, weigth, year, 'Sedan'); } -@Nameof(coverage: Coverage.excludeImplicit) +@Nameof(coverage: Coverage.excludeImplicit, scope: NameofScope.all) class Sample extends BaseClass with VinilMixin { final String name; String _behind = ''; diff --git a/packages/nameof/example/pubspec.yaml b/packages/nameof/example/pubspec.yaml index f6c7702..990bf65 100644 --- a/packages/nameof/example/pubspec.yaml +++ b/packages/nameof/example/pubspec.yaml @@ -4,14 +4,15 @@ version: 1.1.0 # homepage: https://www.example.com environment: - sdk: ^3.0.0 + sdk: ^3.8.0 dependencies: - nameof_annotation: ^0.2.0 + nameof_annotation: + path: ../../nameof_annotation/ dev_dependencies: - lints: ^3.0.0 + lints: ^6.1.0 build_runner: # nameof: ^0.2.0 nameof: diff --git a/packages/nameof/lib/src/model/property_info.dart b/packages/nameof/lib/src/model/property_info.dart index 063f51a..d054806 100644 --- a/packages/nameof/lib/src/model/property_info.dart +++ b/packages/nameof/lib/src/model/property_info.dart @@ -5,20 +5,14 @@ class PropertyInfo extends ElementInfo { final bool isGetter; PropertyInfo({ - required String name, - required String originalName, - required bool isPrivate, - required bool isAnnotated, - required bool isIgnore, + required super.name, + required super.originalName, + required super.isPrivate, + required super.isAnnotated, + required super.isIgnore, required this.isSetter, required this.isGetter, - }) : assert(isGetter ^ isSetter), - super( - name: name, - originalName: originalName, - isIgnore: isIgnore, - isPrivate: isPrivate, - isAnnotated: isAnnotated); + }) : assert(isGetter ^ isSetter); factory PropertyInfo.fromElementInfo(ElementInfo based, {required bool isGetter, required bool isSetter}) { diff --git a/packages/nameof/lib/src/nameof_generator.dart b/packages/nameof/lib/src/nameof_generator.dart index b09921a..0fa9a67 100644 --- a/packages/nameof/lib/src/nameof_generator.dart +++ b/packages/nameof/lib/src/nameof_generator.dart @@ -33,7 +33,7 @@ class NameofGenerator extends GeneratorForAnnotation { return code; } - NameofOptions _parseConfig(ConstantReader annotation) { + Coverage _parseCoverage(ConstantReader annotation) { final coverageConfigString = config['coverage']?.toString(); bool covTest(Coverage coverage) => @@ -47,11 +47,33 @@ class NameofGenerator extends GeneratorForAnnotation { annotation.read('coverage'), Coverage.values, ); + return coverageAnnotation ?? coverageConfig ?? Coverage.includeImplicit; + } + + NameofScope _parseScope(ConstantReader annotation) { + final scopeConfigString = config.containsKey('scope') ? config['scope']?.toString() : ''; + + bool scopeTest(NameofScope scope) => + scopeConfigString == scope.toShortString(); + + final scopeConfig = NameofScope.values.any(scopeTest) + ? NameofScope.values.firstWhere(scopeTest) + : null; + + final scopeConstantReader = annotation.peek('scope'); + final scopeAnnotation = scopeConstantReader != null ? enumValueForDartObject( + scopeConstantReader, + NameofScope.values, + ) : null; + + return scopeAnnotation ?? scopeConfig ?? NameofScope.onlyPublic; + } + + NameofOptions _parseConfig(ConstantReader annotation) { return NameofOptions( - coverage: - coverageAnnotation ?? coverageConfig ?? Coverage.includeImplicit, - scope: NameofScope.onlyPublic); + coverage: _parseCoverage(annotation), + scope: _parseScope(annotation)); } T? enumValueForDartObject( diff --git a/packages/nameof/lib/src/nameof_visitor.dart b/packages/nameof/lib/src/nameof_visitor.dart index a38ecc2..1493ffd 100644 --- a/packages/nameof/lib/src/nameof_visitor.dart +++ b/packages/nameof/lib/src/nameof_visitor.dart @@ -1,4 +1,3 @@ -import 'package:analyzer/dart/element/visitor.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:nameof/src/model/element_info.dart'; import 'package:nameof/src/util/element_extensions.dart'; @@ -8,7 +7,7 @@ import 'package:nameof_annotation/nameof_annotation.dart'; import 'model/property_info.dart'; /// Class for collect info about inner elements of class (or mixin) -class NameofVisitor extends SimpleElementVisitor { +class NameofVisitor extends ElementVisitor2 { late String className; final constructors = {}; @@ -20,7 +19,11 @@ class NameofVisitor extends SimpleElementVisitor { @override void visitConstructorElement(ConstructorElement element) { - constructors[element.name] = _getElementInfo(element); + if (element.name == null) { + throw UnsupportedError('Element does not have a name!'); + } + + constructors[element.name!] = _getElementInfo(element); } @override @@ -29,24 +32,20 @@ class NameofVisitor extends SimpleElementVisitor { return; } - fields[element.name] = _getElementInfo(element); - } - - @override - void visitPropertyAccessorElement(PropertyAccessorElement element) { - if (element.isSynthetic) { - return; + if (element.name == null) { + throw UnsupportedError('Element does not have a name!'); } - properties[element.name] = PropertyInfo.fromElementInfo( - _getElementInfo(element), - isGetter: element.isGetter, - isSetter: element.isSetter); + fields[element.name!] = _getElementInfo(element); } @override void visitMethodElement(MethodElement element) { - functions[element.name] = _getElementInfo(element); + if (element.name == null) { + throw UnsupportedError('Element does not have a name!'); + } + + functions[element.name!] = _getElementInfo(element); } ElementInfo _getElementInfo(Element element) { @@ -58,6 +57,7 @@ class NameofVisitor extends SimpleElementVisitor { final isAnnotated = element.hasAnnotation(NameofKey); final isIgnore = element.hasAnnotation(NameofIgnore); + String? name = (isAnnotated ? element .getAnnotation(NameofKey) @@ -76,4 +76,128 @@ class NameofVisitor extends SimpleElementVisitor { isAnnotated: isAnnotated, isIgnore: isIgnore); } + + @override + void visitClassElement(ClassElement element) { + } + + @override + void visitEnumElement(EnumElement element) { + } + + @override + void visitExtensionElement(ExtensionElement element) { + } + + @override + void visitExtensionTypeElement(ExtensionTypeElement element) { + } + + @override + void visitFieldFormalParameterElement(FieldFormalParameterElement element) { + } + + @override + void visitGenericFunctionTypeElement(GenericFunctionTypeElement element) { + } + + @override + void visitGetterElement(GetterElement element) { + if (element.isSynthetic) { + return; + } + + if (element.name == null) { + throw UnsupportedError('Element does not have a name!'); + } + + if (properties.containsKey(element.name!)) { + properties[element.name!] = PropertyInfo.fromElementInfo( + _getElementInfo(element), + isGetter: true, isSetter: properties[element.name!]!.isSetter); + } else { + properties[element.name!] = PropertyInfo.fromElementInfo( + _getElementInfo(element), + isGetter: true, isSetter: false); + } + } + + @override + void visitLabelElement(LabelElement element) { + } + + @override + void visitLibraryElement(LibraryElement element) { + } + + @override + void visitLocalFunctionElement(LocalFunctionElement element) { + if (element.name == null) { + throw UnsupportedError('Element does not have a name!'); + } + + functions[element.name!] = _getElementInfo(element); + } + + @override + void visitLocalVariableElement(LocalVariableElement element) { + } + + @override + void visitMixinElement(MixinElement element) { + } + + @override + void visitMultiplyDefinedElement(MultiplyDefinedElement element) { + } + + @override + void visitPrefixElement(PrefixElement element) { + + } + + @override + void visitSetterElement(SetterElement element) { + if (element.isSynthetic) { + return; + } + + if (element.name == null) { + throw UnsupportedError('Element does not have a name!'); + } + + if (properties.containsKey(element.name!)) { + properties[element.name!] = PropertyInfo.fromElementInfo( + _getElementInfo(element), + isGetter: properties[element.name!]!.isGetter, isSetter: true); + } else { + properties[element.name!] = PropertyInfo.fromElementInfo( + _getElementInfo(element), + isGetter: false, isSetter: true); + } + } + + @override + void visitSuperFormalParameterElement(SuperFormalParameterElement element) { + } + + @override + void visitTopLevelVariableElement(TopLevelVariableElement element) { + } + + @override + void visitTypeAliasElement(TypeAliasElement element) { + } + + @override + void visitTypeParameterElement(TypeParameterElement element) { + } + + @override + void visitFormalParameterElement(FormalParameterElement element) { + } + + @override + void visitTopLevelFunctionElement(TopLevelFunctionElement element) { + } } diff --git a/packages/nameof/lib/src/util/element_extensions.dart b/packages/nameof/lib/src/util/element_extensions.dart index 137e871..f203112 100644 --- a/packages/nameof/lib/src/util/element_extensions.dart +++ b/packages/nameof/lib/src/util/element_extensions.dart @@ -2,7 +2,7 @@ import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:source_gen/source_gen.dart'; -TypeChecker _typeChecker(final Type type) => TypeChecker.fromRuntime(type); +TypeChecker _typeChecker(final Type type) => TypeChecker.typeNamed(type); extension AnnotationChecker on Element { bool hasAnnotation(final Type type) { diff --git a/packages/nameof/pubspec.yaml b/packages/nameof/pubspec.yaml index ac8e01d..6fa9483 100644 --- a/packages/nameof/pubspec.yaml +++ b/packages/nameof/pubspec.yaml @@ -1,21 +1,23 @@ name: nameof description: Generator for Dart class member's names, such as fields, properties, methods, constructors -version: 0.2.2 +version: 0.3.1 homepage: https://github.com/flankb/nameof environment: - sdk: '>=2.16.0 <4.0.0' + sdk: ">=3.9.0 <4.0.0" dependencies: - analyzer: '>=5.2.0 <7.0.0' - build: ^2.1.0 - source_gen: ^1.4.0 - build_config: '>=0.4.4 <2.0.0' - nameof_annotation: ^0.2.0 + analyzer: ^10.0.0 + build: ^4.0.4 + source_gen: ^4.2.0 + build_config: ^1.3.0 + nameof_annotation: + path: ../nameof_annotation/ + dev_dependencies: - build_runner: ^2.1.11 - build_test: ^2.2.2 - source_gen_test: ^1.0.6 - lints: ^3.0.0 - test: ^1.24.0 + build_runner: ^2.12.2 + build_test: ^3.5.10 + source_gen_test: ^1.3.4 + lints: ^6.1.0 + test: ^1.30.0 diff --git a/packages/nameof/test/integration/models.dart b/packages/nameof/test/integration/models.dart index fcc2d8c..1ccd847 100644 --- a/packages/nameof/test/integration/models.dart +++ b/packages/nameof/test/integration/models.dart @@ -2,6 +2,10 @@ import 'package:nameof_annotation/nameof_annotation.dart'; part 'models.nameof.dart'; +void main() { + +} + @nameof class BaseClass { final double price; diff --git a/packages/nameof/test/nameof_test.dart b/packages/nameof/test/nameof_test.dart index 541bac1..96fdc76 100644 --- a/packages/nameof/test/nameof_test.dart +++ b/packages/nameof/test/nameof_test.dart @@ -6,20 +6,21 @@ void main() { group('A group of tests for check generation code', () { test('test generate code for model one', () { expect(NameofModelOne.className, 'ModelOne'); - expect(NameofModelOne.constructor, ''); + expect(NameofModelOne.constructorNew, 'new'); expect(NameofModelOne.fieldName, 'name'); expect(NameofModelOne.fieldId, 'id'); expect(NameofModelOne.functionBuildValue, 'buildValue'); + expect(NameofModelOne.propertySetBehindProp, 'behindProp'); }); test('test generate code for base class', () { expect(NameofBaseClass.className, 'BaseClass'); expect(NameofBaseClass.fieldPrice, 'price'); - expect(NameofBaseClass.constructor, ''); + expect(NameofBaseClass.constructorNew, 'new'); }); test('test generate code for mixin', () { - expect(NameofMixinOne.propertyGetHameleon, 'hameleon'); + expect(NameofMixinOne.propertyGetNameVinage, 'hameleon'); expect(NameofMixinOne.className, 'MixinOne'); }); }); diff --git a/packages/nameof/test/source_gen_src.dart b/packages/nameof/test/source_gen_src.dart index 45355d7..d10f7c3 100644 --- a/packages/nameof/test/source_gen_src.dart +++ b/packages/nameof/test/source_gen_src.dart @@ -6,7 +6,7 @@ import 'package:source_gen_test/annotations.dart'; abstract class NameofModelTest { static const String className = 'ModelTest'; - static const String constructor = ''; + static const String constructorNew = 'new'; static const String fieldName = 'name'; static const String fieldId = 'id'; @@ -34,7 +34,7 @@ class ModelTest { abstract class NameofModelTest2 { static const String className = 'ModelTest2'; - static const String constructor = ''; + static const String constructorNew = 'new'; static const String fieldName = 'name'; static const String fieldId = 'id'; @@ -53,6 +53,29 @@ class ModelTest2 { ModelTest2(this.name, this.id); } +@ShouldGenerate(r''' +/// Container for names of elements belonging to the [ModelTest3] class +abstract class NameofModelTest3 { + static const String className = 'ModelTest3'; + + static const String constructorNew = 'new'; + + static const String fieldName = 'name'; + static const String fieldId = 'id'; + + static const String functionPrivateSetCal = '_setCal'; +} +''') +@Nameof(scope: NameofScope.all,) +class ModelTest3 { + final String name; + final int id; + + void _setCal() {} + + ModelTest3(this.name, this.id); +} + @ShouldGenerate(r''' /// Container for names of elements belonging to the [MixinTest3] class abstract class NameofMixinTest3 { @@ -75,7 +98,7 @@ mixin MixinTest3 { abstract class NameofCinema { static const String className = 'Cinema'; - static const String constructor = ''; + static const String constructorNew = 'new'; static const String fieldStreet = 'street'; static const String fieldValue = 'value'; diff --git a/packages/nameof_annotation/lib/nameof_annotation.dart b/packages/nameof_annotation/lib/nameof_annotation.dart index a85d3f8..2296352 100644 --- a/packages/nameof_annotation/lib/nameof_annotation.dart +++ b/packages/nameof_annotation/lib/nameof_annotation.dart @@ -6,8 +6,9 @@ library nameof_annotation; class Nameof { /// This setting response for including and excluding elements of class final Coverage? coverage; + final NameofScope? scope; - const Nameof({this.coverage}); + const Nameof({this.coverage, this.scope}); } /// Annotation for ignore inner elements of class (or mixin) diff --git a/packages/nameof_annotation/pubspec.yaml b/packages/nameof_annotation/pubspec.yaml index d0a35ac..e838ae9 100644 --- a/packages/nameof_annotation/pubspec.yaml +++ b/packages/nameof_annotation/pubspec.yaml @@ -1,6 +1,6 @@ name: nameof_annotation description: Annotations for nameof package, that is Generator for Dart class member's names, such as fields, properties, methods, constructors -version: 0.2.1 +version: 0.3.1 homepage: https://github.com/flankb/nameof environment: @@ -10,5 +10,5 @@ environment: # path: ^1.8.0 dev_dependencies: - lints: ^3.0.0 - test: ^1.24.0 + lints: ^6.1.0 + test: ^1.29.0