Merge pull request #130 from mjrousos/mikerou/DelegateBeginInvoke
Delegate.BeginInvoke/EndInvoke analyzer
This commit is contained in:
Коммит
e2a658de3b
|
@ -0,0 +1,41 @@
|
|||
# PC004: Delegate.BeginInvoke and EndInvoke are Unsupported on .NET Core
|
||||
|
||||
## Cause
|
||||
|
||||
You're using the [Asynchronous Programming Model](https://docs.microsoft.com/dotnet/standard/asynchronous-programming-patterns/calling-synchronous-methods-asynchronously) to invoke a delegate (via the `BeginInvoke` method) which is unsupported on .NET Core.
|
||||
|
||||
## Rule description
|
||||
|
||||
The `BeginInvoke` and `EndInvoke` methods automatically generated for delegate types at compile-time are not supported by .NET Core. Calling these methods will throw a `NotSupportedException`. Task-based [TPL](https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl) patterns should be used instead.
|
||||
|
||||
## How to fix violations
|
||||
|
||||
Remove calls to `BeginInvoke` and `EndInvoke`. Replace `IAsyncResult` usage with `Task`-based patterns, instead. For example:
|
||||
|
||||
```CSharp
|
||||
delegate int WorkDelegate(int arg);
|
||||
...
|
||||
WorkDelegate del = DoWork;
|
||||
|
||||
// Schedule the work using a Task
|
||||
Console.WriteLine("Starting with Task.Run");
|
||||
var workTask = Task.Run(() => DoWork(11));
|
||||
|
||||
// Optionally, we can specify a continuation delegate
|
||||
// to execute when DoWork has finished
|
||||
var followUpTask = workTask.ContinueWith(TaskCallback);
|
||||
|
||||
// This writes output to the console while DoWork is running in the background
|
||||
Console.WriteLine("Waiting on work...");
|
||||
|
||||
// We await the task instead of calling EndInvoke
|
||||
var ret = await workTask;
|
||||
await folowUpTask;
|
||||
```
|
||||
|
||||
## When to suppress warnings
|
||||
|
||||
These methods are never usable on .NET Core. Suppress the warning only if:
|
||||
|
||||
1. These code paths are only used while running on .NET Framework.
|
||||
2. The analyzer has mistakenly flagged an API that is not a call to a compiler-generated `BeginInvoke`/`EndInvoke` APM method.
|
|
@ -59,6 +59,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{6F07EE72-A
|
|||
docs\PC001.md = docs\PC001.md
|
||||
docs\PC002.md = docs\PC002.md
|
||||
docs\PC003.md = docs\PC003.md
|
||||
docs\PC004.md = docs\PC004.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{09FF4C67-A805-490B-9323-4F60882875B6}"
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.DotNet.Analyzers.Compatibility.BeginInvokeEndInvoke;
|
||||
using Microsoft.DotNet.Analyzers.Compatibility.Tests.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.DotNet.Analyzers.Compatibility.Tests
|
||||
{
|
||||
public class BeginInvokeEndInvokeAnalyzerTests : CSharpDiagnosticTest
|
||||
{
|
||||
protected override DiagnosticAnalyzer CreateAnalyzer()
|
||||
{
|
||||
return new BeginInvokeEndInvokeAnalyzer();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotTrigger_WhenDocumentEmpty()
|
||||
{
|
||||
AssertNoMatch(string.Empty);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotTriggerForCallsToOtherMethods()
|
||||
{
|
||||
var source = @"
|
||||
delegate void TestDelegate(int i);
|
||||
|
||||
class Program
|
||||
{
|
||||
static void TestMethod2(int i) {}
|
||||
static void BeginInvoke() {}
|
||||
|
||||
static void TestMethod(int i)
|
||||
{
|
||||
TestDelegate t = TestMethod;
|
||||
Program.BeginInvoke();
|
||||
Program.TestMethod2(1);
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
AssertNoMatch(source);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotFailWhenNamespaceMissing()
|
||||
{
|
||||
var source = @"
|
||||
class BaseClass {}
|
||||
|
||||
class Program : BaseClass
|
||||
{
|
||||
static void BeginInvoke() {}
|
||||
|
||||
static void TestMethod(int i)
|
||||
{
|
||||
Program.BeginInvoke();
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
AssertNoMatch(source);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TriggersForBeginInvoke()
|
||||
{
|
||||
var source = @"
|
||||
delegate void TestDelegate(int i);
|
||||
|
||||
class Program
|
||||
{
|
||||
static void TestMethod(int i)
|
||||
{
|
||||
TestDelegate t = TestMethod;
|
||||
var result = {{t.BeginInvoke(5, null, null)}};
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
var expected = "PC004: BeginInvoke is unsupported on .NET Core. Use Tasks instead.";
|
||||
|
||||
AssertMatch(source, expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TriggersForEndInvoke()
|
||||
{
|
||||
var source = @"
|
||||
delegate void TestDelegate(int i);
|
||||
|
||||
class Program
|
||||
{
|
||||
static void TestMethod(int i)
|
||||
{
|
||||
TestDelegate t = TestMethod;
|
||||
var result = {{t.BeginInvoke(5, null, null)}};
|
||||
{{t.EndInvoke(result)}};
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
var expected = @"
|
||||
PC004: BeginInvoke is unsupported on .NET Core. Use Tasks instead.
|
||||
PC004: EndInvoke is unsupported on .NET Core. Use Tasks instead.
|
||||
";
|
||||
|
||||
AssertMatch(source, expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TriggersForFuzzyMatches()
|
||||
{
|
||||
var source = @"
|
||||
delegate void TestDelegate(int i);
|
||||
|
||||
class Program
|
||||
{
|
||||
static void TestMethod(int i)
|
||||
{
|
||||
TestDelegate t = TestMethod;
|
||||
var result = {{t.BeginInvoke()}};
|
||||
{{t.EndInvoke(foo)}};
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
var expected = @"
|
||||
PC004: BeginInvoke is unsupported on .NET Core. Use Tasks instead.
|
||||
PC004: EndInvoke is unsupported on .NET Core. Use Tasks instead.
|
||||
";
|
||||
|
||||
AssertMatch(source, expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DoesNotTriggerForNonDelegateFuzzyMatches()
|
||||
{
|
||||
var source = @"
|
||||
delegate void TestDelegate(int i);
|
||||
|
||||
class Program
|
||||
{
|
||||
static void TestMethod(int i)
|
||||
{
|
||||
var t = GetObject();
|
||||
var result = t.BeginInvoke();
|
||||
t.EndInvoke(foo);
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
AssertNoMatch(source);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Analyzers.Compatibility.BeginInvokeEndInvoke
|
||||
{
|
||||
// Looks for use of BeginInvoke or EndInvoke methods on types derived from System.Delegate
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public class BeginInvokeEndInvokeAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
public const string DiagnosticId = "PC004";
|
||||
private const string Category = "Usage";
|
||||
private const string HelpLink = "https://github.com/dotnet/platform-compat/blob/master/docs/" + DiagnosticId + ".md";
|
||||
|
||||
private const string TargetTypeFullName = "System.Delegate";
|
||||
private readonly string[] MethodNames = { "BeginInvoke", "EndInvoke" };
|
||||
|
||||
private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.BeginInvokeEndInvokeAnalyzerTitle), Resources.ResourceManager, typeof(Resources));
|
||||
private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.BeginInvokeEndInvokeAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
|
||||
|
||||
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, helpLinkUri: HelpLink);
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.RegisterSyntaxNodeAction(AnalyzeInvocationExpression, SyntaxKind.InvocationExpression);
|
||||
}
|
||||
|
||||
private void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
// Bail out if the syntax doesn't include a member access expression for some reason
|
||||
if (!(context.Node is InvocationExpressionSyntax invocationExpression &&
|
||||
invocationExpression.Expression is MemberAccessExpressionSyntax memberAccessExpression))
|
||||
return;
|
||||
|
||||
// Bail out if the member access expression doesn't correspond to a method symbol
|
||||
var symbolInfo = context.SemanticModel.GetSymbolInfo(memberAccessExpression);
|
||||
if (!(symbolInfo.Symbol is IMethodSymbol methodSymbol))
|
||||
{
|
||||
// In some cases, the member access expression's symbol won't be definitively known
|
||||
// (if, for example, the argument passed to EndInvoke isn't definitely known yet), so
|
||||
// check candidate symbols and use that if there's only one candidate method there.
|
||||
methodSymbol = symbolInfo.CandidateSymbols.SingleOrDefault(s => s is IMethodSymbol) as IMethodSymbol;
|
||||
if (methodSymbol == null)
|
||||
return;
|
||||
}
|
||||
|
||||
// Only analyze methods with an appropriate name
|
||||
if (!MethodNames.Contains(methodSymbol.Name))
|
||||
return;
|
||||
|
||||
// Only analyze methods on Delegate types
|
||||
if (!TypeIsDescendentOf(methodSymbol.ContainingType, typeof(Delegate)))
|
||||
return;
|
||||
|
||||
context.ReportDiagnostic(Diagnostic.Create(Rule, invocationExpression.GetLocation(), methodSymbol.Name));
|
||||
}
|
||||
|
||||
private bool TypeIsDescendentOf(INamedTypeSymbol containingType, Type targetType)
|
||||
{
|
||||
// If the type has no base, return false
|
||||
if (containingType.BaseType == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the type's parent is the targetType, return true
|
||||
if (TargetTypeFullName.Equals(GetFullName(containingType.BaseType)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, recurse and check the parent's parent
|
||||
return TypeIsDescendentOf(containingType.BaseType, targetType);
|
||||
}
|
||||
|
||||
private string GetFullName(INamedTypeSymbol type) =>
|
||||
$"{type.ContainingNamespace.Name}.{type.Name}";
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CodeActions;
|
||||
using Microsoft.CodeAnalysis.CodeFixes;
|
||||
using Microsoft.DotNet.Analyzers.Compatibility.BeginInvokeEndInvoke;
|
||||
using Microsoft.DotNet.Analyzers.Compatibility.Deprecated;
|
||||
using Microsoft.DotNet.Analyzers.Compatibility.Exceptions;
|
||||
using Microsoft.DotNet.Analyzers.Compatibility.ModernSdk;
|
||||
|
@ -30,6 +31,7 @@ namespace Microsoft.DotNet.Analyzers.Compatibility.Fixes
|
|||
result.Add(ModernSdkAnalyzer.DiagnosticId);
|
||||
result.Add(Net461Analyzer.DiagnosticId);
|
||||
result.AddRange(DeprecatedAnalyzer.GetDescriptors().Select(d => d.Id));
|
||||
result.Add(BeginInvokeEndInvokeAnalyzer.DiagnosticId);
|
||||
return result.ToImmutableArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,6 +70,24 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to {0} is unsupported on .NET Core. Use Tasks instead..
|
||||
/// </summary>
|
||||
internal static string BeginInvokeEndInvokeAnalyzerMessageFormat {
|
||||
get {
|
||||
return ResourceManager.GetString("BeginInvokeEndInvokeAnalyzerMessageFormat", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core.
|
||||
/// </summary>
|
||||
internal static string BeginInvokeEndInvokeAnalyzerTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("BeginInvokeEndInvokeAnalyzerTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Browse to {0}.
|
||||
/// </summary>
|
||||
|
@ -81,13 +99,14 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
|
|||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to DocId,Namespace,Type,Member,DiagnosticIds
|
||||
///M:System.Environment.get_OSVersion,System,Environment,get_OSVersion(),DE0009
|
||||
///F:System.PlatformID.MacOSX,System,PlatformID,MacOSX,DE0007
|
||||
///F:System.PlatformID.Win32S,System,PlatformID,Win32S,DE0007
|
||||
///F:System.PlatformID.Win32Windows,System,PlatformID,Win32Windows,DE0007
|
||||
///F:System.PlatformID.WinCE,System,PlatformID,WinCE,DE0007
|
||||
///F:System.PlatformID.Xbox,System,PlatformID,Xbox,DE0007
|
||||
///T:System.Collections.ArrayList,System.Collections,ArrayList,,DE0006
|
||||
///T:System.Collections.CaseInsensitiveComparer,System.Collections,CaseInsensitiveComparer,,DE000 [rest of string was truncated]";.
|
||||
///M:System.Collections.ArrayList.#ctor,System.Collections,ArrayList,.ctor(),DE0006
|
||||
///M:S [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string Deprecated {
|
||||
get {
|
||||
|
@ -133,8 +152,10 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
|
|||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to DocId,Namespace,Type,Member,linux,osx,win
|
||||
///"M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)",Microsoft.CSharp.RuntimeBinder,RuntimeBinderException,".ctor(SerializationInfo, StreamingContext)",X,X,X
|
||||
///"M:Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException.#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)",Microsoft.CSharp.RuntimeBinder, [rest of string was truncated]";.
|
||||
///M:Microsoft.Win32.PowerModeChangedEventArgs.#ctor(Microsoft.Win32.PowerModes),Microsoft.Win32,PowerModeChangedEventArgs,.ctor(PowerModes),X,X,
|
||||
///M:Microsoft.Win32.PowerModeChangedEventArgs.get_Mode,Microsoft.Win32,PowerModeChangedEventArgs,get_Mode(),X,X,
|
||||
///"M:Microsoft.Win32.Registry.GetValue(System.String,System.String,System.Object)",Microsoft.Win32,Registry,"GetValue(String, String, Object)",X,X,
|
||||
///"M:Microsoft.Win32.Registry.SetValue(System.String,System.String,S [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string Exceptions {
|
||||
get {
|
||||
|
@ -185,12 +206,11 @@ namespace Microsoft.DotNet.Analyzers.Compatibility {
|
|||
/// <summary>
|
||||
/// Looks up a localized string similar to DocId,Namespace,Type,Member
|
||||
///M:System.AppContext.GetData(System.String),System,AppContext,GetData(String)
|
||||
///P:System.AppContext.TargetFrameworkName,System,AppContext,TargetFrameworkName
|
||||
///M:System.AppContext.get_TargetFrameworkName,System,AppContext,get_TargetFrameworkName()
|
||||
///T:System.StringNormalizationExtensions,System,StringNormalizationExtensions,
|
||||
///T:System.Data.Common.DbColumn,System.Data.Common,DbColumn,
|
||||
///T:System.Data.Common.DbDataReaderExtensions,System.Data.Common,DbDataReaderExtensions,
|
||||
///T:System.Data.Common.IDbColumnSchemaGenerator,System.Data.Common,IDbColumnSchemaGenerator,
|
||||
///T:System [rest of string was truncated]";.
|
||||
///T:System.Data.Common.IDbColumnSchemaGenerator,System.Data.Common,IDbColumnSchemaGenerator, [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string Net461 {
|
||||
get {
|
||||
|
|
|
@ -120,6 +120,14 @@
|
|||
<data name="AboutDiagnosticFormatString" xml:space="preserve">
|
||||
<value>About {0}</value>
|
||||
</data>
|
||||
<data name="BeginInvokeEndInvokeAnalyzerMessageFormat" xml:space="preserve">
|
||||
<value>{0} is unsupported on .NET Core. Use Tasks instead.</value>
|
||||
<comment>The format-able message the diagnostic displays.</comment>
|
||||
</data>
|
||||
<data name="BeginInvokeEndInvokeAnalyzerTitle" xml:space="preserve">
|
||||
<value>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</value>
|
||||
<comment>The title of the diagnostic.</comment>
|
||||
</data>
|
||||
<data name="BrowseToUrlFormat" xml:space="preserve">
|
||||
<value>Browse to {0}</value>
|
||||
</data>
|
||||
|
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -57,6 +57,16 @@
|
|||
<target state="new">Report an issue with {0}</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerMessageFormat">
|
||||
<source>{0} is unsupported on .NET Core. Use Tasks instead.</source>
|
||||
<target state="new">{0} is unsupported on .NET Core. Use Tasks instead.</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="BeginInvokeEndInvokeAnalyzerTitle">
|
||||
<source>Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</source>
|
||||
<target state="new">Delegate.BeginInvoke and EndInvoke are unsuported on .NET Core</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
Загрузка…
Ссылка в новой задаче