Slide 1

Slide 1 text

JavaScript AST͜ͱ͸͡Ί

Slide 2

Slide 2 text

Agenda • JavaScript ASTͱ͸Կ͔? • JavaScript ASTͷجૅ஌ࣝ • JavaScript AST࢖ͬͯԿ͔ͯ͠ΈΔ

Slide 3

Slide 3 text

JavaScript ASTͱ͸Կ͔?

Slide 4

Slide 4 text

ͦ΋ͦ΋ASTͱ͸ ͦ΋ͦ΋AST͸ந৅ߏจ໦ͷӳޠ໊Ͱ͋Δabstract syntax treeͷུ শʹͳΓ·͢ɻίϯύΠϥͱ͔ΠϯλϓϦλͳͲͷݴޠॲཧܥͷ தؒॲཧʹྑ͘࢖ΘΕΔख๏Ͱ͢ɻ(ͳ͓؊ػೳͷ਺஋ʹ΋ಉ͡ ASTͱ͍͏ུশ͕͋Δ໛༷) h"ps:/ /en.wikipedia.org/wiki/Abstractsyntaxtree

Slide 5

Slide 5 text

ͦ΋ͦ΋ASTͱ͸ ΩϞͱͯ͠͸ॻ͔Ε͍ͯΔϓϩάϥϜΛߏจղੳͯ͠ߏ଄Խʹෆ ཁͳ෦෼͸࡟আͯ͠ɺ໦ߏ଄ͱͯ͠දݱ͍ͯ͠Δσʔλʹ͢Δͱ ͍͏ͱ͜ΖͰ͢ɻ

Slide 6

Slide 6 text

ͦ΋ͦ΋ASTͱ͸ ͜ͷASTࣗମ͸ಛʹJSݻ༗ͷ΋ͷͱ͍͏Θ͚Ͱ͸ͳ͘ɺ৭ʑͳݴ ޠͰ࢖ΘΕ͍ͯ·͢ɻྫ͑͹JavaͰ࢖ΘΕΔIDEͷEclipseͰ΋Java ͷߏจղੳʹ࢖ͬͯͨΓ͢ΔͬΆ͍Ͱ͢ɻ h"p:/ /www.eclipse.org/ar1cles/Ar1cle- JavaCodeManipula1on_AST/index.html ͜ͷASTʹ͍ۙख๏Ͱ(ݫີʹ͸ҧ͏)ߏங͞Ε͍ͯΔͷ͕਎ۙͰ͍ ͏ͱDOMͩͬͨΓ΋͠·͢ɻ

Slide 7

Slide 7 text

JavaScript AST͸Ͳ͜Ͱ࢖ΘΕ͍ͯΔͷ͔? • React • Babel • UglifyJS • ESLint • PowerAssert ͳͲͳͲ

Slide 8

Slide 8 text

JavaScript AST͸Ͳ͜Ͱ࢖ΘΕ͍ͯΔͷ͔? ҰྫͰ͕͢ݱࡏͷϑϩϯτΤϯυ։ൃʹ͸͔ܽͤͳ͍ϓϩμΫτ ͸େମ࢖ΘΕͯΔΜ͡Όͳ͍Ͱ͠ΐ͏͔ɻ มΘΓμωͱͯ͠ಠࣗʹJSͷϚΫϩΛ࡞ΕΔsweet-js/sweet-core ͳΜ͔Ͱ΋࢖ΘΕ͍ͯ·͢ɻ

Slide 9

Slide 9 text

JavaScriptք۾ͰͷASTͷաڈ JSք۾ͰͷASTͷऔΓѻ͍ͳͲͷ࿩͸ผʹྺ࢙Λશ෦஌ͬͯΔΘ ͚͡Όͳ͍ΜͰ͕͢ɺ͔͍ͭ·ΉͱҎԼͷΑ͏ͳྲྀΕʹͳΔ͔ ΋ɻ

Slide 10

Slide 10 text

JavaScriptք۾ͰͷASTͷաڈ • FirefoxͰ࢖ΘΕ͍ͯͨSpiderMonkyͰ2010೥ʹParser API͕౥ ࡌ͞Εͨ • Parser APIͷJSϙʔτͷzaach/reflect.js͕2011೥4݄͘Β͍ʹϦ Ϧʔε

Slide 11

Slide 11 text

