Skip to content

Commit e2081b9

Browse files
committed
wip: add chalk
1 parent f6f80a6 commit e2081b9

File tree

3 files changed

+52
-11
lines changed

3 files changed

+52
-11
lines changed

bun.lockb

1.2 KB
Binary file not shown.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"@microsoft/tsdoc": "^0.14.2",
6363
"@playwright/test": "^1.40.1",
6464
"argparse": "^2.0.1",
65+
"chalk": "^5.4.1",
6566
"dotenv": "^16.3.1",
6667
"glob": "^10.3.10",
6768
"hi-base32": "^0.5.1",

src/lib/ref_checker2.ts

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import * as ts from 'ts-morph';
55
import path from 'path';
6+
import chalk from 'chalk';
67
import { getExpressionChain } from './utils';
78

89
const LIB_DIR = path.normalize(__dirname);
@@ -28,8 +29,8 @@ function throwError(
2829
strPath: string,
2930
mutationType: 'function' | 'assignment'
3031
) {
31-
const mutationLine = getNodeLines(mutation, strPath);
32-
const accessLine = getNodeLines(access, strPath);
32+
const mutationLine = getNodeLines(mutation, strPath, 'yellow');
33+
const accessLine = getNodeLines(access, strPath, 'red');
3334

3435
if (mutationType === 'assignment') {
3536
const refRhs =
@@ -39,18 +40,22 @@ function throwError(
3940

4041
if (refRhs === undefined) {
4142
throw Error(
42-
`Attempted to access "${access.getText()}" which may have been mutated.\nMutation: ${mutationLine}\nAccessed: ${accessLine}`
43+
`Attempted to access "${access.getText()}" which may have been mutated.
44+
45+
${mutationLine} Value mutated here.
46+
47+
${accessLine} Attempted access of the value ocurred here`
4348
);
4449
}
4550

4651
const aliasInRef = refRhs.isKind(ts.SyntaxKind.Identifier)
4752
? refRhs
4853
: refRhs.getDescendants().find((d) => aliases.map((a) => a.getText()).includes(d.getText()))!;
49-
const staleRefLine = getNodeLines(aliasInRef!, strPath);
54+
const staleRefLine = getNodeLines(aliasInRef!, strPath, 'yellow');
5055
throw Error(
5156
`Attempted to access "${access.getText()}" which may have been mutated. You might want to use clone in the initial assignment
5257
53-
${staleRefLine} Initial assignment here. Suggestion: clone(${aliasInRef.getText()})
58+
${staleRefLine} Initial assignment here. ${chalk.bold.underline.yellow('Suggestion')}: clone(${aliasInRef.getText()})
5459
5560
${mutationLine} Mutation of the value ocurred here.
5661
@@ -63,7 +68,9 @@ ${accessLine} Attempted access of the value occured here.
6368
throw Error(
6469
`Attempted to access "${access.getText()}" after it was passed to a function. You probably want to use clone in the function call
6570
66-
Function Call: ${mutationLine} Value passed to function here. Suggestion: clone(${access.getText()})
71+
Function Call: ${mutationLine} Value passed to function here. ${chalk.bold.underline.yellow(
72+
'Suggestion'
73+
)}: clone(${access.getText()})
6774
6875
${accessLine} Attempted access to value after passed to function here
6976
`
@@ -101,7 +108,33 @@ function includesNode(haystack: ts.Node, needle: ts.Node): boolean {
101108
});
102109
}
103110

104-
function getNodeLines(node: ts.Node, pathStr: string) {
111+
/**
112+
* Colors a specific range of characters in a string using chalk
113+
* @param text The input string to color
114+
* @param startIndex The starting index of the range to color (inclusive)
115+
* @param endIndex The ending index of the range to color (exclusive)
116+
* @param color The chalk color to apply (e.g., 'red', 'blue', 'green')
117+
* @returns The string with the specified range colored
118+
*/
119+
function colorRange(text: string, startIndex: number, endIndex: number, color: 'yellow' | 'red'): string {
120+
// Validate indices
121+
if (startIndex < 0 || endIndex > text.length || startIndex >= endIndex) {
122+
throw new Error('Invalid range indices');
123+
}
124+
125+
// Get the parts of the string
126+
const beforeRange = text.substring(0, startIndex);
127+
const coloredPart = text.substring(startIndex, endIndex);
128+
const afterRange = text.substring(endIndex);
129+
130+
// Apply color using chalk's dynamic method access
131+
const coloredText = chalk[color](coloredPart);
132+
133+
// Combine all parts
134+
return beforeRange + coloredText + afterRange;
135+
}
136+
137+
function getNodeLines(node: ts.Node, pathStr: string, nodeColor: 'yellow' | 'red') {
105138
const nonTrimmedLine = node.getSourceFile().getFullText().split('\n')[node.getStartLineNumber() - 1];
106139
const refFullLine = nonTrimmedLine.trim();
107140
const char = ts.ts.getLineAndCharacterOfPosition(
@@ -110,9 +143,12 @@ function getNodeLines(node: ts.Node, pathStr: string) {
110143
).character;
111144
const nodeOffset = char - (nonTrimmedLine.length - refFullLine.length);
112145

113-
return `${pathStr}:${node.getStartLineNumber()}:${char}\n ${refFullLine}\n ${' '.repeat(nodeOffset)}${'^'.repeat(
114-
node.getText().length
115-
)}`;
146+
return `${pathStr}:${node.getStartLineNumber()}:${char}\n ${colorRange(
147+
refFullLine,
148+
nodeOffset,
149+
nodeOffset + node.getText().length,
150+
nodeColor
151+
)}\n ${' '.repeat(nodeOffset)}${chalk[nodeColor]('^').repeat(node.getText().length)}`;
116152
}
117153

118154
function getAliases(node: ts.Node, methodBody: ts.Node) {
@@ -245,7 +281,11 @@ function checkArrayFunctions(methodBody: ts.Node, pathStr: string) {
245281
const arg = c.getArguments()[0];
246282
if (isArrayOrObject(arg) && !arg.getText().startsWith('clone(')) {
247283
const msg = `Mutable objects must be cloned via "clone" before being pushed into an array`;
248-
throw Error(`${msg}\n${getNodeLines(arg, pathStr)} Suggestion: clone(${arg.getText()})`);
284+
throw Error(
285+
`${msg}\n${getNodeLines(arg, pathStr, 'yellow')} ${chalk.bold.underline.yellow(
286+
'Suggestion'
287+
)}: clone(${arg.getText()})`
288+
);
249289
}
250290
}
251291
}

0 commit comments

Comments
 (0)