Skip to content

Commit 97f3d0a

Browse files
committed
Add failing unit test to illustrate problem.
1 parent d71fde9 commit 97f3d0a

4 files changed

Lines changed: 101 additions & 0 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@
206206
<Content Include="TypeChecks\Graph\scrape.fsx" CopyToOutputDirectory="Never" />
207207
<Compile Include="TypeChecks\Graph\CompilationFromCmdlineArgsTests.fs" />
208208
<Compile Include="TypeChecks\Graph\TypedTreeGraph.fs" />
209+
<Compile Include="TypeChecks\TyparNameTests.fs" />
209210
<Compile Include="CompilerOptions\fsc\checked\checked.fs" />
210211
<Compile Include="CompilerOptions\fsc\cliversion.fs" />
211212
<Compile Include="CompilerOptions\fsc\codepage\codepage.fs" />
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
module FSharp.Compiler.ComponentTests.TypeChecks.TyparNameTests
2+
3+
open FSharp.Compiler.Symbols
4+
open Xunit
5+
open FSharp.Test
6+
open FSharp.Test.Compiler
7+
8+
[<Fact>]
9+
let ``The call site of a generic function should have no influence on the name of the type parameters`` () =
10+
let definitionFile =
11+
Fs
12+
"""
13+
module A
14+
15+
let someGenericFunction _ = ()
16+
"""
17+
|> withFileName "A.fs"
18+
19+
let usageFile =
20+
("""
21+
module B
22+
23+
let otherGenericFunction _ _ _ =
24+
A.someGenericFunction 1
25+
"""
26+
|> FsSource)
27+
.WithFileName("B.fs")
28+
29+
let getGenericParametersNamesFor
30+
(entityDisplayName: string)
31+
(valueDisplayName: string)
32+
(additionalFile: SourceCodeFileKind)
33+
: string array =
34+
let typeCheckResult =
35+
definitionFile |> withAdditionalSourceFile additionalFile |> typecheckProject
36+
37+
typeCheckResult.AssemblySignature.Entities
38+
|> Seq.tryPick (fun (entity: FSharpEntity) ->
39+
if entity.DisplayName <> entityDisplayName then
40+
None
41+
else
42+
entity.MembersFunctionsAndValues
43+
|> Seq.tryFind (fun mfv -> mfv.DisplayName = valueDisplayName)
44+
|> Option.map (fun (mfv: FSharpMemberOrFunctionOrValue) ->
45+
mfv.GenericParameters |> Seq.map (fun gp -> gp.DisplayName) |> Seq.toArray))
46+
|> Option.defaultValue Array.empty
47+
48+
let namesForB = getGenericParametersNamesFor "A" "someGenericFunction" usageFile
49+
50+
let alternativeUsageFile =
51+
("""
52+
module C
53+
54+
let alternateGenericFunction _ =
55+
A.someGenericFunction 1
56+
"""
57+
|> FsSource)
58+
.WithFileName("C.fs")
59+
60+
let namesForC =
61+
getGenericParametersNamesFor "A" "someGenericFunction" alternativeUsageFile
62+
63+
Assert.Equal<string array>(namesForB, namesForC)

tests/FSharp.Test.Utilities/Compiler.fs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ open FSharp.Compiler.Interactive.Shell
66
open FSharp.Compiler.IO
77
open FSharp.Compiler.Diagnostics
88
open FSharp.Compiler.Symbols
9+
open FSharp.Compiler.Text
910
open FSharp.Test.Assert
1011
open FSharp.Test.Utilities
1112
open FSharp.Test.ScriptHelpers
@@ -347,6 +348,12 @@ module rec Compiler =
347348
| CS src -> CS { src with Name = Some name }
348349
| IL _ -> failwith "IL Compilation cannot be named."
349350

351+
let withFileName (name: string) (cUnit: CompilationUnit) : CompilationUnit =
352+
match cUnit with
353+
| FS compilationSource -> FS { compilationSource with Source = compilationSource.Source.WithFileName(name) }
354+
| CS cSharpCompilationSource -> CS { cSharpCompilationSource with Source = cSharpCompilationSource.Source.WithFileName(name) }
355+
| IL _ -> failwith "IL Compilation cannot be named."
356+
350357
let withReferenceFSharpCompilerService (cUnit: CompilationUnit) : CompilationUnit =
351358
// Compute the location of the FSharp.Compiler.Service dll that matches the target framework used to build this test assembly
352359
let compilerServiceAssemblyLocation =
@@ -816,6 +823,26 @@ module rec Compiler =
816823
CompilerAssert.TypeCheck(options, fileName, source)
817824
| _ -> failwith "Typecheck only supports F#"
818825

826+
let typecheckProject (cUnit: CompilationUnit) : FSharp.Compiler.CodeAnalysis.FSharpCheckProjectResults =
827+
match cUnit with
828+
| FS fsSource ->
829+
let options = fsSource.Options |> Array.ofList
830+
let sourceFiles =
831+
[| yield (fsSource.Source.GetSourceFileName, fsSource.Source.GetSourceText)
832+
yield!
833+
fsSource.AdditionalSources
834+
|> List.map (fun source -> source.GetSourceFileName, source.GetSourceText) |]
835+
836+
let getSourceText =
837+
let project = Map.ofArray sourceFiles
838+
fun (name: string) ->
839+
Map.tryFind name project
840+
|> Option.bind (Option.map SourceText.ofString)
841+
842+
let sourceFiles = Array.map fst sourceFiles
843+
CompilerAssert.TypeCheckProject(options, sourceFiles, getSourceText)
844+
| _ -> failwith "Typecheck only supports F#"
845+
819846
let run (result: CompilationResult) : CompilationResult =
820847
match result with
821848
| CompilationResult.Failure f -> failwith (sprintf "Compilation should be successful in order to run.\n Errors: %A" (f.Diagnostics))

tests/FSharp.Test.Utilities/CompilerAssert.fs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace FSharp.Test
44

5+
#nowarn "57"
6+
57
open System
68
open System.IO
79
open System.Text
@@ -856,6 +858,14 @@ Updated automatically, please check diffs in your pull request, changes must be
856858
static member TypeCheckSingleError (source: string) (expectedSeverity: FSharpDiagnosticSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) =
857859
CompilerAssert.TypeCheckWithErrors source [| expectedSeverity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
858860

861+
static member TypeCheckProject(options: string array, sourceFiles: string array, getSourceText: string -> ISourceText option) : FSharpCheckProjectResults =
862+
let checker = FSharpChecker.Create(documentSource = DocumentSource.Custom getSourceText)
863+
let defaultOptions = defaultProjectOptions TargetFramework.Current
864+
let projectOptions = { defaultOptions with OtherOptions = Array.append options defaultOptions.OtherOptions; SourceFiles = sourceFiles }
865+
866+
checker.ParseAndCheckProject(projectOptions)
867+
|> Async.RunImmediate
868+
859869
static member CompileExeWithOptions(options, (source: SourceCodeFileKind)) =
860870
compile true options source (fun (errors, _, _) ->
861871
if errors.Length > 0 then

0 commit comments

Comments
 (0)