JavaScriptք۾ͰͷASTͷաڈ • JavaScript ASTͰຊ֨తʹ࢖ΘΕͩͨ͠jquery/esprima͕2011೥ 11݄͘Β͍ʹϦϦʔε • ݩʑ͸࡞ऀͷAriya͞ΜͷݸਓϓϩδΣΫτ͚ͩͬͨͲɺ3೥ ͘Β͍લʹjQueryࡒஂʹҠ؅ • esprima஗͍͗ͬͯͬͯ͢acornjs/acorn͕ొ৔

Slide 12

Slide 12 text

JavaScriptք۾ͰͷASTͷաڈ • ࠷ॳ͸acorn࢖ͬͯͨBabel͕೿ੜͤͯࣗ͞લͰbabel/babylonΛ 2012೥9݄͘Β͍͔Β࡞ͬͨΓ • ࢓༷֎ͷ͜ͱ΋Ͱ͖ΔΑ͏ʹ֦ு͞ΕͯΔ • JavaScript ASTΛ࡞ΔϥΠϒϥϦ͕৭ʑग़͖ͯͯޓ׵ੑ͕͋ͬͨ Γແ͔ͬͨΓͱ͍͏ঢ়گͩͬͨͷΛ2015೥ʹjQueryࡒஂ΍ Mozilla΋ೖͬͯestree/estreeͱ͍͏JavaScript ASTͷඪ४ن͕֨ Ͱ͖Δ

Slide 13

Slide 13 text

JavaScriptք۾ͰͷASTͷաڈ ͜Μͳײ͡Ͱݱࡏ৭ʑͳϓϩμΫτͰ࢖ΘΕ͍ͯΔJavaScript AST ϥΠϒϥϦ͕৭ʑͰ͖͖ͯ·ͨ͠ɻ ༗໊ॴΛϐοΫΞοϓ͚ͨͩ͠ͳΜͰɺѥྲྀͷύʔα΋৭ʑ͋Γ ྫ͑͹ESLintͳΜ͔͸ݱࡏesprimaͱޓ׵ੑ͕͋Δeslint/espreeͱ ͍͏ύʔαΛࣗલͰ࡞ͬͯ࢖ͬͯͨΓ͠·͢ɻ

Slide 14

Slide 14 text

JavaScript ASTͷجૅ஌ࣝ

Slide 15

Slide 15 text

JavaScript AST͸࣮ࡍͲΜͳίʔυʹͳΔͷ͔ JavaScript AST͸ιʔείʔυΛ໦ߏ଄ʹม׵ͯ͠ɺ࠷ऴతʹ JSONܗࣜʹͯ͠දݱ͍͖ͯ͠·͢ɻ ԼهͷΑ͏ͳ؆୯ͳJSίʔυΛྫʹऔΓ·͢ɻ var hello = 'Hello World'; function sayHello() { console.log(hello) }

Slide 16

Slide 16 text

JavaScript AST͸࣮ࡍͲΜͳίʔυʹͳΔͷ͔ ࠓճ͸acornΛ࢖ͬͯASTʹม׵͢ΔͱԼهͷΑ͏ͳJSONܗ͕ࣜ Ͱ͖·͢ɻ { "type": "Program", "start": 0, "end": 69, "body": [ { "type": "VariableDeclaration", "start": 0, "end": 26, "declarations": [ { "type": "VariableDeclarator", "start": 4, "end": 25, "id": { "type": "Identifier", "start": 4, "end": 9, "name": "hello" }, "init": { "type": "Literal", "start": 12, "end": 25, "value": "Hello World", "raw": "'Hello World'" } } ], "kind": "var" }, { "type": "FunctionDeclaration", "start": 27, "end": 69, "id": { "type": "Identifier", "start": 36, "end": 44, "name": "sayHello" }, "generator": false, "expression": false, "params": [], "body": { "type": "BlockStatement", "start": 47, "end": 69, "body": [ { "type": "ExpressionStatement", "start": 49, "end": 67, "expression": { "type": "CallExpression", "start": 49, "end": 67, "callee": { "type": "MemberExpression", "start": 49, "end": 60, "object": { "type": "Identifier", "start": 49, "end": 56, "name": "console" }, "property": { "type": "Identifier", "start": 57, "end": 60, "name": "log" }, "computed": false }, "arguments": [ { "type": "Identifier", "start": 61, "end": 66, "name": "hello" } ] } } ] } } ], "sourceType": "module" }

