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

Commit 8d023e6

Browse files
authored
Add Expression#toStatement, and tests. (#4)
* Add Expression#toStatement, and tests. * Add example, fix doc comment.
1 parent 7383054 commit 8d023e6

File tree

4 files changed

+229
-120
lines changed

4 files changed

+229
-120
lines changed

lib/src/expression_builder.dart

Lines changed: 124 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,24 @@
55
part of code_builder;
66

77
// Shared functionality between ExpressionBuilder and _LiteralExpression.
8+
/// Represents an expression value of `false`.
9+
const literalFalse = const LiteralBool(false);
10+
11+
/// Represents an expression value of `null`.
12+
const literalNull = const _LiteralNull();
13+
14+
/// Represents an expression value of `true`.
15+
const literalTrue = const LiteralBool(true);
16+
17+
// Returns wrapped as a [ExpressionFunctionBody] AST.
818
final Token _closeP = new Token(TokenType.CLOSE_PAREN, 0);
19+
20+
// Returns wrapped as a [FunctionExpression] AST.
921
final Token _openP = new Token(TokenType.OPEN_PAREN, 0);
22+
1023
final Token _semicolon = new Token(TokenType.SEMICOLON, 0);
1124

12-
// Returns wrapped as a [ExpressionFunctionBody] AST.
25+
// TODO(matanl): Make this part of the public API. See annotation_builder.dart.
1326
ExpressionFunctionBody _asFunctionBody(CodeBuilder<Expression> expression) {
1427
return new ExpressionFunctionBody(
1528
null,
@@ -19,7 +32,6 @@ ExpressionFunctionBody _asFunctionBody(CodeBuilder<Expression> expression) {
1932
);
2033
}
2134

22-
// Returns wrapped as a [FunctionExpression] AST.
2335
FunctionExpression _asFunctionExpression(CodeBuilder<Expression> expression) {
2436
return new FunctionExpression(
2537
null,
@@ -34,6 +46,20 @@ FunctionExpression _asFunctionExpression(CodeBuilder<Expression> expression) {
3446
);
3547
}
3648

49+
ExpressionBuilder _invokeSelfImpl(
50+
ExpressionBuilder self,
51+
String name, {
52+
Iterable<CodeBuilder<Expression>> positional: const [],
53+
Map<String, CodeBuilder<Expression>> named: const {},
54+
}) {
55+
return new _InvokeExpression.target(
56+
name,
57+
self,
58+
positional,
59+
named,
60+
);
61+
}
62+
3763
/// Builds an [Expression] AST.
3864
///
3965
/// For simple literal expressions see:
@@ -59,18 +85,77 @@ abstract class ExpressionBuilder implements CodeBuilder<Expression> {
5985

6086
const ExpressionBuilder._();
6187

88+
/// Return a new [ExpressionBuilder] invoking the result of this expression.
89+
ExpressionBuilder invokeSelf(
90+
String name, {
91+
Iterable<CodeBuilder<Expression>> positional: const [],
92+
Map<String, CodeBuilder<Expression>> named: const {},
93+
}); // TODO(matanl): Rename to invoke when factory is removed.
94+
6295
/// Returns wrapped as a [ExpressionFunctionBody] AST.
6396
ExpressionFunctionBody toFunctionBody() => _asFunctionBody(this);
6497

6598
/// Returns wrapped as a [FunctionExpression] AST.
6699
FunctionExpression toFunctionExpression() => _asFunctionExpression(this);
100+
101+
/// Converts to a [StatementBuilder].
102+
///
103+
/// __Example use__:
104+
/// literalNull.toStatement(); // ==> null;
105+
StatementBuilder toStatement();
106+
}
107+
108+
/// Creates a new literal `bool` value.
109+
class LiteralBool extends _LiteralExpression<BooleanLiteral> {
110+
static final BooleanLiteral _true =
111+
new BooleanLiteral(new KeywordToken(Keyword.TRUE, 0), true);
112+
static final BooleanLiteral _false =
113+
new BooleanLiteral(new KeywordToken(Keyword.FALSE, 0), false);
114+
115+
final bool _value;
116+
117+
/// Returns the passed value as a [BooleanLiteral].
118+
const LiteralBool(this._value);
119+
120+
@override
121+
BooleanLiteral toAst() => _value ? _true : _false;
122+
}
123+
124+
/// Represents an expression value of a literal number.
125+
class LiteralInt extends _LiteralExpression<IntegerLiteral> {
126+
final int _value;
127+
128+
/// Returns the passed value as a [IntegerLiteral].
129+
const LiteralInt(this._value);
130+
131+
@override
132+
IntegerLiteral toAst() =>
133+
new IntegerLiteral(new StringToken(TokenType.INT, '$_value', 0), _value);
134+
}
135+
136+
/// Represents an expression value of a literal `'string'`.
137+
class LiteralString extends _LiteralExpression<StringLiteral> {
138+
final String _value;
139+
140+
/// Returns the passed value as a [StringLiteral].
141+
const LiteralString(this._value);
142+
143+
@override
144+
StringLiteral toAst() => new SimpleStringLiteral(
145+
new StringToken(
146+
TokenType.STRING,
147+
"'$_value'",
148+
0,
149+
),
150+
_value,
151+
);
67152
}
68153

69-
// TODO(matanl): Make this part of the public API. See annotation_builder.dart.
70154
class _InvokeExpression extends ExpressionBuilder
71155
implements CodeBuilder<InvocationExpression> {
72156
static final Token _colon = new Token(TokenType.COLON, 0);
73157

158+
final ExpressionBuilder _target;
74159
final String _name;
75160
final List<CodeBuilder<Expression>> _positionalArguments;
76161
final Map<String, CodeBuilder<Expression>> _namedArguments;
@@ -80,8 +165,35 @@ class _InvokeExpression extends ExpressionBuilder
80165
this._positionalArguments,
81166
this._namedArguments,
82167
)
168+
: _target = null,
169+
super._();
170+
171+
const _InvokeExpression.target(
172+
this._name, this._target, this._positionalArguments, this._namedArguments)
83173
: super._();
84174

175+
@override
176+
ExpressionBuilder invokeSelf(
177+
String name, {
178+
Iterable<CodeBuilder<Expression>> positional: const [],
179+
Map<String, CodeBuilder<Expression>> named: const {},
180+
}) =>
181+
_invokeSelfImpl(this, name, positional: positional, named: named);
182+
183+
@override
184+
InvocationExpression toAst() {
185+
return new MethodInvocation(
186+
_target?.toAst(),
187+
_target != null ? new Token(TokenType.PERIOD, 0) : null,
188+
_stringId(_name),
189+
null,
190+
_getArgumentList(),
191+
);
192+
}
193+
194+
@override
195+
StatementBuilder toStatement() => new StatementBuilder.fromExpression(this);
196+
85197
ArgumentList _getArgumentList() {
86198
return new ArgumentList(
87199
new Token(TokenType.OPEN_CURLY_BRACKET, 0),
@@ -97,55 +209,30 @@ class _InvokeExpression extends ExpressionBuilder
97209
new Token(TokenType.CLOSE_CURLY_BRACKET, 0),
98210
);
99211
}
100-
101-
@override
102-
InvocationExpression toAst() {
103-
return new MethodInvocation(
104-
null,
105-
null,
106-
_stringId(_name),
107-
null,
108-
_getArgumentList(),
109-
);
110-
}
111212
}
112213

113214
abstract class _LiteralExpression<A extends Literal>
114215
implements ExpressionBuilder, CodeBuilder<A> {
115216
const _LiteralExpression();
116217

218+
@override
219+
ExpressionBuilder invokeSelf(
220+
String name, {
221+
Iterable<CodeBuilder<Expression>> positional: const [],
222+
Map<String, CodeBuilder<Expression>> named: const {},
223+
}) =>
224+
_invokeSelfImpl(this, name, positional: positional, named: named);
225+
117226
@override
118227
ExpressionFunctionBody toFunctionBody() => _asFunctionBody(this);
119228

120229
@override
121230
FunctionExpression toFunctionExpression() => _asFunctionExpression(this);
122-
}
123-
124-
/// Represents an expression value of `true`.
125-
const literalTrue = const LiteralBool(true);
126-
127-
/// Represents an expression value of `false`.
128-
const literalFalse = const LiteralBool(false);
129-
130-
/// Creates a new literal `bool` value.
131-
class LiteralBool extends _LiteralExpression<BooleanLiteral> {
132-
static final BooleanLiteral _true =
133-
new BooleanLiteral(new KeywordToken(Keyword.TRUE, 0), true);
134-
static final BooleanLiteral _false =
135-
new BooleanLiteral(new KeywordToken(Keyword.FALSE, 0), false);
136-
137-
final bool _value;
138-
139-
/// Returns the passed value as a [BooleanLiteral].
140-
const LiteralBool(this._value);
141231

142232
@override
143-
BooleanLiteral toAst() => _value ? _true : _false;
233+
StatementBuilder toStatement() => new StatementBuilder.fromExpression(this);
144234
}
145235

146-
/// Represents an expression value of `null`.
147-
const literalNull = const _LiteralNull();
148-
149236
class _LiteralNull extends _LiteralExpression<NullLiteral> {
150237
static NullLiteral _null = new NullLiteral(new KeywordToken(Keyword.NULL, 0));
151238

@@ -154,33 +241,3 @@ class _LiteralNull extends _LiteralExpression<NullLiteral> {
154241
@override
155242
NullLiteral toAst() => _null;
156243
}
157-
158-
/// Represents an expression value of a literal number.
159-
class LiteralInt extends _LiteralExpression<IntegerLiteral> {
160-
final int _value;
161-
162-
/// Returns the passed value as a [IntegerLiteral].
163-
const LiteralInt(this._value);
164-
165-
@override
166-
IntegerLiteral toAst() =>
167-
new IntegerLiteral(new StringToken(TokenType.INT, '$_value', 0), _value);
168-
}
169-
170-
/// Represents an expression value of a literal `'string'`.
171-
class LiteralString extends _LiteralExpression<StringLiteral> {
172-
final String _value;
173-
174-
/// Returns the passed value as a [StringLiteral].
175-
const LiteralString(this._value);
176-
177-
@override
178-
StringLiteral toAst() => new SimpleStringLiteral(
179-
new StringToken(
180-
TokenType.STRING,
181-
"'$_value'",
182-
0,
183-
),
184-
_value,
185-
);
186-
}

0 commit comments

Comments
 (0)