Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
1ca38f5
[WIP] Simplified compiler API for testing
vzarytovskii Jul 7, 2020
b66d8ae
[WIP] Support of references, for F#, C# projects. Added more asserts.
vzarytovskii Jul 8, 2020
b34ca95
Added more examples + ignoreWarnings support
vzarytovskii Jul 8, 2020
9e4561e
Added typecheck + baseline test helpers.
vzarytovskii Jul 9, 2020
e1f6ee9
Added running functionality
vzarytovskii Jul 9, 2020
54c313f
Moved a bunch of compiler tests to a new suite
vzarytovskii Jul 9, 2020
7a6fe9b
Changed error message
vzarytovskii Jul 9, 2020
dcf30fa
[WIP] Added CSharp compilation + referencing
vzarytovskii Jul 19, 2020
285d6e8
Added some simple interop tests
vzarytovskii Jul 19, 2020
ed00d7e
[WIP] Process MetadataReference recursively
vzarytovskii Jul 20, 2020
a91288c
[WIP] Added netcorapp31 support for tests
vzarytovskii Jul 20, 2020
d8f4542
[WIP] Termporary revert to using netcoreapp30 in the tests (instead o…
vzarytovskii Jul 21, 2020
8bf7ded
Added types to errors/warnings as oppose to just having tuples
vzarytovskii Jul 22, 2020
8799253
Fixed tests to fit newer API
vzarytovskii Jul 22, 2020
2f36dc4
Revert libraries upgrade
vzarytovskii Jul 22, 2020
56e8c92
Revert change netcoreapp31 -> netcoreapp30
vzarytovskii Jul 22, 2020
3e10cdb
Update tests/FSharp.Test.Utilities/Compiler.fs
vzarytovskii Jul 22, 2020
957dd77
Addressed some PR comments
vzarytovskii Jul 22, 2020
aa70025
Fixed missing styling inconsistensies
vzarytovskii Jul 22, 2020
a1e4293
Addressed feedback: recursive module instead of forward type declarat…
vzarytovskii Jul 23, 2020
cb9e1cb
Changed Option.isSome -> defaultArg
vzarytovskii Jul 23, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace FSharp.Compiler.UnitTests
namespace FSharp.Compiler.ConstraintSolver.ComponentTests

open NUnit.Framework
open FSharp.Test.Utilities
open FSharp.Compiler.SourceCodeServices
open Xunit
open FSharp.Test.Utilities.Compiler

[<TestFixture>]
module MemberConstraints =

[<Test>]
let ``we can overload operators on a type and not add all the extra jazz such as inlining and the ^ operator.``() =
CompilerAssert.CompileExeAndRun
"""
type Foo(x : int) =
[<Fact>]
let ``Invalid member constraint with ErrorRanges``() = // Regression test for FSharp1.0:2262
FSharp """
let inline length (x: ^a) : int = (^a : (member Length : int with get, set) (x, ()))
"""
|> withOptions ["--test:ErrorRanges"]
|> typecheck
|> shouldFail
|> withSingleDiagnostic (Error 697, Line 2, Col 43, Line 2, Col 76, "Invalid constraint")

[<Fact>]
let ``we can overload operators on a type and not add all the extra jazz such as inlining and the ^ operator.``() =

FSharp """
type Foo(x : int) =
member this.Val = x

static member (-->) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
static member (-->) ((src : Foo), (target : int)) = new Foo(src.Val + target)

static member (+) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
static member (+) ((src : Foo), (target : int)) = new Foo(src.Val + target)

let x = Foo(3) --> 4
let y = Foo(3) --> Foo(4)
let x2 = Foo(3) + 4
Expand All @@ -32,16 +40,8 @@ elif y.Val <> 7 then failwith "y.Val <> 7"
elif x2.Val <> 7 then failwith "x2.Val <> 7"
elif y2.Val <> 7 then failwith "x.Val <> 7"
else ()
"""

[<Test>]
let ``Invalid member constraint with ErrorRanges``() = // Regression test for FSharp1.0:2262
CompilerAssert.TypeCheckSingleErrorWithOptions
[| "--test:ErrorRanges" |]
"""
let inline length (x: ^a) : int = (^a : (member Length : int with get, set) (x, ()))
"""
FSharpErrorSeverity.Error
697
(2, 42, 2, 75)
"Invalid constraint"
"""
|> asExe
|> compile
|> run
// OR |> compileAsExeAndRun
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace FSharp.Compiler.UnitTests
namespace FSharp.Compiler.ConstraintSolver.ComponentTests

open NUnit.Framework
open FSharp.Test.Utilities
open FSharp.Compiler.SourceCodeServices
open Xunit
open FSharp.Test.Utilities.Compiler

[<TestFixture>]
module PrimitiveConstraints =

[<Test>]
[<Fact>]
/// Title: Type checking oddity
///
/// This suggestion was resolved as by design,
/// so the test makes sure, we're emitting error message about 'not being a valid object construction expression'
let ``Invalid object constructor`` () = // Regression test for FSharp1.0:4189
baseline
((__SOURCE_DIRECTORY__ ++ "../testables/"), "typecheck/constructors/neg_invalid_constructor.fs")
|> withOptions ["--test:ErrorRanges"]
|> typecheck


[<Fact>]
let ``Test primitive : constraints``() =
CompilerAssert.CompileExeAndRun
"""
FSharp"""
#light

type Foo(x : int) =
Expand All @@ -33,12 +42,12 @@ let b = new Bar(256)
if test1 f <> 128 then failwith "test1 f <> 128"
elif test2 b <> (-1, 256) then failwith "test2 b <> (-1, 256)"
else ()
"""
"""
|> compileExeAndRun

[<Test>]
[<Fact>]
let ``Test primitive :> constraints``() =
CompilerAssert.CompileExeAndRun
"""
FSharp"""
#light
type Foo(x : int) =
member this.Value = x
Expand All @@ -64,12 +73,12 @@ if test f <> (128, "Foo") then failwith "test f <> (128, 'Foo')"
elif test b <> (-1, "Bar") then failwith "test b <> (-1, 'Bar')"
elif test r <> (10, "Ram") then failwith "test r <> (10, 'Ram')"
else ()
"""
"""
|> compileExeAndRun

[<Test>]
[<Fact>]
let ``Test primitive : null constraint``() =
CompilerAssert.CompileExeAndRun
"""
FSharp"""
let inline isNull<'a when 'a : null> (x : 'a) =
match x with
| null -> "is null"
Expand All @@ -84,12 +93,5 @@ let runTest =
with _ -> reraise()

runTest
"""

[<Test>]
/// Title: Type checking oddity
///
/// This suggestion was resolved as by design,
/// so the test makes sure, we're emitting error message about 'not being a valid object construction expression'
let ``Invalid object constructor``() = // Regression test for FSharp1.0:4189
CompilerAssert.TypeCheckWithErrorsAndOptionsAgainstBaseLine [| "--test:ErrorRanges" |] (__SOURCE_DIRECTORY__ ++ "../../") "typecheck/constructors/neg_invalid_constructor.fs"
"""
|> compileExeAndRun
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,40 @@ namespace FSharp.Compiler.ErrorMessages.ComponentTests

open Xunit
open FSharp.Test.Utilities
open FSharp.Test.Utilities.Compiler
open FSharp.Test.Utilities.Utilities
open FSharp.Compiler.SourceCodeServices

module ``Confusing Type Name`` =

[<Fact>]
let ``Checks expected types with multiple references``() =
let csLibAB = """
let ``Expected types with multiple references`` () =

let csLibA =
CSharp """
public class A { }
public class B<T> { }
"""
let csLibACmpl =
CompilationUtil.CreateCSharpCompilation(csLibAB, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30, name = "libA")
|> CompilationReference.Create
""" |> withName "libA"

let csLibBCmpl =
CompilationUtil.CreateCSharpCompilation(csLibAB, CSharpLanguageVersion.CSharp8, TargetFramework.NetCoreApp30, name = "libB")
|> CompilationReference.Create
let csLibB =
csLibA |> withName "libB"

let fsLibC = """
let fsLibC =
FSharp """
module AMaker
let makeA () : A = A()
let makeB () = B<_>()
"""
""" |> withName "libC" |> withReferences [csLibA]

let fsLibD = """
let fsLibD =
FSharp """
module OtherAMaker
let makeOtherA () : A = A()
let makeOtherB () = B<_>()
"""

let fsLibCCmpl =
Compilation.Create(fsLibC, Fs, Library, cmplRefs = [csLibACmpl], name = "libC")
|> CompilationReference.CreateFSharp
""" |> withName "libD" |> withReferences [csLibB]

let fsLibDCmpl =
Compilation.Create(fsLibD, Fs, Library, cmplRefs = [csLibBCmpl], name = "libD")
|> CompilationReference.CreateFSharp

let app = """
let app =
FSharp """
module ConfusingTypeName
let a = AMaker.makeA()
let otherA = OtherAMaker.makeOtherA()
Expand All @@ -54,14 +48,15 @@ let b = AMaker.makeB<int>()
let otherB = OtherAMaker.makeOtherB<int>()
printfn "%A %A" (b.GetType().AssemblyQualifiedName) (otherB.GetType().AssemblyQualifiedName)
printfn "%A" (b = otherB)
"""

let appCmpl =
Compilation.Create(app, Fs, Library, cmplRefs = [csLibACmpl; csLibBCmpl; fsLibCCmpl; fsLibDCmpl])

CompilerAssert.CompileWithErrors(
appCmpl,
[|
(FSharpErrorSeverity.Error, 1, (6, 19, 6, 25), ("This expression was expected to have type\n 'A (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'A (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' "))
(FSharpErrorSeverity.Error, 1, (11, 19, 11, 25), ("This expression was expected to have type\n 'B<Microsoft.FSharp.Core.int> (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'B<Microsoft.FSharp.Core.int> (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' "))
|], true)
""" |> withReferences [csLibA; csLibB; fsLibC; fsLibD]

app
|> compile
|> shouldFail
|> withDiagnostics [
(Warning 686, Line 8, Col 9, Line 8, Col 21, "The method or function 'makeB' should not be given explicit type argument(s) because it does not declare its type parameters explicitly")
(Warning 686, Line 9, Col 14, Line 9, Col 36, "The method or function 'makeOtherB' should not be given explicit type argument(s) because it does not declare its type parameters explicitly")
(Error 1, Line 6, Col 19, Line 6, Col 25, "This expression was expected to have type\n 'A (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'A (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' ")
(Error 1, Line 11, Col 19, Line 11, Col 25, "This expression was expected to have type\n 'B<Microsoft.FSharp.Core.int> (libA, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' \nbut here has type\n 'B<Microsoft.FSharp.Core.int> (libB, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)' ")

]
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
<Compile Include="ErrorMessages\WarnExpressionTests.fs" />
<Compile Include="ErrorMessages\WrongSyntaxInForLoop.fs" />
<Compile Include="ErrorMessages\ConfusingTypeName.fs" />
<Compile Include="Language\CompilerDirectiveTests.fs" />
<Compile Include="ConstraintSolver\PrimitiveConstraints.fs" />
<Compile Include="ConstraintSolver\MemberConstraints.fs" />
<Compile Include="Interop/SimpleInteropTests.fs" />
</ItemGroup>

<ItemGroup>
Expand Down
75 changes: 75 additions & 0 deletions tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace FSharp.Compiler.ErrorMessages.ComponentTests

open Xunit
open FSharp.Test.Utilities
open FSharp.Test.Utilities.Compiler

module ``C# <-> F# basic interop`` =

[<Fact>]
let ``Instantiate C# type from F#`` () =

let CSLib =
CSharp """
public class A { }
""" |> withName "CSLib"

let FSLib =
FSharp """
module AMaker
let makeA () : A = A()
""" |> withName "FSLib" |> withReferences [CSLib]

let app =
FSharp """
module ReferenceCSfromFS
let a = AMaker.makeA()
""" |> withReferences [CSLib; FSLib]

app
|> compile
|> shouldSucceed


[<Fact(Skip="TODO: This is broken RN, since netcoreapp30 is used for C# and 3.1 for F#, should be fixed as part of https://github.com/dotnet/fsharp/issues/9740")>]
let ``Instantiate F# type from C#`` () =
let FSLib =
FSharp """
namespace Interop.FS
type Bicycle(manufacturer: string) =
member this.Manufactirer = manufacturer
""" |> withName "FSLib"

let app =
CSharp """
using Interop.FS;
public class BicycleShop {
public Bicycle[] cycles;
}
""" |> withReferences [FSLib]

app
|> compile
|> shouldSucceed

[<Fact>]
let ``Instantiate F# type from C# fails without import`` () =
let FSLib =
FSharp """
namespace Interop.FS
type Bicycle(manufacturer: string) =
member this.Manufactirer = manufacturer
""" |> withName "FSLib"

let app =
CSharp """
public class BicycleShop {
public Bicycle[] cycles;
}
""" |> withReferences [FSLib]

app
|> compile
|> shouldFail
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace FSharp.Compiler.Language.ComponentTests

open Xunit
open FSharp.Test.Utilities
open FSharp.Test.Utilities.Compiler
open FSharp.Compiler.SourceCodeServices

module ``Test Compiler Directives`` =

[<Fact>]
let ``r# "" is invalid`` () =
Fsx"""
#r ""
""" |> ignoreWarnings
|> compile
|> shouldSucceed
|> withSingleDiagnostic (Warning 213, Line 2, Col 1, Line 2, Col 6, "'' is not a valid assembly name")

[<Fact>]
let ``#r " " is invalid`` () =
Fsx"""
#r " "
""" |> compile
|> shouldFail
|> withSingleDiagnostic (Warning 213, Line 2, Col 1, Line 2, Col 10, "'' is not a valid assembly name")
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
typecheck/constructors/neg_invalid_constructor.fs (3,29)-(3,56) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a list

Candidates:
- new : col:'b -> ImmutableStack<'a>
- private new : items:'a list -> ImmutableStack<'a>
typecheck/constructors/neg_invalid_constructor.fs (4,93)-(4,111) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a list

Candidates:
- new : col:'b -> ImmutableStack<'a>
- private new : items:'a list -> ImmutableStack<'a>
typecheck/constructors/neg_invalid_constructor.fs (7,30)-(7,60) typecheck error A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed.

Known type of argument: 'a list

Candidates:
- new : col:'b -> ImmutableStack<'a> when 'b :> seq<'c>
- private new : items:'a list -> ImmutableStack<'a>
typecheck/constructors/neg_invalid_constructor.fs (7,30)-(7,60) typecheck error This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type ImmutableStack<'a> private(items: 'a list) =

member this.Push item = ImmutableStack(item::items)
member this.Pop = match items with | [] -> failwith "No elements in stack" | x::xs -> x,ImmutableStack(xs)

// Notice type annotation is commented out, which results in an error
new(col (*: seq<'a>*)) = ImmutableStack(List.ofSeq col)
Loading