pascalabcnet/SyntaxVisitors/Async/OperationsVisitor.cs
Kalsash ced4424196
Async await# GenGetResult (#3151)
* Добавил комментарии для async/await

* source_context fix

* ReplaceVarNames fix

* Parametrs fix

* async_defs fix

* no await fix

* исправлен баг с объявлением Task<T> без инициализации

* await как bin_expr может теперь быть в if_node.condition

* Обработка операций с await

* генерация GetResult

* OperationsVisitor fix

---------

Co-authored-by: Aleksandr Kalinin <akalinin@sfedu.ru>
Co-authored-by: Mikhalkovich Stanislav <miks@math.sfedu.ru>
2024-06-18 08:57:06 +03:00

104 lines
3.1 KiB
C#

using PascalABCCompiler.SyntaxTree;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SyntaxVisitors.Async
{
// Визитор, который заменяет все await
// на await.GetResult
internal class OperationsVisitor : BaseChangeVisitor
{
public static bool HasAwait = false;
public string ExprType = "";
public static OperationsVisitor New
{
get { return new OperationsVisitor(); }
}
public static void Accept(if_node if_nd)
{
if (if_nd == null)
return;
if (if_nd.condition[0] is bin_expr)
{
New.ProcessNode(if_nd.condition[0] as bin_expr);
return;
}
if (if_nd.condition is bin_expr)
{
New.ProcessNode(if_nd.condition as bin_expr);
return;
}
if (if_nd.condition is un_expr)
{
New.ProcessNode(if_nd.condition);
return;
}
}
public static void Accept(var_def_statement vds)
{
if (vds == null)
return;
if (vds.inital_value is bin_expr)
{
New.ProcessNode(vds.inital_value as bin_expr);
}
if (vds.inital_value is un_expr)
{
New.ProcessNode(vds.inital_value as un_expr);
}
}
public static void Accept(assign a)
{
if (a == null)
return;
New.ProcessNode(a.from);
}
public override void visit(un_expr un_Expr)
{
ProcessNode(un_Expr.subnode);
}
public override void visit(bin_expr b_epxr)
{
ExprType = "left";
ProcessNode(b_epxr.left);
ExprType = "right";
ProcessNode(b_epxr.right);
}
public override void visit(await_node a)
{
if (a.Parent == null)
return;
var mmc = new method_call();
mmc.source_context = a.source_context;
if (a.ex is method_call)
mmc.dereferencing_value = AwaitBuilder.GenGetResult(new dot_node(a.ex as method_call,
new ident("GetAwaiter", a.source_context)),a);
else
mmc.dereferencing_value = AwaitBuilder.GenGetResult(new dot_node(new ident(a.ex.ToString(), a.source_context),
new ident("GetAwaiter", a.source_context)), a);
if (a.Parent is bin_expr)
{
if (ExprType == "left")
(a.Parent as bin_expr).left = mmc;
if (ExprType == "right")
(a.Parent as bin_expr).right = mmc;
}
if (a.Parent is un_expr)
{
(a.Parent as un_expr).subnode = mmc;
}
if (a.Parent is assign)
{
(a.Parent as assign).from = mmc;
}
HasAwait = true;
}
}
}