code_builder 3.0.0-alpha code_builder: ^3.0.0-alpha copied to clipboard
A fluent API for generating Dart code
3.0.0-alpha #
-
Using
equalsDart
no longer formats automatically withdartfmt
. -
Removed deprecated
Annotation
andFile
classes. -
Method.lambda
is inferred based onMethod.body
where possible and now defaults tonull
.
2.4.0 #
- Add
equalTo
,notEqualTo
,greaterThan
,lessThan
,greateOrEqualTo
, andlessOrEqualTo
toExpression
.
2.3.0 #
- Using
equalsDart
and expectingdartfmt
by default is deprecated. This requires this package to have a direct dependency on specific versions ofdart_style
(and transitivelyanalyzer
), which is problematic just for testing infrastructure. To future proof, we've exposed theEqualsDart
class with aformat
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;
- Added
Expression.isA
andExpression.isNotA
:
void main() {
test('should emit an is check', () {
expect(
refer('foo').isA(refer('String')),
equalsDart('foo is String'),
);
});
}
- Deprecated
Annotation
. It is now legal to simply pass anyExpression
as a metadata annotation toClass
,Method
,Field,
andParameter
. In3.0.0
, theAnnotation
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();
}
'''),
);
});
}
- Added inference support for
Method.lambda
andConstructor.lambda
. If not explicitly provided and the body of the function originated from anExpression
thenlambda
is inferred to be true. This is not a breaking change yet, as it requires an explicitnull
value. In3.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)}'));
}
- Added
nullSafeProperty
toExpression
to access properties with?.
- Added
conditional
toExpression
to use the ternary operator? :
- Methods taking
positionalArguments
acceptIterable<Expression>
- BUG FIX: Parameters can take a
FunctionType
as atype
.Reference.type
now returns aReference
. Note that this change is technically breaking but should not impacts most clients.
2.2.0 #
-
Imports are prefixed with
_i1
rather than_1
which satisfies the lintlowercase_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 anIterable
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();
'''),
);
});
}
2.1.0 #
We now require the Dart 2.0-dev branch SDK (>= 2.0.0-dev
).
- Added support for raw
String
literals. - Automatically escapes single quotes in now-raw
String
literals. - Deprecated
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.
2.0.0 #
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:
- Builders now use
built_value
, and have a more consistent, friendly API. - Builders are now consistent - they don't any work until code is emitted.
- It's possible to overwrite the built-in code emitting, formatting, etc by
providing your own visitors. See
DartEmitter
as an example of the built-in visitor/emitter. - Most of the expression and statement level helpers were removed; in practice
they were difficult to write and maintain, and many users commonly asked for
opt-out type APIs. See the
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!
2.0.0-beta #
2.0.0-alpha+3 #
-
Added
Expression.annotation
andExpression.annotationNamed
. -
Added
Method.closure
to create anExpression
. -
Added
FunctionType
. -
Added
{new|const}InstanceNamed
toExpression
#135.- Also added a
typeArguments
option to all invocations.
- Also added a
-
Added
assign{...}
variants toExpression
#137. -
Added
.awaited
and.returned
toExpression
#138. -
BUG FIX:
Block
now implementsCode
#136. -
BUG FIX:
new DartEmitter.scoped()
applies prefixing #139. -
Renamed many of the
.asFoo(...)
and.toFoo(...)
methods to single getter:asCode()
tocode
asStatement()
tostatement
toExpression()
toexpression
-
Moved
{new|const}Instance{[Named]}
fromExpression
toReference
.
2.0.0-alpha+2 #
-
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 aMethod
withasync|async*|sync*
. -
Added
show|hide
toDirective
. -
Added
Directive.importDeferredAs
. -
Added a new line character after emitting some types (class, method, etc).
-
Added
refer
as a short-hand fornew Reference(...)
.Reference
now implementsExpression
.
-
Added many classes/methods for writing bodies of
Code
fluently:Expression
LiteralExpression
literal
literalNull
literalBool
literalTrue
literalFalse
literalNum
literalString
literalList
andliteralConstList
literalMap
andliteralConstMap
const Code(staticString)
const Code.scope((allocate) => '')
-
Removed
SimpleSpecVisitor
(it was unused). -
Removed
implements Reference
fromMethod
andField
; not a lot of value. -
SpecVisitor<T>
's methods all have an optional[T context]
parameter now.- This makes it much easier to avoid allocating extra
StringBuffer
s.
- This makes it much easier to avoid allocating extra
-
equalsDart
removes insignificant white space before comparing results.
2.0.0-alpha+1 #
- Removed
Reference.localScope
. Just useReference(symbol)
now. - Allow
Reference
instead of an explicitTypeReference
in most APIs.toType()
is performed for you as part the emitter process
final 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\')'))));
- We now support the Dart 2.0 pre-release SDKs (
<2.0.0-dev.infinity
) - Removed the ability to treat
Class
as aTypeReference
.- Was required for compilation to
dart2js
, which is now tested on travis.
- Was required for compilation to
2.0.0-alpha #
- Complete re-write to not use
package:analyzer
. - Code generation now properly uses the builder pattern (via
built_value
). - See examples and tests for details.
1.0.4 #
- Added
isInstanceOf
toExpressionBuilder
, which performs anis
check:
expect(
reference('foo').isInstanceOf(_barType),
equalsSource('foo is Bar'),
);
1.0.3 #
- Support latest
pkg/analyzer
andpkg/func
.
1.0.2 #
- Update internals to use newer analyzer API
1.0.1 #
- Support the latest version of
package:dart_style
.
1.0.0 #
First full release. At this point all changes until 2.0.0
will be backwards
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.
- Exposed
uri
inImportBuilder
,ExportBuilder
, andPart[Of]Builder
.
1.0.0-beta+7 #
- Added
ExpressionBuilder#ternary
.
1.0.0-beta+6 #
- Added
TypeDefBuilder
. - Added
FunctionParameterBuilder
. - Added
asAbstract
to variousMethodBuilder
constructors.
1.0.0-beta+5 #
- Re-published the package without merge conflicts.
1.0.0-beta+4 #
- Renamed
PartBuilder
toPartOfBuilder
. - Added a new class,
PartBuilder
, to representpart '...dart'
directives. - Added the
HasAnnotations
interface to all library/part/directive builders. - Added
asFactory
andasConst
toConstructorBuilder
. - Added
ConstructorBuilder.redirectTo
for a redirecting factory constructor. - Added a
name
getter toReferenceBuilder
. - Supplying an empty constructor name (
''
) is equivalent tonull
(default). - Automatically encodes string literals with multiple lines as
'''
. - Added
asThrow
toExpressionBuilder
. - Fixed a bug that prevented
FieldBuilder
from being used at the top-level.
1.0.0-beta+3 #
- Added support for
genericTypes
parameter forExpressionBuilder#invoke
:
expect(
explicitThis.invoke('doThing', [literal(true)], genericTypes: [
lib$core.bool,
]),
equalsSource(r'''
this.doThing<bool>(true)
'''),
);
- Added a
castAs
method toExpressionBuilder
:
expect(
literal(1.0).castAs(lib$core.num),
equalsSource(r'''
1.0 as num
'''),
);
BREAKING CHANGES #
- Removed
namedNewInstance
andnamedConstInstance
, replaced withconstructor:
:
expect(
reference('Foo').newInstance([], constructor: 'other'),
equalsSource(r'''
new Foo.other()
'''),
);
- Renamed
named
parameter tonamedArguments
:
expect(
reference('doThing').call(
[literal(true)],
namedArguments: {
'otherFlag': literal(false),
},
),
equalsSource(r'''
doThing(true, otherFlag: false)
'''),
);
1.0.0-beta+2 #
BREAKING CHANGES #
Avoid creating symbols that can collide with the Dart language:
MethodModifier.async
->MethodModifier.asAsync
MethodModifier.asyncStar
->MethodModifier.asAsyncStar
MethodModifier.syncStar
->MethodModifier.asSyncStar
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.
- Allow referring to a
ClassBuilder
andTypeBuilder
as an expression - Add support for accessing the index
[]
operator on an expression
BREAKING CHANGES #
- Changed
ExpressionBuilder.asAssign
to always take anExpressionBuilder
as target and removed thevalue
property. Most changes are pretty simple, and involve just usingreference(...)
. For example:
literal(true).asAssign(reference('flag'))
... emits flag = true
.
1.0.0-beta #
- Add support for
async
,sync
,sync*
functions - Add support for expression
asAwait
,asYield
,asYieldStar
- Add
toExportBuilder
andtoImportBuilder
to types and references - Fix an import scoping bug in
return
statements and named constructor invocations. - Added constructor initializer support
- Add
while
anddo {} while
loop support - Add
for
andfor-in
support - Added a
name
getter forParameterBuilder
1.0.0-alpha+7 #
- Make use of new analyzer API in preparation for analyzer version 0.30.
1.0.0-alpha+6 #
MethodBuilder.closure
emits properly as a top-level function
1.0.0-alpha+5 #
- MethodBuilder with no statements will create an empty block instead of a semicolon.
// main() {}
method('main')
- Fix lambdas and closures to not include a trailing semicolon when used as an expression.
// () => false
new MethodBuilder.closure(returns: literal(false));
1.0.0-alpha+4 #
- Add support for latest
pkg/analyzer
.
1.0.0-alpha+3 #
- BREAKING CHANGE: Added generics support to
TypeBuilder
:
importFrom
becomes a named, not positional argument, and the named
argument genericTypes
is added (Iterable<TypeBuilder>
).
// List<String>
new TypeBuilder('List', genericTypes: [reference('String')])
- Added generic support to
ReferenceBuilder
:
// List<String>
reference('List').toTyped([reference('String')])
- Fixed a bug where
ReferenceBuilder.buildAst
was not implemented - Added
and
andor
methods toExpressionBuilder
:
// true || false
literal(true).or(literal(false));
// true && false
literal(true).and(literal(false));
- Added support for creating closures -
MethodBuilder.closure
:
// () => true
new MethodBuilder.closure(
returns: literal(true),
returnType: lib$core.bool,
)
1.0.0-alpha+2 #
- Added
returnVoid
to well,return;
- Added support for top-level field assignments:
new LibraryBuilder()..addMember(literal(false).asConst('foo'))
- Added support for specifying a
target
when usingasAssign
:
// Outputs bank.bar = goldBar
reference('goldBar').asAssign('bar', target: reference('bank'))
- Added support for the cascade operator:
// Outputs foo..doThis()..doThat()
reference('foo').cascade((c) => <ExpressionBuilder> [
c.invoke('doThis', []),
c.invoke('doThat', []),
]);
- Added support for accessing a property
// foo.bar
reference('foo').property('bar');
1.0.0-alpha+1 #
- Slight updates to confusing documentation.
- Added support for null-aware assignments.
- Added
show
andhide
support toImportBuilder
- Added
deferred
support toImportBuilder
- Added
ExportBuilder
- Added
list
andmap
literals that support generic types
1.0.0-alpha #
- Large refactor that makes the library more feature complete.
0.1.1 #
- Add concept of
Scope
and changetoAst
to support it
Now your entire AST tree can be scoped and import directives
automatically added to a LibraryBuilder
for you if you use
LibraryBuilder.scope
.
0.1.0 #
- Initial version