pascalabcnet/SyntaxVisitors/Async/AwaitBuilder.cs
2024-07-12 21:06:00 +03:00

815 lines
36 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using PascalABCCompiler.SyntaxTree;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
namespace SyntaxVisitors.Async
{
internal class AwaitBuilder
{
// корень дерева
private program_module program_Module { get; set; }
// текущий асинхронный метод
public procedure_definition proc_def { get; set; }
int lbnum = 0;
// тело асинхронного метода
private statement_list code_list = new statement_list();
// Список Taskов, принадлежащих к какому-нибудь await
public expression_list TaskList = new expression_list();
// Счетчик awaitов
public int AwaiterCounter = 0;
// Счетчик временных переменных для Task
public int TempTaskCounter = 1;
public VarsHelper VarsHelper;
// Возвращаемый тип асинхронного метода
public string ResultType = "";
// Результат работы асинхронного метода
public expression ResultVal = new expression();
//ctor
public AwaitBuilder(program_module pm, procedure_definition pd)
{
program_Module = pm;
proc_def = pd;
VarsHelper = new VarsHelper();
}
public int NewAwaiterCounter = 1;
public string NewAwaiter()
{
return "@aw@_" + NewAwaiterCounter++;
}
// для каждого await добавляем awaiter
public void AddAwaiter(bool IsFirstTime, expression ex, int c)
{
var a_name = NewAwaiter();
TaskList.AddFirst(ex);
var tdecl = program_Module.program_block.defs.list[c] as type_declarations;
var tdef = tdecl.types_decl[0];
var cd = tdef.type_def as class_definition;
var bd = cd.body;
var vds = new var_def_statement(new ident(a_name, bd.source_context), new named_type_reference(new ident("string", bd.source_context)), bd.source_context);
var class_name = proc_def.proc_header.name.class_name;
if (IsFirstTime)
{
List<declaration> members = new List<declaration> { vds };
if (class_name != null)
{
members.Add(new var_statement(new var_def_statement(new ident("@awclass", bd.source_context), new named_type_reference(class_name), bd.source_context), bd.source_context));
}
var cm = new class_members(members, new access_modifer_node(access_modifer.private_modifer), bd.source_context);
bd.AddFirst(cm);
}
else
{
var cm2 = bd.class_def_blocks[0];
cm2.Add(vds);
}
}
// Меняем тип AsyncBuilder
public void ChangeBuilder(string Type, int ChangeBuilderCounter)
{
var tdecl = program_Module.program_block.defs.list[ChangeBuilderCounter] as type_declarations;
var tdef = tdecl.types_decl[0];
var cd = tdef.type_def as class_definition;
var bd = cd.body;
var cm = bd[1] as class_members;
var vdf = cm[2] as var_def_statement;
var pd = program_Module.program_block.defs.list[ChangeBuilderCounter + 1] as procedure_definition;
var pb = pd.proc_body as block;
var st = pb.program_code;
var a = st.list[0] as assign;
var mc = new method_call();
mc.source_context = st.source_context;
if (Type.StartsWith("AsyncVoidMethodBuilder") || Type == "AsyncTaskMethodBuilder")
{
vdf.vars_type = new named_type_reference(Type, vdf.source_context);
mc.dereferencing_value = new dot_node(new ident(Type, vdf.source_context), new ident("Create"));
}
else
{
var tt = Type.Substring(23);
tt = tt.Replace(">", "");
ResultType = tt;
var tpl = new template_param_list();
tpl.source_context = vdf.source_context;
tpl.params_list.Add(new named_type_reference(new ident(tt, vdf.source_context)));
vdf.vars_type = new template_type_reference("AsyncTaskMethodBuilder", tpl);
mc.dereferencing_value = new dot_node(new ident_with_templateparams(new ident("AsyncTaskMethodBuilder", vdf.source_context),
tpl, vdf.source_context), new ident("Create", vdf.source_context), vdf.source_context);
}
a.from = mc;
}
public string newLabelName()
{
lbnum++;
return "@awlb@_" + lbnum.ToString();
}
// Обрабатываем тело асинхронного метода
public void GetCode()
{
var class_name = proc_def.proc_header.name.class_name;
if (class_name != null)
{
foreach (var item in program_Module.program_block.defs.list)
{
if (item is type_declarations)
{
var tds = item as type_declarations;
foreach (var tdef in tds.types_decl)
{
if (tdef.type_name.name == class_name.name)
{
var cd = tdef.type_def as class_definition;
var bd = cd.body;
for (int i = 0; i < bd.Count; i++)
{
if (bd[i] is class_members)
{
var cm = bd[i] as class_members;
foreach (var mem in cm.members)
{
if (mem is var_def_statement)
{
var vm = mem as var_def_statement;
if (vm.var_attr != definition_attribute.Static)
{
foreach (var vms in vm.vars.list)
{
VarsHelper.ClassIdentSet.Add(vms.name);
}
}
else
{
foreach (var vms in vm.vars.list)
{
VarsHelper.ClassStaticSet.Add(vms.name);
}
}
}
}
}
}
}
}
}
}
}
var b = proc_def.proc_header is function_header;
var procedure_code = (proc_def.proc_body as block).program_code.list[0] as statement_list;
var temp_list = new statement_list();
var r_list = new statement_list();
if (proc_def.proc_header.parameters != null)
{
var par = proc_def.proc_header.parameters;
foreach (var p in par.params_list)
{
if (p.param_kind is parametr_kind.var_parametr)
{
throw new SyntaxVisitorError("var-параметры нельзя использовать в асинхронных методах ", p.source_context);
}
foreach (var id in p.idents.list)
{
var v = new var_statement(new var_def_statement(id, p.vars_type, p.source_context), p.source_context);
VarsHelper.VarsList.Add(v);
VarsHelper.Parametrs.Add(id.name);
}
}
}
var await_counter = 0;
bool flag = true;
for (int i = 0; i < procedure_code.list.Count; i++)
{
if (procedure_code.list[i] is await_node_statement)
{
var pp = procedure_code.list[i] as await_node_statement;
await_counter++;
flag = false;
var a = pp.aw;
if (a.ex is ident)
{
VarsHelper.ExprHash.Add(a.ex.ToString());
if (!VarsHelper.TaskIdents.ContainsKey(a.ex.ToString()))
{
VarsHelper.TaskIdents.Add(a.ex.ToString(), await_counter.ToString());
}
}
}
if (procedure_code.list[i] is if_node)
{
var if_node = procedure_code.list[i] as if_node;
OperationsVisitor.HasAwait = false;
OperationsVisitor.Accept(if_node);
if (OperationsVisitor.HasAwait == true)
{
temp_list.Add(procedure_code.list[i]);
if (i + 1 >= procedure_code.Count)
{
await_counter++;
flag = false;
}
else
if (!(procedure_code.list[i + 1] is if_node))
{
await_counter++;
flag = false;
}
}
}
// бывший цикл while
if (procedure_code.list[i] is labeled_statement)
{
var lb = procedure_code.list[i] as labeled_statement;
if (lb.to_statement is if_node)
{
var if_node = lb.to_statement as if_node;
OperationsVisitor.HasAwait = false;
OperationsVisitor.Accept(if_node);
if (OperationsVisitor.HasAwait == true)
{
temp_list.Add(procedure_code.list[i]);
await_counter++;
flag = false;
}
}
}
if (procedure_code.list[i] is var_statement)
{
var pp = procedure_code.list[i] as var_statement;
if (pp.var_def.inital_value is bin_expr || pp.var_def.inital_value is un_expr)
{
OperationsVisitor.HasAwait = false;
OperationsVisitor.Accept(pp.var_def);
}
if (pp.var_def.inital_value is await_node)
{
var a = pp.var_def.inital_value as await_node;
VarsHelper.VarsList.Add(pp);
foreach (var v in pp.var_def.vars.list)
{
var mmc = new method_call();
mmc.source_context = v.source_context;
if (a.ex is method_call)
mmc.dereferencing_value = GenGetResult(new dot_node(a.ex as method_call,
new ident("GetAwaiter", v.source_context)), v);
else
mmc.dereferencing_value = GenGetResult(new dot_node(new ident(a.ex.ToString(), v.source_context),
new ident("GetAwaiter", v.source_context)), v);
var ass = new assign(v, mmc, Operators.Assignment, v.source_context);
ass.first_assignment_defines_type = true;
r_list.Add(ass);
}
await_counter++;
flag = false;
if (a.ex is ident)
{
VarsHelper.ExprHash.Add(a.ex.ToString());
if (!VarsHelper.TaskIdents.ContainsKey(a.ex.ToString()))
{
VarsHelper.TaskIdents.Add(a.ex.ToString(), await_counter.ToString());
}
}
}
else
{
if (pp.var_def.inital_value != null)
{
if (pp.var_def.inital_value is ident)
{
var id = pp.var_def.inital_value as ident;
if (AsyncVisitor.ProcedureSet.Contains(id.name.ToString()))
{
pp.var_def.inital_value = null;
pp.var_def.vars_type = new procedure_header();
VarsHelper.VarsList.Add(pp);
foreach (var item in pp.var_def.vars.list)
{
var ass = new assign(item, id, Operators.Assignment, item.source_context);
temp_list.Add(ass);
}
continue;
}
if (AsyncVisitor.FunctionSet.Contains(id.name.ToString()))
{
var mc = new method_call();
mc.dereferencing_value = id;
pp.var_def.inital_value = mc;
}
}
foreach (var item in pp.var_def.vars.list)
{
var ass = new assign(item, pp.var_def.inital_value, Operators.Assignment, item.source_context);
ass.first_assignment_defines_type = true;
temp_list.Add(ass);
}
}
else
{
if (pp.var_def.vars_type.ToString().Contains("Task"))
{
pp.var_def.inital_value = new default_operator(new named_type_reference
(pp.var_def.vars_type.ToString()));
pp.var_def.vars_type = null;
foreach (var item in pp.var_def.vars.list)
{
var ass = new assign(item, pp.var_def.inital_value, Operators.Assignment, item.source_context);
ass.first_assignment_defines_type = true;
temp_list.Add(ass);
}
}
}
VarsHelper.VarsList.Add(pp);
continue;
}
}
if (procedure_code.list[i] is assign)
{
var a = procedure_code.list[i] as assign;
OperationsVisitor.HasAwait = false;
OperationsVisitor.Accept(a);
if (OperationsVisitor.HasAwait == true)
{
temp_list.Add(procedure_code.list[i]);
await_counter++;
flag = false;
}
}
if (procedure_code.list[i] is assign && b)
{
var pa = procedure_code.list[i] as assign;
if (pa.to is ident)
{
var pat = pa.to as ident;
if (pat.name == "Result")
{
ResultVal = pa.from;
}
}
}
if (flag)
temp_list.Add(procedure_code.list[i]);
else
{
flag = true;
code_list.Add(temp_list);
temp_list = r_list;
r_list = new statement_list();
}
}
VarsHelper.MarkVars();
AwaiterCounter = await_counter;
code_list.Add(temp_list);
code_list.source_context = procedure_code.source_context;
}
// Изменяем метод MoveNext в зависимости от количества await
public void GenAwait(int c)
{
var pd = program_Module.program_block.defs.list[c] as procedure_definition;
var bl = pd.proc_body as block;
var class_name = proc_def.proc_header.name.class_name;
var awaiter = "@aw@_";
var aw_temp = "@awtemp@_";
var extp = "awextemp@_";
// используется если await внутри цикла
if ((proc_def.proc_body as block).defs != null)
{
var loopLabelsList = (proc_def.proc_body as block).defs.list;
if (loopLabelsList != null)
foreach (var b in loopLabelsList)
{
bl.defs.Add(b);
}
}
var lb1 = newLabelName();
bl.defs.Add(new label_definitions(new ident(lb1, bl.source_context)), bl.source_context);
var ts = bl.program_code.list[0] as try_stmt;
var g1 = new goto_statement(lb1, ts.source_context);
var ls = new labeled_statement(lb1);
ls.source_context = ts.source_context;
(code_list.list[1] as statement_list).source_context = ts.source_context;
ts.stmt_list.Remove(ts.stmt_list.Last());
// если метод возвращает значение
if (ResultType != "")
{
var r_pc = new procedure_call(new method_call(new dot_node(new ident("tbuilder", ts.source_context),
new ident("SetResult", ts.source_context)),
new expression_list(new ident("@aw_res", ts.source_context), ts.source_context), ts.source_context), ts.source_context);
bl.program_code.list[2] = r_pc;
r_pc.Parent = bl.program_code;
}
////// if (state == 1)
var ifnode = new if_node();
ifnode.source_context = ts.source_context;
ifnode.condition = new bin_expr(new dot_node(new ident("self"), new ident("state")), new int32_const(1), Operators.Equal, ts.source_context);
var extemp = new var_statement(new var_def_statement(new ident(extp, TaskList[0].source_context),
TaskList[0] as expression, TaskList[0].source_context), TaskList[0].source_context);
(code_list.list[0] as statement_list).Add(extemp);
var mcс = new method_call();
mcс.dereferencing_value = new dot_node(new ident(extp, TaskList[0].source_context), new ident("GetAwaiter", TaskList[0].source_context));
mcс.source_context = TaskList[0].source_context;
var assign_ = new assign(new ident("@aw@_" + "1", ts.source_context), mcс, Operators.Assignment, ts.source_context);
assign_.first_assignment_defines_type = true;
var if2 = new if_node();
if2.source_context = ts.source_context;
if2.condition = new bin_expr(new dot_node(new ident("@aw@_" + "1", ts.source_context), new ident("IsCompleted", ts.source_context), ts.source_context),
new ident("False", ts.source_context), Operators.Equal, ts.source_context);
var a1 = new assign(new dot_node(new ident("self", if2.source_context), new ident("state", ts.source_context), if2.source_context), new int32_const(2, ts.source_context), Operators.Assignment, ts.source_context);
var temp = new var_statement(new var_def_statement(new ident(aw_temp, ts.source_context), new ident("self", ts.source_context)), ts.source_context);
var dt = new dot_node(new dot_node(new ident("self", ts.source_context), new ident("tbuilder", ts.source_context)),
new ident("AwaitUnsafeOnCompleted", ts.source_context), ts.source_context);
var ex = new expression_list(new ident("@aw@_" + "1", ts.source_context), ts.source_context);
ex.Add(new ident(aw_temp));
var mc = new method_call(dt, ex, ts.source_context);
var pc = new procedure_call(mc, ts.source_context);
var ifnode_body2 = new statement_list(a1, temp, pc, new procedure_call(new ident("exit"), ts.source_context), new empty_statement());
ifnode_body2.left_logical_bracket = new token_info("begin");
ifnode_body2.right_logical_bracket = new token_info("end");
if2.then_body = ifnode_body2;
if2.then_body.source_context = ts.source_context;
(code_list.list[0] as statement_list).Add(assign_, ts.source_context);
(code_list.list[0] as statement_list).Add(if2, ts.source_context);
(code_list.list[0] as statement_list).Add(new empty_statement(), ts.source_context);
var ifnode_body1 = new statement_list(code_list.list[0], ts.source_context);
ifnode_body1.Add(g1, ts.source_context);
ifnode_body1.left_logical_bracket = new token_info("begin");
ifnode_body1.right_logical_bracket = new token_info("end");
ifnode.then_body = ifnode_body1;
ifnode.source_context = ts.source_context;
FillTypedVars(c - 2);
ts.stmt_list.Add(ifnode, ts.source_context);
////// if (state == 1)
// Добавляем метки для переходов по состояниям
var awCount = AwaiterCounter;
while (awCount > 1)
{
awCount--;
lb1 = newLabelName();
bl.defs.Add(new label_definitions(new ident(lb1, ts.source_context)), ts.source_context);
}
lbnum = 0;
awCount = AwaiterCounter;
// Когда Task уже завершен
while (awCount != 0)
{
awCount--;
///if (state == 2,3,4 ...)
var ifnode2 = new if_node();
ifnode2.condition = new bin_expr(new dot_node(new ident("self", ts.source_context), new ident("state", ts.source_context)),
new int32_const(lbnum + 2, ts.source_context), Operators.Equal, ts.source_context);
///state = -1;
var a5 = new assign(new dot_node(new ident("self", ts.source_context),
new ident("state", ts.source_context)), new un_expr(new int32_const(1, ts.source_context),
Operators.Minus, ts.source_context), Operators.Assignment, ts.source_context);
///goto label;
var stlist3 = new statement_list(a5, new goto_statement(newLabelName(), ts.source_context), new empty_statement());
stlist3.left_logical_bracket = new token_info("begin");
stlist3.right_logical_bracket = new token_info("end");
ifnode2.then_body = stlist3;
ifnode2.then_body.source_context = ts.source_context;
ifnode2.source_context = ts.source_context;
ts.stmt_list.Add(ifnode2, ts.source_context);
}
lbnum = 1;
awCount = AwaiterCounter;
ts.stmt_list.Add(ls, ts.source_context);
var mc2 = new method_call();
mc2.source_context = ts.source_context;
// начиная со второго встреченного await
while (awCount > 1)
{
awCount--;
var lb2 = newLabelName();
var g2 = new goto_statement(lb2, ts.source_context);
var ls2 = new labeled_statement(lb2);
ls2.source_context = ts.source_context;
mc2 = new method_call();
mc2.source_context = ts.source_context;
mc2.dereferencing_value = GenGetResult(new ident(awaiter + (lbnum - 1).ToString(), ts.source_context), ts);
ts.stmt_list.Add(new procedure_call(mc2, ts.source_context), ts.source_context);
var tt = code_list.list[lbnum - 1] as statement_list;
var fg = true;
foreach (var stat in tt.list)
{
if (stat is assign && fg)
{
var asstat = stat as assign;
if (asstat.from.ToString().Contains("GetResult"))
{
asstat.from = mc2;
mc2.Parent = asstat;
}
}
fg = false;
ts.stmt_list.Add(stat, stat.source_context);
}
extemp = new var_statement(new var_def_statement(new ident(extp + lbnum.ToString(), TaskList[lbnum - 1].source_context),
TaskList[lbnum - 1] as expression, TaskList[lbnum - 1].source_context), TaskList[lbnum - 1].source_context);
extemp.source_context = TaskList[lbnum - 1].source_context;
ts.stmt_list.Add(extemp, TaskList[lbnum - 1].source_context);
var mccc = new method_call();
mccc.dereferencing_value = new dot_node(new ident(extp + lbnum.ToString(), TaskList[lbnum - 1].source_context),
new ident("GetAwaiter", TaskList[lbnum - 1].source_context), TaskList[lbnum - 1].source_context);
mccc.source_context = TaskList[lbnum - 1].source_context;
var assign22_ = new assign(new ident(awaiter + lbnum.ToString(), ts.source_context), mccc, Operators.Assignment, ts.source_context);
assign22_.source_context = ts.source_context;
assign22_.first_assignment_defines_type = true;
ts.stmt_list.Add(assign22_, ts.source_context);
var if3 = new if_node();
if3.source_context = ts.source_context;
if3.condition = new bin_expr(new dot_node(new ident(awaiter + lbnum.ToString(), ts.source_context),
new ident("IsCompleted", ts.source_context)),
new ident("False", ts.source_context), Operators.Equal, ts.source_context);
var a11 = new assign(new dot_node(new ident("self", ts.source_context), new ident("state", ts.source_context)),
new int32_const(lbnum + 1), Operators.Assignment, ts.source_context);
var temp2 = new var_statement(new var_def_statement
(new ident(aw_temp, ts.source_context),
new ident("self", ts.source_context), ts.source_context), ts.source_context);
var dt1 = new dot_node(new dot_node(new ident("self", ts.source_context),
new ident("tbuilder", ts.source_context), ts.source_context),
new ident("AwaitUnsafeOnCompleted", ts.source_context), ts.source_context);
var ex1 = new expression_list(new ident(awaiter + lbnum.ToString(), ts.source_context), ts.source_context);
ex1.Add(new ident(aw_temp, ts.source_context), ts.source_context);
var mc11 = new method_call(dt1, ex1, ts.source_context);
var pc11 = new procedure_call(mc11, ts.source_context);
var stlist4 = new statement_list(a11, temp2, pc11, new procedure_call(new ident("exit")), new empty_statement());
stlist4.source_context = ts.source_context;
stlist4.left_logical_bracket = new token_info("begin");
stlist4.right_logical_bracket = new token_info("end");
if3.then_body = stlist4;
ts.stmt_list.Add(if3, ts.source_context);
ts.stmt_list.Add(g2, ts.source_context);
ts.stmt_list.Add(ls2, ts.source_context);
}
// Когда await закончились и пора выводить результат
mc2 = new method_call();
mc2.source_context = ts.source_context;
mc2.dereferencing_value = GenGetResult(new ident(awaiter + lbnum.ToString(), ts.source_context), ts);
ts.stmt_list.Add(new procedure_call(mc2, ts.source_context), ts.source_context);
var tt2 = code_list.list.Last() as statement_list;
var fg2 = true;
foreach (var stat in tt2.list)
{
if (stat is assign && fg2)
{
var asstat = stat as assign;
if (asstat.from.ToString().Contains("GetResult"))
{
asstat.from = mc2;
mc2.Parent = asstat;
}
}
fg2 = false;
ts.stmt_list.Add(stat, stat.source_context);
}
// Переименование всех переменных класса, находящихся в теле асинхронного метода
foreach (var cis in VarsHelper.ClassIdentSet)
{
var replacerVis = new ReplaceVarNamesVisitor(cis, "@awclass." + cis);
ts.visit(replacerVis);
if (replacerVis.counter != 0 && proc_def.proc_header.class_keyword)
{
throw new SyntaxVisitorError("Для нестатического поля, метода или свойства требуется ссылка на объект",
ts.source_context);
}
}
// Переименование всех статических переменных класса, находящихся в теле асинхронного метода
foreach (var cis in VarsHelper.ClassStaticSet)
{
var replacerVis = new ReplaceVarNamesVisitor(cis, class_name + "." + cis);
ts.visit(replacerVis);
}
var MethodsSet = new HashSet<string>();
if (class_name != null)
{
foreach (var dec in program_Module.program_block.defs.list)
{
if (dec is type_declarations)
{
var td = (type_declarations)dec;
foreach (var tdeff in td.types_decl)
{
if (tdeff.type_name.name != class_name.name)
{
continue;
}
if (tdeff.type_def is class_definition)
{
var cd = tdeff.type_def as class_definition;
var bd = cd.body;
for (int j = 0; j < bd.Count; j++)
{
if (bd[j] is class_members)
{
var cm = bd[j] as class_members;
foreach (var item in cm.members)
{
if (item is procedure_header)
{
var pph = item as procedure_header;
if (!pph.class_keyword)
{
MethodsSet.Add(pph.name.meth_name.name);
}
}
if (item is function_header)
{
var fh = item as function_header;
if (!fh.class_keyword)
MethodsSet.Add(fh.name.meth_name.name);
}
}
}
}
}
}
}
}
}
foreach (var item in MethodsSet)
{
var replacerVis = new ReplaceVarNamesVisitor(item, "@awclass." + item);
ts.visit(replacerVis);
}
// Сохранение результата асинхронного метода
if (ResultType != "")
{
if (ResultVal.Parent == null && ResultVal.Parent == null)
{
ts.stmt_list.Add(new assign(new ident("@aw_res", ts.source_context),
new default_operator(new named_type_reference(ResultType, ts.source_context),
ts.source_context), ts.source_context), ts.source_context);
}
else
{
var replacerVis = new ReplaceVarNamesVisitor("Result", "@aw_res");
ts.visit(replacerVis);
}
}
}
// Генерируем GetResult, заменяя GetResult на GenGetResult
public static dot_node GenGetResult(syntax_tree_node stn, syntax_tree_node ts)
{
if (stn is ident)
{
return new dot_node(stn as ident, new ident("GetResult"), ts.source_context);
}
return new dot_node(stn as dot_node, new ident("GetResult"), ts.source_context);
}
// Объявляем локальные переменные полями класса StateMachine
public void FillTypedVars(int c)
{
var tdecl = program_Module.program_block.defs.list[c] as type_declarations;
var tdef = tdecl.types_decl[0];
var cd = tdef.type_def as class_definition;
var bd = cd.body;
var cm = bd[1] as class_members;
if (ResultType != "")
{
var r_vds = new var_def_statement(new ident("@aw_res", cm.source_context),
new named_type_reference(new ident(ResultType, cm.source_context), cm.source_context), cm.source_context);
cm.Add(r_vds);
}
foreach (var vt in VarsHelper.TasksHash)
{
var vd = new var_def_statement(new ident_list(), new named_type_reference("string", vt.source_context));
foreach (var w in vt.var_def.vars.list)
{
vd.vars.Add(w, w.source_context);
}
cm.Add(vd);
}
foreach (var v in VarsHelper.VarsList)
{
if (VarsHelper.TasksHash.Contains(v))
{
continue;
}
if (VarsHelper.NoneTypedVarsList.Contains(v))
{
var vv = new var_statement();
vv.source_context = v.source_context;
vv.var_def = new var_def_statement(v.var_def.vars,
new named_type_reference(new ident("string", v.source_context), v.source_context), v.source_context);
cm.Add(vv.var_def);
continue;
}
cm.Add(v.var_def);
}
}
// Удаляем тело асинхронной функции
public void DeleteBody()
{
var b = proc_def.proc_body as block;
var st = b.program_code;
st.list.Remove(st.list.First());
}
}
}