diff --git a/eng/build.ps1 b/eng/build.ps1 index e85b12d5793a8726995cb8c5a6162fce1842397f..67784c7adfe97c2949a37b9b79e77629d1aea46e 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -428,6 +428,11 @@ function TestUsingOptimizedRunner() { if ($testIOperation) { Remove-Item env:\ROSLYN_TEST_IOPERATION } + + if ($testVsi) { + Write-Host "Copying ServiceHub logs to $LogDir" + Copy-Item -Path (Join-Path $TempDir "servicehub\logs") -Destination (Join-Path $LogDir "servicehub") -Recurse + } } } @@ -622,7 +627,9 @@ try { } catch { - echo "##vso[task.logissue type=error](NETCORE_ENGINEERING_TELEMETRY=Build) Build failed" + if ($ci) { + echo "##vso[task.logissue type=error](NETCORE_ENGINEERING_TELEMETRY=Build) Build failed" + } throw $_ } @@ -642,7 +649,9 @@ try { } catch { - echo "##vso[task.logissue type=error](NETCORE_ENGINEERING_TELEMETRY=Test) Tests failed" + if ($ci) { + echo "##vso[task.logissue type=error](NETCORE_ENGINEERING_TELEMETRY=Test) Tests failed" + } throw $_ } diff --git a/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs b/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs index 2a3612d7f14e5da5b4d6cda93cfa94fffac20d87..21f4cc3d747ed2c6a5fc2029eaba71cd14b2452b 100644 --- a/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs +++ b/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs @@ -386,7 +386,7 @@ public CompilationOptions WithGeneralDiagnosticOption(ReportDiagnostic value) /// /// Creates a new options instance with the specified diagnostic-specific options. /// - public CompilationOptions WithSpecificDiagnosticOptions(ImmutableDictionary value) + public CompilationOptions WithSpecificDiagnosticOptions(ImmutableDictionary? value) { return CommonWithSpecificDiagnosticOptions(value); } @@ -497,7 +497,7 @@ public CompilationOptions WithCryptoKeyContainer(string? cryptoKeyContainer) return CommonWithCryptoKeyContainer(cryptoKeyContainer); } - public CompilationOptions WithCryptoKeyFile(string cryptoKeyFile) + public CompilationOptions WithCryptoKeyFile(string? cryptoKeyFile) { return CommonWithCryptoKeyFile(cryptoKeyFile); } @@ -531,14 +531,14 @@ public CompilationOptions WithOverflowChecks(bool checkOverflow) protected abstract CompilationOptions CommonWithAssemblyIdentityComparer(AssemblyIdentityComparer comparer); protected abstract CompilationOptions CommonWithStrongNameProvider(StrongNameProvider? provider); protected abstract CompilationOptions CommonWithGeneralDiagnosticOption(ReportDiagnostic generalDiagnosticOption); - protected abstract CompilationOptions CommonWithSpecificDiagnosticOptions(ImmutableDictionary specificDiagnosticOptions); + protected abstract CompilationOptions CommonWithSpecificDiagnosticOptions(ImmutableDictionary? specificDiagnosticOptions); protected abstract CompilationOptions CommonWithSpecificDiagnosticOptions(IEnumerable> specificDiagnosticOptions); protected abstract CompilationOptions CommonWithReportSuppressedDiagnostics(bool reportSuppressedDiagnostics); protected abstract CompilationOptions CommonWithModuleName(string? moduleName); protected abstract CompilationOptions CommonWithMainTypeName(string? mainTypeName); protected abstract CompilationOptions CommonWithScriptClassName(string scriptClassName); protected abstract CompilationOptions CommonWithCryptoKeyContainer(string? cryptoKeyContainer); - protected abstract CompilationOptions CommonWithCryptoKeyFile(string cryptoKeyFile); + protected abstract CompilationOptions CommonWithCryptoKeyFile(string? cryptoKeyFile); protected abstract CompilationOptions CommonWithCryptoPublicKey(ImmutableArray cryptoPublicKey); protected abstract CompilationOptions CommonWithDelaySign(bool? delaySign); protected abstract CompilationOptions CommonWithCheckOverflow(bool checkOverflow); diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs index c84b5c62e4351ab9d750b8b128d46fa0cb5f7522..b6ddad85941264b1dd7f9c95a2963ed4ca5c5df2 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.cs @@ -20,6 +20,10 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionPr [UseExportProvider] public class ExtensionMethodImportCompletionProviderTests : AbstractCSharpCompletionProviderTests { + private static readonly IExportProviderFactory s_exportProviderFactory + = ExportProviderCache.GetOrCreateExportProviderFactory( + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(TestExperimentationService))); + public ExtensionMethodImportCompletionProviderTests(CSharpTestWorkspaceFixture workspaceFixture) : base(workspaceFixture) { } @@ -36,11 +40,7 @@ protected override OptionSet WithChangedOptions(OptionSet options) } protected override ExportProvider GetExportProvider() - { - return ExportProviderCache - .GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(TestExperimentationService))) - .CreateExportProvider(); - } + => s_exportProviderFactory.CreateExportProvider(); internal override CompletionProvider CreateCompletionProvider() { @@ -76,34 +76,16 @@ private static IEnumerable> BuiltInTypes { get { - var predefinedTypes = new List> - { - new List() - { "int", "Int32", "System.Int32" }, - new List() - { "float", "Single", "System.Single" }, - new List() - { "uint", "UInt32", "System.UInt32" }, - new List() - { "bool", "Boolean", "System.Boolean"}, - new List() - { "string", "String", "System.String"}, - new List() - { "object", "Object", "System.Object"}, - }; - + var predefinedTypes = new List() { "string", "String", "System.String" }; var arraySuffixes = new[] { "", "[]", "[,]" }; - foreach (var group in predefinedTypes) + foreach (var type1 in predefinedTypes) { - foreach (var type1 in group) + foreach (var type2 in predefinedTypes) { - foreach (var type2 in group) + foreach (var suffix in arraySuffixes) { - foreach (var suffix in arraySuffixes) - { - yield return new List() { type1 + suffix, type2 + suffix }; - } + yield return new List() { type1 + suffix, type2 + suffix }; } } } diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs index 876733b5f9790cc900cee59b3ee870cc7cbf3eb7..5c87290351a9130254b1ccad1fa8f825283f3c91 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs @@ -25,6 +25,10 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionSe [UseExportProvider] public partial class SymbolCompletionProviderTests : AbstractCSharpCompletionProviderTests { + private static readonly IExportProviderFactory s_exportProviderFactory + = ExportProviderCache.GetOrCreateExportProviderFactory( + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(TestExperimentationService))); + public SymbolCompletionProviderTests(CSharpTestWorkspaceFixture workspaceFixture) : base(workspaceFixture) { } @@ -35,11 +39,7 @@ internal override CompletionProvider CreateCompletionProvider() } protected override ExportProvider GetExportProvider() - { - return ExportProviderCache - .GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(TestExperimentationService))) - .CreateExportProvider(); - } + => s_exportProviderFactory.CreateExportProvider(); [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task EmptyFile() diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs index f33b169b02554aa1eb441fbdc7b4eb4a3fe9384e..87804a61859990ada458a2a2871fdc32d00ac705 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs @@ -22,6 +22,10 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionPr [UseExportProvider] public class TypeImportCompletionProviderTests : AbstractCSharpCompletionProviderTests { + private static readonly IExportProviderFactory s_exportProviderFactory + = ExportProviderCache.GetOrCreateExportProviderFactory( + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(TestExperimentationService))); + public TypeImportCompletionProviderTests(CSharpTestWorkspaceFixture workspaceFixture) : base(workspaceFixture) { } @@ -43,11 +47,7 @@ protected override OptionSet WithChangedOptions(OptionSet options) } protected override ExportProvider GetExportProvider() - { - return ExportProviderCache - .GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(typeof(TestExperimentationService))) - .CreateExportProvider(); - } + => s_exportProviderFactory.CreateExportProvider(); #region "Option tests" diff --git a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.vb b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.vb index ece7f4c006c11e8ba7a1e80706b151c30758e619..e069a2e9a12885f862082ad6e67d90218531ad84 100644 --- a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/ExtensionMethodImportCompletionProviderTests.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet Public Class ExtensionMethodImportCompletionProviderTests Inherits AbstractVisualBasicCompletionProviderTests + Private Shared ReadOnly s_exportProviderFactory As IExportProviderFactory = + ExportProviderCache.GetOrCreateExportProviderFactory( + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(GetType(TestExperimentationService))) + Public Sub New(workspaceFixture As VisualBasicTestWorkspaceFixture) MyBase.New(workspaceFixture) End Sub @@ -32,7 +36,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet End Function Protected Overrides Function GetExportProvider() As ExportProvider - Return ExportProviderCache.GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(GetType(TestExperimentationService))).CreateExportProvider() + Return s_exportProviderFactory.CreateExportProvider() End Function Friend Overrides Function CreateCompletionProvider() As CompletionProvider diff --git a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb index 66949779a46194fc81c52e34ec3f8f8d71994a1e..b79d170011f1f2a0519285b2e244ab0e0467d599 100644 --- a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb @@ -18,6 +18,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet Private Const s_unicodeEllipsis = ChrW(&H2026) + Private Shared ReadOnly s_exportProviderFactory As IExportProviderFactory = + ExportProviderCache.GetOrCreateExportProviderFactory( + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(GetType(TestExperimentationService))) + Public Sub New(workspaceFixture As VisualBasicTestWorkspaceFixture) MyBase.New(workspaceFixture) End Sub @@ -27,7 +31,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet End Function Protected Overrides Function GetExportProvider() As ExportProvider - Return ExportProviderCache.GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(GetType(TestExperimentationService))).CreateExportProvider() + Return s_exportProviderFactory.CreateExportProvider() End Function #Region "StandaloneNamespaceAndTypeSourceTests" diff --git a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.vb b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.vb index 4cd782d9698817dec01b82265649ea432f8d87d1..fe0053bb1065d80cd76130d8557a29cfa6c6112a 100644 --- a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.vb @@ -15,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet Public Class TypeImportCompletionProviderTests Inherits AbstractVisualBasicCompletionProviderTests + Private Shared ReadOnly s_exportProviderFactory As IExportProviderFactory = + ExportProviderCache.GetOrCreateExportProviderFactory( + TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(GetType(TestExperimentationService))) + Public Sub New(workspaceFixture As VisualBasicTestWorkspaceFixture) MyBase.New(workspaceFixture) End Sub @@ -30,7 +34,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Completion.Complet End Function Protected Overrides Function GetExportProvider() As ExportProvider - Return ExportProviderCache.GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic.WithPart(GetType(TestExperimentationService))).CreateExportProvider() + Return s_exportProviderFactory.CreateExportProvider() End Function Friend Overrides Function CreateCompletionProvider() As CompletionProvider diff --git a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/TempPECompiler.cs b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/TempPECompiler.cs index 6ff4f407dd1d812e4dd692bd67982eeb544604a4..dffdf5eb02d9bd78ed91caf6e09b090753d954c1 100644 --- a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/TempPECompiler.cs +++ b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/TempPECompiler.cs @@ -2,14 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.ComponentModel.Composition; using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.LanguageServices.ProjectSystem; using Roslyn.Utilities; @@ -37,22 +40,27 @@ public async Task CompileAsync(IWorkspaceProjectContext context, string ou throw new ArgumentException(nameof(outputFileName), "Must specify an output file name."); } - var project = _workspace.CurrentSolution.GetProject(context.Id); + var project = _workspace.CurrentSolution.GetRequiredProject(context.Id); + + // Start by fetching the compilation we have already have that will have references correct + var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - // Remove all files except the ones we care about - var documents = project.Documents; - foreach (var document in documents) + // Update to just the syntax trees we need to keep + var syntaxTrees = new List(capacity: filesToInclude.Count); + foreach (var document in project.Documents) { - if (!filesToInclude.Contains(document.FilePath)) + if (document.FilePath != null && filesToInclude.Contains(document.FilePath)) { - project = project.RemoveDocument(document.Id); + syntaxTrees.Add(await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false)); } cancellationToken.ThrowIfCancellationRequested(); } + compilation = compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(syntaxTrees); + // We need to inherit most of the projects options, mainly for VB (RootNamespace, GlobalImports etc.), but we need to override about some specific things surrounding the output - var options = project.CompilationOptions + compilation = compilation.WithOptions(compilation.Options // copied from the old TempPE compiler used by legacy, for parity. // See: https://github.com/dotnet/roslyn/blob/fab7134296816fc80019c60b0f5bef7400cf23ea/src/VisualStudio/CSharp/Impl/ProjectSystemShim/TempPECompilerService.cs#L58 .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default) @@ -70,14 +78,10 @@ public async Task CompileAsync(IWorkspaceProjectContext context, string ou .WithDelaySign(false) .WithCryptoKeyFile(null) .WithPublicSign(false) - .WithStrongNameProvider(null); - - project = project - .WithCompilationOptions(options) - // AssemblyName should be set to the filename of the output file because multiple TempPE DLLs can be created for the same project - .WithAssemblyName(Path.GetFileName(outputFileName)); + .WithStrongNameProvider(null)); - var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + // AssemblyName should be set to the filename of the output file because multiple TempPE DLLs can be created for the same project + compilation = compilation.WithAssemblyName(Path.GetFileName(outputFileName)); cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs index 5ff65edb4505cd67b508f9cdaa9a2469aef10ebe..0fd0aa1f1d1eaed532c08fc9cfda14f6a36749ce 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs @@ -510,21 +510,14 @@ private async Task GetOrBuildDeclarationCompilationAsync(SolutionSt var compilation = CreateEmptyCompilation(); var trees = ArrayBuilder.GetInstance(ProjectState.DocumentIds.Count); - foreach (var document in this.ProjectState.OrderedDocumentStates) + foreach (var document in ProjectState.OrderedDocumentStates) { cancellationToken.ThrowIfCancellationRequested(); - - // Do not include syntax trees for documents whose content failed to load. - // Analyzers should not run on these (empty) syntax trees. - var loadDiagnostic = await document.GetLoadDiagnosticAsync(cancellationToken).ConfigureAwait(false); - if (loadDiagnostic == null) - { - trees.Add(await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false)); - } + // Include the tree even if the content of the document failed to load. + trees.Add(await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false)); } compilation = compilation.AddSyntaxTrees(trees); - trees.Free(); WriteState(new FullDeclarationState(compilation), solution); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs index 3fcee3807e21f826c537826955f71336468fd33b..8df4aa30621034f8bc57f0f716df824771285ce5 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs @@ -1995,6 +1995,9 @@ public bool TryGetCompilation(ProjectId projectId, [NotNullWhen(returnValue: tru /// Returns the compilation for the specified . Can return when the project /// does not support compilations. /// + /// + /// The compilation is guaranteed to have a syntax tree for each document of the project. + /// private Task GetCompilationAsync(ProjectId projectId, CancellationToken cancellationToken) { // TODO: figure out where this is called and why the nullable suppression is required @@ -2005,6 +2008,9 @@ public bool TryGetCompilation(ProjectId projectId, [NotNullWhen(returnValue: tru /// Returns the compilation for the specified . Can return when the project /// does not support compilations. /// + /// + /// The compilation is guaranteed to have a syntax tree for each document of the project. + /// public Task GetCompilationAsync(ProjectState project, CancellationToken cancellationToken) { return project.SupportsCompilation diff --git a/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs b/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs index b4eb2dd91f1ab396d315bb327e4fe3253a75cbff..f1aeb7f3ee5389a1519667a4e8c45033c17115ef 100644 --- a/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs +++ b/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs @@ -1273,6 +1273,11 @@ public async Task TestDocumentFileAccessFailureMissingFile() Assert.Equal(@"C:\doesnotexist.cs: (0,0)-(0,0)", diagnostic.Location.GetLineSpan().ToString()); Assert.Equal(WorkspaceDiagnosticKind.Failure, diagnosticFromEvent.Kind); Assert.Equal("", text.ToString()); + + // Verify invariant: The compilation is guaranteed to have a syntax tree for each document of the project (even if the contnet fails to load). + var compilation = await solution.State.GetCompilationAsync(doc.Project.State, CancellationToken.None).ConfigureAwait(false); + var syntaxTree = compilation.SyntaxTrees.Single(); + Assert.Equal("", syntaxTree.ToString()); } [Fact]