Slide 17

Slide 17 text

JavaScript AST͸࣮ࡍͲΜͳίʔυʹͳΔͷ͔ શવಡΊͳ͍ͱࢥ͏ͷͰɺ෼͔Γ΍͍͢Α͏ͳπϦʔܗࣜͷεΫ γϣ͕ͪ͜Βɻ

Slide 18

Slide 18 text

JavaScript ASTͷม׵ϧʔϧ ͲͷΑ͏ʹม׵͞ΕΔ͔?ͷϧʔϧ͸࢖͏ύʔαͷυΩϡϝϯτ ΍ɺParser API - Mozilla | MDNɺestree/estree: The ESTree Specͳ Μ͔Λࢀߟʹ͠·͢ɻ΋͏ͪΐ͍ಥͬ͜Μͩ࿩Ͱ͍͏ͱ ECMAScriptͷ࢓༷ॻ΋߹ΘͤͯಡΉͱΑ͍͔΋͠Εͳ͍Ͱ͢ɻ • h#ps:/ /developer.mozilla.org/en-US/docs/Mozilla/Projects/ SpiderMonkey/Parser_API • h#ps:/ /github.com/estree/estree • h#ps:/ /www.ecma-internaEonal.org/ecma-262/8.0/index.html

Slide 19

Slide 19 text

ύʔαͰม׵͞Εͨ΋ͷͨͪͷઆ໌ ͞Βͬͱࠓճͷ΋ͷΛୈೋ֊૚·Ͱઆ໌͢Δͱɺ͜Μͳײ͡Ͱ͢ • Program • ϧʔτʹͳΔΦϒδΣΫτ • Կ͸ͳ͘ͱ΋ઈରʹม׵͢Δͱ࡞ΒΕΔ • ϓϩάϥϜ͸શ෦͜ͷ߲໨ͷbodyʹ໦ߏ଄Ͱ֨ೲ͞ΕΔ

Slide 20

Slide 20 text

ύʔαͰม׵͞Εͨ΋ͷͨͪͷઆ໌ • VariableDeclaration • var hello = 'Hello World';ͷ෦෼ • ม਺એݴ͸͜ͷ߲໨ʹͳΔ • kind͕ม਺એݴͷΩʔϫʔυͷछྨʹͳΔɻ • declarations͕એݴ͞Ε͍ͯΔ಺༰Λ֨ೲ͍ͯ͠Δ෦෼ • ม਺໊΍ॳظ஋ʹԿ͕ೖ͍ͬͯΔͳͲ͕֨ೲ

Slide 21

Slide 21 text

ύʔαͰม׵͞Εͨ΋ͷͨͪͷઆ໌ • FunctionDeclaration • function sayHello() { console.log(hello) }ͷ෦ ෼ • ؔ਺એݴ͸͜ͷ߲໨ʹͳΔ • id͕ؔ਺໊ͳͲ֨ೲ͍ͯ͠Δ෦෼ • params͸ࠓճۭ͕ͩɺԾҾ਺Λ֨ೲ͍ͯ͠Δ෦෼

Slide 22

Slide 22 text

ݸੑ๛͔ͳύʔαͨͪ Ͳͷύʔαʔ΋جຊͱͯ͠͸͜ΕΒͷ߲໨͸ESTreeͰఆٛ͞Εͯ ͍Δ΋ͷΛ࢖͍ͬͯΔͷͰ͕͢ɺࡉ͔͍ҧ͍͕͋ͬͨΓɺ bablylonͷΑ͏ʹಠࣗͰ৭ʑͳ߲໨ΛೖΕ͍ͯͨΓ͢Δͱ͍͏ײ ͡ʹͳ͍͖ͬͯ·͢ɻ h"ps:/ /github.com/babel/babylon/blob/master/ast/spec.md

Slide 23

Slide 23 text

JavaScript ASTͷ࢖͍Ͳ͜Ζ ͜͜·Ͱجຊతͳ࿩Λ͖ͯ͠·͕ͨ͠ɺͰ͸JavaScript ASTΛࣗ෼ ୡͰ࢖͏৔߹…Ͳ͏͍͏ͱ͖Ͱ͠ΐ͏͔?ͺͬͱࢥ͍ͭ͘ͱ͜Ζ͸ ͜Μͳײ͔͡ͳ͋ͱɻ - babelͷϓϥάΠϯ࡞੒ - eslintͷϓϥάΠϯ࡞੒ - ࣗલͰιʔείʔυΛมߋ͢Δ(APIมߋͳΜ͔ͷ)πʔϧ࡞Δͱ͖

