Skip to content

Commit aa42f6e

Browse files
authored
Merge branch 'main' into 17742-nullness-issue-string-function-signature-doesnt-hold
2 parents 850c279 + b19e419 commit aa42f6e

File tree

12 files changed

+266
-263
lines changed

12 files changed

+266
-263
lines changed

.fantomasignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ src/Compiler/Utilities/HashMultiMap.fs
116116
src/Compiler/Facilities/AsyncMemoize.fsi
117117
src/Compiler/Facilities/AsyncMemoize.fs
118118
src/Compiler/AbstractIL/il.fs
119+
src/Compiler/SyntaxTree/LexerStore.fs
119120

120121
src/Compiler/Driver/GraphChecking/Graph.fsi
121122
src/Compiler/Driver/GraphChecking/Graph.fs

src/Compiler/Driver/ParseAndCheckInputs.fs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ open FSharp.Compiler.Diagnostics
2727
open FSharp.Compiler.DiagnosticsLogger
2828
open FSharp.Compiler.Features
2929
open FSharp.Compiler.IO
30+
open FSharp.Compiler.LexerStore
3031
open FSharp.Compiler.Lexhelp
3132
open FSharp.Compiler.NameResolution
3233
open FSharp.Compiler.ParseHelpers
@@ -239,7 +240,7 @@ let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) =
239240

240241
let private collectCodeComments (lexbuf: UnicodeLexing.Lexbuf) (tripleSlashComments: range list) =
241242
[
242-
yield! LexbufCommentStore.GetComments(lexbuf)
243+
yield! CommentStore.GetComments(lexbuf)
243244
yield! (List.map CommentTrivia.LineComment tripleSlashComments)
244245
]
245246
|> List.sortBy (function
@@ -285,7 +286,7 @@ let PostParseModuleImpls
285286
yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
286287
]
287288

288-
let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf)
289+
let conditionalDirectives = IfdefStore.GetTrivia(lexbuf)
289290
let codeComments = collectCodeComments lexbuf tripleSlashComments
290291

291292
let trivia: ParsedImplFileInputTrivia =
@@ -336,7 +337,7 @@ let PostParseModuleSpecs
336337
yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
337338
]
338339

339-
let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf)
340+
let conditionalDirectives = IfdefStore.GetTrivia(lexbuf)
340341
let codeComments = collectCodeComments lexbuf tripleSlashComments
341342

342343
let trivia: ParsedSigFileInputTrivia =
@@ -488,15 +489,13 @@ let ParseInput
488489
if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
489490
let impl = Parser.implementationFile lexer lexbuf
490491

491-
let tripleSlashComments =
492-
LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf)
492+
let tripleSlashComments = XmlDocStore.ReportInvalidXmlDocPositions(lexbuf)
493493

494494
PostParseModuleImpls(defaultNamespace, fileName, isLastCompiland, impl, lexbuf, tripleSlashComments, Set identStore)
495495
elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix fileName) then
496496
let intfs = Parser.signatureFile lexer lexbuf
497497

498-
let tripleSlashComments =
499-
LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf)
498+
let tripleSlashComments = XmlDocStore.ReportInvalidXmlDocPositions(lexbuf)
500499

501500
PostParseModuleSpecs(defaultNamespace, fileName, isLastCompiland, intfs, lexbuf, tripleSlashComments, Set identStore)
502501
else if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then

src/Compiler/FSharp.Compiler.Service.fsproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,11 @@
247247
<Link>SyntaxTree\pplex.fsl</Link>
248248
</FsLex>
249249
<FsYacc Include="pppars.fsy">
250-
<OtherFlags>--module FSharp.Compiler.PPParser --open FSharp.Compiler.ParseHelpers --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char</OtherFlags>
250+
<OtherFlags>--module FSharp.Compiler.PPParser --open FSharp.Compiler.ParseHelpers --open FSharp.Compiler.LexerStore --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char</OtherFlags>
251251
<Link>SyntaxTree\pppars.fsy</Link>
252252
</FsYacc>
253253
<FsLex Include="lex.fsl">
254-
<OtherFlags>--module FSharp.Compiler.Lexer --open FSharp.Compiler.Lexhelp --open Internal.Utilities.Text.Lexing --open FSharp.Compiler.Parser --open FSharp.Compiler.Text --open FSharp.Compiler.ParseHelpers --internal --unicode --lexlib Internal.Utilities.Text.Lexing</OtherFlags>
254+
<OtherFlags>--module FSharp.Compiler.Lexer --open FSharp.Compiler.Lexhelp --open Internal.Utilities.Text.Lexing --open FSharp.Compiler.Parser --open FSharp.Compiler.Text --open FSharp.Compiler.ParseHelpers --open FSharp.Compiler.LexerStore --internal --unicode --lexlib Internal.Utilities.Text.Lexing</OtherFlags>
255255
<Link>SyntaxTree\lex.fsl</Link>
256256
</FsLex>
257257
<FsYacc Include="pars.fsy">
@@ -280,6 +280,8 @@
280280
<Compile Include="SyntaxTree\SyntaxTree.fs" />
281281
<Compile Include="SyntaxTree\SyntaxTreeOps.fsi" />
282282
<Compile Include="SyntaxTree\SyntaxTreeOps.fs" />
283+
<Compile Include="SyntaxTree\LexerStore.fsi" />
284+
<Compile Include="SyntaxTree\LexerStore.fs" />
283285
<Compile Include="SyntaxTree\ParseHelpers.fsi" />
284286
<Compile Include="SyntaxTree\ParseHelpers.fs" />
285287
<Compile Include="$(FsYaccOutputFolder)pppars.fsi">

