refactoring (#3428)

This commit is contained in:
samuraiGH 2026-06-13 09:40:55 +03:00 committed by GitHub
parent 4fbea87b68
commit d940541c65
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 64 additions and 57 deletions

View file

@ -566,7 +566,7 @@ namespace PascalABCCompiler
} }
} }
private Hashtable BadNodesInSyntaxTree = new Hashtable(); private HashSet<SyntaxTree.syntax_tree_node> BadNodesInSyntaxTree = new HashSet<SyntaxTree.syntax_tree_node>();
program_node semanticTree = null; program_node semanticTree = null;
public SemanticTree.IProgramNode SemanticTree public SemanticTree.IProgramNode SemanticTree
@ -3505,7 +3505,7 @@ namespace PascalABCCompiler
currentUnit.syntax_error = errorsList[0] as SyntaxError; currentUnit.syntax_error = errorsList[0] as SyntaxError;
foreach (Error er in errorsList) foreach (Error er in errorsList)
if (er is SyntaxError && (er as SyntaxError).bad_node != null) if (er is SyntaxError && (er as SyntaxError).bad_node != null)
BadNodesInSyntaxTree[(er as SyntaxError).bad_node] = er; BadNodesInSyntaxTree.Add((er as SyntaxError).bad_node);
} }
} }

View file

