// Looks at the project item. If it's a supported file type it's added to the list, and if it's a filter it keeps digging into it. private async Task scanProjectItemForSourceFilesAsync(ProjectItem item, SourceFilesWithConfiguration configuredFiles, Configuration configuration, Project project) { await JoinableTaskFactory.SwitchToMainThreadAsync(); var itemType = await getTypeOfProjectItemAsync(item); if (itemType == ProjectItemType.folder) { foreach (ProjectItem subItem in item.ProjectItems) { await scanProjectItemForSourceFilesAsync(subItem, configuredFiles, configuration, project); } } else if (itemType == ProjectItemType.headerFile || itemType == ProjectItemType.cFile || itemType == ProjectItemType.cppFile) { var document = item.Document; if (document == null) { Debug.Fail("isCppFileAsync(item) is true, but item.Document is null!"); return; } SourceFile sourceFile = await createSourceFileAsync(document.FullName, configuration, project); configuredFiles.addFileIfDoesntExistAlready(sourceFile); } }
private void runSavedFileAnalysis(SourceFile file, Configuration currentConfig) { Debug.Assert(currentConfig != null); var configuredFiles = new SourceFilesWithConfiguration(); configuredFiles.addFileIfDoesntExistAlready(file); configuredFiles.Configuration = currentConfig; _ = System.Threading.Tasks.Task.Run(async delegate { await System.Threading.Tasks.Task.Delay(750); await JoinableTaskFactory.SwitchToMainThreadAsync(); runAnalysis(new List <SourceFilesWithConfiguration> { configuredFiles }, true); }); }
private async Task <SourceFilesWithConfiguration> getAllSupportedFilesFromProjectAsync(Project project) { var sourceFiles = new SourceFilesWithConfiguration(); sourceFiles.Configuration = await getConfigurationAsync(project); await JoinableTaskFactory.SwitchToMainThreadAsync(); foreach (ProjectItem item in project.ProjectItems) { ProjectItemType itemType = await getTypeOfProjectItemAsync(item); if (itemType == ProjectItemType.cFile || itemType == ProjectItemType.cppFile || itemType == ProjectItemType.headerFile) { //List<SourceFile> projectSourceFileList = await getProjectFilesAsync(project, configuration); //foreach (SourceFile projectSourceFile in projectSourceFileList) // addEntry(currentConfiguredFiles, projectSourceFileList, project); } } return(sourceFiles); }
private async Task checkProjectsAsync(List <Project> projects) { Debug.Assert(projects.Any()); List <SourceFilesWithConfiguration> allConfiguredFiles = new List <SourceFilesWithConfiguration>(); foreach (var project in projects) { await JoinableTaskFactory.SwitchToMainThreadAsync(); Configuration config = await getConfigurationAsync(project); if (config == null) { MessageBox.Show("No valid configuration in project " + project.Name); continue; } SourceFilesWithConfiguration sourceFiles = new SourceFilesWithConfiguration(); sourceFiles.Configuration = config; foreach (ProjectItem projectItem in project.ProjectItems) { await scanProjectItemForSourceFilesAsync(projectItem, sourceFiles, config, project); } allConfiguredFiles.Add(sourceFiles); } _ = JoinableTaskFactory.RunAsync(async() => { await JoinableTaskFactory.SwitchToMainThreadAsync(); MainToolWindow.Instance.ContentsType = ICodeAnalyzer.AnalysisType.ProjectAnalysis; MainToolWindow.Instance.showIfWindowNotCreated(); }); runAnalysis(allConfiguredFiles, false); }
// Looks at the project item. If it's a supported file type it's added to the list, and if it's a filter it keeps digging into it. private async Task scanProjectItemForSourceFilesAsync(ProjectItem item, SourceFilesWithConfiguration configuredFiles, Configuration configuration, Project project) { await JoinableTaskFactory.SwitchToMainThreadAsync(); var itemType = await getTypeOfProjectItemAsync(item); if (itemType == ProjectItemType.folder) { foreach (ProjectItem subItem in item.ProjectItems) { await scanProjectItemForSourceFilesAsync(subItem, configuredFiles, configuration, project); } } else if (itemType == ProjectItemType.headerFile || itemType == ProjectItemType.cFile || itemType == ProjectItemType.cppFile) { var itemName = item.Name; if (item.FileCount == 0) { Debug.Fail("isCppFileAsync(item) is true, but item.FileCount is null!"); return; } var itemFileName = item.FileNames[1]; if (!configuredFiles.Exists(itemFileName)) { // Don't bother rebuilding the entire definition if it already exists. SourceFile sourceFile = await createSourceFileAsync(item); if (sourceFile != null) { configuredFiles.addOrUpdateFile(sourceFile); scanProgressUpdated(configuredFiles.Count()); } } } }
private string getCPPCheckArgs(SourceFilesWithConfiguration configuredFiles, bool analysisOnSavedFile, string tempFileName) { if (!configuredFiles.Any()) { Debug.Fail("Empty files list!"); return(""); } Debug.Assert(_numCores > 0); String cppheckargs = Properties.Settings.Default.DefaultArguments; if (Properties.Settings.Default.SeveritiesString.Length != 0) { cppheckargs += " --enable=" + Properties.Settings.Default.SeveritiesString; } HashSet <string> suppressions = new HashSet <string>(Properties.Settings.Default.SuppressionsString.Split(',')); suppressions.Add("unmatchedSuppression"); HashSet <string> skippedFilesMask = new HashSet <string>(); HashSet <string> skippedIncludeMask = new HashSet <string>(); SuppressionsInfo unitedSuppressionsInfo = readSuppressions(ICodeAnalyzer.SuppressionStorage.Global); unitedSuppressionsInfo.UnionWith(readSuppressions(ICodeAnalyzer.SuppressionStorage.Solution)); var filesToAnalyze = configuredFiles.Files; // Creating the list of all different project locations (no duplicates) HashSet <string> projectPaths = new HashSet <string>(); // enforce uniqueness on the list of project paths foreach (var file in filesToAnalyze) { projectPaths.Add(file.BaseProjectPath); } Debug.Assert(projectPaths.Count == 1); _projectBasePath = projectPaths.First(); _projectName = filesToAnalyze.First().ProjectName; // Creating the list of all different suppressions (no duplicates) foreach (var path in projectPaths) { unitedSuppressionsInfo.UnionWith(readSuppressions(SuppressionStorage.Project, path, filesToAnalyze.First().ProjectName)); } cppheckargs += (" --relative-paths=\"" + _projectBasePath + "\""); cppheckargs += (" -j " + _numCores.ToString()); if (Properties.Settings.Default.InconclusiveChecksEnabled) { cppheckargs += " --inconclusive "; } suppressions.UnionWith(unitedSuppressionsInfo.SuppressionLines); foreach (string suppression in suppressions) { if (!String.IsNullOrWhiteSpace(suppression)) { cppheckargs += (" --suppress=" + suppression); } } if (!(analysisOnSavedFile && Properties.Settings.Default.IgnoreIncludePaths)) { // We only add include paths once, and then specify a set of files to check HashSet <string> includePaths = new HashSet <string>(); foreach (var file in filesToAnalyze) { if (!matchMasksList(file.FilePath, unitedSuppressionsInfo.SkippedFilesMask)) { includePaths.UnionWith(file.IncludePaths); } } includePaths.Add(filesToAnalyze.First().BaseProjectPath); // Fix for #60 foreach (string path in includePaths) { if (!matchMasksList(path, unitedSuppressionsInfo.SkippedIncludesMask)) { String includeArgument = " -I\"" + path + "\""; cppheckargs = cppheckargs + " " + includeArgument; } } } using (StreamWriter tempFile = new StreamWriter(tempFileName)) { foreach (SourceFile file in filesToAnalyze) { if (!matchMasksList(file.FilePath, unitedSuppressionsInfo.SkippedFilesMask)) { tempFile.WriteLine(file.FilePath); } } } cppheckargs += " --file-list=\"" + tempFileName + "\""; if ((analysisOnSavedFile && Properties.Settings.Default.FileOnlyCheckCurrentConfig) || (!analysisOnSavedFile && Properties.Settings.Default.ProjectOnlyCheckCurrentConfig)) // Only checking current macros configuration (for speed) { cppheckargs = cppheckargs.Replace("--force", ""); // Creating the list of all different macros (no duplicates) HashSet <string> macros = new HashSet <string>(); // TODO: handle /Zc:__cplusplus // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ macros.Add("__cplusplus=199711L"); // At least in VS2012, this is still 199711L // Assuming all files passed here are from the same project / same toolset, which should be true, so peeking the first file for global settings switch (filesToAnalyze.First().vcCompilerVersion) { case SourceFile.VCCompilerVersion.vc2003: macros.Add("_MSC_VER=1310"); break; case SourceFile.VCCompilerVersion.vc2005: macros.Add("_MSC_VER=1400"); break; case SourceFile.VCCompilerVersion.vc2008: macros.Add("_MSC_VER=1500"); break; case SourceFile.VCCompilerVersion.vc2010: macros.Add("_MSC_VER=1600"); break; case SourceFile.VCCompilerVersion.vc2012: macros.Add("_MSC_VER=1700"); break; case SourceFile.VCCompilerVersion.vc2013: macros.Add("_MSC_VER=1800"); break; case SourceFile.VCCompilerVersion.vc2015: macros.Add("_MSC_VER=1900"); break; case SourceFile.VCCompilerVersion.vc2017: macros.Add("_MSC_VER=1916"); break; case SourceFile.VCCompilerVersion.vc2019: macros.Add("_MSC_VER=1926"); macros.Add("_MSC_FULL_VER=192628808"); break; } foreach (var file in filesToAnalyze) { macros.UnionWith(file.Macros); } macros.Add("WIN32"); macros.Add("_WIN32"); CPPCheckPluginPackage.Instance.JoinableTaskFactory.Run(async() => { if (await configuredFiles.is64bitConfigurationAsync()) { macros.Add("_M_X64"); macros.Add("_WIN64"); } else { macros.Add("_M_IX86"); } if (await configuredFiles.isDebugConfigurationAsync()) { macros.Add("_DEBUG"); } }); foreach (string macro in macros) { if (!String.IsNullOrEmpty(macro) && !macro.Contains(" ") /* macros with spaces are invalid in VS */) { String macroArgument = " -D" + macro; cppheckargs += macroArgument; } } HashSet <string> macrosToUndefine = new HashSet <string>(); foreach (var file in filesToAnalyze) { macrosToUndefine.UnionWith(file.MacrosToUndefine); } foreach (string macro in macrosToUndefine) { if (!String.IsNullOrEmpty(macro) && !macro.Contains(" ") /* macros with spaces are invalid in VS */) { String macroUndefArgument = " -U" + macro; cppheckargs += macroUndefArgument; } } } else if (!cppheckargs.Contains("--force")) { cppheckargs += " --force"; } return(cppheckargs); }
private async Task checkProjectsAsync(List <Project> projects) { Debug.Assert(projects.Any()); setMenuState(true); List <SourceFilesWithConfiguration> allConfiguredFiles = new List <SourceFilesWithConfiguration>(); foreach (var project in projects) { await JoinableTaskFactory.SwitchToMainThreadAsync(); Configuration config = await getConfigurationAsync(project); if (config == null) { MessageBox.Show("No valid configuration in project " + project.Name); continue; } SourceFilesWithConfiguration sourceFiles = new SourceFilesWithConfiguration(); sourceFiles.Configuration = config; foreach (ProjectItem projectItem in project.ProjectItems) { await scanProjectItemForSourceFilesAsync(projectItem, sourceFiles, config, project); } // Although we're using the same base configuration, it's possible for each file to override that. // Group files into separate configs based on actual parameters. We'll be iterating in reverse order so // reverse the list first to keep the final order the same. List <SourceFile> allSourceFiles = sourceFiles.Files.ToList(); allSourceFiles.Reverse(); while (allSourceFiles.Any()) { SourceFilesWithConfiguration newConfig = new SourceFilesWithConfiguration(); newConfig.Configuration = config; SourceFile templateFile = allSourceFiles.Last(); newConfig.addOrUpdateFile(templateFile); allSourceFiles.RemoveAt(allSourceFiles.Count - 1); for (int i = allSourceFiles.Count - 1; i >= 0; i--) { SourceFile otherFile = allSourceFiles[i]; if (otherFile.Macros.All(templateFile.Macros.Contains) && templateFile.Macros.All(otherFile.Macros.Contains) && otherFile.MacrosToUndefine.All(templateFile.MacrosToUndefine.Contains) && templateFile.MacrosToUndefine.All(otherFile.MacrosToUndefine.Contains) && otherFile.IncludePaths.All(templateFile.IncludePaths.Contains) && templateFile.IncludePaths.All(otherFile.IncludePaths.Contains) && otherFile.ProjectName == templateFile.ProjectName ) { newConfig.addOrUpdateFile(otherFile); allSourceFiles.RemoveAt(i); } } if (newConfig.Any()) { allConfiguredFiles.Add(newConfig); } } } _ = JoinableTaskFactory.RunAsync(async() => { await JoinableTaskFactory.SwitchToMainThreadAsync(); MainToolWindow.Instance.ContentsType = ICodeAnalyzer.AnalysisType.ProjectAnalysis; MainToolWindow.Instance.showIfWindowNotCreated(); }); scanProgressUpdated(-1); runAnalysis(allConfiguredFiles, false); }