dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.06k stars 4.04k forks source link

GetProjectFileInfosAsync throws when it tries to delete MSBuild property from import file #31011

Open AArnott opened 6 years ago

AArnott commented 6 years ago

The ProjectFile.GetProjectFileInfosAsync method rotates through setting a TargetFramework property for each value in TargetFrameworks for a project. But when the project imports MSBuild.Sdk.Extras (or otherwise imports a .targets file at the end of the project file that re-sets the <TargetFramework> property), this method throws an exception by calling into MSBuild asking it to delete the property as it is defined in the .targets file instead of the property set in the root project file itself.

System.InvalidOperationException HResult=0x80131509 Message=Cannot modify an evaluated object originating in an imported file "C:\Users\andarno.nuget\packages\msbuild.sdk.extras\1.5.4\build\MSBuild.Sdk.Extras.Core.targets". Source=Microsoft.Build StackTrace: at Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(String resourceName, Object[] args) in /_/src/Shared/ErrorUtilities.cs:line 304

    Microsoft.Build.dll!Microsoft.Build.Shared.ErrorUtilities.ThrowInvalidOperation(string resourceName, object[] args) Line 304    C#
    Microsoft.Build.dll!Microsoft.Build.Shared.ErrorUtilities.VerifyThrowInvalidOperation(bool condition, string resourceName, object arg0) Line 347    C#
    Microsoft.Build.dll!Microsoft.Build.Evaluation.Project.RemoveProperty(Microsoft.Build.Evaluation.ProjectProperty property) Line 1965    C#