Slide 24

Slide 24 text

JavaScript ASTͷ࢖͍Ͳ͜Ζ ݸਓతʹ͸ڊਓͷݞʹ৐͔ͬΓ͍ͨͷͰɺ༻్͕ϓϥάΠϯ࡞੒ ʹͳͬͨΓͯ͠·͕͢ɺJavaScript ASTͷ࢓૊ΈΛ࢖͑͹ࣗલͷτ ϥϯεύΠϥΛ࡞ͬͨΓ΋Ͱ͖Δ͸ͣͰ͢ɻ ࣮ࡍʹJavaScript ASTΛ࢖ͬͯJSΛੜ੒͢Δʹ͸ɺ঺հͨ͠ύʔα ͷଞʹASTΛtraverseͯ͠ॲཧ͢ΔϥΠϒϥϦ(estraverseͳͲ)΍ AST͔ΒJSΛੜ੒͢ΔϥΠϒϥϦ(escodegenͳͲ)͕ඞཁʹͳΓ· ͢ɻ

Slide 25

Slide 25 text

JavaScript AST࢖ͬͯԿ͔ͯ͠ΈΔ

Slide 26

Slide 26 text

AST Explore ࠷ޙʹͪΐͬͱ࣮ͨ͠ྫΛ͝঺հͯ͠ऴΘΓ·͕͢ɺͦͷલʹ JavaScript ASTΛѻ͏ͷʹແͯ͘͸ͳΒͳ͍πʔϧ͕͋ΔͷͰ঺ հɻ

Slide 27

Slide 27 text

AST Explore AST Explore: h.p:/ /astexplorer.net/

Slide 28

Slide 28 text

AST Explore ͜ͷαΠτ͸JavaScript AST͚ͩͰ͸ͳ͘ଞͷ৭ʑͳݴޠͷύʔα ΍ίʔυδΣωϨʔλ͕ΦϯϥΠϯͰ؆୯ʹͰ͖ΔΑ͏ʹͳͬͯ ͍ΔαΠτͰ͢ɻ JSBin΍JSFiddleͷAST൛ͱ͍͏ײ͡ɻSave͢ΔͱύʔϚϦϯΫ࡞ ͬͯ͘ΕͨΓASTͷπϦʔ͕ݟ΍͔ͬͨ͢Γ͢ΔπʔϧͰ͢ɻ ࢖͍͍ͨύʔα΍δΣωϨʔλ΋৭ʑͳछྨ͔Βબ΂·͢ɻࠓճ ͷྫ΋͜ͷπʔϧ࢖ͬͯ঺հ͠·͢ɻ

Slide 29

Slide 29 text

var Ͱॻ͔ΕͨJSΛconstʹॻ͖͔͑Δ ύʔα: babylon v7 / τϥϯεύΠϥ: babel7 DEMO: varΩϥΠ

Slide 30

Slide 30 text

Vue.js 1.xܥ͔Β2.xܥͷϚΠάϨʔγϣϯʹ଱͑Δ ύʔα: acorn / τϥϯεύΠϥ: jscodeshi/ h"ps:/ /vuejs.org/v2/guide/migra4on.html#a"ached-removed DEMO: a(atchͷϚΠάϨʔγϣϯ

Slide 31

Slide 31 text

ऴΘΓ

Slide 32

Slide 32 text

ࢀߟ • h#ps:/ /speakerdeck.com/michaelficarra/spidermonkey-parser- api-a-standard-for-structured-js-representa;ons • h#p:/ /azu.github.io/slide/JSojisan/#1 • h#ps:/ /efcl.info/2016/03/06/ast-first-step/ • h#ps:/ /efcl.info/2015/02/26/recent-js-ast/ • h#ps:/ /medium.com/@jotadeveloper/abstract-syntax-trees-on- javascript-534e33361fc7

Slide 33

Slide 33 text

ࢀߟ • h#ps:/ /www.sitepoint.com/understanding-asts-building-babel- plugin/ • h#ps:/ /github.com/jamiebuilds/babel-handbook • h#ps:/ /github.com/facebook/jscodeshi<