Skip to content

Commit 979fd60

Browse files
fixed the TODO comment placement.
1 parent ad94ced commit 979fd60

File tree

1 file changed

+81
-18
lines changed

1 file changed

+81
-18
lines changed

codemods/regexp-to-arkregex/scripts/codemod.ts

Lines changed: 81 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ function hasRegexConflict(rootNode: SgNode<TSX>): boolean {
329329

330330
async function transform(root: SgRoot<TSX>): Promise<string | null> {
331331
const rootNode = root.root();
332+
const sourceText = rootNode.text();
332333

333334
// Check if regex is already imported
334335
const importInfo = hasRegexImport(rootNode);
@@ -435,18 +436,49 @@ async function transform(root: SgRoot<TSX>): Promise<string | null> {
435436

436437
// Add TODO comment if either is dynamic
437438
if (!patternStatic || !flagsStatic) {
438-
const containingStmt = expression.ancestors().find((a: SgNode<TSX>) =>
439-
a.kind() === "expression_statement" ||
440-
a.kind() === "variable_declaration" ||
441-
a.kind() === "return_statement"
442-
);
439+
// Find the start of the line where the expression is located
440+
const exprRange = expression.range();
443441

444-
if (containingStmt && !hasTodoComment(containingStmt)) {
442+
// Find the start of the line (go backwards to find the previous newline)
443+
let lineStart = exprRange.start.index;
444+
while (lineStart > 0 && sourceText[lineStart - 1] !== '\n') {
445+
lineStart--;
446+
}
447+
448+
// Check if there's already a TODO comment on this line or the line before
449+
// First, check the current line
450+
const lineEnd = sourceText.indexOf('\n', lineStart);
451+
const currentLineText = lineEnd >= 0
452+
? sourceText.substring(lineStart, lineEnd)
453+
: sourceText.substring(lineStart);
454+
const hasCommentOnCurrentLine = currentLineText.trim().startsWith("//") &&
455+
currentLineText.includes("TODO(arkregex)");
456+
457+
// Then check the previous line
458+
const lineBeforeStart = lineStart > 0 ? (() => {
459+
let pos = lineStart - 1;
460+
// Skip the newline itself
461+
if (pos >= 0 && sourceText[pos] === '\n') pos--;
462+
// Go back to find the start of the previous line
463+
while (pos > 0 && sourceText[pos - 1] !== '\n') {
464+
pos--;
465+
}
466+
return pos;
467+
})() : -1;
468+
469+
const hasCommentOnPreviousLine = lineBeforeStart >= 0 &&
470+
sourceText.substring(lineBeforeStart, lineStart).includes("TODO(arkregex)");
471+
472+
const hasExistingComment = hasCommentOnCurrentLine || hasCommentOnPreviousLine;
473+
474+
if (!hasExistingComment) {
445475
const todoComment = "// TODO(arkregex): pattern/flags not statically known; typing may degrade. Consider regex.as<...>(...)\n";
446-
const stmtRange = containingStmt.range();
476+
// Place comment at the start of the current line (which will appear right above the expression)
477+
// If we're not at the start of the file, we're placing it on the line before
478+
const insertPos = lineStart > 0 ? lineStart : 0;
447479
edits.push({
448-
startPos: stmtRange.start.index,
449-
endPos: stmtRange.start.index,
480+
startPos: insertPos,
481+
endPos: insertPos,
450482
insertedText: todoComment,
451483
});
452484
}
@@ -509,18 +541,49 @@ async function transform(root: SgRoot<TSX>): Promise<string | null> {
509541
}
510542

511543
if (!patternStatic || !flagsStatic) {
512-
const containingStmt = call.ancestors().find((a: SgNode<TSX>) =>
513-
a.kind() === "expression_statement" ||
514-
a.kind() === "variable_declaration" ||
515-
a.kind() === "return_statement"
516-
);
544+
// Find the start of the line where the call is located
545+
const callRange = call.range();
546+
547+
// Find the start of the line (go backwards to find the previous newline)
548+
let lineStart = callRange.start.index;
549+
while (lineStart > 0 && sourceText[lineStart - 1] !== '\n') {
550+
lineStart--;
551+
}
552+
553+
// Check if there's already a TODO comment on this line or the line before
554+
// First, check the current line
555+
const lineEnd = sourceText.indexOf('\n', lineStart);
556+
const currentLineText = lineEnd >= 0
557+
? sourceText.substring(lineStart, lineEnd)
558+
: sourceText.substring(lineStart);
559+
const hasCommentOnCurrentLine = currentLineText.trim().startsWith("//") &&
560+
currentLineText.includes("TODO(arkregex)");
561+
562+
// Then check the previous line
563+
const lineBeforeStart = lineStart > 0 ? (() => {
564+
let pos = lineStart - 1;
565+
// Skip the newline itself
566+
if (pos >= 0 && sourceText[pos] === '\n') pos--;
567+
// Go back to find the start of the previous line
568+
while (pos > 0 && sourceText[pos - 1] !== '\n') {
569+
pos--;
570+
}
571+
return pos;
572+
})() : -1;
573+
574+
const hasCommentOnPreviousLine = lineBeforeStart >= 0 &&
575+
sourceText.substring(lineBeforeStart, lineStart).includes("TODO(arkregex)");
576+
577+
const hasExistingComment = hasCommentOnCurrentLine || hasCommentOnPreviousLine;
517578

518-
if (containingStmt && !hasTodoComment(containingStmt)) {
579+
if (!hasExistingComment) {
519580
const todoComment = "// TODO(arkregex): pattern/flags not statically known; typing may degrade. Consider regex.as<...>(...)\n";
520-
const stmtRange = containingStmt.range();
581+
// Place comment at the start of the current line (which will appear right above the expression)
582+
// If we're not at the start of the file, we're placing it on the line before
583+
const insertPos = lineStart > 0 ? lineStart : 0;
521584
edits.push({
522-
startPos: stmtRange.start.index,
523-
endPos: stmtRange.start.index,
585+
startPos: insertPos,
586+
endPos: insertPos,
524587
insertedText: todoComment,
525588
});
526589
}

0 commit comments

Comments
 (0)