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
52 changes: 18 additions & 34 deletions src/core/IronPython/Compiler/Ast/AsyncForStatement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

using System.Threading;

using Microsoft.Scripting;
using IronPython.Runtime.Binding;
using IronPython.Runtime.Exceptions;

using MSAst = System.Linq.Expressions;

namespace IronPython.Compiler.Ast {
Expand Down Expand Up @@ -70,60 +72,42 @@ 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 aiterCall = SetScope(new UnaryExpression(PythonOperationKind.AIter, List));
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 anextCall = SetScope(new UnaryExpression(PythonOperationKind.ANext, SetScope(new NameExpression(iterName))));
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(nameof(PythonExceptions.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
15 changes: 0 additions & 15 deletions src/core/IronPython/Compiler/Ast/AsyncStatement.cs

This file was deleted.

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
5 changes: 0 additions & 5 deletions src/core/IronPython/Compiler/Ast/PythonNameBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,6 @@ public override bool Walk(AsyncForStatement node) {
node.Parent = _currentScope;
return base.Walk(node);
}
// AsyncStatement
public override bool Walk(AsyncStatement node) {
node.Parent = _currentScope;
return base.Walk(node);
}
// AsyncWithStatement
public override bool Walk(AsyncWithStatement node) {
node.Parent = _currentScope;
Expand Down
8 changes: 0 additions & 8 deletions src/core/IronPython/Compiler/Ast/PythonWalker.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,6 @@ public virtual void PostWalk(AssignmentStatement node) { }
public virtual bool Walk(AsyncForStatement node) { return true; }
public virtual void PostWalk(AsyncForStatement node) { }

// AsyncStatement
public virtual bool Walk(AsyncStatement node) { return true; }
public virtual void PostWalk(AsyncStatement node) { }

// AsyncWithStatement
public virtual bool Walk(AsyncWithStatement node) { return true; }
public virtual void PostWalk(AsyncWithStatement node) { }
Expand Down Expand Up @@ -415,10 +411,6 @@ public override void PostWalk(AssignmentStatement node) { }
public override bool Walk(AsyncForStatement node) { return false; }
public override void PostWalk(AsyncForStatement node) { }

// AsyncStatement
public override bool Walk(AsyncStatement node) { return false; }
public override void PostWalk(AsyncStatement node) { }

// AsyncWithStatement
public override bool Walk(AsyncWithStatement node) { return false; }
public override void PostWalk(AsyncWithStatement node) { }
Expand Down
26 changes: 14 additions & 12 deletions src/core/IronPython/Compiler/Ast/UnaryExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using MSAst = System.Linq.Expressions;
#nullable enable

using System;
using System.Diagnostics;

using IronPython.Runtime.Binding;

namespace IronPython.Compiler.Ast {
using Ast = MSAst.Expression;
using AstUtils = Microsoft.Scripting.Ast.Utils;
using MSAst = System.Linq.Expressions;

namespace IronPython.Compiler.Ast {
public class UnaryExpression : Expression {
public UnaryExpression(PythonOperator op, Expression expression) {
Operator = op;
OperationKind = PythonOperatorToOperatorString(op);
Expression = expression;
EndIndex = expression.EndIndex;
}

internal UnaryExpression(PythonOperationKind op, Expression expression) {
OperationKind = op;
Expression = expression;
EndIndex = expression.EndIndex;
}
Expand All @@ -24,13 +29,10 @@ public UnaryExpression(PythonOperator op, Expression expression) {

public PythonOperator Operator { get; }

public override MSAst.Expression Reduce() {
return GlobalParent.Operation(
typeof(object),
PythonOperatorToOperatorString(Operator),
Expression
);
}
internal PythonOperationKind OperationKind { get; }

public override MSAst.Expression Reduce()
=> GlobalParent.Operation(typeof(object), OperationKind, Expression);

public override void Walk(PythonWalker walker) {
if (walker.Walk(this)) {
Expand Down
Loading
Loading