2021-04-29 13:18:31 +01:00

630 lines
22 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of GtkSourceView
Author: Scott Martin <scott@coffeeblack.org>
Copyright (C) 2004 Scott Martin <scott@coffeeblack.org>
Copyright (C) 2005 Stef Walter (formerly Nate Nielsen) <stef@memberwebs.com>
Copyright (C) 2005-2007 Marco Barisione <barisione@gmail.com>
Copyright (C) 2005-2007 Emanuele Aina
Copyright (C) 2019-2020 Jeffery To <jeffery.to@gmail.com>
GtkSourceView is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
GtkSourceView is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, see <http://www.gnu.org/licenses/>.
-->
<language id="js-lit" name="JavaScript Literals" version="2.0" _section="Script" hidden="true">
<!-- from js:identifier-char -->
<keyword-char-class>(?!\x{2E2F})[\p{L}\p{Nl}\x{1885}-\x{1886}\x{2118}\x{212E}\x{309B}-\x{309C}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{00B7}\x{0387}\x{1369}-\x{1371}\x{19DA}$\x{200C}\x{200D}]</keyword-char-class>
<definitions>
<!--
See javascript.lang for general notes, naming conventions, etc.
-->
<!-- # Keyword values -->
<!-- <NullLiteral> -->
<context id="null-value" style-ref="js:null-value">
<match>\%{js:null-keyword}</match>
</context> <!-- /null-value -->
<!-- <BooleanLiteral> -->
<context id="boolean" style-ref="js:boolean">
<match extended="true">
\%{js:false-keyword} | \%{js:true-keyword}
</match>
</context> <!-- /boolean -->
<!-- # Number -->
<!-- <NumericLiteral> -->
<context id="choice-number">
<include>
<define-regex id="_decimal" extended="true">
(?&gt;
(?: [1-9][0-9]* | 0 ) (?: \. [0-9]* )? |
\. [0-9]+
)
(?&gt; [eE] [+-]? [0-9]+ )?
</define-regex> <!-- /_decimal -->
<!-- <DecimalLiteral> -->
<context id="_choice-decimal" style-ref="js:decimal" end-parent="true">
<start extended="true">
\%{js:number-start} (?= \%{_decimal} \%{js:number-end} )
</start>
<end>\%{_decimal}</end>
</context> <!-- /_choice-decimal -->
<define-regex id="_decimal-integer" extended="true">
(?&gt; [1-9][0-9]* | 0 )
</define-regex> <!-- /_decimal-integer -->
<!-- ES2020 -->
<!-- <DecimalBigIntegerLiteral> -->
<context id="_choice-decimal-big-integer" style-ref="js:decimal" end-parent="true">
<start extended="true">
\%{js:number-start} (?= \%{_decimal-integer} n \%{js:number-end} )
</start>
<end>\%{_decimal-integer}n</end>
</context> <!-- /_choice-decimal-big-integer -->
<define-regex id="_binary-integer" extended="true">
(?&gt; 0 [bB] [01]+ )
</define-regex> <!-- /_binary-integer -->
<!-- <BinaryIntegerLiteral> -->
<context id="_choice-binary-integer" style-ref="js:binary-integer" end-parent="true">
<start extended="true">
\%{js:number-start} (?= \%{_binary-integer} n? \%{js:number-end} )
</start>
<end>\%{_binary-integer}n?</end>
</context> <!-- /_choice-binary-integer -->
<define-regex id="_octal-integer" extended="true">
(?&gt; 0 [oO] [0-7]+ )
</define-regex> <!-- /_octal-integer -->
<!-- <OctalIntegerLiteral> -->
<context id="_choice-octal-integer" style-ref="js:octal-integer" end-parent="true">
<start extended="true">
\%{js:number-start} (?= \%{_octal-integer} n? \%{js:number-end} )
</start>
<end>\%{_octal-integer}n?</end>
</context> <!-- /_choice-octal-integer -->
<!-- <HexIntegerLiteral> -->
<define-regex id="_hex-integer" extended="true">
(?&gt; 0 [xX] [0-9a-fA-F]+ )
</define-regex> <!-- /_hex-integer -->
<context id="_choice-hex-integer" style-ref="js:hex-integer" end-parent="true">
<start extended="true">
\%{js:number-start} (?= \%{_hex-integer} n? \%{js:number-end} )
</start>
<end>\%{_hex-integer}n?</end>
</context> <!-- /_choice-hex-integer -->
<define-regex id="_legacy-octal-integer" extended="true">
(?&gt; 0 [0-7]+ )
</define-regex> <!-- /_legacy-octal-integer -->
<!-- Annex B: <LegacyOctalIntegerLiteral> -->
<context id="_choice-legacy-octal-integer" style-ref="js:error" end-parent="true">
<start extended="true">
\%{js:number-start} (?= \%{_legacy-octal-integer} \%{js:number-end} )
</start>
<end>\%{_legacy-octal-integer}</end>
</context> <!-- /_choice-legacy-octal-integer -->
</include>
</context> <!-- /choice-number -->
<!-- # Escape sequences -->
<context id="_escapes">
<include>
<!-- Annex B: <LegacyOctalEscapeSequence> (preceeded by
backslash) -->
<context id="_legacy-octal-escape-sequences" style-ref="js:escape">
<match extended="true">
\\
(?:
0 [0-7]{1,2} | # 0-padded number, not \0 (null character)
[1-3] [0-7]{0,2} | # max \377
[4-7] [0-7]{0,1}
)
</match>
</context> <!-- /_legacy-octal-escape-sequences -->
<!-- <EscapeSequence> (preceeded by backslash) -->
<context id="_escape-sequences" style-ref="js:escape">
<match extended="true">
\%{js:unicode-escape} |
\\
(?:
x[0-9a-fA-F]{2} | # hexadecimal escape
[^1-9xu] # single character escape
)
</match>
</context> <!-- /_escape-sequences -->
</include>
</context> <!-- /_escapes -->
<!-- # String -->
<context id="_string-content">
<include>
<context ref="_escapes"/>
<context ref="def:line-continue"/>
</include>
</context> <!-- /_string-content -->
<!-- <StringLiteral> -->
<context id="choice-string" style-ref="js:string" end-at-line-end="true" end-parent="true" class="string" class-disabled="no-spell-check">
<start>["']</start>
<end>\%{0@start}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<!-- no comments here -->
<context ref="_string-content"/>
</include>
</context> <!-- /choice-string -->
<!-- <StringLiteral> -->
<context id="choice-string-path" style-ref="js:included-file" end-at-line-end="true" end-parent="true" class="path">
<start>["']</start>
<end>\%{0@start}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<!-- no comments here -->
<context ref="_string-content"/>
</include>
</context> <!-- /choice-string-path -->
<!-- # Array literal
[ 1, 2, 3, ...anotherArray ]
-->
<context id="_array-literal-element-content">
<include>
<context ref="js:ordered-spread-syntax"/>
<context ref="js-expr:expression-without-comma"/>
</include>
</context> <!-- /_array-literal-element-content -->
<!-- <ArrayLiteral> -->
<context id="choice-array-literal" style-ref="js:array-literal" end-parent="true">
<start>\[</start>
<end>]</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_array-literal-content">
<include>
<context id="_array-literal-first-element" once-only="true">
<start>\%{js:before-next-token}</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context ref="_array-literal-element-content"/>
</include>
</context> <!-- /_array-literal-first-element -->
<context id="_array-literal-elements">
<start>,</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context ref="_array-literal-element-content"/>
</include>
</context> <!-- /_array-literal-elements -->
</include>
</context> <!-- /_array-literal-content -->
</include>
</context> <!-- /choice-array-literal -->
<!-- # Property name -->
<!-- <PropertyName> -->
<context id="_property-name" once-only="true">
<start>\%{js:before-next-token}</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_property-name-content">
<include>
<!-- <ComputedPropertyName> -->
<context id="_choice-computed-property-name" end-parent="true">
<start>\[</start>
<end>]</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_computed-property-name-content">
<include>
<context ref="js-expr:expression-without-comma"/>
</include>
</context> <!-- /_computed-property-name-content -->
</include>
</context> <!-- /_choice-computed-property-name -->
<context ref="choice-number"/>
<context ref="choice-string"/>
<context ref="js:choice-identifier-name"/>
</include>
</context> <!-- /_property-name-content -->
</include>
</context> <!-- /_property-name -->
<context id="ordered-property-name" once-only="true">
<start>\%{js:before-next-token}</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="_property-name"/>
</include>
</context> <!-- /ordered-property-name -->
<!-- # Object literal
{
propertyA: 'a',
"propertyB": getB(),
1: 'one',
[ computedName() ]: 2 + 3,
method() { ... },
get prop() { return this._prop; },
set prop(v) { this._prop = v; },
...objectToCopy
}
-->
<!-- ES2018 -->
<context id="_choice-object-literal-spread-syntax" end-parent="true">
<start>\%{js:spread-syntax}</start>
<end>\%{js:before-next-token}</end>
<include>
<context sub-pattern="0" where="start" style-ref="js:spread-syntax"/>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_object-literal-spread-syntax-content">
<include>
<context ref="js-expr:expression-without-comma"/>
</include>
</context> <!-- /_object-literal-spread-syntax-content -->
</include>
</context> <!-- /_choice-object-literal-spread-syntax -->
<context id="_object-literal-property-value" once-only="true">
<start>:</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_object-literal-property-value-content">
<include>
<context ref="js-expr:expression-without-comma"/>
</include>
</context> <!-- /_object-literal-property-value-content -->
</include>
</context> <!-- /_object-literal-property-value -->
<context id="_ordered-object-literal-property-value" once-only="true">
<start>\%{js:before-next-token}</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="_object-literal-property-value"/>
</include>
</context> <!-- /_ordered-object-literal-property-value -->
<context id="_choice-object-literal-keyword-named-property-or-method" end-parent="true">
<start extended="true">
(?: \%{js:get-keyword} | \%{js:set-keyword} )
(?= \%{js:optional-whitespace-or-comments} [:=(] )
</start>
<end>\%{js:before-next-token}</end>
<include>
<context sub-pattern="0" where="start" style-ref="js:identifier"/>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_object-literal-keyword-named-property-or-method-content">
<include>
<context ref="js-fn:choice-method-definition"/>
<context ref="_ordered-object-literal-property-value"/>
<context ref="js:ordered-default-value-assignment"/> <!-- for destructuring assignment -->
</include>
</context> <!-- /_object-literal-keyword-named-property-or-method-content -->
</include>
</context> <!-- /_choice-object-literal-keyword-named-property-or-method -->
<context id="_choice-object-literal-property-or-method" end-parent="true">
<start extended="true">
(?= [\['"] ) | # computed property name, string
\%{js:number-start} (?= \.? [0-9] ) | # number
\%{js:identifier-container-start} # identifier
</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_object-literal-property-or-method-content">
<include>
<context ref="js-fn:ordered-property-accessor-keyword"/>
<context ref="ordered-property-name"/>
<context ref="js-fn:choice-method-definition"/>
<context ref="_ordered-object-literal-property-value"/>
<context ref="js:ordered-default-value-assignment"/> <!-- for destructuring assignment -->
</include>
</context> <!-- /_object-literal-property-or-method-content -->
</include>
</context> <!-- /_choice-object-literal-property-or-method -->
<context id="_object-literal-property-content">
<include>
<context ref="_choice-object-literal-spread-syntax"/>
<context ref="_choice-object-literal-keyword-named-property-or-method"/>
<context ref="js-fn:choice-method-keyword-method-definition"/>
<context ref="_choice-object-literal-property-or-method"/>
</include>
</context> <!-- /_object-literal-property-content -->
<!-- <ObjectLiteral> -->
<context id="choice-object-literal" style-ref="js:object-literal" end-parent="true">
<start>{</start>
<end>}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_object-literal-content">
<include>
<context id="_object-literal-first-property" once-only="true">
<start>\%{js:before-next-token}</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context ref="_object-literal-property-content"/>
</include>
</context> <!-- /_object-literal-first-property -->
<context id="_object-literal-properties">
<start>,</start>
<end>\%{js:before-next-token}</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context ref="_object-literal-property-content"/>
</include>
</context> <!-- /_object-literal-properties -->
</include>
</context> <!-- /_object-literal-content -->
</include>
</context> <!-- /choice-object-literal -->
<!-- # Regular expression literal
/(foo|bar)+/u
-->
<!-- only valid in regular expressions -->
<context id="_control-escapes" style-ref="js:escape">
<match>\\c[a-zA-Z]</match>
</context> <!-- /_control-escapes -->
<!-- ES2018 -->
<context id="_unicode-property-escapes" style-ref="js:escape">
<match extended="true">
\\ [pP] { (?: [a-zA-Z_]+ = )? [a-zA-Z0-9_]+ }
</match>
</context> <!-- /_unicode-property-escapes -->
<!-- ES2018 -->
<context id="_named-capture-groups">
<match extended="true">
\(\? &lt; ( \%{js:identifier} ) &gt;
</match>
<include>
<context sub-pattern="1" style-ref="js:regex-group"/>
</include>
</context> <!-- /_named-capture-groups -->
<!-- ES2018 -->
<context id="_named-capture-group-backreferences" style-ref="js:escape">
<match extended="true">
\\k &lt; ( \%{js:identifier} ) &gt;
</match>
<include>
<context sub-pattern="1" style-ref="js:regex-group"/>
</include>
</context> <!-- /_named-capture-group-backreferences -->
<context id="_regular-expression-character-classes" style-ref="js:regex-class" style-inside="true">
<start>\[</start>
<end>]</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<!-- no comments here -->
<context id="_regular-expression-character-class-content">
<include>
<context ref="_control-escapes"/>
<context ref="_unicode-property-escapes"/>
<context ref="_escapes"/>
</include>
</context> <!-- /_regular-expression-character-class-content -->
</include>
</context> <!-- /_regular-expression-character-classes -->
<!-- <RegularExpressionLiteral> -->
<!-- technically, line terminators are not allowed inside -->
<context id="choice-regular-expression-literal" style-ref="js:regex" end-parent="true">
<start>/</start>
<end>/([gimsuy]*)</end> <!-- s (dotAll): ES2018 -->
<include>
<context sub-pattern="1" where="end" style-ref="js:regex-flag"/>
<context ref="js:embedded-lang-hooks"/>
<!-- no comments here -->
<context id="_regular-expression-literal-content">
<include>
<context ref="_control-escapes"/>
<context ref="_unicode-property-escapes"/>
<context ref="_named-capture-group-backreferences"/>
<context ref="_escapes"/>
<context ref="_named-capture-groups"/>
<context ref="_regular-expression-character-classes"/>
</include>
</context> <!-- /_regular-expression-literal-content -->
</include>
</context> <!-- /choice-regular-expression-literal -->
<!-- # Template literal (template string)
`this is a ${adjective} template`
the contexts are structured this way so that the
template-literal and template-placeholder styles (and any
styles inside the placeholder) do not overlap
-->
<context id="_template-content">
<include>
<context ref="_escapes"/>
<context ref="def:line-continue"/>
</include>
</context> <!-- /_template-content -->
<context id="_template-literal-content">
<include>
<context id="_template-head" style-ref="js:template-literal" once-only="true">
<start>(?&lt;=`)</start>
<end>(?=`|\${)</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<!-- no comments here -->
<context ref="_template-content"/>
</include>
</context> <!-- /_template-head -->
<context ref="js:embedded-lang-hooks"/>
<context id="_template-substitution-tails" style-ref="js:template-literal">
<start>(?&lt;=})</start>
<end>(?=`|\${)</end>
<include>
<context ref="js:embedded-lang-hooks"/>
<!-- no comments here -->
<context ref="_template-content"/>
</include>
</context> <!-- /_template-substitution-tails -->
<context id="_template-placeholders">
<start>\${</start>
<end>}</end>
<include>
<context sub-pattern="0" where="start" style-ref="js:template-placeholder"/>
<context sub-pattern="0" where="end" style-ref="js:template-placeholder"/>
<context ref="js:embedded-lang-hooks"/>
<context ref="js:comments"/>
<context id="_template-placeholder-content">
<include>
<context ref="js-expr:expression-with-comma"/>
</include>
</context> <!-- /_template-placeholder-content -->
</include>
</context> <!-- /_template-placeholders -->
</include>
</context> <!-- /_template-literal-content -->
<!-- <Template> / <TemplateLiteral> -->
<context id="template-literals">
<start>`</start>
<end>`</end>
<include>
<context sub-pattern="0" where="start" style-ref="js:template-literal"/>
<context sub-pattern="0" where="end" style-ref="js:template-literal"/>
<!-- no embedded-lang-hooks here -->
<!-- no comments here -->
<!-- do not match comments or embedded-lang-hooks here, because
template-head must match immediately -->
<context ref="_template-literal-content"/>
</include>
</context> <!-- /template-literals -->
<!-- <Template> / <TemplateLiteral> -->
<context id="choice-template-literal" end-parent="true">
<start>`</start>
<end>`</end>
<include>
<context sub-pattern="0" where="start" style-ref="js:template-literal"/>
<context sub-pattern="0" where="end" style-ref="js:template-literal"/>
<!-- no embedded-lang-hooks here -->
<!-- no comments here -->
<!-- do not match comments or embedded-lang-hooks here, because
template-head must match immediately -->
<context ref="_template-literal-content"/>
</include>
</context> <!-- /choice-template-literal -->
</definitions>
</language>