AvalonStudio.Languages.CPlusPlus.CPlusPlusLanguageService.GenerateTranslationUnit C# (CSharp) Method

GenerateTranslationUnit() private method

private GenerateTranslationUnit ( ISourceFile file, List unsavedFiles ) : ClangTranslationUnit
file ISourceFile
unsavedFiles List
return ClangTranslationUnit
        private ClangTranslationUnit GenerateTranslationUnit(ISourceFile file, List<ClangUnsavedFile> unsavedFiles)
        {
            ClangTranslationUnit result = null;

            if (System.IO.File.Exists(file.Location))
            {
                var args = new List<string>();

                var superProject = file.Project.Solution.StartupProject as IStandardProject;
                var project = file.Project as IStandardProject;

                var toolchainIncludes = superProject.ToolChain?.GetToolchainIncludes(file);

                if (toolchainIncludes != null)
                {
                    foreach (var include in toolchainIncludes)
                    {
                        AddArgument(args, string.Format("-isystem{0}", include));
                    }
                }

                // toolchain includes
                // This code is same as in toolchain, get compiler arguments... does this need a refactor, or toolchain get passed in? Clang take GCC compatible arguments.
                // perhaps this language service has its own clang tool chain, to generate compiler arguments from project configuration?


                // Referenced includes
                var referencedIncludes = project.GetReferencedIncludes();

                foreach (var include in referencedIncludes)
                {
                    AddArgument(args, string.Format("-I{0}", include));
                }

                // global includes
                var globalIncludes = superProject.GetGlobalIncludes();

                foreach (var include in globalIncludes)
                {
                    AddArgument(args, string.Format("-I{0}", include));
                }

                // public includes
                foreach (var include in project.PublicIncludes)
                {
                    AddArgument(args, string.Format("-I{0}", include));
                }

                // includes
                foreach (var include in project.Includes)
                {
                    AddArgument(args, string.Format("-I{0}", Path.Combine(project.CurrentDirectory, include.Value)));
                }

                var referencedDefines = project.GetReferencedDefines();
                foreach (var define in referencedDefines)
                {
                    AddArgument(args, string.Format("-D{0}", define));
                }

                // global includes
                var globalDefines = superProject.GetGlobalDefines();

                foreach (var define in globalDefines)
                {
                    AddArgument(args, string.Format("-D{0}", define));
                }

                foreach (var define in project.Defines)
                {
                    AddArgument(args, string.Format("-D{0}", define));
                }

                //foreach (var arg in superProject.ToolChainArguments)
                //{
                //    args.Add(string.Format("{0}", arg));
                //}

                //foreach (var arg in superProject.CompilerArguments)
                //{
                //    args.Add(string.Format("{0}", arg));
                //}

                switch (file.Extension)
                {
                    case ".c":
                        {
                            foreach (var arg in superProject.CCompilerArguments)
                            {
                                args.Add(string.Format("{0}", arg));
                            }
                        }
                        break;

                    case ".cpp":
                        {
                            foreach (var arg in superProject.CppCompilerArguments)
                            {
                                args.Add(string.Format("{0}", arg));
                            }
                        }
                        break;
                }

                // TODO do we mark files as class header? CAn clang auto detect this?
                //if (file.Language == Language.Cpp)
                {
                    args.Add("-xc++");
                    args.Add("-std=c++14");
                    args.Add("-D__STDC__"); // This is needed to ensure inbuilt functions are appropriately prototyped.
                }

                args.Add("-Wunused-variable");

                result = index.ParseTranslationUnit(file.Location, args.ToArray(), unsavedFiles.ToArray(),
                    TranslationUnitFlags.IncludeBriefCommentsInCodeCompletion | TranslationUnitFlags.PrecompiledPreamble |
                    TranslationUnitFlags.CacheCompletionResults | TranslationUnitFlags.Incomplete);
            }

            if (result == null)
            {
                throw new Exception("Error generating translation unit.");
            }

            return result;
        }