Skip to content
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

[WIP] Source cache refactor #1827

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft

[WIP] Source cache refactor #1827

wants to merge 20 commits into from

Conversation

vkleen
Copy link
Member

@vkleen vkleen commented Feb 23, 2024

No description provided.

Copy link
Member

@yannham yannham left a comment

Choose a reason for hiding this comment

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

I didn't look into all the details. I think I like the general idea of making the cache...just a cache. Although the previous one had a nice encapsulation, it also made extracting some data from it (like source ids or the like) quite painful, needing to couple code with the actual cache instead of ImportResolver for example.

One aspect that needs to be really considered is the error tolerance, though. I see it disappeared from the new cache. I think we had several series of annoying bugs where some operation should be error-tolerant but wasn't, or the converse, leading to errors being reported too late in the pipe line. We thus decided to set in stone at the cache level if we are in an error tolerant mode (basically, LSP), or not. Doing that on a per-function basis was just too error prone. I think we should have the same kind of guarantee in the new cache (or it can somewhere else than in cache, but at least centralized in an object such that each individual "parse" doesn't have to think about error tolerance). I honestly don't know these days how the LSP uses the cache. Maybe it's also possible to make the cache strict by default, with specific method for error-tolerant parsing, and use that only in the LSP. Although I think that's exactly what we used to do, and it was still not entirely reliable.

#[cfg(feature = "nix-experimental")]
Nix,
Raw,
}
Copy link
Member

@yannham yannham Mar 1, 2024

Choose a reason for hiding this comment

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

I wonder if we should mix that with this module. In particular because it's been in the back of my head to move the (pure) Nickel parser in a separate crate, so that

  1. It can be used by other crates to make tooling around Nickel without depending on the whole of nickel-lang-core
  2. It's a separate compilation unit that we don't need to even look at if we didn't touch the grammar

I guess it's still doable, but we should be wary of coupling too much the "parser pure Nickel code" with "parse generic Nickel inputs including JSON", if possible.

Copy link
Member Author

@vkleen vkleen Mar 5, 2024

Choose a reason for hiding this comment

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

Those are good points. I'm thinking of renaming the prepare.rs module into a driver module where this functionality might fit better. That should also give us a better point to track error tolerance.

file_id: FileId,
) -> Result<CacheOp<()>, Vec<Diagnostic<FileId>>> {
file_id: CacheKey,
) -> Result<(), Vec<Diagnostic<CacheKey>>> {
Copy link
Member

Choose a reason for hiding this comment

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

I vaguely remember CacheOp<()> being a useful distinction from () to avoid cycles/loops when typechecking or importing circular stuff. But I'm not sure.

Copy link
Member Author

Choose a reason for hiding this comment

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

Grepping through the source code, by now CacheOp is used in a single place in the LSP (apart from the cache itself) and that is an extension function to the cache. So I think it's safe to get rid of it in the external interface of the cache.

}
_ => Ok(cache
.get_parse_errors(cache_key)
.expect("Any parsed entry should have a corresponding entry in parse_errors")
Copy link
Member

@yannham yannham Mar 1, 2024

Choose a reason for hiding this comment

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

Should we encode that with an enum, instead of a separate EntryState in a struct?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure why I wanted the parse errors to be stored separately from the cache entries, but that seems silly to me now. I've changed the code to store parse errors directly in the cache entry for parsed entries. The only wrinkle is that it would be annoying to keep parse errors around after the entry is advanced from "parsed" to "typechecked". But would there be any reason to proceed to typechecking for a source file that doesn't parse correctly, even in the LSP?

Copy link
Member

@yannham yannham Mar 7, 2024

Choose a reason for hiding this comment

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

Ah, I believe we do proceed with typechecking on a source file that doesn't parse correctly. If only because typechecking is actually the driver for the whole code analysis (goto(ref|def), hover, etc.), and we want to provide analysis for as much code as possible. In fact the typechecker explicitly ignores parse errors in the AST for that very reason:

Term::ParseError(_) => Ok(()),

@github-actions github-actions bot temporarily deployed to pull request March 5, 2024 12:38 Inactive
@github-actions github-actions bot temporarily deployed to pull request March 6, 2024 19:07 Inactive
@github-actions github-actions bot temporarily deployed to pull request March 6, 2024 19:12 Inactive
@github-actions github-actions bot temporarily deployed to pull request March 7, 2024 10:41 Inactive
@github-actions github-actions bot temporarily deployed to pull request March 7, 2024 21:39 Inactive
@github-actions github-actions bot temporarily deployed to pull request March 8, 2024 17:02 Inactive
@github-actions github-actions bot temporarily deployed to pull request March 8, 2024 17:57 Inactive
@github-actions github-actions bot temporarily deployed to pull request March 9, 2024 21:34 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants