(cpp) Template parameters trigger class header rule
See original GitHub issueDescribe the issue
When using the template <class T>
syntax in C++, the class
keyword misleads the parser into thinking it’s found a class header, and goes into class title mode, if there’s some {
shortly afterwards. The relevant rule is
Which language seems to have the issue?
cpp
Are you using highlight
or highlightAuto
?
highlight
. When using highlightAuto
, the code snippet is mis-categorised as angelscript
and parsed differently still.
Sample Code to Reproduce
template <class T> // comment
auto foo(T x) { … }
highlight.js marks this up as
<keyword>template</keyword> <<class><keyword>class</keyword> <title>T</title>> // <title>comment</title>
<title>auto</title> <title>foo</title>(<title>T</title> <title>x</title>) {</class> … }
Expected behavior
When replacing class
with typename
(which is 100% equivalent in this context), it’s marked up (more) correctly:
<keyword>template</keyword> <<keyword>typename</keyword> T> <comment>// comment</comment>
<function><keyword>auto</keyword> <title>foo</title><params>(T x)</params> </function>{ … }
Additional context
Present in master. Some earlier version used highlighted this correctly (presumably before support for class headers was added). Fundamentally the issue is that template parameter declarations aren’t handled at all by the lexer (by contrast, template argument lists do have rudimentary handling; i.e. usage rather than declaration).
A fix would probably require a separate mode for template parameter declarations, which is a hairy topic. In fact, correctly disambiguating the meaning of >>
(can be right-shift operator or a terminating nested template argument list) is context-sensitive, and undecidable for the lexer (!) because its meaning can depend on the type of names it is applied to: a<b<c>>d
can either be parsed as a variable declaration of d
where the type has a nested template argument (list if a
is a type), or as an expression involving less-than comparison and bit shifts, if a
is a variable: https://godbolt.org/z/rM18oc
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (5 by maintainers)
I don’t think so - and definitely not before ruling out ALL other choices. That does not sound like a great path forward to me. If someone just wants colored keywords there are other highlighting options available that are much simpler. We try to go further than that - and we successfully highlight TONS of valid C++ code, just you’ve found one case where we don’t work so well.
Right now it seems your original issue would be fixed by simply adding a special rule for:
If that would not resolve the issue, please expand your issue to provide additional examples.
I’m happy to take a stab at this once I find some time but I agree with you that this probably can’t be solved entirely. In fact, I suspect that we may have to give up something else: would you be open to a PR that increases overall reliability of C++ rendering at the cost of no longer recognising class/function declarations, and thus won’t highlight them as titles (nor the parameter lists)? That would make things drastically easier, since the language definition no longer needs to try to infer this context, and reverts to being a glorified tokeniser.
Personally I’d classify title/params highlighting as “nice to have”, and stuff like correctly recognising comments and keywords as essential. The current version of the C++ highlighter (almost certainly unintentionally!) seems to prioritise them the other way round.