(complete, intrusive fix) async rules crash under the TransparentCompiler#863
Conversation
… TransparentCompiler The library-heuristic rules (AsynchronousFunctionNames, SimpleAsyncComplementaryHelpers, NoAsyncRunSynchronouslyInLibrary) need only the project file name. The two-phase ProjectOptions lazy derived it via FSharpProjectContext.ProjectOptions, which throws by design when the check results come from FCS's TransparentCompiler, aborting linting of the whole file. Expose the project file name to rules directly (AstNodeRuleParams.ProjectFileName) and let callers supply it (ParsedFileInformation.ProjectFileName / FileParseInfo.ProjectFileName). Project-mode lint fills it from the FSharpProjectOptions it already builds; analyzer hosts can supply their .fsproj path. Deriving it from the check results remains as a guarded fallback, so behavior is preserved everywhere and no longer depends on a getter the TransparentCompiler cannot serve. Regression: TestApi lints TransparentCompiler-produced results without an internal failure, and verifies a caller-supplied library project name engages the async-naming rule under the TransparentCompiler.
864cf99 to
5d80961
Compare
|
fwiw, the F# Analyzers SDK tries to cover up some of the differences between the Not sure if doing something like that around here could add more support for the transparent compiler in general? |
|
Hey @michaelglass thanks for the PRs.
Hey Richard, would adopting this approach mean that we don't need the try-with block anymore? (I'm not very fond of typeless try-with blocks) BTW apologies in advance for not being very responsive these days, as I'm kinda busy IRL with a move. |
When this happens
If you run FSharpLint as a library — the
lintParsedFile/lintParsedSourceAPI, passing your ownProjectCheckResults— and those results come from anFSharpCheckercreated withuseTransparentCompiler = true, linting aborts on otherwise-valid files with an internal error. The trigger is the async/library-heuristic rules:AsynchronousFunctionNames,SimpleAsyncComplementaryHelpers, andNoAsyncRunSynchronouslyInLibrary(the first and last are on by default).Concretely: in my project FsHotWatch I use FSharpLint as a library (not the CLI tool), reusing warm FCS check results to re-lint files on save. When I switched the underlying
FSharpCheckerto the TransparentCompiler, valid files started failing to lint with an internal error.Why
Those rules need only one thing: the project file name, for a name-based "is this a library?" check. They get it through the two-phase
ProjectOptionslazy, which readsFSharpProjectContext.ProjectOptions— a getter that throws by design under the TransparentCompiler. And under the TransparentCompiler there's no way to recover the name from the check results at all: the context exposes no file name and no snapshot.Fix
Let the caller supply the project file name directly, since it's all the rules need:
ProjectFileName(was the wholeProjectOptions);ParsedFileInformation/FileParseInfogain aProjectFileName: string option;FSharpProjectOptionsit already builds; a library caller passes its.fsprojpath;Net effect: the library heuristic keeps working under the TransparentCompiler instead of silently treating every project as not-a-library.
Test
TestApi.fs:MyLib.fsproj) engages the async-naming rule under the TransparentCompiler, whileNonedegrades to not-a-library.Trade-off vs #862 (the SIMPLER fix)
#862 is smaller (no public API change) but leaves the three rules degraded under the TransparentCompiler. This one adds a small public field (
ParsedFileInformation.ProjectFileName) plus the rule-context change, and in exchange loses no behavior.if it wasn't obvious from the tone of the PR: this work was done with the extensive help with AI, and then eyeballed / confirmed by a fleshy human being