Skip to content

Commit 500f24f

Browse files
authored
C# params interop tests (#17495)
* C# params interop tests * One more test
1 parent 0787ef6 commit 500f24f

File tree

8 files changed

+222
-127
lines changed

8 files changed

+222
-127
lines changed

tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@
250250
<Compile Include="Interop\StaticsInInterfaces.fs" />
251251
<Compile Include="Interop\VisibilityTests.fs" />
252252
<Compile Include="Interop\ByrefTests.fs" />
253+
<Compile Include="Interop\ParamArrayMigrated.fs" />
254+
<Compile Include="Interop\ParamArray.fs" />
253255
<Compile Include="Scripting\Interactive.fs" />
254256
<Compile Include="TypeChecks\SeqTypeCheckTests.fs" />
255257
<Compile Include="TypeChecks\CheckDeclarationsTests.fs" />
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace Interop
4+
5+
open Xunit
6+
open FSharp.Test
7+
open FSharp.Test.Compiler
8+
9+
module ParamArray =
10+
11+
[<Fact>]
12+
let ``C# 13 params enhancements`` () =
13+
let csharp =
14+
CSharp """
15+
using System;
16+
using System.Collections.Generic;
17+
18+
namespace CSharpAssembly;
19+
20+
public class CS13ParamArray
21+
{
22+
public static void WriteNames(params string[] names)
23+
=> Console.WriteLine("First: " + string.Join(" + ", names));
24+
25+
public static void WriteNames(params List<string> names)
26+
=> Console.WriteLine("Second: " + string.Join(" + ", names));
27+
28+
public static void WriteNames(params IEnumerable<string> names)
29+
=> Console.WriteLine("Third: " + string.Join(" + ", names));
30+
}"""
31+
|> withCSharpLanguageVersionPreview
32+
33+
FSharp """
34+
open System.Collections.Generic;
35+
open CSharpAssembly
36+
37+
CS13ParamArray.WriteNames("Petr", "Jana")
38+
CS13ParamArray.WriteNames(List["Petr"; "Jana"])
39+
CS13ParamArray.WriteNames(["Petr"; "Jana"])
40+
"""
41+
|> withReferences [csharp]
42+
|> compileExeAndRun
43+
|> shouldSucceed
44+
|> withStdOutContainsAllInOrder [
45+
"First: Petr + Jana"
46+
"Second: Petr + Jana"
47+
"Third: Petr + Jana"
48+
]
49+
50+
[<FactForNETCOREAPP>]
51+
let ``C# 13 params enhancements - ReadOnlySpan`` () =
52+
let csharp =
53+
CSharp """
54+
using System;
55+
56+
namespace CSharpAssembly;
57+
58+
public class CS13ParamArray
59+
{
60+
public static void WriteNames(params ReadOnlySpan<string> names)
61+
=> Console.WriteLine(string.Join(" + ", names));
62+
}"""
63+
|> withCSharpLanguageVersionPreview
64+
65+
FSharp """
66+
open System
67+
open CSharpAssembly
68+
69+
CS13ParamArray.WriteNames(ReadOnlySpan([|"Petr"; "Jana"|]))
70+
"""
71+
|> withReferences [csharp]
72+
|> compileExeAndRun
73+
|> shouldSucceed
74+
|> withStdOutContainsAllInOrder [ "Petr + Jana" ]
75+
76+
[<Fact>]
77+
let ``C# 13 params enhancements - error when no matching overload is available`` () =
78+
let csharp =
79+
CSharp """
80+
using System;
81+
using System.Collections.Generic;
82+
83+
namespace CSharpAssembly;
84+
85+
public class CS13ParamArray
86+
{
87+
public static void WriteNames(params List<string> names)
88+
=> Console.WriteLine("Second: " + string.Join(" + ", names));
89+
90+
public static void WriteNames(params IEnumerable<string> names)
91+
=> Console.WriteLine("Third: " + string.Join(" + ", names));
92+
}"""
93+
|> withCSharpLanguageVersionPreview
94+
95+
FSharp """
96+
open CSharpAssembly
97+
98+
CS13ParamArray.WriteNames("Petr", "Jana")
99+
"""
100+
|> withReferences [csharp]
101+
|> asExe
102+
|> compile
103+
|> shouldFail
104+
|> withDiagnostics [
105+
(Error 503, Line 4, Col 1, Line 4, Col 42,
106+
"A member or object constructor 'WriteNames' taking 2 arguments is not accessible from this code location. All accessible versions of method 'WriteNames' take 1 arguments.")
107+
]
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace Interop
4+
5+
open Xunit
6+
open FSharp.Test.Compiler
7+
8+
module ParamArrayMigrated =
9+
10+
let csharp =
11+
CSharp """
12+
using System;
13+
14+
namespace CSharpAssembly
15+
{
16+
[AttributeUsage(AttributeTargets.All)]
17+
public class AttributeWithParamArray : Attribute
18+
{
19+
public object[] Parameters;
20+
21+
public AttributeWithParamArray(params object[] x)
22+
{
23+
24+
Parameters = x;
25+
}
26+
}
27+
28+
public class CSParamArray
29+
{
30+
public static int Method(params int[] allArgs)
31+
{
32+
int total = 0;
33+
foreach (int i in allArgs)
34+
total += i;
35+
36+
return total;
37+
}
38+
39+
public static int Method<T>(params T[] args)
40+
{
41+
return args.Length;
42+
}
43+
}
44+
}"""
45+
46+
[<Fact>]
47+
let ``Valid params call`` () =
48+
FSharp """
49+
open System
50+
open CSharpAssembly
51+
52+
// Apply the attribute
53+
[<AttributeWithParamArray([| (0 :> obj) |])>]
54+
type Foo() =
55+
[<AttributeWithParamArray([| ("foo" :> obj); ("bar" :> obj) |])>]
56+
override this.ToString() = "Stuff"
57+
58+
let callCSGenericMethod (a: 't[]) = CSParamArray.Method(a)
59+
60+
[<assembly:AttributeWithParamArray ([| |])>]
61+
do
62+
let getTestAttribute (t : Type) =
63+
let tyAttributes = t.GetCustomAttributes(false)
64+
let attrib = tyAttributes |> Array.find (fun attrib -> match attrib with :? AttributeWithParamArray -> true | _ -> false)
65+
(attrib :?> AttributeWithParamArray)
66+
67+
let tyFoo = typeof<Foo>
68+
let testAtt = getTestAttribute tyFoo
69+
if testAtt.Parameters <> [| (0 :> obj) |] then
70+
failwith "Attribute parameters not as expected"
71+
72+
let directCallWorks =
73+
CSParamArray.Method(9, 8, 7) + CSParamArray.Method(1, 2) + CSParamArray.Method() = (9 + 8 + 7) + (1 + 2)
74+
if not directCallWorks then
75+
failwith "Calling C# param array method gave unexpected result"
76+
77+
let callParamArray (x : int array) = CSParamArray.Method(x)
78+
let asArrayCallWorks = (callParamArray [| 9; 8; 7 |]) = (9 + 8 + 7)
79+
if not asArrayCallWorks then
80+
failwith "Calling C# param array method, passing args as an array, gave unexpected result"
81+
82+
if callCSGenericMethod [|"1";"2";"3"|] <> 3 then
83+
failwith "Calling C# generic param array method gave unexpected result"
84+
85+
if CSParamArray.Method("1", "2", "3") <> CSParamArray.Method([|"1"; "2"; "3"|]) then
86+
failwith "Calling C# generic param array in normal and expanded method gave unexpected result"
87+
"""
88+
|> withReferences [csharp]
89+
|> compileExeAndRun
90+
|> shouldSucceed
91+
92+
[<Fact>]
93+
let ``Invalid params call`` () =
94+
FSharp """
95+
open CSharpAssembly
96+
97+
[<AttributeWithParamArray([|upcast 0|])>]
98+
type Foo() =
99+
override this.ToString() = "Stuff"
100+
"""
101+
|> withReferences [csharp]
102+
|> asExe
103+
|> compile
104+
|> shouldFail
105+
|> withDiagnostics [
106+
(Error 13, Line 4, Col 29, Line 4, Col 37,
107+
"The static coercion from type\n int \nto \n 'a \n involves an indeterminate type based on information prior to this program point. Static coercions are not allowed on some types. Further type annotations are needed.")
108+
(Error 267, Line 4, Col 29, Line 4, Col 37,
109+
"This is not a valid constant expression or custom attribute value")
110+
]

