AST for Beginners

Gyandeep Singh   

@gyandeeps

Backbone of JS tools

Agenda

  • What is AST?
  • Why do we care
  • Basics of AST
  • Babel example
  • ESLint example

What is AST?

AST is a tree representation of the abstract syntactic structure of source code written in a programming language

 

- Wikipedia

 

 

  • Abstract - not representing every detail appearing in the real syntax.

Code for humans

if (planet === "earth") {
    console.log("Humans");
}
else {
    console.log("Aliens");
}

Code for computers

{
  "type": "Program",
  "start": 0,
  "end": 91,
  "loc": {
    "start": {
      "line": 1,
      "column": 0
    },
    "end": {
      "line": 7,
      "column": 0
    }
  },
  "range": [
    0,
    91
  ],
  "body": [
    {
      "type": "IfStatement",
      "start": 0,
      "end": 90,
      "loc": {
        "start": {
          "line": 1,
          "column": 0
        },
        "end": {
          "line": 6,
          "column": 1
        }
      },
      "range": [
        0,
        90
      ],
      "test": {
        "type": "BinaryExpression",
        "start": 4,
        "end": 22,
        "loc": {
          "start": {
            "line": 1,
            "column": 4
          },
          "end": {
            "line": 1,
            "column": 22
          }
        },
        "range": [
          4,
          22
        ],
        "left": {
          "type": "Identifier",
          "start": 4,
          "end": 10,
          "loc": {
            "start": {
              "line": 1,
              "column": 4
            },
            "end": {
              "line": 1,
              "column": 10
            }
          },
          "range": [
            4,
            10
          ],
          "name": "planet"
        },
        "operator": "===",
        "right": {
          "type": "Literal",
          "start": 15,
          "end": 22,
          "loc": {
            "start": {
              "line": 1,
              "column": 15
            },
            "end": {
              "line": 1,
              "column": 22
            }
          },
          "range": [
            15,
            22
          ],
          "value": "earth",
          "raw": "\"earth\""
        }
      },
      "consequent": {
        "type": "BlockStatement",
        "start": 24,
        "end": 54,
        "loc": {
          "start": {
            "line": 1,
            "column": 24
          },
          "end": {
            "line": 3,
            "column": 1
          }
        },
        "range": [
          24,
          54
        ],
        "body": [
          {
            "type": "ExpressionStatement",
            "start": 30,
            "end": 52,
            "loc": {
              "start": {
                "line": 2,
                "column": 4
              },
              "end": {
                "line": 2,
                "column": 26
              }
            },
            "range": [
              30,
              52
            ],
            "expression": {
              "type": "CallExpression",
              "start": 30,
              "end": 51,
              "loc": {
                "start": {
                  "line": 2,
                  "column": 4
                },
                "end": {
                  "line": 2,
                  "column": 25
                }
              },
              "range": [
                30,
                51
              ],
              "callee": {
                "type": "MemberExpression",
                "start": 30,
                "end": 41,
                "loc": {
                  "start": {
                    "line": 2,
                    "column": 4
                  },
                  "end": {
                    "line": 2,
                    "column": 15
                  }
                },
                "range": [
                  30,
                  41
                ],
                "object": {
                  "type": "Identifier",
                  "start": 30,
                  "end": 37,
                  "loc": {
                    "start": {
                      "line": 2,
                      "column": 4
                    },
                    "end": {
                      "line": 2,
                      "column": 11
                    }
                  },
                  "range": [
                    30,
                    37
                  ],
                  "name": "console"
                },
                "property": {
                  "type": "Identifier",
                  "start": 38,
                  "end": 41,
                  "loc": {
                    "start": {
                      "line": 2,
                      "column": 12
                    },
                    "end": {
                      "line": 2,
                      "column": 15
                    }
                  },
                  "range": [
                    38,
                    41
                  ],
                  "name": "log"
                },
                "computed": false
              },
              "arguments": [
                {
                  "type": "Literal",
                  "start": 42,
                  "end": 50,
                  "loc": {
                    "start": {
                      "line": 2,
                      "column": 16
                    },
                    "end": {
                      "line": 2,
                      "column": 24
                    }
                  },
                  "range": [
                    42,
                    50
                  ],
                  "value": "Humans",
                  "raw": "\"Humans\""
                }
              ]
            }
          }
        ]
      },
      "alternate": {
        "type": "BlockStatement",
        "start": 60,
        "end": 90,
        "loc": {
          "start": {
            "line": 4,
            "column": 5
          },
          "end": {
            "line": 6,
            "column": 1
          }
        },
        "range": [
          60,
          90
        ],
        "body": [
          {
            "type": "ExpressionStatement",
            "start": 66,
            "end": 88,
            "loc": {
              "start": {
                "line": 5,
                "column": 4
              },
              "end": {
                "line": 5,
                "column": 26
              }
            },
            "range": [
              66,
              88
            ],
            "expression": {
              "type": "CallExpression",
              "start": 66,
              "end": 87,
              "loc": {
                "start": {
                  "line": 5,
                  "column": 4
                },
                "end": {
                  "line": 5,
                  "column": 25
                }
              },
              "range": [
                66,
                87
              ],
              "callee": {
                "type": "MemberExpression",
                "start": 66,
                "end": 77,
                "loc": {
                  "start": {
                    "line": 5,
                    "column": 4
                  },
                  "end": {
                    "line": 5,
                    "column": 15
                  }
                },
                "range": [
                  66,
                  77
                ],
                "object": {
                  "type": "Identifier",
                  "start": 66,
                  "end": 73,
                  "loc": {
                    "start": {
                      "line": 5,
                      "column": 4
                    },
                    "end": {
                      "line": 5,
                      "column": 11
                    }
                  },
                  "range": [
                    66,
                    73
                  ],
                  "name": "console"
                },
                "property": {
                  "type": "Identifier",
                  "start": 74,
                  "end": 77,
                  "loc": {
                    "start": {
                      "line": 5,
                      "column": 12
                    },
                    "end": {
                      "line": 5,
                      "column": 15
                    }
                  },
                  "range": [
                    74,
                    77
                  ],
                  "name": "log"
                },
                "computed": false
              },
              "arguments": [
                {
                  "type": "Literal",
                  "start": 78,
                  "end": 86,
                  "loc": {
                    "start": {
                      "line": 5,
                      "column": 16
                    },
                    "end": {
                      "line": 5,
                      "column": 24
                    }
                  },
                  "range": [
                    78,
                    86
                  ],
                  "value": "Aliens",
                  "raw": "\"Aliens\""
                }
              ]
            }
          }
        ]
      }
    }
  ],
  "sourceType": "module"
}

After looking at code for computers....

Let's make it beautiful

Why do we care

  • Do you lint your code?
  • Do you transpile your code?
  • Do you use IDE with auto-suggest?
  • Do you format your code?

JavaScript ecosystem relies heavily on AST

const pow = (x) => x ** 2;
var pow = function pow(x) {
  return Math.pow(x, 2);
};
const hi = `hi`;
// Do not use template literals (at 1:12)
   const hi = `hi`;
// -----------^

AST are everywhere

Thank You

@gyandeeps

AST for Beginners

By Gyandeep Singh

AST for Beginners

AST for Beginners

  • 160