diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj b/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj
index c4303ea9e..12a3c6390 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs b/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs
index b4f1be3b0..36af35d56 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers.Tests/VSTHRD010MainThreadUsageAnalyzerTests.cs
@@ -964,6 +964,25 @@ void F() {
await Verify.VerifyAnalyzerAsync(test, expected);
}
+ [Fact]
+ public async Task CastToVsSolutionViaIsWithPatternMatching()
+ {
+ var test = @"
+using System;
+using Microsoft.VisualStudio.Shell.Interop;
+
+class Test {
+ void F() {
+ object obj1 = null;
+ if (obj1 is IVsSolution solution) {
+ }
+ }
+}
+";
+ var expected = Verify.Diagnostic(DescriptorSync).WithSpan(8, 18, 8, 32).WithArguments("IVsSolution", "Test.VerifyOnUIThread");
+ await Verify.VerifyAnalyzerAsync(test, expected);
+ }
+
///
/// Verifies that the as cast operator does not produce a diagnostic when the type is to a managed type.
///
diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj b/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj
index 33ea56c12..af7895d67 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers/Microsoft.VisualStudio.Threading.Analyzers.csproj
@@ -1,7 +1,6 @@
- netstandard1.1
- $(PackageTargetFallback);portable-net45+win8
+ netstandard1.3
true
$(NoWarn);CS1591
Microsoft.VisualStudio.Threading.Analyzers.ruleset
@@ -13,7 +12,7 @@
© Microsoft Corporation. All rights reserved.
https://github.com/Microsoft/vs-threading
https://aka.ms/VsExtensibilityIcon
- In the v15.8 release, analyzers are incomplete in the context of Visual Studio without the Microsoft.VisualStudio.Sdk.Analyzers 15.8 package also installed.
+ In the v16.0 release, analyzers require at least C# 7.3 (Visual Studio 2017 Update 7).
full
@@ -58,7 +57,7 @@
-
+
@@ -81,4 +80,4 @@
https://raw.githubusercontent.com/Microsoft/vs-threading/$(GitCommitIdShort)/LICENSE
-
\ No newline at end of file
+
diff --git a/src/Microsoft.VisualStudio.Threading.Analyzers/VSTHRD010MainThreadUsageAnalyzer.cs b/src/Microsoft.VisualStudio.Threading.Analyzers/VSTHRD010MainThreadUsageAnalyzer.cs
index d5021f375..c526f4f93 100644
--- a/src/Microsoft.VisualStudio.Threading.Analyzers/VSTHRD010MainThreadUsageAnalyzer.cs
+++ b/src/Microsoft.VisualStudio.Threading.Analyzers/VSTHRD010MainThreadUsageAnalyzer.cs
@@ -9,7 +9,6 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
- using Microsoft.CodeAnalysis.Semantics;
using Microsoft.CodeAnalysis.Text;
///
@@ -133,6 +132,7 @@ public override void Initialize(AnalysisContext context)
codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeCast), SyntaxKind.CastExpression);
codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeAs), SyntaxKind.AsExpression);
codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeAs), SyntaxKind.IsExpression);
+ codeBlockStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(methodAnalyzer.AnalyzeIsPattern), SyntaxKind.IsPatternExpression);
});
compilationStartContext.RegisterSyntaxNodeAction(Utils.DebuggableWrapper(c => AddToCallerCalleeMap(c, callerToCalleeMap)), SyntaxKind.InvocationExpression);
@@ -369,6 +369,23 @@ internal void AnalyzeAs(SyntaxNodeAnalysisContext context)
}
}
+ internal void AnalyzeIsPattern(SyntaxNodeAnalysisContext context)
+ {
+ var patternSyntax = (IsPatternExpressionSyntax)context.Node;
+ if (patternSyntax.Pattern is DeclarationPatternSyntax declarationPatternSyntax && declarationPatternSyntax.Type != null)
+ {
+ var type = context.SemanticModel.GetSymbolInfo(declarationPatternSyntax.Type, context.CancellationToken).Symbol as ITypeSymbol;
+ if (type != null && IsObjectLikelyToBeCOMObject(type))
+ {
+ Location isAndTypeSide = Location.Create(
+ context.Node.SyntaxTree,
+ TextSpan.FromBounds(patternSyntax.IsKeyword.SpanStart,
+ declarationPatternSyntax.Type.Span.End));
+ this.AnalyzeMemberWithinContext(type, null, context, isAndTypeSide);
+ }
+ }
+ }
+
///
/// Determines whether a given type is likely to be (or implemented by) a COM object.
///
diff --git a/src/Microsoft.VisualStudio.Threading/Microsoft.VisualStudio.Threading.csproj b/src/Microsoft.VisualStudio.Threading/Microsoft.VisualStudio.Threading.csproj
index da2848216..1dadde7cc 100644
--- a/src/Microsoft.VisualStudio.Threading/Microsoft.VisualStudio.Threading.csproj
+++ b/src/Microsoft.VisualStudio.Threading/Microsoft.VisualStudio.Threading.csproj
@@ -69,9 +69,15 @@
-
+ but have a package dependency so users of this library will automatically get the analyzers.
+ This requires an MSBuild workaround as documented here: https://github.com/Microsoft/msbuild/issues/2661#issuecomment-338808137
+ -->
+
+ none
+ false
+ true
+ TargetFramework
+