示例#1
0
		public void SaveXml(CompilationUnit cu)
		{
            try
            {
                this.cu = cu;
                is_assembly = cu.SyntaxTree is SyntaxTree.program_module || Compiler.is_dll(cu.SyntaxTree);
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = Encoding.UTF8;
                settings.Indent = true;
                xtw = XmlTextWriter.Create(Path.ChangeExtension(cu.UnitName, ".xml"), settings);
                unit_name = Path.GetFileNameWithoutExtension(cu.UnitName);
                xtw.WriteStartDocument();
                xtw.WriteStartElement("doc");
                if (is_assembly)
                {
                    xtw.WriteStartElement("assembly");
                    xtw.WriteStartElement("name");
                    xtw.WriteString(Path.GetFileNameWithoutExtension(cu.UnitName));
                    xtw.WriteEndElement();
                    xtw.WriteEndElement();
                }
                else
                {
                    xtw.WriteStartElement("unit");
                    xtw.WriteStartAttribute("name");
                    //xtw.WriteString((cu.SemanticTree as common_unit_node).unit_name);
                    xtw.WriteString(Path.GetFileNameWithoutExtension(cu.UnitName));
                    xtw.WriteEndAttribute();
                    xtw.WriteString(cu.SemanticTree.documentation);
                    xtw.WriteEndElement();
                }
                SaveMembers();
                xtw.WriteEndElement();
                xtw.Flush();
            }
            catch (Exception e)
            {

            }
			try
			{
				if (xtw != null)
					xtw.Close();
			}
			catch
			{
				
			}
		}
		public CompilationUnit ReadDLL(string FileName)
		{
            if (DLLCashe.ContainsKey(FileName))
                return DLLCashe[FileName];
            OnChangeCompilerState(this, CompilerState.ReadDLL, FileName);
            TreeRealization.using_namespace_list using_namespaces = new TreeRealization.using_namespace_list();
            try
            {
                TreeRealization.dot_net_unit_node un =
                    new TreeRealization.dot_net_unit_node(new NetHelper.NetScope(using_namespaces,
                    /*System.Reflection.Assembly.LoadFrom(FileName)*/
                    PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(FileName), SyntaxTreeToSemanticTreeConverter.SymbolTable));
                CompilationUnit cu = new CompilationUnit();
                cu.SemanticTree = un;

                //un.dotNetScope=new PascalABCCompiler.NetHelper.NetScope(using_namespaces,
                //	System.Reflection.Assembly.LoadFrom(FileName),SyntaxTreeToSemanticTreeConverter.SymbolTable);
                DLLCashe[FileName] = cu;

                return cu;
            }
            catch (Exception e)
            {
                return null;
            }
		}
 private TreeRealization.unit_node_list buildImplementationUsesList(CompilationUnit cu)
 {
     TreeRealization.unit_node_list unl = new PascalABCCompiler.TreeRealization.unit_node_list();
     unl.AddRange(cu.ImplementationUsedUnits);
     foreach (TreeRealization.unit_node un in cu.InterfaceUsedUnits)
     {
         if (un is TreeRealization.dot_net_unit_node)
             unl.AddElement(un);
     }
     return unl;
 }
		public void SavePCU(CompilationUnit Unit,string TagertFileName)
		{
//#if DEBUG
            try
            {
                if (Unit.SyntaxTree != null && Unit.SyntaxTree is SyntaxTree.unit_module)
                {
                    if (((SyntaxTree.unit_module)Unit.SyntaxTree).unit_name.HeaderKeyword == PascalABCCompiler.SyntaxTree.UnitHeaderKeyword.Library)
                        return;
                    foreach (SyntaxTree.compiler_directive cd in Unit.SyntaxTree.compiler_directives)
                        if (cd.Name.text.ToLower() == TreeConverter.compiler_string_consts.compiler_savepcu)
                            if (!Convert.ToBoolean(cd.Directive.text))
                                return;
                }
            }
            catch
            {
            }
//#endif
            PCUWriter writer=null;
            try
            {
#if DEBUG
                if (InternalDebug.PCUGenerate)
#endif
                if (compilerOptions.SavePCU)
                if ((Unit.SemanticTree as TreeRealization.common_unit_node).namespaces.Count > 1 && 
                    Unit.SyntaxTree!=null && 
                    Unit.State == UnitState.Compiled)
                {
                    writer = new PCUWriter(this, pr_ChangeState);
                    if (FileInSearchDirectory(TagertFileName))
                        TagertFileName = Path.ChangeExtension(TagertFileName, CompilerOptions.CompiledUnitExtension);
                    else
                    {
                        if(CompilerOptions.useOutputDirectory)
                            TagertFileName = Path.Combine(CompilerOptions.OutputDirectory, Path.GetFileName(Path.ChangeExtension(TagertFileName, CompilerOptions.CompiledUnitExtension)));
                        else
                            TagertFileName = Path.Combine(Path.GetDirectoryName(Unit.SyntaxTree.file_name), Path.GetFileName(Path.ChangeExtension(TagertFileName, CompilerOptions.CompiledUnitExtension)));
                    }
                    bool dbginfo = true;/*CompilerOptions.Debug*/
#if DEBUG
                    dbginfo = InternalDebug.IncludeDebugInfoInPCU;
#endif
                    writer.SaveSemanticTree(Unit, TagertFileName, dbginfo);
                    
                }
            }
            catch (Exception err)
            {
                //ErrorsList.Add(new Errors.CompilerInternalError(string.Format("Compiler.Compile[{0}]", Path.GetFileName(this.CurrentCompilationUnit.SyntaxTree.file_name)), err));
                OnChangeCompilerState(this, CompilerState.PCUWritingError, TagertFileName);
#if DEBUG
                if (!InternalDebug.SkipPCUErrors)
                    throw new Errors.CompilerInternalError(string.Format("Compiler.Compile[{0}]", Path.GetFileName(this.CurrentCompilationUnit.SyntaxTree.file_name)), err);
                writer.RemoveSelf();
#endif
            }
        }
        public CompilationUnit CompileUnit(PascalABCCompiler.TreeRealization.unit_node_list Units, SyntaxTree.unit_or_namespace SyntaxUsesUnit)
        {
            string UnitName = GetUnitFileName(SyntaxUsesUnit);
            //if (UnitName == null) throw new UnitNotFound(SyntaxUsesUnit.name,
            CompilationUnit CurrentUnit = UnitTable[UnitName];
            string name = Path.GetFileNameWithoutExtension(UnitName);
            if (Path.GetExtension(UnitName).ToLower() == CompilerOptions.CompiledUnitExtension)
            {
                string sfn = FindSourceFileName(Path.GetFileNameWithoutExtension(UnitName));
                if (sfn != null && UnitTable[sfn] != null)
                    CurrentUnit = UnitTable[sfn];
            }

            if (CurrentUnit != null)
                if (CurrentUnit.State != UnitState.BeginCompilation || CurrentUnit.SemanticTree != null)  //ИЗБАВИТЬСЯ ОТ ВТОРОГО УСЛОВИЯ
                {
                    Units.AddElement(CurrentUnit.SemanticTree);
                    Units.AddRange(GetReferences(CurrentUnit));
                    return CurrentUnit;
                }

            if (UnitName.ToLower().LastIndexOf(".dll") >= 0 || UnitName.ToLower().LastIndexOf(".exe") >= 0)
                if (File.Exists(UnitName))
                {
                    if (UnitTable.Count == 0) throw new ProgramModuleExpected(UnitName, null);
                    if ((CurrentUnit = ReadDLL(UnitName)) != null)
                    {
                        Units.AddElement(CurrentUnit.SemanticTree);
                        UnitTable[UnitName] = CurrentUnit;
                        return CurrentUnit;
                    }
                    else
                        //throw new DLLReadingError(UnitName);
                        throw new AssemblyReadingError(CurrentCompilationUnit.SyntaxTree.file_name, UnitName, SyntaxUsesUnit.source_context);
                }
            if (Path.GetExtension(UnitName).ToLower() == CompilerOptions.CompiledUnitExtension)
                if (File.Exists(UnitName))
                {
                    if (UnitTable.Count == 0) throw new ProgramModuleExpected(UnitName, null);
                    string SourceFileName = FindSourceFileName(Path.Combine(Path.GetDirectoryName(UnitName), Path.GetFileNameWithoutExtension(UnitName)));
                    try
                    {
                        //TODO: подумать как это нормально сделать
                        /*if (CompilerOptions.Debug)
                        {
                            PCUReader.PCUFileHeadState PCUFileHeadState = PCUReader.GetPCUFileHeadState(UnitName);
                            if (PCUFileHeadState.IsPCUFile && 
                                PCUFileHeadState.SupportedVersion && 
                                !PCUFileHeadState.IncludetDebugInfo && 
                                SourceFileName != null)
                            {
                                //перекомпилируем файл для получения отладочной информации
                                throw new Exception("");
                            }
                        }*/
                        if ((CurrentUnit = ReadPCU(UnitName)) != null)
                        {
                            Units.AddElement(CurrentUnit.SemanticTree);
                            Units.AddRange(GetReferences(CurrentUnit));
                            UnitTable[UnitName] = CurrentUnit;
                            return CurrentUnit;
                        }
                    }
                    catch (InvalidPCUFule)
                    {
                        //Перекомпилируем....
                    }
                    catch (Error)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        OnChangeCompilerState(this, CompilerState.PCUReadingError, UnitName);
#if DEBUG
                        if (!InternalDebug.SkipPCUErrors)
                            throw new Errors.CompilerInternalError("PCUReader", e);
#endif
                    }
                    if (SourceFileName == null)
                        throw new ReadPCUError(UnitName);
                    else
                        UnitName = SourceFileName;
                }
            string SourceText = null;
            Dictionary<SyntaxTree.syntax_tree_node, string> docs = null;
            if (CurrentUnit == null)
            {

                CurrentUnit = new CompilationUnit();
                if (FirstCompilationUnit == null)
                    FirstCompilationUnit = CurrentUnit;
                OnChangeCompilerState(this, CompilerState.BeginCompileFile, UnitName);
                SourceText = GetSourceFileText(UnitName);
                if (SourceText == null)
                    if (CurrentUnit == FirstCompilationUnit)
                        throw new SourceFileNotFound(UnitName);
                    else
                        throw new UnitNotFound(CurrentCompilationUnit.SyntaxTree.file_name, UnitName, SyntaxUsesUnit.source_context);

                CurrentUnit.SyntaxTree = InternalParseText(UnitName, SourceText, errorsList);

                if (errorsList.Count == 0) // SSM 2/05/16 - для преобразования синтаксических деревьев извне
                {
                    CurrentUnit.SyntaxTree = syntaxTreeConvertersController.Convert(CurrentUnit.SyntaxTree) as SyntaxTree.compilation_unit;
                }

                if (errorsList.Count == 0 && need_gen_doc(CurrentUnit.SyntaxTree))
                {
                    if (SourceText != null)
                    {
                        docs = AddDocumentationToNodes(CurrentUnit.SyntaxTree, SourceText);
                        if (docs != null)
                            CurrentUnit.Documented = true;
                    }
                }
                if (CurrentUnit.SyntaxTree is SyntaxTree.unit_module)
                    compilerOptions.UseDllForSystemUnits = false;
                if (is_dll(CurrentUnit.SyntaxTree))
                    compilerOptions.OutputFileType = PascalABCCompiler.CompilerOptions.OutputType.ClassLibrary;
                CurrentUnit.CaseSensitive = ParsersController.LastParser.CaseSensitive;
                CurrentCompilationUnit = CurrentUnit;

                CurrentUnit.SyntaxUnitName = SyntaxUsesUnit;

                //BadNodesInSyntaxTree.Clear();
                if (errorsList.Count > 0)
                {
                    CurrentUnit.syntax_error = errorsList[0] as PascalABCCompiler.Errors.SyntaxError;
                    foreach (Errors.Error er in errorsList)
                        if (er is SyntaxError && (er as SyntaxError).bad_node != null)
                            BadNodesInSyntaxTree[(er as SyntaxError).bad_node] = er;
                }

                //if (CurrentUnit.SyntaxTree == null)
                if (errorsList.Count > 0)
                {
                    //if (errorsList.Count == 0)
                    //    throw new Errors.SyntaxError("Internal parser error: Parser not create syntax tree", UnitName,null,null);
                    throw errorsList[0];
                }

                UnitTable[UnitName] = CurrentUnit;

                if (UnitTable.Count > 1)//если это не главный модуль
                    if (CurrentUnit.SyntaxTree is SyntaxTree.program_module)
                        throw new UnitModuleExpected(UnitName, CurrentUnit.SyntaxTree.source_context.LeftSourceContext);
                    else if (is_dll(CurrentUnit.SyntaxTree))
                        throw new UnitModuleExpectedLibraryFound(UnitName, CurrentUnit.SyntaxTree.source_context.LeftSourceContext);
                //здесь в начало uses добавляем стандартные модули
#if DEBUG
                if (InternalDebug.AddStandartUnits)
#endif
                    AddStandartUnitsToUsesSection(CurrentUnit.SyntaxTree);

            }
            CurrentSyntaxUnit = SyntaxUsesUnit;
            CurrentCompilationUnit = CurrentUnit;

            CurrentUnit.PossibleNamespaces.Clear();

            //TODO переделать, слишком сложно, некоторый код дублируется
            

            System.Collections.Generic.List<SyntaxTree.unit_or_namespace> SyntaxUsesList;
            SyntaxUsesList = GetSyntaxInterfaceUsesList(CurrentUnit.SyntaxTree);

            if (SyntaxUsesList != null)
            {
                for (int i = SyntaxUsesList.Count - 1 - CurrentUnit.InterfaceUsedUnits.Count; i >= 0; i--)
                {
                    if (!IsPossibleNamespace(SyntaxUsesList[i], false))
                    {
                        compilerOptions.UseDllForSystemUnits = false;
                        break;
                    }
                }
            }
            TreeRealization.unit_node_list References = GetReferences(CurrentUnit);

            if (SyntaxUsesList != null)
            {
                
                for (int i = SyntaxUsesList.Count - 1 - CurrentUnit.InterfaceUsedUnits.Count; i >= 0; i--)
                {
                    if (IsPossibleNamespace(SyntaxUsesList[i], true))
                    {
                        CurrentUnit.InterfaceUsedUnits.AddElement(new TreeRealization.namespace_unit_node(GetNamespace(SyntaxUsesList[i])));
                        CurrentUnit.PossibleNamespaces.Add(SyntaxUsesList[i]);
                    }
                    else
                    {
                        string CurrentSyntaxUnitName = GetUnitFileName(SyntaxUsesList[i]);
                        CurrentUnit.CurrentUsesUnit = CurrentSyntaxUnitName;
                        if (UnitTable[CurrentSyntaxUnitName] != null)
                            if (UnitTable[CurrentSyntaxUnitName].State == UnitState.BeginCompilation)
                            {
                                string CurrentSyntaxUnitNameCurrentUsesUnit = UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit;
                                if (CurrentSyntaxUnitNameCurrentUsesUnit != null)
                                {
                                    //если сначало взали pcu а потом решили его перекомпилировать, поэтому в таблице его нет
                                    if (UnitTable[CurrentSyntaxUnitNameCurrentUsesUnit] == null)
                                        UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit = FindSourceFileName(Path.GetFileNameWithoutExtension(CurrentSyntaxUnitNameCurrentUsesUnit));
                                    //далее финальная поверка на зацикливание
                                    if (UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit != null && UnitTable[UnitTable[CurrentSyntaxUnitName].CurrentUsesUnit].State == UnitState.BeginCompilation)
                                        throw new CycleUnitReference(UnitName, SyntaxUsesList[i]);
                                }
                            }
                        CompileUnit(CurrentUnit.InterfaceUsedUnits, SyntaxUsesList[i]);
                        if (CurrentUnit.State == UnitState.Compiled)
                        {
                            Units.AddElement(CurrentUnit.SemanticTree);
                            Units.AddRange(References);
                            return CurrentUnit;
                        }
                    }

                }
            }

            CurrentCompilationUnit = CurrentUnit;

            CurrentUnit.InterfaceUsedUnits.AddRange(References);

            AddNamespaces(CurrentUnit.InterfaceUsingNamespaceList, CurrentUnit.PossibleNamespaces, true);
            AddNamespaces(CurrentUnit.InterfaceUsingNamespaceList, GetInterfaceSyntaxUsingList(CurrentUnit.SyntaxTree));

            //Console.WriteLine("Compile Interface "+UnitName);//DEBUG
