@@ -31,6 +31,10 @@ var ScopeNodes = []string{
3131 "for_in_statement" ,
3232 "for_of_statement" ,
3333 "program" ,
34+ "arrow_function" ,
35+ "class_body" ,
36+ // "class_declaration",
37+ "method_definition" ,
3438}
3539
3640func (ts * TsScopeBuilder ) NodeCreatesScope (node * sitter.Node ) bool {
@@ -39,7 +43,14 @@ func (ts *TsScopeBuilder) NodeCreatesScope(node *sitter.Node) bool {
3943
4044func (ts * TsScopeBuilder ) DeclaresVariable (node * sitter.Node ) bool {
4145 typ := node .Type ()
42- return typ == "variable_declarator" || typ == "import_clause" || typ == "import_specifier"
46+ return typ == "variable_declarator" ||
47+ typ == "import_clause" ||
48+ typ == "import_specifier" ||
49+ typ == "formal_parameters" ||
50+ typ == "function_declaration" ||
51+ typ == "method_definition" ||
52+ typ == "class_declaration" ||
53+ typ == "export_statement" || typ == "assignment_expression" || typ == "public_field_definition"
4354}
4455
4556func (ts * TsScopeBuilder ) scanDecl (idOrPattern , declarator * sitter.Node , decls []* Variable ) []* Variable {
@@ -135,6 +146,10 @@ func (ts *TsScopeBuilder) CollectVariables(node *sitter.Node) []*Variable {
135146 lhs := node .ChildByFieldName ("name" )
136147 return ts .scanDecl (lhs , node , declaredVars )
137148
149+ case "assignment_expression" :
150+ lhs := node .ChildByFieldName ("left" )
151+ return ts .scanDecl (lhs , node , declaredVars )
152+
138153 case "function_declaration" :
139154 name := node .ChildByFieldName ("name" )
140155 // skipcq: TCV-001
@@ -150,6 +165,40 @@ func (ts *TsScopeBuilder) CollectVariables(node *sitter.Node) []*Variable {
150165
151166 case "formal_parameters" :
152167 // TODO
168+ for i := 0 ; i < int (node .NamedChildCount ()); i ++ {
169+ param := node .NamedChild (i )
170+ if param == nil {
171+ continue
172+ }
173+
174+ var identifier * sitter.Node
175+ if param .Type () == "identifier" {
176+ identifier = param
177+ } else if param .Type () == "required_parameter" || param .Type () == "optional_parameter" {
178+ // Look for pattern which might be identifier or destructuring
179+ pattern := param .ChildByFieldName ("pattern" )
180+ if pattern != nil && pattern .Type () == "identifier" {
181+ identifier = pattern
182+ }
183+ // TODO: Handle destructuring patterns within parameters if needed by calling scanDecl
184+ } else if param .Type () == "assignment_pattern" {
185+ // Parameter with default value: function foo(x = 1)
186+ left := param .ChildByFieldName ("left" )
187+ if left != nil && left .Type () == "identifier" {
188+ identifier = left
189+ }
190+ // TODO: Handle destructuring patterns within parameters if needed by calling scanDecl
191+ }
192+ // TODO: Handle rest parameter (...)+
193+ if identifier != nil {
194+ declaredVars = append (declaredVars , & Variable {
195+ Kind : VarKindParameter ,
196+ Name : identifier .Content (ts .source ),
197+ DeclNode : param , // Use the parameter node itself (or identifier) as DeclNode
198+ })
199+ }
200+ // Add handling for destructuring patterns here if necessary using scanDecl
201+ }
153202
154203 case "import_specifier" :
155204 // import { <name> } from ...
@@ -166,6 +215,36 @@ func (ts *TsScopeBuilder) CollectVariables(node *sitter.Node) []*Variable {
166215 DeclNode : defaultImport ,
167216 })
168217 }
218+
219+ case "class_declaration" :
220+ className := node .ChildByFieldName ("name" )
221+ if className != nil {
222+ declaredVars = append (declaredVars , & Variable {
223+ Kind : VarKindClass ,
224+ Name : className .Content (ts .source ),
225+ DeclNode : className ,
226+ })
227+ }
228+
229+ case "method_definition" :
230+ methodName := node .ChildByFieldName ("name" )
231+ if methodName != nil {
232+ declaredVars = append (declaredVars , & Variable {
233+ Kind : VarKindFunction ,
234+ Name : methodName .Content (ts .source ),
235+ DeclNode : methodName ,
236+ })
237+ }
238+
239+ case "public_field_definition" :
240+ fieldName := node .ChildByFieldName ("name" )
241+ if fieldName != nil {
242+ declaredVars = append (declaredVars , & Variable {
243+ Kind : VarKindVariable ,
244+ Name : fieldName .Content (ts .source ),
245+ DeclNode : fieldName ,
246+ })
247+ }
169248 }
170249
171250 return declaredVars
@@ -232,6 +311,7 @@ func (ts *TsScopeBuilder) OnNodeEnter(node *sitter.Node, scope *Scope) {
232311 }
233312 variable .Refs = append (variable .Refs , ref )
234313 }
314+
235315}
236316
237317func (ts * TsScopeBuilder ) OnNodeExit (node * sitter.Node , scope * Scope ) {
@@ -254,4 +334,70 @@ func (ts *TsScopeBuilder) OnNodeExit(node *sitter.Node, scope *Scope) {
254334 variable .Refs = append (variable .Refs , ref )
255335 }
256336 }
337+ if node .Type () == "export_statement" {
338+ // Handle named exports: export { foo, bar as baz };
339+ exportClause := ChildrenOfType (node , "export_clause" )
340+
341+ for _ , clause := range exportClause {
342+ var varName string
343+ exportSpecifier := ChildrenOfType (clause , "export_specifier" )
344+ if len (exportSpecifier ) == 0 {
345+ continue
346+ }
347+ for _ , specifier := range exportSpecifier {
348+ name := specifier .ChildByFieldName ("name" )
349+ if name == nil {
350+ continue
351+ }
352+ if name .Type () == "identifier" {
353+ varName = name .Content (ts .source )
354+ }
355+ variable := scope .Lookup (varName )
356+ if variable != nil {
357+ variable .Exported = true
358+ }
359+ }
360+
361+ }
362+
363+ // Handle direct exports: export const foo = 123;
364+ declaration := node .ChildByFieldName ("declaration" )
365+ if declaration != nil {
366+ if declaration .Type () == "lexical_declaration" {
367+ // Handle variable declarations: export const foo = 123, bar = 456;
368+ declarators := ChildrenOfType (declaration , "variable_declarator" )
369+ for _ , declarator := range declarators {
370+ name := declarator .ChildByFieldName ("name" )
371+ if name != nil && name .Type () == "identifier" {
372+ varName := name .Content (ts .source )
373+
374+ variable := scope .Lookup (varName )
375+ if variable != nil {
376+ variable .Exported = true
377+ }
378+ }
379+ }
380+ } else if declaration .Type () == "function_declaration" || declaration .Type () == "class_declaration" {
381+ // Handle direct function/class exports: export function foo() {}
382+ name := declaration .ChildByFieldName ("name" )
383+ if name != nil {
384+ varName := name .Content (ts .source )
385+ variable := scope .Lookup (varName )
386+ if variable != nil {
387+ variable .Exported = true
388+ }
389+ }
390+ }
391+ }
392+
393+ // Handle default exports: export default foo;
394+ defaultExport := node .ChildByFieldName ("value" )
395+ if defaultExport != nil && defaultExport .Type () == "identifier" {
396+ varName := defaultExport .Content (ts .source )
397+ variable := scope .Lookup (varName )
398+ if variable != nil {
399+ variable .Exported = true
400+ }
401+ }
402+ }
257403}
0 commit comments