Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support running tidy with compilation db #1366

Merged
merged 8 commits into from
Aug 1, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class TidySettingsModel
public string CustomChecks { get; set; } = string.Empty;

public string CustomExecutable { get; set; } = string.Empty;

public string CompilationDatabase { get; set; } = string.Empty;
public bool DetectClangTidyFile { get; set; } = true;

public bool FormatAfterTidy { get; set; } = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class SettingsTooltips
public string PredefinedChecks { get; } = "A list of clang-tidy static analyzer and diagnostics checks from LLVM.";
public string CustomChecks { get; } = "Specify clang-tidy checks to run using the standard tidy syntax. You can use wildcards to match multiple checks, combine them, etc (Eg. \"modernize-*, readability-*\").";
public string CustomExecutableTidy { get; } = "Specify a custom path for \"clang-tidy.exe\" file to run instead of the built-in one (v8.0).";
public string CompilationDatabase{ get; } = "Specify a custom \"compile_commands.json\" file path to use as a source of compilation flags instead of the flags generated by extension.";
public string DetectClangTidyFile { get; } = "Automatically detect the \".clang-tidy\" file and set the \"Use checks from\" option to \"TidyFile\" if the file exists. Otherwise, set the \"Use checks from\" option to \"PredefinedChecks\".";
public string FormatAfterTidy { get; } = "Automatically run clang-format after clang-tidy finished.";
public string TidyOnSave { get; } = "Automatically run clang-tidy when saving the current source file.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class TidySettingsViewModel : CommonSettingsFunctionality, INotifyPropert
private string displayWarning = string.Empty;
private ICommand headerFilterAddDataCommand;
private ICommand customExecutableBrowseCommand;
private ICommand compilationDatabaseBrowseCommand;
private ICommand predefinedChecksSelectCommand;
private ICommand customChecksAddDataCommand;
private ICommand exportTidyConfigCommand;
Expand Down Expand Up @@ -118,6 +119,11 @@ public ICommand CustomExecutableBrowseCommand
get => customExecutableBrowseCommand ?? (customExecutableBrowseCommand = new RelayCommand(() => UpdateCustomExecutable(), () => CanExecute));
}

public ICommand CompilationDatabaseBrowseCommand
{
get => compilationDatabaseBrowseCommand ?? (compilationDatabaseBrowseCommand = new RelayCommand(() => UpdateCompilationDatabase(), () => CanExecute));
}

public ICommand PredefinedChecksSelectCommand
{
get => predefinedChecksSelectCommand ?? (predefinedChecksSelectCommand = new RelayCommand(() => UpdatePredefinedChecks(), () => CanExecute));
Expand Down Expand Up @@ -167,6 +173,16 @@ private void UpdateCustomExecutable()
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TidyModel"));
}

private void UpdateCompilationDatabase()
{
string path = OpenFile(string.Empty, ".json", "Compilation database (*.json)|*.json");
if (string.IsNullOrEmpty(path) == false)
{
tidyModel.CompilationDatabase = path;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("TidyModel"));
}

