-
Notifications
You must be signed in to change notification settings - Fork 154
Re-implementations to fix function and #define related errors. #206
Conversation
- re-implement function patterns - re-implement #define patterns - prevent unnecessary nesting of section scopes - tokenize all parentheses - highlight #include_next - introduce meta.preprocessor.pragma.c scope - include hyphens in #pragma identifiers - create specs for the changes
- Included Access patterns for functions in blocks. - Moved the storage_types patterns into repository to provide modularization.
I'm looking forward to reviewing this. I recently toyed around a bit with redoing the C grammar as well and had tons of success with just changing how functions and function calls were captured (albeit losing C++ support along the way), so I'll see if I can incorporate some of what I learned into this. (I've also edited your PR description so that all the fixed issues are automatically closed when this is merged) |
Hi there @50Wliu , I know that "varargs" is not a built-in c feature and you may think it would be more appropriate for them to be handled in I have a solution for this situation and I want to fix it in By the way, how is it going with reviewing this PR? I have a new API highlighter package which is heavily dependent on the features in this PR waiting to be published. |
Regarding varargs: go for it. Regarding the review process: I'm hoping to get started this weekend. It might take a while. |
Ok. I briefly looked this over. The biggest thing that stood out to me was the excessive effort required in removing the nesting of |
grammars/c.cson
Outdated
@@ -380,38 +359,48 @@ | |||
'name': 'meta.initialization.c' | |||
} | |||
{ | |||
'include': '#block' | |||
# Prevent unnecessary nesting of meta.block.c scope | |||
'begin': '\\{' |
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.
Curly braces don't need to be escaped
grammars/c.cson
Outdated
'begin': '\\{' | ||
'beginCaptures': | ||
'0': | ||
'name': 'punctuation.section.block.begin.c' |
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.
Include .bracket.curly
after the begin
. Same with end below.
The use for meta.xxx section scopes is in auto-complete suggestions. The suggestion providers take the scopes at cursor as an argument, and are supposed to return their suggestions regarding those scopes. As an example, a suggestion provider may suggest specifically function arguments when the cursor is in meta.function. So their presence is quite important actually. |
- Implements tokenization for vararg ellipses. - Unnecessary escape characters in curly bracket regexes removed. - punctuation.section.block.XXXX.c scopes are renamed as punctuation.section.block.XXXX.bracket.curly.c - New spec added for vararg ellipses, and failing specs because of the above two changes fixed.
Yes, I recognize that. However, meta.block and meta.parens are so generic that there is no information gained from them. I'm not saying to get rid of the other meta scopes. Like you mentioned, most of the other ones do contain useful information, like meta.function. Unless you can provide a counterexample, of course. |
meta.block is again important for auto-complete suggestions. For example, the provider may suggest support function snippets when the cursor is inside a block and not when outside respectively. You wouldn't want to be suggested a function call when outside any function block. It would be annoying. However for meta.parens you may be quite right. But since we did the other two so far, why not keep meta.parens as well? The concept was there before me and maybe some community package somewhere is utilising it! So that drawback may break someones package out there. Who knows? |
@alpyre Could you give a code snippet please? Maybe I'm just too biased to be able to think of something myself 🙂. |
This is the way I used And I was planning to add a check for And finally for |
Ok. So my comment here is going to be based off of language-java, which is very verbose with its meta scopes. Instead of using a generic public class Example // meta.class.java
{ // meta.class.java meta.class.body.java
public static void main(String[] args) // meta.class.java meta.class.body.java meta.method.java
{ // meta.class.java meta.class.body.java meta.method.java meta.method.body.java
// meta.class.java meta.class.body.java meta.method.java meta.method.body.java
} // meta.class.java meta.class.body.java
} // none Basically, I think this method gives us finer-grained control, and takes care of your use case. Is this something you think can be adapted to language-c? |
I believe it can be (and should be) adapted to language-c. According to C curriculum, there are only two major types curly bracket use:
The other is the local blocks. I highly support the idea. It will have great benefits for auto-complete providers. Also the implementation for it will not require the removal of anything implemented in this PR (there will still be i.e. local blocks inside local blocks, which must be handled the same way here). It will just add some additional code. So we can keep this idea to be implemented in a next PR. Currently the only thing that will simplify this PR is the removal of We should decide on that. I'd be happy without it and can remove it with your decision now. |
Let's not worry about this for now. I don't think local blocks need their own meta scope, do you agree with that?
💯 Go for it. Also, maybe those meta changes won't simplify the PR per se, but it may make the end result easier to understand :). |
Inner local blocks don't. The outermost ones do. Because they indicate that the coder is inside a function definition block, so that an autoComplete provider can behave acording to that (the current implementation in this PR is just so). |
Ok, let's try that and see where it goes. |
- Removes all implementations for the tokenization of the section scope meta.parens.c together with all the code tricks to provide unnecessary nesting of it in the scopes array. - Fix the failing specs because of this drawback.
Now, before you do the merge, I'd like to make a subtle change in my This will save the code from one another rule and also solve the ‘blocks in parentheses’ issue mentioned in Alternate Designs (only for |
@alpyre can you clarify on how misnesting is allowed? |
Before including We can now simplify it by removing the special parens pattern. |
Simplifications in #define line rules according to the absence of meta.parens.c scope.
Ok. I've done the very final simplification. I believe we're ok for the merge for this PR. Would you please create an issue for verbose meta.block scopes like in language-java. |
grammars/c.cson
Outdated
'endCaptures': | ||
'0': | ||
'name': 'punctuation.section.block.end.bracket.curly.c' | ||
#'name': 'meta.block.c' |
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.
🔥
grammars/c.cson
Outdated
] | ||
} | ||
{ | ||
# Capture paranthesis' |
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.
This comment isn't needed
grammars/c.cson
Outdated
'endCaptures': | ||
'0': | ||
'name': 'punctuation.section.block.end.bracket.curly.c' | ||
#'name': 'meta.block.c' <-- DO NOT NAME THE SECTION THIS TIME! |
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.
You can safely get rid of this comment.
grammars/c.cson
Outdated
'include': '#parens' | ||
} | ||
{ | ||
# NEW FUNCTION/MACRO IMPLEMENTATION |
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.
You can get rid of the NEW FUNCTION comments.
grammars/c.cson
Outdated
} | ||
{ | ||
'include': '#block' | ||
# NOW CONSUME TOKENS |
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.
🔥
grammars/c.cson
Outdated
{ | ||
'include': '#block' | ||
# NOW CONSUME TOKENS | ||
'include': '#meta-function-scope-innards' |
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.
This is named function_innards
in language-javascript. Since it seems like we're following a dashed convention for this language, could you rename this to function-innards
? I think that still gets the point across.
grammars/c.cson
Outdated
'patterns': [ | ||
{ | ||
# NOW CONSUME TOKENS | ||
'include': '#meta-function-call-scope-innards' |
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.
Rename to function-calls
grammars/c.cson
Outdated
'1': | ||
'name': 'entity.name.function.c' | ||
'2': | ||
'name': 'punctuation.section.parameters.begin.c' |
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.
arguments
for function-calls
grammars/c.cson
Outdated
'name': 'meta.function-call.c' | ||
'patterns': [ | ||
{ | ||
# NOW CONSUME TOKENS |
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.
🔥
Additional comments:
After that, I think it'll be ready for merge. |
|
- Typo fixes. - Removal of unnecessary comments - Addition of .bracket.round to scope names of all parentheses.
Yes. Edit: Oh, I see you already have :) |
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.
Just waiting on CI.
Thanks @alpyre! |
This change appears to have regressed this scenario #218 (#define with no definition). Could someone fix it? #ifndef _UCRT |
@sean-mcmanus: I cannot reproduce this both in C and C++. Are you sure you are on the latest version of language-c grammar (we're at 0.57.0)? As far as I know the way I've implemented I see the |
VS Code is reporting 0.51.3, but I think they just forgot to update the version, because 1.10.2 of VS Code has the same number and doesn't repro the bug and the code is different. I'll ask the VS Code people to take a look at fixing this: microsoft/vscode#23630 . |
Description of the Change
This PR has major re-implementations to provide fixes for many issues (along with some minor tweaks here’n there). Since the issues are related and the fixing implementations are intermingled, it was unable to cover them in separate PRs.
Function patterns are re-implemented according to the “SOLUTION” in issue Scope floods because of macros being matched as functions. #189 :
meta.function scopes are now captured in two steps:
meta.function
scope that even supports the injection of support-function names,#define
pattern is re-implemented according:see: Misnesting
Unnecessary nesting of section scopes (like meta.parens, meta.block, meta.function). fixes Fix unnecessary nesting of
meta.block.c
#113All parenthesis patterns are re-implemented to provide complete balanced parenthesis tokenization everywhere in code. fixes Punctuation improvments #103
And some minor changes like:
#include_next
.#pragma
and#pragma-mark
lines are now named asmeta.preprocessor.pragma.c
so an injecting grammar may choose to inject only into them or exclude them (as they exclude “strings” and “comments” when necessary).#pragma
identifier.New specs added for new features. Old specs are corrected to reflect changes.
Alternate Designs
Since we now have very smart parenthesis tokenization we can catch wayward close parentheses and highlight them as “invalid” (if we wish to).
(See Possible Drawbacks) By adding a specific pattern for function implementation blocks (right before the current function pattern) we can get back the previous behavior (without any drawbacks from the current one) if found necessary.
Implementation to prevent unnecessary nesting of section scopes does not cover ‘blocks in parentheses’ (which is a rare usage). Although occurrence of such a pattern does not break any highlighting features, only an inner
meta.parens
scope will repeat in scopes array. Covering that would confuscate the code a lot (would require many new rules) so it is not done in this PR.NOTE: As an alternative idea, preventing unnecessary nesting of section scopes could be implemented in Atom engine (an issue may be opened there). When such a feature is available we may consider simplifying this grammar.
Benefits
(Also see Description of the Change)
Possible Drawbacks
With this new function implementation we drew back from the function implementation blocks being scoped in meta.function.c scope (which was discussed in Scope floods because of macros being matched as functions. #189). Since this older behaviour had no benefits, yet it is still applicable (See Alternate Designs).
The scope
whitespace.function.leading
(and similars) are not tokenized anymore. This seems to have no side effects.Applicable Issues
Fixes #211, fixes #209, fixes #203, fixes #199, fixes #192, fixes #189, fixes #186, fixes #185, fixes #180, fixes #173, fixes #163, fixes #160, fixes #155, fixes #152, fixes #124, fixes #119, fixes #113, fixes #111, fixes #103, fixes #100, fixes #90, fixes #78, fixes #75, fixes #31
These issues are related (but not fixed):
#101, #23
Visual Demonstrations
Effects of the changes in function patterns:
Effects of the changes in
#define
patterns: