Skip to content

Commit 6f843a2

Browse files
committed
Improve source tracking with Babel integration and TSX context detection
1 parent 206344c commit 6f843a2

6 files changed

Lines changed: 191 additions & 93 deletions

File tree

package-lock.json

Lines changed: 114 additions & 67 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,10 @@
129129
"zod": "^4.2.1"
130130
},
131131
"devDependencies": {
132+
"@babel/core": "^7.28.6",
132133
"@playwright/test": "^1.56.1",
133134
"@stylistic/eslint-plugin-ts": "^2.8.0",
135+
"@types/babel__core": "^7.20.5",
134136
"@types/cookie": "^0.3.3",
135137
"@types/debug": "^4.1.5",
136138
"@types/eslint": "^9.6.1",

src/vs/workbench/contrib/roopik/electron-main/build/esbuildTransformer.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,22 +1003,17 @@ render(h(Component), root);
10031003
framework: Framework,
10041004
componentId: string
10051005
): Record<string, string> {
1006-
const transform = createSourceTrackingTransform(framework);
1006+
const transform = createSourceTrackingTransform(framework, this.logger);
10071007
const trackedFiles: Record<string, string> = {};
10081008

10091009
for (const [filename, content] of Object.entries(files)) {
10101010
try {
10111011
// Apply source tracking transformation
10121012
const transformedContent = transform(content, filename, componentId);
10131013
trackedFiles[filename] = transformedContent;
1014-
1015-
// Log if transformation happened
1016-
if (transformedContent !== content) {
1017-
this.logger.debug('Source tracking applied', { filename });
1018-
}
10191014
} catch (error) {
10201015
// Gracefully handle errors - use original content
1021-
this.logger.warn('Source tracking transformation failed', { filename, error });
1016+
this.logger.warn('[SOURCE_TRACKING] Transformation error', { filename, error });
10221017
trackedFiles[filename] = content;
10231018
}
10241019
}

src/vs/workbench/contrib/roopik/electron-main/build/injectors/sourceTrackingCore.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ export function isInsideTypeScriptTypeContext(code: string, position: number): b
120120
// Look backwards from position to find context
121121
const beforeMatch = code.substring(Math.max(0, position - 100), position);
122122

123+
// CRITICAL Pattern: Generic function/method calls - "useState<", "React.useState<", "useRef<T>"
124+
// This is the MOST COMMON case that causes bugs!
125+
// If an identifier immediately precedes '<', it's almost always a TypeScript generic, NOT JSX
126+
// The ONLY exception is: "return <Component>" (the 'return' keyword)
127+
// Note: "=> <Component>" doesn't match because '=>' isn't an identifier
128+
const identifierBeforeAngleBracket = /[A-Za-z_$][A-Za-z0-9_$.]*\s*$/.exec(beforeMatch);
129+
if (identifierBeforeAngleBracket) {
130+
const matchedIdentifier = identifierBeforeAngleBracket[0].trim();
131+
// If the identifier is 'return', it's JSX (e.g., "return <div>")
132+
// Otherwise, it's a TypeScript generic (e.g., "useState<T>", "Array<string>")
133+
if (matchedIdentifier !== 'return') {
134+
return true; // Skip - it's a generic
135+
}
136+
}
137+
123138
// Pattern 1: Type annotation - "event: React.MouseEvent<" or "value: Array<"
124139
// Look for ": TypeName<" pattern (colon followed by identifier then our position)
125140
if (/:\s*[A-Za-z_$][A-Za-z0-9_$.<>]*$/.test(beforeMatch)) {

0 commit comments

Comments
 (0)