Skip to content

Commit

Permalink
New features for 1.0.0-beta (dart-archive/code_builder#52)
Browse files Browse the repository at this point in the history
* Add for/for-in loop

Closes https://github.com/dart-lang/code_builder/issues/49

* Add support for while/do-while

* Add constructor initializers

Closes https://github.com/dart-lang/code_builder/issues/50

* Update CHANGELOG and pubspec for beta

* Add “name” getter for ParameterBuilder

Partial support towards https://github.com/dart-lang/code_builder/issues/43

* Update CHANGELOG

* Address feedback
  • Loading branch information
matanlurey authored Jan 5, 2017
1 parent 75c8c69 commit 528393f
Show file tree
Hide file tree
Showing 13 changed files with 444 additions and 20 deletions.
9 changes: 5 additions & 4 deletions pkgs/code_builder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
## 1.0.0-alpha+9
## 1.0.0-beta

- Add support for `async`, `sync`, `sync*` functions
- Add support for expression `asAwait`, `asYield`, `asYieldStar`
- Add `toExportBuilder` and `toImportBuilder` to types and references

## 1.0.0-alpha+8

- Fix an import scoping bug in `return` statements and named constructor invocations.
- Added constructor initializer support
- Add `while` and `do {} while` loop support
- Add `for` and `for-in` support
- Added a `name` getter for `ParameterBuilder`

## 1.0.0-alpha+7

Expand Down
4 changes: 3 additions & 1 deletion pkgs/code_builder/lib/code_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export 'src/builders/statement.dart'
elseIf,
elseThen,
returnVoid,
ForStatementBuilder,
IfStatementBuilder,
StatementBuilder;
StatementBuilder,
WhileStatementBuilder;
export 'src/builders/type.dart' show NewInstanceBuilder, TypeBuilder;
61 changes: 60 additions & 1 deletion pkgs/code_builder/lib/src/builders/expression.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:code_builder/src/builders/reference.dart';
import 'package:code_builder/src/builders/shared.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';
import 'package:code_builder/src/builders/type.dart';
import 'package:code_builder/src/tokens.dart';

Expand All @@ -35,6 +36,9 @@ final _null = astFactory.nullLiteral(new KeywordToken(Keyword.NULL, 0));
final _true =
astFactory.booleanLiteral(new KeywordToken(Keyword.TRUE, 0), true);

/// A reference to `super`.
ExpressionBuilder get superRef => new _SuperExpression();

/// Returns a pre-defined literal expression of [value].
///
/// Only primitive values are allowed.
Expand Down Expand Up @@ -123,6 +127,24 @@ abstract class AbstractExpressionMixin implements ExpressionBuilder {
);
}

@override
ExpressionBuilder operator >(ExpressionBuilder other) {
return new _AsBinaryExpression(
this,
other,
$gt,
);
}

@override
ExpressionBuilder operator <(ExpressionBuilder other) {
return new _AsBinaryExpression(
this,
other,
$lt,
);
}

