Esempio n. 1
0
        //Метод, переводящий семантическое дерево в сборку .NET
        public void ConvertFromTree(SemanticTree.IProgramNode p, string TargetFileName, string SourceFileName, CompilerOptions options, string[] ResourceFiles)
        {
            //SystemLibrary.SystemLibInitializer.RestoreStandardFunctions();
            bool RunOnly = false;
            string fname = TargetFileName;
            comp_opt = options;
            ad = Thread.GetDomain(); //получаем домен приложения
            //ad = ad.DomainManager.CreateDomain("D1", null, null);
            an = new AssemblyName(); //создаем имя сборки
            an.Version = new Version("1.0.0.0");
            string dir = Directory.GetCurrentDirectory();
            string source_name = fname;//p.Location.document.file_name;
            int pos = source_name.LastIndexOf(Path.DirectorySeparatorChar);
            if (pos != -1) //если имя файла указано с путем, то выделяем
            {
                dir = source_name.Substring(0, pos + 1);
                an.CodeBase = String.Concat("file:///", source_name.Substring(0, pos));
                source_name = source_name.Substring(pos + 1);
            }
            string name = source_name.Substring(0, source_name.LastIndexOf('.'));
            if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
                an.Name = name;// + ".exe";
            else an.Name = name; //+ ".dll";

            if (name == "PABCRtl" || name == "PABCRtl32")
            {
                an.Flags = AssemblyNameFlags.PublicKey;
                an.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess;
                an.HashAlgorithm = System.Configuration.Assemblies.AssemblyHashAlgorithm.None;
                FileStream publicKeyStream = File.Open(Path.Combine(Path.GetDirectoryName(TargetFileName), name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk"), FileMode.Open);
                byte[] publicKey = new byte[publicKeyStream.Length];
                publicKeyStream.Read(publicKey, 0, (int)publicKeyStream.Length);
                // Provide the assembly with a public key.
                an.SetPublicKey(publicKey);
                publicKeyStream.Close();
            }
            if (RunOnly)
                ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, dir);//определяем сборку
            else
                ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save, dir);//определяем сборку

            //int nn = ad.GetAssemblies().Length;
            if (options.NeedDefineVersionInfo)
            {
                ab.DefineVersionInfoResource(options.Product, options.ProductVersion, options.Company,
                    options.Copyright, options.TradeMark);
            }
            if (options.MainResourceFileName != null)
            {
                try
                {
                    ab.DefineUnmanagedResource(options.MainResourceFileName);
                }
                catch
                {
                    throw new TreeConverter.SourceFileError(options.MainResourceFileName);
                }
            }
            else if (options.MainResourceData != null)
            {
                try
                {
                    ab.DefineUnmanagedResource(options.MainResourceData);
                }
                catch
                {
                    throw new TreeConverter.SourceFileError("");
                }
            }
            save_debug_info = comp_opt.dbg_attrs == DebugAttributes.Debug || comp_opt.dbg_attrs == DebugAttributes.ForDebbuging;
            add_special_debug_variables = comp_opt.dbg_attrs == DebugAttributes.ForDebbuging;

            //bool emit_sym = true;
            if (save_debug_info) //если модуль отладочный, то устанавливаем атрибут, запрещающий inline методов
                ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x01, 0x01, 0x00, 0x00 });
            //ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00 });
            //else
            //  ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 });
            if (RunOnly)
                mb = ab.DefineDynamicModule(name, save_debug_info);
            else
            {
                if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
                    mb = ab.DefineDynamicModule(name + ".exe", an.Name + ".exe", save_debug_info); //определяем модуль (save_debug_info - флаг включать отладочную информацию)
                else
                    mb = ab.DefineDynamicModule(name + ".dll", an.Name + ".dll", save_debug_info);
            }

            cur_unit = Path.GetFileNameWithoutExtension(SourceFileName);
            string entry_cur_unit = cur_unit;
            entry_type = mb.DefineType(cur_unit + ".Program", TypeAttributes.Public);//определяем синтетический статический класс основной программы
            cur_type = entry_type;
            //точка входа в приложение
            if (p.main_function != null)
            {
                ConvertFunctionHeader(p.main_function);
                entry_meth = helper.GetMethod(p.main_function).mi as MethodBuilder;
                /*entry_meth = entry_type.DefineMethod(p.main_function.name, MethodAttributes.Public | MethodAttributes.Static, typeof(void), GetParamTypes(p.main_function));
                for (int i = 0; i < p.main_function.parameters.Length; i++)
                {
                    if (p.main_function.parameters[i].parameter_type == parameter_type.var)
                        entry_meth.DefineParameter(i + 1, ParameterAttributes.Retval, p.main_function.parameters[i].name);
                    else
                        entry_meth.DefineParameter(i + 1, ParameterAttributes.None, p.main_function.parameters[i].name);
                }*/
                cur_meth = entry_meth;
                il = cur_meth.GetILGenerator();
                if (options.target != TargetType.Dll && options.dbg_attrs == DebugAttributes.ForDebbuging)
                    AddSpecialInitDebugCode();
            }
            ILGenerator tmp_il = il;
            MethodBuilder tmp_meth = cur_meth;

            //при отладке компилятора здесь иногда ничего нет!
            ICommonNamespaceNode[] cnns = p.namespaces;


            //создаем отладочные документы
            if (save_debug_info)
            {
                first_doc = mb.DefineDocument(SourceFileName, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft);
                for (int iii = 0; iii < cnns.Length; iii++)
                {
                    if (cnns[iii].Location != null)
                        doc = mb.DefineDocument(cnns[iii].Location.document.file_name, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft);
                    else
                        doc = first_doc;
                    sym_docs.Add(cnns[iii], doc);//сохраняем его в таблице документов
                }
                first_doc = sym_docs[cnns[0]];
                if (p.main_function != null)
                {
                    if (p.main_function.function_code is IStatementsListNode)
                        EntryPointLocation = ((IStatementsListNode)p.main_function.function_code).LeftLogicalBracketLocation;
                    else
                        EntryPointLocation = p.main_function.function_code.Location;
                }
                else
                    EntryPointLocation = null;
            }
            ICommonNamespaceNode entry_ns = null;

            //Переводим заголовки типов
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii]];
                bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == "";
                ICommonNamespaceNode cnn = cnns[iii];
                cur_type = entry_type;
                if (!is_main_namespace)
                    cur_unit = cnn.namespace_name;
                else
                    cur_unit = entry_cur_unit;
                if (iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && iii == cnns.Length - 1)
                    entry_ns = cnn;
                ConvertTypeHeaders(cnn.types);
            }

            //Переводим псевдоинстанции generic-типов
            foreach (ICommonTypeNode ictn in p.generic_type_instances)
            {
                ConvertTypeHeaderInSpecialOrder(ictn);
            }

            Dictionary<ICommonNamespaceNode, TypeBuilder> NamespacesTypes = new Dictionary<ICommonNamespaceNode, TypeBuilder>();

            for (int iii = 0; iii < cnns.Length; iii++)
            {
                bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == "";
                if (!is_main_namespace)
                {
                    //определяем синтетический класс для модуля
                    cur_type = mb.DefineType(cnns[iii].namespace_name + "." + cnns[iii].namespace_name, TypeAttributes.Public);
                    types.Add(cur_type);
                    NamespaceTypesList.Add(cur_type);
                    NamespacesTypes.Add(cnns[iii], cur_type);
                    if (cnns[iii].IsMain)
                    {
                        TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$GlobAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute));
                        ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public);
                        cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 });
                        attr_class.CreateType();
                    }
                    else
                    {
                        TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$ClassUnitAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute));
                        ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public);
                        cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 });
                        attr_class.CreateType();
                    }
                }
                else
                {
                    NamespacesTypes.Add(cnns[iii], entry_type);
                }

            }

            if (comp_opt.target == TargetType.Dll)
            {
                for (int iii = 0; iii < cnns.Length; iii++)
                {
                    string tmp = cur_unit;
                    if (cnns[iii].namespace_name != "")
                        cur_unit = cnns[iii].namespace_name;
                    else
                        cur_unit = entry_cur_unit;
                    foreach (ITemplateClass tc in cnns[iii].templates)
                    {
                        CreateTemplateClass(tc);
                    }
                    cur_unit = tmp;
                }
                for (int iii = 0; iii < cnns.Length; iii++)
                {
                    string tmp = cur_unit;
                    if (cnns[iii].namespace_name != "")
                        cur_unit = cnns[iii].namespace_name;
                    else
                        cur_unit = entry_cur_unit;
                    foreach (ITypeSynonym ts in cnns[iii].type_synonims)
                    {
                        CreateTypeSynonim(ts);
                    }
                    cur_unit = tmp;
                }
            }
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii]];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                ConvertTypeMemberHeaders(cnns[iii].types);
                //				cur_type = NamespacesTypes[cnns[iii]];
                //				cur_unit_type = NamespacesTypes[cnns[iii]];
                //				ConvertFunctionHeaders(cnns[iii].functions);
            }

            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii]];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                ConvertFunctionHeaders(cnns[iii].functions);
            }
            if (p.InitializationCode != null)
            {
                tmp_il = il;
                if (entry_meth != null)
                {
                    il = entry_meth.GetILGenerator();
                    ConvertStatement(p.InitializationCode);
                }
                else
                {
                    //il = unit_cci.GetILGenerator();
                    //ConvertStatement(p.InitializationCode);
                }
                il = tmp_il;
            }

            //Переводим псевдоинстанции generic-типов
            foreach (IGenericTypeInstance ictn in p.generic_type_instances)
            {
                ConvertGenericInstanceTypeMembers(ictn);
            }

            //Переводим псевдоинстанции функций
            foreach (IGenericFunctionInstance igfi in p.generic_function_instances)
            {
                ConvertGenericFunctionInstance(igfi);
            }

            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii]];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                //генерим инциализацию для полей
                foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types)
                    GenerateInitCodeForFields(ctn);
            }

            ConstructorBuilder unit_cci = null;

            //Переводим заголовки всего остального (процедур, переменных)
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii]];
                bool is_main_namespace = iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll;
                ICommonNamespaceNode cnn = cnns[iii];
                string tmp_unit_name = cur_unit;
                if (!is_main_namespace)
                    cur_unit = cnn.namespace_name;
                else
                    cur_unit = entry_cur_unit;
                cur_type = NamespacesTypes[cnn];

                //ConvertFunctionHeaders(cnn.functions);
                
                if (!is_main_namespace)
                {
                    //определяем статический конструктор класса для модуля
                    ConstructorBuilder cb = cur_type.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
                    il = cb.GetILGenerator();
                    if (cnn.IsMain) unit_cci = cb;
                    ModulesInitILGenerators.Add(cur_type, il);
                    //переводим глобальные переменные модуля
                    ConvertGlobalVariables(cnn.variables);
                    //перводим константы
                    ConvertNamespaceConstants(cnn.constants);
                    ConvertNamespaceEvents(cnn.events);
                    //il.Emit(OpCodes.Ret);
                }
                else
                {
                    //Не нарвится мне порядок вызова. надо с этим разобраться
                    init_variables_mb = helper.GetMethodBuilder(cnn.functions[cnn.functions.Length-1]);// cur_type.DefineMethod("$InitVariables", MethodAttributes.Public | MethodAttributes.Static);
                    il = entry_meth.GetILGenerator();
                    ModulesInitILGenerators.Add(cur_type, il);
                    il = init_variables_mb.GetILGenerator();
                    ConvertGlobalVariables(cnn.variables);
                    il = entry_meth.GetILGenerator();
                    //перводим константы
                    ConvertNamespaceConstants(cnn.constants);
                    ConvertNamespaceEvents(cnn.events);
                    //il.Emit(OpCodes.Ret);
                }

                cur_unit = tmp_unit_name;
            }

            if (p.InitializationCode != null)
            {
                tmp_il = il;
                if (entry_meth == null)
                {
                    il = unit_cci.GetILGenerator();
                    ConvertStatement(p.InitializationCode);
                }
                il = tmp_il;
            }
            cur_type = entry_type;
            //is_in_unit = false;
            //переводим реализации
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii]];
                bool is_main_namespace = iii == 0 && comp_opt.target != TargetType.Dll;
                ICommonNamespaceNode cnn = cnns[iii];
                string tmp_unit_name = cur_unit;
                if (!is_main_namespace) cur_unit = cnn.namespace_name;
                //if (iii > 0) is_in_unit = true;
                cur_unit_type = NamespacesTypes[cnns[iii]];
                cur_type = cur_unit_type;
                ConvertTypeImplementations(cnn.types);
                ConvertFunctionsBodies(cnn.functions);
                cur_unit = tmp_unit_name;
            }
            if (comp_opt.target != TargetType.Dll && p.main_function != null)
            {
                cur_unit_type = NamespacesTypes[cnns[0]];
                cur_type = cur_unit_type;
                ConvertBody(p.main_function.function_code);
            }
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii]];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                //вставляем ret в int_meth
                foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types)
                    GenerateRetForInitMeth(ctn);
                ModulesInitILGenerators[cur_type].Emit(OpCodes.Ret);
            }
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                MakeAttribute(cnns[iii]);
            }
            doc = first_doc;
            cur_type = entry_type;
            //			il = entry_type.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes).GetILGenerator();
            //			if (p.InitializationCode != null)
            //			ConvertStatement(p.InitializationCode);
            /*cur_meth = entry_meth;
            il = entry_meth.GetILGenerator();
            //переводим тело основной программы
            //Тут только вызовы init, final
            if (p.main_function != null)
            {
                ConvertBody(p.main_function.function_code);
                il.Emit(OpCodes.Ret);
            }*/

            CloseTypes();//закрываем типы

            entry_type.CreateType();
            switch (comp_opt.target)
            {
                case TargetType.Exe: ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break;
                case TargetType.WinExe:
                    if (!comp_opt.ForRunningWithEnvironment)
                        ab.SetEntryPoint(entry_meth, PEFileKinds.WindowApplication);
                    else
                        ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break;
            }

            /**/
            try
            { //ne osobo vazhnaja vesh, sohranjaet v exe-shnik spisok ispolzuemyh prostranstv imen, dlja strahovki obernuli try catch

                if (comp_opt.dbg_attrs == DebugAttributes.ForDebbuging)
                {
                    string[] namespaces = p.UsedNamespaces;

                    TypeBuilder attr_class = mb.DefineType("$UsedNsAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute));
                    FieldBuilder fld_ns = attr_class.DefineField("ns", TypeFactory.StringType, FieldAttributes.Public);
                    FieldBuilder fld_count = attr_class.DefineField("count", TypeFactory.Int32Type, FieldAttributes.Public);
                    ConstructorBuilder attr_ci = attr_class.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[2] { TypeFactory.Int32Type, TypeFactory.StringType });
                    ILGenerator attr_il = attr_ci.GetILGenerator();
                    attr_il.Emit(OpCodes.Ldarg_0);
                    attr_il.Emit(OpCodes.Ldarg_1);
                    attr_il.Emit(OpCodes.Stfld, fld_count);
                    attr_il.Emit(OpCodes.Ldarg_0);
                    attr_il.Emit(OpCodes.Ldarg_2);
                    attr_il.Emit(OpCodes.Stfld, fld_ns);
                    attr_il.Emit(OpCodes.Ret);
                    int len = 2 + 2 + 4 + 1;
                    foreach (string ns in namespaces)
                    {
                        len += ns.Length + 1;
                    }
                    byte[] bytes = new byte[len];
                    bytes[0] = 1;
                    bytes[1] = 0;
                    using (BinaryWriter bw = new BinaryWriter(new MemoryStream()))
                    {
                        bw.Write(namespaces.Length);
                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
                        foreach (string ns in namespaces)
                        {
                            sb.Append(Convert.ToChar(ns.Length));
                            sb.Append(ns);
                            //bw.Write(ns);
                        }
                        if (sb.Length > 127)
                        {
                            len += 1;
                            bytes = new byte[len];
                            bytes[0] = 1;
                            bytes[1] = 0;
                        }
                        bw.Write(sb.ToString());
                        bw.Seek(0, SeekOrigin.Begin);
                        bw.BaseStream.Read(bytes, 2, len - 4);
                        if (sb.Length > 127)
                        {
                            bytes[7] = (byte)(sb.Length & 0xFF);
                            bytes[6] = (byte)(0x80 | ((sb.Length & 0xFF00) >> 8));
                        }
                    }
                    entry_type.SetCustomAttribute(attr_ci, bytes);
                    attr_class.CreateType();
                }
            }
            catch (Exception e)
            {

            }
            if (an.Name == "PABCRtl" || an.Name == "PABCRtl32")
            {
                CustomAttributeBuilder cab = new CustomAttributeBuilder(typeof(AssemblyKeyFileAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { an.Name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk" });
                ab.SetCustomAttribute(cab);
                cab = new CustomAttributeBuilder(typeof(AssemblyDelaySignAttribute).GetConstructor(new Type[] { typeof(bool) }), new object[] { true });
                ab.SetCustomAttribute(cab);
                cab = new CustomAttributeBuilder(typeof(TargetFrameworkAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { ".NETFramework,Version=v4.0" });
                ab.SetCustomAttribute(cab);
            }

            ab.SetCustomAttribute(new CustomAttributeBuilder(typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }), new object[] { SecurityRuleSet.Level2 },
                new PropertyInfo[] { typeof(SecurityRulesAttribute).GetProperty("SkipVerificationInFullTrust") },
                new object[] { true }));
            /*ab.SetCustomAttribute(new CustomAttributeBuilder(typeof(System.Security.Permissions.SecurityPermissionAttribute).GetConstructor(new Type[] { typeof(System.Security.Permissions.SecurityAction) }), new object[] { System.Security.Permissions.SecurityAction.RequestMinimum },
                new PropertyInfo[] { typeof(System.Security.Permissions.SecurityPermissionAttribute).GetProperty("UnmanagedCode") },
                new object[] { true }));*/
            if (entry_meth != null && comp_opt.target == TargetType.WinExe)
            {
                entry_meth.SetCustomAttribute(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new byte[] { 0x01, 0x00, 0x00, 0x00 });
            }
            List<FileStream> ResStreams = new List<FileStream>();
            if (ResourceFiles != null)
                foreach (string resname in ResourceFiles)
                {
                    FileStream stream = File.OpenRead(resname);
                    ResStreams.Add(stream);
                    mb.DefineManifestResource(Path.GetFileName(resname), stream, ResourceAttributes.Public);
                    //System.Resources.ResourceManager rm;
                    //System.Resources.ResourceSet rs;rs.
                }
            ab.SetCustomAttribute(typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute).GetConstructor(new Type[1] { TypeFactory.Int32Type }),
                                  new byte[] { 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 });
            //ab.SetCustomAttribute(typeof(System.Runtime.CompilerServices.RuntimeCompatibilityAttribute,

            if (RunOnly)
            {
                object main_class = ab.CreateInstance(cur_unit + ".Program");
                MethodInfo methodInfo = main_class.GetType().GetMethod("Main");
                //AppDomain.CreateDomain(
                methodInfo.Invoke(main_class, null);

                //ad.ExecuteAssemblyByName(assembly_to_run.GetName(), new System.Security.Policy.Evidence(), null);
            }
            else
            {
                int tries = 0;
                bool not_done = true;
                do
                {
                    try
                    {
                        if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
                        {
                            if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86)
                                ab.Save(an.Name + ".exe", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
                            //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64)
                            //    ab.Save(an.Name + ".exe", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64);
                            else ab.Save(an.Name + ".exe");
                            //сохраняем сборку
                        }
                        else
                        {
                            if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86)
                                ab.Save(an.Name + ".dll", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
                            //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64)
                            //    ab.Save(an.Name + ".dll", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64);
                            else ab.Save(an.Name + ".dll");
                        }
                        not_done = false;
                    }
                    catch (System.Runtime.InteropServices.COMException e)
                    {
                        throw new TreeConverter.SaveAssemblyError(e.Message);
                    }
                    catch (System.IO.IOException e)
                    {
                        if (tries < num_try_save)
                            tries++;
                        else
                            throw new TreeConverter.SaveAssemblyError(e.Message);
                    }
                }
                while (not_done);
            }
            foreach (FileStream fs in ResStreams)
                fs.Close();

            //ad.ExecuteAssemblyByName(an, new System.Security.Policy.Evidence());
            //это уже не нужно

            //Console.WriteLine(Environment.TickCount-ticks);
        }
		public string Compile()
        {
			
			try
            {
                //var timer = System.Diagnostics.Stopwatch.StartNew(); //////

                if (Path.GetExtension(CompilerOptions.SourceFileName) == ".vb")
                {
                    return CompileVB();
                }

                if (Path.GetExtension(CompilerOptions.SourceFileName) == ".cs")
                {
                    return CompileCS();
                }
                
				OnChangeCompilerState(this, CompilerState.CompilationStarting, CompilerOptions.SourceFileName);

                Reset();
                //Console.WriteLine(timer.ElapsedMilliseconds / 1000.0);  //////
                if (CompilerOptions.ProjectCompiled)
                {
                	PrepareCompileOptionsForProject();
                }
                Environment.CurrentDirectory = CompilerOptions.SourceFileDirectory; // нужно для подключения *.inc и *.resources
                Units = new PascalABCCompiler.TreeRealization.unit_node_list();
                CurrentSyntaxUnit = new SyntaxTree.uses_unit_in(new SyntaxTree.string_const(CompilerOptions.SourceFileName));
                CompileUnit(Units, CurrentSyntaxUnit);
                //Console.WriteLine(timer.ElapsedMilliseconds / 1000.0);  //////
                foreach (CompilationUnit CurrentUnit in UnitsToCompile)
                    if (CurrentUnit.State != UnitState.Compiled)
                    {
                        CurrentCompilationUnit = CurrentUnit;
                        string UnitName = GetUnitFileName(CurrentUnit.SyntaxUnitName);
                        //if(CurrentUnit.State!=UnitState.InterfaceCompiled)													//DEBUG
                        //Console.WriteLine("ERROR! interface not compiled "+GetUnitFileName(CurrentUnit.SyntaxUnitName));//DEBUG
                        System.Collections.Generic.List<SyntaxTree.unit_or_namespace> SyntaxUsesList = GetSyntaxImplementationUsesList(CurrentUnit.SyntaxTree);
                        CurrentUnit.PossibleNamespaces.Clear();
                        if (SyntaxUsesList != null)
                        {
                            for (int i = SyntaxUsesList.Count - 1; i >= 0; i--)
                                if (!IsPossibleNamespace(SyntaxUsesList[i], false))
                                {
                                    compilerOptions.UseDllForSystemUnits = false;
                                    break;
                                }
                            for (int i = SyntaxUsesList.Count - 1; i >= 0; i--)
                                if (!IsPossibleNamespace(SyntaxUsesList[i], true))
                                    CompileUnit(CurrentUnit.ImplementationUsedUnits, SyntaxUsesList[i]);
                                else
                                {
                                    CurrentUnit.ImplementationUsedUnits.AddElement(new TreeRealization.namespace_unit_node(GetNamespace(SyntaxUsesList[i])));
                                    CurrentUnit.PossibleNamespaces.Add(SyntaxUsesList[i]);
                                }
                        }
                        //Console.WriteLine("Compile Implementation "+UnitName);//DEBUG
                        //TODO: Избавиться от преобразования типа.

                        AddNamespaces(CurrentUnit.ImplementationUsingNamespaceList, CurrentUnit.PossibleNamespaces, true);

#if DEBUG
                        if (InternalDebug.SemanticAnalysis)
#endif
                        {
                            OnChangeCompilerState(this, CompilerState.CompileImplementation, UnitName);
                            PascalABCCompiler.TreeConverter.SemanticRules.SymbolTableCaseSensitive = CurrentUnit.CaseSensitive;
                            SyntaxTreeToSemanticTreeConverter.CompileImplementation(
                                (PascalABCCompiler.TreeRealization.common_unit_node)CurrentUnit.SemanticTree,
                                CurrentUnit.SyntaxTree,
                                buildImplementationUsesList(CurrentUnit),
                                ErrorsList,Warnings,
                                CurrentUnit.syntax_error, BadNodesInSyntaxTree,
                                CurrentUnit.InterfaceUsingNamespaceList,
                                CurrentUnit.ImplementationUsingNamespaceList,
                                null,
                                CompilerOptions.Debug,
                                CompilerOptions.ForDebugging
                                );
                            CheckErrors();
                        }
                        CurrentUnit.State = UnitState.Compiled;
                        OnChangeCompilerState(this, CompilerState.EndCompileFile, UnitName);
                        //SavePCU(CurrentUnit, UnitName);
                        CurrentUnit.UnitName = UnitName;
                    }

                ClosePCUReadersAndWriters();
                if (CompilerOptions.SaveDocumentation)
                SaveDocumentations();
                
                compilerDirectives = GetCompilerDirectives(UnitsSortedList);


                TreeRealization.compiler_directive compilerDirective;
                //TODO сделать это понормальному!!!!!
                if (compilerDirectives.ContainsKey(TreeConverter.compiler_string_consts.compiler_directive_apptype))
                {
                    string directive = compilerDirectives[TreeConverter.compiler_string_consts.compiler_directive_apptype][0].directive;
                    if (string.Compare(directive,"console",true)==0)
                        CompilerOptions.OutputFileType = CompilerOptions.OutputType.ConsoleApplicaton;
                    else
                        if (string.Compare(directive,"windows",true)==0)
                            CompilerOptions.OutputFileType = CompilerOptions.OutputType.WindowsApplication;
                        else
                            if (string.Compare(directive,"dll",true)==0)
                                CompilerOptions.OutputFileType = CompilerOptions.OutputType.ClassLibrary;
                            else
                                if (string.Compare(directive,"pcu",true)==0)
                                    CompilerOptions.OutputFileType = CompilerOptions.OutputType.PascalCompiledUnit;
                }

                moveSystemUnitToForwardUnitSortedList();
                PascalABCCompiler.TreeRealization.common_unit_node system_unit = null;
                if (UnitsSortedList.Count>0) 
                    system_unit = UnitsSortedList[0].SemanticTree as PascalABCCompiler.TreeRealization.common_unit_node;
                if (system_unit != null)
                    system_unit.IsConsoleApplicationVariable = CompilerOptions.OutputFileType == CompilerOptions.OutputType.ConsoleApplicaton;

                TreeRealization.program_node pn = null;
                NETGenerator.CompilerOptions cdo = new NETGenerator.CompilerOptions();
                List<TreeRealization.compiler_directive> cds;
                if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.compiler_directive_platformtarget, out cds))
                {
                    string plt = cds[0].directive.ToLower();
                    if (plt.Equals("x86"))
                        cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x86;
                    else if (plt.Equals("x64"))
                        cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x64;
                    else if (plt.Equals("anycpu"))
                        cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.AnyCPU;
                }
                if (this.compilerOptions.Only32Bit)
                    cdo.platformtarget = NETGenerator.CompilerOptions.PlatformTarget.x86;
                if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.product_string, out cds))
                {
                    cdo.Product = cds[0].directive;
                }
                if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.version_string, out cds))
                {
                    cdo.ProductVersion = cds[0].directive;
                }
                if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.company_string, out cds))
                {
                    cdo.Company = cds[0].directive;
                }
                if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.trademark_string, out cds))
                {
                    cdo.TradeMark = cds[0].directive;
                }
                if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.copyright_string, out cds))
                {
                    cdo.Copyright = cds[0].directive;
                }
                if (compilerDirectives.TryGetValue(TreeConverter.compiler_string_consts.main_resource_string, out cds))
                {
                    cdo.MainResourceFileName = cds[0].directive;
                    if (!File.Exists(cdo.MainResourceFileName))
                    {
                        ErrorsList.Add(new ResourceFileNotFound(cds[0].directive, cds[0].location));
                    }
                }

                List<string> ResourceFiles = null;
                if (compilerDirectives.ContainsKey(TreeConverter.compiler_string_consts.compiler_directive_resource))
                {
                    ResourceFiles = new List<string>();
                    List<TreeRealization.compiler_directive> ResourceDirectives = compilerDirectives[TreeConverter.compiler_string_consts.compiler_directive_resource];
                    foreach (TreeRealization.compiler_directive cd in ResourceDirectives)
                        if (!File.Exists(cd.directive))
                        {
                            string fileName = Path.Combine(cd.location.doc.file_name, cd.directive);
                            if (File.Exists(fileName))
                                ResourceFiles.Add(fileName);
                            else
                                ErrorsList.Add(new ResourceFileNotFound(cd.directive, cd.location));
                        }
                        else
                            ResourceFiles.Add(cd.directive);
                }
                string res_file = null;
                if (project != null)
                {
                    if (!(project.major_version == 0 && project.minor_version == 0 && project.build_version == 0 && project.revision_version == 0))
                        cdo.ProductVersion = project.major_version + "." + project.minor_version + "." + project.build_version + "." + project.revision_version;
                    if (!string.IsNullOrEmpty(project.product))
                        cdo.Product = project.product;
                    if (!string.IsNullOrEmpty(project.company))
                        cdo.Company = project.company;
                    if (!string.IsNullOrEmpty(project.trademark))
                        cdo.TradeMark = project.trademark;
                    if (!string.IsNullOrEmpty(project.copyright))
                        cdo.Copyright = project.copyright;
                    if (!string.IsNullOrEmpty(project.app_icon) && false)
                    {
                        //cdo.MainResourceFileName = project.app_icon;
                        string rc_file = Path.GetFileNameWithoutExtension(project.app_icon) + ".rc";
                        StreamWriter sw = File.CreateText(rc_file);
                        sw.WriteLine("1 ICON \"" + project.app_icon.Replace("\\", "\\\\") + "\"");
                        if (cdo.NeedDefineVersionInfo)
                        {
                            cdo.NeedDefineVersionInfo = false;
                            sw.WriteLine("1 VERSIONINFO");
                            string ver = project.major_version + "," + project.minor_version + "," + project.build_version + "," + project.revision_version;
                            sw.WriteLine("FILEVERSION " + ver);
                            /*sw.WriteLine("FILEFLAGSMASK VS_FFI_FILEFLAGSMASK");
                            sw.WriteLine("FILEFLAGS VER_DEBUG");
                            sw.WriteLine("FILEOS VOS__WINDOWS32");
                            if (project.project_type != ProjectType.Library)
                                sw.WriteLine("FILETYPE VFT_APP");
                            else
                                sw.WriteLine("FILETYPE VFT_DLL");
                            sw.WriteLine("FILESUBTYPE VFT2_UNKNOWN");*/
                            sw.WriteLine("BEGIN \r\n BLOCK \"StringFileInfo\"\r\n BEGIN \r\n BLOCK \"041904E3\"\r\nBEGIN");
                            sw.WriteLine("VALUE \"ProductName\"," + "\"" + cdo.Product + "\"");
                            sw.WriteLine("VALUE \"FileVersion\"," + "\"" + ver + "\"");
                            sw.WriteLine("VALUE \"ProductVersion\"," + "\"" + ver + "\"");
                            sw.WriteLine("VALUE \"FileDescription\"," + "\"" + "" + "\"");
                            sw.WriteLine("VALUE \"OriginalFileName\"," + "\"" + Path.GetFileName(CompilerOptions.OutputFileName) + "\"");
                            sw.WriteLine("VALUE \"InternalName\"," + "\"" + Path.GetFileNameWithoutExtension(CompilerOptions.OutputFileName) + "\"");
                            sw.WriteLine("VALUE \"CompanyName\"," + "\"" + cdo.Company + "\"");
                            sw.WriteLine("VALUE \"LegalTrademarks1\"," + "\"" + cdo.TradeMark + "\"");
                            sw.WriteLine("VALUE \"LegalCopyright\"," + "\"" + cdo.Copyright + "\"");
                            sw.WriteLine("END");
                            sw.WriteLine("END");

                            sw.WriteLine("BLOCK \"VarFileInfo\"\r\nBEGIN");
                            sw.WriteLine("VALUE \"Translation\", 0x0419, 1251");
                            sw.WriteLine("END");
                            sw.WriteLine("END");
                        }
                        sw.Close();
                        System.Diagnostics.Process prc = new System.Diagnostics.Process();
                        prc.StartInfo.FileName = Path.Combine(this.CompilerOptions.SystemDirectory, "rc.exe");
                        prc.StartInfo.Arguments = Path.Combine(Path.GetDirectoryName(project.app_icon), Path.GetFileNameWithoutExtension(project.app_icon) + ".rc");
                        prc.StartInfo.CreateNoWindow = true;
                        prc.StartInfo.UseShellExecute = false;
                        prc.StartInfo.RedirectStandardOutput = true;
                        prc.StartInfo.RedirectStandardError = true;
                        prc.Start();
                        prc.WaitForExit();
                        res_file = Path.Combine(Path.GetDirectoryName(project.app_icon), Path.GetFileNameWithoutExtension(project.app_icon) + ".res");
                        if (File.Exists(res_file))
                        {
                            cdo.MainResourceFileName = res_file;
                        }
                        File.Delete(rc_file);
                    }
                }

                if (ErrorsList.Count == 0 && compilerOptions.GenerateCode)
                {
                    cdo.ForRunningWithEnvironment = CompilerOptions.RunWithEnvironment;
                	switch (CompilerOptions.OutputFileType)
                    {
                        case CompilerOptions.OutputType.ClassLibrary: cdo.target = NETGenerator.TargetType.Dll; break;
                        case CompilerOptions.OutputType.ConsoleApplicaton: cdo.target = NETGenerator.TargetType.Exe; break;
                        case CompilerOptions.OutputType.WindowsApplication: cdo.target = NETGenerator.TargetType.WinExe; break;

                    }
                    if (project != null && project.ProjectType == ProjectType.WindowsApp)
                        cdo.target = PascalABCCompiler.NETGenerator.TargetType.WinExe;
                    switch (CompilerOptions.Debug)
                    {
                        case true: cdo.dbg_attrs = NETGenerator.DebugAttributes.Debug; break;
                        case false: cdo.dbg_attrs = NETGenerator.DebugAttributes.Release; break;
                    }
                    if (CompilerOptions.ForDebugging)
                        cdo.dbg_attrs = NETGenerator.DebugAttributes.ForDebbuging;


                    //TODO: Разобратся c location для program_node и правильно передавать main_function. Добавить генератор main_function в SyntaxTreeToSemanticTreeConverter.
                    pn = new PascalABCCompiler.TreeRealization.program_node(null, null);
                    
                    for (int i = 0; i < UnitsSortedList.Count; i++)
                        pn.units.AddElement(UnitsSortedList[i].SemanticTree as TreeRealization.common_unit_node);

                    //(ssyy) Добавил в условие c_module
                    if (FirstCompilationUnit.SyntaxTree is SyntaxTree.program_module ||
                        FirstCompilationUnit.SyntaxTree is SyntaxTree.c_module)
                    {
                        if ((cdo.target == NETGenerator.TargetType.Exe) || (cdo.target == NETGenerator.TargetType.WinExe))
                        {
                            if (UnitsSortedList.Count > 0)
                            {
                                pn.main_function = ((PascalABCCompiler.TreeRealization.common_unit_node)UnitsSortedList[UnitsSortedList.Count - 1].SemanticTree).main_function;
                                /***************************Ivan added*******************************/
                                if (pn.main_function.function_code.location != null)
                                {
                                    bool flag = false;
                                    PascalABCCompiler.TreeRealization.common_namespace_node main_ns = pn.main_function.namespace_node;
                                    for (int i = 0; i < main_ns.variables.Count; i++)
                                    {
                                        PascalABCCompiler.TreeRealization.namespace_variable nv = main_ns.variables[i];
                                        if (nv.inital_value != null && nv.inital_value.location != null && !(nv.inital_value is PascalABCCompiler.TreeRealization.constant_node)
                                            && !(nv.inital_value is PascalABCCompiler.TreeRealization.record_initializer) && !(nv.inital_value is PascalABCCompiler.TreeRealization.array_initializer))
                                        {
                                            varBeginOffset = main_ns.variables[i].inital_value.location.begin_line_num;
                                            flag = true;
                                            break;
                                        }
                                    }
                                    beginOffset = pn.main_function.function_code.location.begin_line_num;
                                }
                                /*******************************************************************/
                                Dictionary<string, object> config_dic = new Dictionary<string, object>();
                                if (CompilerOptions.Locale != null && PascalABCCompiler.StringResourcesLanguage.GetLCIDByTwoLetterISO(CompilerOptions.Locale) != null)
                                { 
                                    config_dic["locale"] = CompilerOptions.Locale;
                                    config_dic["full_locale"] = PascalABCCompiler.StringResourcesLanguage.GetLCIDByTwoLetterISO(CompilerOptions.Locale);
                                }
                                pn.create_main_function(StandarModules.ToArray(), config_dic);
                                
                            }
                        }
                    }
                    else if (FirstCompilationUnit.SyntaxTree is SyntaxTree.unit_module && cdo.target == NETGenerator.TargetType.Dll)
                    {
                    	pn.create_main_function_as_in_module();
                    }
                    pn = semanticTreeConvertersController.Convert(pn) as TreeRealization.program_node;

                    _semantic_tree = pn;

                    if (FirstCompilationUnit.SyntaxTree is SyntaxTree.unit_module && CompilerOptions.OutputFileType != CompilerOptions.OutputType.ClassLibrary)
                    {
                        //если мы комилируем PCU
                        CompilerOptions.OutputFileType = CompilerOptions.OutputType.PascalCompiledUnit;
                    }
                    else
                    {
                        if( CompilerOptions.OutputFileType!= CompilerOptions.OutputType.SemanticTree)
#if DEBUG
                        if (InternalDebug.CodeGeneration)
#endif
                        {
                            try
                            {
                                File.Create(CompilerOptions.OutputFileName).Close();
                                //File.Delete(CompilerOptions.OutputFileName);
                                string pdb_file_name=Path.ChangeExtension(CompilerOptions.OutputFileName, ".pdb");
                                if (File.Exists(pdb_file_name))
                                    File.Delete(pdb_file_name);
                            }
                            catch (Exception)
                            {
                                throw new UnauthorizedAccessToFile(CompilerOptions.OutputFileName);
                            }
                            OnChangeCompilerState(this, CompilerState.CodeGeneration, CompilerOptions.OutputFileName);
                            string[] ResourceFilesArray = null;
                            if (ResourceFiles != null)
                                ResourceFilesArray = ResourceFiles.ToArray();
                            cds = null;
                            /*if (compilerDirectives.TryGetValue("platform", out cds) && cds[0].directive.ToLower() == "native")
                            {
                                //LLVMCodeGeneratorsController.Compile(pn, CompilerOptions.OutputFileName, CompilerOptions.SourceFileName, ResourceFilesArray);
                                PABCToCppCodeGeneratorsController.Compile(pn, CompilerOptions.OutputFileName, CompilerOptions.SourceFileName, ResourceFilesArray);
                            }
                            else*/
                            CodeGeneratorsController.Compile(pn, CompilerOptions.OutputFileName, CompilerOptions.SourceFileName, cdo, CompilerOptions.StandartDirectories, ResourceFilesArray);
                            if (res_file != null)
                                File.Delete(res_file);
                        }
                    }
                }
            }
            catch (TreeConverter.ParserError err)
            {
                //конвертор уткнулся в ошибку. ничего не делаем
            }
            catch (Errors.CompilerInternalError err)
            {
                if (ErrorsList.Count == 0)
                    ErrorsList.Add(err);
                else
                {
#if DEBUG
                    if (!InternalDebug.SkipInternalErrorsIfSyntaxTreeIsCorrupt)
                        ErrorsList.Add(err);
#endif
                }
            }
            catch (Errors.Error err)
            {
                if (ErrorsList.Count == 0)
                    ErrorsList.Add(err);
                else
                    if (err != ErrorsList[0])
                    {
                        if (err is SemanticError)
                        {
                            int pos = ErrorsList.Count;
                            SourceLocation loc = (err as SemanticError).SourceLocation, loctmp;
                            if (loc != null)
                                for (int i = 0; i < ErrorsList.Count; i++)
                                    if (ErrorsList[i] is LocatedError)
                                        if ((loctmp = (ErrorsList[i] as LocatedError).SourceLocation) != null)
                                            if (loctmp > loc)
                                            {
                                                pos = i;
                                                break;
                                            }

                            ErrorsList.Insert(pos, err);
                        }
                        else
                            ErrorsList.Add(err);
                    }
            }
            catch (Exception err)
            {
            	string fn = "Compiler";
                if (CurrentCompilationUnit != null && this.CurrentCompilationUnit.SyntaxTree != null) fn = Path.GetFileName(this.CurrentCompilationUnit.SyntaxTree.file_name);
                Errors.CompilerInternalError comp_err = new Errors.CompilerInternalError(string.Format("Compiler.Compile[{0}]", fn), err);
                if (ErrorsList.Count == 0)
                    ErrorsList.Add(comp_err);
                else
                {
#if DEBUG
                    if (!InternalDebug.SkipInternalErrorsIfSyntaxTreeIsCorrupt)
                        ErrorsList.Add(comp_err);
#endif
                }
            }
            //удаляем лишние ошибки
            /*foreach(Error er in errorsList)
            {

            }*/

            //на случай если мы вывалились по исключению но у нас есть откомпилированные модули
            try
            {
                ClosePCUReadersAndWriters();
            }
            catch (Exception e)
            {
                ErrorsList.Add(new Errors.CompilerInternalError("Compiler.ClosePCUReadersAndWriters", e));
            }
            bool need_recompiled = false;
            if (ErrorsList.Count > 0)
            {
                if (compilerOptions.UseDllForSystemUnits && !has_only_syntax_errors(ErrorsList) && compilerOptions.IgnoreRtlErrors)
                {
                    compilerOptions.UseDllForSystemUnits = false;
                    ErrorsList.Clear();
                    
                    need_recompiled = true;

                }
            }
            OnChangeCompilerState(this, CompilerState.CompilationFinished, CompilerOptions.SourceFileName);
            if (ClearAfterCompilation)
            ClearAll();
            
            
            OnChangeCompilerState(this, CompilerState.Ready, null);
            if (ErrorsList.Count > 0)
            {
                return null;
            }
            else if (need_recompiled)
            {
                //Compiler c = new Compiler(sourceFilesProvider,OnChangeCompilerState);
                //return c.Compile(this.compilerOptions);
                return Compile();
            }
            else
                return CompilerOptions.OutputFileName;
        }
