Merge pull request #21821 from github/tausbn/unified-swift-grammar-cleanup-phase-1

unified: Swift grammar cleanup part 1
This commit is contained in:
Taus
2026-05-12 16:12:09 +02:00
committed by GitHub
6 changed files with 1517 additions and 1365 deletions

View File

@@ -5,6 +5,21 @@ This is a CodeQL extractor based on tree-sitter.
## Building
To build the extractor, run `scripts/create-extractor-pack.sh`
## Editing the Swift grammar
The vendored tree-sitter-swift grammar lives at
`extractor/tree-sitter-swift/`. After editing `grammar.js` (or any other
grammar source), run `scripts/regenerate-grammar.sh` to:
- regenerate `extractor/tree-sitter-swift/src/{parser.c, grammar.json,
node-types.json}` (and the `src/tree_sitter/*.h` headers) via
`tree-sitter generate`; and
- refresh `extractor/tree-sitter-swift/node-types.yml`, the
human-readable companion to `src/node-types.json` produced by yeast's
`node_types_yaml` binary.
`node-types.yml` is the recommended review surface for grammar changes —
it shows the impact of a grammar tweak on the named node kinds, fields,
and child types in a form much easier to read than the raw JSON.
## Testing
- If you changed the extractor code, always rebuild it before running tests.

View File

