Skip to content

Commit

Permalink
fix(cpp) fix class/template parsing issues (#2752)
Browse files Browse the repository at this point in the history
* fix(cpp) fix class/template parsing issues. Fixes #2716. Fixes #2102.
* enh(cpp) add support for `enum struct` and `enum class`
* add support for `union`
* minor file ending with CR changes for some `markup` tests
  • Loading branch information
joshgoebel committed Oct 15, 2020
1 parent 1475886 commit 6d6b8a6
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Language Improvements:

- fix(cpp) improve parsing issues with templates (#2752) [Josh Goebel][]
- enh(cpp) add support for `enum (struct|class)` and `union` (#2752) [Josh Goebel][]
- fix(js/ts) Fix nesting of `{}` inside template literals SUBST expression (#2748) [Josh Goebel][]
- enh(js/ts) Highlight class methods as functions (#2727) [Josh Goebel][]
- fix(js/ts) `constructor` is now highlighted as a function title (not keyword) (#2727) [Josh Goebel][]
Expand Down
5 changes: 2 additions & 3 deletions src/languages/c-like.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,9 @@ export default function(hljs) {
},
{
className: 'class',
beginKeywords: 'class struct', end: /[{;:]/,
beginKeywords: 'enum class struct union', end: /[{;:<>=]/,
contains: [
{ beginKeywords: "final" },
{begin: /</, end: />/, contains: ['self']}, // skip generic stuff
{ beginKeywords: "final class struct" },
hljs.TITLE_MODE
]
}
Expand Down
24 changes: 24 additions & 0 deletions test/markup/cpp/template_complexity.expect.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<span class="hljs-keyword">template</span> &lt;<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">T</span>&gt;</span> <span class="hljs-comment">// comment</span>
<span class="hljs-function"><span class="hljs-keyword">auto</span> <span class="hljs-title">foo</span><span class="hljs-params">(T x)</span> </span>{ ... };

<span class="hljs-keyword">namespace</span> impl {
<span class="hljs-keyword">template</span>&lt;<span class="hljs-keyword">typename</span> T&gt;
<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">is_streamable</span>&lt;</span>T, <span class="hljs-built_in">std</span>::<span class="hljs-keyword">void_t</span>&lt;<span class="hljs-keyword">decltype</span>(<span class="hljs-built_in">std</span>::declval&lt;<span class="hljs-built_in">std</span>::wostream &amp;&gt;() &lt;&lt; <span class="hljs-built_in">std</span>::declval&lt;T&gt;())&gt;&gt; : <span class="hljs-built_in">std</span>::true_type { };
}

<span class="hljs-comment">// Disable overload for already valid operands.</span>
<span class="hljs-keyword">template</span>&lt;<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">T</span>, <span class="hljs-keyword">class</span> =</span> <span class="hljs-built_in">std</span>::<span class="hljs-keyword">enable_if_t</span>&lt;!impl::is_streamable_v&lt;<span class="hljs-keyword">const</span> T &amp;&gt; &amp;&amp; <span class="hljs-built_in">std</span>::is_convertible_v&lt;<span class="hljs-keyword">const</span> T &amp;, <span class="hljs-built_in">std</span>::wstring_view&gt;&gt;&gt;
<span class="hljs-built_in">std</span>::wostream &amp;<span class="hljs-keyword">operator</span> &lt;&lt;(<span class="hljs-built_in">std</span>::wostream &amp;stream, <span class="hljs-keyword">const</span> T &amp;thing)
{
<span class="hljs-keyword">return</span> stream &lt;&lt; <span class="hljs-keyword">static_cast</span>&lt;<span class="hljs-built_in">std</span>::wstring_view&gt;(thing);
}

<span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-keyword">struct</span> <span class="hljs-title">DataHolder</span> {</span> };
<span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DataThingy</span> {</span> };
<span class="hljs-class"><span class="hljs-keyword">enum</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Boolean</span> :</span> <span class="hljs-keyword">char</span> {
True, False, FileNotFound
};

<span class="hljs-class"><span class="hljs-keyword">union</span> <span class="hljs-title">Soy</span>
{</span>
};
24 changes: 24 additions & 0 deletions test/markup/cpp/template_complexity.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
template <class T> // comment
auto foo(T x) { ... };

namespace impl {
template<typename T>
struct is_streamable<T, std::void_t<decltype(std::declval<std::wostream &>() << std::declval<T>())>> : std::true_type { };
}

// Disable overload for already valid operands.
template<class T, class = std::enable_if_t<!impl::is_streamable_v<const T &> && std::is_convertible_v<const T &, std::wstring_view>>>
std::wostream &operator <<(std::wostream &stream, const T &thing)
{
return stream << static_cast<std::wstring_view>(thing);
}

enum struct DataHolder { };
enum class DataThingy { };
enum class Boolean : char {
True, False, FileNotFound
};

union Soy
{
};
2 changes: 1 addition & 1 deletion test/markup/php/strings.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ SQL</span>);
var_dump(<span class="hljs-string">&lt;&lt;&lt;SQL
SELECT *
FROM table
SQL</span>);
SQL</span>);
2 changes: 1 addition & 1 deletion test/markup/protobuf/message-message.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
<span class="hljs-comment">/*
test multiline
comment
*/</span>
*/</span>
2 changes: 1 addition & 1 deletion test/markup/python-repl/sample.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ foo = 42&quot;
<span class="hljs-meta">&gt;&gt;&gt;</span> <span class="python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">test</span>():</span></span>
<span class="hljs-meta">...</span> <span class="python"> <span class="hljs-keyword">pass</span></span>
<span class="hljs-meta">&gt;&gt;&gt;</span>
<span class="hljs-meta">&gt;&gt;&gt;</span>
<span class="hljs-meta">&gt;&gt;&gt;</span>
2 changes: 1 addition & 1 deletion test/markup/python/escaped-quotes.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@

<span class="hljs-string">F&quot;text \&quot; text&quot;</span>
<span class="hljs-string">fR&quot;text \&quot; text&quot;</span>
<span class="hljs-string">RF&quot;text \&quot; text&quot;</span>
<span class="hljs-string">RF&quot;text \&quot; text&quot;</span>
2 changes: 1 addition & 1 deletion test/markup/python/f-strings.expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
<span class="hljs-string">f&quot;<span class="hljs-subst">{name + <span class="hljs-string">f&#x27;<span class="hljs-subst">{name}</span>&#x27;</span>}</span>&quot;</span>
<span class="hljs-string">f&quot;{{ }}&quot;</span>
<span class="hljs-keyword">if</span><span class="hljs-string">&quot;text&quot;</span>==<span class="hljs-string">&quot;text&quot;</span>:
<span class="hljs-string">&quot;good&quot;</span>
<span class="hljs-string">&quot;good&quot;</span>
2 changes: 1 addition & 1 deletion test/markup/python/function-header.expect.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">f</span>(<span class="hljs-params">x: <span class="hljs-built_in">int</span>, *, y: <span class="hljs-built_in">bool</span> = <span class="hljs-literal">True</span></span>) -&gt; <span class="hljs-keyword">None</span>:</span>
<span class="hljs-keyword">pass</span>
<span class="hljs-keyword">pass</span>

0 comments on commit 6d6b8a6

Please sign in to comment.