Skip to content

Commit 5fdb6e0

Browse files
Thoriumknocte
authored andcommitted
Supports async-parsing
1 parent ecb10e9 commit 5fdb6e0

File tree

6 files changed

+55
-39
lines changed

6 files changed

+55
-39
lines changed

src/FSharpLint.Core/Application/Lint.fs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ module Lint =
476476
let parsedFiles =
477477
files
478478
|> List.filter (not << isIgnoredFile)
479-
|> List.map (fun file -> ParseFile.parseFile file checker (Some projectOptions))
479+
|> List.map (fun file -> ParseFile.parseFile file checker (Some projectOptions) |> Async.RunSynchronously)
480480

481481
let failedFiles = List.choose getFailedFiles parsedFiles
482482

@@ -585,19 +585,25 @@ module Lint =
585585
LintResult.Failure (RunTimeConfigError err)
586586

587587
/// Lints F# source code.
588-
let lintSource optionalParams source =
589-
let checker = FSharpChecker.Create(keepAssemblyContents=true)
588+
let lintSourceAsync optionalParams source =
589+
async {
590+
let checker = FSharpChecker.Create(keepAssemblyContents=true)
590591

591-
match ParseFile.parseSource source checker with
592-
| ParseFile.Success(parseFileInformation) ->
593-
let parsedFileInfo =
594-
{ Source = parseFileInformation.Text
595-
Ast = parseFileInformation.Ast
596-
TypeCheckResults = parseFileInformation.TypeCheckResults }
592+
match! ParseFile.parseSource source checker with
593+
| ParseFile.Success(parseFileInformation) ->
594+
let parsedFileInfo =
595+
{ Source = parseFileInformation.Text
596+
Ast = parseFileInformation.Ast
597+
TypeCheckResults = parseFileInformation.TypeCheckResults }
597598

598-
lintParsedSource optionalParams parsedFileInfo
599-
| ParseFile.Failed failure -> LintResult.Failure(FailedToParseFile failure)
599+
return lintParsedSource optionalParams parsedFileInfo
600+
| ParseFile.Failed failure -> return LintResult.Failure(FailedToParseFile failure)
601+
}
600602

603+
/// Lints F# source code.
604+
let lintSource optionalParams source =
605+
lintSourceAsync optionalParams source |> Async.RunSynchronously
606+
601607
/// Lints an F# file that has already been parsed using `FSharp.Compiler.Services` in the calling application.
602608
let lintParsedFile (optionalParams:OptionalLintParameters) (parsedFileInfo:ParsedFileInformation) (filePath:string) =
603609
match getConfig optionalParams.Configuration with
@@ -631,7 +637,7 @@ module Lint =
631637
if IO.File.Exists filePath then
632638
let checker = FSharpChecker.Create(keepAssemblyContents=true)
633639

