Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deduplicate module names #2728

Merged
merged 2 commits into from
Mar 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
32 changes: 32 additions & 0 deletions src/fsharp/fsc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string,Set<string>>()
let deduplicate (paths: Set<string>) 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
Expand Down
5 changes: 5 additions & 0 deletions tests/fsharp/core/samename/folder1/a.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace tempet

module SayA =
let hello name =
printfn "Hello %s" name
4 changes: 4 additions & 0 deletions tests/fsharp/core/samename/folder1/a.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace tempet

module SayA =
val hello : string -> unit
5 changes: 5 additions & 0 deletions tests/fsharp/core/samename/folder1/b.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace tempet

module SayB =
let hello name =
printfn "Hello %s" name
4 changes: 4 additions & 0 deletions tests/fsharp/core/samename/folder1/b.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace tempet

module SayB =
val hello : string -> unit
5 changes: 5 additions & 0 deletions tests/fsharp/core/samename/folder2/a.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace tempet

module SayC =
let hello name =
printfn "Hello %s" name
4 changes: 4 additions & 0 deletions tests/fsharp/core/samename/folder2/a.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace tempet

module SayC =
val hello : string -> unit
5 changes: 5 additions & 0 deletions tests/fsharp/core/samename/folder2/b.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace tempet

module SayD =
let hello name =
printfn "Hello %s" name
4 changes: 4 additions & 0 deletions tests/fsharp/core/samename/folder2/b.fsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace tempet

module SayD =
val hello : string -> unit
23 changes: 23 additions & 0 deletions tests/fsharp/core/samename/tempet.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="folder1/a.fsi" />
<Compile Include="folder1/a.fs" />
<Compile Include="folder1/b.fsi" />
<Compile Include="folder1/b.fs" />
<Compile Include="folder2/a.fsi" />
<Compile Include="folder2/a.fs" />
<Compile Include="folder2/b.fsi" />
<Compile Include="folder2/b.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FSharp.Core" Version="4.1.*" />
<PackageReference Include="FSharp.NET.Sdk" Version="1.0.*" PrivateAssets="All" />
</ItemGroup>

</Project>
36 changes: 35 additions & 1 deletion tests/fsharp/tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,41 @@ module CoreTests =
peverify cfg "test2.exe"

exec cfg ("." ++ "test2.exe") ""


// Repro for https://github.com/Microsoft/visualfsharp/issues/2679
[<Test>]
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") ""

[<Test>]
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") ""

[<Test>]
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") ""

[<Test>]
let ``libtest-FSI_STDIN`` () = singleTestBuildAndRun "core/libtest" FSI_STDIN

Expand Down