Skip to content

Commit

Permalink
enh(autodetect) tcl: improve autodetection (#2865)
Browse files Browse the repository at this point in the history
* enh(autodetect) tcl: fewer false positives on variables

For languages with $ident and @Ident style variables this attempts
to prevent positives for $ident$ and @Ident@ type expressions, which
are likely something else entirely.

- Improves TCL variable detection to be more explicit
- Adds TCL variable detection tests

* fix(tcl) Make regex UTF-8 compatible
  • Loading branch information
joshgoebel committed Feb 14, 2021
1 parent bacf368 commit 374a7e5
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 21 deletions.
33 changes: 24 additions & 9 deletions src/languages/tcl.js
Expand Up @@ -5,7 +5,16 @@ Author: Radek Liska <radekliska@gmail.com>
Website: https://www.tcl.tk/about/language.html
*/

import * as regex from '../lib/regex.js';

export default function(hljs) {
const TCL_IDENT = /[a-zA-Z_][a-zA-Z0-9_]*/;

const NUMBER = {
className: 'number',
variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]
};

return {
name: 'Tcl',
aliases: ['tk'],
Expand Down Expand Up @@ -39,15 +48,24 @@ export default function(hljs) {
]
},
{
excludeEnd: true,
className: "variable",
variants: [
{
begin: '\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*\\(([a-zA-Z0-9_])*\\)',
end: '[^a-zA-Z0-9_\\}\\$]'
begin: regex.concat(
/\$/,
regex.optional(/::/),
TCL_IDENT,
'(::',
TCL_IDENT,
')*'
)
},
{
begin: '\\$(\\{)?(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*',
end: '(\\))?[^a-zA-Z0-9_\\}\\$]'
begin: '\\$\\{(::)?[a-zA-Z_]((::)?[a-zA-Z0-9_])*',
end: '\\}',
contains: [
NUMBER
]
}
]
},
Expand All @@ -58,10 +76,7 @@ export default function(hljs) {
hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null})
]
},
{
className: 'number',
variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]
}
NUMBER
]
}
}
4 changes: 2 additions & 2 deletions test/markup/pgsql/dollar_strings.expect.txt
Expand Up @@ -5,5 +5,5 @@ $$<span class="pgsql">
$$</span>
<span class="hljs-keyword">language</span> <span class="hljs-keyword">sql</span> <span class="hljs-keyword">STRICT</span>;

