better-cpp-syntax
better-cpp-syntax copied to clipboard
#else and #endif have incorrect colorization when in the middle of a function declaration parameter list
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:
Dark+ Theme
It should look like:
Not red, like #if.
This could be a duplicate, but it was hard for me to tell.
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.
-
#ifdef
and#endif
are just patterns inserted into every context -
#else
starts a new pattern range that ends with lookahead for#endif
or#else
-
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.
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.
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.