From 9d80c4db578ed68e633e29f3319c9db42dfe0ae9 Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Wed, 7 Apr 2021 08:30:47 +0000 Subject: [PATCH] [kernel,vm] Migrate vm transformations in package:kernel TEST=existing Change-Id: I86dfda23fa32ecb924fa6c202e7142cb8a258dc6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/192145 Commit-Queue: Johnni Winther Reviewed-by: Aske Simon Christensen --- .../lib/src/fasta/kernel/kernel_target.dart | 2 +- pkg/kernel/lib/core_types.dart | 8 +- pkg/kernel/lib/target/targets.dart | 11 +- pkg/kernel/lib/transformations/async.dart | 66 ++-- .../lib/transformations/continuation.dart | 332 +++++++++--------- .../mixin_full_resolution.dart | 55 ++- .../lib/vm/constants_native_effects.dart | 35 +- pkg/vm/lib/target/vm.dart | 9 +- 8 files changed, 261 insertions(+), 257 deletions(-) diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart index 456dc0901e4..66d862bb496 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart @@ -1266,7 +1266,7 @@ class KernelTarget extends TargetImplementation { ticker.logMs("Evaluated constants"); backendTarget.performTransformationsOnProcedure( - loader.coreTypes, loader.hierarchy, procedure, + loader.coreTypes, loader.hierarchy, procedure, environmentDefines, logger: (String msg) => ticker.logMs(msg)); } diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart index 337ed54729b..98160cf43de 100644 --- a/pkg/kernel/lib/core_types.dart +++ b/pkg/kernel/lib/core_types.dart @@ -161,11 +161,11 @@ class CoreTypes { late final Constructor futureImplConstructor = index.getMember('dart:async', '_Future', '') as Constructor; - late final Member completeOnAsyncReturn = - index.getTopLevelMember('dart:async', '_completeOnAsyncReturn'); + late final Procedure completeOnAsyncReturn = index.getTopLevelMember( + 'dart:async', '_completeOnAsyncReturn') as Procedure; - late final Member completeOnAsyncError = - index.getTopLevelMember('dart:async', '_completeOnAsyncError'); + late final Procedure completeOnAsyncError = index.getTopLevelMember( + 'dart:async', '_completeOnAsyncError') as Procedure; late final Library coreLibrary = index.getLibrary('dart:core'); diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart index 2f4eba52238..6069ec899c8 100644 --- a/pkg/kernel/lib/target/targets.dart +++ b/pkg/kernel/lib/target/targets.dart @@ -252,7 +252,7 @@ abstract class Target { // transformations. Map environmentDefines, DiagnosticReporter diagnosticReporter, - ReferenceFromIndex referenceFromIndex, + ReferenceFromIndex? referenceFromIndex, {void logger(String msg), ChangedStructureNotifier changedStructureNotifier}); @@ -262,7 +262,12 @@ abstract class Target { /// purposes. It is illegal to modify any of the enclosing nodes of the /// procedure. void performTransformationsOnProcedure( - CoreTypes coreTypes, ClassHierarchy hierarchy, Procedure procedure, + CoreTypes coreTypes, + ClassHierarchy hierarchy, + Procedure procedure, + // TODO(askesc): Consider how to generally pass compiler options to + // transformations. + Map environmentDefines, {void Function(String msg)? logger}) {} /// Whether a platform library may define a restricted type, such as `bool`, @@ -463,7 +468,7 @@ class NoneTarget extends Target { List libraries, Map environmentDefines, DiagnosticReporter diagnosticReporter, - ReferenceFromIndex referenceFromIndex, + ReferenceFromIndex? referenceFromIndex, {void Function(String msg)? logger, ChangedStructureNotifier? changedStructureNotifier}) {} diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart index d03d4db315f..f7b74c71075 100644 --- a/pkg/kernel/lib/transformations/async.dart +++ b/pkg/kernel/lib/transformations/async.dart @@ -2,8 +2,6 @@ // 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. -// @dart = 2.9 - library kernel.transformations.async; import '../kernel.dart'; @@ -83,7 +81,7 @@ class ExpressionLifter extends Transformer { ExpressionLifter(this.continuationRewriter); - StaticTypeContext get _staticTypeContext => + StatefulStaticTypeContext get _staticTypeContext => continuationRewriter.staticTypeContext; Block blockOf(List statements) { @@ -100,7 +98,7 @@ class ExpressionLifter extends Transformer { assert(statements.isEmpty); var saved = seenAwait; seenAwait = false; - Expression result = expression.accept(this); + Expression result = transform(expression); outer.addAll(statements.reversed); statements.clear(); seenAwait = seenAwait || saved; @@ -224,18 +222,18 @@ class ExpressionLifter extends Transformer { TreeNode visitPropertySet(PropertySet expr) { return transformTreeNode(expr, () { - expr.value = expr.value.accept(this)..parent = expr; - expr.receiver = expr.receiver.accept(this)..parent = expr; + expr.value = transform(expr.value)..parent = expr; + expr.receiver = transform(expr.receiver)..parent = expr; }); } TreeNode visitArguments(Arguments args) { for (var named in args.named.reversed) { - named.value = named.value.accept(this)..parent = named; + named.value = transform(named.value)..parent = named; } var positional = args.positional; for (var i = positional.length - 1; i >= 0; --i) { - positional[i] = positional[i].accept(this)..parent = args; + positional[i] = transform(positional[i])..parent = args; } // Returns the arguments, which is assumed at the call sites because they do // not replace the arguments or set parent pointers. @@ -245,7 +243,7 @@ class ExpressionLifter extends Transformer { TreeNode visitMethodInvocation(MethodInvocation expr) { return transformTreeNode(expr, () { visitArguments(expr.arguments); - expr.receiver = expr.receiver.accept(this)..parent = expr; + expr.receiver = transform(expr.receiver)..parent = expr; }); } @@ -271,7 +269,7 @@ class ExpressionLifter extends Transformer { return transformTreeNode(expr, () { var expressions = expr.expressions; for (var i = expressions.length - 1; i >= 0; --i) { - expressions[i] = expressions[i].accept(this)..parent = expr; + expressions[i] = transform(expressions[i])..parent = expr; } }); } @@ -280,8 +278,7 @@ class ExpressionLifter extends Transformer { return transformTreeNode(expr, () { var expressions = expr.expressions; for (var i = expressions.length - 1; i >= 0; --i) { - expressions[i] = expr.expressions[i].accept(this) - ..parent = expr; + expressions[i] = transform(expr.expressions[i])..parent = expr; } }); } @@ -289,8 +286,8 @@ class ExpressionLifter extends Transformer { TreeNode visitMapLiteral(MapLiteral expr) { return transformTreeNode(expr, () { for (var entry in expr.entries.reversed) { - entry.value = entry.value.accept(this)..parent = entry; - entry.key = entry.key.accept(this)..parent = entry; + entry.value = transform(entry.value)..parent = entry; + entry.key = transform(entry.key)..parent = entry; } }); } @@ -302,16 +299,15 @@ class ExpressionLifter extends Transformer { // Right is delimited because it is conditionally evaluated. var rightStatements = []; seenAwait = false; - expr.right = - delimit(() => expr.right.accept(this), rightStatements) - ..parent = expr; + expr.right = delimit(() => transform(expr.right), rightStatements) + ..parent = expr; var rightAwait = seenAwait; if (rightStatements.isEmpty) { // Easy case: right did not emit any statements. seenAwait = shouldName; return transformTreeNode(expr, () { - expr.left = expr.left.accept(this)..parent = expr; + expr.left = transform(expr.left)..parent = expr; seenAwait = seenAwait || rightAwait; }); } @@ -352,7 +348,7 @@ class ExpressionLifter extends Transformer { statements.add(new ExpressionStatement(new VariableSet(result, test))); seenAwait = false; - test.receiver = test.receiver.accept(this)..parent = test; + test.receiver = transform(test.receiver)..parent = test; ++nameIndex; seenAwait = seenAwait || rightAwait; @@ -368,7 +364,7 @@ class ExpressionLifter extends Transformer { var thenStatements = []; seenAwait = false; - expr.then = delimit(() => expr.then.accept(this), thenStatements) + expr.then = delimit(() => transform(expr.then), thenStatements) ..parent = expr; var thenAwait = seenAwait; @@ -377,9 +373,9 @@ class ExpressionLifter extends Transformer { var otherwiseStatements = []; seenAwait = false; - expr.otherwise = delimit( - () => expr.otherwise.accept(this), otherwiseStatements) - ..parent = expr; + expr.otherwise = + delimit(() => transform(expr.otherwise), otherwiseStatements) + ..parent = expr; var otherwiseAwait = seenAwait; // Only one side of this branch will get executed at a time, so just make @@ -392,7 +388,7 @@ class ExpressionLifter extends Transformer { // Easy case: neither then nor otherwise emitted any statements. seenAwait = shouldName; return transformTreeNode(expr, () { - expr.condition = expr.condition.accept(this)..parent = expr; + expr.condition = transform(expr.condition)..parent = expr; seenAwait = seenAwait || thenAwait || otherwiseAwait; }); } @@ -416,7 +412,7 @@ class ExpressionLifter extends Transformer { statements.add(branch); seenAwait = false; - branch.condition = branch.condition.accept(this)..parent = branch; + branch.condition = transform(branch.condition)..parent = branch; ++nameIndex; seenAwait = seenAwait || thenAwait || otherwiseAwait; @@ -473,8 +469,7 @@ class ExpressionLifter extends Transformer { seenAwait = false; var index = nameIndex; - arguments.positional[0] = expr.operand.accept(this) - ..parent = arguments; + arguments.positional[0] = transform(expr.operand)..parent = arguments; if (shouldName && index + 1 > nameIndex) nameIndex = index + 1; seenAwait = true; @@ -487,7 +482,7 @@ class ExpressionLifter extends Transformer { } TreeNode visitLet(Let expr) { - var body = expr.body.accept(this); + var body = transform(expr.body); VariableDeclaration variable = expr.variable; if (seenAwait) { @@ -508,7 +503,7 @@ class ExpressionLifter extends Transformer { statements.add(variable); var index = nameIndex; seenAwait = false; - variable.initializer = variable.initializer.accept(this) + variable.initializer = transform(variable.initializer!) ..parent = variable; // Temporaries used in the initializer or the body are not live but the // temporary used for the body is. @@ -521,7 +516,7 @@ class ExpressionLifter extends Transformer { return transformTreeNode(expr, () { // The body has already been translated. expr.body = body..parent = expr; - variable.initializer = variable.initializer.accept(this) + variable.initializer = transform(variable.initializer!) ..parent = variable; }); } @@ -535,17 +530,17 @@ class ExpressionLifter extends Transformer { TreeNode visitBlockExpression(BlockExpression expr) { return transformTreeNode(expr, () { - expr.value = expr.value.accept(this)..parent = expr; + expr.value = transform(expr.value)..parent = expr; List body = []; for (Statement stmt in expr.body.statements.reversed) { - Statement translation = stmt.accept(this); + Statement? translation = _rewriteStatement(stmt); if (translation != null) body.add(translation); } expr.body = new Block(body.reversed.toList())..parent = expr; }); } - TreeNode defaultStatement(Statement stmt) { + Statement? _rewriteStatement(Statement stmt) { // This method translates a statement nested in an expression (e.g., in a // block expression). It produces a translated statement, a list of // statements which are side effects necessary for any await, and a flag @@ -570,4 +565,9 @@ class ExpressionLifter extends Transformer { statements.addAll(results.reversed); return null; } + + TreeNode defaultStatement(Statement stmt) { + throw new UnsupportedError( + "Use _rewriteStatement to transform statement: ${stmt}"); + } } diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart index 56af5c723d9..c477db5eb8a 100644 --- a/pkg/kernel/lib/transformations/continuation.dart +++ b/pkg/kernel/lib/transformations/continuation.dart @@ -2,8 +2,6 @@ // 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. -// @dart = 2.9 - library kernel.transformations.continuation; import 'dart:math' as math; @@ -50,7 +48,7 @@ class ContinuationVariables { void transformLibraries( TypeEnvironment typeEnvironment, List libraries, - {bool productMode}) { + {required bool productMode}) { var helper = new HelperNodes.fromCoreTypes(typeEnvironment.coreTypes, productMode); var rewriter = new RecursiveContinuationRewriter( @@ -62,7 +60,7 @@ void transformLibraries( Component transformComponent( TypeEnvironment typeEnvironment, Component component, - {bool productMode}) { + {required bool productMode}) { var helper = new HelperNodes.fromCoreTypes(typeEnvironment.coreTypes, productMode); var rewriter = new RecursiveContinuationRewriter( @@ -72,7 +70,7 @@ Component transformComponent( Procedure transformProcedure( TypeEnvironment typeEnvironment, Procedure procedure, - {bool productMode}) { + {required bool productMode}) { var helper = new HelperNodes.fromCoreTypes(typeEnvironment.coreTypes, productMode); var rewriter = new RecursiveContinuationRewriter( @@ -101,14 +99,14 @@ class RecursiveContinuationRewriter extends RemovingTransformer { return transform(node); } - visitField(Field node, TreeNode removalSentinel) { + visitField(Field node, TreeNode? removalSentinel) { staticTypeContext.enterMember(node); final result = super.visitField(node, removalSentinel); staticTypeContext.leaveMember(node); return result; } - visitConstructor(Constructor node, TreeNode removalSentinel) { + visitConstructor(Constructor node, TreeNode? removalSentinel) { staticTypeContext.enterMember(node); final result = super.visitConstructor(node, removalSentinel); staticTypeContext.leaveMember(node); @@ -116,7 +114,7 @@ class RecursiveContinuationRewriter extends RemovingTransformer { } @override - visitProcedure(Procedure node, TreeNode removalSentinel) { + visitProcedure(Procedure node, TreeNode? removalSentinel) { staticTypeContext.enterMember(node); final result = node.isAbstract ? node : super.visitProcedure(node, removalSentinel); @@ -125,15 +123,15 @@ class RecursiveContinuationRewriter extends RemovingTransformer { } @override - visitLibrary(Library node, TreeNode removalSentinel) { + visitLibrary(Library node, TreeNode? removalSentinel) { staticTypeContext.enterLibrary(node); - Library result = super.visitLibrary(node, removalSentinel); + Library result = super.visitLibrary(node, removalSentinel) as Library; staticTypeContext.leaveLibrary(node); return result; } @override - visitFunctionNode(FunctionNode node, TreeNode removalSentinel) { + visitFunctionNode(FunctionNode node, TreeNode? removalSentinel) { switch (node.asyncMarker) { case AsyncMarker.Sync: case AsyncMarker.SyncYielding: @@ -149,13 +147,11 @@ class RecursiveContinuationRewriter extends RemovingTransformer { case AsyncMarker.AsyncStar: return new AsyncStarFunctionRewriter(helper, node, staticTypeContext) .rewrite(); - default: - return null; } } @override - TreeNode visitForInStatement(ForInStatement stmt, TreeNode removalSentinel) { + TreeNode visitForInStatement(ForInStatement stmt, TreeNode? removalSentinel) { if (stmt.isAsync) { return super.visitForInStatement(stmt, removalSentinel); } @@ -193,7 +189,7 @@ class RecursiveContinuationRewriter extends RemovingTransformer { assert(const [ Nullability.nonNullable, Nullability.legacy - ].contains(coreTypes.iterableGetIterator.function.returnType.nullability)); + ].contains(coreTypes.iterableGetIterator.function!.returnType.nullability)); final DartType elementType = stmt.getElementType(staticTypeContext); final iteratorType = InterfaceType( @@ -271,18 +267,19 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter { DartType elementTypeFromAsyncReturnType() => elementTypeFromFutureOr(enclosingFunction.returnType); - Statement createContinuationPoint([Expression value]) { + Statement createContinuationPoint([Expression? value]) { if (value == null) value = new NullLiteral(); capturedTryDepth = math.max(capturedTryDepth, currentTryDepth); capturedCatchDepth = math.max(capturedCatchDepth, currentCatchDepth); return new YieldStatement(value, isNative: true); } - TreeNode visitTryCatch(TryCatch node, TreeNode removalSentinel) { + TreeNode visitTryCatch(TryCatch node, TreeNode? removalSentinel) { + // ignore: unnecessary_null_comparison if (node.body != null) { ++currentTryDepth; node.body = transform(node.body); - node.body?.parent = node; + node.body.parent = node; --currentTryDepth; } @@ -292,17 +289,19 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter { return node; } - TreeNode visitTryFinally(TryFinally node, TreeNode removalSentinel) { + TreeNode visitTryFinally(TryFinally node, TreeNode? removalSentinel) { + // ignore: unnecessary_null_comparison if (node.body != null) { ++currentTryDepth; node.body = transform(node.body); - node.body?.parent = node; + node.body.parent = node; --currentTryDepth; } + // ignore: unnecessary_null_comparison if (node.finalizer != null) { ++currentCatchDepth; node.finalizer = transform(node.finalizer); - node.finalizer?.parent = node; + node.finalizer.parent = node; --currentCatchDepth; } return node; @@ -335,7 +334,7 @@ abstract class ContinuationRewriterBase extends RecursiveContinuationRewriter { // unique to given sub-closure to prevent shared variables being overwritten. class ShadowRewriter extends Transformer { final FunctionNode enclosingFunction; - Map _shadowedParameters = {}; + Map _shadowedParameters = {}; ShadowRewriter(this.enclosingFunction) { for (final parameter in enclosingFunction.positionalParameters @@ -348,32 +347,33 @@ class ShadowRewriter extends Transformer { // Return all used parameters. Iterable get shadowedParameters => - _shadowedParameters.values.where((e) => e != null); + _shadowedParameters.values.whereType(); VariableDeclaration _rewrite(VariableDeclaration variable) { if (_shadowedParameters.containsKey(variable)) { // Fill in placeholder. - if (_shadowedParameters[variable] == null) { - _shadowedParameters[variable] = VariableDeclaration( + VariableDeclaration? placeholder = _shadowedParameters[variable]; + if (placeholder == null) { + placeholder = _shadowedParameters[variable] = VariableDeclaration( variable.name, type: variable.type, initializer: VariableGet(variable), ); } - variable = _shadowedParameters[variable]; + variable = placeholder; } return variable; } @override TreeNode visitVariableGet(VariableGet node) { - node = super.visitVariableGet(node); + node = super.visitVariableGet(node) as VariableGet; return node..variable = _rewrite(node.variable); } @override TreeNode visitVariableSet(VariableSet node) { - node = super.visitVariableSet(node); + node = super.visitVariableSet(node) as VariableSet; return node..variable = _rewrite(node.variable); } } @@ -401,8 +401,8 @@ class SyncStarFunctionRewriter extends ContinuationRewriterBase { // initialised to the original parameter values) and rewrite // the body to use these variables instead. final shadowRewriter = ShadowRewriter(enclosingFunction); - enclosingFunction.body = - enclosingFunction.body.accept(shadowRewriter); + enclosingFunction.body = shadowRewriter.transform(enclosingFunction.body!) + ..parent = enclosingFunction; // TODO(cskau): Figure out why inlining this below causes segfaults. // Maybe related to http://dartbug.com/41596 ? @@ -464,9 +464,8 @@ class SyncStarFunctionRewriter extends ContinuationRewriterBase { ContinuationRewriterBase.elementTypeFrom( helper.iterableClass, enclosingFunction.returnType) ]))), - ]); - - enclosingFunction.body.parent = enclosingFunction; + ]) + ..parent = enclosingFunction; enclosingFunction.asyncMarker = AsyncMarker.Sync; return enclosingFunction; @@ -478,13 +477,13 @@ class SyncStarFunctionRewriter extends ContinuationRewriterBase { // :iterator.isYieldEach= // and return `true` as long as it did something and `false` when it's done. return new Block([ - transform(enclosingFunction.body), + transform(enclosingFunction.body!), new ReturnStatement(new BoolLiteral(false)) ..fileOffset = enclosingFunction.fileEndOffset ]); } - visitYieldStatement(YieldStatement node, TreeNode removalSentinel) { + visitYieldStatement(YieldStatement node, TreeNode? removalSentinel) { Expression transformedExpression = transform(node.expression); var statements = []; @@ -508,7 +507,7 @@ class SyncStarFunctionRewriter extends ContinuationRewriterBase { } TreeNode visitReturnStatement( - ReturnStatement node, TreeNode removalSentinel) { + ReturnStatement node, TreeNode? removalSentinel) { // sync* functions cannot return a value. assert(node.expression == null || node.expression is NullLiteral); node.expression = new BoolLiteral(false)..parent = node; @@ -526,12 +525,12 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { // :async_op_error has type (Object e, StackTrace s) -> dynamic final VariableDeclaration catchErrorContinuationVariable; - LabeledStatement labeledBody; + LabeledStatement? labeledBody; - ExpressionLifter expressionRewriter; + ExpressionLifter? expressionRewriter; AsyncRewriterBase(HelperNodes helper, FunctionNode enclosingFunction, - StaticTypeContext staticTypeContext) + StatefulStaticTypeContext staticTypeContext) : nestedClosureVariable = VariableDeclaration( ContinuationVariables.asyncOp, type: FunctionType([ @@ -566,7 +565,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { // modified ; // } final parameters = [ - expressionRewriter.asyncResult, + expressionRewriter!.asyncResult, new VariableDeclaration(ContinuationVariables.exceptionParam), new VariableDeclaration(ContinuationVariables.stackTraceParam), ]; @@ -587,12 +586,12 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { // TODO(kustermann): If we didn't need any variables we should not emit // these. statements.addAll(variableDeclarations()); - statements.addAll(expressionRewriter.variables); + statements.addAll(expressionRewriter!.variables); // Now add the closure function itself. final closureFunction = new FunctionDeclaration(nestedClosureVariable, function) - ..fileOffset = enclosingFunction.parent.fileOffset; + ..fileOffset = enclosingFunction.parent!.fileOffset; statements.add(closureFunction); // :async_op_then = _asyncThenWrapperHelper(asyncBody); @@ -615,7 +614,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { Statement buildWrappedBody() { ++currentTryDepth; labeledBody = new LabeledStatement(null); - labeledBody.body = visitDelimited(enclosingFunction.body) + labeledBody!.body = visitDelimited(enclosingFunction.body!) ..parent = labeledBody; --currentTryDepth; @@ -625,7 +624,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { helper.coreTypes.stackTraceRawType(staticTypeContext.nonNullable)); return new TryCatch( - buildReturn(labeledBody), + buildReturn(labeledBody!), [ new Catch( exceptionVariable, @@ -638,22 +637,22 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { ); } - Statement buildCatchBody( - Statement exceptionVariable, Statement stackTraceVariable); + Statement buildCatchBody(VariableDeclaration exceptionVariable, + VariableDeclaration stackTraceVariable); Statement buildReturn(Statement body); List statements = []; TreeNode visitExpressionStatement( - ExpressionStatement stmt, TreeNode removalSentinel) { - stmt.expression = expressionRewriter.rewrite(stmt.expression, statements) + ExpressionStatement stmt, TreeNode? removalSentinel) { + stmt.expression = expressionRewriter!.rewrite(stmt.expression, statements) ..parent = stmt; statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitBlock(Block stmt, TreeNode removalSentinel) { + TreeNode visitBlock(Block stmt, TreeNode? removalSentinel) { var saved = statements; statements = []; for (var statement in stmt.statements) { @@ -661,15 +660,15 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { } saved.add(new Block(statements)); statements = saved; - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitEmptyStatement(EmptyStatement stmt, TreeNode removalSentinel) { + TreeNode visitEmptyStatement(EmptyStatement stmt, TreeNode? removalSentinel) { statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitAssertBlock(AssertBlock stmt, TreeNode removalSentinel) { + TreeNode visitAssertBlock(AssertBlock stmt, TreeNode? removalSentinel) { var saved = statements; statements = []; for (var statement in stmt.statements) { @@ -677,26 +676,26 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { } saved.add(new Block(statements)); statements = saved; - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } TreeNode visitAssertStatement( - AssertStatement stmt, TreeNode removalSentinel) { + AssertStatement stmt, TreeNode? removalSentinel) { var condEffects = []; - var cond = expressionRewriter.rewrite(stmt.condition, condEffects); + var cond = expressionRewriter!.rewrite(stmt.condition, condEffects); if (stmt.message == null) { stmt.condition = cond..parent = stmt; // If the translation of the condition produced a non-empty list of // statements, ensure they are guarded by whether asserts are enabled. statements.add( condEffects.isEmpty ? stmt : new AssertBlock(condEffects..add(stmt))); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } // The translation depends on the translation of the message, by cases. Statement result; var msgEffects = []; - stmt.message = expressionRewriter.rewrite(stmt.message, msgEffects) + stmt.message = expressionRewriter!.rewrite(stmt.message!, msgEffects) ..parent = stmt; if (condEffects.isEmpty) { if (msgEffects.isEmpty) { @@ -737,7 +736,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { result = new AssertBlock(condEffects); } statements.add(result); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } Statement visitDelimited(Statement stmt) { @@ -750,22 +749,22 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { return result; } - Statement visitLabeledStatement( - LabeledStatement stmt, TreeNode removalSentinel) { + TreeNode visitLabeledStatement( + LabeledStatement stmt, TreeNode? removalSentinel) { stmt.body = visitDelimited(stmt.body)..parent = stmt; statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - Statement visitBreakStatement(BreakStatement stmt, TreeNode removalSentinel) { + TreeNode visitBreakStatement(BreakStatement stmt, TreeNode? removalSentinel) { statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitWhileStatement(WhileStatement stmt, TreeNode removalSentinel) { + TreeNode visitWhileStatement(WhileStatement stmt, TreeNode? removalSentinel) { Statement body = visitDelimited(stmt.body); List effects = []; - Expression cond = expressionRewriter.rewrite(stmt.condition, effects); + Expression cond = expressionRewriter!.rewrite(stmt.condition, effects); if (effects.isEmpty) { stmt.condition = cond..parent = stmt; stmt.body = body..parent = stmt; @@ -788,13 +787,13 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { stmt.body = new Block(effects)..parent = stmt; statements.add(labeled); } - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitDoStatement(DoStatement stmt, TreeNode removalSentinel) { + TreeNode visitDoStatement(DoStatement stmt, TreeNode? removalSentinel) { Statement body = visitDelimited(stmt.body); List effects = []; - stmt.condition = expressionRewriter.rewrite(stmt.condition, effects) + stmt.condition = expressionRewriter!.rewrite(stmt.condition, effects) ..parent = stmt; if (effects.isNotEmpty) { // The condition rewrote to a non-empty sequence of statements S* and @@ -807,44 +806,43 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { } stmt.body = body..parent = stmt; statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitForStatement(ForStatement stmt, TreeNode removalSentinel) { + TreeNode visitForStatement(ForStatement stmt, TreeNode? removalSentinel) { // Because of for-loop scoping and variable capture, it is tricky to deal // with await in the loop's variable initializers or update expressions. bool isSimple = true; int length = stmt.variables.length; List> initEffects = - new List>.filled(length, null); - for (int i = 0; i < length; ++i) { + new List>.generate(length, (int i) { VariableDeclaration decl = stmt.variables[i]; - initEffects[i] = []; + List statements = []; if (decl.initializer != null) { - decl.initializer = expressionRewriter.rewrite( - decl.initializer, initEffects[i]) - ..parent = decl; + decl.initializer = expressionRewriter! + .rewrite(decl.initializer!, statements) + ..parent = decl; } - isSimple = isSimple && initEffects[i].isEmpty; - } + isSimple = isSimple && statements.isEmpty; + return statements; + }); length = stmt.updates.length; List> updateEffects = - new List>.filled(length, null); - for (int i = 0; i < length; ++i) { - updateEffects[i] = []; - stmt.updates[i] = expressionRewriter.rewrite( - stmt.updates[i], updateEffects[i]) + new List>.generate(length, (int i) { + List statements = []; + stmt.updates[i] = expressionRewriter!.rewrite(stmt.updates[i], statements) ..parent = stmt; - isSimple = isSimple && updateEffects[i].isEmpty; - } + isSimple = isSimple && statements.isEmpty; + return statements; + }); Statement body = visitDelimited(stmt.body); - Expression cond = stmt.condition; - List condEffects; + Expression? cond = stmt.condition; + List? condEffects; if (cond != null) { condEffects = []; - cond = expressionRewriter.rewrite(stmt.condition, condEffects); + cond = expressionRewriter!.rewrite(stmt.condition!, condEffects); } if (isSimple) { @@ -860,11 +858,11 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { // No condition in a for loop is the same as true. stmt.condition = null; condEffects - .add(new IfStatement(cond, body, new BreakStatement(labeled))); + .add(new IfStatement(cond!, body, new BreakStatement(labeled))); stmt.body = new Block(condEffects)..parent = stmt; statements.add(labeled); } - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } // If the rewrite of the initializer or update expressions produces a @@ -920,7 +918,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { if (decl.initializer != null) { initializers.addAll(initEffects[i]); initializers.add( - new ExpressionStatement(new VariableSet(decl, decl.initializer))); + new ExpressionStatement(new VariableSet(decl, decl.initializer!))); decl.initializer = null; } updates.add(new ExpressionStatement( @@ -939,7 +937,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { LabeledStatement labeled = new LabeledStatement(null); if (cond != null) { - loopBody.addAll(condEffects); + loopBody.addAll(condEffects!); } else { cond = new BoolLiteral(true); } @@ -951,10 +949,10 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { statements.add(new Block([] ..addAll(temps) ..add(labeled))); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitForInStatement(ForInStatement stmt, TreeNode removalSentinel) { + TreeNode visitForInStatement(ForInStatement stmt, TreeNode? removalSentinel) { if (stmt.isAsync) { // Transform // @@ -1037,7 +1035,7 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { new Name('current'), helper.streamIteratorCurrent) ..fileOffset = stmt.bodyOffset; - valueVariable.initializer.parent = valueVariable; + valueVariable.initializer!.parent = valueVariable; var whileBody = new Block([valueVariable, stmt.body]); var tryBody = new WhileStatement(whileCondition, whileBody); @@ -1063,17 +1061,17 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { var block = new Block( [streamVariable, forIteratorVariable, tryFinally]); - transform(block); - return removalSentinel; + transform(block); + return removalSentinel ?? EmptyStatement(); } else { super.visitForInStatement(stmt, removalSentinel); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } } TreeNode visitSwitchStatement( - SwitchStatement stmt, TreeNode removalSentinel) { - stmt.expression = expressionRewriter.rewrite(stmt.expression, statements) + SwitchStatement stmt, TreeNode? removalSentinel) { + stmt.expression = expressionRewriter!.rewrite(stmt.expression, statements) ..parent = stmt; for (var switchCase in stmt.cases) { // Expressions in switch cases cannot contain await so they do not need to @@ -1081,27 +1079,27 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { switchCase.body = visitDelimited(switchCase.body)..parent = switchCase; } statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } TreeNode visitContinueSwitchStatement( - ContinueSwitchStatement stmt, TreeNode removalSentinel) { + ContinueSwitchStatement stmt, TreeNode? removalSentinel) { statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitIfStatement(IfStatement stmt, TreeNode removalSentinel) { - stmt.condition = expressionRewriter.rewrite(stmt.condition, statements) + TreeNode visitIfStatement(IfStatement stmt, TreeNode? removalSentinel) { + stmt.condition = expressionRewriter!.rewrite(stmt.condition, statements) ..parent = stmt; stmt.then = visitDelimited(stmt.then)..parent = stmt; if (stmt.otherwise != null) { - stmt.otherwise = visitDelimited(stmt.otherwise)..parent = stmt; + stmt.otherwise = visitDelimited(stmt.otherwise!)..parent = stmt; } statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitTryCatch(TryCatch stmt, TreeNode removalSentinel) { + TreeNode visitTryCatch(TryCatch stmt, TreeNode? removalSentinel) { ++currentTryDepth; stmt.body = visitDelimited(stmt.body)..parent = stmt; --currentTryDepth; @@ -1112,10 +1110,10 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { } --currentCatchDepth; statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitTryFinally(TryFinally stmt, TreeNode removalSentinel) { + TreeNode visitTryFinally(TryFinally stmt, TreeNode? removalSentinel) { ++currentTryDepth; stmt.body = visitDelimited(stmt.body)..parent = stmt; --currentTryDepth; @@ -1123,43 +1121,43 @@ abstract class AsyncRewriterBase extends ContinuationRewriterBase { stmt.finalizer = visitDelimited(stmt.finalizer)..parent = stmt; --currentCatchDepth; statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - TreeNode visitYieldStatement(YieldStatement stmt, TreeNode removalSentinel) { - stmt.expression = expressionRewriter.rewrite(stmt.expression, statements) + TreeNode visitYieldStatement(YieldStatement stmt, TreeNode? removalSentinel) { + stmt.expression = expressionRewriter!.rewrite(stmt.expression, statements) ..parent = stmt; statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } TreeNode visitVariableDeclaration( - VariableDeclaration stmt, TreeNode removalSentinel) { + VariableDeclaration stmt, TreeNode? removalSentinel) { if (stmt.initializer != null) { - stmt.initializer = expressionRewriter.rewrite( - stmt.initializer, statements) - ..parent = stmt; + stmt.initializer = expressionRewriter! + .rewrite(stmt.initializer!, statements) + ..parent = stmt; } statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } TreeNode visitFunctionDeclaration( - FunctionDeclaration stmt, TreeNode removalSentinel) { - stmt.function = transform(stmt.function)..parent = stmt; + FunctionDeclaration stmt, TreeNode? removalSentinel) { + stmt.function = transform(stmt.function!)..parent = stmt; statements.add(stmt); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } - defaultExpression(TreeNode node, TreeNode removalSentinel) => + defaultExpression(TreeNode node, TreeNode? removalSentinel) => throw 'unreachable $node'; } class AsyncStarFunctionRewriter extends AsyncRewriterBase { - VariableDeclaration controllerVariable; + VariableDeclaration? controllerVariable; AsyncStarFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction, - StaticTypeContext staticTypeContext) + StatefulStaticTypeContext staticTypeContext) : super(helper, enclosingFunction, staticTypeContext); FunctionNode rewrite() { @@ -1172,7 +1170,7 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase { ContinuationVariables.controller, type: new InterfaceType(helper.asyncStarStreamControllerClass, staticTypeContext.nullable, [elementType])); - statements.add(controllerVariable); + statements.add(controllerVariable!); // dynamic :controller_stream; VariableDeclaration controllerStreamVariable = @@ -1189,11 +1187,11 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase { helper.asyncStarStreamControllerConstructor, arguments) ..fileOffset = enclosingFunction.fileOffset; var setController = new ExpressionStatement( - new VariableSet(controllerVariable, buildController)); + new VariableSet(controllerVariable!, buildController)); statements.add(setController); // :controller_stream = :controller.stream; - var completerGet = new VariableGet(controllerVariable); + var completerGet = new VariableGet(controllerVariable!); statements.add(new ExpressionStatement(new VariableSet( controllerStreamVariable, new PropertyGet(completerGet, new Name('stream', helper.asyncLibrary), @@ -1204,8 +1202,7 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase { new ReturnStatement(new VariableGet(controllerStreamVariable)); statements.add(returnStatement); - enclosingFunction.body = new Block(statements); - enclosingFunction.body.parent = enclosingFunction; + enclosingFunction.body = new Block(statements)..parent = enclosingFunction; enclosingFunction.asyncMarker = AsyncMarker.Sync; return enclosingFunction; } @@ -1216,7 +1213,7 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase { --currentTryDepth; var finallyBody = new ExpressionStatement(new MethodInvocation( - new VariableGet(controllerVariable), + new VariableGet(controllerVariable!), new Name('close'), new Arguments([]), helper.asyncStarStreamControllerClose)); @@ -1225,9 +1222,10 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase { return tryFinally; } - Statement buildCatchBody(exceptionVariable, stackTraceVariable) { + Statement buildCatchBody(VariableDeclaration exceptionVariable, + VariableDeclaration stackTraceVariable) { return new ExpressionStatement(new MethodInvocation( - new VariableGet(controllerVariable), + new VariableGet(controllerVariable!), new Name('addError'), new Arguments([ new VariableGet(exceptionVariable), @@ -1245,11 +1243,11 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase { ]); } - TreeNode visitYieldStatement(YieldStatement stmt, TreeNode removalSentinel) { - Expression expr = expressionRewriter.rewrite(stmt.expression, statements); + TreeNode visitYieldStatement(YieldStatement stmt, TreeNode? removalSentinel) { + Expression expr = expressionRewriter!.rewrite(stmt.expression, statements); var addExpression = new MethodInvocation( - new VariableGet(controllerVariable), + new VariableGet(controllerVariable!), new Name(stmt.isYieldStar ? 'addStream' : 'add', helper.asyncLibrary), new Arguments([expr]), stmt.isYieldStar @@ -1261,26 +1259,26 @@ class AsyncStarFunctionRewriter extends AsyncRewriterBase { addExpression, new ReturnStatement(new NullLiteral()), createContinuationPoint()..fileOffset = stmt.fileOffset)); - return removalSentinel; + return removalSentinel ?? EmptyStatement(); } TreeNode visitReturnStatement( - ReturnStatement node, TreeNode removalSentinel) { + ReturnStatement node, TreeNode? removalSentinel) { // Async* functions cannot return a value. assert(node.expression == null || node.expression is NullLiteral); statements - .add(new BreakStatement(labeledBody)..fileOffset = node.fileOffset); - return removalSentinel; + .add(new BreakStatement(labeledBody!)..fileOffset = node.fileOffset); + return removalSentinel ?? EmptyStatement(); } } class AsyncFunctionRewriter extends AsyncRewriterBase { - VariableDeclaration returnVariable; - VariableDeclaration asyncFutureVariable; - VariableDeclaration isSyncVariable; + VariableDeclaration? returnVariable; + VariableDeclaration? asyncFutureVariable; + VariableDeclaration? isSyncVariable; AsyncFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction, - StaticTypeContext staticTypeContext) + StatefulStaticTypeContext staticTypeContext) : super(helper, enclosingFunction, staticTypeContext); FunctionNode rewrite() { @@ -1309,18 +1307,18 @@ class AsyncFunctionRewriter extends AsyncRewriterBase { ..fileOffset = enclosingFunction.body?.fileOffset ?? -1, isFinal: true, type: futureType); - statements.add(asyncFutureVariable); + statements.add(asyncFutureVariable!); // bool :is_sync = false; isSyncVariable = VariableDeclaration(ContinuationVariables.isSync, initializer: BoolLiteral(false), type: helper.coreTypes.boolLegacyRawType); - statements.add(isSyncVariable); + statements.add(isSyncVariable!); // asy::FutureOr* :return_value; returnVariable = VariableDeclaration(ContinuationVariables.returnValue, type: returnType); - statements.add(returnVariable); + statements.add(returnVariable!); setupAsyncContinuations(statements); @@ -1334,14 +1332,13 @@ class AsyncFunctionRewriter extends AsyncRewriterBase { // :is_sync = true; final setIsSync = - ExpressionStatement(VariableSet(isSyncVariable, BoolLiteral(true))); + ExpressionStatement(VariableSet(isSyncVariable!, BoolLiteral(true))); statements.add(setIsSync); // return :async_future; - statements.add(ReturnStatement(VariableGet(asyncFutureVariable))); + statements.add(ReturnStatement(VariableGet(asyncFutureVariable!))); - enclosingFunction.body = Block(statements); - enclosingFunction.body.parent = enclosingFunction; + enclosingFunction.body = Block(statements)..parent = enclosingFunction; enclosingFunction.asyncMarker = AsyncMarker.Sync; return enclosingFunction; } @@ -1352,10 +1349,10 @@ class AsyncFunctionRewriter extends AsyncRewriterBase { return ExpressionStatement(StaticInvocation( helper.completeOnAsyncError, Arguments([ - VariableGet(asyncFutureVariable), + VariableGet(asyncFutureVariable!), VariableGet(exceptionVariable), VariableGet(stackTraceVariable), - VariableGet(isSyncVariable) + VariableGet(isSyncVariable!) ]))); } @@ -1372,22 +1369,22 @@ class AsyncFunctionRewriter extends AsyncRewriterBase { ExpressionStatement(StaticInvocation( helper.completeOnAsyncReturn, Arguments([ - VariableGet(asyncFutureVariable), - VariableGet(returnVariable), - VariableGet(isSyncVariable) + VariableGet(asyncFutureVariable!), + VariableGet(returnVariable!), + VariableGet(isSyncVariable!) ]))), ReturnStatement()..fileOffset = enclosingFunction.fileEndOffset ]); } - visitReturnStatement(ReturnStatement node, TreeNode removalSentinel) { + visitReturnStatement(ReturnStatement node, TreeNode? removalSentinel) { var expr = node.expression == null ? new NullLiteral() - : expressionRewriter.rewrite(node.expression, statements); + : expressionRewriter!.rewrite(node.expression!, statements); statements.add(new ExpressionStatement( - new VariableSet(returnVariable, expr)..fileOffset = node.fileOffset)); - statements.add(new BreakStatement(labeledBody)); - return removalSentinel; + new VariableSet(returnVariable!, expr)..fileOffset = node.fileOffset)); + statements.add(new BreakStatement(labeledBody!)); + return removalSentinel ?? EmptyStatement(); } } @@ -1401,11 +1398,11 @@ class HelperNodes { final Member asyncStarStreamControllerClose; final Constructor asyncStarStreamControllerConstructor; final Member asyncStarStreamControllerStream; - final Member asyncStarMoveNextHelper; + final Procedure asyncStarMoveNextHelper; final Procedure asyncThenWrapper; final Procedure awaitHelper; - final Member completeOnAsyncReturn; - final Member completeOnAsyncError; + final Procedure completeOnAsyncReturn; + final Procedure completeOnAsyncError; final Library coreLibrary; final CoreTypes coreTypes; final Class futureClass; @@ -1499,6 +1496,7 @@ class HelperNodes { coreTypes.syncIteratorYieldEachIterable, coreTypes.boolClass, productMode, - coreTypes.index.getTopLevelMember('dart:_internal', 'unsafeCast')); + coreTypes.index.getTopLevelMember('dart:_internal', 'unsafeCast') + as Procedure); } } diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart index d4098352f79..c808cf3f58a 100644 --- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart +++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart @@ -2,8 +2,6 @@ // 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. -// @dart = 2.9 - library kernel.transformations.mixin_full_resolution; import '../ast.dart'; @@ -22,7 +20,7 @@ void transformLibraries( CoreTypes coreTypes, ClassHierarchy hierarchy, List libraries, - ReferenceFromIndex referenceFromIndex) { + ReferenceFromIndex? referenceFromIndex) { new MixinFullResolution(targetInfo, coreTypes, hierarchy) .transform(libraries, referenceFromIndex); } @@ -46,7 +44,7 @@ class MixinFullResolution { /// Transform the given new [libraries]. It is expected that all other /// libraries have already been transformed. void transform( - List libraries, ReferenceFromIndex referenceFromIndex) { + List libraries, ReferenceFromIndex? referenceFromIndex) { if (libraries.isEmpty) return; var transformedClasses = new Set(); @@ -71,7 +69,7 @@ class MixinFullResolution { Set processedClasses, Set transformedClasses, Class class_, - ReferenceFromIndex referenceFromIndex) { + ReferenceFromIndex? referenceFromIndex) { // If this class was already handled then so were all classes up to the // [Object] class. if (!processedClasses.add(class_)) return; @@ -79,7 +77,7 @@ class MixinFullResolution { Library enclosingLibrary = class_.enclosingLibrary; if (!librariesToBeTransformed.contains(enclosingLibrary) && - enclosingLibrary.importUri?.scheme == "dart") { + enclosingLibrary.importUri.scheme == "dart") { // If we're not asked to transform the platform libraries then we expect // that they will be already transformed. return; @@ -88,7 +86,7 @@ class MixinFullResolution { // Ensure super classes have been transformed before this class. if (class_.superclass != null) { transformClass(librariesToBeTransformed, processedClasses, - transformedClasses, class_.superclass, referenceFromIndex); + transformedClasses, class_.superclass!, referenceFromIndex); } // If this is not a mixin application we don't need to make forwarding @@ -99,12 +97,13 @@ class MixinFullResolution { transformedClasses.add(class_); // Clone fields and methods from the mixin class. - var substitution = getSubstitutionMap(class_.mixedInType); + var substitution = getSubstitutionMap(class_.mixedInType!); var cloner = new CloneVisitorWithMembers(typeSubstitution: substitution); - IndexedLibrary indexedLibrary = + IndexedLibrary? indexedLibrary = referenceFromIndex?.lookupLibrary(enclosingLibrary); - IndexedClass indexedClass = indexedLibrary?.lookupIndexedClass(class_.name); + IndexedClass? indexedClass = + indexedLibrary?.lookupIndexedClass(class_.name); if (class_.mixin.fields.isNotEmpty) { // When we copy a field from the mixed in class, we remove any @@ -114,17 +113,17 @@ class MixinFullResolution { var setters = {}; for (var procedure in class_.procedures) { if (procedure.isSetter) { - setters[procedure.name] = procedure; + setters[procedure.name!] = procedure; } else { - nonSetters[procedure.name] = procedure; + nonSetters[procedure.name!] = procedure; } } for (var field in class_.mixin.fields) { - Reference getterReference = - indexedClass?.lookupGetterReference(field.name); - Reference setterReference = - indexedClass?.lookupSetterReference(field.name); + Reference? getterReference = + indexedClass?.lookupGetterReference(field.name!); + Reference? setterReference = + indexedClass?.lookupSetterReference(field.name!); if (getterReference == null) { getterReference = nonSetters[field.name]?.reference; getterReference?.canonicalName?.unbind(); @@ -135,11 +134,11 @@ class MixinFullResolution { } Field clone = cloner.cloneField(field, getterReference, setterReference); - Procedure setter = setters[field.name]; + Procedure? setter = setters[field.name!]; if (setter != null) { setters.remove(field.name); VariableDeclaration parameter = - setter.function.positionalParameters.first; + setter.function!.positionalParameters.first; clone.isCovariant = parameter.isCovariant; clone.isGenericCovariantImpl = parameter.isGenericCovariantImpl; } @@ -168,21 +167,21 @@ class MixinFullResolution { // NoSuchMethod forwarders aren't cloned. if (procedure.isNoSuchMethodForwarder) continue; - Reference reference; + Reference? reference; if (procedure.isSetter) { - reference = indexedClass?.lookupSetterReference(procedure.name); + reference = indexedClass?.lookupSetterReference(procedure.name!); } else { - reference = indexedClass?.lookupGetterReference(procedure.name); + reference = indexedClass?.lookupGetterReference(procedure.name!); } // Linear search for a forwarding stub with the same name. - int originalIndex; + int? originalIndex; for (int i = 0; i < originalLength; ++i) { var originalProcedure = class_.procedures[i]; if (originalProcedure.name == procedure.name && originalProcedure.kind == procedure.kind) { - FunctionNode src = originalProcedure.function; - FunctionNode dst = procedure.function; + FunctionNode src = originalProcedure.function!; + FunctionNode dst = procedure.function!; if (src.positionalParameters.length != dst.positionalParameters.length || @@ -196,13 +195,13 @@ class MixinFullResolution { } } if (originalIndex != null) { - reference ??= class_.procedures[originalIndex]?.reference; + reference ??= class_.procedures[originalIndex].reference; } Procedure clone = cloner.cloneProcedure(procedure, reference); if (originalIndex != null) { Procedure originalProcedure = class_.procedures[originalIndex]; - FunctionNode src = originalProcedure.function; - FunctionNode dst = clone.function; + FunctionNode src = originalProcedure.function!; + FunctionNode dst = clone.function!; assert(src.typeParameters.length == dst.typeParameters.length); for (int j = 0; j < src.typeParameters.length; ++j) { dst.typeParameters[j].flags = src.typeParameters[j].flags; @@ -229,7 +228,7 @@ class MixinFullResolution { // This class implements the mixin type. Also, backends rely on the fact // that eliminated mixin is appended into the end of interfaces list. - class_.implementedTypes.add(class_.mixedInType); + class_.implementedTypes.add(class_.mixedInType!); // This class is now a normal class. class_.mixedInType = null; diff --git a/pkg/kernel/lib/vm/constants_native_effects.dart b/pkg/kernel/lib/vm/constants_native_effects.dart index 401504a2d65..f4efb715bbf 100644 --- a/pkg/kernel/lib/vm/constants_native_effects.dart +++ b/pkg/kernel/lib/vm/constants_native_effects.dart @@ -2,8 +2,6 @@ // 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. -// @dart = 2.9 - library vm.constants_native_effects; import '../ast.dart'; @@ -25,12 +23,13 @@ class VmConstantsBackend extends ConstantsBackend { final Library coreLibrary = coreTypes.coreLibrary; final Class immutableMapClass = coreLibrary.classes .firstWhere((Class klass) => klass.name == '_ImmutableMap'); + // ignore: unnecessary_null_comparison assert(immutableMapClass != null); Field unmodifiableSetMap = coreTypes.index - .getMember('dart:collection', '_UnmodifiableSet', '_map'); + .getMember('dart:collection', '_UnmodifiableSet', '_map') as Field; return new VmConstantsBackend._(immutableMapClass, unmodifiableSetMap, - unmodifiableSetMap.enclosingClass); + unmodifiableSetMap.enclosingClass!); } @override @@ -38,12 +37,11 @@ class VmConstantsBackend extends ConstantsBackend { // The _ImmutableMap class is implemented via one field pointing to a list // of key/value pairs -- see runtime/lib/immutable_map.dart! final List kvListPairs = - new List.filled(2 * constant.entries.length, null); - for (int i = 0; i < constant.entries.length; i++) { - final ConstantMapEntry entry = constant.entries[i]; - kvListPairs[2 * i] = entry.key; - kvListPairs[2 * i + 1] = entry.value; - } + new List.generate(2 * constant.entries.length, (int i) { + final int index = i ~/ 2; + final ConstantMapEntry entry = constant.entries[index]; + return i % 2 == 0 ? entry.key : entry.value; + }); // This is a bit fishy, since we merge the key and the value type by // putting both into the same list. final ListConstant kvListConstant = @@ -69,11 +67,11 @@ class VmConstantsBackend extends ConstantsBackend { void forEachLoweredMapConstantEntry( Constant constant, void Function(Constant key, Constant value) f) { assert(isLoweredMapConstant(constant)); - final InstanceConstant instance = constant; + final InstanceConstant instance = constant as InstanceConstant; assert(immutableMapClass.fields.length == 1); final Field kvPairListField = immutableMapClass.fields[0]; final ListConstant kvListConstant = - instance.fieldValues[kvPairListField.getterReference]; + instance.fieldValues[kvPairListField.getterReference] as ListConstant; assert(kvListConstant.entries.length % 2 == 0); for (int index = 0; index < kvListConstant.entries.length; index += 2) { f(kvListConstant.entries[index], kvListConstant.entries[index + 1]); @@ -85,10 +83,9 @@ class VmConstantsBackend extends ConstantsBackend { final DartType elementType = constant.typeArgument; final List entries = constant.entries; final List mapEntries = - new List.filled(entries.length, null); - for (int i = 0; i < entries.length; ++i) { - mapEntries[i] = new ConstantMapEntry(entries[i], new NullConstant()); - } + new List.generate(entries.length, (int index) { + return new ConstantMapEntry(entries[index], new NullConstant()); + }); Constant map = lowerMapConstant( new MapConstant(elementType, const NullType(), mapEntries)); return new InstanceConstant(unmodifiableSetClass.reference, [elementType], @@ -101,7 +98,7 @@ class VmConstantsBackend extends ConstantsBackend { constant.classNode == unmodifiableSetClass) { InstanceConstant instance = constant; return isLoweredMapConstant( - instance.fieldValues[unmodifiableSetMap.getterReference]); + instance.fieldValues[unmodifiableSetMap.getterReference]!); } return false; } @@ -110,9 +107,9 @@ class VmConstantsBackend extends ConstantsBackend { void forEachLoweredSetConstantElement( Constant constant, void Function(Constant element) f) { assert(isLoweredSetConstant(constant)); - final InstanceConstant instance = constant; + final InstanceConstant instance = constant as InstanceConstant; final Constant mapConstant = - instance.fieldValues[unmodifiableSetMap.getterReference]; + instance.fieldValues[unmodifiableSetMap.getterReference]!; forEachLoweredMapConstantEntry(mapConstant, (Constant key, Constant value) { f(key); }); diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart index 7fbf03c919a..d80ff5244c0 100644 --- a/pkg/vm/lib/target/vm.dart +++ b/pkg/vm/lib/target/vm.dart @@ -196,10 +196,15 @@ class VmTarget extends Target { @override void performTransformationsOnProcedure( - CoreTypes coreTypes, ClassHierarchy hierarchy, Procedure procedure, + CoreTypes coreTypes, + ClassHierarchy hierarchy, + Procedure procedure, + Map environmentDefines, {void logger(String msg)}) { + bool productMode = environmentDefines["dart.vm.product"] == "true"; transformAsync.transformProcedure( - new TypeEnvironment(coreTypes, hierarchy), procedure); + new TypeEnvironment(coreTypes, hierarchy), procedure, + productMode: productMode); logger?.call("Transformed async functions"); lowering.transformProcedure(