pascalabcnet/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutionsManager.cs
Александр Земляк 1f4b44c2c0
Исправление ошибок при перекомпиляции pcu файлов (#3398)
* Move yield string constants to StringConstants class

* Add GeneratedNamesManager class to store all generated names during unit compilation

* Make GeneratedNamesManager class non static

* Add Utils project to installer files

* Add GeneratedNamesManager usage in CapturedVariablesSubstitutionsManager

* Move GeneratedNamesManager initialization in CompilationUnit constructor

* More GeneratedNamesManager usage

* QuestionPointDesugarVisitor fix
2026-03-08 18:30:33 +03:00

102 lines
5 KiB
C#

// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System.Linq;
using PascalABCCompiler.SyntaxTree;
using PascalABCCompiler.TreeConverter;
using PascalABCCompiler.CoreUtils;
namespace TreeConverter.LambdaExpressions.Closure
{
class CapturedVariablesSubstitutionsManager
{
public static void Substitute(syntax_tree_visitor _visitor, declarations decls, statement_list _statementList, GeneratedNamesManager generatedNamesManager)
{
var tree = new CapturedVariablesTreeBuilder(_visitor, generatedNamesManager).BuildTree(_statementList);
var substs = new CapturedVariablesSubstitutionClassGenerator(tree.RootNode, generatedNamesManager).GenerateSubstitutions();
new CapturedVariablesSubstitutor(tree.IdentsReferences, substs.GeneratedScopeClassesInfo, substs.LambdasToBeAddedAsMethods, substs.SubstitutionsInfo, tree.CapturedVarsNodesDictionary, substs.ConvertingClassNonPublicMembersMapping, _visitor, generatedNamesManager)
.Substitute(_statementList);
if (_visitor.context.converting_block() == block_type.function_block && tree.ProcedureScope != null)
{
if (decls != null && decls.defs != null)
{
foreach (var def in decls.defs.Where(d => d is const_definition ||
d is consts_definitions_list ||
d is variable_definitions))
{
var constDef = def as const_definition;
if (constDef != null)
{
var finder = new FindMainIdentsVisitor();
finder.ProcessNode(constDef.const_value);
foreach (var v in finder.vars)
{
SymbolInfo si = _visitor.context.find_first(v.name);
if (si == null)
{
continue;
}
if(tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si))
{
_visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v)));
}
}
continue;
}
var constDefList = def as consts_definitions_list;
if (constDefList != null)
{
foreach (var cd in constDefList.const_defs)
{
var finder = new FindMainIdentsVisitor();
finder.ProcessNode(cd.const_value);
foreach (var v in finder.vars)
{
SymbolInfo si = _visitor.context.find_first(v.name);
if (si == null)
{
continue;
}
if (tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si))
{
_visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v)));
}
}
}
continue;
}
var varDefList = def as variable_definitions;
if (varDefList != null)
{
foreach (var d in varDefList.var_definitions)
{
var finder = new FindMainIdentsVisitor();
finder.ProcessNode(d.inital_value);
foreach (var v in finder.vars)
{
SymbolInfo si = _visitor.context.find_first(v.name);
if (si == null)
{
continue;
}
if (tree.ProcedureScope.VariablesDefinedInScope.Any(var => var.SymbolInfo == si))
{
_visitor.AddError(new UsingCapturedParameterIsNotAllowedInInitializers(_visitor.get_location(v)));
}
}
}
}
}
}
}
}
}
}