From 8116290b8fc5a470e41f91b81b26873885dce2d8 Mon Sep 17 00:00:00 2001 From: Jacob MacDonald Date: Thu, 1 Jun 2017 10:54:53 -0700 Subject: [PATCH] Add option to do custom code formatting (#147) --- CHANGELOG.md | 6 ++++ lib/src/builder.dart | 13 +++++++-- pubspec.yaml | 2 +- test/builder_test.dart | 36 ++++++++++++++++++++++++ test/src/unformatted_code_generator.dart | 26 +++++++++++++++++ 5 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 test/src/unformatted_code_generator.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 340b7ebc..d4931bb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.5.8 + +* Add `formatOutput` optional parameter to the `GeneratorBuilder` constructor. + This is a lamda of the form `String formatOutput(String originalCode)` which + allows you do do custom formatting. + ## 0.5.7 * Support for package:analyzer 0.30.0 diff --git a/lib/src/builder.dart b/lib/src/builder.dart index e052bde7..83c31ed7 100644 --- a/lib/src/builder.dart +++ b/lib/src/builder.dart @@ -11,13 +11,19 @@ import 'generated_output.dart'; import 'generator.dart'; import 'utils.dart'; +typedef String OutputFormatter(String generatedCode); + class GeneratorBuilder extends Builder { + final OutputFormatter formatOutput; final List generators; final String generatedExtension; final bool isStandalone; GeneratorBuilder(this.generators, - {this.generatedExtension: '.g.dart', this.isStandalone: false}) { + {OutputFormatter formatOutput, + this.generatedExtension: '.g.dart', + this.isStandalone: false}) + : formatOutput = formatOutput ?? _formatter.format { // TODO: validate that generatedExtension starts with a `.' // not null, empty, etc if (this.isStandalone && this.generators.length > 1) { @@ -72,9 +78,8 @@ class GeneratorBuilder extends Builder { var genPartContent = contentBuffer.toString(); - var formatter = new DartFormatter(); try { - genPartContent = formatter.format(genPartContent); + genPartContent = formatOutput(genPartContent); } catch (e, stack) { log.severe( 'Error formatting generated source code for ${library.identifier}' @@ -124,6 +129,8 @@ Stream _processUnitMember( } } +final _formatter = new DartFormatter(); + const _topHeader = '''// GENERATED CODE - DO NOT MODIFY BY HAND '''; diff --git a/pubspec.yaml b/pubspec.yaml index f46da5b5..db379fd5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: source_gen -version: 0.5.7 +version: 0.5.8 author: Dart Team description: Automatic sourcecode generation for Dart homepage: https://github.com/dart-lang/source_gen diff --git a/test/builder_test.dart b/test/builder_test.dart index 69bd05af..8225832e 100644 --- a/test/builder_test.dart +++ b/test/builder_test.dart @@ -11,6 +11,7 @@ import 'package:source_gen/source_gen.dart'; import 'package:test/test.dart'; import 'src/comment_generator.dart'; +import 'src/unformatted_code_generator.dart'; void main() { test('Simple Generator test', _simpleTest); @@ -93,6 +94,41 @@ void main() { '$pkgName|lib/test_lib.g.dart': _testGenPartContentError, }); }); + + test('defaults to formatting generated code with the DartFormatter', + () async { + await testBuilder(new GeneratorBuilder([new UnformattedCodeGenerator()]), + {'$pkgName|lib/a.dart': 'library a; part "a.part.dart";'}, + generateFor: new Set.from(['$pkgName|lib/a.dart']), + outputs: { + '$pkgName|lib/a.g.dart': + contains(UnformattedCodeGenerator.formattedCode), + }); + }); + + test('can skip formatting with a trivial lambda', () async { + await testBuilder( + new GeneratorBuilder([new UnformattedCodeGenerator()], + formatOutput: (s) => s), + {'$pkgName|lib/a.dart': 'library a; part "a.part.dart";'}, + generateFor: new Set.from(['$pkgName|lib/a.dart']), + outputs: { + '$pkgName|lib/a.g.dart': + contains(UnformattedCodeGenerator.unformattedCode), + }); + }); + + test('can pass a custom formatter with formatOutput', () async { + var customOutput = 'final String hello = "hello";'; + await testBuilder( + new GeneratorBuilder([new UnformattedCodeGenerator()], + formatOutput: (_) => customOutput), + {'$pkgName|lib/a.dart': 'library a; part "a.part.dart";'}, + generateFor: new Set.from(['$pkgName|lib/a.dart']), + outputs: { + '$pkgName|lib/a.g.dart': contains(customOutput), + }); + }); } Future _simpleTest() => _generateTest( diff --git a/test/src/unformatted_code_generator.dart b/test/src/unformatted_code_generator.dart new file mode 100644 index 00000000..b37e75af --- /dev/null +++ b/test/src/unformatted_code_generator.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:analyzer/dart/element/element.dart'; +import 'package:source_gen/source_gen.dart'; + +/// Generates a single-line of unformatted code. +class UnformattedCodeGenerator extends Generator { + const UnformattedCodeGenerator(); + + @override + Future generate(Element element, _) async { + return unformattedCode; + } + + static const formattedCode = ''' +void hello() => print('hello'); +'''; + + static const unformattedCode = ''' +void hello ()=> print('hello'); +'''; +}