diff --git a/CHANGELOG.md b/CHANGELOG.md index be412e6..381b2aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.0.0-beta+1 + +- Add support for `switch` statements +- Add support for a raw expression and statement + - `new ExpressionBuilder.raw(...)` + - `new StatemnetBuilder.raw(...)` + +This should help cover any cases not covered with builders today. + ## 1.0.0-beta - Add support for `async`, `sync`, `sync*` functions diff --git a/lib/src/builders/expression.dart b/lib/src/builders/expression.dart index 4a0d4e0..5e086e2 100644 --- a/lib/src/builders/expression.dart +++ b/lib/src/builders/expression.dart @@ -12,6 +12,7 @@ import 'package:code_builder/src/builders/method.dart'; import 'package:code_builder/src/builders/parameter.dart'; import 'package:code_builder/src/builders/reference.dart'; import 'package:code_builder/src/builders/shared.dart'; +import 'package:code_builder/src/builders/expression/raw.dart'; import 'package:code_builder/src/builders/statement.dart'; import 'package:code_builder/src/builders/statement/if.dart'; import 'package:code_builder/src/builders/statement/while.dart'; @@ -298,6 +299,9 @@ abstract class AbstractExpressionMixin implements ExpressionBuilder { /// Builds an [Expression] AST when [buildExpression] is invoked. abstract class ExpressionBuilder implements AstBuilder, StatementBuilder, ValidParameterMember { + /// Create an expression builder that parses and emits a [raw] expression. + factory ExpressionBuilder.raw(String raw(Scope scope)) = RawExpressionBuilder; + /// Returns as an [ExpressionBuilder] multiplying by [other]. ExpressionBuilder operator *(ExpressionBuilder other); diff --git a/lib/src/builders/expression/raw.dart b/lib/src/builders/expression/raw.dart new file mode 100644 index 0000000..1dff885 --- /dev/null +++ b/lib/src/builders/expression/raw.dart @@ -0,0 +1,28 @@ +// 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/expression.dart'; +import 'package:code_builder/src/builders/shared.dart'; +import 'package:code_builder/src/builders/statement.dart'; +import 'package:func/func.dart'; + +class RawExpressionBuilder extends Object + with AbstractExpressionMixin, TopLevelMixin + implements ExpressionBuilder { + final Func1 _raw; + + RawExpressionBuilder(this._raw); + + @override + AstNode buildAst([Scope scope]) { + FunctionDeclaration d = + parseCompilationUnit('main() => ${_raw(scope)};').declarations.first; + ExpressionFunctionBody f = d.functionExpression.body; + return f.expression; + } + + @override + Expression buildExpression([Scope scope]) => buildAst(scope); +} diff --git a/lib/src/builders/statement.dart b/lib/src/builders/statement.dart index b18c11a..9c36211 100644 --- a/lib/src/builders/statement.dart +++ b/lib/src/builders/statement.dart @@ -7,6 +7,7 @@ import 'package:analyzer/dart/ast/standard_ast_factory.dart'; import 'package:code_builder/src/builders/method.dart'; import 'package:code_builder/src/builders/shared.dart'; import 'package:code_builder/src/builders/statement/if.dart'; +import 'package:code_builder/src/builders/statement/raw.dart'; import 'package:code_builder/src/tokens.dart'; export 'package:code_builder/src/builders/statement/break.dart' @@ -82,6 +83,8 @@ abstract class StatementBuilder ValidIfStatementMember, ValidConstructorMember, ValidMethodMember { + factory StatementBuilder.raw(String raw(Scope scope)) = RawStatementBuilder; + /// Returns an [Statement] AST representing the builder. Statement buildStatement([Scope scope]); } diff --git a/lib/src/builders/statement/raw.dart b/lib/src/builders/statement/raw.dart new file mode 100644 index 0000000..ed489d0 --- /dev/null +++ b/lib/src/builders/statement/raw.dart @@ -0,0 +1,29 @@ +// 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'; +import 'package:func/func.dart'; + +class RawStatementBuilder implements StatementBuilder { + final Func1 _raw; + + const RawStatementBuilder(this._raw); + + @override + AstNode buildAst([Scope scope]) { + FunctionDeclaration d = + parseCompilationUnit('raw() { ${_raw(scope)} }').declarations.first; + BlockFunctionBody f = d.functionExpression.childEntities.elementAt(1); + Block b = f.childEntities.first; + return b.statements.first; + } + + @override + Statement buildStatement([Scope scope]) => buildAst(scope); + + @override + CompilationUnitMember buildTopLevelAst([Scope scope]) => buildAst(scope); +} diff --git a/pubspec.yaml b/pubspec.yaml index 6f46486..3db2f23 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: code_builder -version: 1.0.0-beta +version: 1.0.0-beta+1 description: A fluent API for generating Dart code author: Dart Team homepage: https://github.com/dart-lang/code_builder @@ -10,6 +10,7 @@ environment: dependencies: analyzer: '>=0.29.1 <0.30.0' dart_style: ^0.2.10 + func: ^0.1.0 matcher: ^0.12.0+2 meta: ^1.0.2 diff --git a/test/builders/expression_test.dart b/test/builders/expression_test.dart index 0510f20..0eae4bb 100644 --- a/test/builders/expression_test.dart +++ b/test/builders/expression_test.dart @@ -332,4 +332,18 @@ void main() { '''), ); }); + + test('raw expression', () { + expect( + lambda( + 'main', + new ExpressionBuilder.raw( + (scope) => '5 + 3 + ${scope.identifier('q')}', + ), + ), + equalsSource(r''' + main() => 5 + 3 + q; + '''), + ); + }); } diff --git a/test/builders/statement_test.dart b/test/builders/statement_test.dart index 7f0384b..ca6f912 100644 --- a/test/builders/statement_test.dart +++ b/test/builders/statement_test.dart @@ -139,4 +139,17 @@ void main() { ''')); }); }); + + test('raw statement', () { + expect( + method('main', [ + new StatementBuilder.raw((scope) => 'print(${scope.identifier('q')});'), + ]), + equalsSource(r''' + main() { + print(q); + } + '''), + ); + }); }