@@ -84,18 +84,26 @@ if (tree_sitter_version_supports_emoji()) {
module.exports = grammar({
name: "swift",
supertypes: ($) => [
$.expression,
$.unannotated_type,
$.global_declaration,
$.type_level_declaration,
$.local_declaration,
$.protocol_member_declaration,
],
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],
[$._simple_user_type, $.expression],
// To support nested types A.B not being interpreted as `(navigation_expression ... (type_identifier)) (navigation_suffix)`
[$.user_type],
// How to tell the difference between Foo.bar(with:and:), and Foo.bar(with: smth, and: other)? You need GLR
[$.value_argument],
// { (foo, bar) ...
[$._expression, $.lambda_parameter],
[$.expression, $.lambda_parameter],
[$._primary_expression, $.lambda_parameter],
// (start: start, end: end)
[$._tuple_type_item_identifier, $.tuple_expression],
@@ -105,10 +113,10 @@ module.exports = grammar({
// `+(...)` 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],
[$.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, $._expression],
[$.capture_list_item, $._expression, $._simple_user_type],
[$.capture_list_item, $.expression],
[$.capture_list_item, $.expression, $._simple_user_type],
[$._primary_expression, $.capture_list_item],
// a ? b : c () could be calling c(), or it could be calling a function that's produced by the result of
// `(a ? b : c)`. We have a small hack to force it to be the former of these by intentionally introducing a
@@ -119,10 +127,10 @@ module.exports = grammar({
// `if try foo { } ...` should award its braces to the `if`. In order to make this actually happen, we need to parse
// all the options and pick the best one that doesn't error out.
[$.try_expression, $._unary_expression],
[$.try_expression, $._expression],
[$.try_expression, $.expression],
// await {expression} has the same special cases as `try`.
[$.await_expression, $._unary_expression],
[$.await_expression, $._expression],
[$.await_expression, $.expression],
// In a computed property, when you see an @attribute, it's not yet clear if that's going to be for a
// locally-declared class or a getter / setter specifier.
[
@@ -400,13 +408,15 @@ module.exports = grammar({
type_annotation: ($) =>
seq(":", field("type", $._possibly_implicitly_unwrapped_type)),
_possibly_implicitly_unwrapped_type: ($) =>
seq($._type, optional(token.immediate("!"))),
_type: ($) =>
choice($.type, $.implicitly_unwrapped_type),
implicitly_unwrapped_type: ($) =>
seq($.type, token.immediate("!")),
type: ($) =>
prec.right(
PRECS.ty,
seq(optional($.type_modifiers), field("name", $._unannotated_type))
seq(field("modifiers", optional($.type_modifiers)), field("name", $.unannotated_type))
),
_unannotated_type: ($) =>
unannotated_type: ($) =>
prec.right(
PRECS.ty,
choice(
@@ -450,7 +460,7 @@ module.exports = grammar({
seq(
optional($._tuple_type_item_identifier),
optional($.parameter_modifiers),
field("type", $._type)
field("type", $.type)
)
),
_tuple_type_item_identifier: ($) =>
@@ -464,15 +474,15 @@ module.exports = grammar({
),
function_type: ($) =>
seq(
field("params", choice($.tuple_type, $._unannotated_type)),
field("params", choice($.tuple_type, $.unannotated_type)),
optional($._async_keyword),
optional(choice($.throws_clause, $.throws)),
$._arrow_operator,
field("return_type", $._type)
field("return_type", $.type)
),
array_type: ($) => seq("[", field("element", $._type), "]"),
array_type: ($) => seq("[", field("element", $.type), "]"),
dictionary_type: ($) =>
seq("[", field("key", $._type), ":", field("value", $._type), "]"),
seq("[", field("key", $.type), ":", field("value", $.type), "]"),
optional_type: ($) =>
prec.left(
seq(
@@ -483,18 +493,18 @@ module.exports = grammar({
repeat1(alias($._immediate_quest, "?"))
)
),
metatype: ($) => seq($._unannotated_type, ".", choice("Type", "Protocol")),
metatype: ($) => seq($.unannotated_type, ".", choice("Type", "Protocol")),
_quest: ($) => "?",
_immediate_quest: ($) => token.immediate("?"),
opaque_type: ($) => prec.right(seq("some", $._unannotated_type)),
existential_type: ($) => prec.right(seq("any", $._unannotated_type)),
type_parameter_pack: ($) => prec.left(seq("each", $._unannotated_type)),
type_pack_expansion: ($) => prec.left(seq("repeat", $._unannotated_type)),
opaque_type: ($) => prec.right(seq("some", $.unannotated_type)),
existential_type: ($) => prec.right(seq("any", $.unannotated_type)),
type_parameter_pack: ($) => prec.left(seq("each", $.unannotated_type)),
type_pack_expansion: ($) => prec.left(seq("repeat", $.unannotated_type)),
protocol_composition_type: ($) =>
prec.left(
seq(
$._unannotated_type,
repeat1(seq("&", prec.right($._unannotated_type)))
$.unannotated_type,
repeat1(seq("&", prec.right($.unannotated_type)))
)
),
suppressed_constraint: ($) =>
@@ -507,7 +517,7 @@ module.exports = grammar({
////////////////////////////////
// Expressions - https://docs.swift.org/swift-book/ReferenceManual/Expressions.html
////////////////////////////////
_expression: ($) =>
expression: ($) =>
prec(
PRECS.expr,
choice(
@@ -521,9 +531,11 @@ module.exports = grammar({
$.assignment,
$.value_parameter_pack,
$.value_pack_expansion,
seq($._expression, alias($._immediate_quest, "?"))
$.optional_chain_marker
)
),
optional_chain_marker: ($) =>
seq($.expression, alias($._immediate_quest, "?")),
// Unary expressions
_unary_expression: ($) =>
choice(
@@ -544,7 +556,7 @@ module.exports = grammar({
prec.left(
PRECS.postfix_operations,
seq(
field("target", $._expression),
field("target", $.expression),
field("operation", $._postfix_unary_operator)
)
),
@@ -562,10 +574,7 @@ module.exports = grammar({
_parenthesized_type: ($) =>
seq(
"(",
field(
"element",
choice($.opaque_type, $.existential_type, $.dictionary_type)
),
choice($.opaque_type, $.existential_type, $.dictionary_type),
")"
),
navigation_expression: ($) =>
@@ -576,7 +585,7 @@ module.exports = grammar({
"target",
choice(
$._navigable_type_expression,
$._expression,
$.expression,
$._parenthesized_type
)
),
@@ -590,7 +599,7 @@ module.exports = grammar({
PRECS.range,
seq(
$._range_operator,
prec.right(PRECS.range_suffix, field("end", $._expression))
prec.right(PRECS.range_suffix, field("end", $.expression))
)
),
_range_operator: ($) =>
@@ -598,7 +607,7 @@ module.exports = grammar({
open_end_range_expression: ($) =>
prec.right(
PRECS.range,
seq(field("start", $._expression), $._three_dot_operator)
seq(field("start", $.expression), $._three_dot_operator)
),
prefix_expression: ($) =>
prec.left(
@@ -608,8 +617,8 @@ module.exports = grammar({
field(
"target",
choice(
$._expression,
alias(choice("async", "if", "switch"), $._expression)
$.expression,
alias(choice("async", "if", "switch"), $.expression)
)
)
)
@@ -617,7 +626,7 @@ module.exports = grammar({
as_expression: ($) =>
prec.left(
PRECS.as,
seq(field("expr", $._expression), $.as_operator, field("type", $._type))
seq(field("expr", $.expression), $.as_operator, field("type", $.type))
),
selector_expression: ($) =>
seq(
@@ -625,7 +634,7 @@ module.exports = grammar({
"selector",
"(",
optional(choice("getter:", "setter:")),
$._expression,
$.expression,
")"
),
// Binary expressions
@@ -647,25 +656,25 @@ module.exports = grammar({
prec.left(
PRECS.multiplication,
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $._multiplicative_operator),
field("rhs", $._expression)
field("rhs", $.expression)
)
),
additive_expression: ($) =>
prec.left(
PRECS.addition,
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $._additive_operator),
field("rhs", $._expression)
field("rhs", $.expression)
)
),
range_expression: ($) =>
prec.right(
PRECS.range,
seq(
field("start", $._expression),
field("start", $.expression),
field("op", $._range_operator),
field("end", $._expr_hack_at_ternary_binary_suffix)
)
@@ -674,7 +683,7 @@ module.exports = grammar({
prec.left(
PRECS.infix_operations,
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $.custom_operator),
field("rhs", $._expr_hack_at_ternary_binary_suffix)
)
@@ -683,7 +692,7 @@ module.exports = grammar({
prec.right(
PRECS.nil_coalescing,
seq(
field("value", $._expression),
field("value", $.expression),
$._nil_coalescing_operator,
field("if_nil", $._expr_hack_at_ternary_binary_suffix)
)
@@ -692,15 +701,15 @@ module.exports = grammar({
prec.left(
PRECS.check,
seq(
field("target", $._expression),
field("target", $.expression),
field("op", $._is_operator),
field("type", $._type)
field("type", $.type)
)
),
comparison_expression: ($) =>
prec.left(
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $._comparison_operator),
field("rhs", $._expr_hack_at_ternary_binary_suffix)
)
@@ -709,7 +718,7 @@ module.exports = grammar({
prec.left(
PRECS.equality,
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $._equality_operator),
field("rhs", $._expr_hack_at_ternary_binary_suffix)
)
@@ -718,7 +727,7 @@ module.exports = grammar({
prec.left(
PRECS.conjunction,
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $._conjunction_operator),
field("rhs", $._expr_hack_at_ternary_binary_suffix)
)
@@ -727,7 +736,7 @@ module.exports = grammar({
prec.left(
PRECS.disjunction,
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $._disjunction_operator),
field("rhs", $._expr_hack_at_ternary_binary_suffix)
)
@@ -735,7 +744,7 @@ module.exports = grammar({
bitwise_operation: ($) =>
prec.left(
seq(
field("lhs", $._expression),
field("lhs", $.expression),
field("op", $._bitwise_binary_operator),
field("rhs", $._expr_hack_at_ternary_binary_suffix)
)
@@ -772,7 +781,7 @@ module.exports = grammar({
seq("(", optional(sep1Opt($.value_argument, ",")), ")"),
_fn_call_lambda_arguments: ($) =>
sep1($.lambda_literal, seq(field("name", $.simple_identifier), ":")),
type_arguments: ($) => prec.left(seq("<", sep1Opt($._type, ","), ">")),
type_arguments: ($) => prec.left(seq("<", sep1Opt($.type, ","), ">")),
value_arguments: ($) =>
seq(
choice(
@@ -800,7 +809,7 @@ module.exports = grammar({
),
seq(
optional(seq(field("name", $.value_argument_label), ":")),
field("value", $._expression)
field("value", $.expression)
)
)
)
@@ -816,7 +825,7 @@ module.exports = grammar({
// Prefer direct calls, e.g. `try foo()`, over indirect like `try a ? b() : c`. This allows us to have
// left associativity for the direct calls, which is technically wrong but is the only way to resolve the
// ambiguity of `if foo { ... }` in the correct direction.
prec.right(-2, $._expression),
prec.right(-2, $.expression),
prec.left(0, $._binary_expression),
prec.left(0, $.call_expression),
// Similarly special case the ternary expression, where `try` may come earlier than it is actually needed.
@@ -838,7 +847,7 @@ module.exports = grammar({
"expr",
choice(
// Prefer direct calls over indirect (same as with `try`).
prec.right(-2, $._expression),
prec.right(-2, $.expression),
prec.left(0, $.call_expression),
// Special case ternary to `await` the whole thing (same as with `try`).
prec.dynamic(1, prec.left(-1, $.ternary_expression))
@@ -851,9 +860,9 @@ module.exports = grammar({
prec.right(
PRECS.ternary,
seq(
field("condition", $._expression),
field("condition", $.expression),
$._quest,
field("if_true", $._expression),
field("if_true", $.expression),
":",
field("if_false", $._expr_hack_at_ternary_binary_suffix)
)
@@ -862,13 +871,13 @@ module.exports = grammar({
prec.left(
PRECS.ternary_binary_suffix,
choice(
$._expression,
$.expression,
alias($.expr_hack_at_ternary_binary_call, $.call_expression)
)
),
expr_hack_at_ternary_binary_call: ($) =>
seq(
$._expression,
$.expression,
alias($.expr_hack_at_ternary_binary_call_suffix, $.call_suffix)
),
expr_hack_at_ternary_binary_call_suffix: ($) =>
@@ -876,7 +885,7 @@ module.exports = grammar({
call_expression: ($) =>
prec(
PRECS.call,
prec.dynamic(DYNAMIC_PRECS.call, seq($._expression, $.call_suffix))
prec.dynamic(DYNAMIC_PRECS.call, seq($.expression, $.call_suffix))
),
macro_invocation: ($) =>
prec(
@@ -904,7 +913,7 @@ module.exports = grammar({
$.super_expression,
$.try_expression,
$.await_expression,
$._referenceable_operator,
$.referenceable_operator,
$.key_path_expression,
$.key_path_string_expression,
prec.right(
@@ -920,7 +929,7 @@ module.exports = grammar({
sep1Opt(
seq(
optional(seq(field("name", $.simple_identifier), ":")),
field("value", $._expression)
field("value", $.expression)
),
","
),
@@ -928,7 +937,7 @@ module.exports = grammar({
)
),
array_literal: ($) =>
seq("[", optional(sep1Opt(field("element", $._expression), ",")), "]"),
seq("[", optional(sep1Opt(field("element", $.expression), ",")), "]"),
dictionary_literal: ($) =>
seq(
"[",
@@ -937,7 +946,7 @@ module.exports = grammar({
"]"
),
_dictionary_literal_item: ($) =>
seq(field("key", $._expression), ":", field("value", $._expression)),
seq(field("key", $.expression), ":", field("value", $.expression)),
special_literal: ($) =>
seq(
$._hash_symbol,
@@ -956,7 +965,7 @@ module.exports = grammar({
$._hash_symbol,
choice("colorLiteral", "fileLiteral", "imageLiteral"),
"(",
sep1Opt(seq($.simple_identifier, ":", $._expression), ","),
sep1Opt(seq($.simple_identifier, ":", $.expression), ","),
")"
),
lambda_literal: ($) =>
@@ -985,7 +994,7 @@ module.exports = grammar({
seq(
optional($.ownership_modifier),
field("name", $.simple_identifier),
optional(seq($._equal_sign, field("value", $._expression)))
optional(seq($._equal_sign, field("value", $.expression)))
)
)
),
@@ -1033,17 +1042,17 @@ module.exports = grammar({
PRECS["if"],
seq(
"if",
sep1(field("condition", $._if_condition_sequence_item), ","),
sep1(field("condition", $.if_condition), ","),
$._block,
optional(seq($["else"], $._else_options))
)
),
_if_condition_sequence_item: ($) =>
choice($._if_let_binding, $._expression, $.availability_condition),
_if_let_binding: ($) =>
if_condition: ($) =>
choice($.if_let_binding, $.expression, $.availability_condition),
if_let_binding: ($) =>
seq(
$._direct_or_indirect_binding,
optional(seq($._equal_sign, $._expression)),
optional(seq($._equal_sign, $.expression)),
optional($.where_clause)
),
guard_statement: ($) =>
@@ -1051,7 +1060,7 @@ module.exports = grammar({
PRECS["if"],
seq(
"guard",
sep1(field("condition", $._if_condition_sequence_item), ","),
sep1(field("condition", $.if_condition), ","),
$["else"],
$._block
)
@@ -1061,7 +1070,7 @@ module.exports = grammar({
PRECS["switch"],
seq(
"switch",
field("expr", $._expression),
field("expr", $.expression),
"{",
repeat($.switch_entry),
"}"
@@ -1075,7 +1084,7 @@ module.exports = grammar({
"case",
seq(
$.switch_pattern,
optional(seq($.where_keyword, $._expression))
optional(seq($.where_keyword, $.expression))
),
repeat(seq(",", $.switch_pattern))
),
@@ -1095,7 +1104,7 @@ module.exports = grammar({
optional($.where_clause),
$._block
),
where_clause: ($) => prec.left(seq($.where_keyword, $._expression)),
where_clause: ($) => prec.left(seq($.where_keyword, $.expression)),
key_path_expression: ($) =>
prec.right(
PRECS.keypath,
@@ -1108,7 +1117,7 @@ module.exports = grammar({
)
),
key_path_string_expression: ($) =>
prec.left(seq($._hash_symbol, "keyPath", "(", $._expression, ")")),
prec.left(seq($._hash_symbol, "keyPath", "(", $.expression, ")")),
_key_path_component: ($) =>
prec.left(
choice(
@@ -1164,7 +1173,7 @@ module.exports = grammar({
),
_bitwise_binary_operator: ($) => choice("&", "|", "^", "<<", ">>"),
_postfix_unary_operator: ($) => choice("++", "--", $.bang),
directly_assignable_expression: ($) => $._expression,
directly_assignable_expression: ($) => $.expression,
////////////////////////////////
// Statements - https://docs.swift.org/swift-book/ReferenceManual/Statements.html
@@ -1180,15 +1189,15 @@ module.exports = grammar({
),
_local_statement: ($) =>
choice(
$._expression,
$._local_declaration,
$.expression,
$.local_declaration,
$._labeled_statement,
$.control_transfer_statement
),
_top_level_statement: ($) =>
choice(
$._expression,
$._global_declaration,
$.expression,
$.global_declaration,
$._labeled_statement,
$._throw_statement
),
@@ -1227,15 +1236,15 @@ module.exports = grammar({
// the opposite, though, since function calls may contain trailing code blocks, which are undesirable here.
//
// To fix that, we simply undo the special casing by defining our own `await_expression`.
choice($._expression, alias($.for_statement_await, $.await_expression)),
for_statement_await: ($) => seq($._await_operator, $._expression),
choice($.expression, alias($.for_statement_await, $.await_expression)),
for_statement_await: ($) => seq($._await_operator, $.expression),
while_statement: ($) =>
prec(
PRECS.loop,
seq(
"while",
sep1(field("condition", $._if_condition_sequence_item), ","),
sep1(field("condition", $.if_condition), ","),
"{",
optional($.statements),
"}"
@@ -1252,7 +1261,7 @@ module.exports = grammar({
// Make sure we make it to the `while` before assuming this is a parameter pack.
repeat($._implicit_semi),
"while",
sep1(field("condition", $._if_condition_sequence_item), ",")
sep1(field("condition", $.if_condition), ",")
)
),
control_transfer_statement: ($) =>
@@ -1262,11 +1271,11 @@ module.exports = grammar({
PRECS.control_transfer,
seq(
$._optionally_valueful_control_keyword,
field("result", optional($._expression))
field("result", optional($.expression))
)
)
),
_throw_statement: ($) => seq($.throw_keyword, $._expression),
_throw_statement: ($) => seq($.throw_keyword, $.expression),
throw_keyword: ($) => "throw",
_optionally_valueful_control_keyword: ($) =>
choice("return", "continue", "break", "yield"),
@@ -1276,13 +1285,13 @@ module.exports = grammar({
seq(
field("target", $.directly_assignable_expression),
field("operator", $._assignment_and_operator),
field("result", $._expression)
field("result", $.expression)
)
),
value_parameter_pack: ($) =>
prec.left(PRECS.parameter_pack, seq("each", $._expression)),
prec.left(PRECS.parameter_pack, seq("each", $.expression)),
value_pack_expansion: ($) =>
prec.left(PRECS.parameter_pack, seq("repeat", $._expression)),
prec.left(PRECS.parameter_pack, seq("repeat", $.expression)),
availability_condition: ($) =>
seq(
$._hash_symbol,
@@ -1296,7 +1305,7 @@ module.exports = grammar({
////////////////////////////////
// Declarations - https://docs.swift.org/swift-book/ReferenceManual/Declarations.html
////////////////////////////////
_global_declaration: ($) =>
global_declaration: ($) =>
choice(
$.import_declaration,
$.property_declaration,
@@ -1310,7 +1319,7 @@ module.exports = grammar({
$.associatedtype_declaration,
$.macro_declaration
),
_type_level_declaration: ($) =>
type_level_declaration: ($) =>
choice(
$.import_declaration,
$.property_declaration,
@@ -1325,7 +1334,7 @@ module.exports = grammar({
$.precedence_group_declaration,
$.associatedtype_declaration
),
_local_declaration: ($) =>
local_declaration: ($) =>
choice(
alias($._local_property_declaration, $.property_declaration),
alias($._local_typealias_declaration, $.typealias_declaration),
@@ -1412,12 +1421,12 @@ module.exports = grammar({
1,
seq(
$._equal_sign,
field("value", $._expression),
field("value", $.expression),
$.willset_didset_block
)
),
_expression_without_willset_didset: ($) =>
seq($._equal_sign, field("value", $._expression)),
seq($._equal_sign, field("value", $.expression)),
willset_didset_block: ($) =>
choice(
seq("{", $.willset_clause, optional($.didset_clause), "}"),
@@ -1445,7 +1454,7 @@ module.exports = grammar({
field("name", alias($.simple_identifier, $.type_identifier)),
optional($.type_parameters),
$._equal_sign,
field("value", $._type)
field("value", $.type)
),
function_declaration: ($) =>
prec.right(
@@ -1495,12 +1504,12 @@ module.exports = grammar({
_macro_signature: ($) =>
seq(
$._function_value_parameters,
optional(seq($._arrow_operator, $._unannotated_type))
optional(seq($._arrow_operator, $.unannotated_type))
),
macro_definition: ($) =>
seq(
$._equal_sign,
field("body", choice($._expression, $.external_macro_definition))
field("body", choice($.expression, $.external_macro_definition))
),
external_macro_definition: ($) =>
@@ -1521,7 +1530,7 @@ module.exports = grammar({
),
seq(
field("declaration_kind", "extension"),
field("name", $._unannotated_type),
field("name", $.unannotated_type),
optional($.type_parameters),
optional(seq(":", $._inheritance_specifiers)),
optional($.type_constraints),
@@ -1561,7 +1570,7 @@ module.exports = grammar({
seq(
optional($.type_parameter_modifiers),
$._type_parameter_possibly_packed,
optional(seq(":", $._type))
optional(seq(":", $.type))
),
_type_parameter_possibly_packed: ($) =>
choice(
@@ -1585,20 +1594,18 @@ module.exports = grammar({
repeat($.attribute),
field("constrained_type", $._constrained_type),
choice($._equal_sign, $._eq_eq),
field("must_equal", $._type)
field("must_equal", $.type)
),
_constrained_type: ($) =>
choice(
$.identifier,
seq(
$._unannotated_type,
optional(seq(".", sep1($.simple_identifier, ".")))
)
_constrained_type: ($) => choice($.identifier, $.nested_type_identifier),
nested_type_identifier: ($) =>
seq(
$.unannotated_type,
optional(seq(".", sep1($.simple_identifier, ".")))
),
_class_member_separator: ($) => choice($._semi, $.multiline_comment),
_class_member_declarations: ($) =>
seq(
sep1($._type_level_declaration, $._class_member_separator),
sep1($.type_level_declaration, $._class_member_separator),
optional($._class_member_separator)
),
_function_value_parameters: ($) =>
@@ -1609,7 +1616,7 @@ module.exports = grammar({
seq(
optional($.attribute),
$.parameter,
optional(seq($._equal_sign, field("default_value", $._expression)))
optional(seq($._equal_sign, field("default_value", $.expression)))
),
parameter: ($) =>
seq(
@@ -1623,16 +1630,15 @@ module.exports = grammar({
_non_constructor_function_decl: ($) =>
seq(
"func",
field("name", choice($.simple_identifier, $._referenceable_operator))
field("name", choice($.simple_identifier, $.referenceable_operator))
),
_referenceable_operator: ($) =>
referenceable_operator: ($) =>
choice(
$.custom_operator,
$._comparison_operator,
$._additive_operator,
$._multiplicative_operator,
$._equality_operator,
$._comparison_operator,
$._assignment_and_operator,
"++",
"--",
@@ -1665,9 +1671,9 @@ module.exports = grammar({
_async_modifier: ($) => token("async"),
throws: ($) => choice($._throws_keyword, $._rethrows_keyword),
throws_clause: ($) =>
seq($._throws_keyword, "(", field("type", $._unannotated_type), ")"),
seq($._throws_keyword, "(", field("type", $.unannotated_type), ")"),
enum_class_body: ($) =>
seq("{", repeat(choice($.enum_entry, $._type_level_declaration)), "}"),
seq("{", repeat(choice($.enum_entry, $.type_level_declaration)), "}"),
enum_entry: ($) =>
seq(
optional($.modifiers),
@@ -1685,7 +1691,7 @@ module.exports = grammar({
_enum_entry_suffix: ($) =>
choice(
field("data_contents", $.enum_type_parameters),
seq($._equal_sign, field("raw_value", $._expression))
seq($._equal_sign, field("raw_value", $.expression))
),
enum_type_parameters: ($) =>
seq(
@@ -1696,8 +1702,8 @@ module.exports = grammar({
optional(
seq(optional($.wildcard_pattern), $.simple_identifier, ":")
),
$._type,
optional(seq($._equal_sign, $._expression))
$.type,
optional(seq($._equal_sign, $.expression))
),
","
)
@@ -1719,16 +1725,10 @@ module.exports = grammar({
protocol_body: ($) =>
seq("{", optional($._protocol_member_declarations), "}"),
_protocol_member_declarations: ($) =>
seq(sep1($._protocol_member_declaration, $._semi), optional($._semi)),
_protocol_member_declaration: ($) =>
seq(sep1($.protocol_member_declaration, $._semi), optional($._semi)),
protocol_member_declaration: ($) =>
choice(
alias(
seq(
$._bodyless_function_declaration,
optional(field("body", $.function_body))
),
$.protocol_function_declaration
),
$.protocol_function_declaration,
$.init_declaration,
$.deinit_declaration,
$.protocol_property_declaration,
@@ -1736,6 +1736,11 @@ module.exports = grammar({
$.associatedtype_declaration,
$.subscript_declaration
),
protocol_function_declaration: ($) =>
seq(
$._bodyless_function_declaration,
optional(field("body", $.function_body))
),
init_declaration: ($) =>
prec.right(
seq(
@@ -1804,7 +1809,7 @@ module.exports = grammar({
seq(
choice("prefix", "infix", "postfix"),
"operator",
$._referenceable_operator,
$.referenceable_operator,
optional(seq(":", $.simple_identifier)),
optional($.deprecated_operator_declaration_body)
),
@@ -1831,9 +1836,9 @@ module.exports = grammar({
optional($.modifiers),
"associatedtype",
field("name", alias($.simple_identifier, $.type_identifier)),
optional(seq(":", field("must_inherit", $._type))),
optional(seq(":", field("must_inherit", $.type))),
optional($.type_constraints),
optional(seq($._equal_sign, field("default_value", $._type)))
optional(seq($._equal_sign, field("default_value", $.type)))
),
////////////////////////////////
// Attributes - https://docs.swift.org/swift-book/ReferenceManual/Attributes.html
@@ -1848,9 +1853,9 @@ module.exports = grammar({
_attribute_argument: ($) =>
choice(
// labeled function parameters, used in custom property wrappers
seq($.simple_identifier, ":", $._expression),
seq($.simple_identifier, ":", $.expression),
// Unlabeled function parameters, simple identifiers, or `*`
$._expression,
$.expression,
// References to param names (used in `@objc(foo:bar:)`)
repeat1(seq($.simple_identifier, ":")),
// Version restrictions (iOS 3.4.5, Swift 5.0.0)
@@ -1887,13 +1892,13 @@ module.exports = grammar({
choice(
$._universally_allowed_pattern,
$._binding_pattern,
$._expression
$.expression
),
optional($._quest)
),
_non_binding_pattern_with_expr: ($) =>
seq(
choice($._universally_allowed_pattern, $._expression),
choice($._universally_allowed_pattern, $.expression),
optional($._quest)
),
_direct_or_indirect_binding: ($) =>
@@ -1932,8 +1937,8 @@ module.exports = grammar({
),
_type_casting_pattern: ($) =>
choice(
seq("is", $._type),
seq(alias($._binding_pattern_no_expr, $.pattern), $._as, $._type)
seq("is", $.type),
seq(alias($._binding_pattern_no_expr, $.pattern), $._as, $.type)
),
_binding_pattern: ($) =>
seq(

View File

@@ -0,0 +1,728 @@
supertypes:
expression:
- additive_expression
- array_literal
- as_expression
- assignment
- await_expression
- bin_literal
- bitwise_operation
- boolean_literal
- call_expression
- check_expression
- comparison_expression
- conjunction_expression
- constructor_expression
- diagnostic
- dictionary_literal
- directive
- disjunction_expression
- equality_expression
- fully_open_range
- hex_literal
- if_statement
- infix_expression
- integer_literal
- key_path_expression
- key_path_string_expression
- lambda_literal
- line_string_literal
- macro_invocation
- multi_line_string_literal
- multiplicative_expression
- navigation_expression
- "nil"
- nil_coalescing_expression
- oct_literal
- open_end_range_expression
- open_start_range_expression
- optional_chain_marker
- playground_literal
- postfix_expression
- prefix_expression
- range_expression
- raw_string_literal
- real_literal
- referenceable_operator
- regex_literal
- selector_expression
- self_expression
- simple_identifier
- special_literal
- super_expression
- switch_statement
- ternary_expression
- try_expression
- tuple_expression
- value_pack_expansion
- value_parameter_pack
global_declaration:
- associatedtype_declaration
- class_declaration
- function_declaration
- import_declaration
- init_declaration
- macro_declaration
- operator_declaration
- precedence_group_declaration
- property_declaration
- protocol_declaration
- typealias_declaration
local_declaration:
- class_declaration
- function_declaration
- property_declaration
- typealias_declaration
protocol_member_declaration:
- associatedtype_declaration
- deinit_declaration
- init_declaration
- protocol_function_declaration
- protocol_property_declaration
- subscript_declaration
- typealias_declaration
type_level_declaration:
- associatedtype_declaration
- class_declaration
- deinit_declaration
- function_declaration
- import_declaration
- init_declaration
- operator_declaration
- precedence_group_declaration
- property_declaration
- protocol_declaration
- subscript_declaration
- typealias_declaration
unannotated_type:
- array_type
- dictionary_type
- existential_type
- function_type
- metatype
- opaque_type
- optional_type
- protocol_composition_type
- suppressed_constraint
- tuple_type
- type_pack_expansion
- type_parameter_pack
- user_type
named:
additive_expression:
lhs: expression
op: ["+", "-"]
rhs: expression
array_literal:
element*: expression
array_type:
element: type
as_expression:
$children: as_operator
expr: expression
type: type
as_operator:
assignment:
operator: ["%=", "*=", "+=", "-=", "/=", "="]
result: expression
target: directly_assignable_expression
associatedtype_declaration:
$children*: [modifiers, type_constraints]
default_value?: type
must_inherit?: type
name: type_identifier
attribute:
$children+: [expression, user_type]
availability_condition:
$children*: [identifier, integer_literal]
await_expression:
$children?: expression
expr?: expression
bang:
bin_literal:
bitwise_operation:
lhs: expression
op: ["&", "<<", ">>", "^", "|"]
rhs: expression
boolean_literal:
call_expression:
$children+: [call_suffix, expression]
call_suffix:
$children+: [lambda_literal, value_arguments]
name*: simple_identifier
capture_list:
$children+: capture_list_item
capture_list_item:
$children?: ownership_modifier
name: [self_expression, simple_identifier]
value?: expression
catch_block:
$children+: [catch_keyword, statements, where_clause]
error?: pattern
catch_keyword:
check_expression:
op: "is"
target: expression
type: type
class_body:
$children*: [multiline_comment, type_level_declaration]
class_declaration:
$children*: [attribute, inheritance_modifier, inheritance_specifier, modifiers, ownership_modifier, property_behavior_modifier, type_constraints, type_parameters]
body: [class_body, enum_class_body]
declaration_kind: ["actor", "class", "enum", "extension", "struct"]
name: [type_identifier, unannotated_type]
comment:
comparison_expression:
lhs: expression
op: ["<", "<=", ">", ">="]
rhs: expression
computed_getter:
$children+: [attribute, getter_specifier, statements]
computed_modify:
$children+: [attribute, modify_specifier, statements]
computed_property:
$children*: [computed_getter, computed_modify, computed_setter, statements]
computed_setter:
$children+: [attribute, setter_specifier, simple_identifier, statements]
conjunction_expression:
lhs: expression
op: "&&"
rhs: expression
constructor_expression:
$children: constructor_suffix
constructed_type: [array_type, dictionary_type, user_type]
constructor_suffix:
$children+: [lambda_literal, value_arguments]
name*: simple_identifier
control_transfer_statement:
$children*: [expression, throw_keyword]
result?: expression
custom_operator:
default_keyword:
deinit_declaration:
$children?: modifiers
body: function_body
deprecated_operator_declaration_body:
$children*: [bin_literal, boolean_literal, hex_literal, integer_literal, line_string_literal, multi_line_string_literal, oct_literal, raw_string_literal, real_literal, regex_literal, simple_identifier]
diagnostic:
dictionary_literal:
key*: expression
value*: expression
dictionary_type:
key: type
value: type
didset_clause:
$children*: [modifiers, simple_identifier, statements]
directive:
$children*: [boolean_literal, integer_literal, simple_identifier]
directly_assignable_expression:
$children: expression
disjunction_expression:
lhs: expression
op: "||"
rhs: expression
do_statement:
$children*: [catch_block, statements]
else:
enum_class_body:
$children*: [enum_entry, type_level_declaration]
enum_entry:
$children?: modifiers
data_contents*: enum_type_parameters
name+: simple_identifier
raw_value*: expression
enum_type_parameters:
$children*: [expression, type, wildcard_pattern]
equality_constraint:
$children*: attribute
constrained_type: [identifier, nested_type_identifier]
must_equal: type
equality_expression:
lhs: expression
op: ["!=", "!==", "==", "==="]
rhs: expression
existential_type:
$children: unannotated_type
external_macro_definition:
$children: value_arguments
for_statement:
$children*: [statements, try_operator, type_annotation, where_clause]
collection: expression
item: pattern
fully_open_range:
function_body:
$children?: statements
function_declaration:
$children*: [attribute, inheritance_modifier, modifiers, ownership_modifier, parameter, property_behavior_modifier, throws, throws_clause, type_constraints, type_parameters]
body: function_body
default_value*: expression
name: [referenceable_operator, simple_identifier]
return_type?: [implicitly_unwrapped_type, type]
function_modifier:
function_type:
$children?: [throws, throws_clause]
params: unannotated_type
return_type: type
getter_specifier:
$children*: [mutation_modifier, throws, throws_clause]
guard_statement:
$children+: [else, statements]
condition+: if_condition
hex_literal:
identifier:
$children+: simple_identifier
if_condition:
$children: [availability_condition, expression, if_let_binding]
if_let_binding:
$children*: [expression, pattern, type, type_annotation, user_type, value_binding_pattern, where_clause, wildcard_pattern]
bound_identifier?: simple_identifier
if_statement:
$children*: [else, if_statement, statements]
condition+: if_condition
implicitly_unwrapped_type:
$children: type
import_declaration:
$children+: [identifier, modifiers]
infix_expression:
lhs: expression
op: custom_operator
rhs: expression
inheritance_constraint:
$children*: attribute
constrained_type: [identifier, nested_type_identifier]
inherits_from: [implicitly_unwrapped_type, type]
inheritance_modifier:
inheritance_specifier:
inherits_from: [function_type, suppressed_constraint, user_type]
init_declaration:
$children*: [attribute, bang, modifiers, parameter, throws, throws_clause, type_constraints, type_parameters]
body?: function_body
default_value*: expression
name: "init"
integer_literal:
interpolated_expression:
$children?: type_modifiers
name?: value_argument_label
reference_specifier*: value_argument_label
value?: expression
key_path_expression:
$children*: [array_type, bang, dictionary_type, simple_identifier, type_arguments, type_identifier, value_argument]
key_path_string_expression:
$children: expression
lambda_function_type:
$children*: [lambda_function_type_parameters, throws, throws_clause]
return_type?: [implicitly_unwrapped_type, type]
lambda_function_type_parameters:
$children+: lambda_parameter
lambda_literal:
$children*: [attribute, statements]
captures?: capture_list
type?: lambda_function_type
lambda_parameter:
$children?: [parameter_modifiers, self_expression]
external_name?: simple_identifier
name?: simple_identifier
type?: [implicitly_unwrapped_type, type]
line_str_text:
line_string_literal:
interpolation*: interpolated_expression
text*: [line_str_text, str_escaped_char]
macro_declaration:
$children+: [attribute, modifiers, parameter, simple_identifier, type_constraints, type_parameters, unannotated_type]
default_value*: expression
definition?: macro_definition
macro_definition:
body: [expression, external_macro_definition]
macro_invocation:
$children+: [call_suffix, simple_identifier, type_parameters]
member_modifier:
metatype:
$children: unannotated_type
modifiers:
$children+: [attribute, function_modifier, inheritance_modifier, member_modifier, mutation_modifier, ownership_modifier, parameter_modifier, property_behavior_modifier, property_modifier, visibility_modifier]
modify_specifier:
$children?: mutation_modifier
multi_line_str_text:
multi_line_string_literal:
interpolation*: interpolated_expression
text*: ["\"", multi_line_str_text, str_escaped_char]
multiline_comment:
multiplicative_expression:
lhs: expression
op: ["%", "*", "/"]
rhs: expression
mutation_modifier:
navigation_expression:
suffix: navigation_suffix
target+: ["(", ")", array_type, dictionary_type, existential_type, expression, opaque_type, user_type]
navigation_suffix:
suffix: [integer_literal, simple_identifier]
nested_type_identifier:
$children+: [simple_identifier, unannotated_type]
nil_coalescing_expression:
if_nil: expression
value: expression
oct_literal:
opaque_type:
$children: unannotated_type
open_end_range_expression:
start: expression
open_start_range_expression:
end: expression
operator_declaration:
$children+: [deprecated_operator_declaration_body, referenceable_operator, simple_identifier]
optional_chain_marker:
$children: expression
optional_type:
wrapped: [array_type, dictionary_type, tuple_type, user_type]
ownership_modifier:
parameter:
$children?: parameter_modifiers
external_name?: simple_identifier
name: simple_identifier
type: [implicitly_unwrapped_type, type]
parameter_modifier:
parameter_modifiers:
$children+: parameter_modifier
pattern:
$children*: [expression, pattern, type, user_type, value_binding_pattern, wildcard_pattern]
bound_identifier?: simple_identifier
playground_literal:
$children+: expression
postfix_expression:
operation: ["++", "--", bang]
target: expression
precedence_group_attribute:
$children+: [boolean_literal, simple_identifier]
precedence_group_attributes:
$children+: precedence_group_attribute
precedence_group_declaration:
$children+: [precedence_group_attributes, simple_identifier]
prefix_expression:
operation: ["&", "+", "++", "-", "--", ".", bang, custom_operator, "~"]
target: expression
property_behavior_modifier:
property_declaration:
$children*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier, type_annotation, type_constraints, value_binding_pattern, willset_didset_block]
computed_value*: computed_property
name+: pattern
value*: expression
property_modifier:
protocol_body:
$children*: protocol_member_declaration
protocol_composition_type:
$children+: unannotated_type
protocol_declaration:
$children*: [attribute, inheritance_specifier, modifiers, type_constraints, type_parameters]
body: protocol_body
declaration_kind: "protocol"
name: type_identifier
protocol_function_declaration:
$children*: [attribute, modifiers, parameter, throws, throws_clause, type_constraints, type_parameters]
body?: function_body
default_value*: expression
name: [referenceable_operator, simple_identifier]
return_type?: [implicitly_unwrapped_type, type]
protocol_property_declaration:
$children+: [modifiers, protocol_property_requirements, type_annotation, type_constraints]
name: pattern
protocol_property_requirements:
$children*: [getter_specifier, setter_specifier]
range_expression:
end: expression
op: ["...", "..<"]
start: expression
raw_str_continuing_indicator:
raw_str_end_part:
raw_str_interpolation:
$children: raw_str_interpolation_start
interpolation+: interpolated_expression
raw_str_interpolation_start:
raw_str_part:
raw_string_literal:
$children*: raw_str_continuing_indicator
interpolation*: raw_str_interpolation
text+: [raw_str_end_part, raw_str_part]
real_literal:
referenceable_operator:
$children?: [bang, custom_operator]
regex_literal:
repeat_while_statement:
$children?: statements
condition+: if_condition
selector_expression:
$children: expression
self_expression:
setter_specifier:
$children?: mutation_modifier
shebang_line:
simple_identifier:
source_file:
$children*: [do_statement, expression, for_statement, global_declaration, guard_statement, repeat_while_statement, shebang_line, statement_label, throw_keyword, while_statement]
special_literal:
statement_label:
statements:
$children+: [control_transfer_statement, do_statement, expression, for_statement, guard_statement, local_declaration, repeat_while_statement, statement_label, while_statement]
str_escaped_char:
subscript_declaration:
$children+: [attribute, computed_property, modifiers, parameter, type_constraints, type_parameters]
default_value*: expression
return_type?: [implicitly_unwrapped_type, type]
super_expression:
suppressed_constraint:
suppressed: type_identifier
switch_entry:
$children+: [default_keyword, expression, modifiers, statements, switch_pattern, where_keyword]
switch_pattern:
$children: pattern
switch_statement:
$children*: switch_entry
expr: expression
ternary_expression:
condition: expression
if_false: expression
if_true: expression
throw_keyword:
throws:
throws_clause:
type: unannotated_type
try_expression:
$children: try_operator
expr: expression
try_operator:
tuple_expression:
name*: simple_identifier
value+: expression
tuple_type:
$children?: tuple_type_item
element*: tuple_type_item
tuple_type_item:
$children*: [dictionary_type, existential_type, opaque_type, parameter_modifiers, wildcard_pattern]
name?: simple_identifier
type?: type
type:
modifiers?: type_modifiers
name: unannotated_type
type_annotation:
type: [implicitly_unwrapped_type, type]
type_arguments:
$children+: type
type_constraint:
$children: [equality_constraint, inheritance_constraint]
type_constraints:
$children+: [type_constraint, where_keyword]
type_identifier:
type_modifiers:
$children+: attribute
type_pack_expansion:
$children: unannotated_type
type_parameter:
$children+: [type, type_identifier, type_parameter_modifiers, type_parameter_pack]
type_parameter_modifiers:
$children+: attribute
type_parameter_pack:
$children: unannotated_type
type_parameters:
$children+: [type_constraints, type_parameter]
typealias_declaration:
$children*: [attribute, inheritance_modifier, modifiers, ownership_modifier, property_behavior_modifier, type_parameters]
name: type_identifier
value: type
user_type:
$children+: [type_arguments, type_identifier]
value_argument:
$children?: type_modifiers
name?: value_argument_label
reference_specifier*: value_argument_label
value?: expression
value_argument_label:
$children: simple_identifier
value_arguments:
$children*: value_argument
value_binding_pattern:
mutability: ["let", "var"]
value_pack_expansion:
$children: expression
value_parameter_pack:
$children: expression
visibility_modifier:
where_clause:
$children+: [expression, where_keyword]
where_keyword:
while_statement:
$children?: statements
condition+: if_condition
wildcard_pattern:
willset_clause:
$children*: [modifiers, simple_identifier, statements]
willset_didset_block:
$children+: [didset_clause, willset_clause]
unnamed:
- "?"
- "!"
- "!="
- "!=="
- "\""
- "\"\"\""
- "#"
- "#else"
- "#elseif"
- "#endif"
- "#if"
- "%"
- "%="
- "&"
- "&&"
- "("
- ")"
- "*"
- "*="
- "+"
- "++"
- "+="
- ","
- "-"
- "--"
- "-="
- "->"
- "."
- "..."
- "..<"
- "/"
- "/="
- ":"
- ";"
- "<"
- "<<"
- "<="
- "="
- "=="
- "==="
- ">"
- ">="
- ">>"
- "?"
- "??"
- "@"
- "@autoclosure"
- "@escaping"
- "Protocol"
- "Type"
- "["
- "\\"
- "\\("
- "]"
- "^"
- "^{"
- "_modify"
- "actor"
- "any"
- "arch"
- "as"
- "as!"
- "as?"
- "associatedtype"
- "async"
- "available"
- "await"
- "borrowing"
- "break"
- "canImport"
- "case"
- "class"
- "colorLiteral"
- "column"
- "compiler"
- "consuming"
- "continue"
- "convenience"
- "deinit"
- "didSet"
- "distributed"
- "do"
- "dsohandle"
- "dynamic"
- "each"
- "enum"
- "extension"
- "externalMacro"
- "fallthrough"
- "false"
- "file"
- "fileID"
- "fileLiteral"
- "filePath"
- "fileprivate"
- "final"
- "for"
- "func"
- "function"
- "get"
- "getter:"
- "guard"
- "if"
- "imageLiteral"
- "import"
- "in"
- "indirect"
- "infix"
- "init"
- "inout"
- "internal"
- "is"
- "keyPath"
- "lazy"
- "let"
- "line"
- "macro"
- "mutating"
- "nil"
- "nonisolated"
- "nonmutating"
- "open"
- "operator"
- "optional"
- "os"
- "override"
- "package"
- "postfix"
- "precedencegroup"
- "prefix"
- "private"
- "protocol"
- "public"
- "repeat"
- "required"
- "return"
- "selector"
- "self"
- "set"
- "setter:"
- "some"
- "static"
- "struct"
- "subscript"
- "super"
- "swift"
- "switch"
- "targetEnvironment"
- "true"
- "try"
- "typealias"
- "u"
- "unavailable"
- "unowned"
- "unowned(safe)"
- "unowned(unsafe)"
- "var"
- "weak"
- "while"
- "willSet"
- "yield"
- "{"
- "|"
- "||"
- "}"
- "~"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
#!/bin/bash
# Regenerate the vendored tree-sitter-swift parser tables from grammar.js,
# then refresh the human-readable node-types.yml companion file.
#
# Run this after editing
# unified/extractor/tree-sitter-swift/grammar.js so that:
# * src/parser.c, src/grammar.json, src/node-types.json (and the
# src/tree_sitter/*.h headers) reflect the current grammar; and
# * node-types.yml shows the same information in a form that's
# pleasant to review in PR diffs.
#
# Requirements: tree-sitter CLI on PATH, and a working cargo toolchain.
set -euo pipefail
cd "$(dirname "$0")/.."
SWIFT_DIR="extractor/tree-sitter-swift"
(
cd "$SWIFT_DIR"
tree-sitter generate
)
# Build yeast's node_types_yaml binary and use it to convert the freshly
# generated src/node-types.json into the human-readable node-types.yml.
cargo run --release --quiet -p yeast --bin node_types_yaml -- \
--from-json "$SWIFT_DIR/src/node-types.json" > "$SWIFT_DIR/node-types.yml"
echo "Regenerated $SWIFT_DIR/{src/parser.c,src/grammar.json,src/node-types.json,node-types.yml}"