-
-
Notifications
You must be signed in to change notification settings - Fork 859
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
Warning suppression #4459
base: main
Are you sure you want to change the base?
Warning suppression #4459
Conversation
warnings now get tracepoints
adds tracepoints to returned errors and warnings automatically
avoids an unnecessary sink extension if the sink is empty
no idea why this is needed but it is
done directly in the lexer.
crates/typst-syntax/src/ast.rs
Outdated
|
||
node! { | ||
/// A decorator: `/! allow("warning")`. | ||
Decorator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, I prefer the naming "annotation". We also discussed the syntax // @allow warning
, which I prefer. There was a bunch of discussion about doc comments (and a bit about annotations) on Discord (starting here), so it's still a bit open I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The syntax has been updated, though we may want to confirm it through further discussion.
crates/typst-syntax/src/lexer.rs
Outdated
/// and rigid structure, in the form | ||
/// `/! decorator-name("string argument1", "string argument2")` | ||
/// with optional whitespaces and comments between arguments. | ||
fn decorator(&mut self, start: usize) -> SyntaxNode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll skip reviewing this for now as the syntax is subject the change.
- Improve tree search - Improve annotation argument loop
UPDATE (2024-08-06): After lots of discussion (internally, over Discord etc.) regarding not only the ideal syntax for annotations, but also the potential use cases for warn suppression, we've decided to prioritize other, more important improvements for diagnostics, so this PR won't move forward for the time being.
This PR implements warning suppression within Typst source code, and all the underlying features that it requires:
DecoratorAnnotation syntax (used to annotate where warn suppression occurs, indicating which warnings are suppressed)Regarding internals, also implements some important lexing changes (might conflict a bit with #4364 , but hopefully not very much).
The idea is to make it possible to add more warnings without hurting UX too much, by allowing users to suppress them.
Draft: There are some rough edges in some places, so the PR shouldn't be merged just yet. (Also, many more tests are needed.)
Overview
This is what it looks like:
(Note: Used to be
/! allow("unnecessary-stars")
in the initial version of the PR)We can see all three main elements of this PR here:
DecoratorAnnotation syntax:// @name("argument", "argument2")
annotates something relevant to the compiler at the source code.decoratorsannotations should be nearly as flexible as comments so that they can be inserted in various locations within the source code. Hence why the syntax resembles that of comments as well.**
having no effect now has an identifier,"unnecessary-stars"
. This is bikesheddable and I chose some (in principle, reasonable) initial names for all existing warnings.allow
decorator, which takes warning identifiers, causes the given warning to be suppressed if it is raised under the decorator. That is, it won't be raised by the compiler at that point.Of note, warning suppression applies to warnings raised not only directly under the decorator (or nested within what's under it), but also warnings raised in other files (or elsewhere in the same file) which have tracepoints that lead back to the decorator. For now, only calling functions (during eval) adds tracepoints to warnings, meaning that warnings raised during layout won't have tracepoints, or the tracepoints will be incomplete (e.g. warnings in a
context { }
).This means that the
unnecessary-stars
warning will be suppressed in all of the following cases:But not in the cases below (must be up to one line above):
Implementation highlights
diag.rs
.next()
returns aSyntaxNode
. It's almost always a leaf node, except when there is an error (then an error is returned - this meanstake_error
and such are now internal) or when lexing a decorator (which returns a node with a subtree).SyntaxKind
, and as such I didn't change raw elements to use this new lexer API. I think this is better suited to a separate PR to better gauge if there could be any possible regressions when implementing that.Engine::tracepoint
which is used to run some code and then immediately attach a tracepoint to the returned errors (through a returnedSourceDiagnostic
) and warnings (through a temporarySink
, which is created in the function and then merged into the outer engine'sSink
).impl Eval for FuncCall
to add a tracepoint to all warnings raised during a function's evaluation. This allows tracking which function calls led to a warning being raised.Sink
, we now store duplicate warnings (relaxed warning deduplication), but only as long as they have differing tracepoints. This is because we need to keep track of all sets of tracepoints for a warning, since anallow
decorator above a particular tracepoint might suppress that warning at that point, but the warning might still be raised because it wasn't suppressed at other tracepoint chains.LinkedNode::prev_attached_decorator
which searches for the nearest sibling decorator before the given syntax node, but only up to one line before it. That is, decorators two lines above a given node don't apply to it. (To properly implement this, syntax nodes now keep track of if they have 0, 1 or 2 newlines within them.)Sink::suppress_and_deduplicate_warnings
which performs suppression by searching the syntax tree near where each warning was raised - as well as near each tracepoint - by checking if there is any decorator sibling before the node at the warning's span that suppresses it (see the previous item). If not, checks the node's parent, and keeps checking parents and their attached decorators until either a decorator suppressing this warning is found, or we reached the root node of the source file.compile
to take and return the warnings, so warning suppression always occurs after a compilation.TODO
A few TODOs before undrafting:
\r\n
correctly. Thanks @LaurenzV!)context { }
and tracepointsImprove theKeeping as is for nowTrace
trait stuff indiag.rs
(I feel like there might be a less convoluted way to do this)Decorator::arguments
consideringDecoratorName