>   Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.ProjectFile.GetProjectFileInfosAsync(System.Threading.CancellationToken cancellationToken) Line 78 C#
    [Resuming Async Method] 
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()    Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0() Unknown
    mscorlib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0()   Unknown
    mscorlib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining, ref System.Threading.Tasks.Task currentTask)    Unknown
    mscorlib.dll!System.Threading.Tasks.Task.FinishContinuations()  Unknown
    mscorlib.dll!System.Threading.Tasks.Task<System.__Canon>.TrySetResult(System.__Canon result)    Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<Microsoft.CodeAnalysis.MSBuild.ProjectFileInfo>.SetResult(Microsoft.CodeAnalysis.MSBuild.ProjectFileInfo result)    Unknown
    Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.ProjectFile.BuildProjectFileInfoAsync(System.Threading.CancellationToken cancellationToken) Line 104   C#
    [Resuming Async Method] 
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()    Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0() Unknown
    mscorlib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0()   Unknown
    mscorlib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining, ref System.Threading.Tasks.Task currentTask)    Unknown
    mscorlib.dll!System.Threading.Tasks.Task.FinishContinuations()  Unknown
    mscorlib.dll!System.Threading.Tasks.Task<System.__Canon>.TrySetResult(System.__Canon result)    Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<Microsoft.Build.Execution.ProjectInstance>.SetResult(Microsoft.Build.Execution.ProjectInstance result)  Unknown
    Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.Build.ProjectBuildManager.BuildProjectAsync(Microsoft.Build.Evaluation.Project project, string[] targets, Microsoft.CodeAnalysis.MSBuild.Logging.DiagnosticLog log, System.Threading.CancellationToken cancellationToken) Line 229 C#
    [Resuming Async Method] 
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()    Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0() Unknown
    mscorlib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0()   Unknown
    mscorlib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining, ref System.Threading.Tasks.Task currentTask)    Unknown
    mscorlib.dll!System.Threading.Tasks.Task.FinishContinuations()  Unknown
    mscorlib.dll!System.Threading.Tasks.Task<System.__Canon>.TrySetResult(System.__Canon result)    Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<Microsoft.Build.Execution.BuildResult>.SetResult(Microsoft.Build.Execution.BuildResult result)  Unknown
    Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.Build.ProjectBuildManager.BuildAsync(Microsoft.Build.Execution.BuildRequestData requestData, System.Threading.CancellationToken cancellationToken) Line 241    C#
    [Resuming Async Method] 
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()    Unknown
    mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0() Unknown
    mscorlib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0()   Unknown
    mscorlib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining, ref System.Threading.Tasks.Task currentTask)    Unknown
    mscorlib.dll!System.Threading.Tasks.Task.FinishContinuations()  Unknown
    mscorlib.dll!System.Threading.Tasks.Task<System.__Canon>.TrySetResult(System.__Canon result)    Unknown
    mscorlib.dll!System.Threading.Tasks.TaskCompletionSource<System.__Canon>.TrySetResult(System.__Canon result)    Unknown
    Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.Build.ProjectBuildManager.BuildAsync.AnonymousMethod__1(Microsoft.Build.Execution.BuildSubmission sub) Line 273    C#
    Microsoft.Build.dll!Microsoft.Build.Shared.ThreadPoolExtensions.QueueThreadPoolWorkItemWithCulture.AnonymousMethod__0(object state) Line 46 C#
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)   Unknown
    mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()  Unknown
    mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()    Unknown
    [Async Call Stack]  
    [Async] Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.DoOperationAndReportProgressAsync<System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.MSBuild.ProjectFileInfo>>(Microsoft.CodeAnalysis.MSBuild.ProjectLoadOperation operation, string projectPath, string targetFramework, System.Func<System.Threading.Tasks.Task<System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.MSBuild.ProjectFileInfo>>> doFunc) Line 114   C#
    [Async] Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectFileInfosAsync(string projectPath, Microsoft.CodeAnalysis.MSBuild.DiagnosticReportingOptions reportingOptions, System.Threading.CancellationToken cancellationToken) Line 201   C#
    [Async] Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadProjectInfosFromPathAsync(string projectPath, Microsoft.CodeAnalysis.MSBuild.DiagnosticReportingOptions reportingOptions, System.Threading.CancellationToken cancellationToken) Line 235   C#
    [Async] Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.Worker.LoadAsync(System.Threading.CancellationToken cancellationToken) Line 155   C#
    [Async] Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.LoadSolutionInfoAsync(string solutionFilePath, System.IProgress<Microsoft.CodeAnalysis.MSBuild.ProjectLoadProgress> progress, System.Threading.CancellationToken cancellationToken) Line 199  C#
    [Async] Microsoft.CodeAnalysis.Workspaces.MSBuild.dll!Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.OpenSolutionAsync(string solutionFilePath, System.IProgress<Microsoft.CodeAnalysis.MSBuild.ProjectLoadProgress> progress, System.Threading.CancellationToken cancellationToken) Line 183  C#
danstur commented 5 years ago

@jinujoseph @AArnott Is there any workaround for this? (apart from "don't use the MSBuild.Sdk.Extras project") This bug currently means that we can't run our custom analyzers on any solution (not just the one project) that includes a WPF project that uses MSBuild.Sdk.Extras.

It'd be alright if we could somehow exclude the one project from being analysed.

jinujoseph commented 5 years ago

Talking with @ DustinCampbell , unfortunately doesn't seem to have any good workaround. It looks like we’d need to make a change in MSBuildWorkspace to avoid deleting the property under certain conditions (or just catch the exception and handle it gracefully):

https://github.com/dotnet/roslyn/blob/master/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/ProjectFile.cs#L78

pistonexia commented 5 years ago

I encountered the same situation (with MSBuild.Sdk.Extras). Wonder if any progress has been made on this matter?

danstur commented 5 years ago

@pistonexia I simply created a fork of the MSBuild.Sdk.Extras package that doesn't rewrite the target frameworks. It's completely trivial assuming you only use lowercase target frameworks.

KirillOsenkov commented 4 years ago

Need to check but I have a hunch that https://github.com/dotnet/roslyn/pull/39748 might fix this issue.