Skip to content
This repository has been archived by the owner on Oct 17, 2021. It is now read-only.

Commit

Permalink
Implemented feature: @ToStringMixin() (#42)
Browse files Browse the repository at this point in the history
* Implemented feature: `@ToStringMixin()`
* Updated package description
* Updated documentation for`@ToStringMixin()` and fixed some minor typos
* Updated all to version 1.1.0
  • Loading branch information
xuanswe authored May 21, 2020
1 parent cfd7c13 commit 4b54af9
Show file tree
Hide file tree
Showing 18 changed files with 177 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# to_string_helper
Flexibly configure output of `toString` method (with or without code generation).
Flexibly configure output of `toString` method (with or without code generation) (with or without mixin).

You can choose either to use code generator or not.

Expand Down
1 change: 1 addition & 0 deletions example_with_generator/lib/example.dart
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export 'src/bike.dart';
export 'src/car.dart';
2 changes: 2 additions & 0 deletions example_with_generator/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'src/bike.dart';
import 'src/car.dart';

main() {
print(Bike());
print(EBike());
print(Car());
}
17 changes: 17 additions & 0 deletions example_with_generator/lib/src/car.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:to_string_helper/to_string_helper.dart';

import 'vehicle.dart';

part 'car.g.dart';

@ToStringMixin(
globalInclude: Include(static: true, nullValue: false),
unnamedValue: true,
)
class Car extends Vehicle with _$CarToString {
static String name = 'Car';
@ToStringField(includeNullValue: true, unnamedValue: false)
String _engine;
String color;
final wheels = 4;
}
2 changes: 1 addition & 1 deletion example_with_generator/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: to_string_helper_example_with_generator
version: 1.0.3
version: 1.1.0

environment:
sdk: ">=2.0.0 <3.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,10 @@ void main() {
});
});
});

group('@ToStringMixin()', () {
test('Car', () {
expect(Car().toString(), 'Car{Car, _engine=null, 4}');
});
});
}
2 changes: 1 addition & 1 deletion example_without_generator/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: to_string_helper_example_without_generator
version: 1.0.3
version: 1.1.0

environment:
sdk: ">=2.0.0 <3.0.0"
Expand Down
4 changes: 4 additions & 0 deletions generator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# 1.1.0
* Generate code for annotation `@ToStringMixin`.

# 1.0.3
* Generate code for annotations: `@ToString` and `@ToStringField`.
17 changes: 17 additions & 0 deletions generator/lib/src/config_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ const defaultInclude = Include(
);

