未验证 提交 766976fc 编写于 作者: D dotnet-automerge-bot 提交者: GitHub

Merge pull request #29154 from dotnet/merges/dev15.8.x-to-dev15.9.x

Merge dev15.8.x to dev15.9.x
......@@ -38,6 +38,25 @@ class C
await TestAsync(markup, expectedOrderedItems, usePreviousCharAsTrigger: true);
}
[WorkItem(655607, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/655607")]
[Fact, Trait(Traits.Feature, Traits.Features.SignatureHelp)]
public async Task TestMissingTupleElement()
{
var markup = @"
class C
{
void M()
{
(a, ) = [|($$
|] }
}";
var expectedOrderedItems = new List<SignatureHelpTestItem>();
expectedOrderedItems.Add(new SignatureHelpTestItem("(object a, object)", currentParameterIndex: 0));
await TestAsync(markup, expectedOrderedItems, usePreviousCharAsTrigger: true);
}
[Fact, Trait(Traits.Feature, Traits.Features.SignatureHelp)]
public async Task InvocationAfterOpenParen2()
{
......
......@@ -4,14 +4,11 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.Shell;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Diagnostics
{
......@@ -75,6 +72,8 @@ internal static IAnalyzerAssemblyLoader GetLoader()
// internal for testing purpose
internal static ImmutableArray<HostDiagnosticAnalyzerPackage> GetHostAnalyzerPackagesWithName(object extensionManager, Type parameterType)
{
try
{
// dynamic is wierd. it can't see internal type with public interface even if callee is
// implementation of the public interface in internal type. so we can't use dynamic here
......@@ -132,6 +131,17 @@ internal static ImmutableArray<HostDiagnosticAnalyzerPackage> GetHostAnalyzerPac
return packages;
}
catch (InvalidOperationException)
{
// this can be called from any thread, and extension manager could be disposed in the middle of us using it since
// now all these are free-threaded and there is no central coordinator, or API or state is immutable that prevent states from
// changing in the middle of others using it.
//
// fortunately, this only happens on disposing at shutdown, so we just catch the exception and silently swallow it.
// we are about to shutdown anyway.
return ImmutableArray<HostDiagnosticAnalyzerPackage>.Empty;
}
}
private static void EnsureMandatoryAnalyzers(ImmutableArray<HostDiagnosticAnalyzerPackage> packages)
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Reflection;
......@@ -24,24 +23,27 @@ internal sealed class VisualStudioAnalyzer : IDisposable
private readonly IAnalyzerAssemblyLoader _loader;
private readonly string _language;
private AnalyzerReference _analyzerReference;
private List<DiagnosticData> _analyzerLoadErrors;
public event EventHandler UpdatedOnDisk;
// these 2 are mutable states that must be guarded under the _gate.
private readonly object _gate = new object();
private AnalyzerReference _analyzerReference = null;
private ImmutableArray<DiagnosticData> _analyzerLoadErrors = ImmutableArray<DiagnosticData>.Empty;
public VisualStudioAnalyzer(string fullPath, IVsFileChangeEx fileChangeService, HostDiagnosticUpdateSource hostDiagnosticUpdateSource, ProjectId projectId, Workspace workspace, IAnalyzerAssemblyLoader loader, string language)
{
_fullPath = fullPath;
_tracker = new FileChangeTracker(fileChangeService, fullPath);
_tracker.UpdatedOnDisk += OnUpdatedOnDisk;
_tracker.StartFileChangeListeningAsync();
_hostDiagnosticUpdateSource = hostDiagnosticUpdateSource;
_projectId = projectId;
_workspace = workspace;
_loader = loader;
_language = language;
_tracker = new FileChangeTracker(fileChangeService, fullPath);
_tracker.UpdatedOnDisk += OnUpdatedOnDisk;
_tracker.StartFileChangeListeningAsync();
}
public event EventHandler UpdatedOnDisk;
public string FullPath
{
get { return _fullPath; }
......@@ -49,10 +51,12 @@ public string FullPath
public bool HasLoadErrors
{
get { return _analyzerLoadErrors != null && _analyzerLoadErrors.Count > 0; }
get { return !_analyzerLoadErrors.IsEmpty; }
}
public AnalyzerReference GetReference()
{
lock (_gate)
{
if (_analyzerReference == null)
{
......@@ -71,13 +75,16 @@ public AnalyzerReference GetReference()
return _analyzerReference;
}
}
private void OnAnalyzerLoadError(object sender, AnalyzerLoadFailureEventArgs e)
{
var data = AnalyzerHelper.CreateAnalyzerLoadFailureDiagnostic(_workspace, _projectId, _language, _fullPath, e);
_analyzerLoadErrors = _analyzerLoadErrors ?? new List<DiagnosticData>();
_analyzerLoadErrors.Add(data);
lock (_gate)
{
_analyzerLoadErrors = _analyzerLoadErrors.Add(data);
}
_hostDiagnosticUpdateSource.UpdateDiagnosticsForProject(_projectId, this, _analyzerLoadErrors);
}
......@@ -92,21 +99,32 @@ public void Dispose()
public void Reset()
{
if (_analyzerReference is AnalyzerFileReference analyzerFileReference)
ResetReferenceAndErrors(out var reference, out var loadErrors);
if (reference is AnalyzerFileReference fileReference)
{
analyzerFileReference.AnalyzerLoadFailed -= OnAnalyzerLoadError;
fileReference.AnalyzerLoadFailed -= OnAnalyzerLoadError;
if (_analyzerLoadErrors != null && _analyzerLoadErrors.Count > 0)
if (!loadErrors.IsEmpty)
{
_hostDiagnosticUpdateSource.ClearDiagnosticsForProject(_projectId, this);
}
_hostDiagnosticUpdateSource.ClearAnalyzerReferenceDiagnostics(analyzerFileReference, _language, _projectId);
_hostDiagnosticUpdateSource.ClearAnalyzerReferenceDiagnostics(fileReference, _language, _projectId);
}
}
_analyzerLoadErrors = null;
private void ResetReferenceAndErrors(out AnalyzerReference reference, out ImmutableArray<DiagnosticData> loadErrors)
{
lock (_gate)
{
loadErrors = _analyzerLoadErrors;
reference = _analyzerReference;
_analyzerLoadErrors = ImmutableArray<DiagnosticData>.Empty;
_analyzerReference = null;
}
}
private void OnUpdatedOnDisk(object sender, EventArgs e)
{
......
......@@ -9,10 +9,10 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
using Microsoft.CodeAnalysis.LanguageServices;
namespace Microsoft.CodeAnalysis.CSharp
{
......@@ -2090,9 +2090,10 @@ private IEnumerable<TypeInferenceInfo> InferTypeInVariableComponentAssignment(Ex
{
AddTypeAndName((TupleExpressionSyntax)expr, elementTypesBuilder, elementNamesBuilder);
}
else if (expr.IsKind(SyntaxKind.IdentifierName))
else if (expr is IdentifierNameSyntax name)
{
elementNamesBuilder.Add(((IdentifierNameSyntax)expr).Identifier.ValueText);
elementNamesBuilder.Add(name.Identifier.ValueText == "" ? null :
name.Identifier.ValueText);
elementTypesBuilder.Add(GetTypes(expr).FirstOrDefault().InferredType ?? this.Compilation.ObjectType);
}
else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册