Skip to content

Commit 9541ece

Browse files
committed
chore: wip
1 parent 788c083 commit 9541ece

File tree

2 files changed

+172
-64
lines changed

2 files changed

+172
-64
lines changed

src/extractor.ts

Lines changed: 85 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-case-declarations, regexp/no-contradiction-with-assertion */
12
import type { Declaration } from './types'
23
import * as ts from 'typescript'
34

@@ -80,12 +81,12 @@ export function extractDeclarations(sourceCode: string, filePath: string, keepCo
8081
}
8182

8283
visitTopLevel(sourceFile)
83-
84+
8485
// Second pass: Find referenced types that aren't imported or declared
8586
const referencedTypes = findReferencedTypes(declarations, sourceCode)
8687
const additionalDeclarations = extractReferencedTypeDeclarations(sourceFile, referencedTypes, sourceCode)
8788
declarations.push(...additionalDeclarations)
88-
89+
8990
return declarations
9091
}
9192

@@ -1016,49 +1017,51 @@ function getNodeText(node: ts.Node, sourceCode: string): string {
10161017
*/
10171018
function extractJSDocComments(node: ts.Node, sourceFile: ts.SourceFile): string[] {
10181019
const comments: string[] = []
1019-
1020+
10201021
// Get leading trivia (comments before the node)
10211022
const fullStart = node.getFullStart()
10221023
const start = node.getStart(sourceFile)
1023-
1024+
10241025
if (fullStart !== start) {
10251026
const triviaText = sourceFile.text.substring(fullStart, start)
1026-
1027+
10271028
// Extract JSDoc comments (/** ... */) and single-line comments (// ...)
10281029
const jsDocMatches = triviaText.match(/\/\*\*[\s\S]*?\*\//g)
10291030
if (jsDocMatches) {
10301031
comments.push(...jsDocMatches)
10311032
}
1032-
1033+
10331034
// Also capture regular block comments (/* ... */) that might be documentation
10341035
const blockCommentMatches = triviaText.match(/\/\*(?!\*)[\s\S]*?\*\//g)
10351036
if (blockCommentMatches) {
10361037
comments.push(...blockCommentMatches)
10371038
}
1038-
1039+
10391040
// Capture single-line comments that appear right before the declaration
10401041
const lines = triviaText.split('\n')
10411042
const commentLines: string[] = []
1042-
1043+
10431044
// Look for consecutive comment lines at the end of the trivia
10441045
for (let i = lines.length - 1; i >= 0; i--) {
10451046
const line = lines[i].trim()
10461047
if (line.startsWith('//')) {
10471048
commentLines.unshift(line)
1048-
} else if (line === '') {
1049+
}
1050+
else if (line === '') {
10491051
// Empty line is okay, continue
10501052
continue
1051-
} else {
1053+
}
1054+
else {
10521055
// Non-comment, non-empty line - stop
10531056
break
10541057
}
10551058
}
1056-
1059+
10571060
if (commentLines.length > 0) {
10581061
comments.push(commentLines.join('\n'))
10591062
}
10601063
}
1061-
1064+
10621065
return comments
10631066
}
10641067

@@ -1119,7 +1122,7 @@ function hasAsyncModifier(node: ts.FunctionDeclaration): boolean {
11191122
/**
11201123
* Check if a non-exported function should be included (e.g., if it's referenced by exported items)
11211124
*/
1122-
function shouldIncludeNonExportedFunction(functionName: string, sourceCode: string): boolean {
1125+
function shouldIncludeNonExportedFunction(_functionName?: string, _sourceCode?: string): boolean {
11231126
// For now, don't include non-exported functions
11241127
// In the future, we could analyze if they're referenced by exported functions
11251128
return false
@@ -1139,7 +1142,7 @@ function shouldIncludeNonExportedInterface(interfaceName: string, sourceCode: st
11391142
/**
11401143
* Find types that are referenced in declarations but not imported or declared
11411144
*/
1142-
function findReferencedTypes(declarations: Declaration[], sourceCode: string): Set<string> {
1145+
function findReferencedTypes(declarations: Declaration[], _sourceCode: string): Set<string> {
11431146
const referencedTypes = new Set<string>()
11441147
const importedTypes = new Set<string>()
11451148
const declaredTypes = new Set<string>()
@@ -1260,43 +1263,43 @@ function extractReferencedTypeDeclarations(sourceFile: ts.SourceFile, referenced
12601263
*/
12611264
function extractTypesFromModuleText(moduleText: string): string[] {
12621265
const types: string[] = []
1263-
1266+
12641267
// Look for interface declarations
12651268
const interfaceMatches = moduleText.match(/(?:export\s+)?interface\s+([A-Z][a-zA-Z0-9]*)/g)
12661269
if (interfaceMatches) {
1267-
interfaceMatches.forEach(match => {
1270+
interfaceMatches.forEach((match) => {
12681271
const name = match.replace(/(?:export\s+)?interface\s+/, '')
12691272
types.push(name)
12701273
})
12711274
}
1272-
1275+
12731276
// Look for type alias declarations
12741277
const typeMatches = moduleText.match(/(?:export\s+)?type\s+([A-Z][a-zA-Z0-9]*)/g)
12751278
if (typeMatches) {
1276-
typeMatches.forEach(match => {
1279+
typeMatches.forEach((match) => {
12771280
const name = match.replace(/(?:export\s+)?type\s+/, '')
12781281
types.push(name)
12791282
})
12801283
}
1281-
1284+
12821285
// Look for class declarations
12831286
const classMatches = moduleText.match(/(?:export\s+)?(?:declare\s+)?class\s+([A-Z][a-zA-Z0-9]*)/g)
12841287
if (classMatches) {
1285-
classMatches.forEach(match => {
1288+
classMatches.forEach((match) => {
12861289
const name = match.replace(/(?:export\s+)?(?:declare\s+)?class\s+/, '')
12871290
types.push(name)
12881291
})
12891292
}
1290-
1293+
12911294
// Look for enum declarations
12921295
const enumMatches = moduleText.match(/(?:export\s+)?(?:declare\s+)?(?:const\s+)?enum\s+([A-Z][a-zA-Z0-9]*)/g)
12931296
if (enumMatches) {
1294-
enumMatches.forEach(match => {
1297+
enumMatches.forEach((match) => {
12951298
const name = match.replace(/(?:export\s+)?(?:declare\s+)?(?:const\s+)?enum\s+/, '')
12961299
types.push(name)
12971300
})
12981301
}
1299-
1302+
13001303
return types
13011304
}
13021305

@@ -1305,13 +1308,66 @@ function extractTypesFromModuleText(moduleText: string): string[] {
13051308
*/
13061309
function isBuiltInType(typeName: string): boolean {
13071310
const builtInTypes = new Set([
1308-
'string', 'number', 'boolean', 'object', 'any', 'unknown', 'never', 'void',
1309-
'undefined', 'null', 'Array', 'Promise', 'Record', 'Partial', 'Required',
1310-
'Pick', 'Omit', 'Exclude', 'Extract', 'NonNullable', 'ReturnType',
1311-
'Parameters', 'ConstructorParameters', 'InstanceType', 'ThisType',
1312-
'Function', 'Date', 'RegExp', 'Error', 'Map', 'Set', 'WeakMap', 'WeakSet',
1311+
'string',
1312+
'number',
1313+
'boolean',
1314+
'object',
1315+
'any',
1316+
'unknown',
1317+
'never',
1318+
'void',
1319+
'undefined',
1320+
'null',
1321+
'Array',
1322+
'Promise',
1323+
'Record',
1324+
'Partial',
1325+
'Required',
1326+
'Pick',
1327+
'Omit',
1328+
'Exclude',
1329+
'Extract',
1330+
'NonNullable',
1331+
'ReturnType',
1332+
'Parameters',
1333+
'ConstructorParameters',
1334+
'InstanceType',
1335+
'ThisType',
1336+
'Function',
1337+
'Date',
1338+
'RegExp',
1339+
'Error',
1340+
'Map',
1341+
'Set',
1342+
'WeakMap',
1343+
'WeakSet',
13131344
// Common generic type parameters
1314-
'T', 'K', 'V', 'U', 'R', 'P', 'E', 'A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'L', 'M', 'N', 'O', 'Q', 'S', 'W', 'X', 'Y', 'Z'
1345+
'T',
1346+
'K',
1347+
'V',
1348+
'U',
1349+
'R',
1350+
'P',
1351+
'E',
1352+
'A',
1353+
'B',
1354+
'C',
1355+
'D',
1356+
'F',
1357+
'G',
1358+
'H',
1359+
'I',
1360+
'J',
1361+
'L',
1362+
'M',
1363+
'N',
1364+
'O',
1365+
'Q',
1366+
'S',
1367+
'W',
1368+
'X',
1369+
'Y',
1370+
'Z',
13151371
])
13161372
return builtInTypes.has(typeName)
13171373
}

0 commit comments

Comments
 (0)