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;
            }
        }
Exemple #4
0
        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);
            }
        }
Exemple #5
0
        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);
            }
        }
Exemple #6
0
        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);
        }