Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 17 additions & 33 deletions src/core/IronPython/Compiler/Ast/AsyncForStatement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,60 +70,44 @@ private Statement BuildDesugared() {
var iterName = $"__asyncfor_iter{id}";
var runningName = $"__asyncfor_running{id}";

// Helper to create nodes with proper parent and span
NameExpression MakeName(string name) {
var n = new NameExpression(name) { Parent = parent };
n.IndexSpan = span;
return n;
}

T WithSpan<T>(T node) where T : Node {
// Helper to assign proper parent and span to nodes
T SetScope<T>(T node) where T : Node {
node.Parent = parent;
node.IndexSpan = span;
return node;
}

// _iter = ITER.__aiter__()
var aiterAttr = WithSpan(new MemberExpression(List, "__aiter__") { Parent = parent });
var aiterCall = WithSpan(new CallExpression(aiterAttr, null, null) { Parent = parent });
var assignIter = WithSpan(new AssignmentStatement(new Expression[] { MakeName(iterName) }, aiterCall) { Parent = parent });
var aiterAttr = SetScope(new MemberExpression(List, "__aiter__"));
var aiterCall = SetScope(new CallExpression(aiterAttr, null, null));
var assignIter = SetScope(new AssignmentStatement([SetScope(new NameExpression(iterName))], aiterCall));

// running = True
var trueConst = new ConstantExpression(true) { Parent = parent }; trueConst.IndexSpan = span;
var assignRunning = WithSpan(new AssignmentStatement(new Expression[] { MakeName(runningName) }, trueConst) { Parent = parent });
var trueConst = SetScope(new ConstantExpression(true));
var assignRunning = SetScope(new AssignmentStatement([SetScope(new NameExpression(runningName))], trueConst));

// TARGET = await __aiter.__anext__()
var anextAttr = WithSpan(new MemberExpression(MakeName(iterName), "__anext__") { Parent = parent });
var anextCall = WithSpan(new CallExpression(anextAttr, null, null) { Parent = parent });
var anextAttr = SetScope(new MemberExpression(SetScope(new NameExpression(iterName)), "__anext__"));
var anextCall = SetScope(new CallExpression(anextAttr, null, null));
var awaitNext = new AwaitExpression(anextCall);
var assignTarget = WithSpan(new AssignmentStatement(new Expression[] { Left }, awaitNext) { Parent = parent });
var assignTarget = SetScope(new AssignmentStatement([Left], awaitNext));

// except StopAsyncIteration: __running = False
var falseConst = new ConstantExpression(false) { Parent = parent }; falseConst.IndexSpan = span;
var stopRunning = WithSpan(new AssignmentStatement(
new Expression[] { MakeName(runningName) }, falseConst) { Parent = parent });
var handler = WithSpan(new TryStatementHandler(
MakeName("StopAsyncIteration"),
null!,
WithSpan(new SuiteStatement(new Statement[] { stopRunning }) { Parent = parent })
) { Parent = parent });
var falseConst = SetScope(new ConstantExpression(false));
var stopRunning = SetScope(new AssignmentStatement([SetScope(new NameExpression(runningName))], falseConst));
var handler = SetScope(new TryStatementHandler(SetScope(new NameExpression("StopAsyncIteration")), null!, SetScope(new SuiteStatement([stopRunning]))));
handler.HeaderIndex = span.End;

// try/except/else block
var tryExcept = WithSpan(new TryStatement(
assignTarget,
new[] { handler },
WithSpan(new SuiteStatement(new Statement[] { Body }) { Parent = parent }),
null!
) { Parent = parent });
var tryExcept = SetScope(new TryStatement(assignTarget, [handler], SetScope(new SuiteStatement([Body])), null));
tryExcept.HeaderIndex = span.End;

// while __running: try/except/else
var whileStmt = new WhileStatement(MakeName(runningName), tryExcept, Else);
var whileStmt = new WhileStatement(SetScope(new NameExpression(runningName)), tryExcept, Else);
whileStmt.SetLoc(GlobalParent, span.Start, span.End, span.End);
whileStmt.Parent = parent;

var suite = WithSpan(new SuiteStatement(new Statement[] { assignIter, assignRunning, whileStmt }) { Parent = parent });
return suite;
return SetScope(new SuiteStatement([assignIter, assignRunning, whileStmt]));
}

public override MSAst.Expression Reduce() {
Expand Down
55 changes: 20 additions & 35 deletions src/core/IronPython/Compiler/Ast/AsyncWithStatement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,57 +52,42 @@ private Statement BuildDesugared() {
// finally:
// await mgr.__aexit__(None, None, None)

// Helper to create nodes with proper parent and span
NameExpression MakeName(string name) {
var n = new NameExpression(name) { Parent = parent };
n.IndexSpan = span;
return n;
// Helper to assign proper parent and span to nodes
T SetScope<T>(T node) where T : Node {
node.Parent = parent;
node.IndexSpan = span;
return node;
}

// mgr = EXPR
var assignMgr = new AssignmentStatement(new Expression[] { MakeName("__asyncwith_mgr") }, ContextManager) { Parent = parent };
assignMgr.IndexSpan = span;
var assignMgr = SetScope(new AssignmentStatement([SetScope(new NameExpression("__asyncwith_mgr"))], ContextManager));

// await mgr.__aenter__()
var aenterAttr = new MemberExpression(MakeName("__asyncwith_mgr"), "__aenter__") { Parent = parent };
aenterAttr.IndexSpan = span;
var aenterCall = new CallExpression(aenterAttr, null, null) { Parent = parent };
aenterCall.IndexSpan = span;
var aenterAttr = SetScope(new MemberExpression(SetScope(new NameExpression("__asyncwith_mgr")), "__aenter__"));
var aenterCall = SetScope(new CallExpression(aenterAttr, null, null));
var awaitEnter = new AwaitExpression(aenterCall);

Statement bodyStmt;
if (Variable != null) {
if (Variable is not null) {
// VAR = await value; BLOCK
var assignVar = new AssignmentStatement(new Expression[] { Variable }, awaitEnter) { Parent = parent };
assignVar.IndexSpan = span;
bodyStmt = new SuiteStatement(new Statement[] { assignVar, Body }) { Parent = parent };
var assignVar = SetScope(new AssignmentStatement([Variable], awaitEnter));
bodyStmt = new SuiteStatement([assignVar, Body]) { Parent = parent };
} else {
var exprStmt = new ExpressionStatement(awaitEnter) { Parent = parent };
exprStmt.IndexSpan = span;
bodyStmt = new SuiteStatement(new Statement[] { exprStmt, Body }) { Parent = parent };
var exprStmt = SetScope(new ExpressionStatement(awaitEnter));
bodyStmt = new SuiteStatement([exprStmt, Body]) { Parent = parent };
}

// await mgr.__aexit__(None, None, None)
var aexitAttr = new MemberExpression(MakeName("__asyncwith_mgr"), "__aexit__") { Parent = parent };
aexitAttr.IndexSpan = span;
var none1 = new ConstantExpression(null) { Parent = parent }; none1.IndexSpan = span;
var none2 = new ConstantExpression(null) { Parent = parent }; none2.IndexSpan = span;
var none3 = new ConstantExpression(null) { Parent = parent }; none3.IndexSpan = span;
var aexitCallNormal = new CallExpression(aexitAttr,
new Expression[] { none1, none2, none3 }, null) { Parent = parent };
aexitCallNormal.IndexSpan = span;
var aexitAttr = SetScope(new MemberExpression(SetScope(new NameExpression("__asyncwith_mgr")), "__aexit__"));
var none = SetScope(new ConstantExpression(null));
var aexitCallNormal = SetScope(new CallExpression(aexitAttr, [none, none, none], null));
var awaitExitNormal = new AwaitExpression(aexitCallNormal);

// try/finally: await __aexit__ on normal exit
var finallyExprStmt = new ExpressionStatement(awaitExitNormal) { Parent = parent };
finallyExprStmt.IndexSpan = span;
var tryFinally = new TryStatement(bodyStmt, null, null, finallyExprStmt) { Parent = parent };
tryFinally.IndexSpan = span;
tryFinally.HeaderIndex = span.End;

var suite = new SuiteStatement(new Statement[] { assignMgr, tryFinally }) { Parent = parent };
suite.IndexSpan = span;
return suite;
var finallyExprStmt = SetScope(new ExpressionStatement(awaitExitNormal));
var tryFinally = SetScope(new TryStatement(bodyStmt, null, null, finallyExprStmt) { HeaderIndex = span.End });

return SetScope(new SuiteStatement([assignMgr, tryFinally]));
}

public override MSAst.Expression Reduce() {
Expand Down