Prompt
Implement a custom ESLint rule that flags console.log statements. Define the rule as an object with meta and create(context); the visitor checks each CallExpression and reports when the callee is console.log (but not console.warn/error).
Solution
The principle behind writing lint rules: automate every objective judgment so human review is spent on design, naming, and correctness — a reviewer flagging console.log by hand is a wasted senior, and a rule enforces the standard on every push forever, without the social cost of nitpicking a colleague.
Mechanics: ESLint parses source into an AST and your rule registers visitors keyed by node type. CallExpression fires for every call in the file; you inspect the callee's shape — a MemberExpression whose object is console and property is log — and context.report attaches the diagnostic to the exact node, which is what puts the squiggle on the right token. The optional chaining (callee.object?.name) is load-bearing, not style: a plain call like foo() has no callee.object, and a rule that crashes on valid code takes down the whole lint run. Rules must be total over the language.
Ecosystem context to volunteer: flat config is ESLint's current format (default since v9); TSLint was deprecated in 2019 and its rules live on in typescript-eslint; and rules can ship autofixes — the difference between a complaint and a correction.
Red flag: proposing grep or a pre-commit regex for this. Regex can't tell console.log( from a string containing it or a local variable named console — the AST is exactly why lint rules are reliable and greps are advisory.
Say it: "Lint rules exist so review never argues about the objective layer — I visit CallExpression nodes, match the callee shape on the AST, and report on the node so the fix lands on the right token."