@override
ExpressionBuilder and(ExpressionBuilder other) {
return new _AsBinaryExpression(
Expand Down Expand Up @@ -176,6 +198,11 @@ abstract class AbstractExpressionMixin implements ExpressionBuilder {
@override
StatementBuilder asYieldStar() => new _AsYield(this, true);

@override
WhileStatementBuilder asWhile({bool asDo: false}) {
return new WhileStatementBuilder(asDo, this);
}

@override
Statement buildStatement([Scope scope]) {
return asStatement().buildStatement(scope);
Expand All @@ -200,6 +227,9 @@ abstract class AbstractExpressionMixin implements ExpressionBuilder {
return new _CascadeExpression(this, create(reference('.')));
}

@override
ExpressionBuilder decrement() => new _DecrementExpression(this);

@override
ExpressionBuilder equals(ExpressionBuilder other) {
return new _AsBinaryExpression(
Expand All @@ -209,9 +239,14 @@ abstract class AbstractExpressionMixin implements ExpressionBuilder {
);
}

@override
ExpressionBuilder increment([bool prefix = false]) {
return new _IncrementExpression(this, prefix);
}

@override
ExpressionBuilder identical(ExpressionBuilder other) {
return lib$core.identical.call([
return lib$core.identical.call(<ExpressionBuilder>[
this,
other,
]);
Expand Down Expand Up @@ -275,6 +310,12 @@ abstract class ExpressionBuilder
/// Returns as an [ExpressionBuilder] dividing by [other].
ExpressionBuilder operator /(ExpressionBuilder other);

/// Returns as an [ExpressionBuilder] `<` by [other].
ExpressionBuilder operator <(ExpressionBuilder other);

/// Returns as an [ExpressionBuilder] `>` by [other].
ExpressionBuilder operator >(ExpressionBuilder other);

/// Returns as an [ExpressionBuilder] `&&` [other].
ExpressionBuilder and(ExpressionBuilder other);

Expand Down Expand Up @@ -323,6 +364,9 @@ abstract class ExpressionBuilder
/// Returns as a [StatementBuilder] yielding this one.
StatementBuilder asYieldStar();

/// Returns as a [WhileStatementBuilder] with this as the condition.
WhileStatementBuilder asWhile({bool asDo: false});

/// Returns an [Expression] AST representing the builder.
Expression buildExpression([Scope scope]);

Expand All @@ -337,12 +381,18 @@ abstract class ExpressionBuilder
Iterable<ExpressionBuilder> create(ExpressionBuilder self),
);

/// Returns as an [ExpressionBuilder] decrementing this expression.
ExpressionBuilder decrement();

/// Returns as an [ExpressionBuilder] comparing using `==` against [other].
ExpressionBuilder equals(ExpressionBuilder other);

/// Returns as an [ExpressionBuilder] comparing using `identical`.
ExpressionBuilder identical(ExpressionBuilder other);

/// Returns as an [ExpressionBuilder] incrementing this expression.
ExpressionBuilder increment([bool prefix = false]);

/// Returns as an [InvocationBuilder] on [method] of this expression.
InvocationBuilder invoke(
String method,
Expand Down Expand Up @@ -476,6 +526,15 @@ ExpressionBuilder _expressionify(v) {
throw new ArgumentError('Could not expressionify $v');
}

class _SuperExpression extends Object
with AbstractExpressionMixin, TopLevelMixin {
@override
AstNode buildAst([Scope scope]) => buildExpression(scope);

@override
Expression buildExpression([_]) => astFactory.superExpression($super);
}

class _TypedListExpression extends Object
with AbstractExpressionMixin, TopLevelMixin {
static List<ExpressionBuilder> _toExpression(Iterable values) {
Expand Down
43 changes: 43 additions & 0 deletions pkgs/code_builder/lib/src/builders/expression/operators.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,46 @@ class _AsBinaryExpression extends Object
);
}
}

class _DecrementExpression extends Object
with AbstractExpressionMixin, TopLevelMixin {
final ExpressionBuilder _expression;

_DecrementExpression(this._expression);

@override
AstNode buildAst([Scope scope]) => buildExpression(scope);

@override
Expression buildExpression([Scope scope]) {
return astFactory.postfixExpression(
_expression.buildExpression(scope),
$minusMinus,
);
}
}

class _IncrementExpression extends Object
with AbstractExpressionMixin, TopLevelMixin {
final ExpressionBuilder _expression;
final bool _prefix;

_IncrementExpression(this._expression, this._prefix);

@override
AstNode buildAst([Scope scope]) => buildExpression(scope);

@override
Expression buildExpression([Scope scope]) {
if (_prefix) {
return astFactory.prefixExpression(
$plusPlus,
_expression.buildExpression(scope),
);
}
return astFactory.postfixExpression(
_expression.buildExpression(scope),
$plusPlus,
);
}
}
78 changes: 71 additions & 7 deletions pkgs/code_builder/lib/src/builders/method.dart
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ ConstructorBuilder _constructorImpl({
throw new StateError('Invalid AST type: ${member.runtimeType}');
}
}
final constructor = new ConstructorBuilder(name);
final constructor = new ConstructorBuilder(name: name);
_addFunctions.forEach((a) => a(constructor));
return constructor;
}
Expand All @@ -186,7 +186,20 @@ abstract class ConstructorBuilder
HasStatements,
ValidClassMember {
/// Create a new [ConstructorBuilder], optionally with a [name].
factory ConstructorBuilder([String name]) = _NormalConstructorBuilder;
///
/// Can invoke `super` if [invokeSuper] is set, using super.[superName].
factory ConstructorBuilder({
String name,
String superName,
List<ExpressionBuilder> invokeSuper,
}) = _NormalConstructorBuilder;

/// Adds a field initializer to this constructor.
void addInitializer(
String fieldName, {
ExpressionBuilder toExpression,
String toParameter,
});

@override
void addNamed(ParameterBuilder parameter, {bool asField: false});
Expand Down Expand Up @@ -530,18 +543,69 @@ class _NamedParameterWrapper
class _NormalConstructorBuilder extends Object
with HasAnnotationsMixin, HasParametersMixin, HasStatementsMixin
implements ConstructorBuilder {
final _initializers = <String, ExpressionBuilder>{};
final String _name;
final String _superName;
final List<ExpressionBuilder> _superInvocation;

_NormalConstructorBuilder([this._name]);
_NormalConstructorBuilder({
List<ExpressionBuilder> invokeSuper,
String name,
String superName,
})
: _name = name,
_superInvocation = invokeSuper,
_superName = superName;

@override
void addInitializer(
String fieldName, {
ExpressionBuilder toExpression,
String toParameter,
}) {
_initializers[fieldName] = toExpression ?? reference(toParameter);
}

@override
ConstructorDeclaration buildAst([Scope scope]) {
throw new UnsupportedError('Can only be built as part of a class.');
}

@override
ConstructorDeclaration buildConstructor(TypeBuilder returnType,
[Scope scope]) {
ConstructorDeclaration buildConstructor(
TypeBuilder returnType, [
Scope scope,
]) {
List<ConstructorInitializer> initializers;
if (_initializers.isNotEmpty) {
initializers ??= [];
initializers.addAll(
_initializers.keys.map((fieldName) {
return astFactory.constructorFieldInitializer(
null,
null,
astFactory.simpleIdentifier(stringToken(fieldName)),
$equals,
_initializers[fieldName].buildExpression(scope),
);
}),
);
}
if (_superInvocation != null) {
initializers ??= [];
initializers.add(astFactory.superConstructorInvocation(
$super,
_superName != null ? $period : null,
_superName != null
? astFactory.simpleIdentifier(stringToken(_superName))
: null,
astFactory.argumentList(
$openParen,
_superInvocation.map((e) => e.buildExpression(scope)).toList(),
$closeParen,
),
));
}
return astFactory.constructorDeclaration(
null,
buildAnnotations(scope),
Expand All @@ -552,8 +616,8 @@ class _NormalConstructorBuilder extends Object
_name != null ? $period : null,
_name != null ? stringIdentifier(_name) : null,
buildParameterList(scope),
null,
null,
initializers != null && initializers.isNotEmpty ? $semicolon : null,
initializers,
null,
!hasStatements
? astFactory.emptyFunctionBody($semicolon)
Expand Down
18 changes: 12 additions & 6 deletions pkgs/code_builder/lib/src/builders/parameter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ abstract class ParameterBuilder

/// Returns a positional [FormalParameter] AST representing the builder.
FormalParameter buildPositional(bool field, [Scope scope]);

/// Name of the parameter.
String get name;
}

/// A marker interface for an AST that could be added to [ParameterBuilder].
Expand Down Expand Up @@ -140,6 +143,9 @@ class _OptionalParameterBuilder extends Object
_expression?.buildExpression(scope),
);
}

@override
String get name => _parameter.name;
}

class _ParameterPair {
Expand All @@ -165,15 +171,15 @@ class _ParameterPair {
class _SimpleParameterBuilder extends Object
with HasAnnotationsMixin
implements ParameterBuilder {
final String _name;
@override
final String name;
final TypeBuilder _type;

_SimpleParameterBuilder(
String name, {
this.name, {
TypeBuilder type,
})
: _name = name,
_type = type;
: _type = type;

@override
ParameterBuilder asOptional([ExpressionBuilder defaultTo]) {
Expand All @@ -198,7 +204,7 @@ class _SimpleParameterBuilder extends Object
_type?.buildType(scope),
$this,
$period,
stringIdentifier(_name),
stringIdentifier(name),
null,
null,
);
Expand All @@ -208,7 +214,7 @@ class _SimpleParameterBuilder extends Object
buildAnnotations(scope),
null,
_type?.buildType(scope),
stringIdentifier(_name),
stringIdentifier(name),
);
}
}
4 changes: 4 additions & 0 deletions pkgs/code_builder/lib/src/builders/statement.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ import 'package:code_builder/src/builders/shared.dart';
import 'package:code_builder/src/builders/statement/if.dart';
import 'package:code_builder/src/tokens.dart';

export 'package:code_builder/src/builders/statement/for.dart'
show ForStatementBuilder;
export 'package:code_builder/src/builders/statement/if.dart'
show IfStatementBuilder, elseIf, elseThen, ifThen;
export 'package:code_builder/src/builders/statement/while.dart'
show WhileStatementBuilder;

/// An [AstBuilder] that can add [StatementBuilder].
abstract class HasStatements implements AstBuilder {
Expand Down
Loading

0 comments on commit 528393f

Please sign in to comment.