File: ProjectSystemShim\LegacyProject\CSharpCompilerOptionsTests.cs
Web Access
Project: src\src\VisualStudio\CSharp\Test\Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests.csproj (Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.LanguageServices.CSharp.ProjectSystemShim.Interop;
using Microsoft.VisualStudio.LanguageServices.CSharp.Utilities;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.Interop;
using Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Roslyn.VisualStudio.CSharp.UnitTests.ProjectSystemShim.LegacyProject
{
    [UseExportProvider]
    [Trait(Traits.Feature, Traits.Features.ProjectSystemShims)]
    public class CSharpCompilerOptionsTests
    {
        [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530980")]
        public void DocumentationModeSetToDiagnoseIfProducingDocFile()
        {
            using var environment = new TestEnvironment();
            var project = CSharpHelpers.CreateCSharpProject(environment, "Test");
 
            project.SetOption(CompilerOptions.OPTID_XML_DOCFILE, "DocFile.xml");
 
            var workspaceProject = environment.Workspace.CurrentSolution.Projects.Single();
            var options = (CSharpParseOptions)workspaceProject.ParseOptions;
 
            Assert.Equal(DocumentationMode.Diagnose, options.DocumentationMode);
        }
 
        [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530980")]
        public void DocumentationModeSetToParseIfNotProducingDocFile()
        {
            using var environment = new TestEnvironment();
            var project = CSharpHelpers.CreateCSharpProject(environment, "Test");
 
            project.SetOption(CompilerOptions.OPTID_XML_DOCFILE, "");
 
            var workspaceProject = environment.Workspace.CurrentSolution.Projects.Single();
            var options = (CSharpParseOptions)workspaceProject.ParseOptions;
 
            Assert.Equal(DocumentationMode.Parse, options.DocumentationMode);
        }
 
        [WpfFact]
        public void UseOPTID_COMPATIBILITY()
        {
            using var environment = new TestEnvironment();
            var project = CSharpHelpers.CreateCSharpProject(environment, "Test");
 
            project.SetOption(CompilerOptions.OPTID_COMPATIBILITY, "6");
 
            var workspaceProject = environment.Workspace.CurrentSolution.Projects.Single();
            var options = (CSharpParseOptions)workspaceProject.ParseOptions;
 
            Assert.Equal(LanguageVersion.CSharp6, options.LanguageVersion);
        }
 
        ////[WpfFact]
        ////[Trait(Traits.Feature, Traits.Features.ProjectSystemShims)]
        ////public void UseOPTID_COMPATIBILITY_caseinsensitive()
        ////{
        ////    using (var environment = new TestEnvironment())
        ////    {
        ////        var project = CSharpHelpers.CreateCSharpProject(environment, "Test");
 
        ////        project.SetOptionWithMarshaledValue(CompilerOptions.OPTID_COMPATIBILITY, "Experimental");
 
        ////        var workspaceProject = environment.Workspace.CurrentSolution.Projects.Single();
        ////        var options = (CSharpParseOptions)workspaceProject.ParseOptions;
 
        ////        Assert.Equal(LanguageVersion.Experimental, options.LanguageVersion);
        ////    }
        ////}
 
        [WpfFact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1092636")]
        [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1040247")]
        [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1048368")]
        public void ProjectSettingsOptionAddAndRemove()
        {
            using var environment = new TestEnvironment();
            var project = CSharpHelpers.CreateCSharpProject(environment, "Test");
 
            project.SetOption(CompilerOptions.OPTID_WARNASERRORLIST, "1111");
            var options = environment.GetUpdatedCompilationOptionOfSingleProject();
            Assert.Equal(expected: ReportDiagnostic.Error, actual: options.SpecificDiagnosticOptions["CS1111"]);
 
            project.SetOption(CompilerOptions.OPTID_WARNASERRORLIST, null);
            options = environment.GetUpdatedCompilationOptionOfSingleProject();
            Assert.False(options.SpecificDiagnosticOptions.ContainsKey("CS1111"));
        }
 
        [WpfFact, WorkItem("https://github.com/dotnet/roslyn/pull/33401")]
        public void ProjectOutputPathAndOutputExeNameChange()
        {
            using var environment = new TestEnvironment();
            var initialPath = @"C:\test.dll";
            var project = CSharpHelpers.CreateCSharpProject(environment, "Test");
            project.SetOutputFileName(initialPath);
            Assert.Equal(initialPath, project.GetOutputFileName());
 
            string getCurrentCompilationOutputAssemblyPath()
                => environment.Workspace.CurrentSolution.GetRequiredProject(project.Test_ProjectSystemProject.Id).CompilationOutputInfo.AssemblyPath;
 
            Assert.Equal(initialPath, getCurrentCompilationOutputAssemblyPath());
 
            // Change output folder from command line arguments - verify that objOutputPath changes.
            var newPath = @"C:\NewFolder\test.dll";
            project.SetOutputFileName(newPath);
            Assert.Equal(newPath, project.GetOutputFileName());
 
            Assert.Equal(newPath, getCurrentCompilationOutputAssemblyPath());
 
            // Change output file name - verify that outputPath changes.
            newPath = @"C:\NewFolder\test2.dll";
            project.SetOutputFileName(newPath);
            Assert.Equal(newPath, project.GetOutputFileName());
 
            Assert.Equal(newPath, getCurrentCompilationOutputAssemblyPath());
 
            // Change output file name and folder - verify that outputPath changes.
            newPath = @"C:\NewFolder3\test3.dll";
            project.SetOutputFileName(newPath);
            Assert.Equal(newPath, project.GetOutputFileName());
 
            Assert.Equal(newPath, getCurrentCompilationOutputAssemblyPath());
        }
 
        [WpfFact]
        public void ProjectCompilationOutputsChange()
        {
            using var environment = new TestEnvironment();
            var project = CSharpHelpers.CreateCSharpProject(environment, "Test");
 
            string getCurrentCompilationOutputAssemblyPath()
                => environment.Workspace.CurrentSolution.GetRequiredProject(project.Test_ProjectSystemProject.Id).CompilationOutputInfo.AssemblyPath;
 
            Assert.Null(getCurrentCompilationOutputAssemblyPath());
 
            Assert.Equal(0, ((ICompilerOptionsHostObject)project).SetCompilerOptions(@"/pdb:C:\a\1.pdb /debug+", out _));
 
            // Compilation doesn't have output file, so we don't expect any build outputs either.
            Assert.Null(getCurrentCompilationOutputAssemblyPath());
 
            Assert.Equal(0, ((ICompilerOptionsHostObject)project).SetCompilerOptions(@"/out:C:\a\2.dll /debug+", out _));
 
            Assert.Equal(@"C:\a\2.dll", getCurrentCompilationOutputAssemblyPath());
 
            project.SetOutputFileName(@"C:\a\3.dll");
 
            Assert.Equal(@"C:\a\3.dll", getCurrentCompilationOutputAssemblyPath());
 
            Assert.Equal(0, ((ICompilerOptionsHostObject)project).SetCompilerOptions(@"/pdb:C:\a\4.pdb /debug+", out _));
 
            Assert.Equal(@"C:\a\3.dll", getCurrentCompilationOutputAssemblyPath());
        }
 
        [WpfTheory]
        [InlineData(LanguageVersion.CSharp7_3)]
        [InlineData(LanguageVersion.CSharp8)]
        [InlineData(LanguageVersion.CSharp9)]
        [InlineData(LanguageVersion.Latest)]
        [InlineData(LanguageVersion.LatestMajor)]
        [InlineData(LanguageVersion.Preview)]
        [InlineData(null)]
        public void SetProperty_MaxSupportedLangVersion(LanguageVersion? maxSupportedLangVersion)
        {
            using var environment = new TestEnvironment(typeof(CSharpParseOptionsChangingService));
 
            var hierarchy = environment.CreateHierarchy("CSharpProject", "Bin", projectRefPath: null, projectCapabilities: "CSharp");
            var storage = Assert.IsAssignableFrom<IVsBuildPropertyStorage>(hierarchy);
 
            Assert.True(ErrorHandler.Succeeded(
                storage.SetPropertyValue(
                    "MaxSupportedLangVersion", null, (uint)_PersistStorageType.PST_PROJECT_FILE, maxSupportedLangVersion?.ToDisplayString())));
 
            _ = CSharpHelpers.CreateCSharpProject(environment, "Test", hierarchy);
 
            var project = environment.Workspace.CurrentSolution.Projects.Single();
 
            var oldParseOptions = (CSharpParseOptions)project.ParseOptions;
 
            const LanguageVersion attemptedVersion = LanguageVersion.CSharp8;
 
            var canApply = environment.Workspace.CanApplyParseOptionChange(
                oldParseOptions,
                oldParseOptions.WithLanguageVersion(attemptedVersion),
                project);
 
            if (maxSupportedLangVersion.HasValue)
            {
                Assert.Equal(attemptedVersion <= maxSupportedLangVersion.Value, canApply);
            }
            else
            {
                Assert.True(canApply);
            }
        }
 
        [WpfFact]
        public void SetProperty_MaxSupportedLangVersion_NotSet()
        {
            using var environment = new TestEnvironment(typeof(CSharpParseOptionsChangingService));
 
            var hierarchy = environment.CreateHierarchy("CSharpProject", "Bin", projectRefPath: null, projectCapabilities: "CSharp");
            var storage = Assert.IsAssignableFrom<IVsBuildPropertyStorage>(hierarchy);
 
            _ = CSharpHelpers.CreateCSharpProject(environment, "Test", hierarchy);
 
            var project = environment.Workspace.CurrentSolution.Projects.Single();
 
            var oldParseOptions = (CSharpParseOptions)project.ParseOptions;
 
            const LanguageVersion attemptedVersion = LanguageVersion.CSharp8;
 
            var canApply = environment.Workspace.CanApplyParseOptionChange(
                oldParseOptions,
                oldParseOptions.WithLanguageVersion(attemptedVersion),
                project);
 
            Assert.True(canApply);
        }
    }
}