@ -58,7 +58,13 @@ const PRECS = {
assignment : - 3 ,
comment : - 3 ,
lambda : - 3 ,
regex : - 4 ,
} ;
const DYNAMIC _PRECS = {
call : 1 ,
} ;
const DEC _DIGITS = token ( sep1 ( /[0-9]+/ , /_+/ ) ) ;
const HEX _DIGITS = token ( sep1 ( /[0-9a-fA-F]+/ , /_+/ ) ) ;
const OCT _DIGITS = token ( sep1 ( /[0-7]+/ , /_+/ ) ) ;
@ -74,27 +80,12 @@ if (tree_sitter_version_supports_emoji()) {
LEXICAL _IDENTIFIER = /[_\p{XID_Start}][_\p{XID_Continue}]*/ ;
}
const CUSTOM _OPERATORS = token (
choice (
// https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID418
// This supports a subset of the operators that Swift does but I'm really not concerned about the esoteric ones.
// Someone who wants unicode support can add it. What this does do is:
// * Avoid the reserved operators by saying that certain characters are only available if you don't start with them.
// * Entirely forbid `<` as the last char because it creates ambiguity with type arguments
/[\\<>&?=][\/=\-+!*%<>&|^?~\.]*[\/=\-+!*%>&|^?~]+/ ,
/[\-+!*%|^~]+[\/=\-+!*%<>&|^?~]*[\/=\-+!*%>&|^?~]+/ ,
/[\-+!*%|^~\.]+[\/=\-+!*%<>&|^?~\.]*[\/=\-+!*%>&|^?~\.]+/ ,
/[\/]+[=\-+!*%<>&|^?~]*[=\-+!*%>&|^?~]+/ ,
/[\/]+[=\-+!*%<>&|^?~\.]*[=\-+!*%>&|^?~\.]+/
)
) ;
// XXX need custom scanner for:
// * Custom operators and `<` for type arguments
module . exports = grammar ( {
name : "swift" ,
conflicts : ( $ ) => [
// @Type(... could either be an annotation constructor invocation or an annotated expression
[ $ . attribute ] ,
[ $ . _attribute _argument ] ,
// Is `foo { ... }` a constructor invocation or function invocation?
[ $ . _simple _user _type , $ . _expression ] ,
// To support nested types A.B not being interpreted as `(navigation_expression ... (type_identifier)) (navigation_suffix)`
@ -109,12 +100,10 @@ module.exports = grammar({
// After a `{` in a function or switch context, it's ambigous whether we're starting a set of local statements or
// applying some modifiers to a capture or pattern.
[ $ . modifiers ] ,
// Custom operators get weird special handling for `<` characters in silly stuff like `func =<<<<T>(...)`
[ $ . custom _operator ] ,
[ $ . _prefix _unary _operator , $ . _referenceable _operator ] ,
// `+(...)` is ambigously either "call the function produced by a reference to the operator `+`" or "use the unary
// operator `+` on the result of the parenthetical expression."
[ $ . _additive _operator , $ . _prefix _unary _operator ] ,
[ $ . _referenceable _operator , $ . _prefix _unary _operator ] ,
// `{ [self, b, c] ...` could be a capture list or an array literal depending on what else happens.
[ $ . capture _list _item , $ . self _expression ] ,
[ $ . capture _list _item , $ . _expression ] ,
@ -155,6 +144,35 @@ module.exports = grammar({
// The `class` modifier is legal in many of the same positions that a class declaration itself would be.
[ $ . _bodyless _function _declaration , $ . property _modifier ] ,
[ $ . _local _class _declaration , $ . modifiers ] ,
// Patterns, man
[ $ . _navigable _type _expression , $ . _case _pattern ] ,
[ $ . _no _expr _pattern _already _bound , $ . _binding _pattern _with _expr ] ,
[ $ . _no _expr _pattern _already _bound , $ . _expression ] ,
[ $ . _no _expr _pattern _already _bound , $ . _binding _pattern _no _expr ] ,
// On encountering a closure starting with `{ @Foo ...`, we don't yet know if that attribute applies to the closure
// type or to a declaration within the closure. What a mess! We just have to hope that if we keep going, only one of
// those will parse (because there will be an `in` or a `let`).
[
$ . _lambda _type _declaration ,
$ . _local _property _declaration ,
$ . _local _typealias _declaration ,
$ . _local _function _declaration ,
$ . _local _class _declaration ,
] ,
// We want `foo() { }` to be treated as one function call, but we _also_ want `if foo() { ... }` to be treated as a
// full if-statement. This means we have to treat it as a conflict rather than purely a left or right associative
// construct, and let the parser realize that the second expression won't parse properly with the `{ ... }` as a
// lambda.
[ $ . constructor _suffix ] ,
[ $ . call _suffix ] ,
// `actor` is allowed to be an identifier, even though it is also a locally permitted declaration. If we encounter
// it, the only way to know what it's meant to be is to keep going.
[ $ . _modifierless _class _declaration , $ . property _modifier ] ,
[ $ . _modifierless _class _declaration , $ . simple _identifier ] ,
[ $ . _fn _call _lambda _arguments ] ,
] ,
extras : ( $ ) => [
$ . comment ,
@ -189,12 +207,11 @@ module.exports = grammar({
// `_semi`, we advance a bit further to see if the next non-whitespace token would be one of these other operators.
// If so, we ignore the `_semi` and just produce the operator; if not, we produce the `_semi` and let the rest of
// the grammar sort it out. This isn't perfect, but it works well enough most of the time.
$ . _semi ,
$ . _implicit _semi ,
$ . _explicit _semi ,
// Every one of the below operators will suppress a `_semi` if we encounter it after a newline.
$ . _arrow _operator _custom ,
$ . _dot _custom ,
$ . _three _dot _operator _custom ,
$ . _open _ended _range _operator _custom ,
$ . _conjunction _operator _custom ,
$ . _disjunction _operator _custom ,
$ . _nil _coalescing _operator _custom ,
@ -213,6 +230,7 @@ module.exports = grammar({
$ . _as _quest _custom ,
$ . _as _bang _custom ,
$ . _async _keyword _custom ,
$ . _custom _operator ,
] ,
inline : ( $ ) => [ $ . _locally _permitted _modifiers ] ,
rules : {
@ -222,8 +240,15 @@ module.exports = grammar({
source _file : ( $ ) =>
seq (
optional ( $ . shebang _line ) ,
repeat ( seq ( $ . _top _level _statement , $ . _semi ) )
optional (
seq (
$ . _top _level _statement ,
repeat ( seq ( $ . _semi , $ . _top _level _statement ) ) ,
optional ( $ . _semi )
)
)
) ,
_semi : ( $ ) => choice ( $ . _implicit _semi , $ . _explicit _semi ) ,
shebang _line : ( $ ) => seq ( "#!" , /[^\r\n]*/ ) ,
////////////////////////////////
// Lexical Structure - https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html
@ -235,7 +260,8 @@ module.exports = grammar({
LEXICAL _IDENTIFIER ,
/`[^\r\n` ]*`/ ,
/\$[0-9]+/ ,
token ( seq ( "$" , LEXICAL _IDENTIFIER ) )
token ( seq ( "$" , LEXICAL _IDENTIFIER ) ) ,
"actor"
) ,
identifier : ( $ ) => sep1 ( $ . simple _identifier , $ . _dot ) ,
// Literals
@ -248,6 +274,7 @@ module.exports = grammar({
$ . real _literal ,
$ . boolean _literal ,
$ . _string _literal ,
$ . regex _literal ,
"nil"
) ,
// TODO: Hex exponents
@ -316,6 +343,30 @@ module.exports = grammar({
) ,
_escaped _identifier : ( $ ) => / \ \ [ 0 \ \ tnr " ' \ n ] / ,
multi _line _str _text : ( $ ) => / [ ^ \ \ " ] + / ,
// Based on https://gitlab.com/woolsweater/tree-sitter-swifter/-/blob/3d47c85bd47ce54cdf2023a9c0e01eb90adfcc1d/grammar.js#L1019
// But required modifications to hit all of the cases in SE-354
regex _literal : ( $ ) =>
choice (
$ . _extended _regex _literal ,
$ . _multiline _regex _literal ,
$ . _oneline _regex _literal
) ,
_extended _regex _literal : ( $ ) => / # \ / ( ( \ / [ ^ # ] ) | [ ^ \ n ] ) + \ / # / ,
_multiline _regex _literal : ( $ ) => seq ( /#\/\n/ , /(\/[^#]|[^/])*?\n\/#/ ) ,
_oneline _regex _literal : ( $ ) =>
token (
prec (
PRECS . regex ,
seq (
"/" ,
token . immediate ( /[^ \t\n]?[^/\n]*[^ \t\n/]/ ) ,
token . immediate ( "/" )
)
)
) ,
////////////////////////////////
// Types - https://docs.swift.org/swift-book/ReferenceManual/Types.html
////////////////////////////////
@ -340,6 +391,7 @@ module.exports = grammar({
$ . optional _type ,
$ . metatype ,
$ . opaque _type ,
$ . existential _type ,
$ . protocol _composition _type
)
) ,
@ -375,7 +427,7 @@ module.exports = grammar({
) ,
function _type : ( $ ) =>
seq (
field ( "params" , $. tuple _type ) ,
field ( "params" , choice( $. tuple _type , $ . _unannotated _type ) ) ,
optional ( $ . _async _keyword ) ,
optional ( $ . throws ) ,
$ . _arrow _operator ,
@ -394,13 +446,13 @@ module.exports = grammar({
repeat1 ( alias ( $ . _immediate _quest , "?" ) )
)
) ,
metatype : ( $ ) =>
prec . left ( seq ( $ . _unannotated _type , "." , choice ( "Type" , "Protocol" ) ) ) ,
metatype : ( $ ) => seq ( $ . _unannotated _type , "." , choice ( "Type" , "Protocol" ) ) ,
_quest : ( $ ) => "?" ,
_immediate _quest : ( $ ) => token . immediate ( "?" ) ,
opaque _type : ( $ ) => seq ( "some" , $ . user _type ) ,
opaque _type : ( $ ) => prec . right ( seq ( "some" , $ . _unannotated _type ) ) ,
existential _type : ( $ ) => prec . right ( seq ( "any" , $ . _unannotated _type ) ) ,
protocol _composition _type : ( $ ) =>
prec . righ t(
prec . lef t(
seq (
$ . _unannotated _type ,
repeat1 ( seq ( "&" , prec . right ( $ . _unannotated _type ) ) )
@ -540,7 +592,7 @@ module.exports = grammar({
seq (
field ( "start" , $ . _expression ) ,
field ( "op" , $ . _range _operator ) ,
field ( "end" , $ . _expr ession )
field ( "end" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
infix _expression : ( $ ) =>
@ -549,7 +601,7 @@ module.exports = grammar({
seq (
field ( "lhs" , $ . _expression ) ,
field ( "op" , $ . custom _operator ) ,
field ( "rhs" , $ . _expr ession )
field ( "rhs" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
nil _coalescing _expression : ( $ ) =>
@ -558,7 +610,7 @@ module.exports = grammar({
seq (
field ( "value" , $ . _expression ) ,
$ . _nil _coalescing _operator ,
field ( "if_nil" , $ . _expr ession )
field ( "if_nil" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
check _expression : ( $ ) =>
@ -575,7 +627,7 @@ module.exports = grammar({
seq (
field ( "lhs" , $ . _expression ) ,
field ( "op" , $ . _comparison _operator ) ,
field ( "rhs" , $ . _expr ession )
field ( "rhs" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
equality _expression : ( $ ) =>
@ -584,7 +636,7 @@ module.exports = grammar({
seq (
field ( "lhs" , $ . _expression ) ,
field ( "op" , $ . _equality _operator ) ,
field ( "rhs" , $ . _expr ession )
field ( "rhs" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
conjunction _expression : ( $ ) =>
@ -593,16 +645,7 @@ module.exports = grammar({
seq (
field ( "lhs" , $ . _expression ) ,
field ( "op" , $ . _conjunction _operator ) ,
prec . left (
PRECS . ternary _binary _suffix ,
field (
"rhs" ,
choice (
$ . _expression ,
alias ( $ . expr _hack _at _ternary _binary _call , $ . call _expression )
)
)
)
field ( "rhs" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
disjunction _expression : ( $ ) =>
@ -611,7 +654,7 @@ module.exports = grammar({
seq (
field ( "lhs" , $ . _expression ) ,
field ( "op" , $ . _disjunction _operator ) ,
field ( "rhs" , $ . _expr ession )
field ( "rhs" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
bitwise _operation : ( $ ) =>
@ -619,10 +662,10 @@ module.exports = grammar({
seq (
field ( "lhs" , $ . _expression ) ,
field ( "op" , $ . _bitwise _binary _operator ) ,
field ( "rhs" , $ . _expr ession )
field ( "rhs" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
custom _operator : ( $ ) => seq( CUSTOM _OPERATORS , optional ( "<" ) ) ,
custom _operator : ( $ ) => choice( token ( /[\/]+[*]+/ ) , $ . _custom _operator ) ,
// Suffixes
navigation _suffix : ( $ ) =>
seq (
@ -632,25 +675,28 @@ module.exports = grammar({
call _suffix : ( $ ) =>
prec (
PRECS . call _suffix ,
seq (
choice (
$ . value _arguments ,
sep1 ( $ . lambda _literal , seq ( field ( "name" , $ . simple _identifier ) , ":" ) )
)
choice (
$ . value _arguments ,
prec . dynamic ( - 1 , $ . _fn _call _lambda _arguments ) , // Prefer to treat `foo() { }` as one call not two
seq ( $ . value _arguments , $ . _fn _call _lambda _arguments )
)
) ,
constructor _suffix : ( $ ) =>
prec (
PRECS . call _suffix ,
seq (
choice (
choice (
alias ( $ . _constructor _value _arguments , $ . value _arguments ) ,
prec . dynamic ( - 1 , $ . _fn _call _lambda _arguments ) , // As above
seq (
alias ( $ . _constructor _value _arguments , $ . value _arguments ) ,
$ . lambda _literal
$ . _fn_call _lambda _arguments
)
)
) ,
_constructor _value _arguments : ( $ ) =>
seq ( "(" , optional ( sep1 ( $ . value _argument , "," ) ) , ")" ) ,
_fn _call _lambda _arguments : ( $ ) =>
sep1 ( $ . lambda _literal , seq ( field ( "name" , $ . simple _identifier ) , ":" ) ) ,
type _arguments : ( $ ) => prec . left ( seq ( "<" , sep1 ( $ . _type , "," ) , ">" ) ) ,
value _arguments : ( $ ) =>
seq (
@ -726,7 +772,7 @@ module.exports = grammar({
)
)
) ,
_await _operator : ( $ ) => "await" ,
_await _operator : ( $ ) => alias ( "await" , "await" ) ,
ternary _expression : ( $ ) =>
prec . right (
PRECS . ternary ,
@ -735,16 +781,15 @@ module.exports = grammar({
$ . _quest ,
field ( "if_true" , $ . _expression ) ,
":" ,
prec . left (
PRECS . ternary _binary _suffix ,
field (
"if_false" ,
choice (
$ . _expression ,
alias ( $ . expr _hack _at _ternary _binary _call , $ . call _expression )
)
)
)
field ( "if_false" , $ . _expr _hack _at _ternary _binary _suffix )
)
) ,
_expr _hack _at _ternary _binary _suffix : ( $ ) =>
prec . left (
PRECS . ternary _binary _suffix ,
choice (
$ . _expression ,
alias ( $ . expr _hack _at _ternary _binary _call , $ . call _expression )
)
) ,
expr _hack _at _ternary _binary _call : ( $ ) =>
@ -754,7 +799,11 @@ module.exports = grammar({
) ,
expr _hack _at _ternary _binary _call _suffix : ( $ ) =>
prec ( PRECS . call _suffix , $ . value _arguments ) ,
call _expression : ( $ ) => prec ( PRECS . call , seq ( $ . _expression , $ . call _suffix ) ) ,
call _expression : ( $ ) =>
prec (
PRECS . call ,
prec . dynamic ( DYNAMIC _PRECS . call , seq ( $ . _expression , $ . call _suffix ) )
) ,
_primary _expression : ( $ ) =>
choice (
$ . tuple _expression ,
@ -828,15 +877,20 @@ module.exports = grammar({
prec . left (
PRECS . lambda ,
seq (
"{" ,
prec ( PRECS . expr , optional ( field ( "captures" , $ . capture _list ) ) ) ,
optional ( seq ( optional ( field ( "type" , $ . lambda _function _type ) ) , "in" ) ) ,
choice ( "{" , "^{" ) ,
optional ( $ . _lambda _type _declaration ) ,
optional ( $ . statements ) ,
"}"
)
) ,
capture _list : ( $ ) =>
seq ( repeat ( $ . attribute ) , "[" , sep1 ( $ . capture _list _item , "," ) , "]" ) ,
_lambda _type _declaration : ( $ ) =>
seq (
repeat ( $ . attribute ) ,
prec ( PRECS . expr , optional ( field ( "captures" , $ . capture _list ) ) ) ,
optional ( field ( "type" , $ . lambda _function _type ) ) ,
"in"
) ,
capture _list : ( $ ) => seq ( "[" , sep1 ( $ . capture _list _item , "," ) , "]" ) ,
capture _list _item : ( $ ) =>
choice (
field ( "name" , $ . self _expression ) ,
@ -870,7 +924,6 @@ module.exports = grammar({
lambda _function _type _parameters : ( $ ) => sep1 ( $ . lambda _parameter , "," ) ,
lambda _parameter : ( $ ) =>
seq (
optional ( $ . attribute ) ,
choice (
$ . self _expression ,
prec ( PRECS . expr , field ( "name" , $ . simple _identifier ) ) ,
@ -902,7 +955,11 @@ module.exports = grammar({
_if _condition _sequence _item : ( $ ) =>
choice ( $ . _if _let _binding , $ . _expression , $ . availability _condition ) ,
_if _let _binding : ( $ ) =>
seq ( $ . _direct _or _indirect _binding , $ . _equal _sign , $ . _expression ) ,
seq (
$ . _direct _or _indirect _binding ,
optional ( seq ( $ . _equal _sign , $ . _expression ) ) ,
optional ( $ . where _clause )
) ,
guard _statement : ( $ ) =>
prec . right (
PRECS [ "if" ] ,
@ -942,16 +999,13 @@ module.exports = grammar({
$ . statements ,
optional ( "fallthrough" )
) ,
switch _pattern : ( $ ) => generate_pattern _matching _rule ( $ , true , false , true ) ,
switch _pattern : ( $ ) => alias( $ . _binding _pattern _with _expr , $ . pattern ) ,
do _statement : ( $ ) =>
prec . right ( PRECS [ "do" ] , seq ( "do" , $ . _block , repeat ( $ . catch _block ) ) ) ,
catch _block : ( $ ) =>
seq (
$ . catch _keyword ,
field (
"error" ,
optional ( generate _pattern _matching _rule ( $ , true , false ) )
) ,
field ( "error" , optional ( alias ( $ . _binding _pattern _no _expr , $ . pattern ) ) ) ,
optional ( $ . where _clause ) ,
$ . _block
) ,
@ -987,6 +1041,8 @@ module.exports = grammar({
_assignment _and _operator : ( $ ) => choice ( "+=" , "-=" , "*=" , "/=" , "%=" , "=" ) ,
_equality _operator : ( $ ) => choice ( "!=" , "!==" , $ . _eq _eq , "===" ) ,
_comparison _operator : ( $ ) => choice ( "<" , ">" , "<=" , ">=" ) ,
_three _dot _operator : ( $ ) => alias ( "..." , "..." ) , // Weird alias to satisfy highlight queries
_open _ended _range _operator : ( $ ) => alias ( "..<" , "..<" ) ,
_is _operator : ( $ ) => "is" ,
_additive _operator : ( $ ) =>
choice (
@ -995,7 +1051,10 @@ module.exports = grammar({
"+" ,
"-"
) ,
_multiplicative _operator : ( $ ) => choice ( "*" , "/" , "%" ) ,
// The `/` operator conflicts with a regex literal (which itself appears to conflict with a
// comment, for some reason), so we must give it equivalent token precedence.
_multiplicative _operator : ( $ ) =>
choice ( "*" , alias ( token ( prec ( PRECS . regex , "/" ) ) , "/" ) , "%" ) ,
as _operator : ( $ ) => choice ( $ . _as , $ . _as _quest , $ . _as _bang ) ,
_prefix _unary _operator : ( $ ) =>
prec . right (
@ -1019,7 +1078,8 @@ module.exports = grammar({
$ . navigation _expression ,
$ . call _expression ,
$ . tuple _expression ,
$ . self _expression
$ . self _expression ,
$ . postfix _expression // Since `x[...]! = y` is legal
) ,
////////////////////////////////
// Statements - https://docs.swift.org/swift-book/ReferenceManual/Statements.html
@ -1069,7 +1129,7 @@ module.exports = grammar({
"for" ,
optional ( $ . _try _operator ) ,
optional ( $ . _await _operator ) ,
field ( "item" , generate_pattern _matching _rule ( $ , true , true , false ) ) ,
field ( "item" , alias( $ . _binding _pattern _no _expr , $ . pattern ) ) ,
optional ( $ . type _annotation ) ,
"in" ,
field ( "collection" , $ . _expression ) ,
@ -1138,7 +1198,6 @@ module.exports = grammar({
$ . typealias _declaration ,
$ . function _declaration ,
$ . class _declaration ,
// TODO actor declaration
$ . protocol _declaration ,
$ . operator _declaration ,
$ . precedence _group _declaration ,
@ -1207,7 +1266,7 @@ module.exports = grammar({
prec . right (
seq (
optional ( $ . modifiers ) ,
field ( "name" , $. value _binding _pattern ) ,
field ( "name" , alias( $ . _binding _kind _and _pattern , $ . pattern ) ) ,
optional ( $ . type _annotation ) ,
optional ( $ . type _constraints ) ,
$ . protocol _property _requirements
@ -1220,28 +1279,22 @@ module.exports = grammar({
_modifierless _property _declaration : ( $ ) =>
prec . right (
seq (
choice ( seq ( optional ( $ . _async _modifier ) , "let" ) , "var" ) ,
sep1 (
seq (
field (
"name" ,
alias ( $ . property _binding _pattern , $ . value _binding _pattern )
) ,
optional ( $ . type _annotation ) ,
optional ( $ . type _constraints ) ,
optional (
choice (
seq ( $ . _equal _sign , field ( "value" , $ . _expression ) ) ,
field ( "computed_value" , $ . computed _property )
)
)
) ,
","
$ . _possibly _async _binding _pattern _kind ,
sep1 ( $ . _single _modifierless _property _declaration , "," )
)
) ,
_single _modifierless _property _declaration : ( $ ) =>
seq (
field ( "name" , alias ( $ . _no _expr _pattern _already _bound , $ . pattern ) ) ,
optional ( $ . type _annotation ) ,
optional ( $ . type _constraints ) ,
optional (
choice (
seq ( $ . _equal _sign , field ( "value" , $ . _expression ) ) ,
field ( "computed_value" , $ . computed _property )
)
)
) ,
property _binding _pattern : ( $ ) =>
generate _pattern _matching _rule ( $ , false , false ) ,
typealias _declaration : ( $ ) =>
seq ( optional ( $ . modifiers ) , $ . _modifierless _typealias _declaration ) ,
_modifierless _typealias _declaration : ( $ ) =>
@ -1296,7 +1349,7 @@ module.exports = grammar({
prec . right (
choice (
seq (
field ( "declaration_kind" , choice ( "class" , "struct" )) ,
field ( "declaration_kind" , choice ( "class" , "struct" , "actor" )) ,
field ( "name" , alias ( $ . simple _identifier , $ . type _identifier ) ) ,
optional ( $ . type _parameters ) ,
optional ( seq ( ":" , $ . _inheritance _specifiers ) ) ,
@ -1305,7 +1358,7 @@ module.exports = grammar({
) ,
seq (
field ( "declaration_kind" , "extension" ) ,
field ( "name" , $ . user _type ) ,
field ( "name" , $ . _unannotated _type ) ,
optional ( $ . type _parameters ) ,
optional ( seq ( ":" , $ . _inheritance _specifiers ) ) ,
optional ( $ . type _constraints ) ,
@ -1329,7 +1382,8 @@ module.exports = grammar({
prec . left ( field ( "inherits_from" , choice ( $ . user _type , $ . function _type ) ) ) ,
_annotated _inheritance _specifier : ( $ ) =>
seq ( repeat ( $ . attribute ) , $ . inheritance _specifier ) ,
type _parameters : ( $ ) => seq ( "<" , sep1 ( $ . type _parameter , "," ) , ">" ) ,
type _parameters : ( $ ) =>
seq ( "<" , sep1 ( $ . type _parameter , "," ) , optional ( $ . type _constraints ) , ">" ) ,
type _parameter : ( $ ) =>
seq (
optional ( $ . type _parameter _modifiers ) ,
@ -1361,7 +1415,7 @@ module.exports = grammar({
optional ( $ . _class _member _separator )
) ,
_function _value _parameters : ( $ ) =>
seq( "(" , optional ( sep1 ( $ . _function _value _parameter , "," ) ) , ")" ) ,
repeat1( seq( "(" , optional ( sep1 ( $ . _function _value _parameter , "," ) ) , ")" ) ) ,
_function _value _parameter : ( $ ) =>
seq (
optional ( $ . attribute ) ,
@ -1382,14 +1436,7 @@ module.exports = grammar({
_non _constructor _function _decl : ( $ ) =>
seq (
"func" ,
field (
"name" ,
choice (
$ . simple _identifier ,
$ . _referenceable _operator ,
$ . _bitwise _binary _operator
)
)
field ( "name" , choice ( $ . simple _identifier , $ . _referenceable _operator ) )
) ,
_referenceable _operator : ( $ ) =>
choice (
@ -1399,10 +1446,15 @@ module.exports = grammar({
$ . _multiplicative _operator ,
$ . _equality _operator ,
$ . _comparison _operator ,
$ . _assignment _and _operator ,
"++" ,
"--" ,
$ . bang ,
"~"
"~" ,
"|" ,
"^" ,
"<<" ,
">>"
) ,
// Hide the fact that certain symbols come from the custom scanner by aliasing them to their
// string variants. This keeps us from having to see them in the syntax tree (which would be
@ -1412,9 +1464,6 @@ module.exports = grammar({
_eq _eq : ( $ ) => alias ( $ . _eq _eq _custom , "==" ) ,
_dot : ( $ ) => alias ( $ . _dot _custom , "." ) ,
_arrow _operator : ( $ ) => alias ( $ . _arrow _operator _custom , "->" ) ,
_three _dot _operator : ( $ ) => alias ( $ . _three _dot _operator _custom , "..." ) ,
_open _ended _range _operator : ( $ ) =>
alias ( $ . _open _ended _range _operator _custom , "..<" ) ,
_conjunction _operator : ( $ ) => alias ( $ . _conjunction _operator _custom , "&&" ) ,
_disjunction _operator : ( $ ) => alias ( $ . _disjunction _operator _custom , "||" ) ,
_nil _coalescing _operator : ( $ ) =>
@ -1422,12 +1471,7 @@ module.exports = grammar({
_as : ( $ ) => alias ( $ . _as _custom , "as" ) ,
_as _quest : ( $ ) => alias ( $ . _as _quest _custom , "as?" ) ,
_as _bang : ( $ ) => alias ( $ . _as _bang _custom , "as!" ) ,
_async _keyword : function ( $ ) {
// Backward compatibility: make `async` both a named node and a string node. Remove this once downstream queries
// have all been switched over.
return prec ( - 1 , alias ( $ . _async _keyword _internal , $ . async ) ) ;
} ,
_async _keyword _internal : ( $ ) => alias ( $ . _async _keyword _custom , "async" ) ,
_async _keyword : ( $ ) => alias ( $ . _async _keyword _custom , "async" ) ,
_async _modifier : ( $ ) => token ( "async" ) ,
throws : ( $ ) => choice ( $ . _throws _keyword , $ . _rethrows _keyword ) ,
enum _class _body : ( $ ) =>
@ -1551,9 +1595,13 @@ module.exports = grammar({
seq (
choice ( "prefix" , "infix" , "postfix" ) ,
"operator" ,
$ . custom _operator ,
optional ( seq ( ":" , $ . simple _identifier ) )
$ . _referenceable _operator ,
optional ( seq ( ":" , $ . simple _identifier ) ) ,
optional ( $ . deprecated _operator _declaration _body )
) ,
// The Swift compiler no longer accepts these, but some very old code still uses it.
deprecated _operator _declaration _body : ( $ ) =>
seq ( "{" , repeat ( choice ( $ . simple _identifier , $ . _basic _literal ) ) , "}" ) ,
precedence _group _declaration : ( $ ) =>
seq (
"precedencegroup" ,
@ -1586,64 +1634,104 @@ module.exports = grammar({
"@" ,
$ . user _type ,
// attribute arguments are a mess of special cases, maybe this is good enough?
optional (
seq (
"(" ,
sep1 (
choice (
// labeled function parameters, used in custom property wrappers
seq ( $ . simple _identifier , ":" , $ . _expression ) ,
// Unlabeled function parameters, simple identifiers, or `*`
$ . _expression ,
// References to param names (used in `@objc(foo:bar:)`)
repeat1 ( seq ( $ . simple _identifier , ":" ) ) ,
// Version restrictions (iOS 3.4.5, Swift 5.0.0)
seq ( repeat1 ( $ . simple _identifier ) , sep1 ( $ . integer _literal , "." ) )
) ,
","
) ,
")"
)
)
optional ( seq ( "(" , sep1 ( $ . _attribute _argument , "," ) , ")" ) )
) ,
_attribute _argument : ( $ ) =>
choice (
// labeled function parameters, used in custom property wrappers
seq ( $ . simple _identifier , ":" , $ . _expression ) ,
// Unlabeled function parameters, simple identifiers, or `*`
$ . _expression ,
// References to param names (used in `@objc(foo:bar:)`)
repeat1 ( seq ( $ . simple _identifier , ":" ) ) ,
// Version restrictions (iOS 3.4.5, Swift 5.0.0)
seq ( repeat1 ( $ . simple _identifier ) , sep1 ( $ . integer _literal , "." ) )
) ,
////////////////////////////////
// Patterns - https://docs.swift.org/swift-book/ReferenceManual/Patterns.html
////////////////////////////////
// Higher-than-default precedence to resolve `x as SomeType` ambiguity (expression patterns seem not to support
// as-expressions)
binding _pattern : ( $ ) =>
prec . left ( 1 , generate _pattern _matching _rule ( $ , true , false , false , true ) ) ,
non _binding _pattern : ( $ ) =>
prec . left (
1 ,
generate _pattern _matching _rule ( $ , false , false , false , true )
_universally _allowed _pattern : ( $ ) =>
choice (
$ . wildcard _pattern ,
$ . _tuple _pattern ,
$ . _type _casting _pattern ,
$ . _case _pattern
) ,
_bound _identifier : ( $ ) => field ( "bound_identifier" , $ . simple _identifier ) ,
_binding _pattern _no _expr : ( $ ) =>
seq (
choice (
$ . _universally _allowed _pattern ,
$ . _binding _pattern ,
$ . _bound _identifier
) ,
optional ( $ . _quest )
) ,
_no _expr _pattern _already _bound : ( $ ) =>
seq (
choice ( $ . _universally _allowed _pattern , $ . _bound _identifier ) ,
optional ( $ . _quest )
) ,
// Higher precedence than pattern w/o binding since these are strictly more flexible
_binding _pattern _with _expr : ( $ ) =>
prec . left ( 2 , generate _pattern _matching _rule ( $ , true , false , true , true ) ) ,
seq (
choice (
$ . _universally _allowed _pattern ,
$ . _binding _pattern ,
$ . _expression
) ,
optional ( $ . _quest )
) ,
_non _binding _pattern _with _expr : ( $ ) =>
prec . left ( 2 , generate _pattern _matching _rule ( $ , false , false , true , true ) ) ,
seq (
choice ( $ . _universally _allowed _pattern , $ . _expression ) ,
optional ( $ . _quest )
) ,
_direct _or _indirect _binding : ( $ ) =>
seq (
choice (
$ . value _binding _pattern ,
seq ( "case" , generate _pattern _matching _rule ( $ , true , false , false ) )
$ . _binding_kind _and _pattern ,
seq ( "case" , $. _binding _pattern _no _expr )
) ,
optional ( $ . type _annotation )
) ,
_binding _pattern _kind : ( $ ) => field ( "mutability" , choice ( "var" , "let" ) ) ,
_possibly _async _binding _pattern _kind : ( $ ) =>
seq ( optional ( $ . _async _modifier ) , $ . _binding _pattern _kind ) ,
_binding _kind _and _pattern : ( $ ) =>
seq (
$ . _possibly _async _binding _pattern _kind ,
$ . _no _expr _pattern _already _bound
) ,
wildcard _pattern : ( $ ) => "_" ,
binding _pattern _kind : ( $ ) => choice ( "var" , "let" ) ,
value _binding _pattern : ( $ ) =>
prec . left (
choice (
seq ( "var" , generate _pattern _matching _rule ( $ , false , false ) ) ,
seq (
optional ( $ . _async _modifier ) ,
"let" ,
generate _pattern _matching _rule ( $ , false , false )
)
)
_tuple _pattern _item : ( $ ) =>
choice (
seq (
$ . simple _identifier ,
seq ( ":" , alias ( $ . _binding _pattern _with _expr , $ . pattern ) )
) ,
alias ( $ . _binding _pattern _with _expr , $ . pattern )
) ,
_tuple _pattern : ( $ ) => seq ( "(" , sep1 ( $ . _tuple _pattern _item , "," ) , ")" ) ,
_case _pattern : ( $ ) =>
seq (
optional ( "case" ) ,
optional ( $ . user _type ) , // XXX this should just be _type but that creates ambiguity
$ . _dot ,
$ . simple _identifier ,
optional ( $ . _tuple _pattern )
) ,
_type _casting _pattern : ( $ ) =>
choice (
seq ( "is" , $ . _type ) ,
seq ( alias ( $ . _binding _pattern _no _expr , $ . pattern ) , $ . _as , $ . _type )
) ,
_binding _pattern : ( $ ) =>
seq (
seq ( optional ( "case" ) , $ . _binding _pattern _kind ) ,
$ . _no _expr _pattern _already _bound
) ,
// ==========
// Modifiers
// ==========
@ -1663,17 +1751,15 @@ module.exports = grammar({
$ . function _modifier ,
$ . mutation _modifier ,
$ . property _modifier ,
$ . parameter _modifier
$ . parameter _modifier ,
$ . property _behavior _modifier
) ,
_locally _permitted _modifier : ( $ ) =>
choice (
$ . ownership _modifier ,
$ . property _behavior _modifier ,
$ . inheritance _modifier
) ,
choice ( $ . ownership _modifier , $ . inheritance _modifier ) ,
property _behavior _modifier : ( $ ) => "lazy" ,
type _modifiers : ( $ ) => repeat1 ( $ . attribute ) ,
member _modifier : ( $ ) => choice ( "override" , "convenience" , "required" ) ,
member _modifier : ( $ ) =>
choice ( "override" , "convenience" , "required" , "nonisolated" ) ,
visibility _modifier : ( $ ) =>
seq (
choice ( "public" , "private" , "internal" , "fileprivate" , "open" ) ,
@ -1730,87 +1816,6 @@ module.exports = grammar({
function sep1 ( rule , separator ) {
return seq ( rule , repeat ( seq ( separator , rule ) ) ) ;
}
function generate _tuple _pattern ( $ , allows _binding , allows _expressions ) {
var pattern _rule = generate _pattern _matching _rule (
$ ,
allows _binding ,
false ,
allows _expressions
) ;
var tuple _pattern _item = choice (
seq ( $ . simple _identifier , seq ( ":" , pattern _rule ) ) ,
pattern _rule
) ;
return seq ( "(" , sep1 ( tuple _pattern _item , "," ) , ")" , optional ( $ . _quest ) ) ;
}
function generate _case _pattern ( $ , allows _binding , force ) {
return seq (
optional ( $ . user _type ) , // XXX this should just be _type but that creates ambiguity
$ . _dot ,
$ . simple _identifier ,
optional ( generate _tuple _pattern ( $ , allows _binding , true ) ) ,
optional ( $ . _quest )
) ;
}
function generate _type _casting _pattern ( $ , allows _binding ) {
return choice (
seq ( "is" , $ . _type ) ,
seq (
generate _pattern _matching _rule ( $ , allows _binding , false ) ,
$ . _as ,
$ . _type
)
) ;
}
function generate _pattern _matching _rule (
$ ,
allows _binding ,
allows _case _keyword ,
allows _expressions ,
force
) {
if ( ! force && ! allows _case _keyword ) {
if ( allows _binding && ! allows _expressions ) {
return $ . binding _pattern ;
}
if ( ! allows _binding && ! allows _expressions ) {
return $ . non _binding _pattern ;
}
if ( allows _binding && allows _expressions ) {
return $ . _binding _pattern _with _expr ;
}
if ( ! allows _binding && allows _expressions ) {
return $ . _non _binding _pattern _with _expr ;
}
}
var always _allowed _patterns = [
$ . wildcard _pattern ,
generate _tuple _pattern ( $ , allows _binding , allows _expressions || false ) ,
generate _type _casting _pattern ( $ , allows _binding ) ,
] ;
var binding _pattern _prefix = allows _case _keyword
? seq ( optional ( "case" ) , $ . binding _pattern _kind )
: $ . binding _pattern _kind ;
var binding _pattern _if _allowed = allows _binding
? [
seq (
binding _pattern _prefix ,
generate _pattern _matching _rule ( $ , false , false , false )
) ,
]
: [ ] ;
var case _pattern = allows _case _keyword
? seq ( "case" , generate _case _pattern ( $ , allows _binding ) )
: generate _case _pattern ( $ , allows _binding ) ;
var expression _pattern = allows _expressions
? $ . _expression
: field ( "bound_identifier" , $ . simple _identifier ) ;
var all _patterns = always _allowed _patterns
. concat ( binding _pattern _if _allowed )
. concat ( case _pattern )
. concat ( expression _pattern ) ;
return seq ( choice . apply ( void 0 , all _patterns ) , optional ( $ . _quest ) ) ;
}
function tree _sitter _version _supports _emoji ( ) {
try {