^3.5.0
dart_style
2.3.7.dart-lang/tools
monorepo.Library.docs
to support emitting doc comments on libraries.RepresentationDeclaration
and RepresentationDeclarationBuilder
so they can be used when generating extension types.dart_style
2.3.4.Library.generatedByComment
to support emitting ‘generated by’ comments.Expression.operatorSubtract
Expression.operatorSubstract
Expression.operatorIntDivide
Expression.operatorUnaryPrefixIncrement
Expression.operatorUnaryPostfixIncrement
Expression.operatorUnaryMinus
Expression.operatorUnaryPrefixDecrement
Expression.operatorUnaryPostfixDecrement
Expression.operatorBitwiseAnd
Expression.operatorBitwiseOr
Expression.operatorBitwiseXor
Expression.operatorUnaryBitwiseComplement
Expression.operatorShiftLeft
Expression.operatorShiftRight
Expression.operatorShiftRightUnsigned
Expression.addAssign
Expression.subtractAssign
Expression.multiplyAssign
Expression.divideAssign
Expression.intDivideAssign
Expression.euclideanModuloAssign
Expression.shiftLeftAssign
Expression.shiftRightAssign
Expression.shiftRightUnsignedAssign
Expression.bitwiseAndAssign
Expression.bitwiseXorAssign
Expression.bitwiseOrAssign
Expression
through literal
without an exception.>=3.0.0
.enum
classesExpression.parenthesized
to manually wrap an expression in parenthesis.literalSpread
and literalNullSafeSpread
to support adding spreads to literalMap
.void main() { // Creates a map // { // ...one, // 2: two, // ...?three, // } final map = literalMap({ literalSpread(): refer('one'), 2: refer('two'), literalNullSafeSpread(): refer('three'), }); }
allocator
argument relates to imports in the DartEmitter
constructor doc.ignore_for_file
analyzer directive comments.enum
classes.late
keyword when using null safety syntax.const
when assigning to a declareConst
variable.assignVar
, assignConst
, and assignFinal
.package:lints
recommended set. The lint, no_leading_underscores_for_library_prefixes
is most useful for hand edited code where the appearance of a private name that is already not visible outside the library is confusing.Expression.assign
, ifNullThen
, and assignNullAware
which had the argument and receiver flipped.declareConst
, declareFinal
, and declareVar
to replace Expression.assignConst
, assignFinal
, and assignVar
. Add support for late variables with the declare*
utilities.ParameterBuilder.toSuper
so support super formal parameters language feature.Expression.spread
for the spread operator ...
.Expression.nullChecked
to add a null assertion operator.mixin
s.Expression.nullSafeSpread
for the null aware spread operator ...?
.Library
can now be annotated.DartEmitter
constructor to use named optional parameters.ParenthesizedExpression
and ExpressionVisitor.visitParenthesizedExpression.
Method.genericClosure
.extension
methods.built_value
to allow null safe migrated version.const factory
constructors.equalsDart
. https://github.com/dart-lang/code_builder/issues/293Expression.thrown
for throwing an expression.FunctionType.isNullable
.>=2.7.0 <3.0.0
.??
null-aware operator...
cascade assignment operator.part
directive.TypeReference.isNullable
.DartEmitter
to emit nullable types with trailing ?
characters.2.6.0
.Expression.or
for boolean OR.Expression.negate
for boolean NOT.,
s in FunctionType
s.literalSet
and literalConstSet
.package:built_value
.=
instead of :
for named parameter default values.new
keyword will not be used in generated code.const
keyword will be omitted when it can be inferred.DartEmitter
to order directives.DartEmitter
added a startConstCode
function to track the creation of constant expression trees.BinaryExpression
added the final bool isConst
field.<3.0.0
.Expression.asA
is now wrapped with parenthesis so that further calls may be made on it as an expression.Expression.asA
for creating explicit casts:void main() { test('should emit an explicit cast', () { expect( refer('foo').asA(refer('String')), equalsDart('foo as String'), ); }); }
code_builder
to crash due to build_runner
trying to import our private builder (in tool/
). Sorry for the inconvenience.source_gen: ^0.7.5
.built_value
5.1.0.literalNum
function.literal
supports a Map
.Constructor.lambda
for factory
constructors.Using equalsDart
no longer formats automatically with dartfmt
.
Removed deprecated Annotation
and File
classes.
Method.lambda
is inferred based on Method.body
where possible and now defaults to null
.
equalTo
, notEqualTo
, greaterThan
, lessThan
, greateOrEqualTo
, and lessOrEqualTo
to Expression
.equalsDart
and expecting dartfmt
by default is deprecated. This requires this package to have a direct dependency on specific versions of dart_style
(and transitively analyzer
), which is problematic just for testing infrastructure. To future proof, we've exposed the EqualsDart
class with a format
override:// 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 'package:code_builder/code_builder.dart'; import 'package:dart_style/dart_style.dart'; final DartFormatter _dartfmt = new DartFormatter(); String _format(String source) { try { return _dartfmt.format(source); } on FormatException catch (_) { return _dartfmt.formatStatement(source); } } /// Should be invoked in `main()` of every test in `test/**_test.dart`. void useDartfmt() => EqualsDart.format = _format;
Expression.isA
and Expression.isNotA
:void main() { test('should emit an is check', () { expect( refer('foo').isA(refer('String')), equalsDart('foo is String'), ); }); }
Annotation
. It is now legal to simply pass any Expression
as a metadata annotation to Class
, Method
, Field,
and Parameter
. In 3.0.0
, the Annotation
class will be completely removed:void main() { test('should create a class with a annotated constructor', () { expect( new Class((b) => b ..name = 'Foo' ..constructors.add( new Constructor((b) => b..annotations.add(refer('deprecated'))))), equalsDart(r''' class Foo { @deprecated Foo(); } '''), ); }); }
Method.lambda
and Constructor.lambda
. If not explicitly provided and the body of the function originated from an Expression
then lambda
is inferred to be true. This is not a breaking change yet, as it requires an explicit null
value. In 3.0.0
this will be the default:void main() { final animal = new Class((b) => b ..name = 'Animal' ..extend = refer('Organism') ..methods.add(new Method.returnsVoid((b) => b ..name = 'eat' // In 3.0.0, this may be omitted and still is inferred. ..lambda = null ..body = refer('print').call([literalString('Yum!')]).code))); final emitter = new DartEmitter(); print(new DartFormatter().format('${animal.accept(emitter)}')); }
nullSafeProperty
to Expression
to access properties with ?.
conditional
to Expression
to use the ternary operator ? :
positionalArguments
accept Iterable<Expression>
FunctionType
as a type
. Reference.type
now returns a Reference
. Note that this change is technically breaking but should not impacts most clients.Imports are prefixed with _i1
rather than _1
which satisfies the lint lowercase_with_underscores
. While not a strictly breaking change you may have to fix/regenerate golden file-like tests. We added documentation that the specific prefix is not considered stable.
Added Expression.index
for accessing the []
operator:
void main() { test('should emit an index operator', () { expect( refer('bar').index(literalTrue).assignVar('foo').statement, equalsDart('var foo = bar[true];'), ); }); test('should emit an index operator set', () { expect( refer('bar') .index(literalTrue) .assign(literalFalse) .assignVar('foo') .statement, equalsDart('var foo = bar[true] = false;'), ); }); }
literalList
accepts an Iterable
argument.
Fixed an NPE when a method had a return type of a FunctionType
:
void main() { test('should create a method with a function type return type', () { expect( new Method((b) => b ..name = 'foo' ..returns = new FunctionType((b) => b ..returnType = refer('String') ..requiredParameters.addAll([ refer('int'), ]))), equalsDart(r''' String Function(int) foo(); '''), ); }); }
We now require the Dart 2.0-dev branch SDK (>= 2.0.0-dev
).
String
literals.String
literals.File
, which is now a redirect to the preferred class, Library
.This helps avoid symbol clashes when used with dart:io
, a popular library. It is now safe to do the following and get full access to the code_builder
API:
import 'dart:io'; import 'package:code_builder/code_builder.dart' hide File;
We will remove File
in 3.0.0
, so use Library
instead.
Re-released without a direct dependency on package:analyzer
!
For users of the 1.x
branch of code_builder
, this is a pretty big breaking change but ultimately is for the better - it's easier to evolve this library now and even add your own builders on top of the library.
// 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 'package:code_builder/code_builder.dart'; import 'package:dart_style/dart_style.dart'; void main() { final animal = new Class((b) => b ..name = 'Animal' ..extend = refer('Organism') ..methods.add(new Method.returnsVoid((b) => b ..name = 'eat' ..lambda = true ..body = const Code('print(\'Yum\')')))); final emitter = new DartEmitter(); print(new DartFormatter().format('${animal.accept(emitter)}')); }
...outputs...
class Animal extends Organism { void eat() => print('Yum!'); }
Major changes:
built_value
, and have a more consistent, friendly API.DartEmitter
as an example of the built-in visitor/emitter.Code
example below:void main() { var code = new Code('x + y = z'); code.expression; code.statement; }
See the commit log, examples, and tests for full details. While we want to try and avoid breaking changes, suggestions, new features, and incremental updates are welcome!
Added lazySpec
and lazyCode
to lazily create code on visit #145.
BUG FIX: equalsDart
emits the failing source code #147.
BUG FIX: Top-level lambda
Method
s no longer emit invalid code #146.
Added Expression.annotation
and Expression.annotationNamed
.
Added Method.closure
to create an Expression
.
Added FunctionType
.
Added {new|const}InstanceNamed
to Expression
#135.
typeArguments
option to all invocations.Added assign{...}
variants to Expression
#137.
Added .awaited
and .returned
to Expression
#138.
BUG FIX: Block
now implements Code
#136.
BUG FIX: new DartEmitter.scoped()
applies prefixing #139.
Renamed many of the .asFoo(...)
and .toFoo(...)
methods to single getter:
asCode()
to code
asStatement()
to statement
toExpression()
to expression
Moved {new|const}Instance{[Named]}
from Expression
to Reference
.
Upgraded build_runner
from ^0.3.0
to >=0.4.0 <0.6.0
.
Upgraded build_value{_generator}
from ^1.0.0
to >=2.0.0 <5.0.0
.
Upgraded source_gen
from >=0.5.0 <0.7.0
to ^0.7.0
.
Added MethodModifier
to allow emit a Method
with async|async*|sync*
.
Added show|hide
to Directive
.
Added Directive.importDeferredAs
.
Added a new line character after emitting some types (class, method, etc).
Added refer
as a short-hand for new Reference(...)
.
Reference
now implements Expression
.Added many classes/methods for writing bodies of Code
fluently:
Expression
LiteralExpression
literal
literalNull
literalBool
literalTrue
literalFalse
literalNum
literalString
literalList
and literalConstList
literalMap
and literalConstMap
const Code(staticString)
const Code.scope((allocate) => '')
Removed SimpleSpecVisitor
(it was unused).
Removed implements Reference
from Method
and Field
; not a lot of value.
SpecVisitor<T>
's methods all have an optional [T context]
parameter now.
StringBuffer
s.equalsDart
removes insignificant white space before comparing results.
Reference.localScope
. Just use Reference(symbol)
now.Reference
instead of an explicit TypeReference
in most APIs.toType()
is performed for you as part the emitter processfinal animal = new Class((b) => b ..name = 'Animal' // Used to need a suffix of .toType(). ..extend = const Reference('Organism') ..methods.add(new Method.returnsVoid((b) => b ..name = 'eat' ..lambda = true ..body = new Code((b) => b..code = 'print(\'Yum\')'))));
<2.0.0-dev.infinity
)Class
as a TypeReference
.dart2js
, which is now tested on travis.package:analyzer
.built_value
).isInstanceOf
to ExpressionBuilder
, which performs an is
check:expect( reference('foo').isInstanceOf(_barType), equalsSource('foo is Bar'), );
pkg/analyzer
and pkg/func
.package:dart_style
.First full release. At this point, all changes until 2.0.0
will be backward compatible (new features) or bug fixes that are not breaking. This doesn't mean that the entire Dart language is buildable with our API, though.
Contributions are welcome.
uri
in ImportBuilder
, ExportBuilder
, and Part[Of]Builder
.ExpressionBuilder#ternary
.TypeDefBuilder
.FunctionParameterBuilder
.asAbstract
to various MethodBuilder
constructors.PartBuilder
to PartOfBuilder
.PartBuilder
, to represent part '...dart'
directives.HasAnnotations
interface to all library/part/directive builders.asFactory
and asConst
to ConstructorBuilder
.ConstructorBuilder.redirectTo
for a redirecting factory constructor.name
getter to ReferenceBuilder
.''
) is equivalent to null
(default).'''
.asThrow
to ExpressionBuilder
.FieldBuilder
from being used at the top-level.genericTypes
parameter for ExpressionBuilder#invoke
:expect( explicitThis.invoke('doThing', [literal(true)], genericTypes: [ lib$core.bool, ]), equalsSource(r''' this.doThing<bool>(true) '''), );
castAs
method to ExpressionBuilder
:expect( literal(1.0).castAs(lib$core.num), equalsSource(r''' 1.0 as num '''), );
namedNewInstance
and namedConstInstance
, replaced with constructor:
:expect( reference('Foo').newInstance([], constructor: 'other'), equalsSource(r''' new Foo.other() '''), );
named
parameter to namedArguments
:expect( reference('doThing').call( [literal(true)], namedArguments: { 'otherFlag': literal(false), }, ), equalsSource(r''' doThing(true, otherFlag: false) '''), );
Avoid creating symbols that can collide with the Dart language:
MethodModifier.async
-> MethodModifier.asAsync
MethodModifier.asyncStar
-> MethodModifier.asAsyncStar
MethodModifier.syncStar
-> MethodModifier.asSyncStar
switch
statementsnew ExpressionBuilder.raw(...)
new StatemnetBuilder.raw(...)
This should help cover any cases not covered with builders today.
ClassBuilder
and TypeBuilder
as an expression[]
operator on an expressionExpressionBuilder.asAssign
to always take an ExpressionBuilder
as target and removed the value
property. Most changes are pretty simple, and involve just using reference(...)
. For example:literal(true).asAssign(reference('flag'))
... emits flag = true
.
async
, sync
, sync*
functionsasAwait
, asYield
, asYieldStar
toExportBuilder
and toImportBuilder
to types and referencesreturn
statements and named constructor invocations.while
and do {} while
loop supportfor
and for-in
supportname
getter for ParameterBuilder
MethodBuilder.closure
emits properly as a top-level function// main() {} method('main')
// () => false new MethodBuilder.closure(returns: literal(false));
pkg/analyzer
.TypeBuilder
:importFrom
becomes a named, not a positional argument, and the named argument genericTypes
is added (Iterable<TypeBuilder>
).
// List<String> new TypeBuilder('List', genericTypes: [reference('String')])
ReferenceBuilder
:// List<String> reference('List').toTyped([reference('String')])
ReferenceBuilder.buildAst
was not implementedand
and or
methods to ExpressionBuilder
:// true || false literal(true).or(literal(false)); // true && false literal(true).and(literal(false));
MethodBuilder.closure
:// () => true new MethodBuilder.closure( returns: literal(true), returnType: lib$core.bool, )
returnVoid
to well, return;
new LibraryBuilder()..addMember(literal(false).asConst('foo'))
target
when using asAssign
:// Outputs bank.bar = goldBar reference('goldBar').asAssign('bar', target: reference('bank'))
// Outputs foo..doThis()..doThat() reference('foo').cascade((c) => <ExpressionBuilder> [ c.invoke('doThis', []), c.invoke('doThat', []), ]);
// foo.bar reference('foo').property('bar');
show
and hide
support to ImportBuilder
deferred
support to ImportBuilder
ExportBuilder
list
and map
literals that support generic typesScope
and change toAst
to support itNow your entire AST tree can be scoped and import directives automatically added to a LibraryBuilder
for you if you use LibraryBuilder.scope
.