Lazy generic_instance_type_node.ImplementingInterfaces

This commit is contained in:
Sun Serega 2022-10-06 11:06:27 +03:00
parent f49e132d38
commit 04ae33af4a
5 changed files with 53 additions and 5 deletions

View file

@ -1,4 +1,4 @@
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
// 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.Linq;
@ -1523,7 +1523,10 @@ namespace PascalABCCompiler.NETGenerator
{
AddTypeWithoutConvert(t);
}
foreach (ITypeNode interf in t.ImplementingInterfaces)
// ImplementingInterfacesOrEmpty, потому что если интерфейсы небыли лениво-посчитаны семантикой
// То и тут их обходить нет смысла
// А в ошибочных ситуациях (как err0303.pas) может ещё и зациклится
foreach (ITypeNode interf in t.ImplementingInterfacesOrEmpty)
if (!(interf is ICompiledTypeNode))
ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)interf);
if (t.base_type != null && !(t.base_type is ICompiledTypeNode))

View file

@ -211,6 +211,10 @@ namespace PascalABCCompiler.SemanticTree
}
List<ITypeNode> ImplementingInterfaces
{
get;
}
List<ITypeNode> ImplementingInterfacesOrEmpty
{
get;
}

View file

@ -3872,9 +3872,13 @@ namespace PascalABCCompiler.TreeConverter
// "t1<T> = class(i1<T>)" => "t1<byte>" реализует "i1<byte>" а не "i1<T>"
gti.pseudo_instance.SetBaseType(generic_convertions.determine_type(converted_type.base_type, gti.param_types, false));
// Сбрасываем на null, чтобы их вычислило заново, если понадобится
gti.pseudo_instance.SetImplementingInterfaces(null);
/**
gti.pseudo_instance.ImplementingInterfaces.Clear();
foreach (type_node t in converted_type.ImplementingInterfaces)
gti.pseudo_instance.ImplementingInterfaces.Add(generic_convertions.determine_type(t, gti.param_types, false));
/**/
}

View file

@ -316,8 +316,11 @@ namespace PascalABCCompiler.TreeRealization
return null;
}
public static void init_generic_instance(type_node original, generic_instance_type_node instance, /*SymbolTable.ClassScope instance_scope,*/ List<type_node> param_types)
public static void init_generic_instance(generic_instance_type_node instance/*, SymbolTable.ClassScope instance_scope*/)
{
var original = instance.original_generic;
var param_types = instance.instance_params;
instance.IsInterface = original.IsInterface;
instance.is_class = original.is_class;
instance.internal_is_value = original.is_value;
@ -334,12 +337,15 @@ namespace PascalABCCompiler.TreeRealization
//instance._scope = new SymbolTable.GenericTypeInstanceScope(instance, instance.original_generic.Scope, btype.Scope);
// Создаются лениво
/**
foreach (type_node interf in original.ImplementingInterfaces)
{
instance.ImplementingInterfaces.Add(
determine_type(interf, param_types, false)
);
}
/**/
SystemLibrary.SystemLibrary.init_reference_type(instance);
instance.conform_basic_functions();
@ -1577,6 +1583,7 @@ namespace PascalABCCompiler.TreeRealization
{
_original_generic = original_generic_type;
_instance_params = param_types;
SetImplementingInterfaces(null);
}
public List<SemanticTree.ITypeNode> generic_parameters
@ -1595,6 +1602,29 @@ namespace PascalABCCompiler.TreeRealization
}
}
public override List<SemanticTree.ITypeNode> ImplementingInterfaces
{
get
{
var res = base.ImplementingInterfaces;
if (res==null)
{
res = new List<SemanticTree.ITypeNode>();
foreach (type_node interf in original_generic.ImplementingInterfaces)
res.Add(generic_convertions.determine_type(interf, this.instance_params, false));
SetImplementingInterfaces(res);
}
return res;
}
}
public override List<SemanticTree.ITypeNode> ImplementingInterfacesOrEmpty
{
get
{
return base.ImplementingInterfaces ?? new List<SemanticTree.ITypeNode>();
}
}
private List<SymbolInfo> temp_names = new List<SymbolInfo>(3);
public override void add_name(string name, SymbolInfo si)

View file

@ -219,6 +219,13 @@ namespace PascalABCCompiler.TreeRealization
return null;
}
}
public virtual List<SemanticTree.ITypeNode> ImplementingInterfacesOrEmpty
{
get
{
return ImplementingInterfaces;
}
}
//true, если на данный момент имеется только предописание класса
public virtual bool ForwardDeclarationOnly
@ -2601,7 +2608,7 @@ namespace PascalABCCompiler.TreeRealization
generic_convertions.MakePseudoInstanceName(name, param_types, true),
SemanticTree.type_access_level.tal_public, null, this.loc);
_generic_instances.Add(new generic_type_instance_info(param_types, ctnode));
generic_convertions.init_generic_instance(this, ctnode, param_types);
generic_convertions.init_generic_instance(ctnode);
return ctnode;
}
@ -3175,7 +3182,7 @@ namespace PascalABCCompiler.TreeRealization
generic_convertions.MakePseudoInstanceName(name, param_types, true),
SemanticTree.type_access_level.tal_public, null, /*ct_scope,*/ this.loc);
_generic_instances.Add(new generic_type_instance_info(param_types, ctnode));
generic_convertions.init_generic_instance(this, ctnode, /*ct_scope,*/ param_types);
generic_convertions.init_generic_instance(ctnode/*, ct_scope*/);
return ctnode;
}
//\ssyy