未验证 提交 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
{
......@@ -76,61 +73,74 @@ internal static IAnalyzerAssemblyLoader GetLoader()
// internal for testing purpose
internal static ImmutableArray<HostDiagnosticAnalyzerPackage> GetHostAnalyzerPackagesWithName(object extensionManager, Type parameterType)
{
// 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
var builder = ImmutableArray.CreateBuilder<HostDiagnosticAnalyzerPackage>();
// var enabledExtensions = extensionManager.GetEnabledExtensions(AnalyzerContentTypeName);
var extensionManagerType = extensionManager.GetType();
var extensionManager_GetEnabledExtensionsMethod = extensionManagerType.GetRuntimeMethod("GetEnabledExtensions", new Type[] { typeof(string) });
var enabledExtensions = extensionManager_GetEnabledExtensionsMethod.Invoke(extensionManager, new object[] { AnalyzerContentTypeName }) as IEnumerable<object>;
foreach (var extension in enabledExtensions)
try
{
// var name = extension.Header.LocalizedName;
var extensionType = extension.GetType();
var extensionType_HeaderProperty = extensionType.GetRuntimeProperty("Header");
var extension_Header = extensionType_HeaderProperty.GetValue(extension);
var extension_HeaderType = extension_Header.GetType();
var extension_HeaderType_LocalizedNameProperty = extension_HeaderType.GetRuntimeProperty("LocalizedName");
var name = extension_HeaderType_LocalizedNameProperty.GetValue(extension_Header) as string;
// 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
var assemblies = ImmutableArray.CreateBuilder<string>();
var builder = ImmutableArray.CreateBuilder<HostDiagnosticAnalyzerPackage>();
// var extension_Content = extension.Content;
var extensionType_ContentProperty = extensionType.GetRuntimeProperty("Content");
var extension_Content = extensionType_ContentProperty.GetValue(extension) as IEnumerable<object>;
// var enabledExtensions = extensionManager.GetEnabledExtensions(AnalyzerContentTypeName);
var extensionManagerType = extensionManager.GetType();
var extensionManager_GetEnabledExtensionsMethod = extensionManagerType.GetRuntimeMethod("GetEnabledExtensions", new Type[] { typeof(string) });
var enabledExtensions = extensionManager_GetEnabledExtensionsMethod.Invoke(extensionManager, new object[] { AnalyzerContentTypeName }) as IEnumerable<object>;
foreach (var content in extension_Content)
foreach (var extension in enabledExtensions)
{
if (!ShouldInclude(content))
{
continue;
}
// var name = extension.Header.LocalizedName;
var extensionType = extension.GetType();
var extensionType_HeaderProperty = extensionType.GetRuntimeProperty("Header");
var extension_Header = extensionType_HeaderProperty.GetValue(extension);
var extension_HeaderType = extension_Header.GetType();
var extension_HeaderType_LocalizedNameProperty = extension_HeaderType.GetRuntimeProperty("LocalizedName");
var name = extension_HeaderType_LocalizedNameProperty.GetValue(extension_Header) as string;
var assemblies = ImmutableArray.CreateBuilder<string>();
var extensionType_GetContentMethod = extensionType.GetRuntimeMethod("GetContentLocation", new Type[] { parameterType });
var assembly = extensionType_GetContentMethod?.Invoke(extension, new object[] { content }) as string;
if (assembly == null)
// var extension_Content = extension.Content;
var extensionType_ContentProperty = extensionType.GetRuntimeProperty("Content");
var extension_Content = extensionType_ContentProperty.GetValue(extension) as IEnumerable<object>;
foreach (var content in extension_Content)
{
continue;
if (!ShouldInclude(content))
{
continue;
}
var extensionType_GetContentMethod = extensionType.GetRuntimeMethod("GetContentLocation", new Type[] { parameterType });
var assembly = extensionType_GetContentMethod?.Invoke(extension, new object[] { content }) as string;
if (assembly == null)
{
continue;
}
assemblies.Add(assembly);
}
assemblies.Add(assembly);
builder.Add(new HostDiagnosticAnalyzerPackage(name, assemblies.ToImmutable()));
}
builder.Add(new HostDiagnosticAnalyzerPackage(name, assemblies.ToImmutable()));
}
var packages = builder.ToImmutable();
var packages = builder.ToImmutable();
EnsureMandatoryAnalyzers(packages);
EnsureMandatoryAnalyzers(packages);
// make sure enabled extensions are alive in memory
// so that we can debug it through if mandatory analyzers are missing
GC.KeepAlive(enabledExtensions);
// make sure enabled extensions are alive in memory
// so that we can debug it through if mandatory analyzers are missing
GC.KeepAlive(enabledExtensions);
return packages;
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,35 +51,40 @@ public string FullPath
public bool HasLoadErrors
{
get { return _analyzerLoadErrors != null && _analyzerLoadErrors.Count > 0; }
get { return !_analyzerLoadErrors.IsEmpty; }
}
public AnalyzerReference GetReference()
{
if (_analyzerReference == null)
lock (_gate)
{
if (File.Exists(_fullPath))
if (_analyzerReference == null)
{
// Pass down a custom loader that will ensure we are watching for file changes once we actually load the assembly.
var assemblyLoaderForFileTracker = new AnalyzerAssemblyLoaderThatEnsuresFileBeingWatched(this);
_analyzerReference = new AnalyzerFileReference(_fullPath, assemblyLoaderForFileTracker);
((AnalyzerFileReference)_analyzerReference).AnalyzerLoadFailed += OnAnalyzerLoadError;
if (File.Exists(_fullPath))
{
// Pass down a custom loader that will ensure we are watching for file changes once we actually load the assembly.
var assemblyLoaderForFileTracker = new AnalyzerAssemblyLoaderThatEnsuresFileBeingWatched(this);
_analyzerReference = new AnalyzerFileReference(_fullPath, assemblyLoaderForFileTracker);
((AnalyzerFileReference)_analyzerReference).AnalyzerLoadFailed += OnAnalyzerLoadError;
}
else
{
_analyzerReference = new VisualStudioUnresolvedAnalyzerReference(_fullPath, this);
}
}
else
{
_analyzerReference = new VisualStudioUnresolvedAnalyzerReference(_fullPath, this);
}
}
return _analyzerReference;
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,20 +99,31 @@ 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;
_analyzerReference = 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.
先完成此消息的编辑!
想要评论请 注册