Skip to content
This repository has been archived by the owner on Nov 1, 2024. It is now read-only.

New features for 1.0.0-beta #52

Merged
merged 7 commits into from
Jan 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions 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 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 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] how are you choosing between => and return? Why is this one different from decrement above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying not to use => when it creates a new line, but probably inconsistent.

}

@override
ExpressionBuilder identical(ExpressionBuilder other) {
return lib$core.identical.call([
return lib$core.identical.call(<ExpressionBuilder>[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this fixing an analyzer warning? I'd be surprised if this wasn't inferred in strong mode...

Copy link
Contributor Author

@matanlurey matanlurey Jan 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it could not infer the type and warned as such.

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 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 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].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc comment is no longer complete. This is a case where we can add useful information explaining the 'super' arguments ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged.

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 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 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