Template definition needs multiple fixes
Not entirely sure if this is a duplicate of #106, but in the following example. Typename (note the capitalization) has the scope storage.type.template.argument.Typename.cpp The use of storage.type causes many themes to color Typename the same as a keyword. This can cause people to incorrectly believe that they are creating a standard type template, when in fact they are creating a non-type template.
template <Typename foo>
class foo;
Next thing on my list is to rewrite the template definition syntax from scratch. I agree it should be change, to be honest though, I don't know the meanings/use-case of the more complicated options. I can't even really tell the difference between <typename T> and <class T>. If you have a good grasp on it I'd be happy to learn, otherwise I'll probably take the time another day to read https://en.cppreference.com/w/cpp/language/templates and mess around with it until I figure it out. Once I know the behavior we can find a better tag name.
After this next change, I think all the template definition issues will be permanently solved.
typename and class are identical when used inside a template definition
Ignoring C++20 (concepts) for simplicity. So generally. A template definition contains 0 or more template parameters. Template parameters come in four forms:
type parameter:
Probably the most common, has the form of typename|class Name = type-expression. Both the name and default type are optional. i.e. all of the below are valid
template<typename>template<class Foo>template<typename = A>template<typename Alloc = std::allocator<T>>The type expression is any expression that evaluates into a type.
non type parameter:
This is used when you want to template on some compile time value. See std::array. These have the form of Type Name = expression and should follow the same rules for parameters.
template paramaters
Used when you want your type paramter to itself be a template. Basically a nested template definition followed by a type paramater. Example:
template<class A, template<class B> class C = std::deque<A>>
paramteer packs
Adds ... after typename or class or the Type.
I'm going to turn this into a major issue and close the other ones since they're related and are going to be fixed all at once
Official Syntax: https://en.cppreference.com/w/cpp/language/function_template
- Redo the scope names
- Fix the defaulted matching #106 #208 #245
- Add templated return types #79
This is the next major task on the todo list
Just as an FYI, I added :template_call_range to the :template_call_context so that now it can match nested template calls. I did this mostly because there was an example where it failed inside of the parameters and caused the whole rest of the file to be screwed up, and it seems more common to have a nested template call than a template call with a <
Posting as this example shows many of the previously mentioned issues with templates.
Example:
template <class U,
class = std::enable_if_t<std::is_constructible_v<T, U &&> &&
std::is_convertible_v<U &&, T>>>
constexpr propagate_const(propagate_const<U> &&pu) {}

On line 2 you can see keywords with no highlighting. On line 2, U is yellow and T is purple, however on line 3 they are swapped. It's not clear why enable_if is yellow but is_constructible_v is purple.
Test cases:
template<> // empty template
template<class> // unnamed parameter
template<typename>
template<class T> // named parameter
template<size_t I> // non-type parameter
template<class =void> // defaulted type parameter
template<size_t = 0> // defaulted non type parameter
template<class T, size_t I, class A = my::allocator<T, I>> // complex template
template<class...> // unnamed param-pack
template<size_t...> // unnamed non-type param-pack
template<class A, class...B> // named param pack
template<class A, template<class B> class C = std::deque<A>> // template template
2 more test cases for my issue:
template<class A, typename B> // mixed type-parameter-key
template<typename A, class B> // mixed type-parameter-key