private void runSavedFileAnalysis(SourceFile file, Configuration currentConfig, OutputWindowPane outputPane) { Debug.Assert(currentConfig != null); var configuredFiles = new ConfiguredFiles(); configuredFiles.Files = new List<SourceFile> {file}; configuredFiles.Configuration = currentConfig; runAnalysis(new List<ConfiguredFiles> {configuredFiles}, outputPane, true); }
private void documentSavedSync(Document document) { JoinableTaskFactory.Run(async() => { await JoinableTaskFactory.SwitchToMainThreadAsync(); if (document == null || document.Language != "C/C++") { return; } if (Settings.Default.CheckSavedFilesHasValue && Settings.Default.CheckSavedFiles == false) { return; } if (document.ActiveWindow == null) { // We get here when new files are being created and added to the project and // then trying to obtain document.ProjectItem yields an exception. Will just skip this. return; } try { var kind = document.ProjectItem.ContainingProject.Kind; if (!isVisualCppProjectKind(document.ProjectItem.ContainingProject.Kind)) { return; } Configuration currentConfig = null; try { currentConfig = document.ProjectItem.ConfigurationManager.ActiveConfiguration; } catch (Exception) { currentConfig = null; } if (currentConfig == null) { MessageBox.Show("Cannot perform check - no valid configuration selected", "Cppcheck error"); return; } //dynamic project = document.ProjectItem.ContainingProject.Object; Project project = document.ProjectItem.ContainingProject; SourceFile sourceForAnalysis = await createSourceFileAsync(document.FullName, currentConfig, project); if (sourceForAnalysis == null) { return; } if (!Settings.Default.CheckSavedFilesHasValue) { askCheckSavedFiles(); if (!Settings.Default.CheckSavedFiles) { return; } } MainToolWindow.Instance.showIfWindowNotCreated(); MainToolWindow.Instance.ContentsType = ICodeAnalyzer.AnalysisType.DocumentSavedAnalysis; runSavedFileAnalysis(sourceForAnalysis, currentConfig); } catch (Exception ex) { if (_outputPane != null) { _outputPane.Clear(); _ = AddTextToOutputWindowAsync("Exception occurred in cppcheck add-in: " + ex.Message); } DebugTracer.Trace(ex); } }); }
SourceFile createSourceFile(string filePath, Configuration targetConfig, dynamic project) { Debug.Assert(isVisualCppProject((object)project)); try { var configurationName = targetConfig.ConfigurationName; dynamic config = project.Configurations.Item(configurationName); String toolSetName = config.PlatformToolsetShortName; if (String.IsNullOrEmpty(toolSetName)) toolSetName = config.PlatformToolsetFriendlyName; String projectDirectory = project.ProjectDirectory; String projectName = project.Name; SourceFile sourceForAnalysis = new SourceFile(filePath, projectDirectory, projectName, toolSetName); dynamic toolsCollection = config.Tools; foreach (var tool in toolsCollection) { // Project-specific includes Type toolType = tool.GetType(); var compilerToolInterface = toolType.GetInterface("Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool"); if (compilerToolInterface != null) { String includes = tool.FullIncludePath; String definitions = tool.PreprocessorDefinitions; String macrosToUndefine = tool.UndefinePreprocessorDefinitions; String[] includePaths = includes.Split(';'); for (int i = 0; i < includePaths.Length; ++i) includePaths[i] = config.Evaluate(includePaths[i]); sourceForAnalysis.addIncludePaths(includePaths); sourceForAnalysis.addMacros(definitions.Split(';')); sourceForAnalysis.addMacrosToUndefine(macrosToUndefine.Split(';')); break; } } return sourceForAnalysis; } catch (System.Exception ex) { DebugTracer.Trace(ex); return null; } }
private void documentSaved(Document document) { if (document == null || document.Language != "C/C++") { return; } if (Properties.Settings.Default.CheckSavedFilesHasValue && Properties.Settings.Default.CheckSavedFiles == false) { return; } if (document.ActiveWindow == null) { // We get here when new files are being created and added to the project and // then trying to obtain document.ProjectItem yields an exception. Will just skip this. return; } try { dynamic project = document.ProjectItem.ContainingProject.Object; if (!isVisualCppProject(project)) { return; } Configuration currentConfig = null; try { currentConfig = document.ProjectItem.ConfigurationManager.ActiveConfiguration; } catch (Exception) { currentConfig = null; } if (currentConfig == null) { MessageBox.Show("Cannot perform check - no valid configuration selected", "Cppcheck error"); return; } SourceFile sourceForAnalysis = createSourceFile(document.FullName, currentConfig, project); if (sourceForAnalysis == null) { return; } if (!Properties.Settings.Default.CheckSavedFilesHasValue) { askCheckSavedFiles(); if (!Properties.Settings.Default.CheckSavedFiles) { return; } } MainToolWindow.Instance.showIfWindowNotCreated(); MainToolWindow.Instance.ContentsType = ICodeAnalyzer.AnalysisType.DocumentSavedAnalysis; runSavedFileAnalysis(sourceForAnalysis, currentConfig, _outputPane); } catch (System.Exception ex) { if (_outputPane != null) { _outputPane.Clear(); _outputPane.OutputString("Exception occurred in cppcheck add-in: " + ex.Message); } DebugTracer.Trace(ex); } }
private static async Task <SourceFile> createSourceFileAsync(string filePath, Configuration targetConfig, dynamic project) { // TODO: //Debug.Assert(isVisualCppProject((object)project)); try { await Instance.JoinableTaskFactory.SwitchToMainThreadAsync(); String configurationName = targetConfig.ConfigurationName; dynamic config = project.Configurations.Item(configurationName); String toolSetName = "Win32"; if (config == null) { String targetConfigName = string.Format("{0}|{1}", configurationName, targetConfig.PlatformName); foreach (dynamic cfg in project.Configurations) { String configName = cfg.Name.ToString() as String; if (configName == targetConfigName) { config = cfg; toolSetName = targetConfig.PlatformName; break; } } } else { toolSetName = config.PlatformToolsetShortName; } if (String.IsNullOrEmpty(toolSetName)) { toolSetName = config.PlatformToolsetFriendlyName; } String projectDirectory = project.ProjectDirectory; String projectName = project.Name; SourceFile sourceForAnalysis = new SourceFile(filePath, projectDirectory, projectName, toolSetName); dynamic toolsCollection = config.Tools; foreach (var tool in toolsCollection) { // Project-specific includes if (implementsInterface(tool, "Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool")) { String includes = tool.FullIncludePath; String definitions = tool.PreprocessorDefinitions; String macrosToUndefine = tool.UndefinePreprocessorDefinitions; String[] includePaths = includes.Split(';'); for (int i = 0; i < includePaths.Length; ++i) { includePaths[i] = Environment.ExpandEnvironmentVariables(config.Evaluate(includePaths[i])); } ; sourceForAnalysis.addIncludePaths(includePaths); sourceForAnalysis.addMacros(definitions.Split(';')); sourceForAnalysis.addMacrosToUndefine(macrosToUndefine.Split(';')); break; } } return(sourceForAnalysis); } catch (Exception ex) { DebugTracer.Trace(ex); return(null); } }
private async Task <List <ConfiguredFiles> > getActiveSelectionsAsync() { await _instance.JoinableTaskFactory.SwitchToMainThreadAsync(); Dictionary <Project, ConfiguredFiles> confMap = new Dictionary <Project, ConfiguredFiles>(); foreach (SelectedItem selItem in _dte.SelectedItems) { Project project = null; if (project == null && selItem.ProjectItem != null) { project = selItem.ProjectItem.ContainingProject; } if (project == null) { project = selItem.Project; } if (project == null || !isVisualCppProject(project.Kind)) { continue; } Configuration configuration = await getConfigurationAsync(project); if (!confMap.ContainsKey(project)) { // create new Map key entry for project ConfiguredFiles configuredFiles = new ConfiguredFiles(); confMap.Add(project, configuredFiles); configuredFiles.Files = new List <SourceFile>(); configuredFiles.Configuration = configuration; } ConfiguredFiles currentConfiguredFiles = confMap[project]; if (currentConfiguredFiles == null) { continue; } if (selItem.ProjectItem == null) { // project selected List <SourceFile> projectSourceFileList = await getProjectFilesAsync(project, configuration); foreach (SourceFile projectSourceFile in projectSourceFileList) { addEntry(currentConfiguredFiles, projectSourceFileList, project); } } else { dynamic projectItem = selItem.ProjectItem.Object; if (isFilter(projectItem)) { List <SourceFile> sourceFileList = new List <SourceFile>(); scanFilter(projectItem, sourceFileList, currentConfiguredFiles, configuration, project); addEntry(currentConfiguredFiles, sourceFileList, project); } else if (isCppFile(projectItem)) { dynamic file = selItem.ProjectItem.Object; // non project selected if (file != null) { // document selected SourceFile sourceFile = await createSourceFileAsync(file.FullPath, configuration, project.Object); addEntry(currentConfiguredFiles, sourceFile, project); } } } } List <ConfiguredFiles> configuredFilesList = new List <ConfiguredFiles>(); foreach (ConfiguredFiles configuredFiles in confMap.Values) { if (configuredFiles.Files.Any()) { configuredFilesList.Add(configuredFiles); } } return(configuredFilesList); }
private static async Task <SourceFile> createSourceFileAsync(ProjectItem item) { try { await Instance.JoinableTaskFactory.SwitchToMainThreadAsync(); Debug.Assert(isVisualCppProjectKind(item.ContainingProject.Kind)); VCFile vcFile = item.Object as VCFile; VCProject vcProject = item.ContainingProject.Object as VCProject; VCConfiguration vcconfig = vcProject.ActiveConfiguration; VCFileConfiguration fileConfig = vcFile.FileConfigurations.Item(vcconfig.Name); string toolSetName = ((dynamic)vcconfig).PlatformToolsetFriendlyName; string projectDirectory = vcProject.ProjectDirectory; string projectName = vcProject.Name; SourceFile sourceForAnalysis = null; if (item.FileCount > 0) { bool bInheritDefs = true, bInheritUndefs = true; string[] includePaths = { }; // Do the file-level first in case it disables inheritance. Include files don't have file-level config. if (implementsInterface(fileConfig.Tool, "Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool")) { sourceForAnalysis = new SourceFile(item.FileNames[1], projectDirectory, projectName, toolSetName); includePaths = fileConfig.Tool.FullIncludePath.Split(';'); // Other details may be gathered from the file, project or any inherited property sheets. recursiveAddToolDetails(sourceForAnalysis, vcconfig, fileConfig.Tool, null, ref bInheritDefs, ref bInheritUndefs); } // Now get the full include path VCCLCompilerTool projectTool = (VCCLCompilerTool)vcconfig.Tools.Item("VCCLCompilerTool"); if (projectTool != null && implementsInterface(projectTool, "Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool")) { if (sourceForAnalysis == null) { sourceForAnalysis = new SourceFile(item.FileNames[1], projectDirectory, projectName, toolSetName); includePaths = projectTool.FullIncludePath.Split(';'); } // Take the full include path from file level, which is already fully resolved. for (int i = 0; i < includePaths.Length; ++i) { includePaths[i] = Environment.ExpandEnvironmentVariables(vcconfig.Evaluate(includePaths[i])); } sourceForAnalysis.addIncludePaths(includePaths); recursiveAddToolDetails(sourceForAnalysis, vcconfig, projectTool, vcconfig.PropertySheets, ref bInheritDefs, ref bInheritUndefs); } } return(sourceForAnalysis); } catch (Exception ex) { DebugTracer.Trace(ex); return(null); } }
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); }