From ed56121adf854cf193c613856994dd5e6e7040d8 Mon Sep 17 00:00:00 2001 From: kelmith Date: Tue, 25 Aug 2026 23:41:28 +0530 Subject: [PATCH 1/3] fix: capture private class methods and arrow-fields in TS --- ast/src/lang/queries/react_ts.rs | 10 +++- .../testing/typescript/src/private-methods.ts | 53 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 ast/src/testing/typescript/src/private-methods.ts diff --git a/ast/src/lang/queries/react_ts.rs b/ast/src/lang/queries/react_ts.rs index 048327209..f4392c387 100644 --- a/ast/src/lang/queries/react_ts.rs +++ b/ast/src/lang/queries/react_ts.rs @@ -335,7 +335,10 @@ impl Stack for TypeScriptReact { ) (method_definition - name: (property_identifier) @{FUNCTION_NAME} (#not-eq? @{FUNCTION_NAME} "render") + name: [ + (property_identifier) + (private_property_identifier) + ] @{FUNCTION_NAME} (#not-eq? @{FUNCTION_NAME} "render") parameters: (formal_parameters)? @{ARGUMENTS} return_type: (type_annotation)? @{RETURN_TYPES} ) @{FUNCTION_DEFINITION} @@ -359,7 +362,10 @@ impl Stack for TypeScriptReact { ) @{FUNCTION_DEFINITION} (public_field_definition - name: (property_identifier) @{FUNCTION_NAME} + name: [ + (property_identifier) + (private_property_identifier) + ] @{FUNCTION_NAME} value: [ (function_expression parameters: (formal_parameters)? @{ARGUMENTS} diff --git a/ast/src/testing/typescript/src/private-methods.ts b/ast/src/testing/typescript/src/private-methods.ts new file mode 100644 index 000000000..70cbce56e --- /dev/null +++ b/ast/src/testing/typescript/src/private-methods.ts @@ -0,0 +1,53 @@ +// Deep coverage for private (#-prefixed) class members. +// Every private-method FORM should be captured as a Function node whose name +// keeps the leading '#'. A private field with a non-function value must NOT +// become a Function. Calls through a `this` receiver (this.#x()) are a separate +// limitation and are intentionally not asserted as Calls edges here. + +// @ast node: Class "TokenVault" +export class TokenVault { + // non-function private field — must NOT be captured as a Function + #secret = "seed"; + + // @ast node: Function "unlock" + unlock(challenge: string): boolean { + return this.#derive(challenge) === this.#secret; + } + + // private instance method + // @ast node: Function "#derive" + #derive(salt: string): string { + return salt + this.#secret; + } + + // async private method + // @ast node: Function "#rotate" + async #rotate(): Promise { + this.#secret = await Promise.resolve(this.#derive("next")); + } + + // static private method + // @ast node: Function "#hash" + static #hash(input: string): string { + return input.split("").reverse().join(""); + } + + // private arrow-function field + // @ast node: Function "#onChange" + #onChange = (value: string): void => { + this.#secret = value; + }; +} + +// @ast node: Class "RequestSigner" +export class RequestSigner { + // @ast node: Function "sign" + sign(payload: string): string { + return this.#compute(payload); + } + + // @ast node: Function "#compute" + #compute(payload: string): string { + return payload.length.toString(); + } +} From dcf294b9d65835caa7bc8939e7d317888a9bf9a7 Mon Sep 17 00:00:00 2001 From: kelmith Date: Tue, 25 Aug 2026 23:54:04 +0530 Subject: [PATCH 2/3] test: update typescript coverage counts for private-methods fixture --- ast/src/testing/coverage/typescript.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ast/src/testing/coverage/typescript.rs b/ast/src/testing/coverage/typescript.rs index 1d4049a9a..c61fdca50 100644 --- a/ast/src/testing/coverage/typescript.rs +++ b/ast/src/testing/coverage/typescript.rs @@ -74,7 +74,7 @@ async fn test_btreemap_graph_structure() -> Result<()> { assert_eq!(endpoints.len(), 22); let functions = graph.find_nodes_by_type(NodeType::Function); - assert_eq!(functions.len(), 68); + assert_eq!(functions.len(), 75); let unit_tests = graph.find_nodes_by_type(NodeType::UnitTest); assert_eq!(unit_tests.len(), 8); @@ -86,7 +86,7 @@ async fn test_btreemap_graph_structure() -> Result<()> { assert_eq!(e2e_tests.len(), 3); let classes = graph.find_nodes_by_type(NodeType::Class); - assert_eq!(classes.len(), 11); + assert_eq!(classes.len(), 13); let data_models = graph.find_nodes_by_type(NodeType::DataModel); assert_eq!(data_models.len(), 27); @@ -116,7 +116,7 @@ async fn test_btreemap_test_to_function_edges() -> Result<()> { assert_eq!(calls_edges, 18); let contains_edges = graph.count_edges_of_type(EdgeType::Contains); - assert_eq!(contains_edges, 231); + assert_eq!(contains_edges, 238); let handler_edges = graph.count_edges_of_type(EdgeType::Handler); assert_eq!(handler_edges, 22); @@ -133,8 +133,8 @@ async fn test_typescript_graph_upload() -> Result<()> { let graph_ops = setup_typescript_graph().await?; let (nodes, edges) = graph_ops.get_graph_size().await?; - assert_eq!(nodes, 231); - assert_eq!(edges, 320, "Expected 320 edges, got {}", edges); + assert_eq!(nodes, 238); + assert_eq!(edges, 327, "Expected 327 edges, got {}", edges); Ok(()) } From b3935107e2a8e65de0dd2e46546b9c55af236d2e Mon Sep 17 00:00:00 2001 From: kelmith Date: Wed, 26 Aug 2026 01:19:37 +0530 Subject: [PATCH 3/3] test: fix remaining typescript class-count and neo4j edge assertions --- ast/src/testing/coverage/typescript.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ast/src/testing/coverage/typescript.rs b/ast/src/testing/coverage/typescript.rs index c61fdca50..8b56f541d 100644 --- a/ast/src/testing/coverage/typescript.rs +++ b/ast/src/testing/coverage/typescript.rs @@ -116,7 +116,7 @@ async fn test_btreemap_test_to_function_edges() -> Result<()> { assert_eq!(calls_edges, 18); let contains_edges = graph.count_edges_of_type(EdgeType::Contains); - assert_eq!(contains_edges, 238); + assert_eq!(contains_edges, 241); let handler_edges = graph.count_edges_of_type(EdgeType::Handler); assert_eq!(handler_edges, 22); @@ -133,8 +133,8 @@ async fn test_typescript_graph_upload() -> Result<()> { let graph_ops = setup_typescript_graph().await?; let (nodes, edges) = graph_ops.get_graph_size().await?; - assert_eq!(nodes, 238); - assert_eq!(edges, 327, "Expected 327 edges, got {}", edges); + assert_eq!(nodes, 241); + assert_eq!(edges, 337, "Expected 337 edges, got {}", edges); Ok(()) } @@ -341,8 +341,8 @@ async fn test_nodes_class_type() -> Result<()> { ) .await?; - assert_eq!(count, 11); - assert_eq!(results.len(), 11); + assert_eq!(count, 13); + assert_eq!(results.len(), 13); Ok(()) }