Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions src/FSharpLint.Core/Application/Lint.fs
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ module Lint =
let parsedFiles =
files
|> List.filter (not << isIgnoredFile)
|> List.map (fun file -> ParseFile.parseFile file checker (Some projectOptions))
|> List.map (fun file -> ParseFile.parseFile file checker (Some projectOptions) |> Async.RunSynchronously)

let failedFiles = List.choose getFailedFiles parsedFiles

Expand Down Expand Up @@ -585,19 +585,25 @@ module Lint =
LintResult.Failure (RunTimeConfigError err)

/// Lints F# source code.
let lintSource optionalParams source =
let checker = FSharpChecker.Create(keepAssemblyContents=true)
let asyncLintSource optionalParams source =
async {
let checker = FSharpChecker.Create(keepAssemblyContents=true)

match ParseFile.parseSource source checker with
| ParseFile.Success(parseFileInformation) ->
let parsedFileInfo =
{ Source = parseFileInformation.Text
Ast = parseFileInformation.Ast
TypeCheckResults = parseFileInformation.TypeCheckResults }
match! ParseFile.parseSource source checker with
| ParseFile.Success(parseFileInformation) ->
let parsedFileInfo =
{ Source = parseFileInformation.Text
Ast = parseFileInformation.Ast
TypeCheckResults = parseFileInformation.TypeCheckResults }

lintParsedSource optionalParams parsedFileInfo
| ParseFile.Failed failure -> LintResult.Failure(FailedToParseFile failure)
return lintParsedSource optionalParams parsedFileInfo
| ParseFile.Failed failure -> return LintResult.Failure(FailedToParseFile failure)
}

/// Lints F# source code.
let lintSource optionalParams source =
asyncLintSource optionalParams source |> Async.RunSynchronously

/// Lints an F# file that has already been parsed using `FSharp.Compiler.Services` in the calling application.
let lintParsedFile (optionalParams:OptionalLintParameters) (parsedFileInfo:ParsedFileInformation) (filePath:string) =
match getConfig optionalParams.Configuration with
Expand Down Expand Up @@ -631,7 +637,7 @@ module Lint =
if IO.File.Exists filePath then
let checker = FSharpChecker.Create(keepAssemblyContents=true)

match ParseFile.parseFile filePath checker None with
match ParseFile.parseFile filePath checker None |> Async.RunSynchronously with
| ParseFile.Success astFileParseInfo ->
let parsedFileInfo =
{ Source = astFileParseInfo.Text
Expand All @@ -654,7 +660,7 @@ module Lint =

let lintSingleFile filePath =
if IO.File.Exists filePath then
match ParseFile.parseFile filePath checker None with
match ParseFile.parseFile filePath checker None |> Async.RunSynchronously with
| ParseFile.Success astFileParseInfo ->
let parsedFileInfo =
{ Source = astFileParseInfo.Text
Expand Down
5 changes: 4 additions & 1 deletion src/FSharpLint.Core/Application/Lint.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ module Lint =
/// Lints F# source code.
val lintSource : optionalParams:OptionalLintParameters -> source:string -> LintResult

/// Lints F# source code async.
val asyncLintSource : optionalParams:OptionalLintParameters -> source:string -> Async<LintResult>

/// Lints F# source code that has already been parsed using
/// `FSharp.Compiler.Services` in the calling application.
val lintParsedSource : optionalParams:OptionalLintParameters -> parsedFileInfo:ParsedFileInformation -> LintResult
Expand All @@ -168,4 +171,4 @@ module Lint =

/// Lints an F# file that has already been parsed using
/// `FSharp.Compiler.Services` in the calling application.
val lintParsedFile : optionalParams:OptionalLintParameters -> parsedFileInfo:ParsedFileInformation -> filePath:string -> LintResult
val lintParsedFile : optionalParams:OptionalLintParameters -> parsedFileInfo:ParsedFileInformation -> filePath:string -> LintResult
36 changes: 19 additions & 17 deletions src/FSharpLint.Core/Framework/ParseFile.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace FSharpLint.Framework
namespace FSharpLint.Framework

/// Provides functionality to parse F# files using `FSharp.Compiler.Service`.
module ParseFile =
Expand Down Expand Up @@ -37,49 +37,51 @@ module ParseFile =
| Failed of ParseFileFailure
| Success of 'Content

let private parse file source (checker:FSharpChecker, options) =
let private parse file source (checker:FSharpChecker, options) = async {
let sourceText = SourceText.ofString source
let (parseResults, checkFileAnswer) =
let! parseResults, checkFileAnswer =
checker.ParseAndCheckFileInProject(file, 0, sourceText, options)
|> Async.RunSynchronously

match checkFileAnswer with
| FSharpCheckFileAnswer.Succeeded(typeCheckResults) ->
Success
return Success
{
Text = source
Ast = parseResults.ParseTree
TypeCheckResults = Some(typeCheckResults)
File = file
}
| FSharpCheckFileAnswer.Aborted -> Failed(AbortedTypeCheck)
| FSharpCheckFileAnswer.Aborted -> return Failed(AbortedTypeCheck)
}

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

let (options, _diagnostics) =
let! options, _diagnostics =
checker.GetProjectOptionsFromScript(file, sourceText, assumeDotNetFramework = assumeDotNetFramework, useSdkRefs = not assumeDotNetFramework, otherFlags = otherOpts)
|> Async.RunSynchronously
options
return options
}

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

let projectOptions =
let! projectOptions =
match projectOptions with
| Some(existingOptions) -> existingOptions
| Some(existingOptions) -> async { return existingOptions }
| None -> getProjectOptionsFromScript checker file source

parse file source (checker, projectOptions)
return! parse file source (checker, projectOptions)
}

