
@babel/how-to @NicoloRibaudo NICOLÒ RIBAUDO Babel team @NicoloRibaudo [email protected] @nicolo-ribaudo @NicoloRibaudo 2 https://opencollective.com/babel @babeljs https://babeljs.io @babel @NicoloRibaudo 3 What is Babel? @NicoloRibaudo 4 What is Babel? Babel is a JavaScript compiler @NicoloRibaudo 5 [square] StackCheck const square = n => n ** 2; Ldar a0 ExpSmi [2], [0] Return @NicoloRibaudo 6 [square] StackCheck const square = n => n ** 2; Ldar a0 ExpSmi [2], [0] Return @NicoloRibaudo 7 It’s a JavaScript to JavaScript compiler var square = function (n) { const square = n => n ** 2; return Math.pow(n, 2); }; @NicoloRibaudo 8 Compilers’ data structure: Abstract Syntax Tree (AST) @NicoloRibaudo 9 A naive approach to compilation: Regular Expressions n => n ** 2 @NicoloRibaudo 10 A naive approach to compilation: Regular Expressions n => n ** 2 /(\w+)\s*\*\*\s*(\w+)/ Words or numbers Spaces @NicoloRibaudo 11 A naive approach to compilation: Regular Expressions n => n ** 2 Math.pow($1, $2) /(\w+)\s*\*\*\s*(\w+)/ Words or numbers Spaces @NicoloRibaudo 12 A naive approach to compilation: Regular Expressions n => n ** 2 Math.pow($1, $2) /(\w+)\s*\*\*\s*(\w+)/ Words or numbers Spaces n => Math.pow(n, 2) @NicoloRibaudo 13 A naive approach to compilation: Regular Expressions ☹ @NicoloRibaudo 14 A naive approach to compilation: Regular Expressions COMPLEXITY ☹ INACCURACY fn(a) ** (2 ** 3) "8" !== "2 ** 3" @NicoloRibaudo 15 Abstract Syntax Tree n => n ** 2 ArrowFunctionExpression params body Identifier → n BinaryExpression → ** left right Identifier → n NumericLiteral → 2 @NicoloRibaudo 16 Abstract Syntax Tree n => n ** 2 ArrowFunctionExpression params body Identifier → n BinaryExpression → ** left right Identifier → n NumericLiteral → 2 @NicoloRibaudo 17 Abstract Syntax Tree n => n ** 2 ArrowFunctionExpression params body Identifier → n BinaryExpression → ** left right Identifier → n NumericLiteral → 2 @NicoloRibaudo 18 Abstract Syntax Tree n => n ** 2 ArrowFunctionExpression params body Identifier → n BinaryExpression → ** left right Identifier → n NumericLiteral → 2 @NicoloRibaudo 19 Abstract Syntax Tree n => n ** 2 ArrowFunctionExpression params body Identifier → n BinaryExpression → ** left right Identifier → n NumericLiteral → 2 @NicoloRibaudo 20 Abstract Syntax Tree n => n ** 2 ArrowFunctionExpression params body Identifier → n BinaryExpression → ** left right Identifier → n NumericLiteral → 2 @NicoloRibaudo 21 AST node replacement BinaryExpression → ** left right CallExpression ? ? callee args Math.pow ? ? @NicoloRibaudo 22 AST node replacement ArrowFunctionExpression n => Math.pow(n, 2) params body Identifier → n CallExpression callee args Math.pow Identifier → n NumericLiteral → 2 @NicoloRibaudo 23 AST node replacement @NicoloRibaudo 24 AST node replacement COMPLEXITY INACCURACY fn(a) ** (2 ** 3) "8" !== "2 ** 3" ? ** ? StringLiteral → "2 ** 3" @NicoloRibaudo 25 Babel's AST { { "type": "BinaryExpression", "type": "CallExpression", "operator": "**", "callee": { /* ... */ }, "left": { "arguments": [{ "type": "Identifier", "type": "Identifier", "name": "n" "name": "n" }, }, { "right": { "type": "NumericLiteral", "type": "NumericLiteral", "value": 2 "value": 2 }] } } } @NicoloRibaudo 26 A look inside Babel @NicoloRibaudo 27 A look inside Babel Input source code Original AST Transformed AST Output source code @NicoloRibaudo 28 A look inside Babel @babel/parser @babel/traverse @babel/generator Input source code Original AST Transformed AST Output source code @NicoloRibaudo 29 A look inside Babel @babel/parser @babel/traverse @babel/generator Input source code Original AST Transformed AST Output source code @babel/core @NicoloRibaudo 30 A look inside Babel: @babel/parser @NicoloRibaudo 31 1. Lexical analysis Transform the input source code into a list of tokens var a = 7; @NicoloRibaudo 32 1. Lexical analysis Transform the input source code into a list of tokens var a = 7; 1. Keyword var @NicoloRibaudo 33 1. Lexical analysis Transform the input source code into a list of tokens var a = 7; 1. Keyword var 2. Identifier a @NicoloRibaudo 34 1. Lexical analysis Transform the input source code into a list of tokens var a = 7; 1. Keyword var 2. Identifier a 3. Punctuator = @NicoloRibaudo 35 1. Lexical analysis Transform the input source code into a list of tokens var a = 7; 1. Keyword var 2. Identifier a 3. Punctuator = 4. Literal 7 @NicoloRibaudo 36 1. Lexical analysis Transform the input source code into a list of tokens var a = 7; 1. Keyword var 2. Identifier a 3. Punctuator = 4. Literal 7 5. Punctuator ; @NicoloRibaudo 37 1. Lexical analysis Report errors about invalid literals or characters @NicoloRibaudo 38 1. Lexical analysis Report errors about invalid literals or characters Unterminated comment /* var a = 7; @NicoloRibaudo 39 1. Lexical analysis Report errors about invalid literals or characters Unterminated comment /* var a = 7; Unexpected character '°' var a = 7°; @NicoloRibaudo 40 1. Lexical analysis Report errors about invalid literals or characters Unterminated comment /* var a = 7; Unexpected character '°' var a = 7°; Expected number in radix 2 var a = 0b20; @NicoloRibaudo 41 2. Syntax analysis Transform the list of tokens into an AST var a = 7; @NicoloRibaudo 42 2. Syntax analysis Transform the list of tokens into an AST var a = 7; VariableDeclaration → var @NicoloRibaudo 43 2. Syntax analysis Transform the list of tokens into an AST var a = 7; VariableDeclaration → var declarations VariableDeclarator @NicoloRibaudo 44 2. Syntax analysis Transform the list of tokens into an AST var a = 7; VariableDeclaration → var declarations VariableDeclarator id Identifier → a @NicoloRibaudo 45 2. Syntax analysis Transform the list of tokens into an AST var a = 7; VariableDeclaration → var declarations VariableDeclarator id Identifier → a @NicoloRibaudo 46 2. Syntax analysis Transform the list of tokens into an AST var a = 7; VariableDeclaration → var declarations VariableDeclarator id init Identifier → a NumericLiteral → 7 @NicoloRibaudo 47 2. Syntax analysis Transform the list of tokens into an AST var a = 7; VariableDeclaration → var declarations VariableDeclarator id init Identifier → a NumericLiteral → 7 @NicoloRibaudo 48 2. Syntax analysis Transform the list of tokens into an AST var a = 7; VariableDeclaration → var declarations VariableDeclarator id init Identifier → a NumericLiteral → 7 @NicoloRibaudo 49 2. Syntax analysis Handle automatic semicolon insertion (ASI) @NicoloRibaudo 50 2. Syntax analysis Handle automatic semicolon insertion (ASI) var a = foo foo.forEach(fn) @NicoloRibaudo 51 2. Syntax analysis Handle automatic semicolon insertion (ASI) var a = foo var a = foo; foo.forEach(fn) foo.forEach(fn); @NicoloRibaudo 52 2. Syntax analysis Handle automatic semicolon insertion (ASI) var a = foo var a = foo; foo.forEach(fn) foo.forEach(fn); var a = foo [7].forEach(fn) @NicoloRibaudo 53 2. Syntax analysis Handle automatic semicolon insertion (ASI) var a = foo var a = foo; foo.forEach(fn) foo.forEach(fn); var a = foo var a = foo[7].forEach(n); [7].forEach(fn) @NicoloRibaudo 54 2. Syntax analysis Report errors about misplaced tokens @NicoloRibaudo 55 2. Syntax analysis Report errors about misplaced tokens Unexpected token, expected ")" var a = double(7; @NicoloRibaudo 56 2. Syntax analysis Report errors about misplaced tokens Unexpected token, expected ")" var a = double(7; Unexpected keyword 'if' 1 + if; @NicoloRibaudo 57 3. Semantic analysis Check the AST respects all the static ECMAScript rules: early errors @NicoloRibaudo 58 3. Semantic analysis Check the AST respects all the static ECMAScript rules: early errors Redefinition of __proto__ ({ __proto__: x, property __proto__: y, }) @NicoloRibaudo 59 3. Semantic analysis Check that the AST respects all the static ECMAScript rules: early errors Redefinition of __proto__ ({ __proto__: x, property __proto__: y, }) 'with' in strict mode "use strict"; with (obj) {} @NicoloRibaudo 60 3. Semantic analysis Report errors about invalid variables, using a scope tracker @NicoloRibaudo 61 3. Semantic analysis Report errors about invalid variables, using a scope tracker Identifier 'foo' has let foo = 2; already been declared let foo = 3; @NicoloRibaudo 62 3. Semantic analysis Report errors about invalid variables, using a scope tracker Identifier 'foo' has let foo = 2; already been declared let foo = 3; Export 'bar' is not { let bar = 2 } defined export { bar }; @NicoloRibaudo 63 A look inside Babel: @babel/traverse @NicoloRibaudo 64 Declarative traversal Algorithm: Depth-first search, in-order (enter) and out-order (exit) traverse(ast, { CallExpression: { enter() { console.log("Function call!") } } }) @NicoloRibaudo 65 Declarative traversal Algorithm: Depth-first search, in-order (enter) and out-order (exit) traverse(ast, { CallExpression: { enter() { console.log("Function call!") } } }) @NicoloRibaudo 66 Declarative traversal Algorithm: Depth-first search, in-order (enter) and out-order (exit) traverse(ast, { CallExpression: { enter() { console.log("Function call!") } } }) @NicoloRibaudo 67 Declarative traversal Algorithm: Depth-first search, in-order (enter) and out-order (exit) traverse(ast, { CallExpression: { enter is the default enter() { traversal order console.log("Function call!") } } }) @NicoloRibaudo 68 Declarative traversal Algorithm: Depth-first search, in-order (enter) and out-order (exit) traverse(ast, { CallExpression() { enter is the default traversal order console.log("Function call!") } }) @NicoloRibaudo 69 Dynamic Abstract Syntax Tree 1 + fn(3) Example: 1 + [6, fn] ➔ Traverse 1 + fn(3)
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages165 Page
-
File Size-