Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
georgii-borovinskikh-sonarsource committed Dec 17, 2024
1 parent 698de46 commit 5713ad4
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
using SonarLint.VisualStudio.Integration.Vsix.CFamily.VcxProject;
using static SonarLint.VisualStudio.Integration.Vsix.CFamily.UnitTests.CFamilyTestUtility;
using System.IO.Abstractions;
using SonarLint.VisualStudio.Core.SystemAbstractions;

namespace SonarLint.VisualStudio.Integration.UnitTests.CFamily.VcxProject
{
Expand All @@ -43,18 +44,19 @@ public class FileConfigProviderTests
private FileConfigProvider testSubject;
private const string ClFilePath = "C:\\path\\cl.exe";

private static Mock<IFileSystem> CreateFileSystemWithExistingFile(string fullPath)
private static IFileSystemService CreateFileSystemWithExistingFile(string fullPath)
{
var fileSystem = new Mock<IFileSystem>();
fileSystem.Setup(x => x.File.Exists(fullPath)).Returns(true);
var fileSystem = Substitute.For<IFileSystemService>();
fileSystem.File.Exists(fullPath).Returns(true);
return fileSystem;
}
private static Mock<IFileSystem> CreateFileSystemWithClCompiler() => CreateFileSystemWithExistingFile(ClFilePath);
private static IFileSystemService CreateFileSystemWithClCompiler() => CreateFileSystemWithExistingFile(ClFilePath);

[TestMethod]
public void MefCtor_CheckIsExported() =>
MefTestHelpers.CheckTypeCanBeImported<FileConfigProvider, IFileConfigProvider>(
MefTestHelpers.CreateExport<IFileInSolutionIndicator>(),
MefTestHelpers.CreateExport<IFileSystemService>(),
MefTestHelpers.CreateExport<ILogger>(),
MefTestHelpers.CreateExport<IThreadHandling>(),
MefTestHelpers.CreateExport<IVsUIServiceOperation>());
Expand All @@ -70,10 +72,7 @@ public void TestInitialize()
dte = Substitute.For<DTE2>();
uiServiceOperation = CreateDefaultUiServiceOperation(dte);

testSubject = new FileConfigProvider(uiServiceOperation, fileInSolutionIndicator, logger, new NoOpThreadHandler())
{
FileSystem = CreateFileSystemWithClCompiler().Object
};
testSubject = new FileConfigProvider(uiServiceOperation, fileInSolutionIndicator, CreateFileSystemWithClCompiler(), logger, new NoOpThreadHandler());
}

private static IFileInSolutionIndicator CreateDefaultFileInSolutionIndicator()
Expand Down
53 changes: 25 additions & 28 deletions src/Integration.Vsix/CFamily/VcxProject/FileConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,97 +29,95 @@ namespace SonarLint.VisualStudio.Integration.Vsix.CFamily.VcxProject
{
internal class FileConfig : IFileConfig
{
private static string GetCompilerPathFromClCompilerPath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem)
private static bool TryGetCompilerPathFromClCompilerPath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem, out string compilerPath)
{
var compilerPath = vcConfig.GetEvaluatedPropertyValue("ClCompilerPath");
compilerPath = vcConfig.GetEvaluatedPropertyValue("ClCompilerPath");
if (string.IsNullOrEmpty(compilerPath))
{
logger.WriteLine("\"ClCompilerPath\" was not found.");
return null;
return false;
}

if (!fileSystem.File.Exists(compilerPath))
{
logger.WriteLine($"Compiler path \"{compilerPath}\" does not exist.");
return null;
return false;
}

return compilerPath;
return true;
}

private static string GetCompilerPathFromExecutablePath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem)
private static bool TryGetCompilerPathFromExecutablePath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem, out string compilerPath)
{
compilerPath = default;
var executablePath = vcConfig.GetEvaluatedPropertyValue("ExecutablePath");
if (string.IsNullOrEmpty(executablePath))
{
logger.WriteLine("\"ExecutablePath\" was not found.");
return null;
return false;
}

var toolExe = vcConfig.GetEvaluatedPropertyValue("CLToolExe");
if (string.IsNullOrEmpty(toolExe))
{
logger.WriteLine("\"CLToolExe\" was not found.");
return null;
return false;
}

foreach (var path in executablePath.Split(';'))
{
var compilerPath = Path.Combine(path, toolExe);
compilerPath = Path.Combine(path, toolExe);
if (fileSystem.File.Exists(compilerPath))
{
return compilerPath;
return true;
}
else
{
logger.WriteLine($"Compiler path \"{compilerPath}\" does not exist.");
}
}

return null;
return false;
}

