Skip to content

Ensure script load closure is always executed for GetProjectSnapshotFromScript #16880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 18, 2024

Conversation

nojaf
Copy link
Contributor

@nojaf nojaf commented Mar 15, 2024

Description

In the transparent compiler the GetProjectSnapshotFromScript would currently re-use the load closure from the cache for the same file. This is problematic as newly loaded files would not be picked up.

See test for a good example. There, the loading of file c.fsx (from b.fsx) would not be picked up if the load closure was re-used.

The changes in this PR align the behaviour better with what the background compiler does: never use the load closure cache in GetProjectOptionsFromScript but add the result to the cache afterwards. So it can be reused in ParseAndCheckFileInProject.

//cc @0101 @auduchinok

Checklist

  • Test cases added

  • Performance benchmarks added in case of performance changes

  • Release notes entry updated:

    Please make sure to add an entry with short succinct description of the change as well as link to this pull request to the respective release notes file, if applicable.

    Release notes files:

    • If anything under src/Compiler has been changed, please make sure to make an entry in docs/release-notes/.FSharp.Compiler.Service/<version>.md, where <version> is usually "highest" one, e.g. 42.8.200
    • If language feature was added (i.e. LanguageFeatures.fsi was changed), please add it to docs/releae-notes/.Language/preview.md
    • If a change to FSharp.Core was made, please make sure to edit docs/release-notes/.FSharp.Core/<version>.md where version is "highest" one, e.g. 8.0.200.

    Information about the release notes entries format can be found in the documentation.
    Example:

    If you believe that release notes are not necessary for this PR, please add NO_RELEASE_NOTES label to the pull request.

@nojaf nojaf requested a review from a team as a code owner March 15, 2024 09:48
@nojaf nojaf added NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes Transparent-Compiler labels Mar 15, 2024
Copy link
Contributor

github-actions bot commented Mar 15, 2024

⚠️ Release notes required, but author opted out

Warning

Author opted out of release notes, check is disabled for this pull request.
cc @dotnet/fsharp-team-msft

@vzarytovskii vzarytovskii enabled auto-merge (squash) March 18, 2024 15:49
auto-merge was automatically disabled March 18, 2024 16:02

Head branch was pushed to by a user without write access

@abonie abonie merged commit 74e3362 into dotnet:main Mar 18, 2024
Copy link
Contributor

@0101 0101 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has a bit suspicious use of AsyncMemoize. I get why it's needed, but wondering if there's a more elegant solution to all this.

A "proper" solution would maybe require a two step process where we first gather all the files that are being loaded and then for the second step we can already supply their snapshots as input.

[<InlineData(true)>]
let ``The script load closure should always be evaluated`` useTransparentCompiler =
async {
// The LoadScriptClosure uses the file system shim so we need to reset that.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to deal with the file system when we have DocumentSource? Is it because of the original implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the actual ScriptLoadClosure relies on the FileSystemShim.
It currently cannot use the DocumentSource.

useSdkRefs
assumeDotNetFramework
(projectFileName, "")
otherFlags
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now different than the otherFlags the closure was computed with, is that ok?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because without these changes it does not get reused in ParseAndCheckFileInProject.


// Populate the cache.
let! _ =
caches.ScriptClosure.Get(loadClosureKey, node { return loadClosure })
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will only populate the cache if the key isn't already there, is that expected?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the ISourceTextNew is part of the key, I would also expect this to more or less always be the case that the cache won't have the entry.

Unless GetProjectSnapshotFromScript is being called with the exact same input twice, I don't think this will ever happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes Transparent-Compiler
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants