@@ -61,7 +61,8 @@ static const char *lookup_url_builder(const CBMExtractCtx *ctx, const char *name
6161static int is_string_like (const char * kind ) {
6262 return (strcmp (kind , "string" ) == 0 || strcmp (kind , "string_literal" ) == 0 ||
6363 strcmp (kind , "interpreted_string_literal" ) == 0 ||
64- strcmp (kind , "raw_string_literal" ) == 0 || strcmp (kind , "string_content" ) == 0 );
64+ strcmp (kind , "raw_string_literal" ) == 0 || strcmp (kind , "string_content" ) == 0 ||
65+ strcmp (kind , "line_string_literal" ) == 0 );
6566}
6667
6768/* Strip surrounding quotes from a string, return arena-allocated copy */
@@ -2286,6 +2287,18 @@ static const char *extract_url_or_topic_arg(CBMExtractCtx *ctx, TSNode args) {
22862287 if (strcmp (ts_node_type (arg ), "argument" ) == 0 && ts_node_named_child_count (arg ) > 0 ) {
22872288 arg = ts_node_named_child (arg , 0 );
22882289 }
2290+ /* Swift wraps each argument in a value_argument that may lead with its
2291+ * label, so `data(from: url)` would otherwise yield the label `from`
2292+ * rather than the value. Step past a leading value_argument_label. */
2293+ if (strcmp (ts_node_type (arg ), "value_argument" ) == 0 &&
2294+ ts_node_named_child_count (arg ) > 0 ) {
2295+ TSNode val = ts_node_named_child (arg , 0 );
2296+ if (strcmp (ts_node_type (val ), "value_argument_label" ) == 0 &&
2297+ ts_node_named_child_count (arg ) > 1 ) {
2298+ val = ts_node_named_child (arg , 1 );
2299+ }
2300+ arg = val ;
2301+ }
22892302 const char * ak = ts_node_type (arg );
22902303
22912304 if (strcmp (ak , "keyword_argument" ) == 0 || strcmp (ak , "pair" ) == 0 ) {
@@ -3080,6 +3093,19 @@ static TSNode objectscript_call_args(TSNode node) {
30803093 : cbm_find_child_by_kind (macro_function , "method_args" );
30813094}
30823095
3096+ /* Swift models a call as a target expression plus a call_suffix, and its grammar
3097+ * declares no "arguments" field at all, so the generic field lookup finds
3098+ * nothing for every Swift call. Reach the argument list through the suffix
3099+ * instead. A trailing closure has a call_suffix with no value_arguments, which
3100+ * returns a null node and leaves the call without a string argument, as before. */
3101+ static TSNode swift_call_args (TSNode node ) {
3102+ TSNode suffix = cbm_find_child_by_kind (node , "call_suffix" );
3103+ if (ts_node_is_null (suffix )) {
3104+ return (TSNode ){0 };
3105+ }
3106+ return cbm_find_child_by_kind (suffix , "value_arguments" );
3107+ }
3108+
30833109static bool node_has_token (TSNode node , const char * token ) {
30843110 uint32_t count = ts_node_child_count (node );
30853111 for (uint32_t i = 0 ; i < count ; i ++ ) {
@@ -3676,6 +3702,10 @@ CBMInvocationDescriptor handle_calls(CBMExtractCtx *ctx, TSNode node, const CBML
36763702 if (ts_node_is_null (args ) && is_objectscript_language (ctx -> language )) {
36773703 args = objectscript_call_args (node );
36783704 }
3705+ // Swift has no "arguments" field either; its args hang off call_suffix.
3706+ if (ts_node_is_null (args ) && ctx -> language == CBM_LANG_SWIFT ) {
3707+ args = swift_call_args (node );
3708+ }
36793709 if (!ts_node_is_null (args )) {
36803710 call .first_string_arg = extract_url_or_topic_arg (ctx , args );
36813711 /* #952: routes registered inside Laravel `prefix()->group()`
0 commit comments