提交 b0249eef 编写于 作者: T Ty Overby 提交者: GitHub

Remove remaining prototype comments (#19392)

* remove remaining prototype comments, add extension method tests

* fix old test, address review feedback

* ReturnType implemented on each subclass

* added more tests on non-async task returning mains

* add obsolete tests

* autoformat

* add better tests for successful task overrides
上级 e01e55ab
......@@ -1512,9 +1512,8 @@ bool CheckValid(MethodSymbol candidate, bool isCandidate, DiagnosticBag specific
{
foreach (var (IsValid, Candidate, SpecificDiagnostics) in taskEntryPoints)
{
// PROTOTYPE(async-main): Get the diagnostic to point to a smaller syntax piece.
if (CheckValid(Candidate, IsValid, SpecificDiagnostics) &&
CheckFeatureAvailability(Candidate.GetNonNullSyntaxNode(), MessageID.IDS_FeatureAsyncMain, diagnostics))
CheckFeatureAvailability(Candidate.ExtractReturnTypeSyntax(), MessageID.IDS_FeatureAsyncMain, diagnostics))
{
diagnostics.AddRange(SpecificDiagnostics);
viableEntryPoints.Add(Candidate);
......@@ -1611,7 +1610,6 @@ internal bool ReturnsAwaitableToVoidOrInt(MethodSymbol method, DiagnosticBag dia
var syntax = method.ExtractReturnTypeSyntax();
var dumbInstance = new BoundLiteral(syntax, ConstantValue.Null, method.ReturnType);
// PROTOTYPE(async-main): We might need to adjust the containing member of the binder to be the Main method
var binder = GetBinder(syntax);
BoundExpression result;
var success = binder.GetAwaitableExpressionInfo(dumbInstance, out _, out _, out _, out result, syntax, diagnostics);
......
......@@ -206,9 +206,9 @@ private static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModul
// entryPoint can be a SynthesizedEntryPointSymbol if a script is being compiled.
SynthesizedEntryPointSymbol synthesizedEntryPoint = entryPoint as SynthesizedEntryPointSymbol;
if ((object)synthesizedEntryPoint == null && compilation.ReturnsAwaitableToVoidOrInt(entryPoint, diagnostics))
if ((object)synthesizedEntryPoint == null && (entryPoint.ReturnType.IsGenericTaskType(compilation) || entryPoint.ReturnType.IsNonGenericTaskType(compilation)))
{
synthesizedEntryPoint = new SynthesizedEntryPointSymbol.AsyncForwardEntryPoint(compilation, diagnostics, entryPoint.ContainingType, entryPoint);
synthesizedEntryPoint = new SynthesizedEntryPointSymbol.AsyncForwardEntryPoint(compilation, entryPoint.ContainingType, entryPoint);
entryPoint = synthesizedEntryPoint;
if ((object)moduleBeingBuilt != null)
{
......@@ -221,13 +221,44 @@ private static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModul
!hasDeclarationErrors &&
!diagnostics.HasAnyErrors())
{
var body = synthesizedEntryPoint.CreateBody();
BoundStatement body = synthesizedEntryPoint.CreateBody();
var dynamicAnalysisSpans = ImmutableArray<SourceSpan>.Empty;
VariableSlotAllocator lazyVariableSlotAllocator = null;
var lambdaDebugInfoBuilder = ArrayBuilder<LambdaDebugInfo>.GetInstance();
var closureDebugInfoBuilder = ArrayBuilder<ClosureDebugInfo>.GetInstance();
StateMachineTypeSymbol stateMachineTypeOpt = null;
const int methodOrdinal = -1;
var loweredBody = LowerBodyOrInitializer(
synthesizedEntryPoint,
methodOrdinal,
body,
null,
new TypeCompilationState(synthesizedEntryPoint.ContainingType, compilation, moduleBeingBuilt),
false,
null,
ref dynamicAnalysisSpans,
diagnostics,
ref lazyVariableSlotAllocator,
lambdaDebugInfoBuilder,
closureDebugInfoBuilder,
out stateMachineTypeOpt);
Debug.Assert((object)lazyVariableSlotAllocator == null);
Debug.Assert((object)stateMachineTypeOpt == null);
Debug.Assert(dynamicAnalysisSpans.IsEmpty);
Debug.Assert(lambdaDebugInfoBuilder.IsEmpty());
Debug.Assert(closureDebugInfoBuilder.IsEmpty());
lambdaDebugInfoBuilder.Free();
closureDebugInfoBuilder.Free();
var emittedBody = GenerateMethodBody(
moduleBeingBuilt,
synthesizedEntryPoint,
methodOrdinal,
body,
loweredBody,
ImmutableArray<LambdaDebugInfo>.Empty,
ImmutableArray<ClosureDebugInfo>.Empty,
stateMachineTypeOpt: null,
......
......@@ -19,8 +19,6 @@ internal abstract class SynthesizedEntryPointSymbol : MethodSymbol
internal const string FactoryName = "<Factory>";
private readonly NamedTypeSymbol _containingType;
// PROTOTYPE(async-main): remove this and move it out into inheriting classes?
private TypeSymbol _returnType;
internal static SynthesizedEntryPointSymbol Create(SynthesizedInteractiveInitializerMethod initializerMethod, DiagnosticBag diagnostics)
{
......@@ -57,12 +55,11 @@ internal static SynthesizedEntryPointSymbol Create(SynthesizedInteractiveInitial
}
}
private SynthesizedEntryPointSymbol(NamedTypeSymbol containingType, TypeSymbol returnType = null)
private SynthesizedEntryPointSymbol(NamedTypeSymbol containingType)
{
Debug.Assert((object)containingType != null);
_containingType = containingType;
_returnType = returnType;
}
internal override bool GenerateDebugInfo
......@@ -130,11 +127,6 @@ internal override RefKind RefKind
get { return RefKind.None; }
}
public override TypeSymbol ReturnType
{
get { return _returnType; }
}
public override ImmutableArray<CustomModifier> ReturnTypeCustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
......@@ -162,7 +154,7 @@ public override int Arity
public override bool ReturnsVoid
{
get { return _returnType.SpecialType == SpecialType.System_Void; }
get { return ReturnType.SpecialType == SpecialType.System_Void; }
}
public override MethodKind MethodKind
......@@ -341,7 +333,7 @@ internal sealed class AsyncForwardEntryPoint : SynthesizedEntryPointSymbol
private readonly ImmutableArray<ParameterSymbol> _parameters;
internal AsyncForwardEntryPoint(CSharpCompilation compilation, DiagnosticBag diagnosticBag, NamedTypeSymbol containingType, MethodSymbol userMain) :
internal AsyncForwardEntryPoint(CSharpCompilation compilation, NamedTypeSymbol containingType, MethodSymbol userMain) :
base(containingType)
{
// There should be no way for a userMain to be passed in unless it already passed the
......@@ -349,7 +341,6 @@ internal sealed class AsyncForwardEntryPoint : SynthesizedEntryPointSymbol
Debug.Assert(userMain.ParameterCount == 0 || userMain.ParameterCount == 1);
_userMainReturnTypeSyntax = userMain.ExtractReturnTypeSyntax();
// PROTOTYPE(async-main): we might need to adjust the containing member of the binder to be the Main method.
var binder = compilation.GetBinder(_userMainReturnTypeSyntax);
_parameters = SynthesizedParameterSymbol.DeriveParameters(userMain, this);
......@@ -371,9 +362,10 @@ internal sealed class AsyncForwardEntryPoint : SynthesizedEntryPointSymbol
type: userMain.ReturnType)
{ WasCompilerGenerated = true };
// PROTOTYPE(async-main): lower the tree.
var success = binder.GetAwaitableExpressionInfo(userMainInvocation, out _, out _, out _, out _getAwaiterGetResultCall, _userMainReturnTypeSyntax, diagnosticBag);
_returnType = _getAwaiterGetResultCall.Type;
// The diagnostics that would be produced here will already have been captured and returned.
var droppedBag = DiagnosticBag.GetInstance();
var success = binder.GetAwaitableExpressionInfo(userMainInvocation, out _, out _, out _, out _getAwaiterGetResultCall, _userMainReturnTypeSyntax, droppedBag);
droppedBag.Free();
Debug.Assert(
ReturnType.SpecialType == SpecialType.System_Void ||
......@@ -384,6 +376,8 @@ internal sealed class AsyncForwardEntryPoint : SynthesizedEntryPointSymbol
public override ImmutableArray<ParameterSymbol> Parameters => _parameters;
public override TypeSymbol ReturnType => _getAwaiterGetResultCall.Type;
internal override BoundBlock CreateBody()
{
var syntax = _userMainReturnTypeSyntax;
......@@ -432,21 +426,25 @@ private sealed class ScriptEntryPoint : SynthesizedEntryPointSymbol
{
private readonly MethodSymbol _getAwaiterMethod;
private readonly MethodSymbol _getResultMethod;
private readonly TypeSymbol _returnType;
internal ScriptEntryPoint(NamedTypeSymbol containingType, TypeSymbol returnType, MethodSymbol getAwaiterMethod, MethodSymbol getResultMethod) :
base(containingType, returnType)
base(containingType)
{
Debug.Assert(containingType.IsScriptClass);
Debug.Assert(returnType.SpecialType == SpecialType.System_Void);
_getAwaiterMethod = getAwaiterMethod;
_getResultMethod = getResultMethod;
_returnType = returnType;
}
public override string Name => MainName;
public override ImmutableArray<ParameterSymbol> Parameters => ImmutableArray<ParameterSymbol>.Empty;
public override TypeSymbol ReturnType => _returnType;
// private static void <Main>()
// {
// var script = new Script();
......@@ -516,13 +514,15 @@ internal override BoundBlock CreateBody()
private sealed class SubmissionEntryPoint : SynthesizedEntryPointSymbol
{
private readonly ImmutableArray<ParameterSymbol> _parameters;
private readonly TypeSymbol _returnType;
internal SubmissionEntryPoint(NamedTypeSymbol containingType, TypeSymbol returnType, TypeSymbol submissionArrayType) :
base(containingType, returnType)
base(containingType)
{
Debug.Assert(containingType.IsSubmissionClass);
Debug.Assert(returnType.SpecialType != SpecialType.System_Void);
_parameters = ImmutableArray.Create<ParameterSymbol>(SynthesizedParameterSymbol.Create(this, submissionArrayType, 0, RefKind.None, "submissionArray"));
_returnType = returnType;
}
public override string Name
......@@ -535,6 +535,8 @@ public override ImmutableArray<ParameterSymbol> Parameters
get { return _parameters; }
}
public override TypeSymbol ReturnType => _returnType;
// private static T <Factory>(object[] submissionArray)
// {
// var submission = new Submission#N(submissionArray);
......
......@@ -658,14 +658,33 @@ async static Task Main(string[] args)
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7));
compilation.VerifyDiagnostics(
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1),
// (6,5): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// (6,18): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async static Task Main(string[] args)
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, @"async static Task Main(string[] args)
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task").WithArguments("async main", "7.1").WithLocation(6, 18),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
[Fact]
public void MainCantBeAsyncWithArgs_CSharp7_NoAwait()
{
await Task.Factory.StartNew(() => { });
}").WithArguments("async main", "7.1").WithLocation(6, 5));
var source = @"
using System.Threading.Tasks;
class A
{
static Task Main(string[] args)
{
return Task.Factory.StartNew(() => { });
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7));
compilation.VerifyDiagnostics(
// (6,18): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async static Task Main(string[] args)
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task").WithArguments("async main", "7.1").WithLocation(6, 12),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
[Fact]
......@@ -836,14 +855,33 @@ async static Task<int> Main(string[] args)
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7));
compilation.VerifyDiagnostics(
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1),
// (6,5): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// (6,18): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async static Task<int> Main(string[] args)
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, @"async static Task<int> Main(string[] args)
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task<int>").WithArguments("async main", "7.1").WithLocation(6, 18),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
[Fact]
public void MainCantBeAsyncAndGenericOnInt_WithArgs_Csharp7_NoAsync()
{
return await Task.Factory.StartNew(() => 5);
}").WithArguments("async main", "7.1").WithLocation(6, 5));
var source = @"
using System.Threading.Tasks;
class A
{
static Task<int> Main(string[] args)
{
return Task.Factory.StartNew(() => 5);
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7));
compilation.VerifyDiagnostics(
// (6,18): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async static Task<int> Main(string[] args)
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task<int>").WithArguments("async main", "7.1").WithLocation(6, 12),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
[Fact]
......@@ -901,12 +939,31 @@ async static Task<int> Main()
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7));
compilation.VerifyDiagnostics(
// (6,5): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// (6,18): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async static Task<int> Main()
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, @"async static Task<int> Main()
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task<int>").WithArguments("async main", "7.1").WithLocation(6, 18),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
[Fact]
public void MainCantBeAsyncAndGenericOnInt_CSharp7_NoAsync()
{
return await Task.Factory.StartNew(() => 5);
}").WithArguments("async main", "7.1").WithLocation(6, 5),
var source = @"
using System.Threading.Tasks;
class A
{
static Task<int> Main()
{
return Task.Factory.StartNew(() => 5);
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7));
compilation.VerifyDiagnostics(
// (6,18): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async static Task<int> Main()
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task<int>").WithArguments("async main", "7.1").WithLocation(6, 12),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
......@@ -1146,13 +1203,9 @@ async static Task<float> Main(string[] args)
// (12,30): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
// async static Task<float> Main(string[] args)
Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Main").WithLocation(12, 30),
// (6,5): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// (6,18): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async static Task<int> Main()
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, @"async static Task<int> Main()
{
System.Console.WriteLine(""Task<int>"");
return 0;
}").WithArguments("async main", "7.1").WithLocation(6, 5),
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task<int>").WithArguments("async main", "7.1").WithLocation(6, 18),
// (12,30): warning CS0028: 'A.Main(string[])' has the wrong signature to be an entry point
// async static Task<float> Main(string[] args)
Diagnostic(ErrorCode.WRN_InvalidMainSig, "Main").WithArguments("A.Main(string[])").WithLocation(12, 30),
......@@ -1160,6 +1213,36 @@ async static Task<float> Main(string[] args)
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
[Fact]
public void TaskIntAndTaskFloat_CSharp7_NoAsync()
{
var source = @"
using System.Threading.Tasks;
class A
{
static Task<int> Main()
{
System.Console.WriteLine(""Task<int>"");
return Task.FromResult(0);
}
static Task<float> Main(string[] args)
{
System.Console.WriteLine(""Task<float>"");
return Task.FromResult(0.0F);
}
}";
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseDebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7)).VerifyDiagnostics(
// (6,12): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// static Task<int> Main()
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task<int>").WithArguments("async main", "7.1").WithLocation(6, 12),
// (12,24): warning CS0028: 'A.Main(string[])' has the wrong signature to be an entry point
// static Task<float> Main(string[] args)
Diagnostic(ErrorCode.WRN_InvalidMainSig, "Main").WithArguments("A.Main(string[])").WithLocation(12, 24),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
[Fact]
public void TaskOfFloatMainAndNonTaskMain()
......@@ -1211,5 +1294,169 @@ async static Task<float> Main(string[] args)
var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.ReleaseExe.WithMainTypeName("A")).VerifyDiagnostics();
CompileAndVerify(compilation, expectedOutput: "Non Task Main", expectedReturnCode: 0);
}
[Fact]
public void ImplementGetAwaiterGetResultViaExtensionMethods()
{
var source = @"
using System.Threading.Tasks;
namespace System.Runtime.CompilerServices {
public class ExtensionAttribute {}
}
namespace System.Runtime.CompilerServices {
public interface INotifyCompletion {
void OnCompleted(Action action);
}
}
namespace System.Threading.Tasks {
public class Awaiter: System.Runtime.CompilerServices.INotifyCompletion {
public bool IsCompleted => true;
public void OnCompleted(Action action) {}
public void GetResult() {
System.Console.Write(""GetResult called"");
}
}
public class Task {}
}
public static class MyExtensions {
public static Awaiter GetAwaiter(this Task task) {
System.Console.Write(""GetAwaiter called | "");
return new Awaiter();
}
}
static class Program {
static Task Main() {
return new Task();
}
}";
var sourceCompilation = CreateStandardCompilation(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1));
var verifier = sourceCompilation.VerifyEmitDiagnostics(
// (26,43): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// public static Awaiter GetAwaiter(this Task task) {
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(26, 43),
// (33,12): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// static Task Main() {
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(33, 12),
// (34,20): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// return new Task();
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(34, 20));
CompileAndVerify(sourceCompilation, expectedOutput: "GetAwaiter called | GetResult called");
}
[Fact]
public void ImplementGetAwaiterGetResultViaExtensionMethods_Obsolete()
{
var source = @"
using System.Threading.Tasks;
namespace System.Runtime.CompilerServices {
public class ExtensionAttribute {}
}
namespace System.Runtime.CompilerServices {
public interface INotifyCompletion {
void OnCompleted(Action action);
}
}
namespace System.Threading.Tasks {
public class Awaiter: System.Runtime.CompilerServices.INotifyCompletion {
public bool IsCompleted => true;
public void OnCompleted(Action action) {}
public void GetResult() {
System.Console.Write(""GetResult called"");
}
}
public class Task {}
}
public static class MyExtensions {
[System.Obsolete(""test"")]
public static Awaiter GetAwaiter(this Task task) {
System.Console.Write(""GetAwaiter called | "");
return new Awaiter();
}
}
static class Program {
static Task Main() {
return new Task();
}
}";
var sourceCompilation = CreateStandardCompilation(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1));
var verifier = sourceCompilation.VerifyEmitDiagnostics(
// (34,12): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// static Task Main() {
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(34, 12),
// (27,43): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// public static Awaiter GetAwaiter(this Task task) {
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(27, 43),
// (35,20): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// return new Task();
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(35, 20),
// (34,12): warning CS0618: 'MyExtensions.GetAwaiter(Task)' is obsolete: 'test'
// static Task Main() {
Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "Task").WithArguments("MyExtensions.GetAwaiter(System.Threading.Tasks.Task)", "test").WithLocation(34, 12));
CompileAndVerify(sourceCompilation, expectedOutput: "GetAwaiter called | GetResult called");
}
[Fact]
public void ImplementGetAwaiterGetResultViaExtensionMethods_ObsoleteFailing()
{
var source = @"
using System.Threading.Tasks;
namespace System.Runtime.CompilerServices {
public class ExtensionAttribute {}
}
namespace System.Runtime.CompilerServices {
public interface INotifyCompletion {
void OnCompleted(Action action);
}
}
namespace System.Threading.Tasks {
public class Awaiter: System.Runtime.CompilerServices.INotifyCompletion {
public bool IsCompleted => true;
public void OnCompleted(Action action) {}
public void GetResult() {}
}
public class Task {}
}
public static class MyExtensions {
[System.Obsolete(""test"", true)]
public static Awaiter GetAwaiter(this Task task) {
return null;
}
}
static class Program {
static Task Main() {
return new Task();
}
}";
var sourceCompilation = CreateStandardCompilation(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1));
var verifier = sourceCompilation.VerifyEmitDiagnostics(
// (25,43): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// public static Awaiter GetAwaiter(this Task task) {
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(25, 43),
// (31,12): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// static Task Main() {
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(31, 12),
// (32,20): warning CS0436: The type 'Task' in '' conflicts with the imported type 'Task' in 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''.
// return new Task();
Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Task").WithArguments("", "System.Threading.Tasks.Task", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Threading.Tasks.Task").WithLocation(32, 20),
// (31,12): warning CS0618: 'MyExtensions.GetAwaiter(Task)' is obsolete: 'test'
// static Task Main() {
Diagnostic(ErrorCode.ERR_DeprecatedSymbolStr, "Task").WithArguments("MyExtensions.GetAwaiter(System.Threading.Tasks.Task)", "test").WithLocation(31, 12));
}
}
}
......@@ -3434,11 +3434,9 @@ async public static Task Main()
// (5,30): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
// async public static Task Main()
Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Main").WithLocation(5, 30),
// (5,5): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// (5,25): error CS8107: Feature 'async main' is not available in C# 7. Please use language version 7.1 or greater.
// async public static Task Main()
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, @"async public static Task Main()
{
}").WithArguments("async main", "7.1").WithLocation(5, 5),
Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "Task").WithArguments("async main", "7.1").WithLocation(5, 25),
// error CS5001: Program does not contain a static 'Main' method suitable for an entry point
Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册