-
Notifications
You must be signed in to change notification settings - Fork 656
Conversation
crates/formatter/src/formatter.rs
Outdated
@@ -28,16 +31,17 @@ impl Formatter { | |||
pub fn format_root(self, root: &SyntaxNode) -> FormatResult { | |||
let element = self | |||
.format_syntax_node(root) | |||
.unwrap_or_else(|| self.format_raw(root)); | |||
// TODO: we have an error here. Diagnostic? |
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.
Should the formatter ever be responsible for reporting syntax errors? I assume the parser would still emit diagnostics for every syntax error even if we recover and run other tools like the formatter.
Maybe this would be the difference between logging levels though, if you passed a --log-level=verbose
it would also emit these kinds of events from other tools so we can debug why the formatter didn't format what we expected.
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.
Yes it makes sense. Although executing an unwrap without a comment explaining why we don't care about the error, or a way to handle that error doesn't seem right to me, hence the TODO
:)
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 think we should either return an error or return the text as is
d35e180
to
a234071
Compare
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.
Nice work!
Would you mind testing if your PR affects the coverage?
Your code made it clear to me that there's an issue with the kind parameter of MissingElement
. There's no obvious choice for the missing kind if the child is an union, e.g. the binary expression operator (different tokens) or if it's an expression.
I think we should either drop the param or change the error to MissingRequiredChild { parent: SyntaxNode }
// TODO: review, we can have a better error | ||
None => Err(FormatError::UnknownNode), |
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.
Isn't this a MissingNode
error? Either the equal
or value
were missing. You can get the right kind by extending the match on line 17 to handle the Some(_), None
and None, Some(_)
cases to return a Missing
error. This will be nicer once we improved the AST Facade.
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.
Unfortunately it's impossible to get the .kind()
of equal
and value
unless we actually decide to hardcode it inside the error MissingNode
.
Also, what if .value()
returned a UnknownExpression
? Wouldn't it count as UnknownNode
? That's the part where I am struggling at the moment, understanding and handling missing nodes VS unknown nodes inside the formatter.
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.
Also, what if .value() returned a UnknownExpression? Wouldn't it count as UnknownNode? That's the part where I am struggling at the moment, understanding and handling missing nodes VS unknown nodes inside the formatted.
Maybe, depends on how we want to do the formatting for Unkown
nodes:
- If we want to format the nodes as is, then implementing
ToFormatElement
forUnknownExpression
is enough. - If we want to bail out of formatting, then having an
UnknownNode
error is the way to go and theUnknown*
implementation would just bail out with that error.
So I tried to implement Adding a I will remove the info about the parent for now, I think we can figure out something later. |
Cloning is cheap but yeah, we don't have a use case for the param yet. Should we go with dropping the kind param for now and then add whatever we need for our tracking purposes when we need it? |
a234071
to
2c83063
Compare
/// When the ability to format the current file has been turned off on purpose | ||
CapabilityDisabled, |
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.
Is it worth differentiating between UnsupportedLanguage
and CapabilityDisabled
? Isn't the capability
disabled for the case where our formatter doesn't support formatting (UnsupportedLanguage
?).
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.
Yes it is worth it. Supporting a language and being able to format it should be two separate things. For example, in RomeJS we had support for parsing CSS but the format was turned off publicly. In the meantime, we could programmatically turn it on and test it, incrementally, until we were happy with the final result.
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.
That's fair. Is it something Formater consumers should be aware of tough? For them, it's an unsupported language.
Please go forward with what you think best.
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.
Not necessarily, we might have linting enabled while formatter still disabled (for the same language). If things changes, we are still in time for unifying everything and having the broad "unsupported" error.
closes #1732 |
Summary
Part of #1725
Closes #1731
Closes #1740
This PR applies the following changes:
Optional<Node>
/Optional<SyntaxToken>
. Nodes and tokens that are not marked as optional, will now generated code asSyntaxResult<Node>
/SyntaxResult<SyntaxToken>
;SyntaxResult
;Result
instead ofOption
;TODO
where we know that we will need to remove/change some logic. Some of that logic was kept there to maintain compatibility. Once we will start migrating to a better syntax, we will change (or remove) that logic too;FormatResult
inFormatted
FormatResult
type that isResult<T, FormatError>
FormatError
which yields different types of error based on the situationformat_root
now returns aFormatResult<Formatted>
Test Plan