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

#else and #endif have incorrect colorization when in the middle of a function declaration parameter list #485

Open
sean-mcmanus opened this issue Jul 2, 2020 · 3 comments
Labels
Syntax: C For bugs that only occur in C

Comments

@sean-mcmanus
Copy link

sean-mcmanus commented Jul 2, 2020

Checklist

  • [ yes ] This problem exists even with the setting "C_Cpp.enhancedColorization": "Disabled"
  • [ yes ] This bug exists for C
  • [ no ] This bug exists for C++
  • [ ?] This bug exists for Objective-C
  • [ ? ] This bug exists for Objective-C++

The code with a problem is:

#if FOO
int func(int,
#else
double func(int, 
#endif
int);

It looks like:

image

Dark+ Theme

It should look like:

Not red, like #if.

This could be a duplicate, but it was hard for me to tell.

@matter123
Copy link
Collaborator

matter123 commented Jul 3, 2020

Duplicate of #31, but this one is a bit clearer about the problem.

@jeff-hykin I don't believe the following potential solution has been discussed before.

  1. #ifdef and #endif are just patterns inserted into every context

  2. #else starts a new pattern range that ends with lookahead for #endif or #else

  3. is needed because if all conditional preprocessor directives were just match-rules then the context for the code that follows will be wrong.

Image if the match-rules for those directives had an effect on the rest of the grammar as to make them disappear. The new source would be

int func(int,
double func(int,
int);

any code that follows that would be parsed as if it is in a function definition. The ability for preprocessor ranges to jump contexts means at least one of the paths has to be discarded.

Though there will still be issues similar to #299 with this solution

enum items {
item1,
item2,
#if foo
item3,
#else
item3_v2, // this is not colored like an enum member
#endif
item4
};

I should be able to resume contributing sometime next week.

@jeff-hykin jeff-hykin added the Syntax: C For bugs that only occur in C label Jul 10, 2020
@jeff-hykin
Copy link
Owner

I think its not a duplicate cause this case isn't broken on C++ only C.

@matter123 Yeah I think that is a more clear version of strategy 2 from #31
There are some edge cases though like #if #elseif #end to make sure to cover. Once that general method is implemented I think that will be the best that can ever be done with the textmate parser.

@matter123
Copy link
Collaborator

To clarify:

  • #if, #ifdef and #ifndef do not start a range
  • #else and #elif do start a range, which end on a look ahead for #else, #elif or #endif
  • #endif does not end a range

Even if the previous point is fixed, (by duplicating the range for each context), The context of the ranges will actually be influenced by the contents of the #if block. So it is likely, by itself, not a solution to this issue. The correct solution is incredibly expensive, and that is to create a unique pattern for every possible combination of contexts so that the #else to #endif can use the parent context. A good enough effort is to introduce the root scope back into the possibilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Syntax: C For bugs that only occur in C
Projects
None yet
Development

No branches or pull requests

3 participants