Skip to content

Commit

Permalink
Deduplicate the deduplication code
Browse files Browse the repository at this point in the history
  • Loading branch information
forki committed Apr 3, 2017
1 parent f6fd5e0 commit 2fc7247
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 57 deletions.
31 changes: 31 additions & 0 deletions src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3347,6 +3347,37 @@ let PostParseModuleSpecs (defaultNamespace,filename,isLastCompiland,ParsedSigFil

ParsedInput.SigFile(ParsedSigFileInput(filename,qualName,scopedPragmas,hashDirectives,specs))

/// Checks if a module name is already given and deduplicates the name if needed.
let DeduplicateModuleName (moduleNamesDict:Dictionary<string,Set<string>>) (paths: Set<string>) path (qualifiedNameOfFile: QualifiedNameOfFile) =
let count = if paths.Contains path then paths.Count else paths.Count + 1
moduleNamesDict.[qualifiedNameOfFile.Text] <- Set.add path paths
let id = qualifiedNameOfFile.Id
if count = 1 then qualifiedNameOfFile else QualifiedNameOfFile(Ident(id.idText + "___" + count.ToString(),id.idRange))

/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed.
let DeduplicateParsedInputModuleName (moduleNamesDict:Dictionary<string,Set<string>>) input =
match input with
| ParsedInput.ImplFile (ParsedImplFileInput.ParsedImplFileInput(fileName,isScript,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules,(isLastCompiland,isExe))) ->
let path = Path.GetDirectoryName fileName
match moduleNamesDict.TryGetValue qualifiedNameOfFile.Text with
| true, paths ->
let qualifiedNameOfFile = DeduplicateModuleName moduleNamesDict paths path qualifiedNameOfFile
let input = ParsedInput.ImplFile(ParsedImplFileInput.ParsedImplFileInput(fileName,isScript,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules,(isLastCompiland,isExe)))
Some input
| _ ->
moduleNamesDict.Add(qualifiedNameOfFile.Text,Set.singleton path)
input
| ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules)) ->
let path = Path.GetDirectoryName fileName
match moduleNamesDict.TryGetValue qualifiedNameOfFile.Text with
| true, paths ->
let qualifiedNameOfFile = DeduplicateModuleName moduleNamesDict paths path qualifiedNameOfFile
let input = ParsedInput.SigFile (ParsedSigFileInput.ParsedSigFileInput(fileName,qualifiedNameOfFile,scopedPragmas,hashDirectives,modules))
Some input
| _ ->
moduleNamesDict.Add(qualifiedNameOfFile.Text,Set.singleton path)
input

let ParseInput (lexer,errorLogger:ErrorLogger,lexbuf:UnicodeLexing.Lexbuf,defaultNamespace,filename,isLastCompiland) =
// The assert below is almost ok, but it fires in two cases:
// - fsi.exe sometimes passes "stdin" as a dummy filename
Expand Down
6 changes: 6 additions & 0 deletions src/fsharp/CompileOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ val ComputeQualifiedNameOfFileFromUniquePath : range * string list -> Ast.Qualif

val PrependPathToInput : Ast.Ident list -> Ast.ParsedInput -> Ast.ParsedInput

/// Checks if a module name is already given and deduplicates the name if needed.
val DeduplicateModuleName : Dictionary<string,Set<string>> -> Set<string> -> string -> Ast.QualifiedNameOfFile -> Ast.QualifiedNameOfFile

/// Checks if a ParsedInput is using a module name that was already given and deduplicates the name if needed.
val DeduplicateParsedInputModuleName : Dictionary<string,Set<string>> -> Ast.ParsedInput -> Ast.ParsedInput

val ParseInput : (UnicodeLexing.Lexbuf -> Parser.token) * ErrorLogger * UnicodeLexing.Lexbuf * string option * string * isLastCompiland:(bool * bool) -> Ast.ParsedInput

//----------------------------------------------------------------------------
Expand Down
30 changes: 2 additions & 28 deletions src/fsharp/fsc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1764,35 +1764,9 @@ let main0(ctok, argv, referenceResolver, bannerAlreadyPrinted, exiter:Exiter, er

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))
let moduleNamesDict = Dictionary<string,Set<string>>()
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)
|> List.map (fun (input,x) -> DeduplicateParsedInputModuleName moduleNamesDict input,x)

if tcConfig.parseOnly then exiter.Exit 0
if not tcConfig.continueAfterParseFailure then
Expand Down
32 changes: 3 additions & 29 deletions src/fsharp/vs/IncrementalBuild.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1330,12 +1330,7 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs
cache.GetFileTimeStamp filename

// 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))
let moduleNamesDict = Dictionary<string,Set<string>>()

/// This is a build task function that gets placed into the build rules as the computation for a VectorMap
///
Expand All @@ -1354,29 +1349,8 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs
IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBEParsed filename)
let input = ParseOneInputFile(tcConfig,lexResourceManager, [], filename ,isLastCompiland,errorLogger,(*retryLocked*)true)
fileParsed.Trigger (filename)
let result =
match input with
| Some(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)))
Some input
| _ ->
seen.Add(qualifiedNameOfFile.Text,Set.singleton path)
input
| Some(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))
Some input
| _ ->
seen.Add(qualifiedNameOfFile.Text,Set.singleton path)
input
| input -> input
let result = Option.map (DeduplicateParsedInputModuleName moduleNamesDict) input

result,sourceRange,filename,errorLogger.GetErrors ()
with exn ->
System.Diagnostics.Debug.Assert(false, sprintf "unexpected failure in IncrementalFSharpBuild.Parse\nerror = %s" (exn.ToString()))
Expand Down

0 comments on commit 2fc7247

Please sign in to comment.