private void UpdatePredefinedChecks()
{
OpenChecksWindow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

<BitmapImage x:Key="AddInputImage" UriSource="/ClangPowerTools;component/Resources/AddInput.png" />
<BitmapImage x:Key="BrowseImage" UriSource="/ClangPowerTools;component/Resources/Browse.png" />
<BitmapImage x:Key="BrowseFileImage" UriSource="/ClangPowerTools;component/Resources/DetectOnFileIcon.png" />
<BitmapImage x:Key="AccountAvatarIcon" UriSource="/ClangPowerTools;component/Resources/AccountAvatarIcon.png" />
<BitmapImage x:Key="GitHubIcon" UriSource="/ClangPowerTools;component/Resources/GitHubMark.png" />
<BitmapImage x:Key="LogoutIcon" UriSource="/ClangPowerTools;component/Resources/LogoutIcon.png" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ClangPowerTools"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="420"
d:DesignHeight="440"
d:DesignWidth="770"
mc:Ignorable="d">

Expand Down Expand Up @@ -217,8 +217,49 @@
</Button>
</WrapPanel>

<!-- Auto Detect .clang-tidy file -->
<!-- Path to compile database (-p) -->
<WrapPanel Grid.Row="6" Grid.Column="1">
<WrapPanel.ToolTip>
<ToolTip>
<TextBlock
MaxWidth="400"
Text="{Binding Tooltip.CompilationDatabase}"
TextWrapping="Wrap" />
</ToolTip>
</WrapPanel.ToolTip>

<TextBlock
Width="180"
Padding="10"
VerticalAlignment="Center"
FontFamily="SegoeUI"
FontSize="16"
Text="Compilation database" />

<TextBox
Width="450"
Height="30"
Margin="0,0,20,0"
VerticalContentAlignment="Center"
FontFamily="SegoeUI"
FontSize="15"
Text="{Binding TidyModel.CompilationDatabase}" />

<Button
HorizontalAlignment="Left"
Command="{Binding CompilationDatabaseBrowseCommand}"
Style="{StaticResource SettingsButton}">
<Button.Content>
<Image
Source="{StaticResource BrowseFileImage}"
Width="16"
Height="16" />
</Button.Content>
</Button>
</WrapPanel>

<!-- Auto Detect .clang-tidy file -->
<WrapPanel Grid.Row="7" Grid.Column="1">
<WrapPanel.ToolTip>
<ToolTip>
<TextBlock
Expand All @@ -244,7 +285,7 @@
</WrapPanel>

<!-- Format after tidy -->
<WrapPanel Grid.Row="7" Grid.Column="1">
<WrapPanel Grid.Row="8" Grid.Column="1">
<WrapPanel.ToolTip>
<ToolTip>
<TextBlock
Expand All @@ -270,7 +311,7 @@
</WrapPanel>

<!-- Tidy on save -->
<WrapPanel Grid.Row="8" Grid.Column="1">
<WrapPanel Grid.Row="9" Grid.Column="1">
<WrapPanel.ToolTip>
<ToolTip>
<TextBlock
Expand All @@ -296,7 +337,7 @@
</WrapPanel>

<!-- Apply Tidy-Fix -->
<WrapPanel Grid.Row="9"
<WrapPanel Grid.Row="10"
Grid.Column="1">
<WrapPanel.ToolTip>
<ToolTip>
Expand Down Expand Up @@ -330,7 +371,7 @@
</WrapPanel>

<!-- Export tidy config -->
<WrapPanel Grid.Row="10" Grid.Column="1">
<WrapPanel Grid.Row="11" Grid.Column="1">
<WrapPanel.ToolTip>
<ToolTip>
<TextBlock
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private string GetGeneralParameters()

// Get the Clang Flags list
if (!string.IsNullOrWhiteSpace(compilerSettings.CompileFlags))
parameters.Append(GetClangFlags());
parameters.Append(GetClangFlagsOption());

// Get the continue when errors are detected flag
if (compilerSettings.ContinueOnError)
Expand Down Expand Up @@ -138,7 +138,7 @@ private string GetGeneralParameters()
/// Get the clang flags in the power shell script format
/// </summary>
/// <returns>The clang flags</returns>
private string GetClangFlags()
private string GetClangFlagsOption()
{
var compilerSettings = SettingsProvider.CompilerSettingsModel;

Expand Down Expand Up @@ -182,17 +182,21 @@ private string GetTidyParameters()
using FileStream fs = new FileStream(filePath, FileMode.Create);
using StreamWriter sw = new StreamWriter(fs);
sw.Write(text);
parameters = AppendClangTidyType(filePath);
parameters = AppendClangTidyTypeOption(filePath);
}
else
{
parameters = AppendClangTidyType(parameters);
parameters = AppendClangTidyTypeOption(parameters);
}
}

// Get the header filter option
if (null != tidySettings.HeaderFilter && !string.IsNullOrWhiteSpace(tidySettings.HeaderFilter))
parameters += $" {GetHeaderFilters()}";
if (!string.IsNullOrWhiteSpace(tidySettings.HeaderFilter))
parameters += $" {GetHeaderFiltersOption()}";

// Get the compilation database option
if (!string.IsNullOrWhiteSpace(tidySettings.CompilationDatabase))
parameters += $" {GetCompilationDatabaseOption(tidySettings.CompilationDatabase)}";

