blob: e2bc1bf63eeb9528bdcf7f396c77bd5d0cab09f0 [file] [log] [blame]
// Copyright (c) 2016, 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:analyzer/analyzer.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:code_builder/src/builders/shared.dart';
import 'package:code_builder/src/builders/expression.dart';
import 'package:code_builder/src/builders/statement.dart';
import 'package:code_builder/src/tokens.dart';
/// Short-hand syntax for `new SwitchCaseBuilder(...)`.
SwitchCaseBuilder switchCase(ExpressionBuilder condition,
[Iterable<StatementBuilder> statements = const []]) =>
new SwitchCaseBuilder(condition)..addStatements(statements ?? []);
/// Short-hand syntax for `new SwitchDefaultCaseBuilder(...)`.
SwitchDefaultCaseBuilder switchDefault(
[Iterable<StatementBuilder> statements = const []]) =>
new SwitchDefaultCaseBuilder()..addStatements(statements ?? []);
/// Short-hand syntax for `new SwitchStatementBuilder(...)`.
SwitchStatementBuilder switchStatement(ExpressionBuilder expression,
{Iterable<SwitchCaseBuilder> cases: const [],
SwitchDefaultCaseBuilder defaultCase}) =>
new SwitchStatementBuilder(expression)
..setDefaultCase(defaultCase)
..addCases(cases ?? []);
/// Represents an [ExpressionBuilder] and a series of [SwitchCaseBuilder]s as a switch statement AST.
abstract class SwitchStatementBuilder implements StatementBuilder {
/// Creates a new [SwitchStatementBuilder].
factory SwitchStatementBuilder(ExpressionBuilder expression,
[Iterable<ValidSwitchMember> members = const []]) =>
new _SwitchStatementBuilder(expression, members);
/// Adds a [switchCase] to the builder.
void addCase(SwitchCaseBuilder switchCase);
/// Adds a [switchCase]s to the builder.
void addCases(Iterable<SwitchCaseBuilder> switchCases);
/// Returns an [SwitchStatement] AST representing the builder.
SwitchStatement buildSwitchStatement();
/// Sets the `default` cases of the builder.
void setDefaultCase(SwitchDefaultCaseBuilder defaultCase);
}
/// A marker interface for an AST that could be added to [SwitchStatementBuilder].
///
/// This can be either a [SwitchCaseBuilder] or a [SwitchDefaultCaseBuilder].
abstract class ValidSwitchMember {}
/// Represents an [ExpressionBuilder] and a series of [Statement]s as a switch case AST.
abstract class SwitchCaseBuilder implements HasStatements, ValidSwitchMember {
/// Creates a new [SwitchCaseBuilder].
factory SwitchCaseBuilder(ExpressionBuilder condition) =>
new _SwitchCaseBuilder(condition);
/// Returns an [SwitchMember] AST representing the builder.
SwitchMember buildSwitchMember([Scope scope]);
}
/// Represents a series of [Statement]s as a default switch case AST.
abstract class SwitchDefaultCaseBuilder
implements HasStatements, ValidSwitchMember {
factory SwitchDefaultCaseBuilder() => new _SwitchDefaultCaseBuilder();
/// Returns an [SwitchMember] AST representing the builder.
SwitchMember buildSwitchMember([Scope scope]);
}
class _SwitchStatementBuilder extends Object
with TopLevelMixin
implements SwitchStatementBuilder {
final ExpressionBuilder _expression;
final List<SwitchCaseBuilder> _cases = [];
SwitchDefaultCaseBuilder _defaultCase;
_SwitchStatementBuilder(this._expression,
[Iterable<ValidSwitchMember> members = const []]) {
for (final member in members) {
if (member is SwitchDefaultCaseBuilder)
_defaultCase = member;
else if (member is SwitchCaseBuilder) _cases.add(member);
}
}
@override
void addCase(SwitchCaseBuilder switchCase) => _cases.add(switchCase);
@override
void addCases(Iterable<SwitchCaseBuilder> switchCases) =>
_cases.addAll(switchCases);
@override
void setDefaultCase(SwitchDefaultCaseBuilder defaultCase) {
_defaultCase = defaultCase;
}
@override
AstNode buildAst([Scope scope]) => buildStatement();
@override
SwitchStatement buildSwitchStatement([Scope scope]) {
var members = _cases.map((c) => c.buildSwitchMember(scope)).toList();
if (_defaultCase != null)
members.add(_defaultCase.buildSwitchMember(scope));
return astFactory.switchStatement(
$switch,
$openBracket,
_expression.buildExpression(),
$closeParen,
$openBracket,
members,
$closeBracket);
}
@override
Statement buildStatement([Scope scope]) => buildSwitchStatement(scope);
}
class _SwitchCaseBuilder extends Object
with HasStatementsMixin
implements SwitchCaseBuilder {
final ExpressionBuilder _condition;
_SwitchCaseBuilder(this._condition);
@override
AstNode buildAst([Scope scope]) => buildSwitchMember(scope);
@override
SwitchMember buildSwitchMember([Scope scope]) => astFactory.switchCase(null,
$case, _condition.buildExpression(), $colon, buildStatements(scope));
}
class _SwitchDefaultCaseBuilder extends Object
with HasStatementsMixin
implements SwitchDefaultCaseBuilder {
@override
AstNode buildAst([Scope scope]) => buildSwitchMember(scope);
@override
SwitchMember buildSwitchMember([Scope scope]) =>
astFactory.switchDefault(null, $default, $colon, buildStatements());
}