fix #2878
This commit is contained in:
parent
4e8c5ec89e
commit
5664851b72
13
TestSuite/delegates20.pas
Normal file
13
TestSuite/delegates20.pas
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
type
|
||||||
|
d1<T> = Action<procedure(a: T)>;
|
||||||
|
|
||||||
|
procedure p0(d: d1<byte>) := exit;
|
||||||
|
|
||||||
|
var i: integer;
|
||||||
|
begin
|
||||||
|
var d: d1<string>;
|
||||||
|
//Ошибка: Нельзя преобразовать тип string к byte
|
||||||
|
d := p->p('abc');
|
||||||
|
d((x: string)->begin assert(x = 'abc'); i := 1 end);
|
||||||
|
assert(i = 1);
|
||||||
|
end.
|
||||||
|
|
@ -1266,6 +1266,37 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.IntPtr", sem_type.location), sem_type.location);
|
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.IntPtr", sem_type.location), sem_type.location);
|
||||||
else if (sem_type is compiled_type_node ctn2 && ctn2.compiled_type == typeof(System.UIntPtr))
|
else if (sem_type is compiled_type_node ctn2 && ctn2.compiled_type == typeof(System.UIntPtr))
|
||||||
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.UIntPtr", sem_type.location), sem_type.location);
|
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.UIntPtr", sem_type.location), sem_type.location);
|
||||||
|
else if (sem_type is common_type_node && (sem_type as common_type_node).IsDelegate)
|
||||||
|
{
|
||||||
|
var tn = sem_type as common_type_node;
|
||||||
|
var invokeMeth = tn.find_first_in_type("Invoke");
|
||||||
|
if (invokeMeth != null)
|
||||||
|
{
|
||||||
|
var fn = invokeMeth.sym_info as function_node;
|
||||||
|
PascalABCCompiler.SyntaxTree.procedure_header header;
|
||||||
|
if (fn.return_value_type != null)
|
||||||
|
{
|
||||||
|
header = new PascalABCCompiler.SyntaxTree.function_header(ConvertToSyntaxType(fn.return_value_type));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
header = new PascalABCCompiler.SyntaxTree.procedure_header();
|
||||||
|
}
|
||||||
|
header.parameters = new PascalABCCompiler.SyntaxTree.formal_parameters();
|
||||||
|
foreach (var param in fn.parameters)
|
||||||
|
{
|
||||||
|
var tparam = new PascalABCCompiler.SyntaxTree.typed_parameters();
|
||||||
|
tparam.vars_type = ConvertToSyntaxType(param.type);
|
||||||
|
tparam.idents = new PascalABCCompiler.SyntaxTree.ident_list();
|
||||||
|
tparam.idents.Add(new PascalABCCompiler.SyntaxTree.ident(param.name));
|
||||||
|
header.parameters.Add(tparam);
|
||||||
|
|
||||||
|
}
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location);
|
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18764,7 +18764,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
foreach (SyntaxTree.type_definition id in types)
|
foreach (SyntaxTree.type_definition id in types)
|
||||||
{
|
{
|
||||||
type_node tn = null;
|
type_node tn = null;
|
||||||
if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id))
|
if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id) && !type_synonym_instancing)
|
||||||
tn = delegate_cache[id];
|
tn = delegate_cache[id];
|
||||||
else
|
else
|
||||||
tn = convert_strong(id);
|
tn = convert_strong(id);
|
||||||
|
|
@ -18773,7 +18773,7 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
{
|
{
|
||||||
AddError(get_location(id), "TYPE_NAME_EXPECTED");
|
AddError(get_location(id), "TYPE_NAME_EXPECTED");
|
||||||
}
|
}
|
||||||
if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id))
|
if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id) && !type_synonym_instancing)
|
||||||
{
|
{
|
||||||
delegate_cache[id] = tn;
|
delegate_cache[id] = tn;
|
||||||
}
|
}
|
||||||
|
|
@ -18934,6 +18934,8 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool type_synonym_instancing = false;
|
||||||
|
|
||||||
public common_type_node instance(template_class tc, List<type_node> template_params, location loc, template_type_reference used_ttr = null)
|
public common_type_node instance(template_class tc, List<type_node> template_params, location loc, template_type_reference used_ttr = null)
|
||||||
{
|
{
|
||||||
//Проверяем, что попытка инстанцирования корректна
|
//Проверяем, что попытка инстанцирования корректна
|
||||||
|
|
@ -19093,7 +19095,9 @@ namespace PascalABCCompiler.TreeConverter
|
||||||
prm.source_context = loc;
|
prm.source_context = loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
type_synonym_instancing = true;
|
||||||
type_node synonym_value = convert_strong(tc.type_dec.type_def);
|
type_node synonym_value = convert_strong(tc.type_dec.type_def);
|
||||||
|
type_synonym_instancing = false;
|
||||||
foreach (type_definition td in saved_sc_dict.Keys)
|
foreach (type_definition td in saved_sc_dict.Keys)
|
||||||
td.source_context = saved_sc_dict[td];
|
td.source_context = saved_sc_dict[td];
|
||||||
ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name,
|
ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue