2015-06-01 22:15:17 +03:00
|
|
|
|
// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (for details please see \doc\copyright.txt)
|
|
|
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
|
|
using System.Collections.Generic;
|
2015-05-14 22:35:07 +03:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using PascalABCCompiler.SyntaxTree;
|
|
|
|
|
|
using PascalABCCompiler.TreeRealization;
|
|
|
|
|
|
|
|
|
|
|
|
namespace TreeConverter.LambdaExpressions
|
|
|
|
|
|
{
|
|
|
|
|
|
internal class LambdaCapturedSymbolsHelper
|
|
|
|
|
|
{
|
|
|
|
|
|
private static List<ident> GetTemplateParametersTypeDependsOn(type_node type)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (type.generic_function_container != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new List<ident>
|
|
|
|
|
|
{
|
|
|
|
|
|
new ident(type.name)
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var typeRef = type as ref_type_node;
|
|
|
|
|
|
if (typeRef != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetTemplateParametersTypeDependsOn(typeRef.pointed_type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var typeIi = type.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface;
|
|
|
|
|
|
if (typeIi != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetTemplateParametersTypeDependsOn(typeIi.element_type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
return GetTemplateParametersTypeDependsOn(type.element_type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (type.IsDelegate)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dii = type.get_internal_interface(internal_interface_kind.delegate_interface) as delegate_internal_interface;
|
|
|
|
|
|
var res = new List<ident>();
|
|
|
|
|
|
if (dii != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var paramCount = dii.parameters.Count;
|
|
|
|
|
|
for (var i = 0; i < paramCount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
res.AddRange(GetTemplateParametersTypeDependsOn(dii.parameters[i].type));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (type.is_generic_type_instance)
|
|
|
|
|
|
{
|
|
|
|
|
|
var pcount = type.instance_params.Count;
|
|
|
|
|
|
var res = new List<ident>();
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < pcount; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
res.AddRange(GetTemplateParametersTypeDependsOn(type.instance_params[i]));
|
|
|
|
|
|
}
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return new List<ident>();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static List<ident> GetIdsForTemplateParametersFromLambdaParameters(List<type_node> parametersTypes)
|
|
|
|
|
|
{
|
|
|
|
|
|
var res = new List<ident>();
|
|
|
|
|
|
|
|
|
|
|
|
if (parametersTypes == null
|
|
|
|
|
|
|| parametersTypes.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return res;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var parType in parametersTypes)
|
|
|
|
|
|
{
|
|
|
|
|
|
res.AddRange(GetTemplateParametersTypeDependsOn(parType));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return res.GroupBy(id => id.name)
|
|
|
|
|
|
.Select(ids => ids.First())
|
|
|
|
|
|
.ToList();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|