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
18.97k stars 4.03k forks source link

OpenProjectAsync throws exception when opening a project. CSharpCompilerInputs returns duplicate argument (/ruleset) after compilation. #8408

Closed PaulEremeeff closed 1 year ago

PaulEremeeff commented 8 years ago

I was not able to reproduce the issue on a synthetic project, but it can be steadily reproduced on 'Orleans' framework sources (Windows 10, MSBuild 14).

The code to reproduce as follows:

            MSBuildWorkspace workspace = MSBuildWorkspace.Create(properties);
            var project = workspace.OpenProjectAsync(projectPath).Result

The path to '\Orleans\src\ClientGenerator\ClientGenerator.csproj' project should be passed. The exception will occur when Roslyn begins loading one of this project's dependencies (Orleans.csproj to be precise):

Error was encountered while opening project 'ClientGenerator\ClientGenerator.csproj'.
Exception message:
One or more errors occurred.

Stack:    at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at ProgramVerificationSystems.PVSStudio.Analyzer.Core.DotNetAnalyzer.ParseProjectInSolution(ProjectInSolution sender, SolutionConfigurationInSolution solutionConfigurationInSolution, String solutionFile) in D:\home\paul\SVN\viva64\PVS-Studio\PVS-Studio\Analyzer\Core\DotNetAnalyzer.cs:line 268

Inner Exception:

Exception message:
An item with the same key has already been added.

Stack:    at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Microsoft.CodeAnalysis.RuleSet.GetDiagnosticOptionsFromRulesetFile(Dictionary`2 diagnosticOptions, String resolvedPath, IList`1 diagnosticsOpt, CommonMessageProvider messageProviderOpt)
   at Microsoft.CodeAnalysis.CSharp.CSharpCommandLineParser.Parse(IEnumerable`1 args, String baseDirectory, String sdkDirectory, String additionalReferenceDirectories)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<GetOrLoadProjectAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<ResolveProjectReferencesAsync>d__28.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<GetOrLoadProjectAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<ResolveProjectReferencesAsync>d__28.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectAsync>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildProjectLoader.<LoadProjectInfoAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.<OpenProjectAsync>d__19.MoveNext()

I've managed to trace the issue down to CSharpCompilerInputs returning a duplicate argument ("/ruleset:\"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Team Tools\\Static Analysis Tools\\\\Rule Sets\\MinimumRecommendedRules.ruleset\"" after building it (CSharpProjectFileLoader.GetProjectFileInfoAsync method). Duplicated ruleset leads to duplicated list of diagnostics, thus leading to the exception (there is no check for key already existing in the dictionary before it is appended).

CyrusNajmabadi commented 1 year ago

Need info if this is still an issue.

Firensis commented 1 year ago

We've tried to reproduce the issue by creating a simple analyzer. There are no errors appeared. Perhaps, the issue should be closed.