#if DEBUG
            if (InternalDebug.SemanticAnalysis)
#endif
            {
                OnChangeCompilerState(this, CompilerState.CompileInterface, UnitName);
                PascalABCCompiler.TreeConverter.SemanticRules.SymbolTableCaseSensitive = CurrentUnit.CaseSensitive;
                CurrentUnit.SemanticTree = SyntaxTreeToSemanticTreeConverter.CompileInterface(
                    CurrentUnit.SyntaxTree,
                    CurrentUnit.InterfaceUsedUnits,
                    ErrorsList, Warnings,
                    CurrentUnit.syntax_error,
                    BadNodesInSyntaxTree,
                    CurrentUnit.InterfaceUsingNamespaceList,
                    docs,
                    CompilerOptions.Debug,
                    CompilerOptions.ForDebugging
                    );
                CheckErrors();
            }
            TreeRealization.common_unit_node cun = CurrentUnit.SemanticTree as TreeRealization.common_unit_node;
            /*if (cun != null)
            {
            	if (!UnitsSortedList.Contains(CurrentUnit))//vnimanie zdes inogda pri silnoj zavisimosti modulej moduli popadajut neskolko raz
            	UnitsSortedList.Add(CurrentUnit);
            }*/
            CurrentUnit.State = UnitState.InterfaceCompiled;
            if (Units != null)
            {
                Units.AddElement(CurrentUnit.SemanticTree);
                Units.AddRange(References);
            }
            SyntaxUsesList = GetSyntaxImplementationUsesList(CurrentUnit.SyntaxTree);
            CompilationUnit cu = null; bool interfcompile = true;
            CurrentUnit.ImplementationUsedUnits.clear();
            CurrentUnit.PossibleNamespaces.Clear();
            if (SyntaxUsesList != null)
            {
                for (int i = SyntaxUsesList.Count - 1; i >= 0; i--)
                    if (!IsPossibleNamespace(SyntaxUsesList[i], true))
                    {
                        cu = UnitTable[GetUnitFileName(SyntaxUsesList[i])];
                        if (cu != null && cu.State == UnitState.BeginCompilation)
                        {
                            UnitsToCompile.Add(cu);
                            interfcompile = false;
#if DEBUG
                            //                            Console.WriteLine("[DEBUGINFO]Send compile to end " + Path.GetFileName(GetUnitFileName(SyntaxUsesList[i])));//DEBUG
#endif
                        }
                        else
                            CompileUnit(CurrentUnit.ImplementationUsedUnits, SyntaxUsesList[i]);
                    }
                    else
                    {
                        CurrentUnit.ImplementationUsedUnits.AddElement(new TreeRealization.namespace_unit_node(GetNamespace(SyntaxUsesList[i])));
                        CurrentUnit.PossibleNamespaces.Add(SyntaxUsesList[i]);
                    }
            }

            CurrentCompilationUnit = CurrentUnit;

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

            if (!interfcompile)
            {
                UnitsToCompile.Add(CurrentUnit);
                if (cun != null)
                {
                    if (!UnitsSortedList.Contains(CurrentUnit))//vnimanie zdes inogda pri silnoj zavisimosti modulej moduli popadajut neskolko raz
                        UnitsSortedList.Add(CurrentUnit);
                }
                //Console.WriteLine("Send compile to end "+UnitName);//DEBUG
                return CurrentUnit;
            }

            //Console.WriteLine("Compile Implementation "+UnitName);//DEBUG
            if (CurrentUnit.SyntaxTree is SyntaxTree.unit_module)
            {
#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,
                        docs,
                        CompilerOptions.Debug,
                        CompilerOptions.ForDebugging
                        );
                    CheckErrors();
                }
            }
            CurrentUnit.State = UnitState.Compiled;
            if (cun != null)
            {
                if (!UnitsSortedList.Contains(CurrentUnit))//vnimanie zdes inogda pri silnoj zavisimosti modulej moduli popadajut neskolko raz
                    UnitsSortedList.Add(CurrentUnit);
            }
            OnChangeCompilerState(this, CompilerState.EndCompileFile, UnitName);
            //SavePCU(CurrentUnit, UnitName);
            CurrentUnit.UnitName = UnitName;
            return CurrentUnit;
            /*if(CurrentUnit.State!=UnitState.Compiled)
            { 
                //Console.WriteLine("Compile Interface "+UnitName);//DEBUG
                CurrentUnit.SemanticTree=SyntaxTreeToSemanticTreeConverter.CompileInterface(CurrentUnit.SyntaxTree,
                    CurrentUnit.InterfaceUsedUnits,CurrentUnit.syntax_error);
                CurrentUnit.State=UnitState.InterfaceCompiled;
                SyntaxUsesList=GetSemanticImplementationUsesList(CurrentUnit.SyntaxTree);
                if(SyntaxUsesList!=null)
                    for(int i=SyntaxUsesList.Count-1;i>=0;i--)
                        CompileUnit(CurrentUnit.ImplementationUsedUnits,SyntaxUsesList[i]);        
                //Console.WriteLine("Compile Implementation "+UnitName);//DEBUG
                if (CurrentUnit.SyntaxTree is SyntaxTree.unit_module)
                {
                    SyntaxTreeToSemanticTreeConverter.CompileImplementation(CurrentUnit.SemanticTree,
                        CurrentUnit.SyntaxTree,CurrentUnit.ImplementationUsedUnits,CurrentUnit.syntax_error);
                }
                CurrentUnit.State=UnitState.Compiled;
                Units.Add(CurrentUnit.SemanticTree);
                SaveSemanticTreeToFile(CurrentUnit,UnitName);
            }*/
        }
 public TreeRealization.unit_node_list GetReferences(CompilationUnit Unit)
 {
     //TODO переделать, ConvertDirectives определена дважды и вызывается дважды!
     TreeRealization.unit_node_list res = new TreeRealization.unit_node_list();
     List<TreeRealization.compiler_directive> directives;
     if (Unit.SemanticTree is TreeRealization.common_unit_node)
         directives = (Unit.SemanticTree as TreeRealization.common_unit_node).compiler_directives;
     else
         directives = ConvertDirectives(Unit.SyntaxTree);
     if (CompilerOptions.UseDllForSystemUnits)
     {
         directives.Add(new TreeRealization.compiler_directive("reference", "PABCRtl.dll", null));
         directives.Add(new TreeRealization.compiler_directive("reference", "mscorlib.dll", null));
         directives.Add(new TreeRealization.compiler_directive("reference", "System.dll", null));
         directives.Add(new TreeRealization.compiler_directive("reference", "System.Core.dll", null));
         directives.Add(new TreeRealization.compiler_directive("reference", "System.Numerics.dll", null));
         directives.Add(new TreeRealization.compiler_directive("reference", "System.Windows.Forms.dll", null));
         directives.Add(new TreeRealization.compiler_directive("reference", "System.Drawing.dll", null));
     }
     foreach (TreeRealization.compiler_directive cd in directives)
     {
         if (cd.name.ToLower() == TreeConverter.compiler_string_consts.compiler_directive_reference)
         {
             if (string.IsNullOrEmpty(cd.directive))
                 throw new TreeConverter.SimpleSemanticError(cd.location, "EXPECTED_ASSEMBLY_NAME");
             else
                 CompileReference(res, cd);
         }
     }
     if (CompilerOptions.ProjectCompiled)
     {
     	foreach (ReferenceInfo ri in project.references)
     	{
     		CompileReference(res,new TreeRealization.compiler_directive("reference",ri.full_assembly_name,null));
     	}
     }
     return res;
 }
		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;
        }
 internal void Reset()
 {
     Warnings.Clear();            
     errorsList.Clear();
     //if (!File.Exists(CompilerOptions.SourceFileName)) throw new SourceFileNotFound(CompilerOptions.SourceFileName);
     CurrentCompilationUnit = null;
     FirstCompilationUnit = null;
     linesCompiled = 0;
     PCUReadersAndWritersClosed = false;
     ParsersController.Reset();
     SyntaxTreeToSemanticTreeConverter.Reset();
     CodeGeneratorsController.Reset();
     //PABCToCppCodeGeneratorsController.Reset();
     UnitsToCompile.Clear();
     DLLCashe.Clear();
     project = null;
 }
 private Hashtable GetCompilerDirectives(CompilationUnit Unit)
 {
     Hashtable Directives = new Hashtable(StringComparer.CurrentCultureIgnoreCase);
     TreeRealization.common_unit_node cun = Unit.SemanticTree as TreeRealization.common_unit_node;
     if (cun != null)
         foreach (TreeRealization.compiler_directive cd in cun.compiler_directives)
             Directives[cd.name] = cd;
     return Directives;
 }