parameters += $" {ScriptConstants.kParallel}";
return parameters;
Expand All @@ -204,7 +208,7 @@ private string GetTidyParameters()
/// </summary>
/// <param name="aParameters"></param>
/// <returns>The <"aParameters"> value with the clang tidy type with / without the clang tidy config file option attached</returns>
private string AppendClangTidyType(string aParameters)
private string AppendClangTidyTypeOption(string aParameters)
{
return string.Format("{0} '{1}'",
(CommandIds.kTidyFixId == mCommandId ? ScriptConstants.kTidyFix : ScriptConstants.kTidy),
Expand All @@ -216,7 +220,7 @@ private string AppendClangTidyType(string aParameters)
/// Get the header filter option from the Clang Tidy Option page
/// </summary>
/// <returns>Header filter option</returns>
private string GetHeaderFilters()
private string GetHeaderFiltersOption()
{
var tidySettings = SettingsProvider.TidySettingsModel;

Expand Down Expand Up @@ -244,6 +248,15 @@ private string GetTidyChecks(TidySettingsModel tidyModel)
}
}

/// <summary>
/// Get the compilation database file option from the Clang Tidy Option page
/// </summary>
/// <returns>Compilation database file option</returns>
private string GetCompilationDatabaseOption(string compilationDatabase)
{
DirectoryInfo dbPath = new DirectoryInfo(compilationDatabase);
return string.Format("{0} '{1}'", ScriptConstants.kCompilationDatabaseDir, dbPath.Parent.FullName);
}
#endregion


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public class ScriptConstants

public const string kHeaderFilter = "-header-filter";
public const string kTidyFile = ".clang-tidy";
public const string kCompilationDatabaseDir = "-compilation-database-dir";

public const string kClangFormatStyle = "-format-style";

Expand Down
62 changes: 45 additions & 17 deletions ClangPowerTools/ClangPowerToolsShared/Tooling/v1/clang-build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ param( [alias("proj")]
[Parameter(Mandatory=$false, HelpMessage="Enable Clang-Tidy to run on header files")]
[string] $aTidyHeaderFilter

, [alias("compilation-database-dir")]
[Parameter(Mandatory=$false, HelpMessage="Specify a path of a directory where compile_commands.json is located.")]
[string] $aCompilationDatabaseDir

, [alias("format-style")]
[Parameter(Mandatory=$false, HelpMessage="Used with 'tidy-fix'; tells CLANG TIDY-FIX to also format the fixed file(s)")]
[string] $aAfterTidyFixFormatStyle
Expand Down Expand Up @@ -240,12 +244,14 @@ Set-Variable -name kClangTidyFixExportFixes -value "--export-fixes=" -option

Set-Variable -name kClangCompiler -value "clang++.exe" -option Constant

Set-Variable -name kClangTidyFlags -value @("-quiet"
,"--") -option Constant
Set-Variable -name kQuiet -value '-quiet' -option Constant
Set-Variable -name kEndOptionMarker -value "--" -option Constant

Set-Variable -name kClangTidyFlagHeaderFilter -value "-header-filter=" -option Constant
Set-Variable -name kClangTidyFlagChecks -value "-checks=" -option Constant
Set-Variable -name kClangTidyUseFile -value ".clang-tidy" -option Constant
Set-Variable -name kClangTidyFormatStyle -value "-format-style=" -option Constant
Set-Variable -name kClangTidyCompilationDatabaseDir -value "-p=" -option Constant

Set-Variable -name kClangTidyFlagTempFile -value ""

Expand Down Expand Up @@ -826,7 +832,8 @@ Function Get-TidyCallArguments( [Parameter(Mandatory=$false)][string[]] $preproc
, [Parameter(Mandatory=$false)][string[]] $forceIncludeFiles
, [Parameter(Mandatory=$true)][string] $fileToTidy
, [Parameter(Mandatory=$false)][string] $pchFilePath
, [Parameter(Mandatory=$false)][switch] $fix)
, [Parameter(Mandatory=$false)][switch] $fix
, [Parameter(Mandatory=$false)][string] $compilationDatabaseDir)
{
[string[]] $tidyArgs = @()
if ($fix)
Expand Down Expand Up @@ -864,7 +871,21 @@ Function Get-TidyCallArguments( [Parameter(Mandatory=$false)][string[]] $preproc
}
}

$tidyArgs += $kClangTidyFlags
$tidyArgs += $kQuiet
if (![string]::IsNullOrEmpty($compilationDatabaseDir))
{
if ($compilationDatabaseDir -eq '_')
{
$compilationDatabaseDir = Get-SourceDirectory
}
# When passed to cmd.exe the quote cannot be preceded by a backslash or it's escaped
$tidyArgs += "$kClangTidyCompilationDatabaseDir`"$($compilationDatabaseDir.TrimEnd("\"))`""
# When we use compilation database, we don't need to add further args with
# compilation flags
return $tidyArgs
}

$tidyArgs += $kEndOptionMarker

$tidyArgs += Get-ClangIncludeDirectories -includeDirectories $includeDirectories `
-additionalIncludeDirectories $additionalIncludeDirectories
Expand Down Expand Up @@ -900,7 +921,8 @@ Function Get-ExeCallArguments( [Parameter(Mandatory=$false)][string] $pchF
, [Parameter(Mandatory=$false)][string[]] $preprocessorDefinitions
, [Parameter(Mandatory=$false)][string[]] $forceIncludeFiles
, [Parameter(Mandatory=$true) ][string] $currentFile
, [Parameter(Mandatory=$true) ][WorkloadType] $workloadType)
, [Parameter(Mandatory=$true) ][WorkloadType] $workloadType
, [Parameter(Mandatory=$false)][string] $compilationDatabaseDir)
{
switch ($workloadType)
{
Expand All @@ -915,13 +937,15 @@ Function Get-ExeCallArguments( [Parameter(Mandatory=$false)][string] $pchF
-additionalIncludeDirectories $additionalIncludeDirectories `
-forceIncludeFiles $forceIncludeFiles `
-pchFilePath $pchFilePath `
-fileToTidy $currentFile }
-fileToTidy $currentFile `
-compilationDatabaseDir $compilationDatabaseDir}
TidyFix { return Get-TidyCallArguments -preprocessorDefinitions $preprocessorDefinitions `
-includeDirectories $includeDirectories `
-additionalIncludeDirectories $additionalIncludeDirectories `
-forceIncludeFiles $forceIncludeFiles `
-pchFilePath $pchFilePath `
-fileToTidy $currentFile `
-compilationDatabaseDir $compilationDatabaseDir `
-fix}
}
}
Expand Down Expand Up @@ -1005,17 +1029,20 @@ Function Run-ClangJobs( [Parameter(Mandatory=$true)] $clangJobs
[string] $clangConfigContent = ""
if ($job.FilePath -like '*tidy*')
{
# We have to separate Clang args from Tidy args
$splitparams = $job.ArgumentList -split " -- "
$clangConfigContent = $splitparams[1]

# We may have an explicit .clang-tidy check-flag config file to be used
if (![string]::IsNullOrWhiteSpace($job.TidyFlagsTempFile) -and (Test-Path -LiteralPath $job.TidyFlagsTempFile))
if (!($job.ArgumentList -like "$($job.kClangTidyCompilationDatabaseDir)*"))
{
$splitparams[0] += " --config-file=""$($job.TidyFlagsTempFile)"" "
}
# We have to separate Clang args from Tidy args
$splitparams = $job.ArgumentList -split " -- "
$clangConfigContent = $splitparams[1]

$job.ArgumentList = "$($splitparams[0]) -- --config ""$clangConfigFile"""
# We may have an explicit .clang-tidy check-flag config file to be used
if (![string]::IsNullOrWhiteSpace($job.TidyFlagsTempFile) -and (Test-Path -LiteralPath $job.TidyFlagsTempFile))
{
$splitparams[0] += " --config-file=""$($job.TidyFlagsTempFile)"" "
}

$job.ArgumentList = "$($splitparams[0]) -- --config ""$clangConfigFile"""
}
}
else
{
Expand All @@ -1034,7 +1061,6 @@ Function Run-ClangJobs( [Parameter(Mandatory=$true)] $clangJobs
# When PowerShell encounters errors, the first one is handled differently from consecutive ones
# To circumvent this, do not execute the job directly, but execute it via cmd.exe
# See also https://stackoverflow.com/a/35980675

$callOutput = cmd /c "$($job.FilePath) $($job.ArgumentList) 2>&1" | Out-String

$callSuccess = $LASTEXITCODE -eq 0
Expand Down Expand Up @@ -1550,14 +1576,16 @@ Function Process-Project( [Parameter(Mandatory=$true)] [string] $vcxprojPa
-forceIncludeFiles $cppForceIncludes `
-currentFile $cpp `
-includeDirectories $includeDirectories `
-additionalIncludeDirectories $additionalIncludeDirectories
-additionalIncludeDirectories $additionalIncludeDirectories `
-compilationDatabaseDir $aCompilationDatabaseDir

$newJob = New-Object PsObject -Prop @{ 'FilePath' = $exeToCall
; 'WorkingDirectory' = Get-SourceDirectory
; 'ArgumentList' = $exeArgs
; 'File' = $cpp
; 'JobCounter' = 0 <# will be lazy initialized #>
; 'TidyFlagsTempFile' = $kClangTidyFlagTempFile
; 'kClangTidyCompilationDatabaseDir' = $kClangTidyCompilationDatabaseDir
}
$clangJobs += $newJob
}
Expand Down
Loading