diff --git a/src/dotnet/ReSharperPlugin.DotNetDisassembler.Tests/JitCodegenProviderTests.cs b/src/dotnet/ReSharperPlugin.DotNetDisassembler.Tests/JitCodegenProviderTests.cs
index 510bbe1..35657ad 100644
--- a/src/dotnet/ReSharperPlugin.DotNetDisassembler.Tests/JitCodegenProviderTests.cs
+++ b/src/dotnet/ReSharperPlugin.DotNetDisassembler.Tests/JitCodegenProviderTests.cs
@@ -286,6 +286,60 @@ public async Task GetJitCodegen_WithProperty_ShouldReturnAssemblyCode()
"Output should contain method or class name");
}
+ // https://github.com/JetBrains/dotnet-disassembler-plugin/issues/13
+ // dotnet build ignores MSBuild properties in platform-conditional PropertyGroups
+ [Test]
+ public async Task GetJitCodegen_WithPlatformConditionalProperties_ShouldBuildSuccessfully()
+ {
+ // Arrange
+ var arch = RuntimePlatformUtils.GetCurrentArch();
+
+ File.WriteAllText(_testProjectFile, $@"
+
+
+ Exe
+ net9.0
+ false
+ Release;Debug
+ {arch}
+
+
+ true
+
+
+ true
+
+ ");
+
+ var programFile = Path.Combine(_testProjectDir, "Program.cs");
+ File.WriteAllText(programFile, @"
+ using System;
+
+ public class TestClass
+ {
+ public static void Main()
+ {
+ Console.WriteLine(Add(2, 3));
+ }
+
+ public static unsafe int Add(int a, int b)
+ {
+ int result = a + b;
+ int* p = &result;
+ return *p;
+ }
+ }");
+
+ var projectContext = CreateProjectContext(platform: arch);
+ var config = new JitDisasmConfiguration();
+
+ // Act
+ var result = await _jitCodegenProvider.GetJitCodegenAsync(_addMethodTarget, projectContext, config, CancellationToken.None);
+
+ // Assert
+ Assert.True(result.Succeed, $"Error: {result.FailValue?.Code}\nDetails: {result.FailValue?.Details}");
+ }
+
[Test]
public async Task GetJitCodegen_WithMissingMethod_ShouldReturnEmptyOrMinimalOutput()
{
@@ -305,7 +359,7 @@ public async Task GetJitCodegen_WithMissingMethod_ShouldReturnEmptyOrMinimalOutp
"Expected empty or minimal output for missing method");
}
- private JitDisasmProjectContext CreateProjectContext([CanBeNull] JitDisasmTargetFramework tfm = null)
+ private JitDisasmProjectContext CreateProjectContext([CanBeNull] JitDisasmTargetFramework tfm = null, [CanBeNull] string platform = null)
{
var projectRoot = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "..", "..", ".."));
var dotnetCmd = Path.Combine(projectRoot, "dotnet.cmd");
@@ -325,6 +379,7 @@ private JitDisasmProjectContext CreateProjectContext([CanBeNull] JitDisasmTarget
ProjectFilePath: _testProjectFile,
ProjectDirectory: _testProjectDir,
AssemblyName: "TestProject",
- DotNetCliExePath: dotnetExe);
+ DotNetCliExePath: dotnetExe,
+ Platform: platform);
}
}
diff --git a/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitCodegenProvider.cs b/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitCodegenProvider.cs
index 19663da..a6faa0a 100644
--- a/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitCodegenProvider.cs
+++ b/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitCodegenProvider.cs
@@ -65,6 +65,8 @@ public async Task> GetJitCodegenAsync(DisasmTarg
? ""
: $"-f {tfm}";
+ string platformPart = GetPlatformArg(projectContext);
+
// Some things can't be set in CLI e.g. appending to DefineConstants
var tmpProps = Path.GetTempFileName() + ".props";
File.WriteAllText(tmpProps, $"""
@@ -81,7 +83,7 @@ public async Task> GetJitCodegenAsync(DisasmTarg
logger.LogInformation("Running dotnet publish for reload");
string dotnetPublishArgs =
- $"publish {tfmPart} -r {runtimeId} -c Release -o \"{resultOutDir}\" --self-contained true /p:PublishTrimmed=false /p:PublishSingleFile=false /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\" /p:WarningLevel=0 /p:TreatWarningsAsErrors=false -v:q";
+ $"publish {tfmPart} -r {runtimeId} -c Release -o \"{resultOutDir}\" --self-contained true {platformPart} /p:PublishTrimmed=false /p:PublishSingleFile=false /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\" /p:WarningLevel=0 /p:TreatWarningsAsErrors=false -v:q";
publishResult = await ProcessUtils.RunProcessAsync(dotnetCliExePath, dotnetPublishArgs, null, projectDirPath,
LogProcessOutput, cancellationToken: cancellationToken);
@@ -98,6 +100,7 @@ public async Task> GetJitCodegenAsync(DisasmTarg
}
string dotnetBuildArgs = $"build {tfmPart} -c Release -o \"{resultOutDir}\" --no-self-contained " +
+ $"{platformPart} " +
"/p:RuntimeIdentifier=\"\" " +
"/p:RuntimeIdentifiers=\"\" " +
"/p:WarningLevel=0 " +
@@ -364,7 +367,9 @@ private async Task> GetJitCodegenInternalAsync(D
else if (configuration.IsNonCustomNativeAotMode())
{
logger.LogDebug("Compiling for NativeAOT (.NET 8.0+ is required) ...");
-
+
+ string platformPart = GetPlatformArg(projectContext);
+
// For non-custom NativeAOT we need to use dotnet publish + with custom IlcArgs
// namely, we need to re-direct jit's output to a file (JitStdOutFile).
@@ -410,7 +415,7 @@ private async Task> GetJitCodegenInternalAsync(D
// NOTE: CustomBeforeDirectoryBuildProps is probably not a good idea to overwrite, but we need to pass IlcArgs somehow
string dotnetPublishArgs =
$"publish {tfmPart} -r {runtimeId} -c Release" +
- $" /p:PublishAot=true /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\"" +
+ $" {platformPart} /p:PublishAot=true /p:CustomBeforeDirectoryBuildProps=\"{tmpProps}\"" +
$" /p:WarningLevel=0 /p:TreatWarningsAsErrors=false -v:q";
var publishResult = await ProcessUtils.RunProcessAsync(dotnetCliExePath, dotnetPublishArgs, null,
@@ -571,6 +576,9 @@ private async Task> GetJitCodegenInternalAsync(D
}
}
+ private static string GetPlatformArg(JitDisasmProjectContext projectContext) =>
+ string.IsNullOrEmpty(projectContext.Platform) ? "" : $"/p:Platform=\"{projectContext.Platform}\"";
+
private void LogProcessOutput(bool isError, string message)
{
if (isError)
diff --git a/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitDisasmProjectContext.cs b/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitDisasmProjectContext.cs
index bd4b58a..119f6bf 100644
--- a/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitDisasmProjectContext.cs
+++ b/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/JitDisasmProjectContext.cs
@@ -10,7 +10,8 @@ public record JitDisasmProjectContext(
string ProjectFilePath,
string ProjectDirectory,
[CanBeNull] string AssemblyName,
- string DotNetCliExePath)
+ string DotNetCliExePath,
+ [CanBeNull] string Platform = null)
{
public Result Validate()
{
diff --git a/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasmAdapters/JitDisasmProjectContextFactory.cs b/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasmAdapters/JitDisasmProjectContextFactory.cs
index 385b6a1..2a553ce 100644
--- a/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasmAdapters/JitDisasmProjectContextFactory.cs
+++ b/src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasmAdapters/JitDisasmProjectContextFactory.cs
@@ -1,5 +1,7 @@
using JetBrains.Application.Threading;
using JetBrains.ProjectModel;
+using JetBrains.ProjectModel.MSBuild;
+using JetBrains.ProjectModel.Properties;
using JetBrains.ReSharper.Feature.Services.Protocol;
using JetBrains.Rider.Model;
using JetBrains.Util;
@@ -19,6 +21,7 @@ public static JitDisasmProjectContext Create(IProject project)
var outputDirectory = tfmId != null ? project.GetOutputDirectory(tfmId) : null;
var assemblyName = tfmId != null ? project.GetOutputAssemblyName(tfmId) : null;
var dotNetCliExePath = GetDotNetCliExePath(solution);
+ var platform = project.GetUniqueRequestedProjectProperty(MSBuildProjectUtil.PlatformTargetProperty);
return new JitDisasmProjectContext(
Sdk: sdk,
@@ -27,7 +30,8 @@ public static JitDisasmProjectContext Create(IProject project)
ProjectFilePath: project.ProjectFileLocation?.FullPath,
ProjectDirectory: project.Location?.FullPath,
AssemblyName: assemblyName,
- DotNetCliExePath: dotNetCliExePath);
+ DotNetCliExePath: dotNetCliExePath,
+ Platform: platform);
});
}