src/Compiler/SyntaxTree/LexFilter.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ module internal FSharp.Compiler.LexFilter
77
open System
88
open System.Collections.Generic
99
open Internal.Utilities.Text.Lexing
10-
open FSharp.Compiler
1110
open Internal.Utilities.Library
1211
open FSharp.Compiler.AbstractIL.Diagnostics
1312
open FSharp.Compiler.DiagnosticsLogger
1413
open FSharp.Compiler.Features
14+
open FSharp.Compiler.LexerStore
1515
open FSharp.Compiler.Lexhelp
1616
open FSharp.Compiler.ParseHelpers
1717
open FSharp.Compiler.Parser
@@ -665,7 +665,7 @@ type LexFilterImpl (
665665
let lastTokenEnd = state.EndPos
666666
let token = lexer lexbuf
667667

668-
LexbufLocalXmlDocStore.AddGrabPoint(lexbuf)
668+
XmlDocStore.AddGrabPoint(lexbuf)
669669

670670
// Now we've got the token, remember the lexbuf state, associating it with the token
671671
// and remembering it as the last observed lexbuf state for the wrapped lexer function.

src/Compiler/SyntaxTree/LexHelpers.fs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ open Internal.Utilities.Text.Lexing
1212
open FSharp.Compiler.IO
1313
open FSharp.Compiler.DiagnosticsLogger
1414
open FSharp.Compiler.Features
15+
open FSharp.Compiler.LexerStore
1516
open FSharp.Compiler.ParseHelpers
1617
open FSharp.Compiler.UnicodeLexing
1718
open FSharp.Compiler.Parser
@@ -98,10 +99,8 @@ let mkLexargs
9899
}
99100

100101
/// Register the lexbuf and call the given function
101-
let reusingLexbufForParsing lexbuf f =
102+
let reusingLexbufForParsing (lexbuf: Lexbuf) f =
102103
use _ = UseBuildPhase BuildPhase.Parse
103-
LexbufLocalXmlDocStore.ClearXmlDoc lexbuf
104-
LexbufCommentStore.ClearComments lexbuf
105104

106105
try
107106
f ()