<span class="hljs-keyword">SELECT</span> sql_expression($sql$<span class="tcl">SELECT hello_world($phrase$Regina&#x27;s elephant&#x27;s dog$phrase$)
|| $phrase$ I made a cat&#x27;s meow today.$phrase$ $sql$</span>);
<span class="hljs-keyword">SELECT</span> sql_expression($sql$<span class="tcl">SELECT hello_world(<span class="hljs-variable">$phrase</span><span class="hljs-variable">$Regina</span>&#x27;s elephant&#x27;s dog<span class="hljs-variable">$phrase</span>$)
|| <span class="hljs-variable">$phrase</span>$ I made a cat&#x27;s meow today.<span class="hljs-variable">$phrase</span>$ <span class="hljs-variable">$sql</span>$</span>);
1 change: 0 additions & 1 deletion test/markup/php/comments.expect.txt
Expand Up @@ -17,4 +17,3 @@
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isOdd</span>(<span class="hljs-params"><span class="hljs-variable">$a</span></span>) </span>{
<span class="hljs-keyword">return</span> (<span class="hljs-variable">$a</span> % <span class="hljs-number">2</span>) === <span class="hljs-number">1</span>;
}

18 changes: 9 additions & 9 deletions test/markup/tcl/default.expect.txt
Expand Up @@ -5,22 +5,22 @@
<span class="hljs-keyword">set</span> ::rand <span class="hljs-number">4</span>

<span class="hljs-keyword">proc</span><span class="hljs-title"> give::recursive::count</span> {base p} { <span class="hljs-comment">; # 2 mandatory params</span>
<span class="hljs-keyword">while</span> {$p &gt; <span class="hljs-number">0</span>} {
<span class="hljs-keyword">set</span> result [<span class="hljs-keyword">expr</span> $result * $base]; <span class="hljs-keyword">incr</span> p <span class="hljs-number">-1</span>
<span class="hljs-keyword">while</span> {<span class="hljs-variable">$p</span> &gt; <span class="hljs-number">0</span>} {
<span class="hljs-keyword">set</span> result [<span class="hljs-keyword">expr</span> <span class="hljs-variable">$result</span> * <span class="hljs-variable">$base</span>]; <span class="hljs-keyword">incr</span> p <span class="hljs-number">-1</span>
}
<span class="hljs-keyword">return</span> $result
<span class="hljs-keyword">return</span> <span class="hljs-variable">$result</span>
}

<span class="hljs-keyword">set</span> a {a}; <span class="hljs-keyword">set</span> b <span class="hljs-string">&quot;bcdef&quot;</span>; <span class="hljs-keyword">set</span> lst [<span class="hljs-keyword">list</span> <span class="hljs-string">&quot;item&quot;</span>]
<span class="hljs-keyword">puts</span> [<span class="hljs-keyword">llength</span> $a$b]
<span class="hljs-keyword">puts</span> [<span class="hljs-keyword">llength</span> <span class="hljs-variable">$a</span><span class="hljs-variable">$b</span>]

<span class="hljs-keyword">set</span> ::my::tid($id) $::my::tid(def)
<span class="hljs-keyword">lappend</span> lst $arr($idx) $::my::arr($idx) $ar(key)
<span class="hljs-keyword">lreplace</span> ::my::tid($id) <span class="hljs-number">4</span> <span class="hljs-number">4</span>
<span class="hljs-keyword">puts</span> $::rand ${::rand} ${::AWESOME::component::variable}
<span class="hljs-keyword">set</span> ::my::tid(<span class="hljs-variable">$id</span>) <span class="hljs-variable">$::my::tid</span>(def)
<span class="hljs-keyword">lappend</span> lst <span class="hljs-variable">$arr</span>(<span class="hljs-variable">$idx</span>) <span class="hljs-variable">$::my::arr</span>(<span class="hljs-variable">$idx</span>) <span class="hljs-variable">$ar</span>(key)
<span class="hljs-keyword">lreplace</span> ::my::tid(<span class="hljs-variable">$id</span>) <span class="hljs-number">4</span> <span class="hljs-number">4</span>
<span class="hljs-keyword">puts</span> <span class="hljs-variable">$::rand</span> <span class="hljs-variable">${::rand}</span> <span class="hljs-variable">${::AWESOME::component::variable}</span>

<span class="hljs-keyword">puts</span> <span class="hljs-string">&quot;$x + $y is\t [expr $x + $y]&quot;</span>

<span class="hljs-keyword">proc</span><span class="hljs-title"> isprime</span> x {
<span class="hljs-keyword">expr</span> {$x&gt;<span class="hljs-number">1</span> &amp;&amp; ![<span class="hljs-keyword">regexp</span> {^(oo+?)\<span class="hljs-number">1</span>+$} [<span class="hljs-keyword">string</span> repeat o $x]]}
<span class="hljs-keyword">expr</span> {<span class="hljs-variable">$x</span>&gt;<span class="hljs-number">1</span> &amp;&amp; ![<span class="hljs-keyword">regexp</span> {^(oo+?)\<span class="hljs-number">1</span>+$} [<span class="hljs-keyword">string</span> repeat o <span class="hljs-variable">$x</span>]]}
}
24 changes: 24 additions & 0 deletions test/markup/tcl/variables.expect.txt
@@ -0,0 +1,24 @@
<span class="hljs-variable">$name</span>
<span class="hljs-variable">${name}</span>
<span class="hljs-variable">${::name}</span>
<span class="hljs-variable">${::namespace::name}</span>
<span class="hljs-variable">${::namespace::another::name}</span>

<span class="hljs-variable">$name</span>()
<span class="hljs-variable">$name</span>(<span class="hljs-number">32</span>)
<span class="hljs-variable">$name</span>(index)

<span class="hljs-variable">$with_underscore::oth_er::and_finally</span>(<span class="hljs-number">32</span>)

<span class="hljs-variable">${name()}</span>
<span class="hljs-variable">${name(<span class="hljs-number">32</span>)}</span>
<span class="hljs-variable">${name(index)}</span>

<span class="hljs-variable">${ns::other::name()}</span>
<span class="hljs-variable">${ns::other::name(<span class="hljs-number">32</span>)}</span>
<span class="hljs-variable">${ns::other::name(index)}</span>


<span class="hljs-variable">$ns::other::name</span>()
<span class="hljs-variable">$ns::other::name</span>(<span class="hljs-number">32</span>)
<span class="hljs-variable">$ns::other::name</span>(index)
24 changes: 24 additions & 0 deletions test/markup/tcl/variables.txt
@@ -0,0 +1,24 @@
$name
${name}
${::name}
${::namespace::name}
${::namespace::another::name}

$name()
$name(32)
$name(index)

$with_underscore::oth_er::and_finally(32)

${name()}
${name(32)}
${name(index)}

${ns::other::name()}
${ns::other::name(32)}
${ns::other::name(index)}


$ns::other::name()
$ns::other::name(32)
$ns::other::name(index)

0 comments on commit 374a7e5

Please sign in to comment.