|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public class DelegateTests : CSharpTestBase
{
[Fact]
public void MissingTypes()
{
var text =
@"
delegate void A();
";
var comp = CreateEmptyCompilation(text);
comp.VerifyDiagnostics(
// (2,15): error CS0518: Predefined type 'System.MulticastDelegate' is not defined or imported
// delegate void A();
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "A").WithArguments("System.MulticastDelegate"),
// (2,10): error CS0518: Predefined type 'System.Void' is not defined or imported
// delegate void A();
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "void").WithArguments("System.Void"),
// (2,1): error CS0518: Predefined type 'System.Void' is not defined or imported
// delegate void A();
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "delegate void A();").WithArguments("System.Void"),
// (2,1): error CS0518: Predefined type 'System.Object' is not defined or imported
// delegate void A();
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "delegate void A();").WithArguments("System.Object"),
// (2,1): error CS0518: Predefined type 'System.IntPtr' is not defined or imported
// delegate void A();
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "delegate void A();").WithArguments("System.IntPtr")
);
}
[WorkItem(530363, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530363")]
[Fact]
public void MissingAsyncTypes()
{
var source = "delegate void A();";
var comp = CreateEmptyCompilation(
source: new[] { Parse(source) },
references: new[] { MinCorlibRef });
comp.VerifyDiagnostics();
}
[Fact]
public void Simple1()
{
var text =
@"
class A {
delegate void D();
}
";
var comp = CreateCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 0).Single();
var d = a.GetMembers("D")[0] as NamedTypeSymbol;
var tmp = d.GetMembers();
Assert.Equal(d.Locations[0], d.DelegateInvokeMethod.Locations[0], EqualityComparer<Location>.Default);
Assert.Equal(d.Locations[0], d.InstanceConstructors[0].Locations[0], EqualityComparer<Location>.Default);
}
[Fact]
public void Duplicate()
{
var text =
@"
delegate void D(int x);
delegate void D(float y);
";
var comp = CreateCompilation(text);
var diags = comp.GetDeclarationDiagnostics();
Assert.Equal(1, diags.Count());
var global = comp.GlobalNamespace;
var d = global.GetTypeMembers("D", 0);
Assert.Equal(2, d.Length);
}
[Fact]
public void MetadataDelegateField()
{
var text =
@"
class A {
public System.Func<int> Field;
}
";
var comp = CreateCompilation(text);
var global = comp.GlobalNamespace;
var a = global.GetTypeMembers("A", 0).Single();
var field = a.GetMembers("Field")[0] as FieldSymbol;
var fieldType = field.Type as NamedTypeSymbol;
Assert.Equal(TypeKind.Delegate, fieldType.TypeKind);
var invoke = fieldType.DelegateInvokeMethod;
Assert.Equal(MethodKind.DelegateInvoke, invoke.MethodKind);
var ctor = fieldType.InstanceConstructors[0];
Assert.Equal(2, ctor.Parameters.Length);
Assert.Equal(comp.GetSpecialType(SpecialType.System_Object), ctor.Parameters[0].Type);
Assert.Equal(comp.GetSpecialType(SpecialType.System_IntPtr), ctor.Parameters[1].Type);
}
[WorkItem(537188, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537188")]
[Fact]
public void SimpleDelegate()
{
var text =
@"delegate void MyDel(int n);";
var comp = CreateCompilation(text);
var v = comp.GlobalNamespace.GetTypeMembers("MyDel", 0).Single();
Assert.NotNull(v);
Assert.Equal(SymbolKind.NamedType, v.Kind);
Assert.Equal(TypeKind.Delegate, v.TypeKind);
Assert.True(v.IsReferenceType);
Assert.False(v.IsValueType);
Assert.True(v.IsSealed);
Assert.False(v.IsAbstract);
Assert.Equal(0, v.Arity); // number of type parameters
Assert.Equal(1, v.DelegateInvokeMethod.Parameters.Length);
Assert.Equal(Accessibility.Internal, v.DeclaredAccessibility);
Assert.Equal("System.MulticastDelegate", v.BaseType().ToTestDisplayString());
}
[WorkItem(537188, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537188")]
[WorkItem(538707, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538707")]
[Fact]
public void BeginInvokeEndInvoke()
{
var text = @"
delegate int MyDel(int x, ref int y, out int z);
namespace System
{
interface IAsyncResult {}
}
";
var comp = CreateCompilation(text);
var global = comp.GlobalNamespace;
var myDel = global.GetTypeMembers("MyDel", 0).Single() as NamedTypeSymbol;
var invoke = myDel.DelegateInvokeMethod;
var beginInvoke = myDel.GetMembers("BeginInvoke").Single() as MethodSymbol;
Assert.Equal(invoke.Parameters.Length + 2, beginInvoke.Parameters.Length);
Assert.Equal(TypeKind.Interface, beginInvoke.ReturnType.TypeKind);
Assert.Equal("System.IAsyncResult", beginInvoke.ReturnType.ToTestDisplayString());
for (int i = 0; i < invoke.Parameters.Length; i++)
{
Assert.Equal(invoke.Parameters[i].Type, beginInvoke.Parameters[i].Type);
Assert.Equal(invoke.Parameters[i].RefKind, beginInvoke.Parameters[i].RefKind);
}
var lastParameterType = beginInvoke.Parameters[invoke.Parameters.Length].Type;
Assert.Equal("System.AsyncCallback", lastParameterType.ToTestDisplayString());
Assert.Equal(SpecialType.System_AsyncCallback, lastParameterType.SpecialType);
Assert.Equal("System.Object", beginInvoke.Parameters[invoke.Parameters.Length + 1].Type.ToTestDisplayString());
var endInvoke = myDel.GetMembers("EndInvoke").Single() as MethodSymbol;
Assert.Equal(invoke.ReturnType, endInvoke.ReturnType);
int k = 0;
for (int i = 0; i < invoke.Parameters.Length; i++)
{
if (invoke.Parameters[i].RefKind != RefKind.None)
{
Assert.Equal(invoke.Parameters[i].Type, endInvoke.Parameters[k].Type);
Assert.Equal(invoke.Parameters[i].RefKind, endInvoke.Parameters[k++].RefKind);
}
}
lastParameterType = endInvoke.Parameters[k++].Type;
Assert.Equal("System.IAsyncResult", lastParameterType.ToTestDisplayString());
Assert.Equal(SpecialType.System_IAsyncResult, lastParameterType.SpecialType);
Assert.Equal(k, endInvoke.Parameters.Length);
}
[WorkItem(537188, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537188")]
[Fact]
public void GenericDelegate()
{
var text =
@"namespace NS
{
internal delegate void D<Q>(Q q);
}";
var comp = CreateCompilation(text);
var namespaceNS = comp.GlobalNamespace.GetMembers("NS").First() as NamespaceOrTypeSymbol;
Assert.Equal(1, namespaceNS.GetTypeMembers().Length);
var d = namespaceNS.GetTypeMembers("D").First();
Assert.Equal(namespaceNS, d.ContainingSymbol);
Assert.Equal(SymbolKind.NamedType, d.Kind);
Assert.Equal(TypeKind.Delegate, d.TypeKind);
Assert.Equal(Accessibility.Internal, d.DeclaredAccessibility);
Assert.Equal(1, d.TypeParameters.Length);
Assert.Equal("Q", d.TypeParameters[0].Name);
var q = d.TypeParameters[0];
Assert.Equal(q.ContainingSymbol, d);
Assert.Equal(d.DelegateInvokeMethod.Parameters[0].Type, q);
// same as type parameter
Assert.Equal(1, d.TypeArguments().Length);
}
[WorkItem(537401, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537401")]
[Fact]
public void DelegateEscapedIdentifier()
{
var text = @"
delegate void @out();
";
var comp = CreateCompilation(Parse(text));
NamedTypeSymbol dout = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("out").Single();
Assert.Equal("out", dout.Name);
Assert.Equal("@out", dout.ToString());
}
[Fact]
public void DelegatesEverywhere()
{
var text = @"
using System;
delegate int Intf(int x);
class C
{
Intf I;
Intf Method(Intf f1)
{
Intf i = f1;
i = f1;
I = i;
i = I;
Delegate d1 = f1;
MulticastDelegate m1 = f1;
object o1 = f1;
f1 = i;
return f1;
}
}
";
CreateCompilation(text).VerifyDiagnostics();
}
[Fact]
public void DelegateCreation()
{
var text = @"
namespace CSSample
{
class Program
{
static void Main(string[] args)
{
}
delegate void D1();
delegate void D2();
delegate int D3(int x);
static D1 d1;
static D2 d2;
static D3 d3;
internal virtual void V() { }
void M() { }
static void S() { }
static int M2(int x) { return x; }
static void F(Program p)
{
// Good cases
d2 = new D2(d1);
d1 = new D1(d2);
d1 = new D1(d2.Invoke);
d1 = new D1(d1);
d1 = new D1(p.V);
d1 = new D1(p.M);
d1 = new D1(S);
}
}
}
";
CreateCompilation(text).VerifyDiagnostics(
// (17,19): warning CS0169: The field 'CSSample.Program.d3' is never used
// static D3 d3;
Diagnostic(ErrorCode.WRN_UnreferencedField, "d3").WithArguments("CSSample.Program.d3"));
}
[WorkItem(538722, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538722")]
[Fact]
public void MulticastIsNotDelegate()
{
var text = @"
using System;
class Program
{
static void Main()
{
MulticastDelegate d = Main;
}
}
";
CreateCompilation(text, parseOptions: TestOptions.Regular9).VerifyDiagnostics(
// (7,27): error CS0428: Cannot convert method group 'Main' to non-delegate type 'System.MulticastDelegate'. Did you intend to invoke the method?
Diagnostic(ErrorCode.ERR_MethGrpToNonDel, "Main").WithArguments("Main", "System.MulticastDelegate"));
CreateCompilation(text).VerifyDiagnostics();
}
[WorkItem(538706, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538706")]
[Fact]
public void DelegateMethodParameterNames()
{
var text = @"
delegate int D(int x, ref int y, out int z);
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics();
NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single();
MethodSymbol invoke = d.DelegateInvokeMethod;
ImmutableArray<ParameterSymbol> invokeParameters = invoke.Parameters;
Assert.Equal(3, invokeParameters.Length);
Assert.Equal("x", invokeParameters[0].Name);
Assert.Equal("y", invokeParameters[1].Name);
Assert.Equal("z", invokeParameters[2].Name);
MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single();
ImmutableArray<ParameterSymbol> beginInvokeParameters = beginInvoke.Parameters;
Assert.Equal(5, beginInvokeParameters.Length);
Assert.Equal("x", beginInvokeParameters[0].Name);
Assert.Equal("y", beginInvokeParameters[1].Name);
Assert.Equal("z", beginInvokeParameters[2].Name);
Assert.Equal("callback", beginInvokeParameters[3].Name);
Assert.Equal("object", beginInvokeParameters[4].Name);
MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single();
ImmutableArray<ParameterSymbol> endInvokeParameters = endInvoke.Parameters;
Assert.Equal(3, endInvokeParameters.Length);
Assert.Equal("y", endInvokeParameters[0].Name);
Assert.Equal("z", endInvokeParameters[1].Name);
Assert.Equal("result", endInvokeParameters[2].Name);
}
[WorkItem(541179, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541179")]
[Fact]
public void DelegateWithTypeParameterNamedInvoke()
{
var text = @"
delegate void F<Invoke>(Invoke i);
class Goo
{
void M(int i)
{
F<int> x = M;
}
}
";
CreateCompilation(text).VerifyDiagnostics();
}
[WorkItem(612002, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/612002")]
[Fact]
public void DelegateWithOutParameterNamedResult()
{
var text = @"
delegate void D(out int result);
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics();
NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single();
MethodSymbol invoke = d.DelegateInvokeMethod;
ImmutableArray<ParameterSymbol> invokeParameters = invoke.Parameters;
Assert.Equal(1, invokeParameters.Length);
Assert.Equal("result", invokeParameters[0].Name);
MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single();
ImmutableArray<ParameterSymbol> beginInvokeParameters = beginInvoke.Parameters;
Assert.Equal(3, beginInvokeParameters.Length);
Assert.Equal("result", beginInvokeParameters[0].Name);
Assert.Equal("callback", beginInvokeParameters[1].Name);
Assert.Equal("object", beginInvokeParameters[2].Name);
MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single();
ImmutableArray<ParameterSymbol> endInvokeParameters = endInvoke.Parameters;
Assert.Equal(2, endInvokeParameters.Length);
Assert.Equal("result", endInvokeParameters[0].Name);
Assert.Equal("__result", endInvokeParameters[1].Name);
}
[WorkItem(612002, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/612002")]
[Fact]
public void DelegateWithOutParameterNamedResult2()
{
var text = @"
delegate void D(out int @__result);
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics();
NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single();
MethodSymbol invoke = d.DelegateInvokeMethod;
ImmutableArray<ParameterSymbol> invokeParameters = invoke.Parameters;
Assert.Equal(1, invokeParameters.Length);
Assert.Equal("__result", invokeParameters[0].Name);
MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single();
ImmutableArray<ParameterSymbol> beginInvokeParameters = beginInvoke.Parameters;
Assert.Equal(3, beginInvokeParameters.Length);
Assert.Equal("__result", beginInvokeParameters[0].Name);
Assert.Equal("callback", beginInvokeParameters[1].Name);
Assert.Equal("object", beginInvokeParameters[2].Name);
MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single();
ImmutableArray<ParameterSymbol> endInvokeParameters = endInvoke.Parameters;
Assert.Equal(2, endInvokeParameters.Length);
Assert.Equal("__result", endInvokeParameters[0].Name);
Assert.Equal("result", endInvokeParameters[1].Name);
}
[WorkItem(612002, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/612002")]
[Fact]
public void DelegateWithOutParameterNamedResult3()
{
var text = @"
delegate void D(out int result, out int @__result);
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics();
NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single();
MethodSymbol invoke = d.DelegateInvokeMethod;
ImmutableArray<ParameterSymbol> invokeParameters = invoke.Parameters;
Assert.Equal(2, invokeParameters.Length);
Assert.Equal("result", invokeParameters[0].Name);
Assert.Equal("__result", invokeParameters[1].Name);
MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single();
ImmutableArray<ParameterSymbol> beginInvokeParameters = beginInvoke.Parameters;
Assert.Equal(4, beginInvokeParameters.Length);
Assert.Equal("result", invokeParameters[0].Name);
Assert.Equal("__result", invokeParameters[1].Name);
Assert.Equal("callback", beginInvokeParameters[2].Name);
Assert.Equal("object", beginInvokeParameters[3].Name);
MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single();
ImmutableArray<ParameterSymbol> endInvokeParameters = endInvoke.Parameters;
Assert.Equal(3, endInvokeParameters.Length);
Assert.Equal("result", endInvokeParameters[0].Name);
Assert.Equal("__result", endInvokeParameters[1].Name);
Assert.Equal("____result", endInvokeParameters[2].Name);
}
[WorkItem(612002, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/612002")]
[Fact]
public void DelegateWithParametersNamedCallbackAndObject()
{
var text = @"
delegate void D(int callback, int @object);
";
var comp = CreateCompilation(text);
comp.VerifyDiagnostics();
NamedTypeSymbol d = (NamedTypeSymbol)comp.SourceModule.GlobalNamespace.GetMembers("D").Single();
MethodSymbol invoke = d.DelegateInvokeMethod;
ImmutableArray<ParameterSymbol> invokeParameters = invoke.Parameters;
Assert.Equal(2, invokeParameters.Length);
Assert.Equal("callback", invokeParameters[0].Name);
Assert.Equal("object", invokeParameters[1].Name);
MethodSymbol beginInvoke = (MethodSymbol)d.GetMembers("BeginInvoke").Single();
ImmutableArray<ParameterSymbol> beginInvokeParameters = beginInvoke.Parameters;
Assert.Equal(4, beginInvokeParameters.Length);
Assert.Equal("callback", beginInvokeParameters[0].Name);
Assert.Equal("object", beginInvokeParameters[1].Name);
Assert.Equal("__callback", beginInvokeParameters[2].Name);
Assert.Equal("__object", beginInvokeParameters[3].Name);
MethodSymbol endInvoke = (MethodSymbol)d.GetMembers("EndInvoke").Single();
ImmutableArray<ParameterSymbol> endInvokeParameters = endInvoke.Parameters;
Assert.Equal(1, endInvokeParameters.Length);
Assert.Equal("result", endInvokeParameters[0].Name);
}
[Fact]
public void DelegateConversion()
{
var text = @"
public class A { }
public class B { }
public class C<T> { }
public class DelegateTest
{
public static void FT<T>(T t) { }
public static void FTT<T>(T t1, T t2) { }
public static void FTi<T>(T t, int x) { }
public static void FST<S, T>(S s, T t) { }
public static void FCT<T>(C<T> c) { }
public static void PT<T>(params T[] args) { }
public static void PTT<T>(T t, params T[] arr) { }
public static void PST<S, T>(S s, params T[] arr) { }
public delegate void Da(A x);
public delegate void Daa(A x, A y);
public delegate void Dab(A x, B y);
public delegate void Dai(A x, int y);
public delegate void Dpa(A[] x);
public delegate void Dapa(A x, A[] y);
public delegate void Dapb(A x, B[] y);
public delegate void Dpapa(A[] x, A[] y);
public delegate void Dca(C<A> x);
public delegate void D1<T>(T t);
public static void Run()
{
Da da;
Daa daa;
Dai dai;
Dab dab;
Dpa dpa;
Dapa dapa;
Dapb dapb;
Dpapa dpapa;
Dca dca;
da = new Da(FTT);
da = new Da(FCT);
da = new Da(PT);
daa = new Daa(FT);
daa = new Daa(FTi);
daa = new Daa(PTT);
daa = new Daa(PST);
dai = new Dai(FT);
dai = new Dai(FTT);
dai = new Dai(PTT);
dai = new Dai(PST);
dab = new Dab(FT);
dab = new Dab(FTT);
dab = new Dab(FTi);
dab = new Dab(PTT);
dab = new Dab(PST);
dpa = new Dpa(FTT);
dpa = new Dpa(FCT);
dapa = new Dapa(FT);
dapa = new Dapa(FTT);
dapb = new Dapb(FT);
dapb = new Dapb(FTT);
dapb = new Dapb(PTT);
dpapa = new Dpapa(FT);
dpapa = new Dpapa(PTT);
dca = new Dca(FTT);
dca = new Dca(PT);
RunG(null);
}
public static void RunG<T>(T t) { }
}
";
CreateCompilation(text).VerifyDiagnostics(
// (44,14): error CS0123: No overload for 'FTT' matches delegate 'DelegateTest.Da'
// da = new Da(FTT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Da(FTT)").WithArguments("FTT", "DelegateTest.Da").WithLocation(44, 14),
// (45,21): error CS0411: The type arguments for method 'DelegateTest.FCT<T>(C<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// da = new Da(FCT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "FCT").WithArguments("DelegateTest.FCT<T>(C<T>)").WithLocation(45, 21),
// (46,21): error CS0411: The type arguments for method 'DelegateTest.PT<T>(params T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// da = new Da(PT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "PT").WithArguments("DelegateTest.PT<T>(params T[])").WithLocation(46, 21),
// (48,15): error CS0123: No overload for 'FT' matches delegate 'DelegateTest.Daa'
// daa = new Daa(FT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Daa(FT)").WithArguments("FT", "DelegateTest.Daa").WithLocation(48, 15),
// (49,15): error CS0123: No overload for 'FTi' matches delegate 'DelegateTest.Daa'
// daa = new Daa(FTi);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Daa(FTi)").WithArguments("FTi", "DelegateTest.Daa").WithLocation(49, 15),
// (50,15): error CS0123: No overload for 'PTT' matches delegate 'DelegateTest.Daa'
// daa = new Daa(PTT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Daa(PTT)").WithArguments("PTT", "DelegateTest.Daa").WithLocation(50, 15),
// (51,23): error CS0411: The type arguments for method 'DelegateTest.PST<S, T>(S, params T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// daa = new Daa(PST);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "PST").WithArguments("DelegateTest.PST<S, T>(S, params T[])").WithLocation(51, 23),
// (53,15): error CS0123: No overload for 'FT' matches delegate 'DelegateTest.Dai'
// dai = new Dai(FT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dai(FT)").WithArguments("FT", "DelegateTest.Dai").WithLocation(53, 15),
// (54,23): error CS0411: The type arguments for method 'DelegateTest.FTT<T>(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dai = new Dai(FTT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "FTT").WithArguments("DelegateTest.FTT<T>(T, T)").WithLocation(54, 23),
// (55,15): error CS0123: No overload for 'PTT' matches delegate 'DelegateTest.Dai'
// dai = new Dai(PTT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dai(PTT)").WithArguments("PTT", "DelegateTest.Dai").WithLocation(55, 15),
// (56,23): error CS0411: The type arguments for method 'DelegateTest.PST<S, T>(S, params T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dai = new Dai(PST);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "PST").WithArguments("DelegateTest.PST<S, T>(S, params T[])").WithLocation(56, 23),
// (58,15): error CS0123: No overload for 'FT' matches delegate 'DelegateTest.Dab'
// dab = new Dab(FT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dab(FT)").WithArguments("FT", "DelegateTest.Dab").WithLocation(58, 15),
// (59,23): error CS0411: The type arguments for method 'DelegateTest.FTT<T>(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dab = new Dab(FTT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "FTT").WithArguments("DelegateTest.FTT<T>(T, T)").WithLocation(59, 23),
// (60,15): error CS0123: No overload for 'FTi' matches delegate 'DelegateTest.Dab'
// dab = new Dab(FTi);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dab(FTi)").WithArguments("FTi", "DelegateTest.Dab").WithLocation(60, 15),
// (61,15): error CS0123: No overload for 'PTT' matches delegate 'DelegateTest.Dab'
// dab = new Dab(PTT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dab(PTT)").WithArguments("PTT", "DelegateTest.Dab").WithLocation(61, 15),
// (62,23): error CS0411: The type arguments for method 'DelegateTest.PST<S, T>(S, params T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dab = new Dab(PST);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "PST").WithArguments("DelegateTest.PST<S, T>(S, params T[])").WithLocation(62, 23),
// (64,15): error CS0123: No overload for 'FTT' matches delegate 'DelegateTest.Dpa'
// dpa = new Dpa(FTT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dpa(FTT)").WithArguments("FTT", "DelegateTest.Dpa").WithLocation(64, 15),
// (65,23): error CS0411: The type arguments for method 'DelegateTest.FCT<T>(C<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dpa = new Dpa(FCT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "FCT").WithArguments("DelegateTest.FCT<T>(C<T>)").WithLocation(65, 23),
// (67,16): error CS0123: No overload for 'FT' matches delegate 'DelegateTest.Dapa'
// dapa = new Dapa(FT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dapa(FT)").WithArguments("FT", "DelegateTest.Dapa").WithLocation(67, 16),
// (68,25): error CS0411: The type arguments for method 'DelegateTest.FTT<T>(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dapa = new Dapa(FTT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "FTT").WithArguments("DelegateTest.FTT<T>(T, T)").WithLocation(68, 25),
// (70,16): error CS0123: No overload for 'FT' matches delegate 'DelegateTest.Dapb'
// dapb = new Dapb(FT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dapb(FT)").WithArguments("FT", "DelegateTest.Dapb").WithLocation(70, 16),
// (71,25): error CS0411: The type arguments for method 'DelegateTest.FTT<T>(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dapb = new Dapb(FTT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "FTT").WithArguments("DelegateTest.FTT<T>(T, T)").WithLocation(71, 25),
// (72,25): error CS0411: The type arguments for method 'DelegateTest.PTT<T>(T, params T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dapb = new Dapb(PTT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "PTT").WithArguments("DelegateTest.PTT<T>(T, params T[])").WithLocation(72, 25),
// (74,17): error CS0123: No overload for 'FT' matches delegate 'DelegateTest.Dpapa'
// dpapa = new Dpapa(FT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dpapa(FT)").WithArguments("FT", "DelegateTest.Dpapa").WithLocation(74, 17),
// (75,27): error CS0411: The type arguments for method 'DelegateTest.PTT<T>(T, params T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dpapa = new Dpapa(PTT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "PTT").WithArguments("DelegateTest.PTT<T>(T, params T[])").WithLocation(75, 27),
// (77,15): error CS0123: No overload for 'FTT' matches delegate 'DelegateTest.Dca'
// dca = new Dca(FTT);
Diagnostic(ErrorCode.ERR_MethDelegateMismatch, "new Dca(FTT)").WithArguments("FTT", "DelegateTest.Dca").WithLocation(77, 15),
// (78,23): error CS0411: The type arguments for method 'DelegateTest.PT<T>(params T[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// dca = new Dca(PT);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "PT").WithArguments("DelegateTest.PT<T>(params T[])").WithLocation(78, 23),
// (80,9): error CS0411: The type arguments for method 'DelegateTest.RunG<T>(T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
// RunG(null);
Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "RunG").WithArguments("DelegateTest.RunG<T>(T)").WithLocation(80, 9));
}
[Fact]
public void CastFromMulticastDelegate()
{
var source =
@"using System;
delegate void D();
class Program
{
public static void Main(string[] args)
{
MulticastDelegate d = null;
D d2 = (D)d;
}
}
";
CreateCompilation(source).VerifyDiagnostics();
}
[WorkItem(634014, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/634014")]
[Fact]
public void DelegateTest634014()
{
var source =
@"delegate void D(ref int x);
class C
{
D d = async delegate { };
}";
CreateCompilation(source).VerifyDiagnostics(
// (4,17): error CS1988: Async methods cannot have ref, in or out parameters
// D d = async delegate { };
Diagnostic(ErrorCode.ERR_BadAsyncArgType, "delegate").WithLocation(4, 17),
// (4,17): 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.
// D d = async delegate { };
Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "delegate").WithLocation(4, 17));
}
[Fact]
public void AnonymousMethodWithRefParameter()
{
var source =
@"delegate void D(ref int x);
class C
{
D d = delegate { };
}";
var comp = CreateCompilation(source).VerifyDiagnostics();
var syntaxTree = comp.SyntaxTrees.Single();
var root = syntaxTree.GetRoot();
var model = comp.GetSemanticModel(syntaxTree);
var anonymousMethod = root.DescendantNodes().OfType<AnonymousMethodExpressionSyntax>().Single();
Assert.Equal("delegate { }", anonymousMethod.ToString());
var parameter = model.GetSymbolInfo(anonymousMethod).Symbol.GetParameters()[0];
Assert.Equal("ref System.Int32 <p0>", parameter.ToTestDisplayString());
Assert.Equal(RefKind.Ref, parameter.RefKind);
}
[Fact]
public void AnonymousMethodWithOutParameter()
{
var source =
@"delegate void D(out int x);
class C
{
D d = delegate { };
}";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (4,11): error CS1688: Cannot convert anonymous method block without a parameter list to delegate type 'D' because it has one or more out parameters
// D d = delegate { };
Diagnostic(ErrorCode.ERR_CantConvAnonMethNoParams, "delegate").WithArguments("D").WithLocation(4, 11));
var syntaxTree = comp.SyntaxTrees.Single();
var root = syntaxTree.GetRoot();
var model = comp.GetSemanticModel(syntaxTree);
var anonymousMethod = root.DescendantNodes().OfType<AnonymousMethodExpressionSyntax>().Single();
Assert.Equal("delegate { }", anonymousMethod.ToString());
Assert.Empty(model.GetSymbolInfo(anonymousMethod).Symbol.GetParameters());
}
[Fact]
public void RefReturningDelegate()
{
var source = @"delegate ref int D();";
var comp = CreateCompilationWithMscorlib461(source);
comp.VerifyDiagnostics();
var global = comp.GlobalNamespace;
var d = global.GetMembers("D")[0] as NamedTypeSymbol;
Assert.True(d.DelegateInvokeMethod.ReturnsByRef);
Assert.False(d.DelegateInvokeMethod.ReturnsByRefReadonly);
Assert.Equal(RefKind.Ref, d.DelegateInvokeMethod.RefKind);
Assert.Equal(RefKind.Ref, ((MethodSymbol)d.GetMembers("EndInvoke").Single()).RefKind);
}
[Fact]
[CompilerTrait(CompilerFeature.ReadOnlyReferences)]
public void RefReadonlyReturningDelegate()
{
var source = @"delegate ref readonly int D(in int arg);";
var comp = CreateCompilationWithMscorlib461(source);
comp.VerifyDiagnostics();
var global = comp.GlobalNamespace;
var d = global.GetMembers("D")[0] as NamedTypeSymbol;
Assert.False(d.DelegateInvokeMethod.ReturnsByRef);
Assert.True(d.DelegateInvokeMethod.ReturnsByRefReadonly);
Assert.Equal(RefKind.RefReadOnly, d.DelegateInvokeMethod.RefKind);
Assert.Equal(RefKind.RefReadOnly, ((MethodSymbol)d.GetMembers("EndInvoke").Single()).RefKind);
Assert.Equal(RefKind.In, d.DelegateInvokeMethod.Parameters[0].RefKind);
}
[Fact]
[CompilerTrait(CompilerFeature.ReadOnlyReferences)]
public void RefReadonlysInlambda()
{
var source = @"
class C
{
public delegate ref readonly T DD<T>(in T arg);
public static void Main()
{
DD<int> d1 = (in int a) => ref a;
DD<int> d2 = delegate(in int a){return ref a;};
}
}";
var tree = SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.Regular);
var compilation = CreateCompilationWithMscorlib461(new SyntaxTree[] { tree }).VerifyDiagnostics();
var model = compilation.GetSemanticModel(tree);
ExpressionSyntax lambdaSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ParenthesizedLambdaExpressionSyntax>().Single();
var lambda = (IMethodSymbol)model.GetSymbolInfo(lambdaSyntax).Symbol;
Assert.False(lambda.ReturnsByRef);
Assert.True(lambda.ReturnsByRefReadonly);
Assert.Equal(RefKind.In, lambda.Parameters[0].RefKind);
lambdaSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType<AnonymousMethodExpressionSyntax>().Single();
lambda = (IMethodSymbol)model.GetSymbolInfo(lambdaSyntax).Symbol;
Assert.False(lambda.ReturnsByRef);
Assert.True(lambda.ReturnsByRefReadonly);
Assert.Equal(RefKind.In, lambda.Parameters[0].RefKind);
}
[Fact]
public void PartialPublicDelegate()
{
CreateCompilation("partial public delegate void M();").VerifyDiagnostics(
// (1,1): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'record', 'struct', 'interface', or a method return type.
// partial public delegate void M();
Diagnostic(ErrorCode.ERR_PartialMisplaced, "partial").WithLocation(1, 1),
// (1,30): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'record', 'struct', 'interface', or a method return type.
// partial public delegate void M();
Diagnostic(ErrorCode.ERR_PartialMisplaced, "M").WithLocation(1, 30));
}
[Fact]
public void PublicPartialDelegate()
{
CreateCompilation("public partial delegate void M();").VerifyDiagnostics(
// (1,30): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'record', 'struct', 'interface', or a method return type.
// public partial delegate void M();
Diagnostic(ErrorCode.ERR_PartialMisplaced, "M").WithLocation(1, 30));
}
[Fact]
public void PartialDelegate()
{
CreateCompilation("public partial delegate void M();").VerifyDiagnostics(
// (1,30): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'record', 'struct', 'interface', or a method return type.
// public partial delegate void M();
Diagnostic(ErrorCode.ERR_PartialMisplaced, "M").WithLocation(1, 30));
}
}
}
|