Skip to content

Commit d320c81

Browse files
committed
Use indexes in TrieNodeInfo, consider auto open modules and do some stricter checks in the TypedTreeGraph.
1 parent dc7d2aa commit d320c81

File tree

7 files changed

+366
-189
lines changed

7 files changed

+366
-189
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module ParallelTypeCheckingTests.Code.TrieApproach.AutoOpenDetection
2+
3+
open FSharp.Compiler.Syntax
4+
5+
let private autoOpenShapes =
6+
set
7+
[|
8+
"FSharp.Core.AutoOpenAttribute"
9+
"Core.AutoOpenAttribute"
10+
"AutoOpenAttribute"
11+
"FSharp.Core.AutoOpen"
12+
"Core.AutoOpen"
13+
"AutoOpen"
14+
|]
15+
16+
/// This isn't bullet proof but I wonder who would really alias this very core attribute.
17+
let isAutoOpenAttribute (attribute: SynAttribute) =
18+
match attribute.ArgExpr with
19+
| SynExpr.Const(constant = SynConst.Unit _)
20+
| SynExpr.Const(constant = SynConst.String _)
21+
| SynExpr.Paren(expr = SynExpr.Const(constant = SynConst.String _)) ->
22+
let attributeName =
23+
attribute.TypeName.LongIdent
24+
|> List.map (fun ident -> ident.idText)
25+
|> String.concat "."
26+
27+
autoOpenShapes.Contains attributeName
28+
| _ -> false
29+
30+
let isAnyAttributeAutoOpen (attributes: SynAttributes) =
31+
List.exists (fun (atl: SynAttributeList) -> List.exists isAutoOpenAttribute atl.Attributes) attributes
32+
33+
let rec hasNestedModuleWithAutoOpenAttribute (decls: SynModuleDecl list) : bool =
34+
decls
35+
|> List.exists (function
36+
| SynModuleDecl.NestedModule (moduleInfo = SynComponentInfo (attributes = attributes); decls = decls) ->
37+
isAnyAttributeAutoOpen attributes || hasNestedModuleWithAutoOpenAttribute decls
38+
| _ -> false)
39+
40+
let rec hasNestedSigModuleWithAutoOpenAttribute (decls: SynModuleSigDecl list) : bool =
41+
decls
42+
|> List.exists (function
43+
| SynModuleSigDecl.NestedModule (moduleInfo = SynComponentInfo (attributes = attributes); moduleDecls = decls) ->
44+
isAnyAttributeAutoOpen attributes
45+
|| hasNestedSigModuleWithAutoOpenAttribute decls
46+
| _ -> false)
47+
48+
let hasAutoOpenAttributeInFile (ast: ParsedInput) : bool =
49+
match ast with
50+
| ParsedInput.SigFile (ParsedSigFileInput (contents = contents)) ->
51+
contents
52+
|> List.exists (fun (SynModuleOrNamespaceSig (attribs = attribs; decls = decls)) ->
53+
isAnyAttributeAutoOpen attribs || hasNestedSigModuleWithAutoOpenAttribute decls)
54+
| ParsedInput.ImplFile (ParsedImplFileInput (contents = contents)) ->
55+
contents
56+
|> List.exists (fun (SynModuleOrNamespace (attribs = attribs; decls = decls)) ->
57+
isAnyAttributeAutoOpen attribs || hasNestedModuleWithAutoOpenAttribute decls)
58+
59+
// ==============================================================================================================================
60+
// ==============================================================================================================================
61+
62+
open NUnit.Framework
63+
open FSharp.Compiler.Service.Tests.Common
64+
65+
[<Test>]
66+
let ``detect auto open`` () =
67+
let file =
68+
@"C:\Users\nojaf\Projects\safesparrow-fsharp\src\Compiler\Utilities\ImmutableArray.fsi"
69+
70+
let ast = parseSourceCode (file, System.IO.File.ReadAllText(file))
71+
Assert.True(hasAutoOpenAttributeInFile ast)

tests/ParallelTypeCheckingTests/Code/TrieApproach/DependencyResolution.fs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module ParallelTypeCheckingTests.Code.TrieApproach.DependencyResolution
22

3+
open System.Linq
34
open FSharp.Compiler.Syntax
45

56
// This is pseudo code of how we could restructure the trie code
@@ -113,7 +114,7 @@ let rec processStateEntry (queryTrie: QueryTrie) (state: FileContentQueryState)
113114
}
114115

115116
let getFileNameBefore (files: FileWithAST array) idx =
116-
files.[0 .. (idx - 1)] |> Array.map (fun f -> f.File) |> Set.ofArray
117+
files.[0 .. (idx - 1)] |> Array.map (fun f -> f.Idx) |> Set.ofArray
117118

118119
let time msg f a =
119120
let sw = System.Diagnostics.Stopwatch.StartNew()
@@ -123,21 +124,25 @@ let time msg f a =
123124
result
124125

125126
let mkGraph (files: FileWithAST array) =
126-
let trie =
127-
let input =
128-
files
129-
|> Array.filter (fun f ->
130-
match f.AST with
131-
| ParsedInput.SigFile _ -> true
132-
| ParsedInput.ImplFile _ -> Array.forall (fun (sigFile: FileWithAST) -> sigFile.File <> $"{f.File}i") files)
127+
let trieInput =
128+
files
129+
|> Array.filter (fun f ->
130+
match f.AST with
131+
| ParsedInput.SigFile _ -> true
132+
| ParsedInput.ImplFile _ -> Array.forall (fun (sigFile: FileWithAST) -> sigFile.File <> $"{f.File}i") files)
133133

134-
time "TrieMapping.mkTrie" TrieMapping.mkTrie input
134+
let trie = time "TrieMapping.mkTrie" TrieMapping.mkTrie trieInput
135135

136136
let queryTrie: QueryTrie = queryTrieMemoized trie
137137

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

141+
let filesWithAutoOpen =
142+
trieInput
143+
|> Array.filter (fun f -> AutoOpenDetection.hasAutoOpenAttributeInFile f.AST)
144+
|> Array.map (fun f -> f.Idx)
145+
141146
time
142147
"mkGraph"
143148
Array.Parallel.map
@@ -146,9 +151,18 @@ let mkGraph (files: FileWithAST array) =
146151
let knownFiles = getFileNameBefore files file.Idx
147152

148153
let result =
149-
Seq.fold (processStateEntry queryTrie) (FileContentQueryState.Create file.File knownFiles) fileContent
154+
Seq.fold (processStateEntry queryTrie) (FileContentQueryState.Create file.Idx knownFiles) fileContent
155+
156+
let allDependencies =
157+
if filesWithAutoOpen.Length > 0 then
158+
let autoOpenDependencies =
159+
set ([| 0 .. (file.Idx - 1) |].Intersect(filesWithAutoOpen))
160+
161+
Set.union result.FoundDependencies autoOpenDependencies
162+
else
163+
result.FoundDependencies
150164

151-
file, Set.toArray result.FoundDependencies)
165+
file, Set.toArray allDependencies)
152166
files
153167

154168
// =============================================================================================================
@@ -170,7 +184,10 @@ let mkGraphAndReport files =
170184
let graph = mkGraph filesWithAST
171185

172186
for fileName, deps in graph do
173-
let depString = String.concat "\n " deps
187+
let depString =
188+
deps
189+
|> Array.map (fun depIdx -> filesWithAST.[depIdx].File)
190+
|> String.concat "\n "
174191

175192
if deps.Length = 0 then
176193
printfn $"%s{fileName.File}: []"

0 commit comments

Comments
 (0)