Code Transformation and Linting with ASTs

Challenge 5: Solution

Kent C. Dodds

Kent C. Dodds

Professional Trainer
Code Transformation and Linting with ASTs

Check out a free preview of the full Code Transformation and Linting with ASTs course

The "Challenge 5: Solution" Lesson is part of the full, Code Transformation and Linting with ASTs course featured in this preview video. Here's what you'd learn in this lesson:

Kent walks through the solution to Challenge 5.


Transcript from the "Challenge 5: Solution" Lesson

>> Kent C Dodds: As far as a solution is concerned, for my solution, I wanted to create a report function. So I'm gonna do that right here. And I'm going to accept the property, so the offending. This is the log, or the info, or whatever. And then also the consoleObject so that I can swap it out.

And then I'll just move this down here, and I'll call report with the property. And then the consoleObject is gonna be reference.identifier.parent.object. So this parent is gonna be the member expression, that's the, or csl.log, or whatever. And it has a property, that'll be the info or the log, and it has an object, and that'll be the csl, or console, or whatever.

So I haven't actually fixed anything yet, but let's just refactor our report up here to do the same thing. Report on the property and the object. Could probably just pass the member expression and then have our report function deal with that, which probably work just as well. Okay, great, so we haven't actually fixed any code, but we haven't broken anything, so that's good.

Okay, so then we'll take our fixer and replaceText. We're gonna replace, or here, actually, before we do this, let me show you with this handy trick. With the context, if you want to see what the source code is that a certain node represents, you can do that with context.

So we'll say, sourceCode = context.getSourceCode().
>> Kent C Dodds: And then down here in our report, we're going to, I think it's getText, I might have to reference this, for the consoleObject.
>> Kent C Dodds: And it's gonna be in here somewhere. I have this fancy thing I call space console that's impossible to miss.

So it's gonna be in here. Actually, did I forget to put, no, I put fixable in there. What?
>> Kent C Dodds: Let's put this up here. Okay, so we are seeing that sourceCode, I'm not sure why it wasn't happening in our fixer. So yeah, if we wanted to do the property, and then that's gonna be the log.

We could do parent, and that csl.log, we'd do parent from that. And that gives us the call expression. And a parent from that is gonna be, I'm not even sure what the parent of our call expression is, but you get the idea. You pass it a node, it will give you the text that that node represents.

Which is really, really handy, and I use it often. So we want to swap out the csl, or the console reference. And so, whoops.
>> Kent C Dodds: Let's just get rid of this stuff.
>> Kent C Dodds: And we'll swap out the consoleObject.
>> Kent C Dodds: And sorry, I didn't make that clear, super sorry, but you need to return this.

Did anybody, yeah, catch that? Reference is not defined, what?
>> Student: Node, I think the node.
>> Kent C Dodds: Thank you.
>> Kent C Dodds: And the node, wait, we wanna replace consoleObject, sorry, consoleObject with logger.
>> Kent C Dodds: Output is incorrect for this one. Yeah, that's right, okay. So for this one, we don't wanna replace csl.

We wanna replace the console, so that csl will be assigned to console. So instead of passing the identifier.parent.object, we're just gonna pass the consoleUsage identifier. Does that make sense? So remember this consoleUsage is a collection of all of the identifiers that are console, and in the case of it being a reference of some kind.

Or sorry, whoops, I got the wrong one. That is this one.
>> Kent C Dodds: Yeah, that one.
>> Kent C Dodds: Yeah, cool, and then I gotta remove this bad code test.
>> Kent C Dodds: Let me just expand this out a little bit.
>> Kent C Dodds: So just to recap, we have our report function, takes a property, and then the consoleObject that we wanna have be replaced.

And we do our normal reporting on that property, and then we provide a fix that takes a fixer. We call replaceText on that consoleObject that we wanna replace. We replace it with logger, which is presumably some global that we have for our app or something. Yeah, so these ESLint rules can get decently complicated.

But what I think is really cool about them is if you really feel like you need to control against developers doing some really potentially bad things, an ESLint rule is great because you can find a lot of really common patterns. And even if the developers are doing some kinda wacky things like assigning console to another object and calling logs on that, you can still accomplish your static analyzation.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now