From 47c06610b7a1fc1a1cae750bf51e027a26058f68 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 14 Nov 2016 15:48:24 -0800 Subject: [PATCH 1/7] Various changes. --- analysis_options.yaml => .analysis_options | 19 +-- CHANGELOG.md | 9 ++ lib/code_builder.dart | 5 +- lib/dart/async.dart | 6 + lib/dart/core.dart | 5 + lib/src/builders/expression.dart | 153 +++++++++++++++++--- lib/src/builders/expression/assert.dart | 4 + lib/src/builders/expression/assign.dart | 4 + lib/src/builders/expression/invocation.dart | 4 + lib/src/builders/expression/negate.dart | 4 + lib/src/builders/expression/operators.dart | 4 + lib/src/builders/expression/return.dart | 4 + lib/src/builders/field.dart | 4 + lib/src/builders/file.dart | 103 ++++++++++++- lib/src/builders/statement/block.dart | 4 + lib/src/builders/statement/if.dart | 4 + lib/src/builders/type/new_instance.dart | 4 + lib/src/tokens.dart | 9 ++ test/builders/expression_test.dart | 23 +++ test/builders/field_test.dart | 4 + test/builders/file_test.dart | 62 ++++++++ test/builders/reference_test.dart | 9 -- test/builders/shared_test.dart | 4 + test/builders/statement_test.dart | 4 + test/builders/type_test.dart | 4 + test/scope_test.dart | 4 + 26 files changed, 415 insertions(+), 48 deletions(-) rename analysis_options.yaml => .analysis_options (67%) create mode 100644 test/builders/file_test.dart delete mode 100644 test/builders/reference_test.dart diff --git a/analysis_options.yaml b/.analysis_options similarity index 67% rename from analysis_options.yaml rename to .analysis_options index b256a69..6f04432 100644 --- a/analysis_options.yaml +++ b/.analysis_options @@ -2,32 +2,27 @@ analyzer: strong-mode: true linter: rules: + # Errors - avoid_empty_else - - comment_references - control_flow_in_finally - empty_statements - - hash_and_equals - - iterable_contains_unrelated_type - - list_remove_unrelated_type - test_types_in_equals - throw_in_finally - - unrelated_type_equality_checks - valid_regexps - - always_declare_return_types + + # Style - annotate_overrides - avoid_init_to_null - avoid_return_types_on_setters - await_only_futures - camel_case_types - - constant_identifier_names + - comment_references - empty_catches - empty_constructor_bodies - - library_names + - hash_and_equals - library_prefixes - - only_throw_errors - - overridden_fields - - package_prefixed_library_names + - non_constant_identifier_names - prefer_is_not_empty - slash_for_doc_comments - type_init_formals - - unnecessary_getters_setters + - unrelated_type_equality_checks diff --git a/CHANGELOG.md b/CHANGELOG.md index ffc86f3..c2ed69b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.0.0-alpha+1 + +- Slight updates to confusing documentation. +- Added support for null-aware assignments. +- Added `show` and `hide` support to `ImportBuilder` +- Added `deferred` support to `ImportBuilder` +- Added `ExportBuilder` +- Added `list` and `map` literals that support generic types + ## 1.0.0-alpha - Large refactor that makes the library more feature complete. diff --git a/lib/code_builder.dart b/lib/code_builder.dart index 9506468..abc1430 100644 --- a/lib/code_builder.dart +++ b/lib/code_builder.dart @@ -6,10 +6,11 @@ export 'src/builders/annotation.dart' show AnnotationBuilder; export 'src/builders/class.dart' show asStatic, clazz, extend, implement, mixin, ClassBuilder; export 'src/builders/expression.dart' - show literal, ExpressionBuilder, InvocationBuilder; + show literal, list, map, ExpressionBuilder, InvocationBuilder; export 'src/builders/field.dart' show varConst, varField, varFinal, FieldBuilder; -export 'src/builders/file.dart' show ImportBuilder, LibraryBuilder, PartBuilder; +export 'src/builders/file.dart' + show ExportBuilder, ImportBuilder, LibraryBuilder, PartBuilder; export 'src/builders/method.dart' show constructor, diff --git a/lib/dart/async.dart b/lib/dart/async.dart index 6025c39..68d0b27 100644 --- a/lib/dart/async.dart +++ b/lib/dart/async.dart @@ -35,6 +35,12 @@ class DartAsync { /// References [dart_async.Future]. final ReferenceBuilder Future = _ref('Future'); + /// References [dart_async.Stream]. + final ReferenceBuilder Stream = _ref('Stream'); + + /// References [dart_async.StreamSubscription]. + final ReferenceBuilder StreamSubscription = _ref('StreamSubscription'); + DartAsync._(); static ReferenceBuilder _ref(String name) => reference(name, 'dart:async'); diff --git a/lib/dart/core.dart b/lib/dart/core.dart index 9a5a0d7..fbbe89f 100644 --- a/lib/dart/core.dart +++ b/lib/dart/core.dart @@ -213,6 +213,11 @@ class DartCore { /// References [dart_core.UriData]. final ReferenceBuilder UriData = _ref('UriData'); + /// References `dynamic` type for returning any in a method. + /// + /// **NOTE**: As a language limitation, this cannot be named `dynamic`. + final TypeBuilder $dynamic = new TypeBuilder('dynamic'); + /// References `void` type for returning nothing in a method. /// /// **NOTE**: As a language limitation, this cannot be named `void`. diff --git a/lib/src/builders/expression.dart b/lib/src/builders/expression.dart index faa78c7..4bd6439 100644 --- a/lib/src/builders/expression.dart +++ b/lib/src/builders/expression.dart @@ -1,8 +1,7 @@ -library code_builder.src.builders.expression; - // Copyright (c) 2016, 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. +library code_builder.src.builders.expression; import 'package:analyzer/analyzer.dart'; import 'package:analyzer/dart/ast/token.dart'; @@ -32,7 +31,37 @@ final _true = new BooleanLiteral(new KeywordToken(Keyword.TRUE, 0), true); /// Returns a pre-defined literal expression of [value]. /// /// Only primitive values are allowed. -ExpressionBuilder literal(value) => new _LiteralExpression(_literal(value)); +ExpressionBuilder literal(value) { + if (value is List) { + return list(value); + } + if (value is Map) { + return map(value); + } + return new _LiteralExpression(_literal(value)); +} + +/// Returns a literal `List` expression from [values]. +/// +/// Optionally specify [asConst] or with a generic [type]. +ExpressionBuilder list( + Iterable values, { + bool asConst: false, + TypeBuilder type, +}) => + new _TypedListExpression(values, asConst: asConst, type: type); + +/// Returns a literal `Map` expression from [values]. +/// +/// Optionally specify [asConst] or with a generic [keyType] or [valueType]. +ExpressionBuilder map( + Map values, { + bool asConst: false, + TypeBuilder keyType, + TypeBuilder valueType, +}) => + new _TypedMapExpression(values, + asConst: asConst, keyType: keyType, valueType: valueType); Literal _literal(value) { if (value == null) { @@ -45,24 +74,6 @@ Literal _literal(value) { return new IntegerLiteral(stringToken('$value'), value); } else if (value is double) { return new DoubleLiteral(stringToken('$value'), value); - } else if (value is List) { - return new ListLiteral( - null, - null, - $openBracket, - value.map/**/(_literal).toList(), - $closeBracket, - ); - } else if (value is Map) { - return new MapLiteral( - null, - null, - $openBracket, - value.keys.map/**/((k) { - return new MapLiteralEntry(_literal(k), $colon, _literal(value[k])); - }).toList(), - $closeBracket, - ); } throw new ArgumentError.value(value, 'Unsupported'); } @@ -357,3 +368,103 @@ class _ParenthesesExpression extends Object with AbstractExpressionMixin { ); } } + +ExpressionBuilder _expressionify(v) { + if (v == null || v is bool || v is String || v is int || v is double) { + return new _LiteralExpression(_literal(v)); + } + if (v is ExpressionBuilder) { + return v; + } + throw new ArgumentError('Could not expressionify $v'); +} + +class _TypedListExpression extends Object with AbstractExpressionMixin { + static List _toExpression(Iterable values) { + return values.map(_expressionify).toList(); + } + + final bool _asConst; + final TypeBuilder _type; + final List _values; + + _TypedListExpression(Iterable values, {bool asConst, TypeBuilder type}) + : _values = _toExpression(values), + _asConst = asConst, + _type = type; + + @override + AstNode buildAst([Scope scope]) => buildExpression(scope); + + @override + Expression buildExpression([Scope scope]) { + return new ListLiteral( + _asConst ? $const : null, + _type != null + ? new TypeArgumentList( + $openBracket, + [_type.buildType(scope)], + $closeBracket, + ) + : null, + $openBracket, + _values.map((v) => v.buildExpression(scope)).toList(), + $closeBracket, + ); + } +} + +class _TypedMapExpression extends Object with AbstractExpressionMixin { + static Map _toExpression(Map values) { + return new Map.fromIterable( + values.keys, + key: (k) => _expressionify(k), + value: (k) => _expressionify(values[k]), + ); + } + + final bool _asConst; + final TypeBuilder _keyType; + final TypeBuilder _valueType; + final Map _values; + + _TypedMapExpression(Map values, + {bool asConst, TypeBuilder keyType, TypeBuilder valueType}) + : _values = _toExpression(values), + _asConst = asConst, + _keyType = keyType != null + ? keyType + : valueType != null ? lib$core.$dynamic : null, + _valueType = valueType != null + ? valueType + : keyType != null ? lib$core.$dynamic : null; + + @override + AstNode buildAst([Scope scope]) => buildExpression(scope); + + @override + Expression buildExpression([Scope scope]) { + return new MapLiteral( + _asConst ? $const : null, + _keyType != null + ? new TypeArgumentList( + $openBracket, + [ + _keyType.buildType(scope), + _valueType.buildType(scope), + ], + $closeBracket, + ) + : null, + $openBracket, + _values.keys.map((k) { + return new MapLiteralEntry( + k.buildExpression(scope), + $colon, + _values[k].buildExpression(scope), + ); + }).toList(), + $closeBracket, + ); + } +} diff --git a/lib/src/builders/expression/assert.dart b/lib/src/builders/expression/assert.dart index 3313fee..3030235 100644 --- a/lib/src/builders/expression/assert.dart +++ b/lib/src/builders/expression/assert.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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. + part of code_builder.src.builders.expression; class _AsAssert implements StatementBuilder { diff --git a/lib/src/builders/expression/assign.dart b/lib/src/builders/expression/assign.dart index 5c6b191..00bf017 100644 --- a/lib/src/builders/expression/assign.dart +++ b/lib/src/builders/expression/assign.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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. + part of code_builder.src.builders.expression; class _AsAssign extends AbstractExpressionMixin { diff --git a/lib/src/builders/expression/invocation.dart b/lib/src/builders/expression/invocation.dart index 1c015e6..cef1e32 100644 --- a/lib/src/builders/expression/invocation.dart +++ b/lib/src/builders/expression/invocation.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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. + part of code_builder.src.builders.expression; /// Partial implementation of [InvocationBuilder]. diff --git a/lib/src/builders/expression/negate.dart b/lib/src/builders/expression/negate.dart index d1d58d3..e5fa834 100644 --- a/lib/src/builders/expression/negate.dart +++ b/lib/src/builders/expression/negate.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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. + part of code_builder.src.builders.expression; class _NegateExpression extends AbstractExpressionMixin { diff --git a/lib/src/builders/expression/operators.dart b/lib/src/builders/expression/operators.dart index f36140a..cebc852 100644 --- a/lib/src/builders/expression/operators.dart +++ b/lib/src/builders/expression/operators.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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. + part of code_builder.src.builders.expression; class _AsBinaryExpression extends Object with AbstractExpressionMixin { diff --git a/lib/src/builders/expression/return.dart b/lib/src/builders/expression/return.dart index d57c7de..0778b0f 100644 --- a/lib/src/builders/expression/return.dart +++ b/lib/src/builders/expression/return.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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. + part of code_builder.src.builders.expression; class _AsReturn implements StatementBuilder { diff --git a/lib/src/builders/field.dart b/lib/src/builders/field.dart index 51b5d97..16e10fc 100644 --- a/lib/src/builders/field.dart +++ b/lib/src/builders/field.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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 'package:analyzer/analyzer.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/src/dart/ast/token.dart'; diff --git a/lib/src/builders/file.dart b/lib/src/builders/file.dart index fc6e71b..ce580f4 100644 --- a/lib/src/builders/file.dart +++ b/lib/src/builders/file.dart @@ -131,25 +131,120 @@ class _LibraryDirectiveBuilder implements AstBuilder { class ImportBuilder implements AstBuilder { final String _prefix; final String _uri; + final bool _deferred; - factory ImportBuilder(String path, {String prefix}) { - return new ImportBuilder._(path, prefix); + final Set _show = new Set(); + final Set _hide = new Set(); + + factory ImportBuilder(String path, {bool deferred: false, String prefix}) { + return new ImportBuilder._(path, prefix, deferred); + } + + ImportBuilder._(this._uri, this._prefix, this._deferred); + + void hide(String identifier) { + _hide.add(identifier); } - ImportBuilder._(this._uri, this._prefix); + void hideAll(Iterable identifiers) { + _hide.addAll(identifiers); + } + + void show(String identifier) { + _show.add(identifier); + } + + void showAll(Iterable identifier) { + _show.addAll(identifier); + } @override ImportDirective buildAst([_]) { + var combinators = []; + if (_show.isNotEmpty) { + combinators.add( + new ShowCombinator( + $show, + _show.map(stringIdentifier).toList(), + ), + ); + } + if (_hide.isNotEmpty) { + combinators.add( + new HideCombinator( + $hide, + _hide.map(stringIdentifier).toList(), + ), + ); + } return new ImportDirective( null, null, null, new SimpleStringLiteral(stringToken("'$_uri'"), _uri), null, - null, + _deferred ? $deferred : null, _prefix != null ? $as : null, _prefix != null ? stringIdentifier(_prefix) : null, + combinators, + $semicolon, + ); + } +} + +/// Lazily builds an [ExportDirective] AST when built. +class ExportBuilder implements AstBuilder { + final String _uri; + + final Set _show = new Set(); + final Set _hide = new Set(); + + factory ExportBuilder(String path) = ExportBuilder._; + + ExportBuilder._(this._uri); + + void hide(String identifier) { + _hide.add(identifier); + } + + void hideAll(Iterable identifiers) { + _hide.addAll(identifiers); + } + + void show(String identifier) { + _show.add(identifier); + } + + void showAll(Iterable identifier) { + _show.addAll(identifier); + } + + @override + ExportDirective buildAst([_]) { + var combinators = []; + if (_show.isNotEmpty) { + combinators.add( + new ShowCombinator( + $show, + _show.map(stringIdentifier).toList(), + ), + ); + } + if (_hide.isNotEmpty) { + combinators.add( + new HideCombinator( + $hide, + _hide.map(stringIdentifier).toList(), + ), + ); + } + return new ExportDirective( + null, + null, + null, + new SimpleStringLiteral(stringToken("'$_uri'"), _uri), null, + combinators, $semicolon, ); } diff --git a/lib/src/builders/statement/block.dart b/lib/src/builders/statement/block.dart index 57ef9eb..f3f8e69 100644 --- a/lib/src/builders/statement/block.dart +++ b/lib/src/builders/statement/block.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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 'package:analyzer/analyzer.dart'; import 'package:code_builder/src/builders/shared.dart'; import 'package:code_builder/src/builders/statement.dart'; diff --git a/lib/src/builders/statement/if.dart b/lib/src/builders/statement/if.dart index ad3b9a9..768c8d2 100644 --- a/lib/src/builders/statement/if.dart +++ b/lib/src/builders/statement/if.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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 'package:analyzer/dart/ast/ast.dart'; import 'package:code_builder/src/builders/expression.dart'; import 'package:code_builder/src/builders/shared.dart'; diff --git a/lib/src/builders/type/new_instance.dart b/lib/src/builders/type/new_instance.dart index c2d9b68..05b9b9d 100644 --- a/lib/src/builders/type/new_instance.dart +++ b/lib/src/builders/type/new_instance.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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. + part of code_builder.src.builders.type; /// Lazily builds an [InstanceCreationExpression] AST when built. diff --git a/lib/src/tokens.dart b/lib/src/tokens.dart index 17e70b5..9b97264 100644 --- a/lib/src/tokens.dart +++ b/lib/src/tokens.dart @@ -35,6 +35,9 @@ final Token $colon = new Token(TokenType.COLON, 0); /// The `const` token. final Token $const = new KeywordToken(Keyword.CONST, 0); +/// The `deferred` token. +final Token $deferred = new KeywordToken(Keyword.DEFERRED, 0); + /// The `/` token. final Token $divide = new Token(TokenType.SLASH, 0); @@ -64,6 +67,9 @@ final Token $if = new KeywordToken(Keyword.IF, 0); // Simple tokens +/// The `hide` token. +final Token $hide = new StringToken(TokenType.KEYWORD, 'hide', 0); + /// The `implements` token. final Token $implements = new KeywordToken(Keyword.IMPLEMENTS, 0); @@ -121,6 +127,9 @@ final Token $return = new KeywordToken(Keyword.RETURN, 0); /// The ';' token. final Token $semicolon = new Token(TokenType.SEMICOLON, 0); +/// The `show` token. +final Token $show = new StringToken(TokenType.KEYWORD, 'show', 0); + /// The `static` token. final Token $static = new KeywordToken(Keyword.STATIC, 0); diff --git a/test/builders/expression_test.dart b/test/builders/expression_test.dart index 5d6b453..78f5198 100644 --- a/test/builders/expression_test.dart +++ b/test/builders/expression_test.dart @@ -37,9 +37,32 @@ void main() { expect(literal([1, 2, 3]), equalsSource(r'[1, 2, 3]')); }); + test('should emit a typed list', () { + expect( + list([1, 2, 3], type: lib$core.int), + equalsSource(r' [1, 2, 3]'), + ); + }); + test('should emit a map', () { expect(literal({1: 2, 2: 3}), equalsSource(r'{1 : 2, 2 : 3}')); }); + + test('should emit a typed map', () { + expect( + map( + { + 1: '2', + 2: '3', + }, + keyType: lib$core.int, + valueType: lib$core.String, + ), + equalsSource(r''' + {1 : '2', 2 : '3'} + '''), + ); + }); }); test('should emit an assert statemnet', () { diff --git a/test/builders/field_test.dart b/test/builders/field_test.dart index fcadb66..739e7a7 100644 --- a/test/builders/field_test.dart +++ b/test/builders/field_test.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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 'package:code_builder/code_builder.dart'; import 'package:code_builder/dart/core.dart'; import 'package:code_builder/testing.dart'; diff --git a/test/builders/file_test.dart b/test/builders/file_test.dart new file mode 100644 index 0000000..f9f258c --- /dev/null +++ b/test/builders/file_test.dart @@ -0,0 +1,62 @@ +// Copyright (c) 2016, 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 'package:code_builder/code_builder.dart'; +import 'package:code_builder/testing.dart'; +import 'package:test/test.dart'; + +void main() { + group('$ImportBuilder', () { + test('should support "show"', () { + expect( + new ImportBuilder('package:foo/foo.dart')..show('Foo'), + equalsSource(r''' + import 'package:foo/foo.dart' show Foo; + '''), + ); + }); + + test('should support "show"', () { + expect( + new ImportBuilder('package:foo/foo.dart')..hide('Bar'), + equalsSource(r''' + import 'package:foo/foo.dart' hide Bar; + '''), + ); + }); + + test('should support "deferred as"', () { + expect( + new ImportBuilder( + 'package:foo/foo.dart', + deferred: true, + prefix: 'foo', + ), + equalsSource(r''' + import 'package:foo/foo.dart' deferred as foo; + '''), + ); + }); + }); + + group('$ExportBuilder', () { + test('should support "show"', () { + expect( + new ExportBuilder('package:foo/foo.dart')..show('Foo'), + equalsSource(r''' + export 'package:foo/foo.dart' show Foo; + '''), + ); + }); + + test('should support "show"', () { + expect( + new ExportBuilder('package:foo/foo.dart')..hide('Bar'), + equalsSource(r''' + export 'package:foo/foo.dart' hide Bar; + '''), + ); + }); + }); +} diff --git a/test/builders/reference_test.dart b/test/builders/reference_test.dart deleted file mode 100644 index f25ae74..0000000 --- a/test/builders/reference_test.dart +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2016, 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 'package:test/test.dart'; - -void main() { - group('reference', () {}); -} diff --git a/test/builders/shared_test.dart b/test/builders/shared_test.dart index a38a062..12a314f 100644 --- a/test/builders/shared_test.dart +++ b/test/builders/shared_test.dart @@ -2,6 +2,10 @@ // 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. +// Copyright (c) 2016, 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 'package:code_builder/src/builders/shared.dart'; import 'package:code_builder/src/tokens.dart'; import 'package:test/test.dart'; diff --git a/test/builders/statement_test.dart b/test/builders/statement_test.dart index b899c85..5833a7e 100644 --- a/test/builders/statement_test.dart +++ b/test/builders/statement_test.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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 'package:code_builder/code_builder.dart'; import 'package:code_builder/dart/core.dart'; import 'package:code_builder/testing.dart'; diff --git a/test/builders/type_test.dart b/test/builders/type_test.dart index b9ac7b8..323f972 100644 --- a/test/builders/type_test.dart +++ b/test/builders/type_test.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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 'package:code_builder/code_builder.dart'; import 'package:code_builder/dart/core.dart'; import 'package:code_builder/testing.dart'; diff --git a/test/scope_test.dart b/test/scope_test.dart index 64b41d5..084d7af 100644 --- a/test/scope_test.dart +++ b/test/scope_test.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2016, 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 'package:analyzer/analyzer.dart'; import 'package:code_builder/src/scope.dart'; import 'package:test/test.dart'; From 6bdb6a9af958077a4479e99fdf5d0df5e1b351ae Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 14 Nov 2016 15:53:18 -0800 Subject: [PATCH 2/7] Update presubmit. --- tool/presubmit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tool/presubmit.sh b/tool/presubmit.sh index 035e29e..364bee7 100755 --- a/tool/presubmit.sh +++ b/tool/presubmit.sh @@ -14,7 +14,7 @@ echo "PASSED" # Make sure we pass the analyzer echo "Checking dartanalyzer..." -FAILS_ANALYZER="$(find lib test -name "*.dart" | xargs dartanalyzer --options analysis_options.yaml)" +FAILS_ANALYZER="$(find lib test -name "*.dart" | xargs dartanalyzer --options .analysis_options)" if [[ $FAILS_ANALYZER == *"[error]"* ]] then echo "FAILED" From 6d53a9d77f4a2a436b2e60fac9d9468697a1c22b Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 12 Dec 2016 22:37:33 -0800 Subject: [PATCH 3/7] Add async, await, yield --- lib/code_builder.dart | 1 + lib/src/builders/expression.dart | 27 +++++++- lib/src/builders/expression/await.dart | 22 +++++++ lib/src/builders/expression/yield.dart | 25 ++++++++ lib/src/builders/method.dart | 86 +++++++++++++++++++++----- lib/src/tokens.dart | 12 ++++ test/builders/expression_test.dart | 27 ++++++++ test/builders/method_test.dart | 43 +++++++++++-- 8 files changed, 220 insertions(+), 23 deletions(-) create mode 100644 lib/src/builders/expression/await.dart create mode 100644 lib/src/builders/expression/yield.dart diff --git a/lib/code_builder.dart b/lib/code_builder.dart index 283898c..ed6494e 100644 --- a/lib/code_builder.dart +++ b/lib/code_builder.dart @@ -23,6 +23,7 @@ export 'src/builders/method.dart' named, ConstructorBuilder, MethodBuilder, + MethodModifier, ValidMethodMember; export 'src/builders/parameter.dart' show parameter, ParameterBuilder; export 'src/pretty_printer.dart' show prettyToSource; diff --git a/lib/src/builders/expression.dart b/lib/src/builders/expression.dart index f5fda5f..a73c65d 100644 --- a/lib/src/builders/expression.dart +++ b/lib/src/builders/expression.dart @@ -18,11 +18,13 @@ import 'package:code_builder/src/tokens.dart'; part 'expression/assert.dart'; part 'expression/assign.dart'; +part 'expression/await.dart'; part 'expression/cascade.dart'; part 'expression/invocation.dart'; part 'expression/negate.dart'; part 'expression/operators.dart'; part 'expression/return.dart'; +part 'expression/yield.dart'; final _false = new BooleanLiteral(new KeywordToken(Keyword.FALSE, 0), true); @@ -138,6 +140,9 @@ abstract class AbstractExpressionMixin implements ExpressionBuilder { }) => new _AsAssign(this, variable, nullAware, target); + @override + ExpressionBuilder asAwait() => new _AsAwait(this); + @override StatementBuilder asConst(String variable, [TypeBuilder type]) { return new _AsAssignNew(this, variable, type, $const); @@ -162,6 +167,12 @@ abstract class AbstractExpressionMixin implements ExpressionBuilder { return new _AsAssignNew(this, variable, type, $var); } + @override + StatementBuilder asYield() => new _AsYield(this, false); + + @override + StatementBuilder asYieldStar() => new _AsYield(this, true); + @override Statement buildStatement([Scope scope]) { return asStatement().buildStatement(scope); @@ -270,8 +281,14 @@ abstract class ExpressionBuilder /// Returns as a [StatementBuilder] that assigns to an existing [variable]. /// /// If [target] is specified, determined to be `{target}.{variable}`. - StatementBuilder asAssign(String variable, - {ExpressionBuilder target, bool nullAware}); + StatementBuilder asAssign( + String variable, { + ExpressionBuilder target, + bool nullAware, + }); + + /// Returns as an expression `await`-ing this one. + ExpressionBuilder asAwait() => new _AsAwait(this); /// Returns as a [StatementBuilder] that assigns to a new `const` [variable]. StatementBuilder asConst(String variable, [TypeBuilder type]); @@ -297,6 +314,12 @@ abstract class ExpressionBuilder /// If [type] is supplied, the resulting statement is `{type} {variable} =`. StatementBuilder asVar(String variable, [TypeBuilder type]); + /// Returns as a [StatementBuilder] yielding this one. + StatementBuilder asYield(); + + /// Returns as a [StatementBuilder] yielding this one. + StatementBuilder asYieldStar(); + /// Returns an [Expression] AST representing the builder. Expression buildExpression([Scope scope]); diff --git a/lib/src/builders/expression/await.dart b/lib/src/builders/expression/await.dart new file mode 100644 index 0000000..5b15fab --- /dev/null +++ b/lib/src/builders/expression/await.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2016, 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. + +part of code_builder.src.builders.expression; + +class _AsAwait extends AbstractExpressionMixin with TopLevelMixin { + final ExpressionBuilder _expression; + + _AsAwait(this._expression); + + @override + AstNode buildAst([Scope scope]) => buildExpression(scope); + + @override + Expression buildExpression([Scope scope]) { + return new AwaitExpression( + $await, + _expression.buildExpression(scope), + ); + } +} diff --git a/lib/src/builders/expression/yield.dart b/lib/src/builders/expression/yield.dart new file mode 100644 index 0000000..9874261 --- /dev/null +++ b/lib/src/builders/expression/yield.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2016, 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. + +part of code_builder.src.builders.expression; + +class _AsYield extends TopLevelMixin implements StatementBuilder { + final ExpressionBuilder _expression; + final bool _isStar; + + _AsYield(this._expression, this._isStar); + + @override + Statement buildAst([Scope scope]) => buildStatement(scope); + + @override + Statement buildStatement([Scope scope]) { + return new YieldStatement( + $yield, + _isStar ? $star : null, + _expression.buildExpression(scope), + $semicolon, + ); + } +} diff --git a/lib/src/builders/method.dart b/lib/src/builders/method.dart index e4660ee..1335ee3 100644 --- a/lib/src/builders/method.dart +++ b/lib/src/builders/method.dart @@ -17,20 +17,42 @@ import 'package:code_builder/src/builders/type.dart'; import 'package:code_builder/src/tokens.dart'; /// Short-hand for `new ConstructorBuilder(...)`. -ConstructorBuilder constructor( - [Iterable members = const []]) { +ConstructorBuilder constructor([ + Iterable members = const [], +]) { return _constructorImpl(members: members); } /// Short-hand for `new ConstructorBuilder(name)`. -ConstructorBuilder constructorNamed(String name, - [Iterable members = const []]) { +ConstructorBuilder constructorNamed( + String name, [ + Iterable members = const [], +]) { return _constructorImpl(name: name, members: members); } +/// Various types of modifiers for methods. +class MethodModifier implements ValidMethodMember { + static const MethodModifier async = const MethodModifier._('async', false); + static const MethodModifier asyncStar = const MethodModifier._('async', true); + static const MethodModifier syncStar = const MethodModifier._('sync', true); + + final String _keyword; + + const MethodModifier._(this._keyword, this.isStar); + + @override + buildAst([_]) => throw new UnsupportedError('Not an AST'); + + final bool isStar; + + Token keyword() => new StringToken(TokenType.KEYWORD, _keyword, 0); +} + /// Short-hand for `new MethodBuilder.getter(...)`. MethodBuilder getter( String name, { + MethodModifier modifier, Iterable statements, ExpressionBuilder returns, TypeBuilder returnType, @@ -38,12 +60,14 @@ MethodBuilder getter( if (returns != null) { return new MethodBuilder.getter( name, + modifier: modifier, returnType: returnType, returns: returns, ); } else { return new MethodBuilder.getter( name, + modifier: modifier, returnType: returnType, )..addStatements(statements); } @@ -53,9 +77,15 @@ MethodBuilder getter( MethodBuilder lambda( String name, ExpressionBuilder value, { + MethodModifier modifier, TypeBuilder returnType, }) { - return new MethodBuilder(name, returns: value, returnType: returnType); + return new MethodBuilder( + name, + modifier: modifier, + returns: value, + returnType: returnType, + ); } /// A more short-hand way of constructing a [MethodBuilder]. @@ -66,6 +96,7 @@ MethodBuilder method( final List positional = []; final List<_NamedParameterWrapper> named = <_NamedParameterWrapper>[]; final List statements = []; + MethodModifier modifier; TypeBuilder returnType; for (final member in members) { if (member is TypeBuilder) { @@ -76,12 +107,15 @@ MethodBuilder method( named.add(member); } else if (member is StatementBuilder) { statements.add(member); + } else if (member is MethodModifier) { + modifier = member; } else { throw new StateError('Invalid AST type: ${member.runtimeType}'); } } final method = new _MethodBuilderImpl( name, + modifier: modifier, returns: returnType, ); positional.forEach(method.addPositional); @@ -160,8 +194,10 @@ abstract class ConstructorBuilder void addPositional(ParameterBuilder parameter, {bool asField: false}); /// Returns an [ConstructorDeclaration] AST representing the builder. - ConstructorDeclaration buildConstructor(TypeBuilder returnType, - [Scope scope]); + ConstructorDeclaration buildConstructor( + TypeBuilder returnType, [ + Scope scope, + ]); } /// Lazily builds a method/function AST when the builder is invoked. @@ -175,6 +211,7 @@ abstract class MethodBuilder /// Creates a new [MethodBuilder]. factory MethodBuilder( String name, { + MethodModifier modifier, ExpressionBuilder returns, TypeBuilder returnType, }) { @@ -184,10 +221,12 @@ abstract class MethodBuilder returns, returnType, null, + modifier, ); } else { return new _MethodBuilderImpl( name, + modifier: modifier, returns: returnType, ); } @@ -195,6 +234,7 @@ abstract class MethodBuilder /// Creates a new [MethodBuilder] that returns an anonymous closure. factory MethodBuilder.closure({ + MethodModifier modifier, ExpressionBuilder returns, TypeBuilder returnType, }) { @@ -204,10 +244,12 @@ abstract class MethodBuilder returns, returnType, null, + modifier, ); } else { return new _MethodBuilderImpl( null, + modifier: modifier, returns: returnType, ); } @@ -216,12 +258,14 @@ abstract class MethodBuilder /// Creates a getter. factory MethodBuilder.getter( String name, { + MethodModifier modifier, TypeBuilder returnType, ExpressionBuilder returns, }) { if (returns == null) { return new _MethodBuilderImpl( name, + modifier: modifier, returns: returnType, property: Keyword.GET, ); @@ -231,6 +275,7 @@ abstract class MethodBuilder returns, returnType, Keyword.GET, + modifier, ); } } @@ -245,6 +290,7 @@ abstract class MethodBuilder returns, lib$core.$void, null, + null, ); } @@ -264,6 +310,7 @@ abstract class MethodBuilder returns, null, Keyword.SET, + null, ); } } @@ -299,12 +346,18 @@ class _LambdaMethodBuilder extends Object TopLevelMixin implements MethodBuilder { final ExpressionBuilder _expression; + final MethodModifier _modifier; final String _name; final TypeBuilder _returnType; final Keyword _property; _LambdaMethodBuilder( - this._name, this._expression, this._returnType, this._property); + this._name, + this._expression, + this._returnType, + this._property, + this._modifier, + ); @override void addStatement(StatementBuilder statement) { @@ -334,7 +387,7 @@ class _LambdaMethodBuilder extends Object null, _property != Keyword.GET ? buildParameterList(scope) : null, new ExpressionFunctionBody( - null, + _modifier?.keyword(), null, _expression.buildExpression(scope), isStatement ? $semicolon : null, @@ -369,7 +422,7 @@ class _LambdaMethodBuilder extends Object null, _property != Keyword.GET ? buildParameterList(scope) : null, new ExpressionFunctionBody( - null, + _modifier?.keyword(), null, _expression.buildExpression(scope), $semicolon, @@ -389,16 +442,19 @@ class _MethodBuilderImpl extends Object HasStatementsMixin, TopLevelMixin implements MethodBuilder { + final MethodModifier _modifier; final String _name; final TypeBuilder _returnType; final Keyword _property; _MethodBuilderImpl( this._name, { + MethodModifier modifier, TypeBuilder returns, Keyword property, }) - : _returnType = returns, + : _modifier = modifier, + _returnType = returns, _property = property; @override @@ -415,8 +471,8 @@ class _MethodBuilderImpl extends Object null, _property != Keyword.GET ? buildParameterList(scope) : null, new BlockFunctionBody( - null, - null, + _modifier?.keyword(), + _modifier?.isStar == true ? $star : null, buildBlock(scope), ), ); @@ -449,8 +505,8 @@ class _MethodBuilderImpl extends Object null, _property != Keyword.GET ? buildParameterList(scope) : null, new BlockFunctionBody( - null, - null, + _modifier?.keyword(), + _modifier?.isStar == true ? $star : null, buildBlock(scope), ), ); diff --git a/lib/src/tokens.dart b/lib/src/tokens.dart index 883e2c2..01b42da 100644 --- a/lib/src/tokens.dart +++ b/lib/src/tokens.dart @@ -14,9 +14,15 @@ final Token $as = new KeywordToken(Keyword.AS, 0); /// The `assert` token. final Token $assert = new KeywordToken(Keyword.ASSERT, 0); +/// The `async` token. +final Token $async = new StringToken(TokenType.KEYWORD, 'async', 0); + /// The `@` token. final Token $at = new Token(TokenType.AT, 0); +/// The `await` token. +final Token $await = new StringToken(TokenType.KEYWORD, 'await', 0); + /// The `class` token. final Token $class = new KeywordToken(Keyword.CLASS, 0); @@ -65,11 +71,17 @@ final Token $gt = new Token(TokenType.GT, 0); /// The `if` token. final Token $if = new KeywordToken(Keyword.IF, 0); +/// The `yield` token. +final Token $yield = new StringToken(TokenType.KEYWORD, 'yield', 0); + // Simple tokens /// The `&&` token. final Token $and = new Token(TokenType.AMPERSAND_AMPERSAND, 0); +/// The `*` token. +final Token $star = $multiply; + /// The `hide` token. final Token $hide = new StringToken(TokenType.KEYWORD, 'hide', 0); diff --git a/test/builders/expression_test.dart b/test/builders/expression_test.dart index 2fa687b..36f477e 100644 --- a/test/builders/expression_test.dart +++ b/test/builders/expression_test.dart @@ -294,4 +294,31 @@ void main() { '''), ); }); + + test('should emit await', () { + expect( + reference('foo').asAwait(), + equalsSource(r''' + await foo + '''), + ); + }); + + test('should emit yield', () { + expect( + reference('foo').asYield(), + equalsSource(r''' + yield foo; + '''), + ); + }); + + test('should emit yield*', () { + expect( + reference('foo').asYieldStar(), + equalsSource(r''' + yield* foo; + '''), + ); + }); } diff --git a/test/builders/method_test.dart b/test/builders/method_test.dart index 332cdf9..5ff6c7a 100644 --- a/test/builders/method_test.dart +++ b/test/builders/method_test.dart @@ -170,6 +170,33 @@ void main() { ); }); + test('should emit an async method', () { + expect( + method('fetch', [MethodModifier.async]), + equalsSource(r''' + fetch() async {} + '''), + ); + }); + + test('should emit an async* method', () { + expect( + method('fetch', [MethodModifier.asyncStar]), + equalsSource(r''' + fetch() async* {} + '''), + ); + }); + + test('should emit an sync* method', () { + expect( + method('fetch', [MethodModifier.syncStar]), + equalsSource(r''' + fetch() sync* {} + '''), + ); + }); + group('closure', () { MethodBuilder closure; setUp(() { @@ -185,22 +212,26 @@ void main() { expect( closure, equalsSource(r''' - (bool defaultTo) => false || defaultTo - '''), + (bool defaultTo) => false || defaultTo + '''), ); test('should treat closure as expression', () { expect( - list([true, false]).invoke('where', [closure]), - equalsSource( - '[true, false].where((bool defaultTo) => false || defaultTo)')); + list([true, false]).invoke('where', [closure]), + equalsSource( + '[true, false].where((bool defaultTo) => false || defaultTo)', + ), + ); }); test('should emit a closure as a function in a library', () { final library = new LibraryBuilder(); library.addMember(closure); expect( - library, equalsSource('(bool defaultTo) => false || defaultTo;')); + library, + equalsSource('(bool defaultTo) => false || defaultTo;'), + ); }); }); }); From bcc0a3205527f1c989c375e8f70602d9b25b6474 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 12 Dec 2016 22:44:59 -0800 Subject: [PATCH 4/7] . --- CHANGELOG.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7415873..d448c2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.0-alpha+8 + +- Add support for `async`, `sync`, `sync*` functions +- Add support for ann expression to `asAwait`, `asYield`, `asYieldStar` + ## 1.0.0-alpha+7 - Make use of new analyzer API in preparation for analyzer version 0.30. diff --git a/pubspec.yaml b/pubspec.yaml index 9fbdca2..de1f53f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: code_builder -version: 1.0.0-alpha+7 +version: 1.0.0-alpha+8 description: A fluent API for generating Dart code author: Dart Team homepage: https://github.com/dart-lang/code_builder From f1edec0cc0fb13ae12278c9aa297bbb06eba5d9d Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 12 Dec 2016 23:01:50 -0800 Subject: [PATCH 5/7] . --- CHANGELOG.md | 1 + lib/src/builders/class.dart | 11 +++++++++++ lib/src/builders/reference.dart | 21 +++++++++++++++++++++ lib/src/builders/type.dart | 27 +++++++++++++++++++++++++++ lib/src/pretty_printer.dart | 5 ++++- test/builders/type_test.dart | 18 ++++++++++++++++++ 6 files changed, 82 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d448c2a..009294b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Add support for `async`, `sync`, `sync*` functions - Add support for ann expression to `asAwait`, `asYield`, `asYieldStar` +- Add `toExportBuilder` and `toImportBuilder` to types and references ## 1.0.0-alpha+7 diff --git a/lib/src/builders/class.dart b/lib/src/builders/class.dart index 88830e8..ea1794c 100644 --- a/lib/src/builders/class.dart +++ b/lib/src/builders/class.dart @@ -7,6 +7,7 @@ import 'package:analyzer/dart/ast/standard_ast_factory.dart'; import 'package:code_builder/dart/core.dart'; import 'package:code_builder/src/builders/annotation.dart'; import 'package:code_builder/src/builders/field.dart'; +import 'package:code_builder/src/builders/file.dart'; import 'package:code_builder/src/builders/method.dart'; import 'package:code_builder/src/builders/shared.dart'; import 'package:code_builder/src/builders/type.dart'; @@ -254,6 +255,16 @@ class _ClassBuilderImpl extends Object void setExtends(TypeBuilder extend) { _extends = extend; } + + @override + ExportBuilder toExportBuilder() { + throw new UnsupportedError('Not supported for ClassBuilder'); + } + + @override + ImportBuilder toImportBuilder({bool deferred: false, String prefix}) { + throw new UnsupportedError('Not supported for ClassBuilder'); + } } class _TypeNameWrapper implements ValidClassMember { diff --git a/lib/src/builders/reference.dart b/lib/src/builders/reference.dart index b48f725..5e771ad 100644 --- a/lib/src/builders/reference.dart +++ b/lib/src/builders/reference.dart @@ -6,6 +6,7 @@ import 'package:analyzer/analyzer.dart'; import 'package:analyzer/dart/ast/standard_ast_factory.dart'; import 'package:code_builder/src/builders/annotation.dart'; import 'package:code_builder/src/builders/expression.dart'; +import 'package:code_builder/src/builders/file.dart'; import 'package:code_builder/src/builders/shared.dart'; import 'package:code_builder/src/builders/statement.dart'; import 'package:code_builder/src/builders/type.dart'; @@ -63,6 +64,26 @@ class ReferenceBuilder extends Object return new TypeBuilder(_name, importFrom: _importFrom).buildType(scope); } + @override + ExportBuilder toExportBuilder() { + if (_importFrom == null) { + throw new StateError('Cannot create an import - no URI provided'); + } + return new ExportBuilder(_importFrom)..show(_name); + } + + @override + ImportBuilder toImportBuilder({bool deferred: false, String prefix}) { + if (_importFrom == null) { + throw new StateError('Cannot create an import - no URI provided'); + } + return new ImportBuilder( + _importFrom, + deferred: deferred, + prefix: prefix, + )..show(_name); + } + /// Returns a new [ReferenceBuilder] with [genericTypes]. /// /// Example use: diff --git a/lib/src/builders/type.dart b/lib/src/builders/type.dart index 27f6b6a..851462b 100644 --- a/lib/src/builders/type.dart +++ b/lib/src/builders/type.dart @@ -8,6 +8,7 @@ import 'package:analyzer/analyzer.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/standard_ast_factory.dart'; import 'package:analyzer/src/dart/ast/token.dart'; +import 'package:code_builder/code_builder.dart'; import 'package:code_builder/src/builders/annotation.dart'; import 'package:code_builder/src/builders/expression.dart'; import 'package:code_builder/src/builders/method.dart'; @@ -62,6 +63,12 @@ abstract class AbstractTypeBuilderMixin { return builder; } + /// Returns as an import to this reference. + ImportBuilder toImportBuilder({bool deferred: false, String prefix}); + + /// Returns as an export to the reference. + ExportBuilder toExportBuilder(); + static void _addArguments( NewInstanceBuilder builder, Iterable positional, @@ -123,4 +130,24 @@ class TypeBuilder extends Object ), ); } + + @override + ExportBuilder toExportBuilder() { + if (_importFrom == null) { + throw new StateError('Cannot create an import - no URI provided'); + } + return new ExportBuilder(_importFrom)..show(_name); + } + + @override + ImportBuilder toImportBuilder({bool deferred: false, String prefix}) { + if (_importFrom == null) { + throw new StateError('Cannot create an import - no URI provided'); + } + return new ImportBuilder( + _importFrom, + deferred: deferred, + prefix: prefix, + )..show(_name); + } } diff --git a/lib/src/pretty_printer.dart b/lib/src/pretty_printer.dart index 53d3324..5aef4dc 100644 --- a/lib/src/pretty_printer.dart +++ b/lib/src/pretty_printer.dart @@ -84,7 +84,10 @@ class _PrettyToSourceVisitor extends ToSourceVisitor { // Write a list of [nodes], separated by the given [separator], followed by // the given [suffix] if the list is not empty. void _visitNodeListWithSeparatorAndSuffix( - NodeList nodes, String separator, String suffix) { + NodeList nodes, + String separator, + String suffix, + ) { if (nodes != null) { int size = nodes.length; if (size > 0) { diff --git a/test/builders/type_test.dart b/test/builders/type_test.dart index bd82af3..16c9f4d 100644 --- a/test/builders/type_test.dart +++ b/test/builders/type_test.dart @@ -94,5 +94,23 @@ void main() { '''), ); }); + + test('emits an export builder', () { + expect( + reference('Foo', 'package:foo/foo.dart').toExportBuilder(), + equalsSource(r''' + export 'package:foo/foo.dart' show Foo; + '''), + ); + }); + + test('emits an export builder', () { + expect( + reference('Foo', 'package:foo/foo.dart').toImportBuilder(), + equalsSource(r''' + import 'package:foo/foo.dart' show Foo; + '''), + ); + }); }); } From 5329353c40e3666fc97867311e6dd0385b653d49 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 19 Dec 2016 13:09:15 -0800 Subject: [PATCH 6/7] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c34cb4..a45bafc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## 1.0.0-alpha+9 - Add support for `async`, `sync`, `sync*` functions -- Add support for ann expression to `asAwait`, `asYield`, `asYieldStar` +- Add support for expression `asAwait`, `asYield`, `asYieldStar` - Add `toExportBuilder` and `toImportBuilder` to types and references ## 1.0.0-alpha+8 From b3723ffede500ca1a341172bb3b87b86a11a785d Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 19 Dec 2016 13:11:28 -0800 Subject: [PATCH 7/7] Update pubspec.yaml --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index de1f53f..5b84bab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: code_builder -version: 1.0.0-alpha+8 +version: 1.0.0-alpha+9 description: A fluent API for generating Dart code author: Dart Team homepage: https://github.com/dart-lang/code_builder