| Index: pkg/compiler/lib/src/ssa/kernel_impact.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d4d161e8c5b79dc0857d1a416286c36131afbc13
|
| --- /dev/null
|
| +++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
|
| @@ -0,0 +1,203 @@
|
| +// 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:kernel/ast.dart' as ir;
|
| +
|
| +import '../common.dart';
|
| +import '../compiler.dart';
|
| +import '../constants/expressions.dart';
|
| +import '../dart_types.dart';
|
| +import '../elements/elements.dart';
|
| +import '../js_backend/backend.dart' show JavaScriptBackend;
|
| +import '../kernel/kernel.dart';
|
| +import '../kernel/kernel_visitor.dart';
|
| +import '../resolution/registry.dart' show ResolutionWorldImpactBuilder;
|
| +import '../universe/feature.dart';
|
| +import '../universe/use.dart';
|
| +
|
| +import 'kernel_ast_adapter.dart';
|
| +import '../common/resolution.dart';
|
| +
|
| +/// Computes the [ResolutionImpact] for [resolvedAst] through kernel.
|
| +ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) {
|
| + AstElement element = resolvedAst.element.implementation;
|
| + Kernel kernel = new Kernel(compiler);
|
| + KernelVisitor visitor =
|
| + new KernelVisitor(element, resolvedAst.elements, kernel);
|
| + IrFunction function;
|
| + try {
|
| + function = visitor.buildFunction();
|
| + } catch (e) {
|
| + throw "Failed to convert to Kernel IR: $e";
|
| + }
|
| + KernelImpactBuilder builder = new KernelImpactBuilder(
|
| + function, element, resolvedAst, compiler, visitor, kernel);
|
| + return builder.build();
|
| +}
|
| +
|
| +class KernelImpactBuilder extends ir.Visitor {
|
| + final IrFunction function;
|
| + final FunctionElement functionElement;
|
| + final ResolvedAst resolvedAst;
|
| + final Compiler compiler;
|
| +
|
| + JavaScriptBackend get backend => compiler.backend;
|
| +
|
| + ResolutionWorldImpactBuilder impactBuilder;
|
| + KernelAstAdapter astAdapter;
|
| +
|
| + KernelImpactBuilder(this.function, this.functionElement, this.resolvedAst,
|
| + this.compiler, KernelVisitor visitor, Kernel kernel) {
|
| + this.impactBuilder = new ResolutionWorldImpactBuilder('$functionElement');
|
| + this.astAdapter = new KernelAstAdapter(
|
| + compiler.backend,
|
| + resolvedAst,
|
| + visitor.nodeToAst,
|
| + visitor.nodeToElement,
|
| + kernel.functions,
|
| + kernel.classes,
|
| + kernel.libraries);
|
| + }
|
| +
|
| + ResolutionImpact build() {
|
| + if (function.kind == ir.ProcedureKind.Method ||
|
| + function.kind == ir.ProcedureKind.Operator) {
|
| + buildMethod(function);
|
| + } else {
|
| + compiler.reporter.internalError(
|
| + functionElement,
|
| + "Unable to compute resolution impact for this kind of Kernel "
|
| + "procedure: ${function.kind}");
|
| + }
|
| + return impactBuilder;
|
| + }
|
| +
|
| + /// Add a checked-mode type use of [type] if it is not `dynamic`.
|
| + DartType checkType(DartType type) {
|
| + if (!type.isDynamic) {
|
| + impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type));
|
| + }
|
| + return type;
|
| + }
|
| +
|
| + void buildMethod(IrFunction method) {
|
| + method.node.body.accept(this);
|
| + }
|
| +
|
| + void visitNodes(Iterable<ir.Node> nodes) {
|
| + nodes.forEach((ir.Node node) => node.accept(this));
|
| + }
|
| +
|
| + @override
|
| + void visitBlock(ir.Block block) => visitNodes(block.statements);
|
| +
|
| + @override
|
| + void visitExpressionStatement(ir.ExpressionStatement exprStatement) {
|
| + exprStatement.expression.accept(this);
|
| + }
|
| +
|
| + @override
|
| + void visitReturnStatement(ir.ReturnStatement returnStatement) {
|
| + returnStatement.expression?.accept(this);
|
| + }
|
| +
|
| + @override
|
| + void visitIfStatement(ir.IfStatement ifStatement) {
|
| + ifStatement.condition.accept(this);
|
| + ifStatement.then.accept(this);
|
| + ifStatement.otherwise?.accept(this);
|
| + }
|
| +
|
| + @override
|
| + void visitIntLiteral(ir.IntLiteral literal) {
|
| + impactBuilder
|
| + .registerConstantLiteral(new IntConstantExpression(literal.value));
|
| + }
|
| +
|
| + @override
|
| + void visitDoubleLiteral(ir.DoubleLiteral literal) {
|
| + impactBuilder
|
| + .registerConstantLiteral(new DoubleConstantExpression(literal.value));
|
| + }
|
| +
|
| + @override
|
| + void visitBoolLiteral(ir.BoolLiteral literal) {
|
| + impactBuilder
|
| + .registerConstantLiteral(new BoolConstantExpression(literal.value));
|
| + }
|
| +
|
| + @override
|
| + void visitStringLiteral(ir.StringLiteral literal) {
|
| + impactBuilder
|
| + .registerConstantLiteral(new StringConstantExpression(literal.value));
|
| + }
|
| +
|
| + @override
|
| + void visitSymbolLiteral(ir.SymbolLiteral literal) {
|
| + impactBuilder.registerConstSymbolName(literal.value);
|
| + }
|
| +
|
| + @override
|
| + void visitNullLiteral(ir.NullLiteral literal) {
|
| + impactBuilder.registerConstantLiteral(new NullConstantExpression());
|
| + }
|
| +
|
| + @override
|
| + void visitListLiteral(ir.ListLiteral literal) {
|
| + visitNodes(literal.expressions);
|
| + DartType elementType =
|
| + checkType(astAdapter.getDartType(literal.typeArgument));
|
| +
|
| + impactBuilder.registerListLiteral(new ListLiteralUse(
|
| + compiler.coreTypes.listType(elementType),
|
| + isConstant: literal.isConst,
|
| + isEmpty: literal.expressions.isEmpty));
|
| + }
|
| +
|
| + @override
|
| + void visitMapLiteral(ir.MapLiteral literal) {
|
| + visitNodes(literal.entries);
|
| + DartType keyType = checkType(astAdapter.getDartType(literal.keyType));
|
| + DartType valueType = checkType(astAdapter.getDartType(literal.valueType));
|
| + impactBuilder.registerMapLiteral(new MapLiteralUse(
|
| + compiler.coreTypes.mapType(keyType, valueType),
|
| + isConstant: literal.isConst,
|
| + isEmpty: literal.entries.isEmpty));
|
| + }
|
| +
|
| + void visitMapEntry(ir.MapEntry entry) {
|
| + entry.key.accept(this);
|
| + entry.value.accept(this);
|
| + }
|
| +
|
| + void _visitArguments(ir.Arguments arguments) {
|
| + for (ir.Expression argument in arguments.positional) {
|
| + argument.accept(this);
|
| + }
|
| + for (ir.NamedExpression argument in arguments.named) {
|
| + argument.value.accept(this);
|
| + }
|
| + }
|
| +
|
| + @override
|
| + void visitStaticInvocation(ir.StaticInvocation invocation) {
|
| + _visitArguments(invocation.arguments);
|
| + Element target = astAdapter.getElement(invocation.target).declaration;
|
| + impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
|
| + target, astAdapter.getCallStructure(invocation.arguments)));
|
| + }
|
| +
|
| + @override
|
| + void visitMethodInvocation(ir.MethodInvocation invocation) {
|
| + invocation.receiver.accept(this);
|
| + _visitArguments(invocation.arguments);
|
| + impactBuilder.registerDynamicUse(
|
| + new DynamicUse(astAdapter.getSelector(invocation), null));
|
| + }
|
| +
|
| + @override
|
| + void visitNot(ir.Not not) {
|
| + not.operand.accept(this);
|
| + }
|
| +}
|
|
|