/// Parses source code using `FSharp.Compiler.Service`.
let parseSourceFile fileName source (checker:FSharpChecker) =
let options = getProjectOptionsFromScript checker fileName source
let parseSourceFile fileName source (checker:FSharpChecker) = async {
let! options = getProjectOptionsFromScript checker fileName source

parse fileName source (checker, options)
return! parse fileName source (checker, options)
}

let parseSource source (checker:FSharpChecker) =
let fileName = Path.ChangeExtension(Path.GetTempFileName(), "fsx")
Expand Down
2 changes: 1 addition & 1 deletion tests/FSharpLint.Core.Tests/Rules/TestAstNodeRule.fs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type TestAstNodeRuleBase (rule:Rule) =

let globalConfig = Option.defaultValue GlobalRuleConfig.Default globalConfig

match parseResults with
match Async.RunSynchronously parseResults with
| ParseFileResult.Success parseInfo ->
let syntaxArray = AbstractSyntaxArray.astToArray parseInfo.Ast
let checkResult =
Expand Down
2 changes: 1 addition & 1 deletion tests/FSharpLint.Core.Tests/Rules/TestHintMatcherBase.fs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ type TestHintMatcherBase () =

let globalConfig = Option.defaultValue GlobalRuleConfig.Default globalConfig

match parseResults with
match Async.RunSynchronously parseResults with
| ParseFileResult.Success parseInfo ->
let syntaxArray = AbstractSyntaxArray.astToArray parseInfo.Ast
let checkResult =
Expand Down
21 changes: 13 additions & 8 deletions tests/FSharpLint.Core.Tests/TestUtils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,22 @@

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

let generateAst source =
let checker = FSharpChecker.Create(keepAssemblyContents=true)
let sourceText = SourceText.ofString source
let asyncGenerateAst source =
async {
let checker = FSharpChecker.Create(keepAssemblyContents=true)
let sourceText = SourceText.ofString source

let! options =
ParseFile.getProjectOptionsFromScript checker performanceTestSourceFile source

let options = ParseFile.getProjectOptionsFromScript checker performanceTestSourceFile source
let! parseResults =
checker.ParseFile(performanceTestSourceFile, sourceText, options |> checker.GetParsingOptionsFromProjectOptions |> fst)

let parseResults =
checker.ParseFile(performanceTestSourceFile, sourceText, options |> checker.GetParsingOptionsFromProjectOptions |> fst)
|> Async.RunSynchronously
return parseResults.ParseTree
}

parseResults.ParseTree
let generateAst source =
asyncGenerateAst source |> Async.RunSynchronously

let getPerformanceTestInput =
let memoizedResult = ref None
Expand Down
Loading