| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| index 6541e41a2533146b0cbf615a0c3a7ffff500457e..a0b91ef7987fc1b46820c1f7a0b2ad9b819cade5 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
|
| @@ -45,6 +45,8 @@ class IrBuilderTask extends CompilerTask {
|
| <Element, ir.ExecutableDefinition>{};
|
| final bool generateSourceMap;
|
|
|
| + String bailoutMessage = null;
|
| +
|
| IrBuilderTask(Compiler compiler, {this.generateSourceMap: true})
|
| : super(compiler);
|
|
|
| @@ -57,7 +59,11 @@ class IrBuilderTask extends CompilerTask {
|
| }
|
|
|
| ir.ExecutableDefinition buildNode(AstElement element) {
|
| - if (!canBuild(element)) return null;
|
| + bailoutMessage = null;
|
| + if (!canBuild(element)) {
|
| + bailoutMessage = 'unsupported element ${element.name}:${element.kind}';
|
| + return null;
|
| + }
|
|
|
| TreeElements elementsMapping = element.resolvedAst.elements;
|
| element = element.implementation;
|
| @@ -74,7 +80,9 @@ class IrBuilderTask extends CompilerTask {
|
| elementsMapping, compiler, sourceInformationBuilder);
|
| ir.ExecutableDefinition definition =
|
| builder.buildExecutable(element);
|
| - if (definition != null) {
|
| + if (definition == null) {
|
| + bailoutMessage = builder.bailoutMessage;
|
| + } else {
|
| nodes[element] = definition;
|
| }
|
| return definition;
|
| @@ -163,6 +171,8 @@ abstract class IrBuilderVisitor extends SemanticVisitor<ir.Primitive, dynamic>
|
| @override
|
| bulkHandleNode(ast.Node node, String message, _) => giveup(node, message);
|
|
|
| + String bailoutMessage = null;
|
| +
|
| @override
|
| ir.Primitive apply(ast.Node node, _) => node.accept(this);
|
|
|
| @@ -1761,21 +1771,22 @@ abstract class IrBuilderVisitor extends SemanticVisitor<ir.Primitive, dynamic>
|
| }
|
|
|
| void internalError(ast.Node node, String message) {
|
| - giveup(node);
|
| + giveup(node, message);
|
| }
|
|
|
| @override
|
| visitNode(ast.Node node) {
|
| internalError(node, "Unhandled node");
|
| }
|
| +
|
| + dynamic giveup(ast.Node node, [String reason]) {
|
| + bailoutMessage = '($node): $reason';
|
| + throw ABORT_IRNODE_BUILDER;
|
| + }
|
| }
|
|
|
| final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
|
|
|
| -dynamic giveup(ast.Node node, [String reason]) {
|
| - throw ABORT_IRNODE_BUILDER;
|
| -}
|
| -
|
| /// Classifies local variables and local functions as captured, if they
|
| /// are accessed from within a nested function.
|
| ///
|
| @@ -1797,6 +1808,13 @@ class DartCapturedVariables extends ast.Visitor {
|
| List<TryStatementInfo> tryNestingStack = <TryStatementInfo>[];
|
| bool get inTryStatement => tryNestingStack.isNotEmpty;
|
|
|
| + String bailoutMessage = null;
|
| +
|
| + giveup(ast.Node node, [String reason]) {
|
| + bailoutMessage = '($node): $reason';
|
| + throw ABORT_IRNODE_BUILDER;
|
| + }
|
| +
|
| void markAsCaptured(Local local) {
|
| capturedVariables.add(local);
|
| }
|
| @@ -1929,7 +1947,12 @@ class DartIrBuilderVisitor extends IrBuilderVisitor {
|
| DartIrBuilder makeIRBuilder(ast.Node node, ExecutableElement element) {
|
| DartCapturedVariables closures = new DartCapturedVariables(elements);
|
| if (!element.isSynthesized) {
|
| - closures.visit(node);
|
| + try {
|
| + closures.visit(node);
|
| + } catch (e) {
|
| + bailoutMessage = closures.bailoutMessage;
|
| + rethrow;
|
| + }
|
| }
|
| return new DartIrBuilder(compiler.backend.constantSystem,
|
| element,
|
|
|