634-
match ParseFile.parseFile filePath checker None with
640+
match ParseFile.parseFile filePath checker None |> Async.RunSynchronously with
635641
| ParseFile.Success astFileParseInfo ->
636642
let parsedFileInfo =
637643
{ Source = astFileParseInfo.Text

src/FSharpLint.Core/Application/Lint.fsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ module Lint =
156156
/// Lints F# source code.
157157
val lintSource : optionalParams:OptionalLintParameters -> source:string -> LintResult
158158

159+
/// Lints F# source code async.
160+
val lintSourceAsync : optionalParams:OptionalLintParameters -> source:string -> Async<LintResult>
161+
159162
/// Lints F# source code that has already been parsed using
160163
/// `FSharp.Compiler.Services` in the calling application.
161164
val lintParsedSource : optionalParams:OptionalLintParameters -> parsedFileInfo:ParsedFileInformation -> LintResult

src/FSharpLint.Core/Framework/ParseFile.fs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace FSharpLint.Framework
1+
namespace FSharpLint.Framework
22

33
/// Provides functionality to parse F# files using `FSharp.Compiler.Service`.
44
module ParseFile =
@@ -37,49 +37,51 @@ module ParseFile =
3737
| Failed of ParseFileFailure
3838
| Success of 'Content
3939

40-
let private parse file source (checker:FSharpChecker, options) =
40+
let private parse file source (checker:FSharpChecker, options) = async {
4141
let sourceText = SourceText.ofString source
42-
let (parseResults, checkFileAnswer) =
42+
let! parseResults, checkFileAnswer =
4343
checker.ParseAndCheckFileInProject(file, 0, sourceText, options)
44-
|> Async.RunSynchronously
4544

4645
match checkFileAnswer with
4746
| FSharpCheckFileAnswer.Succeeded(typeCheckResults) ->
48-
Success
47+
return Success
4948
{
5049
Text = source
5150
Ast = parseResults.ParseTree
5251
TypeCheckResults = Some(typeCheckResults)
5352
File = file
5453
}
55-
| FSharpCheckFileAnswer.Aborted -> Failed(AbortedTypeCheck)
54+
| FSharpCheckFileAnswer.Aborted -> return Failed(AbortedTypeCheck)
55+
}
5656

57-
let getProjectOptionsFromScript (checker:FSharpChecker) file (source:string) =
57+
let getProjectOptionsFromScript (checker:FSharpChecker) file (source:string) = async {
5858
let sourceText = SourceText.ofString source
5959
let assumeDotNetFramework = false
6060
let otherOpts = [| "--targetprofile:netstandard" |]
6161

62-
let (options, _diagnostics) =
62+
let! options, _diagnostics =
6363
checker.GetProjectOptionsFromScript(file, sourceText, assumeDotNetFramework = assumeDotNetFramework, useSdkRefs = not assumeDotNetFramework, otherFlags = otherOpts)
64-
|> Async.RunSynchronously
65-
options
64+
return options
65+
}
6666

6767
/// Parses a file using `FSharp.Compiler.Service`.
68-
let parseFile file (checker:FSharpChecker) projectOptions =
68+
let parseFile file (checker:FSharpChecker) projectOptions = async {
6969
let source = File.ReadAllText(file)
7070

71-
let projectOptions =
71+
let! projectOptions =
7272
match projectOptions with
73-
| Some(existingOptions) -> existingOptions
73+
| Some(existingOptions) -> async { return existingOptions }
7474
| None -> getProjectOptionsFromScript checker file source
7575

76-
parse file source (checker, projectOptions)
76+
return! parse file source (checker, projectOptions)
77+
}
7778

7879
/// Parses source code using `FSharp.Compiler.Service`.
79-
let parseSourceFile fileName source (checker:FSharpChecker) =
80-
let options = getProjectOptionsFromScript checker fileName source
80+
let parseSourceFile fileName source (checker:FSharpChecker) = async {
81+
let! options = getProjectOptionsFromScript checker fileName source
8182

82-
parse fileName source (checker, options)
83+
return! parse fileName source (checker, options)
84+
}
8385

8486
let parseSource source (checker:FSharpChecker) =
8587
let fileName = Path.ChangeExtension(Path.GetTempFileName(), "fsx")

tests/FSharpLint.Core.Tests/Rules/TestAstNodeRule.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type TestAstNodeRuleBase (rule:Rule) =
2828

2929
let globalConfig = Option.defaultValue GlobalRuleConfig.Default globalConfig
3030

31-
match parseResults with
31+
match parseResults |> Async.RunSynchronously with
3232
| ParseFileResult.Success parseInfo ->
3333
let syntaxArray = AbstractSyntaxArray.astToArray parseInfo.Ast
3434
let checkResult =

tests/FSharpLint.Core.Tests/Rules/TestHintMatcherBase.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type TestHintMatcherBase () =
5151

5252
let globalConfig = Option.defaultValue GlobalRuleConfig.Default globalConfig
5353

54-
match parseResults with
54+
match parseResults |> Async.RunSynchronously with
5555
| ParseFileResult.Success parseInfo ->
5656
let syntaxArray = AbstractSyntaxArray.astToArray parseInfo.Ast
5757
let checkResult =

tests/FSharpLint.Core.Tests/TestUtils.fs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,22 @@
1515

1616
let private performanceTestSourceFile = basePath </> "TypeChecker.fs"
1717

18-
let generateAst source =
19-
let checker = FSharpChecker.Create(keepAssemblyContents=true)
20-
let sourceText = SourceText.ofString source
18+
let generateAstAsync source =
19+
async {
20+
let checker = FSharpChecker.Create(keepAssemblyContents=true)
21+
let sourceText = SourceText.ofString source
22+
23+
let! options =
24+
ParseFile.getProjectOptionsFromScript checker performanceTestSourceFile source
2125

22-
let options = ParseFile.getProjectOptionsFromScript checker performanceTestSourceFile source
26+
let! parseResults =
27+
checker.ParseFile(performanceTestSourceFile, sourceText, options |> checker.GetParsingOptionsFromProjectOptions |> fst)
2328

24-
let parseResults =
25-
checker.ParseFile(performanceTestSourceFile, sourceText, options |> checker.GetParsingOptionsFromProjectOptions |> fst)
26-
|> Async.RunSynchronously
29+
return parseResults.ParseTree
30+
}
2731

28-
parseResults.ParseTree
32+
let generateAst source =
33+
generateAstAsync source |> Async.RunSynchronously
2934

3035
let getPerformanceTestInput =
3136
let memoizedResult = ref None

0 commit comments

Comments
 (0)