| Index: pkg/analyzer2dart/lib/src/cps_generator.dart
|
| diff --git a/pkg/analyzer2dart/lib/src/cps_generator.dart b/pkg/analyzer2dart/lib/src/cps_generator.dart
|
| index 8bd4c0ad66833a2c492c6af8d94bcaaa1677667e..1e5bb6dbf342c262e61e15bc67d7d7f170a3b289 100644
|
| --- a/pkg/analyzer2dart/lib/src/cps_generator.dart
|
| +++ b/pkg/analyzer2dart/lib/src/cps_generator.dart
|
| @@ -1,589 +1,589 @@
|
| -// Copyright (c) 2014, 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 analyzer2dart.cps_generator;
|
| -
|
| -import 'package:analyzer/analyzer.dart';
|
| -
|
| -import 'package:compiler/src/dart_types.dart' as dart2js;
|
| -import 'package:compiler/src/elements/elements.dart' as dart2js;
|
| -import 'package:analyzer/src/generated/source.dart';
|
| -import 'package:analyzer/src/generated/element.dart' as analyzer;
|
| -
|
| -import 'package:compiler/src/constant_system_dart.dart'
|
| - show DART_CONSTANT_SYSTEM;
|
| -import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
|
| -import 'package:compiler/src/cps_ir/cps_ir_builder.dart';
|
| -import 'package:compiler/src/universe/universe.dart';
|
| -
|
| -import 'semantic_visitor.dart';
|
| -import 'element_converter.dart';
|
| -import 'util.dart';
|
| -import 'identifier_semantics.dart';
|
| -
|
| -/// Visitor that converts the AST node of an analyzer element into a CPS ir
|
| -/// node.
|
| -class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {
|
| - final ElementConverter converter;
|
| - final AstNode node;
|
| -
|
| - CpsElementVisitor(this.converter, this.node);
|
| -
|
| - @override
|
| - ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {
|
| - CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| - FunctionDeclaration functionDeclaration = node;
|
| - return visitor.handleFunctionDeclaration(
|
| - element, functionDeclaration.functionExpression.body);
|
| - }
|
| -
|
| - @override
|
| - ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {
|
| - CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| - MethodDeclaration methodDeclaration = node;
|
| - return visitor.handleFunctionDeclaration(element, methodDeclaration.body);
|
| - }
|
| -
|
| - @override
|
| - ir.FieldDefinition visitTopLevelVariableElement(
|
| - analyzer.TopLevelVariableElement element) {
|
| - CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| - VariableDeclaration variableDeclaration = node;
|
| - return visitor.handleFieldDeclaration(element, variableDeclaration);
|
| - }
|
| -
|
| - @override
|
| - ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {
|
| - CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| - if (!element.isFactory) {
|
| - ConstructorDeclaration constructorDeclaration = node;
|
| - FunctionBody body;
|
| - if (constructorDeclaration != null) {
|
| - body = constructorDeclaration.body;
|
| - } else {
|
| - assert(element.isSynthetic);
|
| - }
|
| - return visitor.handleConstructorDeclaration(element, body);
|
| - }
|
| - // TODO(johnniwinther): Support factory constructors.
|
| - return null;
|
| - }
|
| -}
|
| -
|
| -/// Visitor that converts analyzer AST nodes into CPS ir nodes.
|
| -class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
|
| - with IrBuilderMixin<AstNode> {
|
| - /// Promote the type of [irBuilder] to [DartIrBuilder].
|
| - /// The JS backend requires closure conversion which we do not support yet.
|
| - DartIrBuilder get irBuilder => super.irBuilder;
|
| - final analyzer.Element element;
|
| - final ElementConverter converter;
|
| -
|
| - CpsGeneratingVisitor(this.converter, this.element);
|
| -
|
| - Source get currentSource => element.source;
|
| -
|
| - analyzer.LibraryElement get currentLibrary => element.library;
|
| -
|
| - ir.Node visit(AstNode node) => node.accept(this);
|
| -
|
| - ir.ConstructorDefinition handleConstructorDeclaration(
|
| - analyzer.ConstructorElement constructor, FunctionBody body) {
|
| - dart2js.ConstructorElement element = converter.convertElement(constructor);
|
| - return withBuilder(
|
| - new DartIrBuilder(DART_CONSTANT_SYSTEM,
|
| - element,
|
| - // TODO(johnniwinther): Support closure variables.
|
| - new Set<dart2js.Local>()),
|
| - () {
|
| - irBuilder.buildFunctionHeader(
|
| - constructor.parameters.map(converter.convertElement));
|
| - // Visit the body directly to avoid processing the signature as
|
| - // expressions.
|
| - // Call to allow for `body == null` in case of synthesized constructors.
|
| - build(body);
|
| - return irBuilder.makeConstructorDefinition(const [], const []);
|
| - });
|
| - }
|
| -
|
| - ir.FieldDefinition handleFieldDeclaration(
|
| - analyzer.PropertyInducingElement field, VariableDeclaration node) {
|
| - dart2js.FieldElement element = converter.convertElement(field);
|
| - return withBuilder(
|
| - new DartIrBuilder(DART_CONSTANT_SYSTEM,
|
| - element,
|
| - // TODO(johnniwinther): Support closure variables.
|
| - new Set<dart2js.Local>()),
|
| - () {
|
| - irBuilder.buildFieldInitializerHeader();
|
| - ir.Primitive initializer = build(node.initializer);
|
| - return irBuilder.makeFieldDefinition(initializer);
|
| - });
|
| - }
|
| -
|
| - ir.FunctionDefinition handleFunctionDeclaration(
|
| - analyzer.ExecutableElement function, FunctionBody body) {
|
| - dart2js.FunctionElement element = converter.convertElement(function);
|
| - return withBuilder(
|
| - new DartIrBuilder(DART_CONSTANT_SYSTEM,
|
| - element,
|
| - // TODO(johnniwinther): Support closure variables.
|
| - new Set<dart2js.Local>()),
|
| - () {
|
| - irBuilder.buildFunctionHeader(
|
| - function.parameters.map(converter.convertElement));
|
| - // Visit the body directly to avoid processing the signature as
|
| - // expressions.
|
| - visit(body);
|
| - return irBuilder.makeFunctionDefinition(const []);
|
| - });
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive visitFunctionExpression(FunctionExpression node) {
|
| - return irBuilder.buildFunctionExpression(
|
| - handleFunctionDeclaration(node.element, node.body));
|
| - }
|
| -
|
| - @override
|
| - ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
|
| - return handleFunctionDeclaration(
|
| - node.element, node.functionExpression.body);
|
| - }
|
| -
|
| - @override
|
| - visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
|
| - FunctionDeclaration functionDeclaration = node.functionDeclaration;
|
| - analyzer.FunctionElement function = functionDeclaration.element;
|
| - dart2js.FunctionElement element = converter.convertElement(function);
|
| - ir.FunctionDefinition definition = handleFunctionDeclaration(
|
| - function, functionDeclaration.functionExpression.body);
|
| - irBuilder.declareLocalFunction(element, definition);
|
| - }
|
| -
|
| - List<ir.Primitive> visitArguments(ArgumentList argumentList) {
|
| - List<ir.Primitive> arguments = <ir.Primitive>[];
|
| - for (Expression argument in argumentList.arguments) {
|
| - ir.Primitive value = build(argument);
|
| - if (value == null) {
|
| - giveUp(argument,
|
| - 'Unsupported argument: $argument (${argument.runtimeType}).');
|
| - }
|
| - arguments.add(value);
|
| - }
|
| - return arguments;
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitMethodInvocation(MethodInvocation node) {
|
| - // Overridden to avoid eager visits of the receiver and arguments.
|
| - return handleMethodInvocation(node);
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive visitDynamicInvocation(MethodInvocation node,
|
| - AccessSemantics semantics) {
|
| - // TODO(johnniwinther): Handle implicit `this`.
|
| - ir.Primitive receiver = build(semantics.target);
|
| - List<ir.Primitive> arguments = visitArguments(node.argumentList);
|
| - return irBuilder.buildDynamicInvocation(
|
| - receiver,
|
| - createSelectorFromMethodInvocation(
|
| - node.argumentList, node.methodName.name),
|
| - arguments);
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
|
| - AccessSemantics semantics) {
|
| - analyzer.Element staticElement = semantics.element;
|
| - dart2js.Element element = converter.convertElement(staticElement);
|
| - List<ir.Primitive> arguments = visitArguments(node.argumentList);
|
| - return irBuilder.buildStaticFunctionInvocation(
|
| - element,
|
| - createCallStructureFromMethodInvocation(node.argumentList),
|
| - arguments);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
|
| - return handleLocalAccess(node, semantics);
|
| - }
|
| -
|
| - ir.Primitive handleLocalInvocation(MethodInvocation node,
|
| - AccessSemantics semantics) {
|
| - analyzer.Element staticElement = semantics.element;
|
| - dart2js.Element element = converter.convertElement(staticElement);
|
| - List<ir.Definition> arguments = visitArguments(node.argumentList);
|
| - CallStructure callStructure = createCallStructureFromMethodInvocation(
|
| - node.argumentList);
|
| - if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
|
| - return irBuilder.buildLocalFunctionInvocation(
|
| - element, callStructure, arguments);
|
| - } else {
|
| - return irBuilder.buildLocalVariableInvocation(
|
| - element, callStructure, arguments);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitLocalVariableInvocation(MethodInvocation node,
|
| - AccessSemantics semantics) {
|
| - return handleLocalInvocation(node, semantics);
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,
|
| - AccessSemantics semantics) {
|
| - return handleLocalInvocation(node, semantics);
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive visitFunctionExpressionInvocation(
|
| - FunctionExpressionInvocation node) {
|
| - ir.Primitive target = build(node.function);
|
| - List<ir.Definition> arguments = visitArguments(node.argumentList);
|
| - return irBuilder.buildCallInvocation(
|
| - target,
|
| - createCallStructureFromMethodInvocation(node.argumentList),
|
| - arguments);
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive visitInstanceCreationExpression(
|
| - InstanceCreationExpression node) {
|
| - analyzer.Element staticElement = node.staticElement;
|
| - if (staticElement != null) {
|
| - dart2js.Element element = converter.convertElement(staticElement);
|
| - dart2js.DartType type = converter.convertType(node.staticType);
|
| - List<ir.Primitive> arguments = visitArguments(node.argumentList);
|
| - return irBuilder.buildConstructorInvocation(
|
| - element,
|
| - createCallStructureFromMethodInvocation(node.argumentList),
|
| - type,
|
| - arguments);
|
| - }
|
| - return giveUp(node, "Unresolved constructor invocation.");
|
| - }
|
| -
|
| - @override
|
| - ir.Constant visitNullLiteral(NullLiteral node) {
|
| - return irBuilder.buildNullConstant();
|
| - }
|
| -
|
| - @override
|
| - ir.Constant visitBooleanLiteral(BooleanLiteral node) {
|
| - return irBuilder.buildBooleanConstant(node.value);
|
| - }
|
| -
|
| - @override
|
| - ir.Constant visitDoubleLiteral(DoubleLiteral node) {
|
| - return irBuilder.buildDoubleConstant(node.value);
|
| - }
|
| -
|
| - @override
|
| - ir.Constant visitIntegerLiteral(IntegerLiteral node) {
|
| - return irBuilder.buildIntegerConstant(node.value);
|
| - }
|
| -
|
| - @override
|
| - visitAdjacentStrings(AdjacentStrings node) {
|
| - String value = node.stringValue;
|
| - if (value != null) {
|
| - return irBuilder.buildStringConstant(value);
|
| - }
|
| - giveUp(node, "Non constant adjacent strings.");
|
| - }
|
| -
|
| - @override
|
| - ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {
|
| - return irBuilder.buildStringConstant(node.value);
|
| - }
|
| -
|
| - @override
|
| - visitStringInterpolation(StringInterpolation node) {
|
| - giveUp(node, "String interpolation.");
|
| - }
|
| -
|
| - @override
|
| - visitReturnStatement(ReturnStatement node) {
|
| - irBuilder.buildReturn(build(node.expression));
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitPropertyAccess(PropertyAccess node) {
|
| - // Overridden to avoid eager visits of the receiver.
|
| - return handlePropertyAccess(node);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
|
| - return handleLocalAccess(node, semantics);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
|
| - return handleLocalAccess(node, semantics);
|
| - }
|
| -
|
| - @override
|
| - visitVariableDeclaration(VariableDeclaration node) {
|
| - // TODO(johnniwinther): Handle constant local variables.
|
| - ir.Node initialValue = build(node.initializer);
|
| - irBuilder.declareLocalVariable(
|
| - converter.convertElement(node.element),
|
| - initialValue: initialValue);
|
| - }
|
| -
|
| - dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {
|
| - analyzer.Element element = semantics.element;
|
| - dart2js.Element target = converter.convertElement(element);
|
| - assert(invariant(node, target.isLocal, '$target expected to be local.'));
|
| - return target;
|
| - }
|
| -
|
| - ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
|
| - dart2js.Element local = getLocal(node, semantics);
|
| - if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
|
| - return irBuilder.buildLocalFunctionGet(local);
|
| - } else {
|
| - return irBuilder.buildLocalVariableGet(local);
|
| - }
|
| - }
|
| -
|
| - ir.Primitive handleLocalAssignment(AssignmentExpression node,
|
| - AccessSemantics semantics) {
|
| - if (node.operator.lexeme != '=') {
|
| - return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
|
| - }
|
| - return irBuilder.buildLocalVariableSet(
|
| - getLocal(node, semantics),
|
| - build(node.rightHandSide));
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitAssignmentExpression(AssignmentExpression node) {
|
| - // Avoid eager visiting of left and right hand side.
|
| - return handleAssignmentExpression(node);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitLocalVariableAssignment(AssignmentExpression node,
|
| - AccessSemantics semantics) {
|
| - return handleLocalAssignment(node, semantics);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitParameterAssignment(AssignmentExpression node,
|
| - AccessSemantics semantics) {
|
| - return handleLocalAssignment(node, semantics);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitStaticFieldAssignment(AssignmentExpression node,
|
| - AccessSemantics semantics) {
|
| - if (node.operator.lexeme != '=') {
|
| - return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
|
| - }
|
| - analyzer.Element element = semantics.element;
|
| - dart2js.Element target = converter.convertElement(element);
|
| - // TODO(johnniwinther): Selector information should be computed in the
|
| - // [TreeShaker] and shared with the [CpsGeneratingVisitor].
|
| - assert(invariant(node, target.isTopLevel || target.isStatic,
|
| - '$target expected to be top-level or static.'));
|
| - return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
|
| - // TODO(johnniwinther): Handle implicit `this`.
|
| - ir.Primitive receiver = build(semantics.target);
|
| - return irBuilder.buildDynamicGet(receiver,
|
| - new Selector.getter(semantics.identifier.name,
|
| - converter.convertElement(element.library)));
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
|
| - analyzer.Element element = semantics.element;
|
| - dart2js.Element target = converter.convertElement(element);
|
| - // TODO(johnniwinther): Selector information should be computed in the
|
| - // [TreeShaker] and shared with the [CpsGeneratingVisitor].
|
| - assert(invariant(node, target.isTopLevel || target.isStatic,
|
| - '$target expected to be top-level or static.'));
|
| - return irBuilder.buildStaticFieldLazyGet(target, null);
|
| - }
|
| -
|
| - ir.Primitive handleBinaryExpression(BinaryExpression node,
|
| - String op) {
|
| - ir.Primitive left = build(node.leftOperand);
|
| - ir.Primitive right = build(node.rightOperand);
|
| - Selector selector = new Selector.binaryOperator(op);
|
| - return irBuilder.buildDynamicInvocation(
|
| - left, selector, <ir.Primitive>[right]);
|
| - }
|
| -
|
| - ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
|
| - return irBuilder.buildLogicalOperator(
|
| - build(node.leftOperand),
|
| - subbuild(node.rightOperand),
|
| - isLazyOr: isLazyOr);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitBinaryExpression(BinaryExpression node) {
|
| - // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
|
| - // available through an enum.
|
| - String op = node.operator.lexeme;
|
| - switch (op) {
|
| - case '||':
|
| - case '&&':
|
| - return handleLazyOperator(node, isLazyOr: op == '||');
|
| - case '!=':
|
| - return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
|
| - default:
|
| - return handleBinaryExpression(node, op);
|
| - }
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitConditionalExpression(ConditionalExpression node) {
|
| - return irBuilder.buildConditional(
|
| - build(node.condition),
|
| - subbuild(node.thenExpression),
|
| - subbuild(node.elseExpression));
|
| - }
|
| -
|
| - @override
|
| - visitIfStatement(IfStatement node) {
|
| - irBuilder.buildIf(
|
| - build(node.condition),
|
| - subbuild(node.thenStatement),
|
| - subbuild(node.elseStatement));
|
| - }
|
| -
|
| - @override
|
| - visitBlock(Block node) {
|
| - irBuilder.buildBlock(node.statements, build);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitListLiteral(ListLiteral node) {
|
| - dart2js.InterfaceType type = converter.convertType(node.staticType);
|
| - // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue
|
| - // 18630 has been resolved.
|
| - Iterable<ir.Primitive> values = node.elements.map((e) => build(e));
|
| - return irBuilder.buildListLiteral(type, values);
|
| - }
|
| -
|
| - @override
|
| - ir.Node visitMapLiteral(MapLiteral node) {
|
| - dart2js.InterfaceType type = converter.convertType(node.staticType);
|
| - return irBuilder.buildMapLiteral(
|
| - type,
|
| - node.entries.map((e) => e.key),
|
| - node.entries.map((e) => e.value),
|
| - build);
|
| - }
|
| -
|
| - @override
|
| - visitForStatement(ForStatement node) {
|
| - // TODO(johnniwinther): Support `for` as a jump target.
|
| - List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];
|
| - SubbuildFunction buildInitializer;
|
| - if (node.variables != null) {
|
| - buildInitializer = subbuild(node.variables);
|
| - for (VariableDeclaration variable in node.variables.variables) {
|
| - loopVariables.add(converter.convertElement(variable.element));
|
| - }
|
| - } else {
|
| - buildInitializer = subbuild(node.initialization);
|
| - }
|
| - irBuilder.buildFor(buildInitializer: buildInitializer,
|
| - buildCondition: subbuild(node.condition),
|
| - buildBody: subbuild(node.body),
|
| - buildUpdate: subbuildSequence(node.updaters),
|
| - loopVariables: loopVariables);
|
| - }
|
| -
|
| - @override
|
| - visitWhileStatement(WhileStatement node) {
|
| - // TODO(johnniwinther): Support `while` as a jump target.
|
| - irBuilder.buildWhile(buildCondition: subbuild(node.condition),
|
| - buildBody: subbuild(node.body));
|
| - }
|
| -
|
| - @override
|
| - visitDeclaredIdentifier(DeclaredIdentifier node) {
|
| - giveUp(node, "Unexpected node: DeclaredIdentifier");
|
| - }
|
| -
|
| - @override
|
| - visitForEachStatement(ForEachStatement node) {
|
| - SubbuildFunction buildVariableDeclaration;
|
| - dart2js.Element variableElement;
|
| - Selector variableSelector;
|
| - if (node.identifier != null) {
|
| - AccessSemantics accessSemantics =
|
| - node.identifier.accept(ACCESS_SEMANTICS_VISITOR);
|
| - if (accessSemantics.kind == AccessKind.DYNAMIC) {
|
| - variableSelector = new Selector.setter(
|
| - node.identifier.name, converter.convertElement(currentLibrary));
|
| - } else if (accessSemantics.element != null) {
|
| - variableElement = converter.convertElement(accessSemantics.element);
|
| - variableSelector = new Selector.setter(
|
| - variableElement.name,
|
| - converter.convertElement(accessSemantics.element.library));
|
| - } else {
|
| - giveUp(node, 'For-in of unresolved variable: $accessSemantics');
|
| - }
|
| - } else {
|
| - assert(invariant(
|
| - node, node.loopVariable != null, "Loop variable expected"));
|
| - variableElement = converter.convertElement(node.loopVariable.element);
|
| - buildVariableDeclaration = (IrBuilder builder) {
|
| - builder.declareLocalVariable(variableElement);
|
| - };
|
| - }
|
| - // TODO(johnniwinther): Support `for-in` as a jump target.
|
| - irBuilder.buildForIn(
|
| - buildExpression: subbuild(node.iterable),
|
| - buildVariableDeclaration: buildVariableDeclaration,
|
| - variableElement: variableElement,
|
| - variableSelector: variableSelector,
|
| - buildBody: subbuild(node.body));
|
| - }
|
| - @override
|
| - ir.Primitive visitIsExpression(IsExpression node) {
|
| - return irBuilder.buildTypeOperator(
|
| - visit(node.expression),
|
| - converter.convertType(node.type.type),
|
| - isTypeTest: true,
|
| - isNotCheck: node.notOperator != null);
|
| - }
|
| -
|
| - @override
|
| - ir.Primitive visitAsExpression(AsExpression node) {
|
| - return irBuilder.buildTypeOperator(
|
| - visit(node.expression),
|
| - converter.convertType(node.type.type),
|
| - isTypeTest: false);
|
| - }
|
| -
|
| - @override
|
| - visitTryStatement(TryStatement node) {
|
| - List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
|
| - for (CatchClause catchClause in node.catchClauses) {
|
| - catchClauseInfos.add(new CatchClauseInfo(
|
| - exceptionVariable: converter.convertElement(
|
| - catchClause.exceptionParameter.staticElement),
|
| - buildCatchBlock: subbuild(catchClause.body)));
|
| -
|
| - }
|
| - irBuilder.buildTry(
|
| - tryStatementInfo: new TryStatementInfo(),
|
| - buildTryBlock: subbuild(node.body),
|
| - catchClauseInfos: catchClauseInfos);
|
| - }
|
| -}
|
| +// Copyright (c) 2014, 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 analyzer2dart.cps_generator;
|
| +
|
| +import 'package:analyzer/analyzer.dart';
|
| +
|
| +import 'package:compiler/src/dart_types.dart' as dart2js;
|
| +import 'package:compiler/src/elements/elements.dart' as dart2js;
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/generated/element.dart' as analyzer;
|
| +
|
| +import 'package:compiler/src/constant_system_dart.dart'
|
| + show DART_CONSTANT_SYSTEM;
|
| +import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
|
| +import 'package:compiler/src/cps_ir/cps_ir_builder.dart';
|
| +import 'package:compiler/src/universe/universe.dart';
|
| +
|
| +import 'semantic_visitor.dart';
|
| +import 'element_converter.dart';
|
| +import 'util.dart';
|
| +import 'identifier_semantics.dart';
|
| +
|
| +/// Visitor that converts the AST node of an analyzer element into a CPS ir
|
| +/// node.
|
| +class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {
|
| + final ElementConverter converter;
|
| + final AstNode node;
|
| +
|
| + CpsElementVisitor(this.converter, this.node);
|
| +
|
| + @override
|
| + ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {
|
| + CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| + FunctionDeclaration functionDeclaration = node;
|
| + return visitor.handleFunctionDeclaration(
|
| + element, functionDeclaration.functionExpression.body);
|
| + }
|
| +
|
| + @override
|
| + ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {
|
| + CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| + MethodDeclaration methodDeclaration = node;
|
| + return visitor.handleFunctionDeclaration(element, methodDeclaration.body);
|
| + }
|
| +
|
| + @override
|
| + ir.FieldDefinition visitTopLevelVariableElement(
|
| + analyzer.TopLevelVariableElement element) {
|
| + CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| + VariableDeclaration variableDeclaration = node;
|
| + return visitor.handleFieldDeclaration(element, variableDeclaration);
|
| + }
|
| +
|
| + @override
|
| + ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {
|
| + CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
|
| + if (!element.isFactory) {
|
| + ConstructorDeclaration constructorDeclaration = node;
|
| + FunctionBody body;
|
| + if (constructorDeclaration != null) {
|
| + body = constructorDeclaration.body;
|
| + } else {
|
| + assert(element.isSynthetic);
|
| + }
|
| + return visitor.handleConstructorDeclaration(element, body);
|
| + }
|
| + // TODO(johnniwinther): Support factory constructors.
|
| + return null;
|
| + }
|
| +}
|
| +
|
| +/// Visitor that converts analyzer AST nodes into CPS ir nodes.
|
| +class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
|
| + with IrBuilderMixin<AstNode> {
|
| + /// Promote the type of [irBuilder] to [DartIrBuilder].
|
| + /// The JS backend requires closure conversion which we do not support yet.
|
| + DartIrBuilder get irBuilder => super.irBuilder;
|
| + final analyzer.Element element;
|
| + final ElementConverter converter;
|
| +
|
| + CpsGeneratingVisitor(this.converter, this.element);
|
| +
|
| + Source get currentSource => element.source;
|
| +
|
| + analyzer.LibraryElement get currentLibrary => element.library;
|
| +
|
| + ir.Node visit(AstNode node) => node.accept(this);
|
| +
|
| + ir.ConstructorDefinition handleConstructorDeclaration(
|
| + analyzer.ConstructorElement constructor, FunctionBody body) {
|
| + dart2js.ConstructorElement element = converter.convertElement(constructor);
|
| + return withBuilder(
|
| + new DartIrBuilder(DART_CONSTANT_SYSTEM,
|
| + element,
|
| + // TODO(johnniwinther): Support closure variables.
|
| + new Set<dart2js.Local>()),
|
| + () {
|
| + irBuilder.buildFunctionHeader(
|
| + constructor.parameters.map(converter.convertElement));
|
| + // Visit the body directly to avoid processing the signature as
|
| + // expressions.
|
| + // Call to allow for `body == null` in case of synthesized constructors.
|
| + build(body);
|
| + return irBuilder.makeConstructorDefinition(const [], const []);
|
| + });
|
| + }
|
| +
|
| + ir.FieldDefinition handleFieldDeclaration(
|
| + analyzer.PropertyInducingElement field, VariableDeclaration node) {
|
| + dart2js.FieldElement element = converter.convertElement(field);
|
| + return withBuilder(
|
| + new DartIrBuilder(DART_CONSTANT_SYSTEM,
|
| + element,
|
| + // TODO(johnniwinther): Support closure variables.
|
| + new Set<dart2js.Local>()),
|
| + () {
|
| + irBuilder.buildFieldInitializerHeader();
|
| + ir.Primitive initializer = build(node.initializer);
|
| + return irBuilder.makeFieldDefinition(initializer);
|
| + });
|
| + }
|
| +
|
| + ir.FunctionDefinition handleFunctionDeclaration(
|
| + analyzer.ExecutableElement function, FunctionBody body) {
|
| + dart2js.FunctionElement element = converter.convertElement(function);
|
| + return withBuilder(
|
| + new DartIrBuilder(DART_CONSTANT_SYSTEM,
|
| + element,
|
| + // TODO(johnniwinther): Support closure variables.
|
| + new Set<dart2js.Local>()),
|
| + () {
|
| + irBuilder.buildFunctionHeader(
|
| + function.parameters.map(converter.convertElement));
|
| + // Visit the body directly to avoid processing the signature as
|
| + // expressions.
|
| + visit(body);
|
| + return irBuilder.makeFunctionDefinition(const []);
|
| + });
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive visitFunctionExpression(FunctionExpression node) {
|
| + return irBuilder.buildFunctionExpression(
|
| + handleFunctionDeclaration(node.element, node.body));
|
| + }
|
| +
|
| + @override
|
| + ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
|
| + return handleFunctionDeclaration(
|
| + node.element, node.functionExpression.body);
|
| + }
|
| +
|
| + @override
|
| + visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
|
| + FunctionDeclaration functionDeclaration = node.functionDeclaration;
|
| + analyzer.FunctionElement function = functionDeclaration.element;
|
| + dart2js.FunctionElement element = converter.convertElement(function);
|
| + ir.FunctionDefinition definition = handleFunctionDeclaration(
|
| + function, functionDeclaration.functionExpression.body);
|
| + irBuilder.declareLocalFunction(element, definition);
|
| + }
|
| +
|
| + List<ir.Primitive> visitArguments(ArgumentList argumentList) {
|
| + List<ir.Primitive> arguments = <ir.Primitive>[];
|
| + for (Expression argument in argumentList.arguments) {
|
| + ir.Primitive value = build(argument);
|
| + if (value == null) {
|
| + giveUp(argument,
|
| + 'Unsupported argument: $argument (${argument.runtimeType}).');
|
| + }
|
| + arguments.add(value);
|
| + }
|
| + return arguments;
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitMethodInvocation(MethodInvocation node) {
|
| + // Overridden to avoid eager visits of the receiver and arguments.
|
| + return handleMethodInvocation(node);
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive visitDynamicInvocation(MethodInvocation node,
|
| + AccessSemantics semantics) {
|
| + // TODO(johnniwinther): Handle implicit `this`.
|
| + ir.Primitive receiver = build(semantics.target);
|
| + List<ir.Primitive> arguments = visitArguments(node.argumentList);
|
| + return irBuilder.buildDynamicInvocation(
|
| + receiver,
|
| + createSelectorFromMethodInvocation(
|
| + node.argumentList, node.methodName.name),
|
| + arguments);
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
|
| + AccessSemantics semantics) {
|
| + analyzer.Element staticElement = semantics.element;
|
| + dart2js.Element element = converter.convertElement(staticElement);
|
| + List<ir.Primitive> arguments = visitArguments(node.argumentList);
|
| + return irBuilder.buildStaticFunctionInvocation(
|
| + element,
|
| + createCallStructureFromMethodInvocation(node.argumentList),
|
| + arguments);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
|
| + return handleLocalAccess(node, semantics);
|
| + }
|
| +
|
| + ir.Primitive handleLocalInvocation(MethodInvocation node,
|
| + AccessSemantics semantics) {
|
| + analyzer.Element staticElement = semantics.element;
|
| + dart2js.Element element = converter.convertElement(staticElement);
|
| + List<ir.Definition> arguments = visitArguments(node.argumentList);
|
| + CallStructure callStructure = createCallStructureFromMethodInvocation(
|
| + node.argumentList);
|
| + if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
|
| + return irBuilder.buildLocalFunctionInvocation(
|
| + element, callStructure, arguments);
|
| + } else {
|
| + return irBuilder.buildLocalVariableInvocation(
|
| + element, callStructure, arguments);
|
| + }
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitLocalVariableInvocation(MethodInvocation node,
|
| + AccessSemantics semantics) {
|
| + return handleLocalInvocation(node, semantics);
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,
|
| + AccessSemantics semantics) {
|
| + return handleLocalInvocation(node, semantics);
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive visitFunctionExpressionInvocation(
|
| + FunctionExpressionInvocation node) {
|
| + ir.Primitive target = build(node.function);
|
| + List<ir.Definition> arguments = visitArguments(node.argumentList);
|
| + return irBuilder.buildCallInvocation(
|
| + target,
|
| + createCallStructureFromMethodInvocation(node.argumentList),
|
| + arguments);
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive visitInstanceCreationExpression(
|
| + InstanceCreationExpression node) {
|
| + analyzer.Element staticElement = node.staticElement;
|
| + if (staticElement != null) {
|
| + dart2js.Element element = converter.convertElement(staticElement);
|
| + dart2js.DartType type = converter.convertType(node.staticType);
|
| + List<ir.Primitive> arguments = visitArguments(node.argumentList);
|
| + return irBuilder.buildConstructorInvocation(
|
| + element,
|
| + createCallStructureFromMethodInvocation(node.argumentList),
|
| + type,
|
| + arguments);
|
| + }
|
| + return giveUp(node, "Unresolved constructor invocation.");
|
| + }
|
| +
|
| + @override
|
| + ir.Constant visitNullLiteral(NullLiteral node) {
|
| + return irBuilder.buildNullConstant();
|
| + }
|
| +
|
| + @override
|
| + ir.Constant visitBooleanLiteral(BooleanLiteral node) {
|
| + return irBuilder.buildBooleanConstant(node.value);
|
| + }
|
| +
|
| + @override
|
| + ir.Constant visitDoubleLiteral(DoubleLiteral node) {
|
| + return irBuilder.buildDoubleConstant(node.value);
|
| + }
|
| +
|
| + @override
|
| + ir.Constant visitIntegerLiteral(IntegerLiteral node) {
|
| + return irBuilder.buildIntegerConstant(node.value);
|
| + }
|
| +
|
| + @override
|
| + visitAdjacentStrings(AdjacentStrings node) {
|
| + String value = node.stringValue;
|
| + if (value != null) {
|
| + return irBuilder.buildStringConstant(value);
|
| + }
|
| + giveUp(node, "Non constant adjacent strings.");
|
| + }
|
| +
|
| + @override
|
| + ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {
|
| + return irBuilder.buildStringConstant(node.value);
|
| + }
|
| +
|
| + @override
|
| + visitStringInterpolation(StringInterpolation node) {
|
| + giveUp(node, "String interpolation.");
|
| + }
|
| +
|
| + @override
|
| + visitReturnStatement(ReturnStatement node) {
|
| + irBuilder.buildReturn(build(node.expression));
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitPropertyAccess(PropertyAccess node) {
|
| + // Overridden to avoid eager visits of the receiver.
|
| + return handlePropertyAccess(node);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
|
| + return handleLocalAccess(node, semantics);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
|
| + return handleLocalAccess(node, semantics);
|
| + }
|
| +
|
| + @override
|
| + visitVariableDeclaration(VariableDeclaration node) {
|
| + // TODO(johnniwinther): Handle constant local variables.
|
| + ir.Node initialValue = build(node.initializer);
|
| + irBuilder.declareLocalVariable(
|
| + converter.convertElement(node.element),
|
| + initialValue: initialValue);
|
| + }
|
| +
|
| + dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {
|
| + analyzer.Element element = semantics.element;
|
| + dart2js.Element target = converter.convertElement(element);
|
| + assert(invariant(node, target.isLocal, '$target expected to be local.'));
|
| + return target;
|
| + }
|
| +
|
| + ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
|
| + dart2js.Element local = getLocal(node, semantics);
|
| + if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
|
| + return irBuilder.buildLocalFunctionGet(local);
|
| + } else {
|
| + return irBuilder.buildLocalVariableGet(local);
|
| + }
|
| + }
|
| +
|
| + ir.Primitive handleLocalAssignment(AssignmentExpression node,
|
| + AccessSemantics semantics) {
|
| + if (node.operator.lexeme != '=') {
|
| + return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
|
| + }
|
| + return irBuilder.buildLocalVariableSet(
|
| + getLocal(node, semantics),
|
| + build(node.rightHandSide));
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitAssignmentExpression(AssignmentExpression node) {
|
| + // Avoid eager visiting of left and right hand side.
|
| + return handleAssignmentExpression(node);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitLocalVariableAssignment(AssignmentExpression node,
|
| + AccessSemantics semantics) {
|
| + return handleLocalAssignment(node, semantics);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitParameterAssignment(AssignmentExpression node,
|
| + AccessSemantics semantics) {
|
| + return handleLocalAssignment(node, semantics);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitStaticFieldAssignment(AssignmentExpression node,
|
| + AccessSemantics semantics) {
|
| + if (node.operator.lexeme != '=') {
|
| + return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
|
| + }
|
| + analyzer.Element element = semantics.element;
|
| + dart2js.Element target = converter.convertElement(element);
|
| + // TODO(johnniwinther): Selector information should be computed in the
|
| + // [TreeShaker] and shared with the [CpsGeneratingVisitor].
|
| + assert(invariant(node, target.isTopLevel || target.isStatic,
|
| + '$target expected to be top-level or static.'));
|
| + return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
|
| + // TODO(johnniwinther): Handle implicit `this`.
|
| + ir.Primitive receiver = build(semantics.target);
|
| + return irBuilder.buildDynamicGet(receiver,
|
| + new Selector.getter(semantics.identifier.name,
|
| + converter.convertElement(element.library)));
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
|
| + analyzer.Element element = semantics.element;
|
| + dart2js.Element target = converter.convertElement(element);
|
| + // TODO(johnniwinther): Selector information should be computed in the
|
| + // [TreeShaker] and shared with the [CpsGeneratingVisitor].
|
| + assert(invariant(node, target.isTopLevel || target.isStatic,
|
| + '$target expected to be top-level or static.'));
|
| + return irBuilder.buildStaticFieldLazyGet(target, null);
|
| + }
|
| +
|
| + ir.Primitive handleBinaryExpression(BinaryExpression node,
|
| + String op) {
|
| + ir.Primitive left = build(node.leftOperand);
|
| + ir.Primitive right = build(node.rightOperand);
|
| + Selector selector = new Selector.binaryOperator(op);
|
| + return irBuilder.buildDynamicInvocation(
|
| + left, selector, <ir.Primitive>[right]);
|
| + }
|
| +
|
| + ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
|
| + return irBuilder.buildLogicalOperator(
|
| + build(node.leftOperand),
|
| + subbuild(node.rightOperand),
|
| + isLazyOr: isLazyOr);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitBinaryExpression(BinaryExpression node) {
|
| + // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
|
| + // available through an enum.
|
| + String op = node.operator.lexeme;
|
| + switch (op) {
|
| + case '||':
|
| + case '&&':
|
| + return handleLazyOperator(node, isLazyOr: op == '||');
|
| + case '!=':
|
| + return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
|
| + default:
|
| + return handleBinaryExpression(node, op);
|
| + }
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitConditionalExpression(ConditionalExpression node) {
|
| + return irBuilder.buildConditional(
|
| + build(node.condition),
|
| + subbuild(node.thenExpression),
|
| + subbuild(node.elseExpression));
|
| + }
|
| +
|
| + @override
|
| + visitIfStatement(IfStatement node) {
|
| + irBuilder.buildIf(
|
| + build(node.condition),
|
| + subbuild(node.thenStatement),
|
| + subbuild(node.elseStatement));
|
| + }
|
| +
|
| + @override
|
| + visitBlock(Block node) {
|
| + irBuilder.buildBlock(node.statements, build);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitListLiteral(ListLiteral node) {
|
| + dart2js.InterfaceType type = converter.convertType(node.staticType);
|
| + // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue
|
| + // 18630 has been resolved.
|
| + Iterable<ir.Primitive> values = node.elements.map((e) => build(e));
|
| + return irBuilder.buildListLiteral(type, values);
|
| + }
|
| +
|
| + @override
|
| + ir.Node visitMapLiteral(MapLiteral node) {
|
| + dart2js.InterfaceType type = converter.convertType(node.staticType);
|
| + return irBuilder.buildMapLiteral(
|
| + type,
|
| + node.entries.map((e) => e.key),
|
| + node.entries.map((e) => e.value),
|
| + build);
|
| + }
|
| +
|
| + @override
|
| + visitForStatement(ForStatement node) {
|
| + // TODO(johnniwinther): Support `for` as a jump target.
|
| + List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];
|
| + SubbuildFunction buildInitializer;
|
| + if (node.variables != null) {
|
| + buildInitializer = subbuild(node.variables);
|
| + for (VariableDeclaration variable in node.variables.variables) {
|
| + loopVariables.add(converter.convertElement(variable.element));
|
| + }
|
| + } else {
|
| + buildInitializer = subbuild(node.initialization);
|
| + }
|
| + irBuilder.buildFor(buildInitializer: buildInitializer,
|
| + buildCondition: subbuild(node.condition),
|
| + buildBody: subbuild(node.body),
|
| + buildUpdate: subbuildSequence(node.updaters),
|
| + loopVariables: loopVariables);
|
| + }
|
| +
|
| + @override
|
| + visitWhileStatement(WhileStatement node) {
|
| + // TODO(johnniwinther): Support `while` as a jump target.
|
| + irBuilder.buildWhile(buildCondition: subbuild(node.condition),
|
| + buildBody: subbuild(node.body));
|
| + }
|
| +
|
| + @override
|
| + visitDeclaredIdentifier(DeclaredIdentifier node) {
|
| + giveUp(node, "Unexpected node: DeclaredIdentifier");
|
| + }
|
| +
|
| + @override
|
| + visitForEachStatement(ForEachStatement node) {
|
| + SubbuildFunction buildVariableDeclaration;
|
| + dart2js.Element variableElement;
|
| + Selector variableSelector;
|
| + if (node.identifier != null) {
|
| + AccessSemantics accessSemantics =
|
| + node.identifier.accept(ACCESS_SEMANTICS_VISITOR);
|
| + if (accessSemantics.kind == AccessKind.DYNAMIC) {
|
| + variableSelector = new Selector.setter(
|
| + node.identifier.name, converter.convertElement(currentLibrary));
|
| + } else if (accessSemantics.element != null) {
|
| + variableElement = converter.convertElement(accessSemantics.element);
|
| + variableSelector = new Selector.setter(
|
| + variableElement.name,
|
| + converter.convertElement(accessSemantics.element.library));
|
| + } else {
|
| + giveUp(node, 'For-in of unresolved variable: $accessSemantics');
|
| + }
|
| + } else {
|
| + assert(invariant(
|
| + node, node.loopVariable != null, "Loop variable expected"));
|
| + variableElement = converter.convertElement(node.loopVariable.element);
|
| + buildVariableDeclaration = (IrBuilder builder) {
|
| + builder.declareLocalVariable(variableElement);
|
| + };
|
| + }
|
| + // TODO(johnniwinther): Support `for-in` as a jump target.
|
| + irBuilder.buildForIn(
|
| + buildExpression: subbuild(node.iterable),
|
| + buildVariableDeclaration: buildVariableDeclaration,
|
| + variableElement: variableElement,
|
| + variableSelector: variableSelector,
|
| + buildBody: subbuild(node.body));
|
| + }
|
| + @override
|
| + ir.Primitive visitIsExpression(IsExpression node) {
|
| + return irBuilder.buildTypeOperator(
|
| + visit(node.expression),
|
| + converter.convertType(node.type.type),
|
| + isTypeTest: true,
|
| + isNotCheck: node.notOperator != null);
|
| + }
|
| +
|
| + @override
|
| + ir.Primitive visitAsExpression(AsExpression node) {
|
| + return irBuilder.buildTypeOperator(
|
| + visit(node.expression),
|
| + converter.convertType(node.type.type),
|
| + isTypeTest: false);
|
| + }
|
| +
|
| + @override
|
| + visitTryStatement(TryStatement node) {
|
| + List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
|
| + for (CatchClause catchClause in node.catchClauses) {
|
| + catchClauseInfos.add(new CatchClauseInfo(
|
| + exceptionVariable: converter.convertElement(
|
| + catchClause.exceptionParameter.staticElement),
|
| + buildCatchBlock: subbuild(catchClause.body)));
|
| +
|
| + }
|
| + irBuilder.buildTry(
|
| + tryStatementInfo: new TryStatementInfo(),
|
| + buildTryBlock: subbuild(node.body),
|
| + catchClauseInfos: catchClauseInfos);
|
| + }
|
| +}
|
|
|