// 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; using PascalABCCompiler.SemanticTree; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Threading; using PascalABCCompiler.TreeConverter; using PascalABCCompiler.TreeRealization; namespace PascalABCCompiler.NetHelper { class TypeInfo { public Type type; public string FullName; public TypeInfo(Type type, string FullName) { this.type = type; this.FullName = FullName; } } class TypeNamespaceInfo { public TypeInfo type_info; public using_namespace us_ns; public TypeNamespaceInfo(TypeInfo type_info, using_namespace us_ns) { this.type_info = type_info; this.us_ns = us_ns; } } class FoundInfo { public bool exists; public List type_infos; public FoundInfo(bool exists, TypeInfo TypeInfo=null, using_namespace un=null) { this.exists = exists; if (exists) { type_infos = new List(); type_infos.Add(new TypeNamespaceInfo(TypeInfo,un)); } } public TypeInfo GetTypeByNamespaceList(using_namespace_list unl) { foreach (TypeNamespaceInfo tni in type_infos) { foreach (using_namespace un in unl) { if (string.Compare(un.namespace_name, tni.us_ns.namespace_name, true) == 0) { return tni.type_info; } } } return null; } } public class NetScope : SymbolTable.DotNETScope { //private base_scope _up_scope; private PascalABCCompiler.TreeRealization.using_namespace_list _unar; internal System.Reflection.Assembly _assembly; private SymbolTable.TreeConverterSymbolTable _tcst; internal Type entry_type = null; private List UnitTypes = null; public NetScope(PascalABCCompiler.TreeRealization.using_namespace_list unar, SymbolTable.TreeConverterSymbolTable tcst) : base(tcst) { _unar = unar; _tcst = tcst; } public NetScope(PascalABCCompiler.TreeRealization.using_namespace_list unar,System.Reflection.Assembly assembly, SymbolTable.TreeConverterSymbolTable tcst) : base(tcst) { _unar=unar; _assembly=assembly; UnitTypes = NetHelper.init_namespaces(assembly); if (UnitTypes.Count > 0) { entry_type = GetEntryType(); } _tcst=tcst; } private Type GetEntryType() { if (_unar.Count > 0) { for (int i = 0; i < UnitTypes.Count; i++) { if (string.Compare(UnitTypes[i].Name, _unar[0].namespace_name, true) == 0) return UnitTypes[i]; } return UnitTypes[0]; } else { return UnitTypes[0]; } } public Assembly Assembly { get { return _assembly; } } public PascalABCCompiler.TreeRealization.using_namespace_list used_namespaces { get { return _unar; } set { _unar = value; } } /*public override base_scope top_scope { get { return _up_scope; } }*/ public override List Find(string name, SymbolTable.Scope CurrentScope) { List sil = null; string full_ns = null; if (NetHelper.IsNetNamespace(name, _unar, out full_ns) == true) { compiled_namespace_node cnn = compiled_namespace_node.get_compiled_namespace(full_ns, _tcst);//new compiled_namespace_node(full_ns, _tcst); sil = new List { new SymbolInfo(cnn) }; } else { //Type t = Type.GetType("System."+name,false,true); Type t = null; t = NetHelper.FindType(name, _unar); if (t != null) { compiled_type_node ctn = compiled_type_node.get_type_node(t, _tcst); sil = new List { new SymbolInfo(ctn) }; } else { if (entry_type != null) { type_node pas_tn = NetHelper.FindCompiledPascalType(entry_type.Namespace + "." + name); if (pas_tn != null) { sil = new List { new SymbolInfo(pas_tn) }; return sil; } else { template_class tc = NetHelper.FindCompiledTemplateType(entry_type.Namespace + "." + name); if (tc != null) { sil = new List { new SymbolInfo(tc) }; return sil; } } } if (SemanticRules.AllowGlobalVisibilityForPABCDll && entry_type != null) { t = NetHelper.FindType(entry_type.Namespace + "." + name); if (t != null) sil = new List { new SymbolInfo(compiled_type_node.get_type_node(t)) }; else { object[] attrs = entry_type.GetCustomAttributes(false); for (int j = 0; j < attrs.Length; j++) if (attrs[j].GetType().Name == PascalABCCompiler.TreeConverter.compiler_string_consts.global_attr_name) { sil = NetHelper.FindName(entry_type, name); if (sil != null) break; } } if (sil == null && UnitTypes.Count > 1) { for (int j = 0; j < _unar.Count; j++) { t = in_type_list(_unar[j].namespace_name); if (t != null) { sil = NetHelper.FindName(t, name); if (sil != null) break; } } } } } } return sil; } private Type in_type_list(string name) { for (int i = 1; i < UnitTypes.Count; i++) { if (string.Compare(UnitTypes[i].Name, name, true) == 0) return UnitTypes[i]; } return null; } public override string ToString() { return Assembly.ToString(); } } public class NetTypeScope : SymbolTable.DotNETScope { //private base_scope _up_scope; private Type type_info; public NetTypeScope(Type type_info,SymbolTable.DSSymbolTable tcst) : base(tcst) { this.type_info = type_info; } /*public override base_scope top_scope { get { return _up_scope; } }*/ public Type TypeInfo { get { return type_info; } set { type_info = value; } } public override List Find(string name, SymbolTable.Scope CurrentScope) { return NetHelper.FindName(type_info, name); } } public static class NetHelper { private static Hashtable namespaces; private static Hashtable types; private static Dictionary type_search_cache; private static Hashtable compiled_pascal_types; /*private static Hashtable methods; private static Hashtable properties; private static Hashtable fields;*/ //ssyy- //private static Hashtable interfaces; //\ssyy- private static Dictionary>> members; //private static Hashtable meth_nodes; private static Dictionary prop_nodes; private static Hashtable field_nodes; private static Hashtable constr_nodes; private static Hashtable stand_types; private static Hashtable type_handles; private static Hashtable method_handles; private static Hashtable constr_handles; private static Hashtable field_handles; private static Hashtable assemblies; private static Hashtable special_types; private static Hashtable ns_types; private static Type memberInfo; private static Hashtable namespace_assemblies; public static Hashtable cur_used_assemblies; private static Hashtable cached_type_extensions; public static Type DelegateType; public static Type EnumType; public static Type ArrayType; public static Type void_type; public static Type MulticastDelegateType; public static Type ExtensionAttributeType; public static MethodInfo AddToDictionaryMethod; public static bool UsePABCRtl; public static Assembly SystemCoreAssembly; private static Dictionary extension_methods = new Dictionary(); private static Dictionary> type_extensions = new Dictionary>(); private static Dictionary arrays_with_extension_methods = new Dictionary(); private static Dictionary generics_with_extension_methods = new Dictionary(); private static Dictionary> generic_array_type_extensions = new Dictionary>(); private static List generic_parameter_type_extensions = new List(); public static Type PABCSystemType = null; public static Type PT4Type = null; public static Type StringType = typeof(string); public static Dictionary> generics_names = new Dictionary>(); private static Dictionary member_cache = new Dictionary(); public static void reset() { if (cur_used_assemblies == null) cur_used_assemblies = new Hashtable(); cur_used_assemblies.Clear(); cur_used_assemblies[typeof(string).Assembly] = typeof(string).Assembly; cur_used_assemblies[typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly] = typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly; type_search_cache.Clear(); } private static Hashtable ass_name_cache; private static Hashtable file_dates; public static bool IsAssemblyChanged(string name) { if (name == null) return false; Assembly a = ass_name_cache[name] as Assembly; if (a != null) { if (System.IO.File.GetLastWriteTime(name) != (DateTime)file_dates[a]) return true; return false; } else return false; } public static Assembly LoadAssembly(string name) { if (name == null) return null; Assembly a = ass_name_cache[name] as Assembly; if (a == null && name.IndexOf(System.IO.Path.DirectorySeparatorChar) == -1) a = ass_name_cache[System.IO.Path.Combine(System.IO.Directory.GetCurrentDirectory(), name)] as Assembly; if (a != null) { if (System.IO.File.GetLastWriteTime(name) == (DateTime)file_dates[a]) return a; namespace_assemblies.Remove(a); assemblies.Remove(a); cur_used_assemblies.Remove(a); ns_types.Clear(); Type[] tarr = a.GetTypes(); foreach(Type t in tarr) { if (t.Namespace != "" && t.Namespace != null) { string s = t.Namespace; int pos = s.LastIndexOf('.'); namespaces.Remove(s); while (pos != -1) { s = s.Substring(0,pos); pos = s.LastIndexOf('.'); //if (pos == -1) namespaces.Remove(s); } } if (t.Name.StartsWith("%")) { types.Remove(t.Namespace+"."+t.Name.Substring(1)); } else types.Remove(t.FullName); if (t == ExtensionAttributeType) { ExtensionAttributeType = null; extension_methods.Clear(); } if (type_extensions.ContainsKey(t)) type_extensions.Remove(t); } } //if (!System.IO.Path.GetFileName(name).ToLower().Contains("microsoft.directx")) try { System.IO.FileStream fs = System.IO.File.OpenRead(name); byte[] buf = new byte[fs.Length]; fs.Read(buf, 0, (int)fs.Length); fs.Close(); curr_inited_assm_path = name; a = System.Reflection.Assembly.Load(buf); a.GetTypes(); buf = null; //Thread th = new Thread(new ThreadStart(collect_internal)); //th.Start(); } catch (Exception ex) { a = System.Reflection.Assembly.LoadFrom(name); } ass_name_cache[name] = a; file_dates[a] = System.IO.File.GetLastWriteTime(name); return a; } private static void collect_internal() { } public static Hashtable entry_types = new Hashtable(); private static string curr_inited_assm_path = null; public static List init_namespaces(System.Reflection.Assembly _assembly) { Assembly assembly = (Assembly)assemblies[_assembly]; List nss = new List(); cur_used_assemblies[_assembly] = _assembly; Type entry_type = null; List unit_types = entry_types[_assembly] as List; if (unit_types == null) unit_types = new List(); if (assembly == null) { Type[] tarr = _assembly.GetTypes(); //Hashtable ns_ht = new Hashtable(CaseInsensitiveHashCodeProvider.Default,CaseInsensitiveComparer.Default); Hashtable ns_ht = new Hashtable(StringComparer.CurrentCultureIgnoreCase); foreach (Type t in tarr) { if (t.IsNotPublic) continue; if (t.Namespace != "" && t.Namespace != null && t.FullName.IndexOf('$') == -1) { string s = t.Namespace; int pos = s.LastIndexOf('.'); //if (pos == -1) //if (namespaces[s] == null) ns_ht.Add(s,s); ns_ht[s] = s; namespaces[s] = t; // SSM 17.05.19 Пробую запретить uses Reflection: https://github.com/pascalabcnet/pascalabcnet/issues/1941 /*if (pos != -1) { string[] sub_ns_arr = s.Split('.'); string sub_ns_str = sub_ns_arr[sub_ns_arr.Length - 1]; namespaces[sub_ns_str] = t; ns_ht[sub_ns_str] = s; int ind = sub_ns_arr.Length - 2; while (ind != 0) { sub_ns_str = sub_ns_arr[ind] + "." + sub_ns_str; ind--; } }*/ while (pos != -1) { s = s.Substring(0, pos); pos = s.LastIndexOf('.'); //if (pos == -1) if (namespaces[s] == null) namespaces[s] = t; ns_ht[s] = s; } } TypeInfo ti = new TypeInfo(t, t.FullName); types[t.FullName] = ti; string short_name = t.Name; object o2 = types[short_name]; if (o2 == null) types[short_name] = ti; else { if (o2 is TypeInfo) { List type_lst = new List(); type_lst.Add(o2 as TypeInfo); type_lst.Add(ti); types[short_name] = type_lst; } else if (o2 is List) { (o2 as List).Add(ti); } } AddGenericInfo(t); if (ExtensionAttributeType != null && t.GetCustomAttributes(ExtensionAttributeType, false).Length > 0) { MethodInfo[] meths = t.GetMethods(BindingFlags.Public | BindingFlags.Static); List ext_meths = new List(); if (!extension_methods.ContainsKey(t)) { foreach (MethodInfo mi in meths) if (mi.GetCustomAttributes(ExtensionAttributeType, false).Length > 0) { ext_meths.Add(mi); ParameterInfo[] prms = mi.GetParameters(); if (prms.Length > 0) { List mths = null; List mths2 = null; Type tmp = prms[0].ParameterType; if (tmp.IsGenericType) { tmp = tmp.GetGenericTypeDefinition(); } if (!type_extensions.TryGetValue(tmp, out mths)) { mths = new List(); type_extensions.Add(tmp, mths); } if ((tmp.BaseType == DelegateType || tmp.BaseType == MulticastDelegateType)) { List mths3 = null; if (!type_extensions.TryGetValue(DelegateType, out mths3)) { mths3 = new List(); type_extensions.Add(DelegateType, mths3); } mths3.Add(mi); } mths.Add(mi); if (tmp.IsArray && !generic_array_type_extensions.TryGetValue(tmp.GetArrayRank(), out mths2)) { mths2 = new List(); generic_array_type_extensions.Add(tmp.GetArrayRank(), mths2); } if (mths2 != null) mths2.Add(mi); Dictionary> mht; if (members.TryGetValue(tmp, out mht)) { List mis2 = null; string name = compiler_string_consts.GetNETOperName(mi.Name); if (name == null) name = mi.Name; if (!mht.TryGetValue(name, out mis2)) { mis2 = new List(); mht.Add(name, mis2); } if (!mis2.Contains(mi)) mis2.Add(mi); } if (tmp.IsGenericParameter && !generic_parameter_type_extensions.Contains(mi)) { generic_parameter_type_extensions.Add(mi); foreach (Type tt in members.Keys) { if (members.TryGetValue(tt, out mht)) { List mis2 = null; string name = compiler_string_consts.GetNETOperName(mi.Name); if (name == null) name = mi.Name; if (!mht.TryGetValue(name, out mis2)) { mis2 = new List(); mht.Add(name, mis2); } if (!mis2.Contains(mi)) mis2.Add(mi); } } } foreach (Type arr_t in arrays_with_extension_methods.Keys) { if (members.TryGetValue(arr_t, out mht)) { List mis2 = null; string name = compiler_string_consts.GetNETOperName(mi.Name); if (name == null) name = mi.Name; if (!mht.TryGetValue(name, out mis2)) { mis2 = new List(); mht.Add(name, mis2); } if (!mis2.Contains(mi)) mis2.Add(mi); } } foreach (Type gen_t in generics_with_extension_methods.Keys) { if (members.TryGetValue(gen_t, out mht)) { List mis2 = null; string name = compiler_string_consts.GetNETOperName(mi.Name); if (name == null) name = mi.Name; if (!mht.TryGetValue(name, out mis2)) { mis2 = new List(); mht.Add(name, mis2); } if (!mis2.Contains(mi)) mis2.Add(mi); } } } } extension_methods.Add(t, ext_meths.ToArray()); } } if (t.Name == t.Namespace) { object[] attrs = t.GetCustomAttributes(false); foreach (Attribute attr in attrs) { if (attr.GetType().Name == PascalABCCompiler.TreeConverter.compiler_string_consts.global_attr_name) { entry_type = t; unit_types.Insert(0, t); entry_types[_assembly] = unit_types; break; } else if (attr.GetType().Name == PascalABCCompiler.TreeConverter.compiler_string_consts.class_unit_attr_name) { if (_assembly.ManifestModule.ScopeName == compiler_string_consts.pabc_rtl_dll_name) { if (t.Name == "PABCSystem") PABCSystemType = t; else if (t.Name == "PT4") PT4Type = t; } unit_types.Add(t); break; } } } else if (t.Name.StartsWith("%")) { object[] attrs = t.GetCustomAttributes(false); if (attrs.Length == 1) { Type attr_t = attrs[0].GetType(); if (attr_t.FullName == compiler_string_consts.file_of_attr_name) { object o = attr_t.GetField("Type", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); if (o is Type) attr_t = o as Type; else attr_t = _assembly.GetType(o as string, false); if (PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.compiled_unit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) { type_node tn = CreatePascalType(attr_t); if (tn != null) tn = PascalABCCompiler.TreeConverter.compilation_context.instance.create_typed_file_type(tn, null); else tn = PascalABCCompiler.TreeConverter.compilation_context.instance.create_typed_file_type(compiled_type_node.get_type_node(attr_t), null); compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = tn; } else { compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = t; } } else if (attr_t.FullName == compiler_string_consts.set_of_attr_name) { object o = attr_t.GetField("Type", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); if (o is Type) attr_t = o as Type; else { attr_t = t.Assembly.GetType(o as string, false); } if (PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.compiled_unit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) { type_node tn = CreatePascalType(attr_t); if (tn != null) tn = PascalABCCompiler.TreeConverter.compilation_context.instance.create_set_type(tn, null); else tn = PascalABCCompiler.TreeConverter.compilation_context.instance.create_set_type(compiled_type_node.get_type_node(attr_t), null); compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = tn; } else { compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = t; } } else if (attr_t.FullName == compiler_string_consts.short_string_attr_name) { int len = (int)attr_t.GetField("Length", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); if (PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.compiled_unit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) { type_node tn = PascalABCCompiler.TreeConverter.compilation_context.instance.create_short_string_type(len, null); compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = tn; } else { compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = t; } } else if (attr_t.FullName == compiler_string_consts.template_class_attr_name) { compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = t; } else if (attr_t.FullName == compiler_string_consts.type_synonim_attr_name) { object o = attr_t.GetField("Type", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); if (o is Type) attr_t = o as Type; else attr_t = _assembly.GetType(o as string, false); if (attr_t != null) { type_node tn = CreatePascalType(attr_t); if (tn != null) compiled_pascal_types[t.Namespace + "." + t.Name.Substring(1)] = tn; else types[t.Namespace + "." + t.Name.Substring(1)] = new TypeInfo(attr_t, attr_t.FullName); } } } } } namespace_assemblies[_assembly] = ns_ht; assemblies[_assembly] = _assembly; } return unit_types; } private static template_class CreateTemplateClassType(Type t) { if (t == null) return null; object[] attrs = t.GetCustomAttributes(false); if (attrs.Length == 1) { Type attr_t = attrs[0].GetType(); byte[] tree = (byte[])attr_t.GetField("Tree", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); return PascalABCCompiler.TreeConverter.compilation_context.instance.create_template_class(t.FullName, tree); } return null; } private static type_node CreatePascalType(Type t) { if (t == null) return null; object[] attrs = t.GetCustomAttributes(false); bool not_pascal_type = false; if (attrs.Length == 1) { Type attr_t = attrs[0].GetType(); if (attr_t.FullName == compiler_string_consts.file_of_attr_name) { object o = attr_t.GetField("Type", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); if (o is Type) attr_t = o as Type; else { attr_t = t.Assembly.GetType(o as string, false); if (attr_t != null) { type_node tn = CreatePascalType(attr_t); if (tn != null) return PascalABCCompiler.TreeConverter.compilation_context.instance.create_typed_file_type(tn, null); } } return PascalABCCompiler.TreeConverter.compilation_context.instance.create_typed_file_type(compiled_type_node.get_type_node(attr_t), null); } else if (attr_t.FullName == compiler_string_consts.set_of_attr_name) { object o = attr_t.GetField("Type", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); if (o is Type) attr_t = o as Type; else { attr_t = t.Assembly.GetType(o as string, false); if (attr_t != null) { type_node tn = CreatePascalType(attr_t); if (tn != null) return PascalABCCompiler.TreeConverter.compilation_context.instance.create_set_type(tn, null); } } return PascalABCCompiler.TreeConverter.compilation_context.instance.create_set_type(compiled_type_node.get_type_node(attr_t), null); } else if (attr_t.FullName == compiler_string_consts.short_string_attr_name) { int len = (int)attr_t.GetField("Length", BindingFlags.Public | BindingFlags.Instance).GetValue(attrs[0]); return PascalABCCompiler.TreeConverter.compilation_context.instance.create_short_string_type(len, null); } else if (attr_t.FullName == compiler_string_consts.template_class_attr_name) { return null; } else not_pascal_type = true; } else not_pascal_type = true; if (not_pascal_type) { if (t.IsPointer) { if (t.GetElementType() == void_type) return SystemLibrary.SystemLibrary.pointer_type; else { type_node elem_t = CreatePascalType(t.GetElementType()); return elem_t.ref_type; } } else return compiled_type_node.get_type_node(t, SystemLibrary.SystemLibrary.syn_visitor.SymbolTable); } return null; } public static bool IsEntryType(Type t) { object[] attrs = t.GetCustomAttributes(false); for (int j=0; j>>(128); //fields = new Hashtable(); assemblies = new Hashtable(); //meth_nodes = new Hashtable(); prop_nodes = new Dictionary(); field_nodes = new Hashtable(); constr_nodes = new Hashtable(); stand_types = new Hashtable(); type_handles = new Hashtable(); method_handles = new Hashtable(); constr_handles = new Hashtable(); field_handles = new Hashtable(); special_types = new Hashtable(); type_search_cache = new Dictionary(300); cached_type_extensions = new Hashtable(); namespace_assemblies = new Hashtable(); cur_used_assemblies = new Hashtable(); //ns_types = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default); ns_types = new Hashtable(StringComparer.CurrentCultureIgnoreCase); memberInfo = typeof(MemberInfo); stand_types[typeof(int)] = stand_types; stand_types[typeof(byte)] = stand_types; stand_types[typeof(bool)] = stand_types; stand_types[typeof(sbyte)] = stand_types; stand_types[typeof(short)] = stand_types; stand_types[typeof(ushort)] = stand_types; stand_types[typeof(uint)] = stand_types; stand_types[typeof(long)] = stand_types; stand_types[typeof(ulong)] = stand_types; stand_types[typeof(char)] = stand_types; stand_types[typeof(float)] = stand_types; stand_types[typeof(double)] = stand_types; //stand_types[typeof(decimal)]=stand_types; //stand_types[NetHelper.void_ptr_type] = stand_types; DelegateType = typeof(Delegate); MulticastDelegateType = typeof(MulticastDelegate); void_type = typeof(void); AddSpecialType(void_ptr_type); AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve); ExtensionAttributeType = typeof(System.Runtime.CompilerServices.ExtensionAttribute); SystemCoreAssembly = ExtensionAttributeType.Assembly; EnumType = typeof(Enum); ArrayType = typeof(Array); AddToDictionaryMethod = typeof(Dictionary).GetMethod("Add"); } private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { try { if (curr_inited_assm_path != null) { Assembly assm = null; string path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(curr_inited_assm_path), args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"); if (System.IO.File.Exists(path)) assm = LoadAssembly(path); curr_inited_assm_path = null; //return LoadAssembly(args.Name); return assm; } return null; } catch { return null; } } private static void AddSpecialType(Type t) { special_types[t.MetadataToken] = t; } public static bool IsStandType(Type t) { if (stand_types[t] != null) return true; return false; } public static bool IsNetNamespace(string name, Type tt = null) { Type t = null; if (tt != null) t = tt; else t = namespaces[name] as Type; if (t != null && cur_used_assemblies.ContainsKey(t.Assembly)) return true; foreach (Assembly a in namespace_assemblies.Keys) if (cur_used_assemblies != null && cur_used_assemblies.ContainsKey(a) && (namespace_assemblies[a] as Hashtable).ContainsKey(name)) return true; return false; } public static bool IsNetNamespace(string name,PascalABCCompiler.TreeRealization.using_namespace_list _unar, out string full_ns) { Type t = namespaces[name] as Type; full_ns = name; if (t != null) { if (PABCSystemType != null && t.Assembly == PABCSystemType.Assembly && !UsePABCRtl) return false; Type tt = t; if (string.Compare(t.Namespace, name, true) == 0) { full_ns = t.Namespace; return true; } for (int i = 0; i < _unar.Count; i++) { string full_name = _unar[i].namespace_name + "." + name; if (string.Compare(full_name, t.Namespace, true) == 0) { full_ns = full_name; return IsNetNamespace(name, t); } } for (int i = 0; i < _unar.Count; i++) { string full_name = _unar[i].namespace_name + "." + name; t = namespaces[full_name] as Type; if (t != null) { full_ns = full_name; return IsNetNamespace(full_ns, t); } } if (tt.Namespace.IndexOf(name, 0, StringComparison.OrdinalIgnoreCase) == 0) { return true; } } return false; } public static Type void_ptr_type { get { if(SemanticRules.PoinerRealization == PoinerRealization.IntPtr) return FindTypeOrCreate(compiler_string_consts.pointer_net_type_name_intptr); return FindTypeOrCreate(compiler_string_consts.pointer_net_type_name_void); } } public static IEnumerable GetExtensionMethods(Type t) { List meths = null; if (SystemCoreAssembly == null || !cur_used_assemblies.ContainsKey(SystemCoreAssembly)) return new List(); if (type_extensions.TryGetValue(t, out meths) || t.IsGenericType && type_extensions.TryGetValue(t.GetGenericTypeDefinition(), out meths)) { //return meths.ToArray(); } else { meths = new List(); } //meths = new List(); Type[] tt = t.GetInterfaces(); for (int i = 0; i < tt.Length; i++) { meths.AddRange((MethodInfo[])GetExtensionMethodsNoRecursive(tt[i])); } if (t.BaseType != null) meths.AddRange((MethodInfo[])GetExtensionMethods(t.BaseType)); return meths.ToArray(); } private static IEnumerable GetExtensionMethodsNoRecursive(Type t) { List meths = null; if (type_extensions.TryGetValue(t, out meths) || t.IsGenericType && type_extensions.TryGetValue(t.GetGenericTypeDefinition(), out meths)) { return meths.ToArray(); } return new List().ToArray(); } private static function_node get_conversion(compiled_type_node in_type,compiled_type_node from, compiled_type_node to,string op_name, NetTypeScope scope) { //MethodInfo[] mia = in_type.compiled_type.GetMethods(); List mia = GetMembers(in_type.compiled_type, op_name); foreach (MemberInfo mbi in mia) { if (!(mbi is MethodInfo)) continue; MethodInfo mi = mbi as MethodInfo; if (mi.ReturnType != to.compiled_type) { continue; } ParameterInfo[] piarr = mi.GetParameters(); if (piarr.Length != 1) { continue; } if (piarr[0].ParameterType != from.compiled_type) { continue; } return compiled_function_node.get_compiled_method(mi); } if (scope != null) { List sil = scope.FindOnlyInType(op_name, scope); if(sil != null) foreach(SymbolInfo si in sil) { if (si.sym_info is common_namespace_function_node) { function_node fn = si.sym_info as function_node; if ((fn.return_value_type == to || fn.return_value_type.original_generic == to) && fn.parameters.Count == 1 && (fn.parameters[0].type == from || fn.parameters[0].type.original_generic == from)) { return fn; } } } } return null; } public static function_node get_implicit_conversion(compiled_type_node in_type, compiled_type_node from, compiled_type_node to, NetTypeScope scope) { return get_conversion(in_type, from, to, compiler_string_consts.implicit_operator_name, scope); } public static function_node get_explicit_conversion(compiled_type_node in_type, compiled_type_node from, compiled_type_node to, NetTypeScope scope) { return get_conversion(in_type, from, to, compiler_string_consts.explicit_operator_name, scope); } public static compiled_type_node get_array_type(compiled_type_node element_type) { return (compiled_type_node.get_type_node(element_type.compiled_type.MakeArrayType())); } public static compiled_type_node get_array_type(compiled_type_node element_type, int rank) { if (rank == 1) return (compiled_type_node.get_type_node(element_type.compiled_type.MakeArrayType())); else return (compiled_type_node.get_type_node(element_type.compiled_type.MakeArrayType(rank))); } public static string[] GetNamespaces(Assembly a) { Hashtable ht = (Hashtable)namespace_assemblies[a]; List lst = new List(); foreach (string s in ht.Values) //if (s.IndexOf('.') == -1) lst.Add(s); return lst.ToArray(); } public static void FormBaseInterfacesList(Type t, List interfaces) { if (interfaces.IndexOf(t) < 0) { interfaces.Add(t); Type[] inters = t.GetInterfaces(); int count = inters.Length; for (int i = inters.Length - 1; i > -1; --i) { FormBaseInterfacesList(inters[i], interfaces); } } } public static bool IsExtensionMethod(MethodInfo mi) { if (ExtensionAttributeType != null && mi.GetCustomAttributes(ExtensionAttributeType, false).Length > 0) return true; return false; } public static List GetMembers(Type t, string name) { Dictionary> mht = null; if (members.TryGetValue(t, out mht)) { List mis2 = null; if (!mht.TryGetValue(name, out mis2)) { return EmptyMemberInfoList; } return mis2; } else { BindingFlags bf = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic; MemberInfo[] mis; if (t.IsInterface) { List all_interfaces = new List(); FormBaseInterfacesList(t, all_interfaces); List mem_info = new List(); foreach (Type interf in all_interfaces) { mem_info.AddRange(interf.GetMembers(bf)); } mem_info.AddRange(typeof(object).GetMembers(bf)); mis = mem_info.ToArray(); } else { mis = t.GetMembers(bf); } //(ssyy) DarkStar, что за предупреждение по следующей строке? var ht = new Dictionary>(StringComparer.CurrentCultureIgnoreCase); //(ssyy) DarkStar, может быть эффективнее слить следующие 2 цикла в один? foreach (MemberInfo mi2 in mis) { //Console.WriteLine(mi2.Name.ToLower()); string s = mi2.Name;//.ToLower(); if (!ht.ContainsKey(s)) ht[s] = new List(); } foreach (MemberInfo mi in mis) { ht[mi.Name].Add(mi); } if (ExtensionAttributeType != null) { List meths = null; Type tmp_t = t; if (tmp_t.IsArray) arrays_with_extension_methods[tmp_t] = tmp_t; if (tmp_t.IsGenericTypeDefinition) generics_with_extension_methods[tmp_t] = tmp_t; cached_type_extensions[t] = t; while (tmp_t != null) { List meths1 = null; List meths2 = null; List meths3 = generic_parameter_type_extensions; if (tmp_t.IsGenericType && !tmp_t.IsGenericTypeDefinition) type_extensions.TryGetValue(tmp_t.GetGenericTypeDefinition(), out meths1); if (tmp_t.IsArray) generic_array_type_extensions.TryGetValue(tmp_t.GetArrayRank(), out meths2); if (type_extensions.TryGetValue(tmp_t, out meths) || meths1 != null || meths2 != null || meths3 != null) { List all_meths = new List(); if (meths != null) all_meths.AddRange(meths); if (meths1 != null) all_meths.AddRange(meths1); if (meths2 != null) all_meths.AddRange(meths2); if (meths3 != null) all_meths.AddRange(meths3); foreach (MethodInfo mi in all_meths) { if (cur_used_assemblies.ContainsKey(mi.DeclaringType.Assembly)) { List al = null; string s = compiler_string_consts.GetNETOperName(mi.Name); if (s == null) s = mi.Name; if (!ht.TryGetValue(s, out al)) { al = new List(); ht[s] = al; } al.Insert(0, mi); } } } tmp_t = tmp_t.BaseType; } Type[] intfs = t.GetInterfaces(); foreach (Type intf_t in intfs) { Type tmp = intf_t; if (tmp.IsGenericType) tmp = tmp.GetGenericTypeDefinition(); if (type_extensions.TryGetValue(tmp, out meths)) { foreach (MethodInfo mi in meths) { if (cur_used_assemblies.ContainsKey(mi.DeclaringType.Assembly)) { List al = null; if (!ht.TryGetValue(mi.Name, out al)) { al = new List(); ht[mi.Name] = al; } al.Insert(0,mi); } } } } } members[t] = ht; List lst = null; if (!ht.TryGetValue(name, out lst)) return EmptyMemberInfoList; return lst; } } private static List EmptyMemberInfoList = new List(); //(ssyy) Является ли член класса видимым. public static field_access_level get_access_level(MemberInfo mi) { field_access_level amod = field_access_level.fal_public; switch (mi.MemberType) { case MemberTypes.Constructor: case MemberTypes.Method: { MethodBase mb = mi as MethodBase; MethodAttributes attrs = mb.Attributes; if (attrs == (attrs | MethodAttributes.Public)) { amod = field_access_level.fal_public; } else { if ((attrs == (attrs | MethodAttributes.Family) || attrs == (attrs | MethodAttributes.FamORAssem)) && ((mi.MemberType == MemberTypes.Constructor) ? true : (attrs != (attrs | MethodAttributes.SpecialName)))) { amod = field_access_level.fal_protected; } else { amod = field_access_level.fal_private; } } } break; case MemberTypes.Field: FieldInfo fi = mi as FieldInfo; if (fi.Attributes == (fi.Attributes | FieldAttributes.Public) && (fi.Attributes != (fi.Attributes | FieldAttributes.SpecialName))) { amod = field_access_level.fal_public; } else { if (fi.Attributes == (fi.Attributes | FieldAttributes.Family) || fi.Attributes == (fi.Attributes | FieldAttributes.FamORAssem)) { amod = field_access_level.fal_protected; } else { amod = field_access_level.fal_private; } } break; case MemberTypes.Property: //PropertyInfo pi = mi as PropertyInfo; MethodInfo mi2 = GetAnyAccessor(mi as PropertyInfo); if (mi2 != null) if (mi2.Attributes == (mi2.Attributes | MethodAttributes.Public)) { amod = field_access_level.fal_public; } else { if ((mi2.Attributes == (mi2.Attributes | MethodAttributes.Family) || mi2.Attributes == (mi2.Attributes | MethodAttributes.FamORAssem))) { amod = field_access_level.fal_protected; } else { amod = field_access_level.fal_private; } } break; } return amod; } public static bool is_visible(MemberInfo mi) { field_access_level amod = get_access_level(mi); if (amod == field_access_level.fal_public) { return true; } if (amod == field_access_level.fal_private) { return false; } common_type_node curr_type = SystemLibrary.SystemLibrary.syn_visitor.context.converted_type; compiled_type_node comp_node = compiled_type_node.get_type_node(mi.DeclaringType); return curr_type != null && type_table.is_derived(comp_node, curr_type); } public static List GetConstructor(Type t) { ConstructorInfo[] constrs = t.GetConstructors(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic); SymbolInfo si = null; List res_si = null; foreach (ConstructorInfo ci in constrs) { field_access_level fal = get_access_level(ci); if (fal != field_access_level.fal_private && fal != field_access_level.fal_internal) { si = new SymbolInfo(compiled_constructor_node.get_compiled_constructor(ci)); if (res_si == null) res_si = new List(); res_si.Add(si); } } return res_si; } public static bool HasFlagAttribute(Type t) { return t.GetCustomAttributes(typeof(FlagsAttribute), true).Length != 0; } public static bool IsParamsParameter(ParameterInfo pi) { return pi.GetCustomAttributes(typeof(ParamArrayAttribute), true).Length > 0; } public static bool IsType(string name) { return FindType(name) != null; } public static List FindNameIncludeProtected(Type t, string name) { if (name == null) return null; if (name == compiler_string_consts.assign_name) return null; string s = compiler_string_consts.GetNETOperName(name); if (s != null) { if (IsStandType(t)) return null; name = s; } List sil=null; List mis = GetMembers(t,name); foreach (MemberInfo mi in mis) { if (mi.DeclaringType != null && PABCSystemType != null && mi.DeclaringType.Assembly == PABCSystemType.Assembly && !UsePABCRtl) continue; field_access_level fal = get_access_level(mi); if (fal != field_access_level.fal_private && fal != field_access_level.fal_internal) { SymbolInfo temp = null; switch (mi.MemberType) { case MemberTypes.Method: temp = new SymbolInfo(compiled_function_node.get_compiled_method((MethodInfo)mi)); break; case MemberTypes.Constructor: temp = new SymbolInfo(compiled_constructor_node.get_compiled_constructor((ConstructorInfo)mi)); break; case MemberTypes.Property: temp = new SymbolInfo(GetPropertyNode((PropertyInfo)mi)); break; case MemberTypes.Field: temp = GetSymbolInfoForFieldNode((FieldInfo)mi); break; case MemberTypes.Event: temp = new SymbolInfo(GetEvent((EventInfo)mi)); break; default: continue; } if (sil == null) sil = new List(); sil.Insert(0, temp); } } Type nested_t = null; foreach (Type nt in t.GetNestedTypes()) { if (string.Compare(nt.Name, name, true) == 0) { nested_t = nt; break; } } if (nested_t != null) { SymbolInfo temp = new SymbolInfo(compiled_type_node.get_type_node(nested_t)); if (sil == null) sil = new List(); sil.Insert(0, temp); } return sil; } public static List FindName(Type t, string name) { if (name == null) return null; if (name == compiler_string_consts.assign_name) return null; string s = compiler_string_consts.GetNETOperName(name); string tmp_name = name; if (s != null) { if (IsStandType(t)) return null; if (t != NetHelper.PABCSystemType) name = s; } List sil = null; List mis = GetMembers(t, name); //(ssyy) Изменил алгоритм. //У нас некоторые алгоритмы базируются на том, что возвращённые //сущности будут одной природы (например, все - методы). Это неверно, //так как в случае наличия функции Ident и поля ident оба должны попасть //в список. //TODO: проанализировать и изменить алгоритмы, использующие поиск. //List si_list = new List(); foreach (MemberInfo mi in mis) { if (mi.DeclaringType != null && PABCSystemType != null && mi.DeclaringType.Assembly == PABCSystemType.Assembly && !UsePABCRtl) continue; if (is_visible(mi)) { SymbolInfo temp = null; switch (mi.MemberType) { case MemberTypes.Method: temp = new SymbolInfo(compiled_function_node.get_compiled_method(mi as MethodInfo)); // SSM 2018.05.05 исправляет bug #815 temp.symbol_kind = symbol_kind.sk_overload_function; break; case MemberTypes.Constructor: temp = new SymbolInfo(compiled_constructor_node.get_compiled_constructor(mi as ConstructorInfo)); break; case MemberTypes.Property: temp = new SymbolInfo(GetPropertyNode(mi as PropertyInfo)); break; case MemberTypes.Field: temp = GetSymbolInfoForFieldNode(mi as FieldInfo); break; case MemberTypes.Event: temp = new SymbolInfo(GetEvent(mi as EventInfo)); break; default: continue; } if (sil == null) sil = new List { temp }; else sil.Add(temp); //temp.Next = si; //si = temp; } } Type nested_t = null; foreach (Type nt in t.GetNestedTypes()) { if (string.Compare(nt.Name, name, true) == 0) { nested_t = nt; break; } } if (nested_t != null) { List temp = new List { new SymbolInfo(compiled_type_node.get_type_node(nested_t)) }; if(sil != null) temp.AddRange(sil); sil = temp; } return sil; } public static SymbolInfo GetSymbolInfoForFieldNode(FieldInfo fi) { SymbolInfo si = null; if (fi.IsLiteral && !fi.FieldType.IsEnum) { compiled_class_constant_definition cd = GetConstantFieldNode(fi); if (cd != null) si = new SymbolInfo(cd); } if (si == null) si = new SymbolInfo(GetFieldNode(fi)); return si; } /* public static compiled_function_node GetMethodNode(MethodInfo mi) { compiled_function_node cfn = (compiled_function_node)meth_nodes[mi]; if (cfn != null) return cfn; cfn = new compiled_function_node(mi); meth_nodes[mi] = cfn; return cfn; } */ public static compiled_property_node GetPropertyNode(PropertyInfo pi) { compiled_property_node cpn = null; if (prop_nodes.TryGetValue(pi, out cpn)) return cpn; cpn = new compiled_property_node(pi); prop_nodes[pi] = cpn; return cpn; } public static compiled_variable_definition GetFieldNode(FieldInfo pi) { compiled_variable_definition cpn = field_nodes[pi] as compiled_variable_definition; if (cpn != null) { if (cpn.type is compiled_type_node) return cpn; if (PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.compiled_unit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) { if (cpn.type.type_special_kind == type_special_kind.typed_file && (!PascalABCCompiler.TreeConverter.compilation_context.instance.TypedFiles.ContainsKey(cpn.type.element_type) || PascalABCCompiler.TreeConverter.compilation_context.instance.TypedFiles[cpn.type.element_type] != cpn.type)) { cpn.type = PascalABCCompiler.TreeConverter.compilation_context.instance.create_typed_file_type(cpn.type.element_type,null); return cpn; } else if (cpn.type.type_special_kind == type_special_kind.set_type && (!PascalABCCompiler.TreeConverter.compilation_context.instance.TypedSets.ContainsKey(cpn.type.element_type) || PascalABCCompiler.TreeConverter.compilation_context.instance.TypedSets[cpn.type.element_type] != cpn.type)) { cpn.type = PascalABCCompiler.TreeConverter.compilation_context.instance.create_set_type(cpn.type.element_type,null); return cpn; } else if (cpn.type.type_special_kind == type_special_kind.short_string && (!PascalABCCompiler.TreeConverter.compilation_context.instance.ShortStringTypes.ContainsKey((cpn.type as short_string_type_node).Length) || PascalABCCompiler.TreeConverter.compilation_context.instance.ShortStringTypes[(cpn.type as short_string_type_node).Length] != cpn.type)) { cpn.type = PascalABCCompiler.TreeConverter.compilation_context.instance.create_short_string_type((cpn.type as short_string_type_node).Length,null); return cpn; } } } cpn = new compiled_variable_definition(pi); if (PascalABCCompiler.TreeConverter.compilation_context.instance != null && PascalABCCompiler.TreeConverter.compilation_context.instance.syntax_tree_visitor.compiled_unit != null && PascalABCCompiler.TreeConverter.compilation_context.instance.converted_namespace != null) { object[] attrs = pi.GetCustomAttributes(false); for (int i=0; i) { foreach (TypeInfo t in o as List) { for (int i = 0; i < _unar.Count; i++) { if (string.Compare(_unar[i].namespace_name + "." + name, t.FullName, true) == 0) { if (!type_search_cache.TryGetValue(name, out fi)) { fi = new FoundInfo(true, t, _unar[i]); type_search_cache[name] = fi; } else { fi.type_infos.Add(new TypeNamespaceInfo(t, _unar[i])); } if (cur_used_assemblies.ContainsKey(t.type.Assembly)) return t.type; else return null; } } } return null; } for (int i = 0; i < _unar.Count; i++) { o = types[_unar[i].namespace_name + "." + name]; if (o == null) continue; if (o is TypeInfo) return (o as TypeInfo).type; List typs = o as List; List founded_types = new List(); foreach (TypeInfo t in typs) { if (cur_used_assemblies.ContainsKey(t.type.Assembly)) founded_types.Add(t); } if (founded_types.Count == 1 && cur_used_assemblies.ContainsKey(founded_types[0].type.Assembly)) return founded_types[0].type; else return null; } return null; } public static void AddType(string name, Type t) { types[name] = new TypeInfo(t, t.FullName); AddGenericInfo(t); } public static Type FindTypeOrCreate(string name) { TypeInfo ti = (TypeInfo)types[name]; if (ti != null /*&& cur_used_assemblies.ContainsKey(t.Assembly)*/) return ti.type; //ivan added - runtime types adding Type t = Type.GetType(name, false, true); if (t == null) foreach (Assembly a in assemblies.Values) { t = a.GetType(name, false, true); if (t != null) break; } if (t != null) { types[name] = new TypeInfo(t, t.FullName); AddGenericInfo(t); } return t; } public static Type FindAnyTypeInNamespace(string name) { foreach (string s in types.Keys) { TypeInfo ti = types[s] as TypeInfo; if (string.Compare(ti.type.Namespace,name, true) == 0) { return ti.type; } } return null; } private static void AddTypeToNamespace(string name, Type[] typs) { ns_types[name] = typs; } public static Type[] FindTypesInNamespace(string name) { List lst = new List(); Type[] typs = (Type[])ns_types[name]; if (typs != null) return typs; foreach (string s in types.Keys) { TypeInfo ti = types[s] as TypeInfo; if (ti != null) if (string.Compare(ti.type.Namespace,name, true) == 0) { lst.Add(ti.type); } } if (lst.Count == 0) { AddTypeToNamespace(name,new Type[0]); return null; } typs = lst.ToArray(); AddTypeToNamespace(name,typs); return typs; } public static string[] FindSubNamespaces(string name) { List lst = new List(); foreach (string s in namespaces.Keys) { if (s != name && s.StartsWith(name, StringComparison.CurrentCultureIgnoreCase)) lst.Add(s.Substring(name.Length+1)); } if (lst == null) return null; return lst.ToArray(); } private static Hashtable InitHandles(Assembly a) { Type[] types = a.GetTypes(); Hashtable ht = new Hashtable(); foreach (Type t in types) ht[(int)t.MetadataToken] = t; type_handles[a] = ht; return ht; } private static Hashtable InitMethodHandles(Type t) { MethodInfo[] mis = t.GetMethods(); Hashtable ht = new Hashtable(); foreach (MethodInfo mi in mis) ht[(int)mi.MetadataToken] = mi; method_handles[t] = ht; return ht; } private static Hashtable InitConstructorHandles(Type t) { ConstructorInfo[] cis = t.GetConstructors(); Hashtable ht = new Hashtable(); foreach (ConstructorInfo ci in cis) ht[(int)ci.MetadataToken] = ci; constr_handles[t] = ht; return ht; } private static Hashtable InitFieldHandles(Type t) { FieldInfo[] fis = t.GetFields(); Hashtable ht = new Hashtable(); foreach (FieldInfo fi in fis) ht[(int)fi.MetadataToken] = fi; field_handles[t] = ht; return ht; } public static Type FindTypeByHandle(Assembly a, int handle) { Hashtable ht = (Hashtable)type_handles[a]; if (ht == null) ht = InitHandles(a); Type t = (Type)ht[handle]; if (t == null) return (Type)special_types[handle]; return t; } public static MethodInfo FindMethodByHandle(Type t, int handle) { Hashtable ht = (Hashtable)method_handles[t]; if (ht == null) ht = InitMethodHandles(t); return (MethodInfo)ht[handle]; } public static ConstructorInfo FindConstructorByHandle(Type t, int handle) { Hashtable ht = (Hashtable)constr_handles[t]; if (ht == null) ht = InitConstructorHandles(t); return (ConstructorInfo)ht[handle]; } public static FieldInfo FindFieldByHandle(Type t, int handle) { Hashtable ht = (Hashtable)field_handles[t]; if (ht == null) ht = InitFieldHandles(t); return (FieldInfo)ht[handle]; } public static void AddGenericInfo(Type t) { if (t == null || !t.IsGenericTypeDefinition) return; int n; string s = compiler_string_consts.GetGenericTypeInformation(t.Name, out n).ToLower(); if (n == 0) { return; } List counts; bool exists = generics_names.TryGetValue(s, out counts); if (!exists) { counts = new List(); generics_names[s] = counts; } if (counts.IndexOf(n) < 0) { counts.Add(n); } } public static constant_node make_constant(object val) { try { Type t = val.GetType(); if (t == typeof(int)) return new int_const_node((int)val, null); if (t == typeof(byte)) return new byte_const_node((byte)val, null); if (t == typeof(sbyte)) return new sbyte_const_node((sbyte)val, null); if (t == typeof(short)) return new short_const_node((short)val, null); if (t == typeof(ushort)) return new ushort_const_node((ushort)val, null); if (t == typeof(uint)) return new uint_const_node((uint)val, null); if (t == typeof(long)) return new long_const_node((long)val, null); if (t == typeof(ulong)) return new ulong_const_node((ulong)val, null); if (t == typeof(char)) return new char_const_node((char)val, null); if (t == typeof(string)) return new string_const_node((string)val, null); if (t == typeof(double)) return new double_const_node((double)val, null); if (t == typeof(float)) return new double_const_node((float)val, null); if (t == typeof(bool)) return new bool_const_node((bool)val, null); if (t.IsEnum) return new enum_const_node(Convert.ToInt32(val), compiled_type_node.get_type_node(t), null); if (t.FullName == "System.Reflection.Missing") return new compiled_static_field_reference_as_constant(new static_compiled_variable_reference(new compiled_variable_definition(t.GetField("Value", BindingFlags.Public | BindingFlags.Static)), null), null); } catch { } return null; } } }