private static string GetCompilerPathFromVCExecutablePath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem)
private static bool TryGetCompilerPathFromVCExecutablePath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem, out string compilerPath)
{
var platform = ((VCPlatform)vcConfig.Platform).Name.Contains("64") ? "x64" : "x86";
var exeVar = "VC_ExecutablePath_" + platform;
var compilerPath = Path.Combine(vcConfig.GetEvaluatedPropertyValue(exeVar), "cl.exe");
compilerPath = Path.Combine(vcConfig.GetEvaluatedPropertyValue(exeVar), "cl.exe");
if (fileSystem.File.Exists(compilerPath))
{
return compilerPath;
return true;
}
else
{
logger.WriteLine($"Compiler path \"{compilerPath}\" does not exist.");
return null;
return false;
}
}

private static string GetCompilerPath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem)
private static bool GetCompilerPath(ILogger logger, VCConfiguration vcConfig, IFileSystem fileSystem, out string compilerPath)
{
var compilerPath = GetCompilerPathFromClCompilerPath(logger, vcConfig, fileSystem);
if (!string.IsNullOrEmpty(compilerPath))
if (TryGetCompilerPathFromClCompilerPath(logger, vcConfig, fileSystem, out compilerPath))
{
return compilerPath;
return true;
}

// Fallback to ExecutablePath and CLToolExe
compilerPath = GetCompilerPathFromExecutablePath(logger, vcConfig, fileSystem);
if (!string.IsNullOrEmpty(compilerPath))
if (TryGetCompilerPathFromExecutablePath(logger, vcConfig, fileSystem, out compilerPath))
{
return compilerPath;
return true;
}

// Fallback to VC_ExecutablePath, which is used to be used in VS2017 toolchains
// because ClCompilerPath was not available
compilerPath = GetCompilerPathFromVCExecutablePath(logger, vcConfig, fileSystem);
if (!string.IsNullOrEmpty(compilerPath))
if (TryGetCompilerPathFromVCExecutablePath(logger, vcConfig, fileSystem, out compilerPath))
{
return compilerPath;
return true;
}

logger.WriteLine("Compiler is not supported.");
return null;
return false;
}

[ExcludeFromCodeCoverage]
Expand All @@ -143,8 +141,7 @@ public static FileConfig TryGet(ILogger logger, ProjectItem dteProjectItem, stri
bool isHeaderFile = vcFile.ItemType == "ClInclude";
CmdBuilder cmdBuilder = new CmdBuilder(isHeaderFile);

var compilerPath = GetCompilerPath(logger, vcConfig, fileSystem);
if (string.IsNullOrEmpty(compilerPath))
if (!GetCompilerPath(logger, vcConfig, fileSystem, out var compilerPath))
{
return null;
}
Expand Down
5 changes: 3 additions & 2 deletions src/Integration.Vsix/CFamily/VcxProject/FileConfigProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using SonarLint.VisualStudio.Infrastructure.VS;
using SonarLint.VisualStudio.Integration.Helpers;
using System.IO.Abstractions;
using SonarLint.VisualStudio.Core.SystemAbstractions;

namespace SonarLint.VisualStudio.Integration.Vsix.CFamily.VcxProject
{
Expand All @@ -42,11 +43,11 @@ internal interface IFileConfigProvider
internal class FileConfigProvider(
IVsUIServiceOperation uiServiceOperation,
IFileInSolutionIndicator fileInSolutionIndicator,
IFileSystemService fileSystem,
ILogger logger,
IThreadHandling threadHandling) : IFileConfigProvider
{
private static readonly NoOpLogger noOpLogger = new NoOpLogger();
public IFileSystem FileSystem { get; set; } = new FileSystem();

public IFileConfig Get(string analyzedFilePath, CFamilyAnalyzerOptions analyzerOptions)
{
Expand Down Expand Up @@ -77,7 +78,7 @@ private FileConfig GetInternal(string analyzedFilePath, DTE2 dte, ILogger analys
// Note: if the C++ tools are not installed then it's likely an exception will be thrown when
// the framework tries to JIT-compile the TryGet method (since it won't be able to find the MS.VS.VCProjectEngine
// types).
return FileConfig.TryGet(analysisLogger, projectItem, analyzedFilePath, FileSystem);
return FileConfig.TryGet(analysisLogger, projectItem, analyzedFilePath, fileSystem);
}
catch (Exception ex) when (!Microsoft.VisualStudio.ErrorHandler.IsCriticalException(ex))
{
Expand Down

0 comments on commit 5713ad4

Please sign in to comment.