diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 2158fd4c71e..542a0c14ad4 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -1761,6 +1761,38 @@ let main0(ctok, argv, referenceResolver, bannerAlreadyPrinted, exiter:Exiter, er with e -> errorRecoveryNoRange e exiter.Exit 1 + + let inputs = + // Deduplicate module names + let seen = Dictionary>() + let deduplicate (paths: Set) path (qualifiedNameOfFile: QualifiedNameOfFile) = + let count = if paths.Contains path then paths.Count else paths.Count + 1 + seen.[qualifiedNameOfFile.Text] <- Set.add path paths + let id = qualifiedNameOfFile.Id + if count = 1 then qualifiedNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(),id.idRange)) + inputs + |> List.map (fun (input,x) -> + match input with + | ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput(fileName,isScript,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules,(isLastCompiland,isExe))) -> + let path = Path.GetDirectoryName fileName + match seen.TryGetValue qualifiedNameOfFile.Text with + | true, paths -> + let qualifiedNameOfFile = deduplicate paths path qualifiedNameOfFile + let input = ParsedInput.ImplFile(ParsedImplFileInput.ParsedImplFileInput(fileName,isScript,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules,(isLastCompiland,isExe))) + input,x + | _ -> + seen.Add(qualifiedNameOfFile.Text,Set.singleton path) + input,x + | ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules)) -> + let path = Path.GetDirectoryName fileName + match seen.TryGetValue qualifiedNameOfFile.Text with + | true, paths -> + let qualifiedNameOfFile = deduplicate paths path qualifiedNameOfFile + let input = ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules)) + input,x + | _ -> + seen.Add(qualifiedNameOfFile.Text,Set.singleton path) + input,x) if tcConfig.parseOnly then exiter.Exit 0 if not tcConfig.continueAfterParseFailure then diff --git a/tests/fsharp/core/samename/folder1/a.fs b/tests/fsharp/core/samename/folder1/a.fs new file mode 100644 index 00000000000..dd36669a8c4 --- /dev/null +++ b/tests/fsharp/core/samename/folder1/a.fs @@ -0,0 +1,5 @@ +namespace tempet + +module SayA = + let hello name = + printfn "Hello %s" name diff --git a/tests/fsharp/core/samename/folder1/a.fsi b/tests/fsharp/core/samename/folder1/a.fsi new file mode 100644 index 00000000000..becca951185 --- /dev/null +++ b/tests/fsharp/core/samename/folder1/a.fsi @@ -0,0 +1,4 @@ +namespace tempet + +module SayA = + val hello : string -> unit diff --git a/tests/fsharp/core/samename/folder1/b.fs b/tests/fsharp/core/samename/folder1/b.fs new file mode 100644 index 00000000000..8591f3337af --- /dev/null +++ b/tests/fsharp/core/samename/folder1/b.fs @@ -0,0 +1,5 @@ +namespace tempet + +module SayB = + let hello name = + printfn "Hello %s" name diff --git a/tests/fsharp/core/samename/folder1/b.fsi b/tests/fsharp/core/samename/folder1/b.fsi new file mode 100644 index 00000000000..97fdbc5c25d --- /dev/null +++ b/tests/fsharp/core/samename/folder1/b.fsi @@ -0,0 +1,4 @@ +namespace tempet + +module SayB = + val hello : string -> unit diff --git a/tests/fsharp/core/samename/folder2/a.fs b/tests/fsharp/core/samename/folder2/a.fs new file mode 100644 index 00000000000..cfb35c08cb0 --- /dev/null +++ b/tests/fsharp/core/samename/folder2/a.fs @@ -0,0 +1,5 @@ +namespace tempet + +module SayC = + let hello name = + printfn "Hello %s" name diff --git a/tests/fsharp/core/samename/folder2/a.fsi b/tests/fsharp/core/samename/folder2/a.fsi new file mode 100644 index 00000000000..d48c41d6fc6 --- /dev/null +++ b/tests/fsharp/core/samename/folder2/a.fsi @@ -0,0 +1,4 @@ +namespace tempet + +module SayC = + val hello : string -> unit diff --git a/tests/fsharp/core/samename/folder2/b.fs b/tests/fsharp/core/samename/folder2/b.fs new file mode 100644 index 00000000000..1c43836d220 --- /dev/null +++ b/tests/fsharp/core/samename/folder2/b.fs @@ -0,0 +1,5 @@ +namespace tempet + +module SayD = + let hello name = + printfn "Hello %s" name diff --git a/tests/fsharp/core/samename/folder2/b.fsi b/tests/fsharp/core/samename/folder2/b.fsi new file mode 100644 index 00000000000..c360a810f50 --- /dev/null +++ b/tests/fsharp/core/samename/folder2/b.fsi @@ -0,0 +1,4 @@ +namespace tempet + +module SayD = + val hello : string -> unit diff --git a/tests/fsharp/core/samename/tempet.fsproj b/tests/fsharp/core/samename/tempet.fsproj new file mode 100644 index 00000000000..66280fa2b63 --- /dev/null +++ b/tests/fsharp/core/samename/tempet.fsproj @@ -0,0 +1,23 @@ + + + + netstandard1.6 + + + + + + + + + + + + + + + + + + + diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index ad416121eb5..b6e402701ab 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -774,7 +774,41 @@ module CoreTests = peverify cfg "test2.exe" exec cfg ("." ++ "test2.exe") "" - + + // Repro for https://github.com/Microsoft/visualfsharp/issues/2679 + [] + let ``add files with same name from different folders`` () = + let cfg = testConfig "core/samename" + + log "== Compiling F# Code with files with same name in different folders" + fsc cfg "%s -o:test.exe" cfg.fsc_flags ["folder1/a.fs"; "folder1/b.fs"; "folder2/a.fs"; "folder2/b.fs"] + + peverify cfg "test.exe" + + exec cfg ("." ++ "test.exe") "" + + [] + let ``add files with same name from different folders including signature files`` () = + let cfg = testConfig "core/samename" + + log "== Compiling F# Code with files with same name in different folders including signature files" + fsc cfg "%s -o:test.exe" cfg.fsc_flags ["folder1/a.fsi"; "folder1/a.fs"; "folder1/b.fsi"; "folder1/b.fs"; "folder2/a.fsi"; "folder2/a.fs"; "folder2/b.fsi"; "folder2/b.fs"] + + peverify cfg "test.exe" + + exec cfg ("." ++ "test.exe") "" + + [] + let ``add files with same name from different folders including signature files that are not synced`` () = + let cfg = testConfig "core/samename" + + log "== Compiling F# Code with files with same name in different folders including signature files" + fsc cfg "%s -o:test.exe" cfg.fsc_flags ["folder1/a.fsi"; "folder1/a.fs"; "folder1/b.fs"; "folder2/a.fsi"; "folder2/a.fs"; "folder2/b.fsi"; "folder2/b.fs"] + + peverify cfg "test.exe" + + exec cfg ("." ++ "test.exe") "" + [] let ``libtest-FSI_STDIN`` () = singleTestBuildAndRun "core/libtest" FSI_STDIN