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 |
deleted file mode 100644 |
index 1e5bb6dbf342c262e61e15bc67d7d7f170a3b289..0000000000000000000000000000000000000000 |
--- a/pkg/analyzer2dart/lib/src/cps_generator.dart |
+++ /dev/null |
@@ -1,589 +0,0 @@ |
-// 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); |
- } |
-} |