Esempio n. 3
0
        //Метод, переводящий семантическое дерево в сборку .NET
        public void ConvertFromTree(SemanticTree.IProgramNode p, string TargetFileName, string SourceFileName, CompilerOptions options, string[] ResourceFiles)
        {
            //SystemLibrary.SystemLibInitializer.RestoreStandardFunctions();
            bool RunOnly = false;
            string fname = TargetFileName;
            comp_opt = options;
            ad = Thread.GetDomain(); //получаем домен приложения
            an = new AssemblyName(); //создаем имя сборки
            an.Version = new Version("1.0.0.0");
            string dir = Directory.GetCurrentDirectory();
            string source_name = fname;//p.Location.document.file_name;
            int pos = source_name.LastIndexOf(Path.DirectorySeparatorChar);
            if (pos != -1) //если имя файла указано с путем, то выделяем
            {
                dir = source_name.Substring(0, pos + 1);
                an.CodeBase = String.Concat("file:///", source_name.Substring(0, pos));
                source_name = source_name.Substring(pos + 1);
            }
            string name = source_name.Substring(0, source_name.LastIndexOf('.'));
            if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
                an.Name = name;// + ".exe";
            else an.Name = name; //+ ".dll";

            if (name == "PABCRtl" || name == "PABCRtl32")
            {
                an.Flags = AssemblyNameFlags.PublicKey;
                an.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess;
                an.HashAlgorithm = System.Configuration.Assemblies.AssemblyHashAlgorithm.None;
                FileStream publicKeyStream = File.Open(Path.Combine(Path.GetDirectoryName(TargetFileName), name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk"), FileMode.Open);
                byte[] publicKey = new byte[publicKeyStream.Length];
                publicKeyStream.Read(publicKey, 0, (int)publicKeyStream.Length);
                // Provide the assembly with a public key.
                an.SetPublicKey(publicKey);
                publicKeyStream.Close();
            }
            if (RunOnly)
                ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, dir);//определяем сборку
            else
                ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save, dir);//определяем сборку

            //int nn = ad.GetAssemblies().Length;
            if (options.NeedDefineVersionInfo)
            {
                ab.DefineVersionInfoResource(options.Product, options.ProductVersion, options.Company,
                    options.Copyright, options.TradeMark);
            }
            if (options.MainResourceFileName != null)
            {
                try
                {
                    ab.DefineUnmanagedResource(options.MainResourceFileName);
                }
                catch
                {
                    throw new TreeConverter.SourceFileError(options.MainResourceFileName);
                }
            }
            else if (options.MainResourceData != null)
            {
                try
                {
                    ab.DefineUnmanagedResource(options.MainResourceData);
                }
                catch
                {
                    throw new TreeConverter.SourceFileError("");
                }
            }
            save_debug_info = comp_opt.dbg_attrs == DebugAttributes.Debug || comp_opt.dbg_attrs == DebugAttributes.ForDebbuging;
            add_special_debug_variables = comp_opt.dbg_attrs == DebugAttributes.ForDebbuging;

            //bool emit_sym = true;
            if (save_debug_info) //если модуль отладочный, то устанавливаем атрибут, запрещающий inline методов
                ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x01, 0x01, 0x00, 0x00 });
            if (RunOnly)
                mb = ab.DefineDynamicModule(name, save_debug_info);
            else
            {
                if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
                    mb = ab.DefineDynamicModule(name + ".exe", an.Name + ".exe", save_debug_info); //определяем модуль (save_debug_info - флаг включать отладочную информацию)
                else
                    mb = ab.DefineDynamicModule(name + ".dll", an.Name + ".dll", save_debug_info);
            }

            cur_unit = Path.GetFileNameWithoutExtension(SourceFileName);
            string entry_cur_unit = cur_unit;
            entry_type = mb.DefineType(cur_unit + ".Program", TypeAttributes.Public);//определяем синтетический статический класс основной программы
            cur_type = entry_type;
            //точка входа в приложение
            if (p.main_function != null)
            {
                ConvertFunctionHeader(p.main_function);
                entry_meth = helper.GetMethod(p.main_function).mi as MethodBuilder;
                cur_meth = entry_meth;
                il = cur_meth.GetILGenerator();
                if (options.target != TargetType.Dll && options.dbg_attrs == DebugAttributes.ForDebbuging)
                    AddSpecialInitDebugCode();
            }
            ILGenerator tmp_il = il;
            MethodBuilder tmp_meth = cur_meth;

            //при отладке компилятора здесь иногда ничего нет!
            ICommonNamespaceNode[] cnns = p.namespaces;


            //создаем отладочные документы
            if (save_debug_info)
            {
                first_doc = mb.DefineDocument(SourceFileName, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft);
                sym_docs.Add(SourceFileName, first_doc);
                for (int iii = 0; iii < cnns.Length; iii++)
                {
                    string cnns_document_file_name = null;
                    if (cnns[iii].Location != null)
                    {
                        cnns_document_file_name = cnns[iii].Location.document.file_name;
                        doc = mb.DefineDocument(cnns_document_file_name, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft);
                    }
                    else
                        doc = first_doc;
                    if (!sym_docs.ContainsKey(cnns_document_file_name))
                        sym_docs.Add(cnns_document_file_name, doc);//сохраняем его в таблице документов
                }
                first_doc = sym_docs[cnns[0].Location == null ? SourceFileName : cnns[0].Location.document.file_name];

                if (p.main_function != null)
                {
                    if (p.main_function.function_code is IStatementsListNode)
                        EntryPointLocation = ((IStatementsListNode)p.main_function.function_code).LeftLogicalBracketLocation;
                    else
                        EntryPointLocation = p.main_function.function_code.Location;
                }
                else
                    EntryPointLocation = null;
            }
            ICommonNamespaceNode entry_ns = null;

            //Переводим заголовки типов
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name];
                bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == "";
                ICommonNamespaceNode cnn = cnns[iii];
                cur_type = entry_type;
                if (!is_main_namespace)
                    cur_unit = cnn.namespace_name;
                else
                    cur_unit = entry_cur_unit;
                if (iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && iii == cnns.Length - 1)
                    entry_ns = cnn;
                ConvertTypeHeaders(cnn.types);
            }

            //Переводим псевдоинстанции generic-типов
            foreach (ICommonTypeNode ictn in p.generic_type_instances)
            {
                ConvertTypeHeaderInSpecialOrder(ictn);
            }

            Dictionary<ICommonNamespaceNode, TypeBuilder> NamespacesTypes = new Dictionary<ICommonNamespaceNode, TypeBuilder>();

            for (int iii = 0; iii < cnns.Length; iii++)
            {
                bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == "";
                if (!is_main_namespace)
                {
                    //определяем синтетический класс для модуля
                    cur_type = mb.DefineType(cnns[iii].namespace_name + "." + cnns[iii].namespace_name, TypeAttributes.Public);
                    types.Add(cur_type);
                    NamespaceTypesList.Add(cur_type);
                    NamespacesTypes.Add(cnns[iii], cur_type);
                    if (cnns[iii].IsMain)
                    {
                        TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$GlobAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute));
                        ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public);
                        cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 });
                        attr_class.CreateType();
                    }
                    else
                    {
                        TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$ClassUnitAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute));
                        ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public);
                        cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 });
                        attr_class.CreateType();
                    }
                }
                else
                {
                    NamespacesTypes.Add(cnns[iii], entry_type);
                }

            }

            if (comp_opt.target == TargetType.Dll)
            {
                for (int iii = 0; iii < cnns.Length; iii++)
                {
                    string tmp = cur_unit;
                    if (cnns[iii].namespace_name != "")
                        cur_unit = cnns[iii].namespace_name;
                    else
                        cur_unit = entry_cur_unit;
                    foreach (ITemplateClass tc in cnns[iii].templates)
                    {
                        CreateTemplateClass(tc);
                    }
                    cur_unit = tmp;
                }
                for (int iii = 0; iii < cnns.Length; iii++)
                {
                    string tmp = cur_unit;
                    if (cnns[iii].namespace_name != "")
                        cur_unit = cnns[iii].namespace_name;
                    else
                        cur_unit = entry_cur_unit;
                    foreach (ITypeSynonym ts in cnns[iii].type_synonims)
                    {
                        CreateTypeSynonim(ts);
                    }
                    cur_unit = tmp;
                }
            }
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                ConvertTypeMemberHeaders(cnns[iii].types);
            }

            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                ConvertFunctionHeaders(cnns[iii].functions);
            }
            if (p.InitializationCode != null)
            {
                tmp_il = il;
                if (entry_meth != null)
                {
                    il = entry_meth.GetILGenerator();
                    ConvertStatement(p.InitializationCode);
                }
                il = tmp_il;
            }

            //Переводим псевдоинстанции generic-типов
            foreach (IGenericTypeInstance ictn in p.generic_type_instances)
            {
                ConvertGenericInstanceTypeMembers(ictn);
            }

            //Переводим псевдоинстанции функций
            foreach (IGenericFunctionInstance igfi in p.generic_function_instances)
            {
                ConvertGenericFunctionInstance(igfi);
            }

            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                //генерим инциализацию для полей
                foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types)
                    GenerateInitCodeForFields(ctn);
            }

            ConstructorBuilder unit_cci = null;

            //Переводим заголовки всего остального (процедур, переменных)
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name];
                bool is_main_namespace = iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll;
                ICommonNamespaceNode cnn = cnns[iii];
                string tmp_unit_name = cur_unit;
                if (!is_main_namespace)
                    cur_unit = cnn.namespace_name;
                else
                    cur_unit = entry_cur_unit;
                cur_type = NamespacesTypes[cnn];

                //ConvertFunctionHeaders(cnn.functions);
                
                if (!is_main_namespace)
                {
                    //определяем статический конструктор класса для модуля
                    ConstructorBuilder cb = cur_type.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
                    il = cb.GetILGenerator();
                    if (cnn.IsMain) unit_cci = cb;
                    ModulesInitILGenerators.Add(cur_type, il);
                    //переводим глобальные переменные модуля
                    ConvertGlobalVariables(cnn.variables);
                    //перводим константы
                    ConvertNamespaceConstants(cnn.constants);
                    ConvertNamespaceEvents(cnn.events);
                    //il.Emit(OpCodes.Ret);
                }
                else
                {
                    //Не нарвится мне порядок вызова. надо с этим разобраться
                    init_variables_mb = helper.GetMethodBuilder(cnn.functions[cnn.functions.Length-1]);// cur_type.DefineMethod("$InitVariables", MethodAttributes.Public | MethodAttributes.Static);
                    il = entry_meth.GetILGenerator();
                    ModulesInitILGenerators.Add(cur_type, il);
                    il = init_variables_mb.GetILGenerator();
                    ConvertGlobalVariables(cnn.variables);
                    il = entry_meth.GetILGenerator();
                    //перводим константы
                    ConvertNamespaceConstants(cnn.constants);
                    ConvertNamespaceEvents(cnn.events);
                    //il.Emit(OpCodes.Ret);
                }

                cur_unit = tmp_unit_name;
            }

            if (p.InitializationCode != null)
            {
                tmp_il = il;
                if (entry_meth == null)
                {
                    il = unit_cci.GetILGenerator();
                    ConvertStatement(p.InitializationCode);
                }
                il = tmp_il;
            }
            cur_type = entry_type;
            //is_in_unit = false;
            //переводим реализации
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name];
                bool is_main_namespace = iii == 0 && comp_opt.target != TargetType.Dll;
                ICommonNamespaceNode cnn = cnns[iii];
                string tmp_unit_name = cur_unit;
                if (!is_main_namespace) cur_unit = cnn.namespace_name;
                //if (iii > 0) is_in_unit = true;
                cur_unit_type = NamespacesTypes[cnns[iii]];
                cur_type = cur_unit_type;
                ConvertTypeImplementations(cnn.types);
                ConvertFunctionsBodies(cnn.functions);
                cur_unit = tmp_unit_name;
            }
            if (comp_opt.target != TargetType.Dll && p.main_function != null)
            {
                cur_unit_type = NamespacesTypes[cnns[0]];
                cur_type = cur_unit_type;
                ConvertBody(p.main_function.function_code);
            }
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name];
                cur_type = NamespacesTypes[cnns[iii]];
                cur_unit_type = NamespacesTypes[cnns[iii]];
                //вставляем ret в int_meth
                foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types)
                    GenerateRetForInitMeth(ctn);
                ModulesInitILGenerators[cur_type].Emit(OpCodes.Ret);
            }
            for (int iii = 0; iii < cnns.Length; iii++)
            {
                MakeAttribute(cnns[iii]);
            }
            doc = first_doc;
            cur_type = entry_type;

            CloseTypes();//закрываем типы

            entry_type.CreateType();
            switch (comp_opt.target)
            {
                case TargetType.Exe: ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break;
                case TargetType.WinExe:
                    if (!comp_opt.ForRunningWithEnvironment)
                        ab.SetEntryPoint(entry_meth, PEFileKinds.WindowApplication);
                    else
                        ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break;
            }

            /**/
            try
            { //ne osobo vazhnaja vesh, sohranjaet v exe-shnik spisok ispolzuemyh prostranstv imen, dlja strahovki obernuli try catch

                if (comp_opt.dbg_attrs == DebugAttributes.ForDebbuging)
                {
                    string[] namespaces = p.UsedNamespaces;

                    TypeBuilder attr_class = mb.DefineType("$UsedNsAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute));
                    FieldBuilder fld_ns = attr_class.DefineField("ns", TypeFactory.StringType, FieldAttributes.Public);
                    FieldBuilder fld_count = attr_class.DefineField("count", TypeFactory.Int32Type, FieldAttributes.Public);
                    ConstructorBuilder attr_ci = attr_class.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[2] { TypeFactory.Int32Type, TypeFactory.StringType });
                    ILGenerator attr_il = attr_ci.GetILGenerator();
                    attr_il.Emit(OpCodes.Ldarg_0);
                    attr_il.Emit(OpCodes.Ldarg_1);
                    attr_il.Emit(OpCodes.Stfld, fld_count);
                    attr_il.Emit(OpCodes.Ldarg_0);
                    attr_il.Emit(OpCodes.Ldarg_2);
                    attr_il.Emit(OpCodes.Stfld, fld_ns);
                    attr_il.Emit(OpCodes.Ret);
                    int len = 2 + 2 + 4 + 1;
                    foreach (string ns in namespaces)
                    {
                        len += ns.Length + 1;
                    }
                    byte[] bytes = new byte[len];
                    bytes[0] = 1;
                    bytes[1] = 0;
                    using (BinaryWriter bw = new BinaryWriter(new MemoryStream()))
                    {
                        bw.Write(namespaces.Length);
                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
                        foreach (string ns in namespaces)
                        {
                            sb.Append(Convert.ToChar(ns.Length));
                            sb.Append(ns);
                            //bw.Write(ns);
                        }
                        if (sb.Length > 127)
                        {
                            len += 1;
                            bytes = new byte[len];
                            bytes[0] = 1;
                            bytes[1] = 0;
                        }
                        bw.Write(sb.ToString());
                        bw.Seek(0, SeekOrigin.Begin);
                        bw.BaseStream.Read(bytes, 2, len - 4);
                        if (sb.Length > 127)
                        {
                            bytes[7] = (byte)(sb.Length & 0xFF);
                            bytes[6] = (byte)(0x80 | ((sb.Length & 0xFF00) >> 8));
                        }
                    }
                    entry_type.SetCustomAttribute(attr_ci, bytes);
                    attr_class.CreateType();
                }
            }
            catch (Exception e)
            {

            }
            if (an.Name == "PABCRtl" || an.Name == "PABCRtl32")
            {
                CustomAttributeBuilder cab = new CustomAttributeBuilder(typeof(AssemblyKeyFileAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { an.Name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk" });
                ab.SetCustomAttribute(cab);
                cab = new CustomAttributeBuilder(typeof(AssemblyDelaySignAttribute).GetConstructor(new Type[] { typeof(bool) }), new object[] { true });
                ab.SetCustomAttribute(cab);
                cab = new CustomAttributeBuilder(typeof(TargetFrameworkAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { ".NETFramework,Version=v4.0" });
                ab.SetCustomAttribute(cab);
            }

            ab.SetCustomAttribute(new CustomAttributeBuilder(typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }), new object[] { SecurityRuleSet.Level2 },
                new PropertyInfo[] { typeof(SecurityRulesAttribute).GetProperty("SkipVerificationInFullTrust") },
                new object[] { true }));
            if (entry_meth != null && comp_opt.target == TargetType.WinExe)
            {
                entry_meth.SetCustomAttribute(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new byte[] { 0x01, 0x00, 0x00, 0x00 });
            }
            List<FileStream> ResStreams = new List<FileStream>();
            if (ResourceFiles != null)
                foreach (string resname in ResourceFiles)
                {
                    FileStream stream = File.OpenRead(resname);
                    ResStreams.Add(stream);
                    mb.DefineManifestResource(Path.GetFileName(resname), stream, ResourceAttributes.Public);
                }
            ab.SetCustomAttribute(typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute).GetConstructor(new Type[1] { TypeFactory.Int32Type }),
                                  new byte[] { 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 });

            if (RunOnly)
            {
                object main_class = ab.CreateInstance(cur_unit + ".Program");
                MethodInfo methodInfo = main_class.GetType().GetMethod("Main");
                methodInfo.Invoke(main_class, null);
            }
            else
            {
                int tries = 0;
                bool not_done = true;
                do
                {
                    try
                    {
                        if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe)
                        {
                            if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86)
                                ab.Save(an.Name + ".exe", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
                            //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64)
                            //    ab.Save(an.Name + ".exe", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64);
                            else ab.Save(an.Name + ".exe");
                            //сохраняем сборку
                        }
                        else
                        {
                            if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86)
                                ab.Save(an.Name + ".dll", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386);
                            //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64)
                            //    ab.Save(an.Name + ".dll", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64);
                            else ab.Save(an.Name + ".dll");
                        }
                        not_done = false;
                    }
                    catch (System.Runtime.InteropServices.COMException e)
                    {
                        throw new TreeConverter.SaveAssemblyError(e.Message);
                    }
                    catch (System.IO.IOException e)
                    {
                        if (tries < num_try_save)
                            tries++;
                        else
                            throw new TreeConverter.SaveAssemblyError(e.Message);
                    }
                }
                while (not_done);
            }
            foreach (FileStream fs in ResStreams)
                fs.Close();

        }

        private void AddSpecialInitDebugCode()
        {
            //il.Emit(OpCodes.Call,typeof(Console).GetMethod("ReadLine"));
            //il.Emit(OpCodes.Pop);
        }

        private void ConvertNamespaceConstants(INamespaceConstantDefinitionNode[] Constants)
        {
            foreach (INamespaceConstantDefinitionNode Constant in Constants)
                ConvertConstantDefinitionNode(Constant, Constant.name, Constant.type, Constant.constant_value);
        }

        private void ConvertNamespaceEvents(ICommonNamespaceEventNode[] Events)
        {
            foreach (ICommonNamespaceEventNode Event in Events)
                Event.visit(this);
        }

        private void ConvertCommonFunctionConstantDefinitions(ICommonFunctionConstantDefinitionNode[] Constants)
        {
            foreach (ICommonFunctionConstantDefinitionNode Constant in Constants)
                //ConvertFunctionConstantDefinitionNode(Constant);
                ConvertConstantDefinitionNode(Constant, Constant.name, Constant.type, Constant.constant_value);
        }

        private void ConvertConstantDefinitionNode(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value)
        {
            if (constant_value is IArrayConstantNode)
                ConvertArrayConstantDef(cnst, name, type, constant_value);
            else
                if (constant_value is IRecordConstantNode || constant_value is ICompiledStaticMethodCallNodeAsConstant)
                    ConvertConstantDefWithInitCall(cnst, name, type, constant_value);
                else if (constant_value is ICommonNamespaceFunctionCallNodeAsConstant || constant_value is IBasicFunctionCallNodeAsConstant || constant_value is ICommonConstructorCallAsConstant || constant_value is ICompiledStaticFieldReferenceNodeAsConstant)
                    ConvertSetConstantDef(cnst, name, type, constant_value);
                else ConvertSimpleConstant(cnst, name, type, constant_value);
        }

        private void ConvertSetConstantDef(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value)
        {
            TypeInfo ti = helper.GetTypeReference(type);
            FieldAttributes attrs = FieldAttributes.Public | FieldAttributes.Static;
            if (comp_opt.target == TargetType.Dll)
                attrs |= FieldAttributes.InitOnly;
            FieldBuilder fb = cur_type.DefineField(name, ti.tp, attrs);
            //il.Emit(OpCodes.Newobj, ti.tp.GetConstructor(Type.EmptyTypes));
            //il.Emit(OpCodes.Stsfld, fb);
            if (cnst != null)
                helper.AddConstant(cnst, fb);
            bool tmp = save_debug_info;
            save_debug_info = false;
            constant_value.visit(this);
            save_debug_info = tmp;
            il.Emit(OpCodes.Stsfld, fb);

            if (!ConvertedConstants.ContainsKey(constant_value))
                ConvertedConstants.Add(constant_value, fb);
        }

        private void ConvertSimpleConstant(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value)
        {
            FieldBuilder fb = cur_type.DefineField(name, helper.GetTypeReference(type).tp, FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.Literal);
            Type t = helper.GetTypeReference(type).tp;
            if (t.IsEnum)
            {
                if (!(t is EnumBuilder))
                    fb.SetConstant(Enum.ToObject(t, (constant_value as IEnumConstNode).constant_value));
                else
                    fb.SetConstant(constant_value.value);
            }
            else if (!(constant_value is INullConstantNode))
            {
                if (constant_value.value.GetType() != t)
                {

                }
                else
                fb.SetConstant(constant_value.value);
            }
        }

        private void PushConstantValue(IConstantNode cnst)
        {
            if (cnst is IIntConstantNode)
                PushIntConst((cnst as IIntConstantNode).constant_value);
            else if (cnst is IDoubleConstantNode)
                PushDoubleConst((cnst as IDoubleConstantNode).constant_value);
            else if (cnst is IFloatConstantNode)
                PushFloatConst((cnst as IFloatConstantNode).constant_value);
            else if (cnst is ICharConstantNode)
                PushCharConst((cnst as ICharConstantNode).constant_value);
            else if (cnst is IStringConstantNode)
                PushStringConst((cnst as IStringConstantNode).constant_value);
            else if (cnst is IByteConstantNode)
                PushByteConst((cnst as IByteConstantNode).constant_value);
            else if (cnst is ILongConstantNode)
                PushLongConst((cnst as ILongConstantNode).constant_value);
            else if (cnst is IBoolConstantNode)
                PushBoolConst((cnst as IBoolConstantNode).constant_value);
            else if (cnst is ISByteConstantNode)
                PushSByteConst((cnst as ISByteConstantNode).constant_value);
            else if (cnst is IUShortConstantNode)
                PushUShortConst((cnst as IUShortConstantNode).constant_value);
            else if (cnst is IUIntConstantNode)
                PushUIntConst((cnst as IUIntConstantNode).constant_value);
            else if (cnst is IULongConstantNode)
                PushULongConst((cnst as IULongConstantNode).constant_value);
            else if (cnst is IShortConstantNode)
                PushShortConst((cnst as IShortConstantNode).constant_value);
            else if (cnst is IEnumConstNode)
                PushIntConst((cnst as IEnumConstNode).constant_value);
            else if (cnst is INullConstantNode)
                il.Emit(OpCodes.Ldnull);
        }

        private void ConvertConstantDefWithInitCall(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value)
        {
            TypeInfo ti = helper.GetTypeReference(type);
            FieldAttributes attrs = FieldAttributes.Public | FieldAttributes.Static;
            if (comp_opt.target == TargetType.Dll)
                attrs |= FieldAttributes.InitOnly;
            FieldBuilder fb = cur_type.DefineField(name, ti.tp, attrs);
            if (cnst != null)
                helper.AddConstant(cnst, fb);
            bool tmp = save_debug_info;
            save_debug_info = false;
            AddInitCall(il, fb, ti.init_meth, constant_value);
            save_debug_info = tmp;
            if (!ConvertedConstants.ContainsKey(constant_value))
                ConvertedConstants.Add(constant_value, fb);
        }

        private void ConvertArrayConstantDef(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value)
        {
            //ConvertedConstants.ContainsKey(ArrayConstant)
            TypeInfo ti = helper.GetTypeReference(type);
            FieldAttributes attrs = FieldAttributes.Public | FieldAttributes.Static;
            if (comp_opt.target == TargetType.Dll)
                attrs |= FieldAttributes.InitOnly;
            FieldBuilder fb = cur_type.DefineField(name, ti.tp, attrs);
            if (cnst != null)
                helper.AddConstant(cnst, fb);
            CreateArrayGlobalVariable(il, fb, ti, constant_value as IArrayConstantNode, type);

            if (!ConvertedConstants.ContainsKey(constant_value))
                ConvertedConstants.Add(constant_value, fb);
        }

        //это требование Reflection.Emit - все типы должны быть закрыты
        private void CloseTypes()
        {
            //(ssyy) TODO: подумать, в каком порядке создавать типы
            for (int i = 0; i < types.Count; i++)
                if (types[i].IsInterface)
                    types[i].CreateType();
            for (int i = 0; i < enums.Count; i++)
                enums[i].CreateType();
            for (int i = 0; i < value_types.Count; i++)
                value_types[i].CreateType();
            for (int i = 0; i < types.Count; i++)
                if (!types[i].IsInterface)
                    types[i].CreateType();
        }

        //перевод тела
        private void ConvertBody(IStatementNode body)
        {
            if (!(body is IStatementsListNode) && save_debug_info && body.Location != null)
                if (body.Location.begin_line_num == 0xFFFFFF) MarkSequencePoint(il, body.Location);
            body.visit(this);
            OptMakeExitLabel();
        }

        private void OptMakeExitLabel()
        {
            if (ExitProcedureCall)
            {
                il.MarkLabel(ExitLabel);
                ExitProcedureCall = false;
            }
        }

        //перевод заголовков типов
        private void ConvertTypeHeaders(ICommonTypeNode[] types)
        {
            foreach (ICommonTypeNode t in types)
            {
                ConvertTypeHeaderInSpecialOrder(t);
            }
        }

        private void CreateTemplateClass(ITemplateClass t)
        {
            if (t.serialized_tree != null)
            {
                TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType);
                types.Add(tb);
                CustomAttributeBuilder cust_bldr = new CustomAttributeBuilder(this.TemplateClassAttributeConstructor, new object[1] { t.serialized_tree });
                tb.SetCustomAttribute(cust_bldr);
            }
        }

        private void CreateTypeSynonim(ITypeSynonym t)
        {
            TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType);
            types.Add(tb);
            add_possible_type_attribute(tb, t);
        }

        private Type CreateTypedFileType(ICommonTypeNode t)
        {
            Type tt = helper.GetPascalTypeReference(t);
            if (tt != null) return tt;
            TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType);
            types.Add(tb);
            helper.AddPascalTypeReference(t, tb);
            add_possible_type_attribute(tb, t);
            return tb;
        }

        private Type CreateTypedSetType(ICommonTypeNode t)
        {
            Type tt = helper.GetPascalTypeReference(t);
            if (tt != null) return tt;
            TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType);
            types.Add(tb);
            helper.AddPascalTypeReference(t, tb);
            add_possible_type_attribute(tb, t);
            return tb;
        }

        private Type CreateShortStringType(ITypeNode t)
        {
            TypeBuilder tb = mb.DefineType(cur_unit + ".$string" + (uid++).ToString(), TypeAttributes.Public, TypeFactory.ObjectType);
            types.Add(tb);
            add_possible_type_attribute(tb, t);
            return tb;
        }

        //переводим заголовки типов в порядке начиная с базовых классов (т. е. у которых наследники - откомпилированные типы)
        private void ConvertTypeHeaderInSpecialOrder(ICommonTypeNode t)
        {
            if (t.type_special_kind == type_special_kind.diap_type) return;
            if (t.type_special_kind == type_special_kind.array_kind) return;
            if (t.depended_from_indefinite) return;
            if (t.type_special_kind == type_special_kind.typed_file && comp_opt.target == TargetType.Dll)
            {
                if (!t.name.Contains(" "))
                {
                    CreateTypedFileType(t);
                    return;
                }
            }
            else
                if (t.type_special_kind == type_special_kind.set_type && comp_opt.target == TargetType.Dll)
                {
                    if (!t.name.Contains(" "))
                    {
                        CreateTypedSetType(t);
                        return;
                    }
                }

            if (helper.GetTypeReference(t) != null && !t.is_generic_parameter) return;

            if (t.is_generic_parameter)
            {
                //ConvertTypeHeaderInSpecialOrder(t.generic_container);
                AddTypeWithoutConvert(t);
                if (converting_generic_param != t)
                {
                    return;
                }
                converting_generic_param = null;
            }
            IGenericTypeInstance gti = t as IGenericTypeInstance;
            if (gti != null)
            {
                if (gti.original_generic is ICommonTypeNode)
                {
                    ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)gti.original_generic);
                }
                foreach (ITypeNode itn in gti.generic_parameters)
                {
                    if (itn is ICommonTypeNode && !itn.is_generic_parameter)
                    {
                        ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)itn);
                    }
                }
            }
            if (t.is_generic_type_definition)
            {
                AddTypeWithoutConvert(t);
                foreach (ICommonTypeNode par in t.generic_params)
                {
                    converting_generic_param = par;
                    ConvertTypeHeaderInSpecialOrder(par);
                }
            }
            else if ((t.type_special_kind == type_special_kind.none_kind ||
                t.type_special_kind == type_special_kind.record) && !t.IsEnum &&
                !t.is_generic_type_instance && !t.is_generic_parameter)
            {
                AddTypeWithoutConvert(t);
            }
            foreach (ITypeNode interf in t.ImplementingInterfaces)
                if (!(interf is ICompiledTypeNode))
                    ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)interf);
            if (t.base_type != null && !(t.base_type is ICompiledTypeNode))
            {
                ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)t.base_type);
            }
            ConvertTypeHeader(t);
        }

        private void AddTypeWithoutConvert(ICommonTypeNode t)
        {
            if (helper.GetTypeReference(t) != null) return;
            TypeBuilder tb = mb.DefineType(cur_unit + "." + t.name, ConvertAttributes(t), null, new Type[0]);
            helper.AddType(t, tb);
            //(ssyy) обрабатываем generics
            if (t.is_generic_type_definition)
            {
                int count = t.generic_params.Count;
                string[] par_names = new string[count];
                //Создаём массив имён параметров
                for (int i = 0; i < count; i++)
                {
                    par_names[i] = t.generic_params[i].name;
                }
                //Определяем параметры в строящемся типе
                GenericTypeParameterBuilder[] net_pars = tb.DefineGenericParameters(par_names);
                for (int i = 0; i < count; i++)
                {
                    //добавляем параметр во внутр. структуры
                    helper.AddExistingType(t.generic_params[i], net_pars[i]);
                }
            }
        }

        //перевод релизаций типов
        private void ConvertTypeImplementations(ICommonTypeNode[] types)
        {
            foreach (ICommonTypeNode t in types)
            //если это не особый тип переводим реализацию наверно здесь много лишнего нужно оставить ISimpleArrayNode
            {
                if ( t.type_special_kind != type_special_kind.diap_type &&
                    !t.depended_from_indefinite)
                    t.visit(this);
            }
        }

        private void ConvertTypeMemberHeaderAndRemoveFromList(ICommonTypeNode type, List<ICommonTypeNode> types)
        {
            if (!type.depended_from_indefinite)
            {
                if (type.type_special_kind == type_special_kind.array_wrapper &&
                    type.element_type.type_special_kind == type_special_kind.array_wrapper &&
                    type.element_type is ICommonTypeNode &&
                    types.IndexOf((ICommonTypeNode)(type.element_type)) > -1)
                {
                    ConvertTypeMemberHeaderAndRemoveFromList((ICommonTypeNode)(type.element_type), types);
                }
                ConvertTypeMemberHeader(type);
            }
            types.Remove(type);
        }

        //перевод заголовков членов класса
        private void ConvertTypeMemberHeaders(ICommonTypeNode[] types)
        {
            //(ssyy) Переупорядочиваем, чтобы массивы создавались в правильном порядке
            List<ICommonTypeNode> ts = new List<ICommonTypeNode>(types);
            while (ts.Count > 0)
            {
                ConvertTypeMemberHeaderAndRemoveFromList(ts[0], ts);
            }
            foreach (ICommonTypeNode t in types)
            {
                foreach (ICommonMethodNode meth in t.methods)
                {
                    if (meth.is_generic_function)
                    {
                        ConvertTypeInstancesMembersInFunction(meth);
                    }
                }
            }
        }

        private Dictionary<TypeBuilder, TypeBuilder> added_types = new Dictionary<TypeBuilder, TypeBuilder>();
        private void BuildCloseTypeOrder(ICommonTypeNode value, TypeBuilder tb)
        {
            foreach (ICommonClassFieldNode fld in value.fields)
            {
                ITypeNode ctn = fld.type;
                TypeInfo ti = helper.GetTypeReference(ctn);
                if (ctn is ICommonTypeNode && ti.tp.IsValueType && ti.tp is TypeBuilder)
                {
                    BuildCloseTypeOrder((ICommonTypeNode)ctn, (TypeBuilder)ti.tp);
                }
            }
            if (!added_types.ContainsKey(tb))
            {
                value_types.Add(tb);
                added_types[tb] = tb;
            }
        }

        private Type GetTypeOfGenericInstanceField(Type t, FieldInfo finfo)
        {
            if (finfo.FieldType.IsGenericParameter)
            {
                return t.GetGenericArguments()[finfo.FieldType.GenericParameterPosition];
            }
            else
            {
                return finfo.FieldType;
            }
        }

        private void ConvertGenericInstanceTypeMembers(IGenericTypeInstance value)
        {
            if (helper.GetTypeReference(value) == null)
            {
                return;
            }
            ICompiledGenericTypeInstance compiled_inst = value as ICompiledGenericTypeInstance;
            if (compiled_inst != null)
            {
                ConvertCompiledGenericInstanceTypeMembers(compiled_inst);
                return;
            }
            ICommonGenericTypeInstance common_inst = value as ICommonGenericTypeInstance;
            if (common_inst != null)
            {
                ConvertCommonGenericInstanceTypeMembers(common_inst);
                return;
            }
        }

        //ssyy 04.02.2010. Вернул следующие 2 функции в исходное состояние.
        private void ConvertCompiledGenericInstanceTypeMembers(ICompiledGenericTypeInstance value)
        {
            Type t = helper.GetTypeReference(value).tp;
            bool is_delegated_type = t.BaseType == TypeFactory.MulticastDelegateType;
            foreach (IDefinitionNode dn in value.used_members.Keys)
            {
                ICompiledConstructorNode iccn = dn as ICompiledConstructorNode;
                if (iccn != null)
                {
                    ConstructorInfo ci = TypeBuilder.GetConstructor(t, iccn.constructor_info);
                    helper.AddConstructor(value.used_members[dn] as IFunctionNode, ci);
                    continue;
                }
                ICompiledMethodNode icmn = dn as ICompiledMethodNode;
                if (icmn != null)
                {
                    if (is_delegated_type && icmn.method_info.IsSpecialName) continue;
                    MethodInfo mi = null;
                    try
                    {
                        mi = TypeBuilder.GetMethod(t, icmn.method_info);
                    }
                    catch
                    {
                        if (icmn.method_info.DeclaringType.IsGenericType && !icmn.method_info.DeclaringType.IsGenericTypeDefinition)
                        {
                            Type gen_def_type = icmn.method_info.DeclaringType.GetGenericTypeDefinition();

                            foreach (MethodInfo mi2 in gen_def_type.GetMethods())
                            {
                                if (mi2.MetadataToken == icmn.method_info.MetadataToken)
                                {
                                    mi = mi2;
                                    break;
                                }
                            }

                            mi = TypeBuilder.GetMethod(t, mi);
                        }
                        else
                            mi = icmn.method_info;
                    }
                    helper.AddMethod(value.used_members[dn] as IFunctionNode, mi);
                    continue;
                }
                ICompiledClassFieldNode icfn = dn as ICompiledClassFieldNode;
                if (icfn != null)
                {
                    Type ftype = GetTypeOfGenericInstanceField(t, icfn.compiled_field);
                    FieldInfo fi = TypeBuilder.GetField(t, icfn.compiled_field);

                    helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype);
                    continue;
                }
            }
        }

        private void ConvertCommonGenericInstanceTypeMembers(ICommonGenericTypeInstance value)
        {
            Type t = helper.GetTypeReference(value).tp;
            foreach (IDefinitionNode dn in value.used_members.Keys)
            {
                ICommonMethodNode icmn = dn as ICommonMethodNode;
                if (icmn != null)
                {
                    if (icmn.is_constructor)
                    {
                        MethInfo mi = helper.GetConstructor(icmn);
                        if (mi != null)
                        {
                            ConstructorInfo cnstr = mi.cnstr;
                            ConstructorInfo ci = TypeBuilder.GetConstructor(t, cnstr);
                            helper.AddConstructor(value.used_members[dn] as IFunctionNode, ci);
                        }
                        continue;
                    }
                    else
                    {
                        MethodInfo meth = helper.GetMethod(icmn).mi;
                        if (meth.GetType().FullName == "System.Reflection.Emit.MethodOnTypeBuilderInstantiation")
                            meth = meth.GetGenericMethodDefinition();
                        MethodInfo mi = TypeBuilder.GetMethod(t, meth);
                        helper.AddMethod(value.used_members[dn] as IFunctionNode, mi);
                        continue;
                    }
                }
                ICommonClassFieldNode icfn = dn as ICommonClassFieldNode;
                if (icfn != null)
                {
                    FldInfo fldinfo = helper.GetField(icfn);
                    if (!(fldinfo is GenericFldInfo))
                    {
                        FieldInfo finfo = fldinfo.fi;
                        Type ftype = GetTypeOfGenericInstanceField(t, finfo);
                        FieldInfo fi = TypeBuilder.GetField(t, finfo);
                        helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype);
                    }
                    else
                    {
                        FieldInfo finfo = fldinfo.fi;
                        FieldInfo fi = finfo;
                        helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type);
                    }
                    continue;
                }
            }
        }

        private object[] get_constants(IConstantNode[] cnsts)
        {
            object[] objs = new object[cnsts.Length];
            for (int i = 0; i < objs.Length; i++)
            {
                objs[i] = cnsts[i].value;
            }
            return objs;
        }

        private PropertyInfo[] get_named_properties(IPropertyNode[] props)
        {
            PropertyInfo[] arr = new PropertyInfo[props.Length];
            for (int i = 0; i < arr.Length; i++)
            {
                if (props[i] is ICompiledPropertyNode)
                    arr[i] = (props[i] as ICompiledPropertyNode).property_info;
                else
                    arr[i] = helper.GetProperty(props[i]).prop;
            }
            return arr;
        }

        private FieldInfo[] get_named_fields(IVAriableDefinitionNode[] fields)
        {
            FieldInfo[] arr = new FieldInfo[fields.Length];
            for (int i = 0; i < arr.Length; i++)
            {
                if (fields[i] is ICompiledClassFieldNode)
                    arr[i] = (fields[i] as ICompiledClassFieldNode).compiled_field;
                else
                    arr[i] = helper.GetField(fields[i] as ICommonClassFieldNode).fi;
            }
            return arr;
        }

        private void MakeAttribute(ICommonNamespaceNode cnn)
        {
            IAttributeNode[] attrs = cnn.Attributes;
            for (int i = 0; i < attrs.Length; i++)
            {
                CustomAttributeBuilder cab = new CustomAttributeBuilder
                    ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                    get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                    get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                ab.SetCustomAttribute(cab);
            }
        }

        private void MakeAttribute(ICommonTypeNode ctn)
        {
            Type t = helper.GetTypeReference(ctn).tp;
            IAttributeNode[] attrs = ctn.Attributes;
            for (int i = 0; i < attrs.Length; i++)
            {
                //if (attrs[i].AttributeType == SystemLibrary.SystemLibrary.comimport_type)
                //	continue;

                CustomAttributeBuilder cab = new CustomAttributeBuilder
                    ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                    get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                    get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                if (t is TypeBuilder)
                    (t as TypeBuilder).SetCustomAttribute(cab);
                else if (t is EnumBuilder)
                    (t as EnumBuilder).SetCustomAttribute(cab);
            }
        }

        private void MakeAttribute(ICommonPropertyNode prop)
        {
            PropertyBuilder pb = (PropertyBuilder)helper.GetProperty(prop).prop;
            IAttributeNode[] attrs = prop.Attributes;
            for (int i = 0; i < attrs.Length; i++)
            {
                CustomAttributeBuilder cab = new CustomAttributeBuilder
                    ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                    get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                    get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                pb.SetCustomAttribute(cab);
            }
        }

        private void MakeAttribute(ICommonClassFieldNode fld)
        {
            FieldBuilder fb = (FieldBuilder)helper.GetField(fld).fi;
            IAttributeNode[] attrs = fld.Attributes;
            for (int i = 0; i < attrs.Length; i++)
            {
                CustomAttributeBuilder cab = new CustomAttributeBuilder
                    ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                    get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                    get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                fb.SetCustomAttribute(cab);
            }
        }

        private void MakeAttribute(ICommonFunctionNode func)
        {
            MethodBuilder mb = helper.GetMethod(func).mi as MethodBuilder;
            IAttributeNode[] attrs = func.Attributes;
            for (int i = 0; i < attrs.Length; i++)
            {

                CustomAttributeBuilder cab = new CustomAttributeBuilder
                    ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                    get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                    get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                mb.SetCustomAttribute(cab);
            }
            foreach (IParameterNode pn in func.parameters)
            {
                ParamInfo pi = helper.GetParameter(pn);
                if (pi == null) continue;
                ParameterBuilder pb = pi.pb;
                attrs = pn.Attributes;
                for (int i = 0; i < attrs.Length; i++)
                {
                    CustomAttributeBuilder cab = new CustomAttributeBuilder
                        ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                        get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                        get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                    pb.SetCustomAttribute(cab);
                }
            }
        }

        //определяем заголовки членов класса
        private void ConvertTypeMemberHeader(ICommonTypeNode value)
        {
            //если это оболочка над массивом переводим ее особым образом
            if (value.type_special_kind == type_special_kind.diap_type || value.type_special_kind == type_special_kind.array_kind) return;
            if (value.fields.Length == 1 && value.fields[0].type is ISimpleArrayNode)
            {
                ConvertArrayWrapperType(value);
                return;
            }
            if (value is ISimpleArrayNode) return;
            //этот тип уже был переведен, поэтому находим его
            TypeInfo ti = helper.GetTypeReference(value);

            //ivan
            if (ti.tp.IsEnum || !(ti.tp is TypeBuilder)) return;
            TypeBuilder tb = (TypeBuilder)ti.tp;
            if (tb.IsValueType) BuildCloseTypeOrder(value, tb);
            //сохраняем контекст
            TypeInfo tmp_ti = cur_ti;
            cur_ti = ti;
            TypeBuilder tmp = cur_type;
            cur_type = tb;

            //(ssyy) Если это интерфейс, то пропускаем следующую хрень
            if (!value.IsInterface)
            {
                //определяем метод $Init$ для выделения памяти, если метод еще не определен (в структурах он опред-ся раньше)
                MethodBuilder clone_mb = null;
                MethodBuilder ass_mb = null;
                if (ti.init_meth != null && tb.IsValueType)
                {
                    clone_mb = ti.clone_meth as MethodBuilder;
                    ass_mb = ti.assign_meth as MethodBuilder;
                }
                foreach (ICommonClassFieldNode fld in value.fields)
                    fld.visit(this);

                foreach (ICommonMethodNode meth in value.methods)
                    ConvertMethodHeader(meth);
                foreach (ICommonPropertyNode prop in value.properties)
                    prop.visit(this);

                foreach (IClassConstantDefinitionNode constant in value.constants)
                    constant.visit(this);

                foreach (ICommonEventNode evnt in value.events)
                    evnt.visit(this);

                //(ssyy) 21.05.2008
                /*foreach (ICommonMethodNode meth in value.methods)
                {
                    if (meth.is_generic_function)
                    {
                        ConvertTypeInstancesMembersInFunction(meth);
                    }
                }*/
                //добавляем ритерны в специальные методы
                //ti.init_meth.GetILGenerator().Emit(OpCodes.Ret);
                //if (hndl_mb != null) hndl_mb.GetILGenerator().Emit(OpCodes.Ret);
                if (clone_mb != null)
                {
                    clone_mb.GetILGenerator().Emit(OpCodes.Ldloc_0);
                    clone_mb.GetILGenerator().Emit(OpCodes.Ret);
                }
                if (ass_mb != null)
                {
                    ass_mb.GetILGenerator().Emit(OpCodes.Ret);
                }
                if (ti.fix_meth != null)
                {
                    ti.fix_meth.GetILGenerator().Emit(OpCodes.Ret);
                }
            }