@@ -16,6 +16,39 @@ mod languages;
1616/// A real `swift-syntax-rs` JSON dump of the Swift source `let x = 1`.
1717const LET_X_JSON : & str = include_str ! ( "fixtures/let_x.swiftsyntax.json" ) ;
1818
19+ const IMPORT_FOUNDATION_JSON : & str = r#"{
20+ "kind": "sourceFile",
21+ "range": {"start":{"offset":0,"line":1,"column":1},"end":{"offset":17,"line":1,"column":18}},
22+ "statements": [
23+ {
24+ "kind": "codeBlockItem",
25+ "range": {"start":{"offset":0,"line":1,"column":1},"end":{"offset":17,"line":1,"column":18}},
26+ "item": {
27+ "kind": "importDecl",
28+ "range": {"start":{"offset":0,"line":1,"column":1},"end":{"offset":17,"line":1,"column":18}},
29+ "importKeyword": {
30+ "kind": "token",
31+ "tokenKind": "keyword(SwiftSyntax.Keyword.import)",
32+ "text": "import",
33+ "range": {"start":{"offset":0,"line":1,"column":1},"end":{"offset":6,"line":1,"column":7}}
34+ },
35+ "path": [
36+ {
37+ "kind": "importPathComponent",
38+ "range": {"start":{"offset":7,"line":1,"column":8},"end":{"offset":17,"line":1,"column":18}},
39+ "name": {
40+ "kind": "token",
41+ "tokenKind": "identifier(\"Foundation\")",
42+ "text": "Foundation",
43+ "range": {"start":{"offset":7,"line":1,"column":8},"end":{"offset":17,"line":1,"column":18}}
44+ }
45+ }
46+ ]
47+ }
48+ }
49+ ]
50+ }"# ;
51+
1952#[ test]
2053fn swift_syntax_json_runs_through_the_desugarer ( ) {
2154 let lang = languages:: all_language_specs ( )
@@ -47,3 +80,37 @@ fn swift_syntax_json_runs_through_the_desugarer() {
4780 assert ! ( dump. contains( "top_level" ) , "unexpected dump: {dump}" ) ;
4881 assert ! ( dump. contains( "block" ) , "unexpected dump: {dump}" ) ;
4982}
83+
84+ #[ test]
85+ fn import_name_expr_location_excludes_import_keyword ( ) {
86+ let lang = languages:: all_language_specs ( )
87+ . into_iter ( )
88+ . find ( |l| l. file_globs . iter ( ) . any ( |g| g. contains ( "swift" ) ) )
89+ . expect ( "swift language spec" ) ;
90+ let desugarer = lang. desugarer . as_ref ( ) ;
91+ let adapted = languages:: swift_adapter:: json_to_ast ( IMPORT_FOUNDATION_JSON )
92+ . expect ( "adapter should succeed" ) ;
93+
94+ let desugared = desugarer
95+ . run_from_ast ( adapted. ast )
96+ . expect ( "desugaring an import should not error" ) ;
97+
98+ let name_expr_ids: Vec < yeast:: Id > = desugared
99+ . reachable_node_ids ( )
100+ . into_iter ( )
101+ . filter ( |& id| {
102+ desugared
103+ . get_node ( id)
104+ . is_some_and ( |node| node. kind_name ( ) == "name_expr" )
105+ } )
106+ . collect ( ) ;
107+ assert_eq ! (
108+ name_expr_ids. len( ) ,
109+ 1 ,
110+ "expected exactly one reachable name_expr"
111+ ) ;
112+
113+ let name_expr = desugared. get_node ( name_expr_ids[ 0 ] ) . unwrap ( ) ;
114+ assert_eq ! ( name_expr. start_byte( ) , 7 ) ;
115+ assert_eq ! ( name_expr. end_byte( ) , 17 ) ;
116+ }
0 commit comments