public static IVCFileWrapper create(object wrapped) { if (modules == null) { modules = new Queue <IFactoryModule>(); // One of these modules will be working for each version of Visual Studio. modules.Enqueue(new FactoryModule2017()); modules.Enqueue(new FactoryModule2015()); modules.Enqueue(new FactoryModule2013()); modules.Enqueue(new FactoryModule2012()); } IVCFileWrapper wrapper = null; int testedModuleCount = 0; while (wrapper == null && testedModuleCount < modules.Count) { try { wrapper = modules.Peek().Create(wrapped); } catch (Exception) { wrapper = null; } testedModuleCount++; if (wrapper == null || !wrapper.isValid()) { // Moving the failing module to the end of the queue. // This causes the working module to finall end up in front. IFactoryModule failedModule = modules.Dequeue(); Logging.LogInfo("Discarcing " + failedModule.GetType().Name + " while creating file wrapper."); modules.Enqueue(failedModule); wrapper = null; } } return(wrapper); }
private CompileCommand CreateCompileCommand(ProjectItem item, string commandFlags, string vcStandard, string cStandard, bool isMakefileProject) { Logging.Logging.LogInfo("Starting to create Command Object from item \"" + Logging.Obfuscation.NameObfuscator.GetObfuscatedName(item.Name) + "\""); try { DTE dte = item.DTE; if (dte == null) { Logging.Logging.LogError("Failed to retrieve DTE object. Abort creating command object."); } IVCFileWrapper vcFile = VCFileWrapperFactory.create(item.Object); IVCCLCompilerToolWrapper compilerTool = null; if (!isMakefileProject) { List <IVCFileConfigurationWrapper> vcFileConfigurations = vcFile.GetFileConfigurations(); foreach (IVCFileConfigurationWrapper vcFileConfiguration in vcFileConfigurations) { if (vcFileConfiguration != null && vcFileConfiguration.isValid()) { compilerTool = vcFileConfiguration.GetCLCompilerTool(); if (compilerTool != null && compilerTool.isValid()) { break; } } } } if (CheckIsSourceFile(item)) { string additionalOptions = ""; if (compilerTool != null && compilerTool.isValid()) { additionalOptions = compilerTool.GetAdditionalOptions(); if (additionalOptions == "$(NOINHERIT)") { additionalOptions = ""; } } string languageStandardOption; if (additionalOptions.Contains("-std=")) { // if a language standard was defined in the additional options we do not need to set the language standard again. languageStandardOption = ""; } else { if (compilerTool != null && compilerTool.isValid() && compilerTool.GetCompilesAsC()) { languageStandardOption = "-std=" + cStandard; } else if (compilerTool != null && compilerTool.isValid() && compilerTool.GetCompilesAsCPlusPlus()) { languageStandardOption = "-std=" + vcStandard; } else { // we cannot derive the language from the compiler tool, so we need to check the file extension if (ProjectUtility.HasProperty(item.Properties, "Extension") && _cFileExtensions.Contains(item.Properties.Item("Extension").Value.ToString().Substring(1)) // extension property starts with "." ) { languageStandardOption = "-std=" + cStandard; } else { languageStandardOption = "-std=" + vcStandard; } } } CompileCommand command = new CompileCommand(); string relativeFilePath = item.Properties.Item("RelativePath").Value.ToString(); command.File = _pathResolver.GetAsAbsoluteCanonicalPath(relativeFilePath, vcFile.GetProject()); command.File = command.File.Replace('\\', '/'); command.Directory = _pathResolver.GetCompilationDatabaseFilePath(); command.Command = "clang-tool " + commandFlags; command.Command += languageStandardOption + " "; command.Command += additionalOptions + " "; command.Command += "\"" + command.File + "\""; return(command); } } catch (Exception e) { Logging.Logging.LogError("Exception: " + e.Message); } Logging.Logging.LogError("Failed to create command object."); return(null); }