src/Compiler/SyntaxTree/LexerStore.fs

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
module internal FSharp.Compiler.LexerStore
4+
5+
open FSharp.Compiler.SyntaxTreeOps
6+
open FSharp.Compiler.SyntaxTrivia
7+
open FSharp.Compiler.UnicodeLexing
8+
open FSharp.Compiler.Text
9+
open FSharp.Compiler.Text.Position
10+
open FSharp.Compiler.Text.Range
11+
open FSharp.Compiler.Xml
12+
13+
//------------------------------------------------------------------------
14+
// Lexbuf.BufferLocalStore is used during lexing/parsing of a file for different purposes.
15+
// All access happens through the functions and modules below.
16+
//------------------------------------------------------------------------
17+
18+
let private getStoreData<'T when 'T: not null> (lexbuf: Lexbuf) key (getInitialData: unit -> 'T) =
19+
let store = lexbuf.BufferLocalStore
20+
21+
match store.TryGetValue key with
22+
| true, data -> data :?> 'T
23+
| _ ->
24+
let data = getInitialData ()
25+
store[key] <- data
26+
data
27+
28+
let private tryGetStoreData<'T when 'T: not null> (lexbuf: Lexbuf) key =
29+
let store = lexbuf.BufferLocalStore
30+
31+
match store.TryGetValue key with
32+
| true, data -> Some(data :?> 'T)
33+
| _ -> None
34+
35+
let private setStoreData (lexbuf: Lexbuf) key data = lexbuf.BufferLocalStore[key] <- data
36+
37+
//------------------------------------------------------------------------
38+
// A SynArgNameGenerator for the current file, used by the parser
39+
//------------------------------------------------------------------------
40+
41+
let getSynArgNameGenerator (lexbuf: Lexbuf) =
42+
getStoreData lexbuf "SynArgNameGenerator" SynArgNameGenerator
43+
44+
//------------------------------------------------------------------------
45+
// A XmlDocCollector, used to hold the current accumulated Xml doc lines, and related access functions
46+
//------------------------------------------------------------------------
47+
48+
[<RequireQualifiedAccess>]
49+
module XmlDocStore =
50+
let private xmlDocKey = "XmlDoc"
51+
52+
let private getCollector (lexbuf: Lexbuf) =
53+
getStoreData lexbuf xmlDocKey XmlDocCollector
54+
55+
/// Called from the lexer to save a single line of XML doc comment.
56+
let SaveXmlDocLine (lexbuf: Lexbuf, lineText, range: range) =
57+
let collector = getCollector lexbuf
58+
collector.AddXmlDocLine(lineText, range)
59+
60+
let AddGrabPoint (lexbuf: Lexbuf) =
61+
let collector = getCollector lexbuf
62+
let startPos = lexbuf.StartPos
63+
collector.AddGrabPoint(mkPos startPos.Line startPos.Column)
64+
65+
/// Allowed cases when there are comments after XmlDoc
66+
///
67+
/// /// X xmlDoc
68+
/// // comment
69+
/// //// comment
70+
/// (* multiline comment *)
71+
/// let x = ... // X xmlDoc
72+
///
73+
/// Remember the first position when a comment (//, (* *), ////) is encountered after the XmlDoc block
74+
/// then add a grab point if a new XmlDoc block follows the comments
75+
let AddGrabPointDelayed (lexbuf: Lexbuf) =
76+
let collector = getCollector lexbuf
77+
let startPos = lexbuf.StartPos
78+
collector.AddGrabPointDelayed(mkPos startPos.Line startPos.Column)
79+
80+
/// Called from the parser each time we parse a construct that marks the end of an XML doc comment range,
81+
/// e.g. a 'type' declaration. The markerRange is the range of the keyword that delimits the construct.
82+
let GrabXmlDocBeforeMarker (lexbuf: Lexbuf, markerRange: range) =
83+
match tryGetStoreData lexbuf xmlDocKey with
84+
| Some collector -> PreXmlDoc.CreateFromGrabPoint(collector, markerRange.Start)
85+
| _ -> PreXmlDoc.Empty
86+
87+
let ReportInvalidXmlDocPositions (lexbuf: Lexbuf) =
88+
let collector = getCollector lexbuf
89+
collector.CheckInvalidXmlDocPositions()
90+
91+
//------------------------------------------------------------------------
92+
// Storage to hold the current accumulated ConditionalDirectiveTrivia, and related types and access functions
93+
//------------------------------------------------------------------------
94+
95+
type LexerIfdefExpression =
96+
| IfdefAnd of LexerIfdefExpression * LexerIfdefExpression
97+
| IfdefOr of LexerIfdefExpression * LexerIfdefExpression
98+
| IfdefNot of LexerIfdefExpression
99+
| IfdefId of string
100+
101+
let rec LexerIfdefEval (lookup: string -> bool) =
102+
function
103+
| IfdefAnd(l, r) -> (LexerIfdefEval lookup l) && (LexerIfdefEval lookup r)
104+
| IfdefOr(l, r) -> (LexerIfdefEval lookup l) || (LexerIfdefEval lookup r)
105+
| IfdefNot e -> not (LexerIfdefEval lookup e)
106+
| IfdefId id -> lookup id
107+
108+
[<RequireQualifiedAccess>]
109+
module IfdefStore =
110+
let private getStore (lexbuf: Lexbuf) =
111+
getStoreData lexbuf "Ifdef" ResizeArray<ConditionalDirectiveTrivia>
112+
113+
let private mkRangeWithoutLeadingWhitespace (lexed: string) (m: range) : range =
114+
let startColumn = lexed.Length - lexed.TrimStart().Length
115+
mkFileIndexRange m.FileIndex (mkPos m.StartLine startColumn) m.End
116+
117+
let SaveIfHash (lexbuf: Lexbuf, lexed: string, expr: LexerIfdefExpression, range: range) =
118+
let store = getStore lexbuf
119+
120+
let expr =
121+
let rec visit (expr: LexerIfdefExpression) : IfDirectiveExpression =
122+
match expr with
123+
| LexerIfdefExpression.IfdefAnd(l, r) -> IfDirectiveExpression.And(visit l, visit r)
124+
| LexerIfdefExpression.IfdefOr(l, r) -> IfDirectiveExpression.Or(visit l, visit r)
125+
| LexerIfdefExpression.IfdefNot e -> IfDirectiveExpression.Not(visit e)
126+
| LexerIfdefExpression.IfdefId id -> IfDirectiveExpression.Ident id
127+
128+
visit expr
129+
130+
let m = mkRangeWithoutLeadingWhitespace lexed range
131+
132+
store.Add(ConditionalDirectiveTrivia.If(expr, m))
133+
134+
let SaveElseHash (lexbuf: Lexbuf, lexed: string, range: range) =
135+
let store = getStore lexbuf
136+
let m = mkRangeWithoutLeadingWhitespace lexed range
137+
store.Add(ConditionalDirectiveTrivia.Else(m))
138+
139+
let SaveEndIfHash (lexbuf: Lexbuf, lexed: string, range: range) =
140+
let store = getStore lexbuf
141+
let m = mkRangeWithoutLeadingWhitespace lexed range
142+
store.Add(ConditionalDirectiveTrivia.EndIf(m))
143+
144+
let GetTrivia (lexbuf: Lexbuf) : ConditionalDirectiveTrivia list =
145+
let store = getStore lexbuf
146+
Seq.toList store
147+
148+
//------------------------------------------------------------------------
149+
// Storage to hold the current accumulated CommentTrivia, and related access functions
150+
//------------------------------------------------------------------------
151+
152+
[<RequireQualifiedAccess>]
153+
module CommentStore =
154+
let private getStore (lexbuf: Lexbuf) =
155+
getStoreData lexbuf "Comments" ResizeArray<CommentTrivia>
156+
157+
let SaveSingleLineComment (lexbuf: Lexbuf, startRange: range, endRange: range) =
158+
let store = getStore lexbuf
159+
let m = unionRanges startRange endRange
160+
store.Add(CommentTrivia.LineComment(m))
161+
162+
let SaveBlockComment (lexbuf: Lexbuf, startRange: range, endRange: range) =
163+
let store = getStore lexbuf
164+
let m = unionRanges startRange endRange
165+
store.Add(CommentTrivia.BlockComment(m))
166+
167+
let GetComments (lexbuf: Lexbuf) : CommentTrivia list =
168+
let store = getStore lexbuf
169+
Seq.toList store
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
module internal FSharp.Compiler.LexerStore
4+
5+
open FSharp.Compiler.SyntaxTreeOps
6+
open FSharp.Compiler.SyntaxTrivia
7+
open FSharp.Compiler.UnicodeLexing
8+
open FSharp.Compiler.Text
9+
open FSharp.Compiler.Xml
10+
11+
val getSynArgNameGenerator: Lexbuf -> SynArgNameGenerator
12+
13+
[<RequireQualifiedAccess>]
14+
module XmlDocStore =
15+
16+
val SaveXmlDocLine: lexbuf: Lexbuf * lineText: string * range: range -> unit
17+
18+
val GrabXmlDocBeforeMarker: lexbuf: Lexbuf * markerRange: range -> PreXmlDoc
19+
20+
val AddGrabPoint: lexbuf: Lexbuf -> unit
21+
22+
val AddGrabPointDelayed: lexbuf: Lexbuf -> unit
23+
24+
val ReportInvalidXmlDocPositions: lexbuf: Lexbuf -> range list
25+
26+
type LexerIfdefExpression =
27+
| IfdefAnd of LexerIfdefExpression * LexerIfdefExpression
28+
| IfdefOr of LexerIfdefExpression * LexerIfdefExpression
29+
| IfdefNot of LexerIfdefExpression
30+
| IfdefId of string
31+
32+
val LexerIfdefEval: lookup: (string -> bool) -> _arg1: LexerIfdefExpression -> bool
33+
34+
[<RequireQualifiedAccess>]
35+
module IfdefStore =
36+
37+
val SaveIfHash: lexbuf: Lexbuf * lexed: string * expr: LexerIfdefExpression * range: range -> unit
38+
39+
val SaveElseHash: lexbuf: Lexbuf * lexed: string * range: range -> unit
40+
41+
val SaveEndIfHash: lexbuf: Lexbuf * lexed: string * range: range -> unit
42+
43+
val GetTrivia: lexbuf: Lexbuf -> ConditionalDirectiveTrivia list
44+
45+
[<RequireQualifiedAccess>]
46+
module CommentStore =
47+
48+
val SaveSingleLineComment: lexbuf: Lexbuf * startRange: range * endRange: range -> unit
49+
50+
val SaveBlockComment: lexbuf: Lexbuf * startRange: range * endRange: range -> unit
51+
52+
val GetComments: lexbuf: Lexbuf -> CommentTrivia list

0 commit comments

Comments
 (0)