pascalabcnet/SyntaxVisitors/YieldVisitors/JustTestVisitor.cs

151 lines
6.4 KiB
C#
Raw Normal View History

// 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;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PascalABCCompiler;
using PascalABCCompiler.SyntaxTree;
namespace SyntaxVisitors
{
public class JustTestVisitor : BaseChangeVisitor
{
private void CollectFormalParams(procedure_definition pd, ISet<var_def_statement> collectedFormalParams)
{
if ((object)pd.proc_header.parameters != null)
collectedFormalParams.UnionWith(pd.proc_header.parameters.params_list.Select(tp => new var_def_statement(tp.idents, tp.vars_type)));
}
private void CollectFormalParamsNames(procedure_definition pd, ISet<string> collectedFormalParamsNames)
{
if ((object)pd.proc_header.parameters != null)
collectedFormalParamsNames.UnionWith(pd.proc_header.parameters.params_list.SelectMany(tp => tp.idents.idents).Select(id => id.name));
}
private void CollectClassFieldsNames(procedure_definition pd, ISet<string> collectedFields, out bool isInClassMethod)
{
isInClassMethod = false;
ident className = null;
if ((object)pd.proc_header.name.class_name != null)
{
// Объявление вне класса его метода
className = pd.proc_header.name.class_name;
}
else
{
// Объявление функции в классе?
var classDef = UpperNode(3) as class_definition;
if ((object)(UpperNode(3) as class_definition) != null)
{
var td = UpperNode(4) as type_declaration;
if ((object)td != null)
{
className = td.type_name;
}
}
}
if ((object)className != null)
{
isInClassMethod = true;
CollectClassFieldsVisitor fieldsVis = new CollectClassFieldsVisitor(className);
var cu = UpperTo<compilation_unit>();
if ((object)cu != null)
{
cu.visit(fieldsVis);
// Collect
collectedFields.UnionWith(fieldsVis.CollectedFields.Select(id => id.name));
}
}
}
private void CollectUnitGlobalsNames(procedure_definition pd, ISet<string> collectedUnitGlobalsName)
{
var cu = UpperTo<compilation_unit>();
if ((object)cu != null)
{
var ugVis = new CollectUnitGlobalsVisitor();
cu.visit(ugVis);
// Collect
collectedUnitGlobalsName.UnionWith(ugVis.CollectedGlobals.Select(id => id.name));
}
}
private void CreateCapturedLocalsNamesMap(ISet<string> localsNames, IDictionary<string, string> capturedLocalsNamesMap)
{
foreach (var localName in localsNames)
{
capturedLocalsNamesMap.Add(localName, CapturedNamesHelper.MakeCapturedLocalName(localName));
}
}
private void CreateCapturedFormalParamsNamesMap(ISet<string> formalParamsNames, IDictionary<string, string> captueedFormalParamsNamesMap)
{
foreach (var formalParamName in formalParamsNames)
{
captueedFormalParamsNamesMap.Add(formalParamName, CapturedNamesHelper.MakeCapturedFormalParameterName(formalParamName));
}
}
public override void visit(procedure_definition pd)
{
// frninja
// Classification
ISet<string> CollectedLocalsNames = new HashSet<string>();
ISet<string> CollectedFormalParamsNames = new HashSet<string>();
ISet<string> CollectedClassFieldsNames = new HashSet<string>();
ISet<string> CollectedUnitGlobalsNames = new HashSet<string>();
ISet<var_def_statement> CollectedLocals = new HashSet<var_def_statement>();
ISet<var_def_statement> CollectedFormalParams = new HashSet<var_def_statement>();
// Map from ident idName -> captured ident idName
IDictionary<string, string> CapturedLocalsNamesMap = new Dictionary<string, string>();
IDictionary<string, string> CapturedFormalParamsNamesMap = new Dictionary<string, string>();
var dld = new DeleteAllLocalDefs(); // mids.vars - все захваченные переменные
pd.visit(dld); // Удалить в локальных и блочных описаниях этой процедуры все переменные и вынести их в отдельный список var_def_statement
// frninja 08/12/15
bool isInClassMethod;
// Collect locals
CollectedLocals.UnionWith(dld.LocalDeletedDefs);
CollectedLocalsNames.UnionWith(dld.LocalDeletedDefs.SelectMany(vds => vds.vars.idents).Select(id => id.name));
// Collect formal params
CollectFormalParams(pd, CollectedFormalParams);
CollectFormalParamsNames(pd, CollectedFormalParamsNames);
// Collect class fields
CollectClassFieldsNames(pd, CollectedClassFieldsNames, out isInClassMethod);
// Collect unit globals
CollectUnitGlobalsNames(pd, CollectedUnitGlobalsNames);
// Create maps :: idName -> captureName
CreateCapturedLocalsNamesMap(CollectedLocalsNames, CapturedLocalsNamesMap);
CreateCapturedFormalParamsNamesMap(CollectedFormalParamsNames, CapturedFormalParamsNamesMap);
// AHAHA test!
ReplaceCapturedVariablesVisitor rcapVis = new ReplaceCapturedVariablesVisitor(
CollectedLocalsNames,
CollectedFormalParamsNames,
CollectedClassFieldsNames,
new HashSet<string>(),
new HashSet<string>(),
CollectedUnitGlobalsNames,
CapturedLocalsNamesMap,
CapturedFormalParamsNamesMap,
isInClassMethod
);
// Replace
(pd.proc_body as block).program_code.visit(rcapVis);
}
}
}