Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Unified Diff: pkg/analyzer2dart/lib/src/cps_generator.dart

Issue 1214853002: Update some files from CRLF to LF (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer2dart/lib/src/semantic_visitor.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
+ }
+}
« no previous file with comments | « no previous file | pkg/analyzer2dart/lib/src/semantic_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698