Config getConfig(ConstantReader annotation, ClassElement classElement) {
if (!_isToString(annotation)) {
throw InvalidGenerationSourceError(
'Target class should only be annotated with @ToString() or @ToStringMixin()',
element: classElement);
}

return Config(
mixin: _isToStringMixin(annotation),
format: FormatConfig(
nullString: _peek(annotation, 'nullString')?.stringValue ??
defaultFormatConfig.nullString,
Expand Down Expand Up @@ -170,3 +177,13 @@ ConstantReader _getFieldAnnotation(FieldElement element, Type annotationType) {

return null;
}

bool _isToString(ConstantReader annotation) {
return annotation?.instanceOf(const TypeChecker.fromRuntime(ToString)) ??
false;
}

bool _isToStringMixin(ConstantReader annotation) {
return annotation?.instanceOf(const TypeChecker.fromRuntime(ToStringMixin)) ??
false;
}
9 changes: 8 additions & 1 deletion generator/lib/src/configs/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@ import 'field_config.dart';
import 'format_config.dart';

class Config {
const Config({this.format, this.globalInclude, this.fields});
const Config({
this.format,
this.globalInclude,
this.fields,
this.mixin = false,
});

final FormatConfig format;
final Include globalInclude;
final Set<FieldConfig> fields;
final bool mixin;

@override
String toString() {
return 'Config{'
'format: $format'
', globalInclude: $globalInclude'
', fields: $fields'
', mixin: $mixin'
'}';
}
}
40 changes: 38 additions & 2 deletions generator/lib/src/to_string_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,22 @@ class ToStringGenerator extends GeneratorForAnnotation<ToString> {
Element element, ConstantReader annotation, BuildStep buildStep) async {
if (element is! ClassElement) {
throw InvalidGenerationSourceError(
'@ToString() should only be annotated on class target',
'@ToString() should only be annotated on target class',
element: element);
}
final clazz = element as ClassElement;

return _generateToStringMethod(clazz, getConfig(annotation, clazz));
return _generateCode(clazz, getConfig(annotation, clazz));
}

String _generateCode(ClassElement clazz, Config config) {
if (config.mixin) {
return _generateToStringMethod(clazz, config) +
'\n\n' +
_generateToStringMixin(clazz.name);
} else {
return _generateToStringMethod(clazz, config);
}
}

String _generateToStringMethod(ClassElement clazz, Config config) {
Expand Down Expand Up @@ -79,6 +89,32 @@ class ToStringGenerator extends GeneratorForAnnotation<ToString> {
return sb.toString();
}

String _generateToStringMixin(String classname) {
final mixinName = _getToStringMixinName(classname);
final methodName = _getToStringMethodName(classname);

final sb = StringBuffer();

// start mixin
sb.writeln('mixin $mixinName {');

// mixin body
sb
..writeln('@override')
..writeln('String toString() {')
..writeln('return $methodName(this);')
..writeln('}');

// close mixin
sb.writeln('}');

return sb.toString();
}

String _getToStringMixinName(String classname) {
return '_\$${classname}ToString';
}

String _getToStringMethodName(String classname) {
return '_\$' +
classname[0].toLowerCase() +
Expand Down
10 changes: 8 additions & 2 deletions generator/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: to_string_helper_generator
version: 1.0.3
description: Generate code for package to_string_helper. This package is not needed if you want to use to_string_helper without code generation.
version: 1.1.0
description: >
Generate code for package to_string_helper.
This package is not needed if you want to use to_string_helper without code generation.
homepage: https://github.com/zenonine/to_string_helper
repository: https://github.com/zenonine/to_string_helper/tree/master/generator

Expand All @@ -12,3 +14,7 @@ dependencies:
analyzer: ^0.39.7
build: ^1.0.0
source_gen: ^0.9.5

#dependency_overrides:
# to_string_helper:
# path: ../to_string_helper
3 changes: 3 additions & 0 deletions to_string_helper/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# 1.1.0
* Added annotation `@ToStringMixin`.

# 1.0.5
* Improved documentation.

Expand Down
37 changes: 33 additions & 4 deletions to_string_helper/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# to_string_helper
Flexibly configure output of `toString` method (with or without code generation).
Flexibly configure output of `toString` method (with or without code generation) (with or without mixin).

You can choose either to use code generator or not.

Expand Down Expand Up @@ -46,6 +46,17 @@ Otherwise, you only need this package.
to_string_helper_generator: ^1.0.0
```
2. Configure your class
* With mixin
```dart
import 'package:to_string_helper/to_string_helper.dart';

// assume current file is bike.dart, the generated code should be in bike.g.dart
part 'bike.g.dart';

@ToStringMixin()
class Bike {/*...*/}
```
* Without mixin
```dart
import 'package:to_string_helper/to_string_helper.dart';
Expand All @@ -59,6 +70,19 @@ Otherwise, you only need this package.
* `pub run build_runner build`: run a single build and exit.
* `pub run build_runner watch`: continuously run builds as you edit files.
4. Use the generated code to produce output of `toString`
* With mixin
```dart
import 'package:to_string_helper/to_string_helper.dart';
part 'bike.g.dart';
@ToStringMixin()
class Bike with _$BikeToString {
final hasEngine = false;
final wheels = 2;
}
```
* Without mixin
```dart
import 'package:to_string_helper/to_string_helper.dart';
Expand Down Expand Up @@ -212,9 +236,12 @@ Otherwise, you only need this package.
* `Include` in `inclusion` map and `globalInclude` are then merged.
Below is an example how the attribute `nullValue` is merged.
* If `inclusion[Bike].nullValue == null`, use `globalInclude.nullValue`.
* If `globalInclude.nullValue == null`, use the fallback value (see [default configuration](#default-configuration)).
* If `globalInclude.nullValue == null`, use the fallback value
(see [default configuration](#default-configuration)).

# Default configuration
* Configuration of `@ToString` and `@ToStringMixin` is exactly identical.
`@ToStringMixin` generates the same code as `@ToString` and additionally a mixin class.
* The 2 examples below are treated equally:
```dart
@ToString()
Expand All @@ -240,9 +267,11 @@ Otherwise, you only need this package.
* `static`: `false`
* `public`: `true`
* `private`: `false`
* `@ToStringField()`, `@ToStringField(exclude: false)` or `@ToStringField(exclude: null)` are treated equally. It means, force to include the field regardless of configuration in `@ToString()`.
* `@ToStringField()`, `@ToStringField(exclude: false)` or `@ToStringField(exclude: null)` are treated equally.
It means, force to include the field regardless of configuration in `@ToString()`.
* `@ToStringField(exclude: true)`: force to exclude the field regardless of configuration in `@ToString()`.
* `ToStringField.includeNullValue == null` means inheriting `Include.nullValue` from `@ToString()` after merging `globalInclude` and `inclusion`.
* `ToStringField.includeNullValue == null` means inheriting `Include.nullValue` from `@ToString()`
after merging `globalInclude` and `inclusion`.
* `ToStringField.truncate == null` means inheriting `ToString.truncate`.
* `ToStringField.unnamedValue == null` means inheriting `ToString.unnamedValue`.

Expand Down
16 changes: 15 additions & 1 deletion to_string_helper/example/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,22 @@
build_runner: ^1.0.0
to_string_helper_generator: ^1.0.0
```
* `bike.dart` with mixin
```dart
import 'package:to_string_helper/to_string_helper.dart';
* `bike.dart`
part 'bike.g.dart';
// Name of the generated mixin is in format _$<ClassName>ToString
@ToStringMixin()
class Bike with _$BikeToString {
final hasEngine = false;
@ToStringField(exclude: true)
final wheels = 2;
}
```
* `bike.dart` without mixin
```dart
import 'package:to_string_helper/to_string_helper.dart';
Expand Down
19 changes: 19 additions & 0 deletions to_string_helper/lib/src/annotations/to_string_mixin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'include.dart';
import 'to_string.dart';

class ToStringMixin extends ToString {
const ToStringMixin({
Include globalInclude,
Map<Type, Include> inclusion,
String nullString = 'null',
String separator = ', ',
int truncate = 0,
bool unnamedValue = false,
}) : super(
globalInclude: globalInclude,
inclusion: inclusion,
nullString: nullString,
separator: separator,
truncate: truncate,
unnamedValue: unnamedValue);
}
1 change: 1 addition & 0 deletions to_string_helper/lib/to_string_helper.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export 'src/annotations/include.dart';
export 'src/annotations/to_string.dart';
export 'src/annotations/to_string_field.dart';
export 'src/annotations/to_string_mixin.dart';
export 'src/to_string_helper.dart';
4 changes: 2 additions & 2 deletions to_string_helper/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: to_string_helper
version: 1.0.5
description: Flexibly configure output of toString method (with or without code generation).
version: 1.1.0
description: Flexibly configure output of toString method (with or without code generation) (with or without mixin).
homepage: https://github.com/zenonine/to_string_helper
repository: https://github.com/zenonine/to_string_helper/tree/master/to_string_helper

Expand Down

0 comments on commit 4b54af9

Please sign in to comment.