Skip to content

Commit 70a38a6

Browse files
author
Eric Wheeler
committed
test: add conditional type support to tree-sitter TypeScript parser
- Added test case for conditional type patterns like ReturnType<T> - Verified that conditional types with infer keyword are already supported - Enhanced inspectTreeStructure with detailed node inspection for debugging Signed-off-by: Eric Wheeler <[email protected]>
1 parent fd5db57 commit 70a38a6

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

src/services/tree-sitter/__tests__/parseSourceCodeDefinitions.test.ts

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,43 @@ async function inspectTreeStructure(content: string, language: string = "typescr
181181

182182
// Print the tree structure
183183
console.log(`TREE STRUCTURE (${language}):\n${tree.rootNode.toString()}`)
184+
185+
// Add more detailed debug information
186+
console.log("\nDETAILED NODE INSPECTION:")
187+
188+
// Function to recursively print node details
189+
const printNodeDetails = (node: any, depth: number = 0) => {
190+
const indent = " ".repeat(depth)
191+
console.log(
192+
`${indent}Node Type: ${node.type}, Start: ${node.startPosition.row}:${node.startPosition.column}, End: ${node.endPosition.row}:${node.endPosition.column}`,
193+
)
194+
195+
// Print children
196+
for (let i = 0; i < node.childCount; i++) {
197+
const child = node.child(i)
198+
if (child) {
199+
// For type_alias_declaration nodes, print more details
200+
if (node.type === "type_alias_declaration") {
201+
console.log(`${indent} TYPE ALIAS: ${node.text}`)
202+
}
203+
204+
// For conditional_type nodes, print more details
205+
if (node.type === "conditional_type" || child.type === "conditional_type") {
206+
console.log(`${indent} CONDITIONAL TYPE FOUND: ${child.text}`)
207+
}
208+
209+
// For infer_type nodes, print more details
210+
if (node.type === "infer_type" || child.type === "infer_type") {
211+
console.log(`${indent} INFER TYPE FOUND: ${child.text}`)
212+
}
213+
214+
printNodeDetails(child, depth + 1)
215+
}
216+
}
217+
}
218+
219+
// Start recursive printing from the root node
220+
printNodeDetails(tree.rootNode)
184221
}
185222

186223
const logParseResult = async (description: string, filePath: string) => {
@@ -329,6 +366,98 @@ describe("treeParserDebug", () => {
329366
})
330367
})
331368

369+
it("should parse conditional types", async function () {
370+
const conditionalTypeContent = `
371+
/**
372+
* Extract return type from function type
373+
* Uses conditional types to determine the return type of a function
374+
* @template T - Function type to extract return type from
375+
*/
376+
type ReturnType<T> = T extends
377+
// Function type with any arguments
378+
(...args: any[]) =>
379+
// Using infer to capture the return type
380+
infer R
381+
// If the condition is true, return the inferred type
382+
? R
383+
// Otherwise return never
384+
: never;
385+
386+
/**
387+
* Extract parameter types from function type
388+
* Uses conditional types to determine the parameter types of a function
389+
* @template T - Function type to extract parameter types from
390+
*/
391+
type Parameters<T> = T extends
392+
// Function type with inferred parameters
393+
(...args: infer P) =>
394+
// Any return type
395+
any
396+
// If the condition is true, return the parameter types
397+
? P
398+
// Otherwise return never
399+
: never;
400+
401+
/**
402+
* Extract instance type from constructor type
403+
* Uses conditional types to determine what type a constructor creates
404+
* @template T - Constructor type to extract instance type from
405+
*/
406+
type InstanceType<T> = T extends
407+
// Constructor type with any arguments
408+
new (...args: any[]) =>
409+
// Using infer to capture the instance type
410+
infer R
411+
// If the condition is true, return the inferred type
412+
? R
413+
// Otherwise return never
414+
: never;
415+
416+
/**
417+
* Determine if a type is a function
418+
* Uses conditional types to check if a type is callable
419+
* @template T - Type to check
420+
*/
421+
type IsFunction<T> = T extends
422+
// Function type with any arguments and return type
423+
(...args: any[]) =>
424+
any
425+
// If the condition is true, return true
426+
? true
427+
// Otherwise return false
428+
: false;
429+
`
430+
mockedFs.readFile.mockResolvedValue(Buffer.from(conditionalTypeContent))
431+
432+
// First run without adding the query pattern to see if it's already implemented
433+
const initialResult = await testParseSourceCodeDefinitions("/test/conditional-type.tsx", conditionalTypeContent)
434+
console.log("Initial result before adding query pattern:", initialResult)
435+
436+
// Save the initial line count to compare later
437+
const initialLineCount = initialResult ? initialResult.split("\n").length : 0
438+
const initialCaptures = initialResult ? initialResult : ""
439+
440+
// Now check if the new query pattern improves the output
441+
const updatedResult = await testParseSourceCodeDefinitions("/test/conditional-type.tsx", conditionalTypeContent)
442+
console.log("Updated result after adding query pattern:", updatedResult)
443+
444+
// Compare results
445+
const updatedLineCount = updatedResult ? updatedResult.split("\n").length : 0
446+
expect(updatedResult).toBeDefined()
447+
448+
// Check if the feature is already implemented
449+
if (initialResult && initialResult.includes("ReturnType<T>") && initialResult.includes("Parameters<T>")) {
450+
console.log("Conditional types are already supported by the parser!")
451+
// If the feature is already implemented, we don't need to check if the updated result is better
452+
expect(true).toBe(true)
453+
} else {
454+
// If the feature wasn't already implemented, check if our changes improved it
455+
expect(updatedLineCount).toBeGreaterThan(initialLineCount)
456+
expect(updatedResult).toContain("ReturnType<T>")
457+
expect(updatedResult).toContain("Parameters<T>")
458+
}
459+
})
460+
332461
it("should detect TypeScript interfaces and HOCs", async function () {
333462
const tsContent = `
334463
interface Props {

0 commit comments

Comments
 (0)