tests/FSharp.Test.Utilities/Compiler.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,9 @@ module rec Compiler =
585585
| CS cs -> CS { cs with LangVersion = ver }
586586
| _ -> failwith "Only supported in C#"
587587

588+
let withCSharpLanguageVersionPreview =
589+
withCSharpLanguageVersion CSharpLanguageVersion.Preview
590+
588591
let withOutputType (outputType : CompileOutput) (cUnit: CompilationUnit) : CompilationUnit =
589592
match cUnit with
590593
| FS x -> FS { x with OutputType = outputType }

tests/fsharpqa/Source/Misc/ConsumeParamArray.fsscript

Lines changed: 0 additions & 56 deletions
This file was deleted.

tests/fsharpqa/Source/Misc/E_ConsumeParamArray.fsscript

Lines changed: 0 additions & 35 deletions
This file was deleted.

tests/fsharpqa/Source/Misc/ParamArray.cs

Lines changed: 0 additions & 33 deletions
This file was deleted.

tests/fsharpqa/Source/Misc/env.lst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
PRECMD="\$CSC_PIPE /target:library ParamArray.cs" SOURCE=ConsumeParamArray.fsscript # ConsumeParamArray.fsscript
2-
PRECMD="\$CSC_PIPE /target:library ParamArray.cs" SOURCE=E_ConsumeParamArray.fsscript # E_ConsumeParamArray.fsscript
3-
41
SOURCE=E_productioncoverage01.fs # E_productioncoverage01.fs
52
SOURCE=E_productioncoverage02.fs # E_productioncoverage02.fs
63
SOURCE=E_productioncoverage03.fs SCFLAGS="--test:ErrorRanges" # E_productioncoverage03.fs

0 commit comments

Comments
 (0)