blob: 01db445a5e6a2056c54326b9046826a6a07fed93 [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.
library kernel.transformations.insert_type_checks;
import '../ast.dart';
import '../class_hierarchy.dart';
import '../core_types.dart';
import '../log.dart';
import '../type_checker.dart';
/// Inserts implicit downcasts in method bodies to ensure type safety.
/// This does not deal with covariant override and covariant use of type
/// parameters.
/// Ideally this should be done when initially generating kernel IR, but this
/// is not practical at the moment.
class InsertTypeChecks {
CoreTypes coreTypes;
ClassHierarchy hierarchy;
InsertTypeChecks({this.coreTypes, this.hierarchy});
void transformProgram(Program program) {
coreTypes ??= new CoreTypes(program);
hierarchy ??= new ClassHierarchy(program);
new CheckInsertingTypeChecker(coreTypes, hierarchy).checkProgram(program);
class CheckInsertingTypeChecker extends TypeChecker {
CheckInsertingTypeChecker(CoreTypes coreTypes, ClassHierarchy hierarchy)
: super(coreTypes, hierarchy);
void fail(TreeNode where, String message) {
log.severe('${where.location}: $message');
void checkAssignable(TreeNode where, DartType from, DartType to) {
if (!environment.isSubtypeOf(from, to)) {
fail(where, '$from cannot be assigned to $to');
Expression checkAndDowncastExpression(
Expression expression, DartType from, DartType to) {
if (!environment.isSubtypeOf(from, to)) {
return new AsExpression(expression, to)
..fileOffset = expression.fileOffset;
} else {
return expression;