Skip to content

Commit

Permalink
queryTrieMemoized
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf committed Nov 21, 2022
1 parent 32dd4bf commit 63539f8
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,25 @@ let queryTrie (trie: TrieNode) (path: ModuleSegment list) : QueryTrieNodeResult

visit trie path

let queryTrieMemoized (trie: TrieNode) : QueryTrie =
Internal.Utilities.Library.Tables.memoize (queryTrie trie)

// Now how to detect the deps between files?
// Process the content of each file using some state

// Helper function to process a open statement
// The statement could link to files and/or should be tracked as an open namespace
let processOpenPath (trie: TrieNode) (path: ModuleSegment list) (state: FileContentQueryState) : FileContentQueryState =
let queryResult = queryTrie trie path
let processOpenPath (queryTrie: QueryTrie) (path: ModuleSegment list) (state: FileContentQueryState) : FileContentQueryState =
let queryResult = queryTrie path

match queryResult with
| QueryTrieNodeResult.NodeDoesNotExist -> state
| QueryTrieNodeResult.NodeDoesNotExposeData -> state.AddOpenNamespace path
| QueryTrieNodeResult.NodeExposesData files -> state.AddDependenciesAndOpenNamespace(files, path)

// Helper function to process an identifier
let processIdentifier (trie: TrieNode) (path: ModuleSegment list) (state: FileContentQueryState) : FileContentQueryState =
let queryResult = queryTrie trie path
let processIdentifier (queryTrie: QueryTrie) (path: ModuleSegment list) (state: FileContentQueryState) : FileContentQueryState =
let queryResult = queryTrie path

match queryResult with
| QueryTrieNodeResult.NodeDoesNotExist -> state
Expand All @@ -60,38 +63,38 @@ let processIdentifier (trie: TrieNode) (path: ModuleSegment list) (state: FileCo
| QueryTrieNodeResult.NodeExposesData files -> state.AddDependencies files

// Typically used to folder FileContentEntry items over a FileContentQueryState
let rec processStateEntry (trie: TrieNode) (state: FileContentQueryState) (entry: FileContentEntry) : FileContentQueryState =
let rec processStateEntry (queryTrie: QueryTrie) (state: FileContentQueryState) (entry: FileContentEntry) : FileContentQueryState =
match entry with
| FileContentEntry.TopLevelNamespace (topLevelPath, content) ->
let state =
match topLevelPath with
| [] -> state
| _ -> processOpenPath trie topLevelPath state
| _ -> processOpenPath queryTrie topLevelPath state

List.fold (processStateEntry trie) state content
List.fold (processStateEntry queryTrie) state content

| FileContentEntry.OpenStatement path ->
// An open statement can directly reference file or be a partial open statement
// Both cases need to be processed.
let stateAfterFullOpenPath = processOpenPath trie path state
let stateAfterFullOpenPath = processOpenPath queryTrie path state

// Any existing open statement could be extended with the current path (if that node where to exists in the trie)
// The extended path could add a new link (in case of a module or namespace with types)
// It might also not add anything at all (in case it the extended path is still a partial one)
(stateAfterFullOpenPath, state.OpenNamespaces)
||> Seq.fold (fun acc openNS -> processOpenPath trie [ yield! openNS; yield! path ] acc)
||> Seq.fold (fun acc openNS -> processOpenPath queryTrie [ yield! openNS; yield! path ] acc)

| FileContentEntry.PrefixedIdentifier path ->
// process the name was if it were a FQN
let stateAfterFullIdentifier = processIdentifier trie path state
let stateAfterFullIdentifier = processIdentifier queryTrie path state

// Process the name in combination with the existing open namespaces
(stateAfterFullIdentifier, state.OpenNamespaces)
||> Seq.fold (fun acc openNS -> processIdentifier trie [ yield! openNS; yield! path ] acc)
||> Seq.fold (fun acc openNS -> processIdentifier queryTrie [ yield! openNS; yield! path ] acc)

| FileContentEntry.NestedModule (nestedContent = nestedContent) ->
// We don't want our current state to be affect by any open statements in the nested module
let nestedState = List.fold (processStateEntry trie) state nestedContent
let nestedState = List.fold (processStateEntry queryTrie) state nestedContent
// Afterward we are only interested in the found dependencies in the nested module
let foundDependencies =
Set.union state.FoundDependencies nestedState.FoundDependencies
Expand Down Expand Up @@ -121,7 +124,10 @@ let mkGraph (files: FileWithAST array) =

time "TrieMapping.mkTrie" TrieMapping.mkTrie input

let fileContents = Array.Parallel.map FileContentMapping.mkFileContent files
let queryTrie: QueryTrie = queryTrieMemoized trie

let fileContents =
time "FileContentMapping.mkFileContent" Array.Parallel.map FileContentMapping.mkFileContent files

time
"mkGraph"
Expand All @@ -131,7 +137,7 @@ let mkGraph (files: FileWithAST array) =
let knownFiles = getFileNameBefore files file.Idx

let result =
Seq.fold (processStateEntry trie) (FileContentQueryState.Create file.File knownFiles) fileContent
Seq.fold (processStateEntry queryTrie) (FileContentQueryState.Create file.File knownFiles) fileContent

file.File, Set.toArray result.FoundDependencies)
files
Expand Down Expand Up @@ -521,7 +527,6 @@ let ``FCS for debugging`` () =
let contents =
Array.map
(fun (file: FileWithAST) ->
printfn "Start %s" file.File
FileContentMapping.mkFileContent file)
filesWithAST

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -729,8 +729,10 @@ let ``Full project simulation`` () =
let knownFiles =
files.[0 .. (fileContent.Idx - 1)] |> Array.map (fun f -> f.Name) |> set

let queryTrie: QueryTrie = queryTrieMemoized fantomasCoreTrie

let result =
Seq.fold (processStateEntry fantomasCoreTrie) (FileContentQueryState.Create fileContent.Name knownFiles) fileContent.Content
Seq.fold (processStateEntry queryTrie) (FileContentQueryState.Create fileContent.Name knownFiles) fileContent.Content

fileContent.Name, Set.toArray result.FoundDependencies)

Expand Down Expand Up @@ -785,7 +787,7 @@ let ``ProcessOpenStatement full path match`` () =
|])

let result =
processOpenPath fantomasCoreTrie [ "Fantomas"; "Core"; "AstExtensions" ] state
processOpenPath (queryTrie fantomasCoreTrie) [ "Fantomas"; "Core"; "AstExtensions" ] state

let dep = Seq.exactlyOne result.FoundDependencies
Assert.AreEqual("AstExtensions.fsi", dep)
Expand Down
2 changes: 2 additions & 0 deletions tests/ParallelTypeCheckingTests/Code/TrieApproach/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,5 @@ type QueryTrieNodeResult =
| NodeDoesNotExposeData
/// A node was found with one or more file links
| NodeExposesData of Files

type QueryTrie = ModuleSegment list -> QueryTrieNodeResult

0 comments on commit 63539f8

Please sign in to comment.