Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

Commit 5e13264

Browse files
authored
Beta release fixes and feature. (#149)
* Beta release fixes and feature. * Dartfmt.
1 parent 9f922c9 commit 5e13264

File tree

9 files changed

+92
-19
lines changed

9 files changed

+92
-19
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 2.0.0-beta
2+
3+
* Added `lazySpec` and `lazyCode` to lazily create code on visit [#145](https://github.com/dart-lang/code_builder/issues/145).
4+
5+
* **BUG FIX**: `equalsDart` emits the failing source code [#147](https://github.com/dart-lang/code_builder/issues/147).
6+
* **BUG FIX**: Top-level `lambda` `Method`s no longer emit invalid code [#146](https://github.com/dart-lang/code_builder/issues/146).
7+
18
## 2.0.0-alpha+3
29

310
* Added `Expression.annotation` and `Expression.annotationNamed`.

lib/code_builder.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
export 'src/allocator.dart' show Allocator;
6-
export 'src/base.dart' show Spec;
6+
export 'src/base.dart' show lazySpec, Spec;
77
export 'src/emitter.dart' show DartEmitter;
88
export 'src/matchers.dart' show equalsDart;
99
export 'src/specs/annotation.dart' show Annotation, AnnotationBuilder;
1010
export 'src/specs/class.dart' show Class, ClassBuilder;
1111
export 'src/specs/code.dart'
12-
show Block, BlockBuilder, Code, StaticCode, ScopedCode;
12+
show lazyCode, Block, BlockBuilder, Code, StaticCode, ScopedCode;
1313
export 'src/specs/constructor.dart' show Constructor, ConstructorBuilder;
1414
export 'src/specs/directive.dart'
1515
show Directive, DirectiveType, DirectiveBuilder;

lib/src/allocator.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:path/path.dart' as p;
6+
57
import 'specs/directive.dart';
68
import 'specs/reference.dart';
79

lib/src/base.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,17 @@ import 'visitors.dart';
77
abstract class Spec {
88
R accept<R>(SpecVisitor<R> visitor, [R context]);
99
}
10+
11+
/// Returns a generic [Spec] that is lazily generated when visited.
12+
Spec lazySpec(Spec Function() generate) => new _LazySpec(generate);
13+
14+
class _LazySpec implements Spec {
15+
final Spec Function() generate;
16+
17+
const _LazySpec(this.generate);
18+
19+
@override
20+
R accept<R>(SpecVisitor<R> visitor, [R context]) {
21+
return generate().accept(visitor, context);
22+
}
23+
}

lib/src/emitter.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ class DartEmitter extends Object
271271
for (final spec in spec.body) {
272272
body.write(visitSpec(spec));
273273
if (spec is Method && spec.lambda) {
274-
output.write(';');
274+
body.write(';');
275275
}
276276
}
277277
// TODO: Allow some sort of logical ordering.

lib/src/matchers.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ String _dartfmt(String source) {
1818
source = _formatter.formatStatement(source);
1919
} catch (_) {
2020
// Ignored on purpose, probably not exactly valid Dart code.
21-
} finally {
2221
source = collapseWhitespace(source);
2322
}
2423
return source;
@@ -54,7 +53,7 @@ class _EqualsDart extends Matcher {
5453
final result = _dart(item, _emitter);
5554
return equals(result).describeMismatch(
5655
_source,
57-
mismatchDescription,
56+
mismatchDescription.add(result),
5857
state,
5958
verbose,
6059
);

lib/src/specs/code.dart

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ abstract class Code implements Spec {
5151
abstract class Block implements Built<Block, BlockBuilder>, Code, Spec {
5252
factory Block([void updates(BlockBuilder b)]) = _$Block;
5353

54+
factory Block.of(Iterable<Code> statements) {
55+
return new Block((b) => b..statements.addAll(statements));
56+
}
57+
5458
Block._();
5559

5660
@override
@@ -111,7 +115,33 @@ abstract class CodeEmitter implements CodeVisitor<StringSink> {
111115
}
112116
}
113117

114-
/// Represents a simple, literal [code] block to be inserted as-is.
118+
/// Represents a code block that requires lazy visiting.
119+
class LazyCode implements Code {
120+
final Spec Function(SpecVisitor) generate;
121+
122+
const LazyCode._(this.generate);
123+
124+
@override
125+
R accept<R>(CodeVisitor<R> visitor, [R context]) {
126+
return generate(visitor).accept(visitor, context);
127+
}
128+
}
129+
130+
/// Returns a generic [Code] that is lazily generated when visited.
131+
Code lazyCode(Code Function() generate) => new _LazyCode(generate);
132+
133+
class _LazyCode implements Code {
134+
final Code Function() generate;
135+
136+
const _LazyCode(this.generate);
137+
138+
@override
139+
R accept<R>(CodeVisitor<R> visitor, [R context]) {
140+
return generate().accept(visitor, context);
141+
}
142+
}
143+
144+
/// Represents a simple, literal code block to be inserted as-is.
115145
class StaticCode implements Code {
116146
final String code;
117147

@@ -126,9 +156,9 @@ class StaticCode implements Code {
126156
String toString() => code;
127157
}
128158

129-
/// Represents a [code] block that may require scoping.
159+
/// Represents a code block that may require scoping.
130160
class ScopedCode implements Code {
131-
final String Function(Allocate allocate) code;
161+
final String Function(Allocate) code;
132162

133163
const ScopedCode._(this.code);
134164

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: code_builder
2-
version: 2.0.0-alpha+3
2+
version: 2.0.0-beta
33
description: A fluent API for generating Dart code
44
author: Dart Team <[email protected]>
55
homepage: https://github.com/dart-lang/code_builder

test/specs/code/statement_test.dart

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import 'package:test/test.dart';
88
void main() {
99
test('should emit a block of code', () {
1010
expect(
11-
new Block((b) => b.statements.addAll([
12-
const Code('if (foo) {'),
13-
const Code(' print(true);'),
14-
const Code('}'),
15-
])),
11+
new Block.of([
12+
const Code('if (foo) {'),
13+
const Code(' print(true);'),
14+
const Code('}'),
15+
]),
1616
equalsDart(r'''
1717
if (foo) {
1818
print(true);
@@ -23,16 +23,37 @@ void main() {
2323

2424
test('should emit a block of code including expressions', () {
2525
expect(
26-
new Block((b) => b.statements.addAll([
27-
const Code('if (foo) {'),
28-
refer('print')([literalTrue]).statement,
29-
const Code('}'),
30-
])),
26+
new Block.of([
27+
const Code('if (foo) {'),
28+
refer('print')([literalTrue]).statement,
29+
const Code('}'),
30+
]),
3131
equalsDart(r'''
3232
if (foo) {
3333
print(true);
3434
}
3535
'''),
3636
);
3737
});
38+
39+
test('should emit a block of code with lazyily invoked generators', () {
40+
expect(
41+
new Method((b) => b
42+
..name = 'main'
43+
..body = new Block.of([
44+
const Code('if ('),
45+
lazyCode(() => refer('foo').code),
46+
const Code(') {'),
47+
refer('print')([literalTrue]).statement,
48+
const Code('}'),
49+
])),
50+
equalsDart(r'''
51+
main() {
52+
if (foo) {
53+
print(true);
54+
}
55+
}
56+
'''),
57+
);
58+
});
3859
}

0 commit comments

Comments
 (0)