diff --git a/pkg/analyzer/lib/src/kernel/resynthesize.dart b/pkg/analyzer/lib/src/kernel/resynthesize.dart index 489bc4e1705..01f88a8692d 100644 --- a/pkg/analyzer/lib/src/kernel/resynthesize.dart +++ b/pkg/analyzer/lib/src/kernel/resynthesize.dart @@ -354,11 +354,21 @@ class _ExprBuilder { return initializer; } - if (k is kernel.AssertInitializer) { - var body = k.statement; - var condition = build(body.condition); - var message = body.message != null ? build(body.message) : null; - return AstTestFactory.assertInitializer(condition, message); + if (k is kernel.LocalInitializer) { + var invocation = k.variable.initializer; + if (invocation is kernel.MethodInvocation) { + var receiver = invocation.receiver; + if (receiver is kernel.FunctionExpression && + invocation.name.name == 'call') { + var body = receiver.function.body; + if (body is kernel.AssertStatement) { + var condition = build(body.condition); + var message = body.message != null ? build(body.message) : null; + return AstTestFactory.assertInitializer(condition, message); + } + } + } + throw new StateError('Expected assert initializer $k'); } if (k is kernel.RedirectingInitializer) { diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 1243dd1aaa3..81eacb65fc8 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -2941,11 +2941,33 @@ class BodyBuilder extends ScopeListener implements BuilderHelper { break; case Assert.Initializer: - push(new ShadowAssertInitializer(statement)); + push(buildAssertInitializer(statement)); break; } } + Initializer buildAssertInitializer(AssertStatement statement) { + // Since kernel only has asserts in statment form, we convert it to an + // expression by wrapping it in an anonymous function which we call + // immediately. + // + // Additionally, kernel has no initializer that evaluates an expression, + // but it does have `LocalInitializer` which requires a variable declartion. + // + // So we produce an initializer like this: + // + // var #t0 = (() { statement; }) () + return new ShadowAssertInitializer( + new VariableDeclaration.forValue(buildMethodInvocation( + new FunctionExpression(new FunctionNode(statement)), + callName, + new Arguments.empty(), + statement.fileOffset, + isConstantExpression: true, + isImplicitCall: true)), + statement); + } + @override void endYieldStatement(Token yieldToken, Token starToken, Token endToken) { debugEvent("YieldStatement"); diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart index 4e0d7a584f0..b3fcd4433e2 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart @@ -119,14 +119,18 @@ class ShadowAsExpression extends AsExpression implements ShadowExpression { } /// Concrete shadow object representing an assert initializer in kernel form. -class ShadowAssertInitializer extends AssertInitializer +class ShadowAssertInitializer extends LocalInitializer implements ShadowInitializer { - ShadowAssertInitializer(AssertStatement statement) : super(statement); + /// The assert statement performing the check + AssertStatement _statement; + + ShadowAssertInitializer(VariableDeclaration variable, this._statement) + : super(variable); @override void _inferInitializer(ShadowTypeInferrer inferrer) { inferrer.listener.assertInitializerEnter(this); - inferrer.inferStatement(statement); + inferrer.inferStatement(_statement); inferrer.listener.assertInitializerExit(this); } } diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart index a6d7113b239..e8c364297d4 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart @@ -107,10 +107,10 @@ class TypeInferenceListener void asExpressionExit(AsExpression expression, DartType inferredType) => genericExpressionExit("asExpression", expression, inferredType); - void assertInitializerEnter(AssertInitializer initializer) => + void assertInitializerEnter(LocalInitializer initializer) => genericInitializerEnter("assertInitializer", initializer); - void assertInitializerExit(AssertInitializer initializer) => + void assertInitializerExit(LocalInitializer initializer) => genericInitializerExit("assertInitializer", initializer); void assertStatementEnter(AssertStatement statement) => diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.direct.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.direct.expect index 602da122444..37c1eede8ba 100644 --- a/pkg/front_end/testcases/inference/assert_initializer.dart.direct.expect +++ b/pkg/front_end/testcases/inference/assert_initializer.dart.direct.expect @@ -4,10 +4,14 @@ import "dart:core" as core; class C extends core::Object { constructor expressionOnly() → void - : assert(self::f()), super core::Object::•() + : final dynamic #t1 = (() → dynamic + assert(self::f()); +).call(), super core::Object::•() ; constructor expressionAndMessage() → void - : assert(self::f(), self::f()), super core::Object::•() + : final dynamic #t2 = (() → dynamic + assert(self::f(), self::f()); +).call(), super core::Object::•() ; } static method f() → self::f::T diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.strong.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.strong.expect index 27f0c32931a..ecd205de70f 100644 --- a/pkg/front_end/testcases/inference/assert_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/inference/assert_initializer.dart.strong.expect @@ -4,10 +4,14 @@ import "dart:core" as core; class C extends core::Object { constructor expressionOnly() → void - : assert(self::f()), super core::Object::•() + : final dynamic #t1 = (() → dynamic + assert(self::f()); +).call(), super core::Object::•() ; constructor expressionAndMessage() → void - : assert(self::f(), self::f()), super core::Object::•() + : final dynamic #t2 = (() → dynamic + assert(self::f(), self::f()); +).call(), super core::Object::•() ; } static method f() → self::f::T diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.direct.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.direct.expect index c72d875497f..5871a4e3404 100644 --- a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.direct.expect +++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.direct.expect @@ -4,7 +4,9 @@ import "dart:core" as core; class C extends core::Object { constructor •(core::Object o) → void - : assert(o), super core::Object::•() + : final dynamic #t1 = (() → dynamic + assert(o); +).call(), super core::Object::•() ; } static method main() → dynamic { diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.strong.expect index 7d2a4f16efd..3b9eddc4ff9 100644 --- a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.strong.expect +++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.strong.expect @@ -4,7 +4,9 @@ import "dart:core" as core; class C extends core::Object { constructor •(core::Object o) → void - : assert(o as{TypeError} core::bool), super core::Object::•() + : final dynamic #t1 = (() → dynamic + assert(o as{TypeError} core::bool); +).call(), super core::Object::•() ; } static method main() → dynamic { diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md index 9556f070037..561778c5374 100644 --- a/pkg/kernel/binary.md +++ b/pkg/kernel/binary.md @@ -408,12 +408,6 @@ type LocalInitializer extends Initializer { VariableDeclaration variable; } -type AssertInitializer extends Initializer { - Byte tag = 12; - Byte isSynthetic; - AssertStatement statement; -} - /* enum AsyncMarker { Sync, diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index a64931739e8..e9505e46a45 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -1759,25 +1759,6 @@ class LocalInitializer extends Initializer { } } -class AssertInitializer extends Initializer { - AssertStatement statement; - - AssertInitializer(this.statement) { - statement.parent = this; - } - - accept(InitializerVisitor v) => v.visitAssertInitializer(this); - - visitChildren(Visitor v) { - statement.accept(v); - } - - transformChildren(Transformer v) { - statement = statement.accept(v); - statement.parent = this; - } -} - // ------------------------------------------------------------------------ // FUNCTIONS // ------------------------------------------------------------------------ diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index e755e16f81a..b783dc5da88 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -1010,8 +1010,6 @@ class BinaryBuilder { readMemberReference(), readArguments()); case Tag.LocalInitializer: return new LocalInitializer(readAndPushVariableDeclaration()); - case Tag.AssertInitializer: - return new AssertInitializer(readStatement()); default: throw fail('Invalid initializer tag: $tag'); } diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 59e4938e656..a7d741b0ee0 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -833,12 +833,6 @@ class BinaryPrinter extends Visitor implements BinarySink { writeVariableDeclaration(node.variable); } - visitAssertInitializer(AssertInitializer node) { - writeByte(Tag.AssertInitializer); - writeByte(node.isSynthetic ? 1 : 0); - writeNode(node.statement); - } - visitFunctionNode(FunctionNode node) { writeByte(Tag.FunctionNode); assert(_variableIndexer != null); diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart index 4fad0cd6e0b..1325ce33ac0 100644 --- a/pkg/kernel/lib/binary/tag.dart +++ b/pkg/kernel/lib/binary/tag.dart @@ -21,7 +21,6 @@ class Tag { static const int SuperInitializer = 9; static const int RedirectingInitializer = 10; static const int LocalInitializer = 11; - static const int AssertInitializer = 12; static const int CheckLibraryIsLoaded = 13; static const int LoadLibrary = 14; diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart index ce21cfe4537..355176896ff 100644 --- a/pkg/kernel/lib/text/ast_to_text.dart +++ b/pkg/kernel/lib/text/ast_to_text.dart @@ -1425,10 +1425,8 @@ class Printer extends Visitor { endLine(';'); } - visitAssertStatement(AssertStatement node, {bool asExpr = false}) { - if (asExpr != true) { - writeIndentation(); - } + visitAssertStatement(AssertStatement node) { + writeIndentation(); writeWord('assert'); writeSymbol('('); writeExpression(node.condition); @@ -1436,11 +1434,7 @@ class Printer extends Visitor { writeComma(); writeExpression(node.message); } - if (asExpr != true) { - endLine(');'); - } else { - writeSymbol(')'); - } + endLine(');'); } visitLabeledStatement(LabeledStatement node) { @@ -1712,10 +1706,6 @@ class Printer extends Visitor { writeVariableDeclaration(node.variable); } - visitAssertInitializer(AssertInitializer node) { - visitAssertStatement(node.statement, asExpr: true); - } - defaultInitializer(Initializer node) { writeIndentation(); endLine(': ${node.runtimeType}'); diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart index 6c8ccb0ecde..ba0d04bf44f 100644 --- a/pkg/kernel/lib/type_checker.dart +++ b/pkg/kernel/lib/type_checker.dart @@ -998,11 +998,6 @@ class TypeCheckingVisitor visitVariableDeclaration(node.variable); } - @override - visitAssertInitializer(AssertInitializer node) { - visitAssertStatement(node.statement); - } - @override visitInvalidInitializer(InvalidInitializer node) {} diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart index 6db182d9f40..2c45328509c 100644 --- a/pkg/kernel/lib/visitor.dart +++ b/pkg/kernel/lib/visitor.dart @@ -120,7 +120,6 @@ abstract class InitializerVisitor { R visitRedirectingInitializer(RedirectingInitializer node) => defaultInitializer(node); R visitLocalInitializer(LocalInitializer node) => defaultInitializer(node); - R visitAssertInitializer(AssertInitializer node) => defaultInitializer(node); } class TreeVisitor @@ -236,7 +235,6 @@ class TreeVisitor R visitRedirectingInitializer(RedirectingInitializer node) => defaultInitializer(node); R visitLocalInitializer(LocalInitializer node) => defaultInitializer(node); - R visitAssertInitializer(AssertInitializer node) => defaultInitializer(node); // Other tree nodes R visitLibrary(Library node) => defaultTreeNode(node); diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index da2cd378571..13e1a549f25 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -1126,9 +1126,6 @@ void StreamingScopeBuilder::VisitInitializer() { case kLocalInitializer: VisitVariableDeclaration(); // read variable. return; - case kAssertInitializer: - VisitStatement(); - return; default: H.ReportError("Unsupported tag at this point: %d.", tag); UNREACHABLE(); @@ -3726,10 +3723,6 @@ Fragment StreamingFlowGraphBuilder::BuildInitializers( instructions += BuildFieldInitializer(canonical_name); // read value. break; } - case kAssertInitializer: { - instructions += BuildStatement(); - break; - } case kSuperInitializer: { NameIndex canonical_target = ReadCanonicalNameReference(); // read target_reference. @@ -4783,9 +4776,6 @@ void StreamingFlowGraphBuilder::SkipInitializer() { case kLocalInitializer: SkipVariableDeclaration(); // read variable. return; - case kAssertInitializer: - SkipStatement(); - return; default: H.ReportError("Unsupported tag at this point: %d.", tag); UNREACHABLE(); diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index edc7192c060..852448a752d 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h @@ -38,7 +38,6 @@ enum Tag { kSuperInitializer = 9, kRedirectingInitializer = 10, kLocalInitializer = 11, - kAssertInitializer = 12, kDirectPropertyGet = 15, kDirectPropertySet = 16,