This commit is contained in:
Ivan Bondarev 2022-01-23 12:10:05 +01:00
parent 775b363a45
commit e132148c44
4 changed files with 60 additions and 7 deletions

View file

@ -2361,6 +2361,7 @@ namespace PascalABCCompiler
p.AddInitFinalMethods();
SystemLibrary.SystemLibInitializer.RestoreStandardFunctions();
p.ProcessWaitedToRestoreFields();
p.RestoreWaitedMethodCodes();
}
bool rest = true;
for (int i=0; i<PCUReader.AllReaders.Count; i++)

View file

@ -66,7 +66,7 @@ namespace PascalABCCompiler.PCU
private SortedDictionary<int, common_type_node> interf_type_list = new SortedDictionary<int, common_type_node>();
private SortedDictionary<int, common_type_node> impl_type_list = new SortedDictionary<int, common_type_node>();
private Dictionary<common_method_node, int> waited_method_codes = new Dictionary<common_method_node, int>();
internal static Dictionary<definition_node, int> AllReadOrWritedDefinitionNodesOffsets = new Dictionary<definition_node, int>();
internal void AddMember(definition_node dn, int offset)
{
@ -687,8 +687,21 @@ namespace PascalABCCompiler.PCU
assemblies[s] = a;
}
}
public void AddWaitedMethodCode(common_method_node cmn, int offset)
{
if (!waited_method_codes.ContainsKey(cmn))
waited_method_codes.Add(cmn, offset);
}
public void RestoreWaitedMethodCodes()
{
foreach (common_method_node cmn in waited_method_codes.Keys)
cmn.function_code = GetCode(waited_method_codes[cmn]);
}
//получение кода метода
public statement_node GetCode(int offset)
public statement_node GetCode(int offset)
{
int tmp = (int)br.BaseStream.Position;
br.BaseStream.Seek(start_pos+offset,SeekOrigin.Begin);
@ -1649,7 +1662,7 @@ namespace PascalABCCompiler.PCU
return ccd;
}
private common_method_node CreateInterfaceMethod(string name, int offset)
private common_method_node CreateInterfaceMethod(string name, int offset, bool not_restore_code = false)
{
definition_node dn = null;
if (members.TryGetValue(offset, out dn))
@ -1705,8 +1718,11 @@ namespace PascalABCCompiler.PCU
cmn.functions_nodes_list.AddElement(GetNestedFunction());
//br.ReadInt32();//code;
cmn.loc = ReadDebugInfo();
if (has_overrided_method)
cmn.function_code = GetCodeWithOverridedMethod(cmn, br.ReadInt32());
else if (not_restore_code && cmn.name != "get_val" && cmn.name != "set_val")//ignore pascal array property accessors
AddWaitedMethodCode(cmn, br.ReadInt32());
else
cmn.function_code = GetCode(br.ReadInt32());
cmn.cont_type.methods.AddElement(cmn);
@ -1761,7 +1777,7 @@ namespace PascalABCCompiler.PCU
//все методы с именем на Get вызываются в процессе восстановления других сущностей
//например, когда восст. код ф-ии, в нем вызывается другая ф-я, которая еще не восстановлена
private common_method_node GetClassMethod(int offset)
private common_method_node GetClassMethod(int offset, bool not_restore_code = false)
{
definition_node dn = null;
if (members.TryGetValue(offset, out dn))
@ -1771,7 +1787,7 @@ namespace PascalABCCompiler.PCU
br.BaseStream.Seek(start_pos + offset, SeekOrigin.Begin);
br.ReadByte();
cmn = (common_method_node)CreateInterfaceMethod(null, offset);
cmn = (common_method_node)CreateInterfaceMethod(null, offset, not_restore_code);
br.BaseStream.Seek(tmp, SeekOrigin.Begin);
return cmn;
@ -1851,9 +1867,11 @@ namespace PascalABCCompiler.PCU
int name_ref = br.ReadInt32();
type_node type = GetTypeReference();
common_method_node get_meth = null;
if (br.ReadByte() == 1) get_meth = GetClassMethod(br.ReadInt32());
if (br.ReadByte() == 1)
get_meth = GetClassMethod(br.ReadInt32(), true);
common_method_node set_meth = null;
if (br.ReadByte() == 1) set_meth = GetClassMethod(br.ReadInt32());
if (br.ReadByte() == 1)
set_meth = GetClassMethod(br.ReadInt32(), true);
int num = br.ReadInt32();
parameter_list pl = new parameter_list();
for (int i = 0; i < num; i++)

View file

@ -0,0 +1,26 @@
unit u_property3;
type
t1 = class
public i: integer;
procedure p1(ind: integer);
// Обязательно default индексное свойство
// Обязательно упомянуть p1, реализованное после объявления t2
// Не важно как упомянуть
public property Item[ind: byte]: word write p1(ind); default;
end;
// Обязательно шаблон
// Обязательно наследовать от t1
t2<T> = class(t1) end;
procedure t1.p1(ind: integer);
begin
// Обязательно упомянуть t2
var a: t2<real>;
self.i := ind;
end;
end.

View file

@ -0,0 +1,8 @@
uses u_property3;
begin
var b: t2<byte>;
var c: t1 := new t1;
c[2] := 2;
assert(c.i = 2);
end.