Commit 00d29b76 authored by Stefan Behnel's avatar Stefan Behnel

move 'with' statement implementation back into WithTransform to fix 'with'...

move 'with' statement implementation back into WithTransform to fix 'with' statement usage for compiler directives
parent 402cc4b9
......@@ -102,7 +102,7 @@ class Context(object):
def create_pipeline(self, pxd, py=False):
from Visitor import PrintTree
from ParseTreeTransforms import NormalizeTree, PostParse, PxdPostParse
from ParseTreeTransforms import WithTransform, NormalizeTree, PostParse, PxdPostParse
from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods
......@@ -139,6 +139,7 @@ class Context(object):
_align_function_definitions,
ConstantFolding(),
FlattenInListTransform(),
WithTransform(self),
DecoratorTransform(self),
AnalyseDeclarationsTransform(self),
AutoTestDictTransform(self),
......
......@@ -4835,7 +4835,7 @@ class WithStatNode(StatNode):
"""
Represents a Python with statement.
Implemented as follows:
Implemented by the WithTransform as follows:
MGR = EXPR
EXIT = MGR.__exit__
......@@ -4855,61 +4855,13 @@ class WithStatNode(StatNode):
MGR = EXIT = VALUE = None
"""
# manager The with statement manager object
# target ExprNode the target lhs of the __enter__() call
# body StatNode
child_attrs = ["manager", "body"]
child_attrs = ["manager", "target", "body"]
has_target = False
def __init__(self, pos, manager, target, body):
StatNode.__init__(self, pos, manager = manager)
import ExprNodes
self.target_temp = ExprNodes.TempNode(pos, type=py_object_type)
if target is not None:
self.has_target = True
body = StatListNode(
pos, stats = [
WithTargetAssignmentStatNode(
pos, lhs = target, rhs = self.target_temp),
body
])
import UtilNodes
excinfo_target = UtilNodes.ResultRefNode(
pos=pos, type=Builtin.tuple_type, may_hold_none=False)
except_clause = ExceptClauseNode(
pos, body = IfStatNode(
pos, if_clauses = [
IfClauseNode(
pos, condition = ExprNodes.NotNode(
pos, operand = ExprNodes.WithExitCallNode(
pos, with_stat = self,
args = excinfo_target)),
body = ReraiseStatNode(pos),
),
],
else_clause = None),
pattern = None,
target = None,
excinfo_target = excinfo_target,
)
self.body = TryFinallyStatNode(
pos, body = TryExceptStatNode(
pos, body = body,
except_clauses = [except_clause],
else_clause = None,
),
finally_clause = ExprStatNode(
pos, expr = ExprNodes.WithExitCallNode(
pos, with_stat = self,
args = ExprNodes.TupleNode(
pos, args = [ExprNodes.NoneNode(pos) for _ in range(3)]
))),
handle_error_case = False,
)
def analyse_declarations(self, env):
self.manager.analyse_declarations(env)
self.body.analyse_declarations(env)
......
......@@ -897,6 +897,61 @@ class InterpretCompilerDirectives(CythonTransform, SkipDeclarations):
return self.visit_with_directives(node.body, directive_dict)
return self.visit_Node(node)
class WithTransform(CythonTransform, SkipDeclarations):
def visit_WithStatNode(self, node):
self.visitchildren(node, 'body')
pos = node.pos
body, target, manager = node.body, node.target, node.manager
node.target_temp = ExprNodes.TempNode(pos, type=PyrexTypes.py_object_type)
if target is not None:
node.has_target = True
body = Nodes.StatListNode(
pos, stats = [
Nodes.WithTargetAssignmentStatNode(
pos, lhs = target, rhs = node.target_temp),
body
])
node.target = None
excinfo_target = ResultRefNode(
pos=pos, type=Builtin.tuple_type, may_hold_none=False)
except_clause = Nodes.ExceptClauseNode(
pos, body = Nodes.IfStatNode(
pos, if_clauses = [
Nodes.IfClauseNode(
pos, condition = ExprNodes.NotNode(
pos, operand = ExprNodes.WithExitCallNode(
pos, with_stat = node,
args = excinfo_target)),
body = Nodes.ReraiseStatNode(pos),
),
],
else_clause = None),
pattern = None,
target = None,
excinfo_target = excinfo_target,
)
node.body = Nodes.TryFinallyStatNode(
pos, body = Nodes.TryExceptStatNode(
pos, body = body,
except_clauses = [except_clause],
else_clause = None,
),
finally_clause = Nodes.ExprStatNode(
pos, expr = ExprNodes.WithExitCallNode(
pos, with_stat = node,
args = ExprNodes.TupleNode(
pos, args = [ExprNodes.NoneNode(pos) for _ in range(3)]
))),
handle_error_case = False,
)
return node
def visit_ExprNode(self, node):
# With statements are never inside expressions.
return node
class DecoratorTransform(CythonTransform, SkipDeclarations):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment