2019-07-28 23:53:15 +03:00
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
2019-06-16 10:28:53 +03:00
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System.Collections.Generic ;
2026-03-08 18:30:33 +03:00
using PascalABCCompiler.CoreUtils ;
2019-06-16 10:28:53 +03:00
using PascalABCCompiler.SyntaxTree ;
namespace PascalABCCompiler.SyntaxTreeConverters
{
// Первое предназначение - вынести последовательность из заголовка в foreach до foreach как отдельное присваивание
// Второе предназначение - переименовать все переменные, совпадающие по имени с типом T обобщенного класса, в котором находится метод, содержащий лямбду
2021-01-10 07:54:31 +03:00
public class StandOutExprWithLambdaInForeachSequenceAndNestedLambdasVisitor : BaseChangeVisitor
2019-06-16 10:28:53 +03:00
{
2026-03-08 18:30:33 +03:00
private readonly GeneratedNamesManager generatedNamesManager ;
private StandOutExprWithLambdaInForeachSequenceAndNestedLambdasVisitor ( GeneratedNamesManager generatedNamesManager )
2019-06-16 10:28:53 +03:00
{
2026-03-08 18:30:33 +03:00
this . generatedNamesManager = generatedNamesManager ;
2019-06-16 10:28:53 +03:00
}
2026-03-08 18:30:33 +03:00
public static StandOutExprWithLambdaInForeachSequenceAndNestedLambdasVisitor Create ( GeneratedNamesManager generatedNamesManager )
= > new StandOutExprWithLambdaInForeachSequenceAndNestedLambdasVisitor ( generatedNamesManager ) ;
2019-06-16 10:28:53 +03:00
//private ident_list ClassTemplateArgsOrNull = null; // если мы - в обобщенном классе, то это - е г о обобщенные параметры
public ident GenIdentName ( )
{
2026-03-08 18:30:33 +03:00
return new ident ( generatedNamesManager . GenerateName ( "$GenContFE" ) ) ;
2019-06-16 10:28:53 +03:00
}
public override void visit ( foreach_stmt fe )
{
//if (fe.DescendantNodes().OfType<function_lambda_definition>().Count() > 0) // из-за #1984 убрал вообще условие. Пусть будет всегда
{
var id = GenIdentName ( ) ;
id . Parent = fe ;
var ass = new var_statement ( id , fe . in_what , fe . in_what . source_context ) ;
2019-11-18 00:34:05 +03:00
id . source_context = fe . in_what . source_context ;
2019-06-16 10:28:53 +03:00
fe . in_what = id ;
var l = new List < statement > { ass , fe } ;
//ReplaceStatement(fe, l);
ReplaceStatementUsingParent ( fe , l ) ;
}
base . visit ( fe ) ;
}
2021-01-09 01:31:53 +03:00
private int countNestedLambdas = 0 ;
public override void visit ( function_lambda_definition fld )
{
countNestedLambdas + = 1 ;
if ( countNestedLambdas > 10 )
throw new SyntaxVisitors . SyntaxVisitorError ( "NESTED_LAMBDAS_MAXIMUM_10" , fld . source_context ) ;
ProcessNode ( fld . proc_body ) ;
countNestedLambdas - = 1 ;
}
2019-06-16 10:28:53 +03:00
}
}