@ -2,7 +2,6 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using PascalABCCompiler.SemanticTree; using PascalABCCompiler.SemanticTree;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
@ -286,9 +285,9 @@ namespace PascalABCCompiler.NetHelper
public static class NetHelper { public static class NetHelper {
private static Dictionary<string, Type> namespaces; private static Dictionary<string, Type> namespaces;
private static Hashtable types; private static Dictionary<string, object> types;
private static Dictionary<string, FoundInfo> type_search_cache; private static Dictionary<string, FoundInfo> type_search_cache;
private static Hashtable compiled_pascal_types; private static Dictionary<string, object> compiled_pascal_types;
/*private static Hashtable methods; /*private static Hashtable methods;
private static Hashtable properties; private static Hashtable properties;
private static Hashtable fields;*/ private static Hashtable fields;*/
@ -298,7 +297,7 @@ namespace PascalABCCompiler.NetHelper
private static Dictionary<Type, Dictionary<string, List<MemberInfo>>> members; private static Dictionary<Type, Dictionary<string, List<MemberInfo>>> members;
//private static Hashtable meth_nodes; //private static Hashtable meth_nodes;
private static Dictionary<PropertyInfo, compiled_property_node> prop_nodes; private static Dictionary<PropertyInfo, compiled_property_node> prop_nodes;
private static Hashtable field_nodes; private static Dictionary<MemberInfo, definition_node> field_nodes;
private static Dictionary<ConstructorInfo, compiled_constructor_node> constr_nodes; private static Dictionary<ConstructorInfo, compiled_constructor_node> constr_nodes;
private static HashSet<Type> stand_types; private static HashSet<Type> stand_types;
private static Dictionary<Assembly, Dictionary<int, Type>> type_handles; private static Dictionary<Assembly, Dictionary<int, Type>> type_handles;
@ -487,7 +486,7 @@ namespace PascalABCCompiler.NetHelper
TypeInfo ti = new TypeInfo(t, t.FullName); TypeInfo ti = new TypeInfo(t, t.FullName);
types[t.FullName] = ti; types[t.FullName] = ti;
string short_name = t.Name; string short_name = t.Name;
object o2 = types[short_name]; types.TryGetValue(short_name, out object o2);
if (o2 == null) if (o2 == null)
types[short_name] = ti; types[short_name] = ti;
@ -870,8 +869,8 @@ namespace PascalABCCompiler.NetHelper
//interfaces = new Hashtable(); //interfaces = new Hashtable();
//\ssyy- //\ssyy-
//types = new Hashtable(1024, CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default); //types = new Hashtable(1024, CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
types = new Hashtable(8096, StringComparer.CurrentCultureIgnoreCase); types = new Dictionary<string, object>(8096, StringComparer.CurrentCultureIgnoreCase);
compiled_pascal_types = new Hashtable(1024, StringComparer.CurrentCultureIgnoreCase); compiled_pascal_types = new Dictionary<string, object>(1024, StringComparer.CurrentCultureIgnoreCase);
namespaces = new Dictionary<string, Type>(1024, StringComparer.CurrentCultureIgnoreCase); namespaces = new Dictionary<string, Type>(1024, StringComparer.CurrentCultureIgnoreCase);
ass_name_cache = new Dictionary<string, Assembly>(1024, StringComparer.CurrentCultureIgnoreCase); ass_name_cache = new Dictionary<string, Assembly>(1024, StringComparer.CurrentCultureIgnoreCase);
assm_full_paths = new Dictionary<Assembly, string>(); assm_full_paths = new Dictionary<Assembly, string>();
@ -884,7 +883,7 @@ namespace PascalABCCompiler.NetHelper
assemblies = new HashSet<Assembly>(); assemblies = new HashSet<Assembly>();
//meth_nodes = new Hashtable(); //meth_nodes = new Hashtable();
prop_nodes = new Dictionary<PropertyInfo,compiled_property_node>(); prop_nodes = new Dictionary<PropertyInfo,compiled_property_node>();
field_nodes = new Hashtable(); field_nodes = new Dictionary<MemberInfo, definition_node>();
constr_nodes = new Dictionary<ConstructorInfo, compiled_constructor_node>(); constr_nodes = new Dictionary<ConstructorInfo, compiled_constructor_node>();
stand_types = new HashSet<Type>(); stand_types = new HashSet<Type>();
type_handles = new Dictionary<Assembly, Dictionary<int, Type>>(); type_handles = new Dictionary<Assembly, Dictionary<int, Type>>();
@ -1716,9 +1715,11 @@ namespace PascalABCCompiler.NetHelper
public static compiled_variable_definition GetFieldNode(FieldInfo pi) public static compiled_variable_definition GetFieldNode(FieldInfo pi)
{ {
compiled_variable_definition cpn = field_nodes[pi] as compiled_variable_definition; compiled_variable_definition cpn;
if (cpn != null) if ( field_nodes.TryGetValue(pi, out var existingNode) )
{ {
cpn = (compiled_variable_definition)existingNode;
if (cpn.type is compiled_type_node) if (cpn.type is compiled_type_node)
return cpn; return cpn;
if (PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.CompiledUnit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) if (PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.CompiledUnit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null)
@ -1840,12 +1841,13 @@ namespace PascalABCCompiler.NetHelper
} }
public static compiled_class_constant_definition GetConstantFieldNode(FieldInfo fi) public static compiled_class_constant_definition GetConstantFieldNode(FieldInfo fi)
{ {
compiled_class_constant_definition cccd = field_nodes[fi] as compiled_class_constant_definition; if ( field_nodes.TryGetValue(fi, out var existingNode) )
if (cccd != null) return cccd; return (compiled_class_constant_definition)existingNode;
constant_node cn = CreateConstantNode(fi.GetRawConstantValue()); constant_node cn = CreateConstantNode(fi.GetRawConstantValue());
if (cn == null) if (cn == null)
return null; return null;
cccd = new compiled_class_constant_definition(fi, cn); var cccd = new compiled_class_constant_definition(fi, cn);
field_nodes[fi] = cccd; field_nodes[fi] = cccd;
return cccd; return cccd;
} }
@ -1865,12 +1867,10 @@ namespace PascalABCCompiler.NetHelper
public static compiled_event GetEvent(EventInfo ei) public static compiled_event GetEvent(EventInfo ei)
{ {
compiled_event ce = field_nodes[ei] as compiled_event; if ( field_nodes.TryGetValue(ei, out var existingNode) )
if (ce != null) return (compiled_event)existingNode;
{
return ce; var ce = new compiled_event(ei);
}
ce = new compiled_event(ei);
field_nodes[ei] = ce; field_nodes[ei] = ce;
return ce; return ce;
} }
@ -1958,8 +1958,8 @@ namespace PascalABCCompiler.NetHelper
if (ti != null) if (ti != null)
return ti.type; return ti.type;
} }
TypeInfo t = (TypeInfo)types[name];
if (t != null) if (types.TryGetValue(name, out var temp) && temp is TypeInfo t)
{ {
fi = new FoundInfo(true, t); fi = new FoundInfo(true, t);
type_search_cache[name] = fi; type_search_cache[name] = fi;
@ -1981,8 +1981,7 @@ namespace PascalABCCompiler.NetHelper
public static template_class FindCompiledTemplateType(string name) public static template_class FindCompiledTemplateType(string name)
{ {
object o = compiled_pascal_types[name]; if ( compiled_pascal_types.TryGetValue(name, out object o) )
if (o != null)
{ {
template_class tc = o as template_class; template_class tc = o as template_class;
if (tc == null && PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.CompiledUnit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) if (tc == null && PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.CompiledUnit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null)
@ -2003,8 +2002,7 @@ namespace PascalABCCompiler.NetHelper
public static type_node FindCompiledPascalType(string name) public static type_node FindCompiledPascalType(string name)
{ {
object o = compiled_pascal_types[name]; if ( compiled_pascal_types.TryGetValue(name, out object o) )
if (o != null)
{ {
type_node tn = o as type_node; type_node tn = o as type_node;
if (tn == null && PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.CompiledUnit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) if (tn == null && PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.CompiledUnit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null)
@ -2062,7 +2060,7 @@ namespace PascalABCCompiler.NetHelper
if (cur_used_assemblies.Contains(ti.type.Assembly)) if (cur_used_assemblies.Contains(ti.type.Assembly))
return ti.type; return ti.type;
} }
object o = types[name]; types.TryGetValue(name, out object o);
if (o == null) if (o == null)
{ {
type_search_cache[name] = new FoundInfo(false); type_search_cache[name] = new FoundInfo(false);
@ -2151,7 +2149,7 @@ namespace PascalABCCompiler.NetHelper
} }
for (int i = 0; i < _unar.Count; i++) for (int i = 0; i < _unar.Count; i++)
{ {
o = types[_unar[i].namespace_name + "." + name]; types.TryGetValue(_unar[i].namespace_name + "." + name, out o);
if (o == null) if (o == null)
continue; continue;
if (o is TypeInfo) if (o is TypeInfo)
@ -2179,8 +2177,9 @@ namespace PascalABCCompiler.NetHelper
public static Type FindTypeOrCreate(string name) public static Type FindTypeOrCreate(string name)
{ {
TypeInfo ti = types[name] as TypeInfo; types.TryGetValue(name, out var tempTI);
if (ti != null /*&& cur_used_assemblies.ContainsKey(t.Assembly)*/) return ti.type;
if (tempTI is TypeInfo ti /*&& cur_used_assemblies.ContainsKey(t.Assembly)*/) return ti.type;
//ivan added - runtime types adding //ivan added - runtime types adding
Type t = Type.GetType(name, false, true); Type t = Type.GetType(name, false, true);
if (t == null) if (t == null)
@ -2222,8 +2221,8 @@ namespace PascalABCCompiler.NetHelper
return typs; return typs;
foreach (string s in types.Keys) foreach (string s in types.Keys)
{ {
TypeInfo ti = types[s] as TypeInfo; types.TryGetValue(name, out var tempTI);
if (ti != null) if (tempTI is TypeInfo ti)
if (string.Compare(ti.type.Namespace,name, true) == 0) if (string.Compare(ti.type.Namespace,name, true) == 0)
{ {
lst.Add(ti.type); lst.Add(ti.type);

View file

@ -2,9 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
using System.Collections;
namespace PascalABCCompiler.TreeConverter namespace PascalABCCompiler.TreeConverter
{ {
@ -104,7 +102,7 @@ namespace PascalABCCompiler.TreeConverter
public List<var_definition_node> current_var_defs; public List<var_definition_node> current_var_defs;
public Stack<code_block> block_stack; public Stack<code_block> block_stack;
public statement_node_stack cycle_stack; public statement_node_stack cycle_stack;
public Hashtable current_member_decls; public Dictionary<SyntaxTree.declaration, definition_node> current_member_decls;
public common_function_node_stack function_node_stack; public common_function_node_stack function_node_stack;
public SymbolInfo current_last_created_function; public SymbolInfo current_last_created_function;
public bool SemanticRulesThrowErrorWithoutSave; public bool SemanticRulesThrowErrorWithoutSave;
@ -122,7 +120,7 @@ namespace PascalABCCompiler.TreeConverter
cycle_stack = syntax_tree_visitor.context.CyclesStack; cycle_stack = syntax_tree_visitor.context.CyclesStack;
syntax_tree_visitor.context.CyclesStack = new statement_node_stack(); syntax_tree_visitor.context.CyclesStack = new statement_node_stack();
current_member_decls = syntax_tree_visitor.context.member_decls; current_member_decls = syntax_tree_visitor.context.member_decls;
syntax_tree_visitor.context.member_decls = new Hashtable(); syntax_tree_visitor.context.member_decls = new Dictionary<SyntaxTree.declaration, definition_node>();
function_node_stack = syntax_tree_visitor.context.func_stack; function_node_stack = syntax_tree_visitor.context.func_stack;
syntax_tree_visitor.context.func_stack = new common_function_node_stack(); syntax_tree_visitor.context.func_stack = new common_function_node_stack();
current_last_created_function = syntax_tree_visitor.context.last_created_function; current_last_created_function = syntax_tree_visitor.context.last_created_function;

View file

@ -12,7 +12,7 @@ namespace PascalABCCompiler.TreeConverter.TreeConversion
{ {
public readonly Errors.SyntaxError parserError; public readonly Errors.SyntaxError parserError;
public readonly Hashtable badNodes; public readonly HashSet<SyntaxTree.syntax_tree_node> badNodes;
public readonly TreeRealization.unit_node_list usedUnits; public readonly TreeRealization.unit_node_list usedUnits;
@ -37,7 +37,7 @@ namespace PascalABCCompiler.TreeConverter.TreeConversion
public InitializationDataForCompilingInterface( public InitializationDataForCompilingInterface(
Errors.SyntaxError parserError, Errors.SyntaxError parserError,
Hashtable badNodes, HashSet<SyntaxTree.syntax_tree_node> badNodes,
TreeRealization.unit_node_list usedUnits, TreeRealization.unit_node_list usedUnits,
TreeRealization.using_namespace_list interfaceNamespaces, TreeRealization.using_namespace_list interfaceNamespaces,
compilation_unit syntaxUnit, compilation_unit syntaxUnit,
@ -78,7 +78,7 @@ namespace PascalABCCompiler.TreeConverter.TreeConversion
public InitializationDataForCompilingImplementation( public InitializationDataForCompilingImplementation(
Errors.SyntaxError parserError, Errors.SyntaxError parserError,
Hashtable badNodes, HashSet<SyntaxTree.syntax_tree_node> badNodes,
TreeRealization.unit_node_list usedUnits, TreeRealization.unit_node_list usedUnits,
TreeRealization.using_namespace_list interfaceNamespaces, TreeRealization.using_namespace_list interfaceNamespaces,
TreeRealization.using_namespace_list implementationNamespaces, TreeRealization.using_namespace_list implementationNamespaces,

View file

@ -4,7 +4,6 @@
using PascalABCCompiler.CoreUtils; using PascalABCCompiler.CoreUtils;
using PascalABCCompiler.TreeRealization; using PascalABCCompiler.TreeRealization;
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -36,7 +35,7 @@ namespace PascalABCCompiler.TreeConverter
public statement_node_stack cycles_stack; public statement_node_stack cycles_stack;
public int num_of_for_cycles; public int num_of_for_cycles;
public SemanticTree.field_access_level _fal; public SemanticTree.field_access_level _fal;
public System.Collections.Hashtable member_decls; public Dictionary<SyntaxTree.declaration, definition_node> member_decls;
public List<common_type_node> types_predefined; public List<common_type_node> types_predefined;
public Stack<common_type_node> type_stack; // Для вложенных типов public Stack<common_type_node> type_stack; // Для вложенных типов
public statement_list_stack stlist_stack; public statement_list_stack stlist_stack;
@ -127,7 +126,7 @@ namespace PascalABCCompiler.TreeConverter
_cycles_stack = new statement_node_stack(); _cycles_stack = new statement_node_stack();
_num_of_for_cycles = 0; _num_of_for_cycles = 0;
_fal = SemanticTree.field_access_level.fal_private; _fal = SemanticTree.field_access_level.fal_private;
member_decls = new Hashtable(); member_decls = new Dictionary<SyntaxTree.declaration, definition_node>();
_types_predefined = new List<common_type_node>(); _types_predefined = new List<common_type_node>();
syntax_tree_visitor.ret.return_value(null); syntax_tree_visitor.ret.return_value(null);
// _type_stack = new Stack<common_type_node>(); // _type_stack = new Stack<common_type_node>();
@ -250,7 +249,7 @@ namespace PascalABCCompiler.TreeConverter
private static compilation_context _instance; private static compilation_context _instance;
private Dictionary<common_namespace_node, Dictionary<string, template_class>> compiled_tc_cache = new Dictionary<common_namespace_node, Dictionary<string, template_class>>(); private Dictionary<common_namespace_node, Dictionary<string, template_class>> compiled_tc_cache = new Dictionary<common_namespace_node, Dictionary<string, template_class>>();
internal System.Collections.Hashtable member_decls = new System.Collections.Hashtable(); internal Dictionary<SyntaxTree.declaration, definition_node> member_decls = new Dictionary<SyntaxTree.declaration, definition_node>();
internal bool namespace_converted = false; internal bool namespace_converted = false;
public compilation_context(convertion_data_and_alghoritms convertion_data_and_alghoritms, syntax_tree_visitor syntax_tree_visitor) public compilation_context(convertion_data_and_alghoritms convertion_data_and_alghoritms, syntax_tree_visitor syntax_tree_visitor)
@ -430,12 +429,16 @@ namespace PascalABCCompiler.TreeConverter
public common_function_node get_method_to_realize(SyntaxTree.declaration dc) public common_function_node get_method_to_realize(SyntaxTree.declaration dc)
{ {
return member_decls[dc] as common_function_node; member_decls.TryGetValue(dc, out var result);
return result as common_function_node;
} }
public common_type_node get_type_to_realize(SyntaxTree.declaration dc) public common_type_node get_type_to_realize(SyntaxTree.declaration dc)
{ {
return member_decls[dc] as common_type_node; member_decls.TryGetValue(dc, out var result);
return result as common_type_node;
} }
public void add_method_header(SyntaxTree.declaration dc, definition_node dn) public void add_method_header(SyntaxTree.declaration dc, definition_node dn)

View file

@ -126,7 +126,7 @@ namespace PascalABCCompiler.TreeConverter
_parser_error = value; _parser_error = value;
} }
} }
public System.Collections.Hashtable bad_nodes_in_syntax_tree; public HashSet<SyntaxTree.syntax_tree_node> bad_nodes_in_syntax_tree;
public SymbolTable.TreeConverterSymbolTable symbol_table public SymbolTable.TreeConverterSymbolTable symbol_table
{ {
@ -3330,7 +3330,7 @@ namespace PascalABCCompiler.TreeConverter
{ {
return; return;
} }
if (bad_nodes_in_syntax_tree[tn]!=null) if ( bad_nodes_in_syntax_tree.Contains(tn) )
{ {
AddError(new ParserError(_parser_error,_stv.get_location(tn))); AddError(new ParserError(_parser_error,_stv.get_location(tn)));
} }

View file

@ -717,7 +717,7 @@ namespace PascalABCCompiler.TreeConverter
convertion_data_and_alghoritms.parser_error = value; convertion_data_and_alghoritms.parser_error = value;
} }
} }
public System.Collections.Hashtable BadNodesInSyntaxTree public HashSet<SyntaxTree.syntax_tree_node> BadNodesInSyntaxTree
{ {
get get
{ {
@ -19741,8 +19741,8 @@ namespace PascalABCCompiler.TreeConverter
SemanticTree.field_access_level curr_fal = context.get_field_access_level(); SemanticTree.field_access_level curr_fal = context.get_field_access_level();
List<var_definition_node> current_var_defs = context.var_defs; List<var_definition_node> current_var_defs = context.var_defs;
context.var_defs = new List<var_definition_node>(); context.var_defs = new List<var_definition_node>();
Hashtable current_member_decls = context.member_decls; Dictionary<SyntaxTree.declaration, definition_node> current_member_decls = context.member_decls;
context.member_decls = new Hashtable(); context.member_decls = new Dictionary<declaration, definition_node>();
//подменяем using-список //подменяем using-список
using_namespace_list current_using_list = new using_namespace_list(); using_namespace_list current_using_list = new using_namespace_list();
foreach (using_namespace un in using_list) foreach (using_namespace un in using_list)

View file

@ -232,14 +232,18 @@ namespace PascalABCCompiler.TreeRealization
public static List<SemanticTree.IGenericFunctionInstance> all_function_instances = public static List<SemanticTree.IGenericFunctionInstance> all_function_instances =
new List<SemanticTree.IGenericFunctionInstance>(); new List<SemanticTree.IGenericFunctionInstance>();
public static Hashtable generic_instances = new Hashtable(); public static Dictionary<definition_node, object> generic_instances =
new Dictionary<definition_node, object>();
public static syntax_tree_visitor visitor; public static syntax_tree_visitor visitor;
public static List<generic_type_instance_info> get_type_instances(type_node original_generic_type) public static List<generic_type_instance_info> get_type_instances(type_node original_generic_type)
{ {
List<generic_type_instance_info> instances = generic_instances[original_generic_type] as List<generic_type_instance_info>; List<generic_type_instance_info> instances;
if (instances == null)
if ( generic_instances.TryGetValue(original_generic_type, out var temp) )
instances = (List<generic_type_instance_info>)temp;
else
{ {
instances = new List<generic_type_instance_info>(); instances = new List<generic_type_instance_info>();
generic_instances.Add(original_generic_type, instances); generic_instances.Add(original_generic_type, instances);
@ -249,14 +253,17 @@ namespace PascalABCCompiler.TreeRealization
public static void remove_type_instances(type_node original_generic_type) public static void remove_type_instances(type_node original_generic_type)
{ {
if (generic_instances[original_generic_type] != null) if (generic_instances.ContainsKey(original_generic_type))
generic_instances.Remove(original_generic_type); generic_instances.Remove(original_generic_type);
} }
public static List<generic_function_instance_info> get_function_instances(function_node original_generic_function) public static List<generic_function_instance_info> get_function_instances(function_node original_generic_function)
{ {
List<generic_function_instance_info> instances = generic_instances[original_generic_function] as List<generic_function_instance_info>; List<generic_function_instance_info> instances;
if (instances == null)
if ( generic_instances.TryGetValue(original_generic_function, out var temp) )
instances = (List<generic_function_instance_info>)temp;
else
{ {
instances = new List<generic_function_instance_info>(); instances = new List<generic_function_instance_info>();
generic_instances.Add(original_generic_function, instances); generic_instances.Add(original_generic_function, instances);