ast shape shifting pseudo note variables

This commit is contained in:
Felix Roos 2022-02-09 20:11:16 +01:00
parent ce579e48a6
commit 9ed198db28
29 changed files with 11174 additions and 12 deletions

3
.gitignore vendored
View File

@ -23,4 +23,5 @@ cabal.project.local~
.HTF/
.ghc.environment.*
node_modules/
.DS_Store
.DS_Store
repl-parcel

268
repl/package-lock.json generated
View File

@ -7,9 +7,16 @@
"dependencies": {
"@tonaljs/tonal": "^4.6.5",
"codemirror": "^5.65.1",
"estraverse": "^5.3.0",
"react": "^17.0.2",
"react-codemirror2": "^7.2.1",
"react-dom": "^17.0.2",
"shift-ast": "^6.1.0",
"shift-codegen": "^7.0.3",
"shift-parser": "^7.0.3",
"shift-reducer": "6.0.0",
"shift-spec": "^2018.0.2",
"shift-traverser": "^1.0.0",
"tone": "^14.7.77"
},
"devDependencies": {
@ -3757,12 +3764,28 @@
"fsevents": "~2.1.2"
}
},
"node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"engines": {
"node": ">=4.0"
}
},
"node_modules/estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
},
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@ -5578,6 +5601,11 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"node_modules/multimap": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz",
"integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw=="
},
"node_modules/nanocolors": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz",
@ -7248,6 +7276,87 @@
"node": ">=8"
}
},
"node_modules/shift-ast": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.1.0.tgz",
"integrity": "sha512-Vj4XUIJIFPIh6VcBGJ1hjH/kM88XGer94Pr7Rvxa+idEylDsrwtLw268HoxGo5xReL6T3DdRl/9/Pr1XihZ/8Q=="
},
"node_modules/shift-codegen": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-codegen/-/shift-codegen-7.0.3.tgz",
"integrity": "sha512-dfCVVdBF0qZ6pkajQ3bjxRdNEltyxEITVe7tBJkQt2eCI3znUkSxq0VSe/tTWq1LKHeAS4HuOiqYEuHMFkSq9w==",
"dependencies": {
"esutils": "^2.0.2",
"object-assign": "^4.1.0",
"shift-reducer": "6.0.0"
}
},
"node_modules/shift-parser": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-parser/-/shift-parser-7.0.3.tgz",
"integrity": "sha512-uYX2ORyZfKZrUc4iKKkO9KOhzUSxCrSBk7QK6ZmShId+BOo1gh1IwecVy97ynyOTpmhPWUttjC8BzsnQl65Zew==",
"dependencies": {
"multimap": "^1.0.2",
"shift-ast": "6.0.0",
"shift-reducer": "6.0.0",
"shift-regexp-acceptor": "2.0.3"
}
},
"node_modules/shift-parser/node_modules/shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
},
"node_modules/shift-reducer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-reducer/-/shift-reducer-6.0.0.tgz",
"integrity": "sha512-2rJraRP8drIOjvaE/sALa+0tGJmMVUzlmS3wIJerJbaYuCjpFAiF0WjkTOFVtz1144Nm/ECmqeG+7yRhuMVsMg==",
"dependencies": {
"shift-ast": "6.0.0"
}
},
"node_modules/shift-reducer/node_modules/shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
},
"node_modules/shift-regexp-acceptor": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/shift-regexp-acceptor/-/shift-regexp-acceptor-2.0.3.tgz",
"integrity": "sha512-sxL7e5JNUFxm+gutFRXktX2D6KVgDAHNuDsk5XHB9Z+N5yXooZG6pdZ1GEbo3Jz6lF7ETYLBC4WAjIFm2RKTmA==",
"dependencies": {
"unicode-match-property-ecmascript": "1.0.4",
"unicode-match-property-value-ecmascript": "1.0.2",
"unicode-property-aliases-ecmascript": "1.0.4"
}
},
"node_modules/shift-spec": {
"version": "2018.0.2",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.2.tgz",
"integrity": "sha512-5CP/cKDEim4rZ6ViCSipTLY2U7HJr8q/kpDuCBmebFqbx/0DeozWO+9ienHmYjgGLDfHrqj+LBAN67FRK2vE6w=="
},
"node_modules/shift-traverser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shift-traverser/-/shift-traverser-1.0.0.tgz",
"integrity": "sha512-DMY3512wJbdC+IC+nhLH3/Stgr2BbxbNcg7qyZ6+e5qNnNs8TBQJWdMsRgHlX1JXwF4C0ONKS8VUxsPT0Tf7aw==",
"dependencies": {
"estraverse": "4.2.0",
"shift-spec": "2018.0.0"
}
},
"node_modules/shift-traverser/node_modules/estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/shift-traverser/node_modules/shift-spec": {
"version": "2018.0.0",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.0.tgz",
"integrity": "sha512-/aiPOkj7dbe+CV2VZhIMTHQToZmgniofpRG7Yr7x2/0sO6CSVC++py1Wzf+s+rWSTDHKcLvziVAxjRRV4i4EoQ=="
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@ -8228,6 +8337,42 @@
"through": "^2.3.8"
}
},
"node_modules/unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
"integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/unicode-match-property-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
"integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
"dependencies": {
"unicode-canonical-property-names-ecmascript": "^1.0.4",
"unicode-property-aliases-ecmascript": "^1.0.4"
},
"engines": {
"node": ">=4"
}
},
"node_modules/unicode-match-property-value-ecmascript": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz",
"integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/unicode-property-aliases-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz",
"integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==",
"engines": {
"node": ">=4"
}
},
"node_modules/unique-filename": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
@ -11624,12 +11769,22 @@
}
}
},
"estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
},
"estree-walker": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@ -13032,6 +13187,11 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"multimap": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz",
"integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw=="
},
"nanocolors": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.13.tgz",
@ -14258,6 +14418,90 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"shift-ast": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.1.0.tgz",
"integrity": "sha512-Vj4XUIJIFPIh6VcBGJ1hjH/kM88XGer94Pr7Rvxa+idEylDsrwtLw268HoxGo5xReL6T3DdRl/9/Pr1XihZ/8Q=="
},
"shift-codegen": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-codegen/-/shift-codegen-7.0.3.tgz",
"integrity": "sha512-dfCVVdBF0qZ6pkajQ3bjxRdNEltyxEITVe7tBJkQt2eCI3znUkSxq0VSe/tTWq1LKHeAS4HuOiqYEuHMFkSq9w==",
"requires": {
"esutils": "^2.0.2",
"object-assign": "^4.1.0",
"shift-reducer": "6.0.0"
}
},
"shift-parser": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/shift-parser/-/shift-parser-7.0.3.tgz",
"integrity": "sha512-uYX2ORyZfKZrUc4iKKkO9KOhzUSxCrSBk7QK6ZmShId+BOo1gh1IwecVy97ynyOTpmhPWUttjC8BzsnQl65Zew==",
"requires": {
"multimap": "^1.0.2",
"shift-ast": "6.0.0",
"shift-reducer": "6.0.0",
"shift-regexp-acceptor": "2.0.3"
},
"dependencies": {
"shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
}
}
},
"shift-reducer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-reducer/-/shift-reducer-6.0.0.tgz",
"integrity": "sha512-2rJraRP8drIOjvaE/sALa+0tGJmMVUzlmS3wIJerJbaYuCjpFAiF0WjkTOFVtz1144Nm/ECmqeG+7yRhuMVsMg==",
"requires": {
"shift-ast": "6.0.0"
},
"dependencies": {
"shift-ast": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/shift-ast/-/shift-ast-6.0.0.tgz",
"integrity": "sha512-XXxDcEBWVBzqWXfNYJlLyJ1/9kMvOXVRXiqPjkOrTCC5qRsBvEMJMRLLFhU3tn8ue56Y7IZyBE6bexFum5QLUw=="
}
}
},
"shift-regexp-acceptor": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/shift-regexp-acceptor/-/shift-regexp-acceptor-2.0.3.tgz",
"integrity": "sha512-sxL7e5JNUFxm+gutFRXktX2D6KVgDAHNuDsk5XHB9Z+N5yXooZG6pdZ1GEbo3Jz6lF7ETYLBC4WAjIFm2RKTmA==",
"requires": {
"unicode-match-property-ecmascript": "1.0.4",
"unicode-match-property-value-ecmascript": "1.0.2",
"unicode-property-aliases-ecmascript": "1.0.4"
}
},
"shift-spec": {
"version": "2018.0.2",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.2.tgz",
"integrity": "sha512-5CP/cKDEim4rZ6ViCSipTLY2U7HJr8q/kpDuCBmebFqbx/0DeozWO+9ienHmYjgGLDfHrqj+LBAN67FRK2vE6w=="
},
"shift-traverser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shift-traverser/-/shift-traverser-1.0.0.tgz",
"integrity": "sha512-DMY3512wJbdC+IC+nhLH3/Stgr2BbxbNcg7qyZ6+e5qNnNs8TBQJWdMsRgHlX1JXwF4C0ONKS8VUxsPT0Tf7aw==",
"requires": {
"estraverse": "4.2.0",
"shift-spec": "2018.0.0"
},
"dependencies": {
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"shift-spec": {
"version": "2018.0.0",
"resolved": "https://registry.npmjs.org/shift-spec/-/shift-spec-2018.0.0.tgz",
"integrity": "sha512-/aiPOkj7dbe+CV2VZhIMTHQToZmgniofpRG7Yr7x2/0sO6CSVC++py1Wzf+s+rWSTDHKcLvziVAxjRRV4i4EoQ=="
}
}
},
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@ -15001,6 +15245,30 @@
"through": "^2.3.8"
}
},
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
"integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ=="
},
"unicode-match-property-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
"integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
"requires": {
"unicode-canonical-property-names-ecmascript": "^1.0.4",
"unicode-property-aliases-ecmascript": "^1.0.4"
}
},
"unicode-match-property-value-ecmascript": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz",
"integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ=="
},
"unicode-property-aliases-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz",
"integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg=="
},
"unique-filename": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",

View File

@ -10,9 +10,13 @@
"dependencies": {
"@tonaljs/tonal": "^4.6.5",
"codemirror": "^5.65.1",
"estraverse": "^5.3.0",
"react": "^17.0.2",
"react-codemirror2": "^7.2.1",
"react-dom": "^17.0.2",
"shift-ast": "^6.1.0",
"shift-codegen": "^7.0.3",
"shift-spec": "^2018.0.2",
"tone": "^14.7.77"
},
"devDependencies": {

View File

@ -8,8 +8,9 @@ import * as tunes from './tunes';
import * as parser from './parse';
import CodeMirror from './CodeMirror';
import hot from '../public/hot';
import { isNote } from 'tone';
const { tetris, tetrisRev } = tunes;
const { tetris, tetrisRev, shapeShifted } = tunes;
const { parse } = parser;
const getHotCode = async () => {
@ -30,17 +31,18 @@ defaultSynth.set({
function App() {
const [mode, setMode] = useState<string>('javascript');
const [code, setCode] = useState<string>(tetrisRev);
const [code, setCode] = useState<string>(shapeShifted);
const [log, setLog] = useState('');
const logBox = useRef<any>();
const [error, setError] = useState<Error>();
const [pattern, setPattern] = useState<Pattern>();
const [activePattern, setActivePattern] = useState<Pattern>();
const [isHot, setIsHot] = useState(false); // set to true to enable live coding in hot.js, using dev server
const pushLog = (message: string) => setLog((log) => log + `${log ? '\n\n' : ''}${message}`);
// logs events of cycle
const logCycle = (_events: any, cycle: any) => {
if (_events.length) {
setLog((log) => log + `${log ? '\n\n' : ''}# cycle ${cycle}\n` + _events.map((e: any) => e.show()).join('\n'));
pushLog(`# cycle ${cycle}\n` + _events.map((e: any) => e.show()).join('\n'));
}
};
// cycle hook to control scheduling
@ -48,6 +50,9 @@ function App() {
onEvent: useCallback((time, event) => {
try {
if (typeof event.value === 'string') {
if (!isNote(event.value)) {
throw new Error('not a note: ' + event.value);
}
defaultSynth.triggerAttackRelease(event.value, event.duration, time);
/* console.warn('no instrument chosen', event);
throw new Error(`no instrument chosen for ${JSON.stringify(event)}`); */
@ -55,11 +60,10 @@ function App() {
const { onTrigger } = event.value;
onTrigger(time, event);
}
setError(undefined);
} catch (err: any) {
console.warn(err);
err.message = 'unplayable event: ' + err?.message;
setError(err);
pushLog(err.message); // not with setError, because then we would have to setError(undefined) on next playable event
}
}, []),
onQuery: useCallback(

View File

@ -3,6 +3,7 @@ import * as strudel from '../../strudel.mjs';
import { Scale, Note, Interval } from '@tonaljs/tonal';
import './tone';
import * as toneStuff from './tone';
import shapeshifter from './shapeshifter';
// even if some functions are not used, we need them to be available in eval
const { pure, stack, slowcat, fastcat, cat, sequence, polymeter, pm, polyrhythm, pr, /* reify, */ silence, Fraction } =
@ -114,6 +115,7 @@ export const parse: any = (code: string) => {
} catch (err) {
// code is not haskell like
mode = 'javascript';
code = shapeshifter(code);
_pattern = eval(code);
if (_pattern?.constructor?.name !== 'Pattern') {
const message = `got "${typeof _pattern}" instead of pattern`;

26
repl/src/shapeshifter.js Normal file
View File

@ -0,0 +1,26 @@
import { parseScript } from './shift-parser/index.js'; // npm module does not work in the browser
import traverser from './shift-traverser'; // npm module does not work in the browser
const { replace } = traverser;
import { LiteralStringExpression, IdentifierExpression } from 'shift-ast';
import codegen from 'shift-codegen';
const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name);
export default (code) => {
const ast = parseScript(code);
const shifted = replace(ast, {
enter(node, parent) {
// replace identifiers that are a note with a note string
if (node.type === 'IdentifierExpression') {
if (isNote(node.name)) {
const value = node.name[1] === 's' ? node.name.replace('s', '#') : node.name;
return new LiteralStringExpression({ value });
}
if (node.name === 'r') {
return new IdentifierExpression({ name: 'silence' });
}
}
},
});
return codegen(shifted);
};

View File

@ -0,0 +1,409 @@
/**
* Copyright 2014 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import MultiMap from 'multimap';
function addEach(thisMap, ...otherMaps) {
otherMaps.forEach(otherMap => {
otherMap.forEachEntry((v, k) => {
thisMap.set.apply(thisMap, [k].concat(v));
});
});
return thisMap;
}
let identity; // initialised below EarlyErrorState
export class EarlyErrorState {
constructor() {
this.errors = [];
// errors that are only errors in strict mode code
this.strictErrors = [];
// Label values used in LabeledStatement nodes; cleared at function boundaries
this.usedLabelNames = [];
// BreakStatement nodes; cleared at iteration; switch; and function boundaries
this.freeBreakStatements = [];
// ContinueStatement nodes; cleared at
this.freeContinueStatements = [];
// labeled BreakStatement nodes; cleared at LabeledStatement with same Label and function boundaries
this.freeLabeledBreakStatements = [];
// labeled ContinueStatement nodes; cleared at labeled iteration statement with same Label and function boundaries
this.freeLabeledContinueStatements = [];
// NewTargetExpression nodes; cleared at function (besides arrow expression) boundaries
this.newTargetExpressions = [];
// BindingIdentifier nodes; cleared at containing declaration node
this.boundNames = new MultiMap;
// BindingIdentifiers that were found to be in a lexical binding position
this.lexicallyDeclaredNames = new MultiMap;
// BindingIdentifiers that were the name of a FunctionDeclaration
this.functionDeclarationNames = new MultiMap;
// BindingIdentifiers that were found to be in a variable binding position
this.varDeclaredNames = new MultiMap;
// BindingIdentifiers that were found to be in a variable binding position
this.forOfVarDeclaredNames = [];
// Names that this module exports
this.exportedNames = new MultiMap;
// Locally declared names that are referenced in export declarations
this.exportedBindings = new MultiMap;
// CallExpressions with Super callee
this.superCallExpressions = [];
// SuperCall expressions in the context of a Method named "constructor"
this.superCallExpressionsInConstructorMethod = [];
// MemberExpressions with Super object
this.superPropertyExpressions = [];
// YieldExpression and YieldGeneratorExpression nodes; cleared at function boundaries
this.yieldExpressions = [];
// AwaitExpression nodes; cleared at function boundaries
this.awaitExpressions = [];
}
addFreeBreakStatement(s) {
this.freeBreakStatements.push(s);
return this;
}
addFreeLabeledBreakStatement(s) {
this.freeLabeledBreakStatements.push(s);
return this;
}
clearFreeBreakStatements() {
this.freeBreakStatements = [];
return this;
}
addFreeContinueStatement(s) {
this.freeContinueStatements.push(s);
return this;
}
addFreeLabeledContinueStatement(s) {
this.freeLabeledContinueStatements.push(s);
return this;
}
clearFreeContinueStatements() {
this.freeContinueStatements = [];
return this;
}
enforceFreeBreakStatementErrors(createError) {
[].push.apply(this.errors, this.freeBreakStatements.map(createError));
this.freeBreakStatements = [];
return this;
}
enforceFreeLabeledBreakStatementErrors(createError) {
[].push.apply(this.errors, this.freeLabeledBreakStatements.map(createError));
this.freeLabeledBreakStatements = [];
return this;
}
enforceFreeContinueStatementErrors(createError) {
[].push.apply(this.errors, this.freeContinueStatements.map(createError));
this.freeContinueStatements = [];
return this;
}
enforceFreeLabeledContinueStatementErrors(createError) {
[].push.apply(this.errors, this.freeLabeledContinueStatements.map(createError));
this.freeLabeledContinueStatements = [];
return this;
}
observeIterationLabel(label) {
this.usedLabelNames.push(label);
this.freeLabeledBreakStatements = this.freeLabeledBreakStatements.filter(s => s.label !== label);
this.freeLabeledContinueStatements = this.freeLabeledContinueStatements.filter(s => s.label !== label);
return this;
}
observeNonIterationLabel(label) {
this.usedLabelNames.push(label);
this.freeLabeledBreakStatements = this.freeLabeledBreakStatements.filter(s => s.label !== label);
return this;
}
clearUsedLabelNames() {
this.usedLabelNames = [];
return this;
}
observeSuperCallExpression(node) {
this.superCallExpressions.push(node);
return this;
}
observeConstructorMethod() {
this.superCallExpressionsInConstructorMethod = this.superCallExpressions;
this.superCallExpressions = [];
return this;
}
clearSuperCallExpressionsInConstructorMethod() {
this.superCallExpressionsInConstructorMethod = [];
return this;
}
enforceSuperCallExpressions(createError) {
[].push.apply(this.errors, this.superCallExpressions.map(createError));
[].push.apply(this.errors, this.superCallExpressionsInConstructorMethod.map(createError));
this.superCallExpressions = [];
this.superCallExpressionsInConstructorMethod = [];
return this;
}
enforceSuperCallExpressionsInConstructorMethod(createError) {
[].push.apply(this.errors, this.superCallExpressionsInConstructorMethod.map(createError));
this.superCallExpressionsInConstructorMethod = [];
return this;
}
observeSuperPropertyExpression(node) {
this.superPropertyExpressions.push(node);
return this;
}
clearSuperPropertyExpressions() {
this.superPropertyExpressions = [];
return this;
}
enforceSuperPropertyExpressions(createError) {
[].push.apply(this.errors, this.superPropertyExpressions.map(createError));
this.superPropertyExpressions = [];
return this;
}
observeNewTargetExpression(node) {
this.newTargetExpressions.push(node);
return this;
}
clearNewTargetExpressions() {
this.newTargetExpressions = [];
return this;
}
bindName(name, node) {
this.boundNames.set(name, node);
return this;
}
clearBoundNames() {
this.boundNames = new MultiMap;
return this;
}
observeLexicalDeclaration() {
addEach(this.lexicallyDeclaredNames, this.boundNames);
this.boundNames = new MultiMap;
return this;
}
observeLexicalBoundary() {
this.previousLexicallyDeclaredNames = this.lexicallyDeclaredNames;
this.lexicallyDeclaredNames = new MultiMap;
this.functionDeclarationNames = new MultiMap;
return this;
}
enforceDuplicateLexicallyDeclaredNames(createError) {
this.lexicallyDeclaredNames.forEachEntry(nodes => {
if (nodes.length > 1) {
nodes.slice(1).forEach(dupeNode => {
this.addError(createError(dupeNode));
});
}
});
return this;
}
enforceConflictingLexicallyDeclaredNames(otherNames, createError) {
this.lexicallyDeclaredNames.forEachEntry((nodes, bindingName) => {
if (otherNames.has(bindingName)) {
nodes.forEach(conflictingNode => {
this.addError(createError(conflictingNode));
});
}
});
return this;
}
observeFunctionDeclaration() {
this.observeVarBoundary();
addEach(this.functionDeclarationNames, this.boundNames);
this.boundNames = new MultiMap;
return this;
}
functionDeclarationNamesAreLexical() {
addEach(this.lexicallyDeclaredNames, this.functionDeclarationNames);
this.functionDeclarationNames = new MultiMap;
return this;
}
observeVarDeclaration() {
addEach(this.varDeclaredNames, this.boundNames);
this.boundNames = new MultiMap;
return this;
}
recordForOfVars() {
this.varDeclaredNames.forEach(bindingIdentifier => {
this.forOfVarDeclaredNames.push(bindingIdentifier);
});
return this;
}
observeVarBoundary() {
this.lexicallyDeclaredNames = new MultiMap;
this.functionDeclarationNames = new MultiMap;
this.varDeclaredNames = new MultiMap;
this.forOfVarDeclaredNames = [];
return this;
}
exportName(name, node) {
this.exportedNames.set(name, node);
return this;
}
exportDeclaredNames() {
addEach(this.exportedNames, this.lexicallyDeclaredNames, this.varDeclaredNames);
addEach(this.exportedBindings, this.lexicallyDeclaredNames, this.varDeclaredNames);
return this;
}
exportBinding(name, node) {
this.exportedBindings.set(name, node);
return this;
}
clearExportedBindings() {
this.exportedBindings = new MultiMap;
return this;
}
observeYieldExpression(node) {
this.yieldExpressions.push(node);
return this;
}
clearYieldExpressions() {
this.yieldExpressions = [];
return this;
}
observeAwaitExpression(node) {
this.awaitExpressions.push(node);
return this;
}
clearAwaitExpressions() {
this.awaitExpressions = [];
return this;
}
addError(e) {
this.errors.push(e);
return this;
}
addStrictError(e) {
this.strictErrors.push(e);
return this;
}
enforceStrictErrors() {
[].push.apply(this.errors, this.strictErrors);
this.strictErrors = [];
return this;
}
// MONOID IMPLEMENTATION
static empty() {
return identity;
}
concat(s) {
if (this === identity) return s;
if (s === identity) return this;
[].push.apply(this.errors, s.errors);
[].push.apply(this.strictErrors, s.strictErrors);
[].push.apply(this.usedLabelNames, s.usedLabelNames);
[].push.apply(this.freeBreakStatements, s.freeBreakStatements);
[].push.apply(this.freeContinueStatements, s.freeContinueStatements);
[].push.apply(this.freeLabeledBreakStatements, s.freeLabeledBreakStatements);
[].push.apply(this.freeLabeledContinueStatements, s.freeLabeledContinueStatements);
[].push.apply(this.newTargetExpressions, s.newTargetExpressions);
addEach(this.boundNames, s.boundNames);
addEach(this.lexicallyDeclaredNames, s.lexicallyDeclaredNames);
addEach(this.functionDeclarationNames, s.functionDeclarationNames);
addEach(this.varDeclaredNames, s.varDeclaredNames);
[].push.apply(this.forOfVarDeclaredNames, s.forOfVarDeclaredNames);
addEach(this.exportedNames, s.exportedNames);
addEach(this.exportedBindings, s.exportedBindings);
[].push.apply(this.superCallExpressions, s.superCallExpressions);
[].push.apply(this.superCallExpressionsInConstructorMethod, s.superCallExpressionsInConstructorMethod);
[].push.apply(this.superPropertyExpressions, s.superPropertyExpressions);
[].push.apply(this.yieldExpressions, s.yieldExpressions);
[].push.apply(this.awaitExpressions, s.awaitExpressions);
return this;
}
}
identity = new EarlyErrorState;
Object.getOwnPropertyNames(EarlyErrorState.prototype).forEach(methodName => {
if (methodName === 'constructor') return;
Object.defineProperty(identity, methodName, {
value() {
return EarlyErrorState.prototype[methodName].apply(new EarlyErrorState, arguments);
},
enumerable: false,
writable: true,
configurable: true,
});
});
export class EarlyError extends Error {
constructor(node, message) {
super(message);
this.node = node;
this.message = message;
}
}

View File

@ -0,0 +1,772 @@
/**
* Copyright 2014 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import reduce, { MonoidalReducer } from '../shift-reducer';
import { isStrictModeReservedWord } from './utils';
import { ErrorMessages } from './errors';
import { EarlyErrorState, EarlyError } from './early-error-state';
function isStrictFunctionBody({ directives }) {
return directives.some(directive => directive.rawValue === 'use strict');
}
function isLabelledFunction(node) {
return node.type === 'LabeledStatement' &&
(node.body.type === 'FunctionDeclaration' || isLabelledFunction(node.body));
}
function isIterationStatement(node) {
switch (node.type) {
case 'LabeledStatement':
return isIterationStatement(node.body);
case 'DoWhileStatement':
case 'ForInStatement':
case 'ForOfStatement':
case 'ForStatement':
case 'WhileStatement':
return true;
}
return false;
}
function isSpecialMethod(methodDefinition) {
if (methodDefinition.name.type !== 'StaticPropertyName' || methodDefinition.name.value !== 'constructor') {
return false;
}
switch (methodDefinition.type) {
case 'Getter':
case 'Setter':
return true;
case 'Method':
return methodDefinition.isGenerator || methodDefinition.isAsync;
}
/* istanbul ignore next */
throw new Error('not reached');
}
function enforceDuplicateConstructorMethods(node, s) {
let ctors = node.elements.filter(e =>
!e.isStatic &&
e.method.type === 'Method' &&
!e.method.isGenerator &&
e.method.name.type === 'StaticPropertyName' &&
e.method.name.value === 'constructor'
);
if (ctors.length > 1) {
ctors.slice(1).forEach(ctor => {
s = s.addError(new EarlyError(ctor, 'Duplicate constructor method in class'));
});
}
return s;
}
const SUPERCALL_ERROR = node => new EarlyError(node, ErrorMessages.ILLEGAL_SUPER_CALL);
const SUPERPROPERTY_ERROR = node => new EarlyError(node, 'Member access on super must be in a method');
const DUPLICATE_BINDING = node => new EarlyError(node, `Duplicate binding ${JSON.stringify(node.name)}`);
const FREE_CONTINUE = node => new EarlyError(node, 'Continue statement must be nested within an iteration statement');
const UNBOUND_CONTINUE = node => new EarlyError(node, `Continue statement must be nested within an iteration statement with label ${JSON.stringify(node.label)}`);
const FREE_BREAK = node => new EarlyError(node, 'Break statement must be nested within an iteration statement or a switch statement');
const UNBOUND_BREAK = node => new EarlyError(node, `Break statement must be nested within a statement with label ${JSON.stringify(node.label)}`);
export class EarlyErrorChecker extends MonoidalReducer {
constructor() {
super(EarlyErrorState);
}
reduceAssignmentExpression() {
return super.reduceAssignmentExpression(...arguments).clearBoundNames();
}
reduceAssignmentTargetIdentifier(node) {
let s = this.identity;
if (node.name === 'eval' || node.name === 'arguments' || isStrictModeReservedWord(node.name)) {
s = s.addStrictError(new EarlyError(node, `The identifier ${JSON.stringify(node.name)} must not be in binding position in strict mode`));
}
return s;
}
reduceArrowExpression(node, { params, body }) {
let isSimpleParameterList = node.params.rest == null && node.params.items.every(i => i.type === 'BindingIdentifier');
params = params.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
if (node.body.type === 'FunctionBody') {
body = body.enforceConflictingLexicallyDeclaredNames(params.lexicallyDeclaredNames, DUPLICATE_BINDING);
if (isStrictFunctionBody(node.body)) {
params = params.enforceStrictErrors();
body = body.enforceStrictErrors();
}
}
params.yieldExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Arrow parameters must not contain yield expressions'));
});
params.awaitExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Arrow parameters must not contain await expressions'));
});
let s = super.reduceArrowExpression(node, { params, body });
if (!isSimpleParameterList && node.body.type === 'FunctionBody' && isStrictFunctionBody(node.body)) {
s = s.addError(new EarlyError(node, 'Functions with non-simple parameter lists may not contain a "use strict" directive'));
}
s = s.clearYieldExpressions();
s = s.clearAwaitExpressions();
s = s.observeVarBoundary();
return s;
}
reduceAwaitExpression(node, { expression }) {
return expression.observeAwaitExpression(node);
}
reduceBindingIdentifier(node) {
let s = this.identity;
if (node.name === 'eval' || node.name === 'arguments' || isStrictModeReservedWord(node.name)) {
s = s.addStrictError(new EarlyError(node, `The identifier ${JSON.stringify(node.name)} must not be in binding position in strict mode`));
}
s = s.bindName(node.name, node);
return s;
}
reduceBlock() {
let s = super.reduceBlock(...arguments);
s = s.functionDeclarationNamesAreLexical();
s = s.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
s = s.enforceConflictingLexicallyDeclaredNames(s.varDeclaredNames, DUPLICATE_BINDING);
s = s.observeLexicalBoundary();
return s;
}
reduceBreakStatement(node) {
let s = super.reduceBreakStatement(...arguments);
s = node.label == null
? s.addFreeBreakStatement(node)
: s.addFreeLabeledBreakStatement(node);
return s;
}
reduceCallExpression(node) {
let s = super.reduceCallExpression(...arguments);
if (node.callee.type === 'Super') {
s = s.observeSuperCallExpression(node);
}
return s;
}
reduceCatchClause(node, { binding, body }) {
binding = binding.observeLexicalDeclaration();
binding = binding.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
binding = binding.enforceConflictingLexicallyDeclaredNames(body.previousLexicallyDeclaredNames, DUPLICATE_BINDING);
binding.lexicallyDeclaredNames.forEachEntry((nodes, bindingName) => {
if (body.varDeclaredNames.has(bindingName)) {
body.varDeclaredNames.get(bindingName).forEach(conflictingNode => {
if (body.forOfVarDeclaredNames.indexOf(conflictingNode) >= 0) {
binding = binding.addError(DUPLICATE_BINDING(conflictingNode));
}
});
}
});
let s = super.reduceCatchClause(node, { binding, body });
s = s.observeLexicalBoundary();
return s;
}
reduceClassDeclaration(node, { name, super: _super, elements }) {
let s = name.enforceStrictErrors();
let sElements = this.append(...elements);
sElements = sElements.enforceStrictErrors();
if (node.super != null) {
_super = _super.enforceStrictErrors();
s = this.append(s, _super);
sElements = sElements.clearSuperCallExpressionsInConstructorMethod();
}
s = this.append(s, sElements);
s = enforceDuplicateConstructorMethods(node, s);
s = s.observeLexicalDeclaration();
return s;
}
reduceClassElement(node) {
let s = super.reduceClassElement(...arguments);
if (!node.isStatic && isSpecialMethod(node.method)) {
s = s.addError(new EarlyError(node, ErrorMessages.ILLEGAL_CONSTRUCTORS));
}
if (node.isStatic && node.method.name.type === 'StaticPropertyName' && node.method.name.value === 'prototype') {
s = s.addError(new EarlyError(node, 'Static class methods cannot be named "prototype"'));
}
return s;
}
reduceClassExpression(node, { name, super: _super, elements }) {
let s = node.name == null ? this.identity : name.enforceStrictErrors();
let sElements = this.append(...elements);
sElements = sElements.enforceStrictErrors();
if (node.super != null) {
_super = _super.enforceStrictErrors();
s = this.append(s, _super);
sElements = sElements.clearSuperCallExpressionsInConstructorMethod();
}
s = this.append(s, sElements);
s = enforceDuplicateConstructorMethods(node, s);
s = s.clearBoundNames();
return s;
}
reduceCompoundAssignmentExpression() {
return super.reduceCompoundAssignmentExpression(...arguments).clearBoundNames();
}
reduceComputedMemberExpression(node) {
let s = super.reduceComputedMemberExpression(...arguments);
if (node.object.type === 'Super') {
s = s.observeSuperPropertyExpression(node);
}
return s;
}
reduceContinueStatement(node) {
let s = super.reduceContinueStatement(...arguments);
s = node.label == null
? s.addFreeContinueStatement(node)
: s.addFreeLabeledContinueStatement(node);
return s;
}
reduceDoWhileStatement(node) {
let s = super.reduceDoWhileStatement(...arguments);
if (isLabelledFunction(node.body)) {
s = s.addError(new EarlyError(node.body, 'The body of a do-while statement must not be a labeled function declaration'));
}
s = s.clearFreeContinueStatements();
s = s.clearFreeBreakStatements();
return s;
}
reduceExport() {
let s = super.reduceExport(...arguments);
s = s.functionDeclarationNamesAreLexical();
s = s.exportDeclaredNames();
return s;
}
reduceExportFrom() {
let s = super.reduceExportFrom(...arguments);
s = s.clearExportedBindings();
return s;
}
reduceExportFromSpecifier(node) {
let s = super.reduceExportFromSpecifier(...arguments);
s = s.exportName(node.exportedName || node.name, node);
s = s.exportBinding(node.name, node);
return s;
}
reduceExportLocalSpecifier(node) {
let s = super.reduceExportLocalSpecifier(...arguments);
s = s.exportName(node.exportedName || node.name.name, node);
s = s.exportBinding(node.name.name, node);
return s;
}
reduceExportDefault(node) {
let s = super.reduceExportDefault(...arguments);
s = s.functionDeclarationNamesAreLexical();
s = s.exportName('default', node);
return s;
}
reduceFormalParameters() {
let s = super.reduceFormalParameters(...arguments);
s = s.observeLexicalDeclaration();
return s;
}
reduceForStatement(node, { init, test, update, body }) {
if (init != null) {
init = init.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
init = init.enforceConflictingLexicallyDeclaredNames(body.varDeclaredNames, DUPLICATE_BINDING);
}
let s = super.reduceForStatement(node, { init, test, update, body });
if (node.init != null && node.init.type === 'VariableDeclaration' && node.init.kind === 'const') {
node.init.declarators.forEach(declarator => {
if (declarator.init == null) {
s = s.addError(new EarlyError(declarator, 'Constant lexical declarations must have an initialiser'));
}
});
}
if (isLabelledFunction(node.body)) {
s = s.addError(new EarlyError(node.body, 'The body of a for statement must not be a labeled function declaration'));
}
s = s.clearFreeContinueStatements();
s = s.clearFreeBreakStatements();
s = s.observeLexicalBoundary();
return s;
}
reduceForInStatement(node, { left, right, body }) {
left = left.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
left = left.enforceConflictingLexicallyDeclaredNames(body.varDeclaredNames, DUPLICATE_BINDING);
let s = super.reduceForInStatement(node, { left, right, body });
if (isLabelledFunction(node.body)) {
s = s.addError(new EarlyError(node.body, 'The body of a for-in statement must not be a labeled function declaration'));
}
s = s.clearFreeContinueStatements();
s = s.clearFreeBreakStatements();
s = s.observeLexicalBoundary();
return s;
}
reduceForOfStatement(node, { left, right, body }) {
left = left.recordForOfVars();
left = left.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
left = left.enforceConflictingLexicallyDeclaredNames(body.varDeclaredNames, DUPLICATE_BINDING);
let s = super.reduceForOfStatement(node, { left, right, body });
if (isLabelledFunction(node.body)) {
s = s.addError(new EarlyError(node.body, 'The body of a for-of statement must not be a labeled function declaration'));
}
s = s.clearFreeContinueStatements();
s = s.clearFreeBreakStatements();
s = s.observeLexicalBoundary();
return s;
}
reduceForAwaitStatement(node, { left, right, body }) {
left = left.recordForOfVars();
left = left.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
left = left.enforceConflictingLexicallyDeclaredNames(body.varDeclaredNames, DUPLICATE_BINDING);
let s = super.reduceForOfStatement(node, { left, right, body });
if (isLabelledFunction(node.body)) {
s = s.addError(new EarlyError(node.body, 'The body of a for-await statement must not be a labeled function declaration'));
}
s = s.clearFreeContinueStatements();
s = s.clearFreeBreakStatements();
s = s.observeLexicalBoundary();
return s;
}
reduceFunctionBody(node) {
let s = super.reduceFunctionBody(...arguments);
s = s.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
s = s.enforceConflictingLexicallyDeclaredNames(s.varDeclaredNames, DUPLICATE_BINDING);
s = s.enforceFreeContinueStatementErrors(FREE_CONTINUE);
s = s.enforceFreeLabeledContinueStatementErrors(UNBOUND_CONTINUE);
s = s.enforceFreeBreakStatementErrors(FREE_BREAK);
s = s.enforceFreeLabeledBreakStatementErrors(UNBOUND_BREAK);
s = s.clearUsedLabelNames();
s = s.clearYieldExpressions();
s = s.clearAwaitExpressions();
if (isStrictFunctionBody(node)) {
s = s.enforceStrictErrors();
}
return s;
}
reduceFunctionDeclaration(node, { name, params, body }) {
let isSimpleParameterList = node.params.rest == null && node.params.items.every(i => i.type === 'BindingIdentifier');
let addError = !isSimpleParameterList || node.isGenerator ? 'addError' : 'addStrictError';
params.lexicallyDeclaredNames.forEachEntry(nodes => {
if (nodes.length > 1) {
nodes.slice(1).forEach(dupeNode => {
params = params[addError](DUPLICATE_BINDING(dupeNode));
});
}
});
body = body.enforceConflictingLexicallyDeclaredNames(params.lexicallyDeclaredNames, DUPLICATE_BINDING);
body = body.enforceSuperCallExpressions(SUPERCALL_ERROR);
body = body.enforceSuperPropertyExpressions(SUPERPROPERTY_ERROR);
params = params.enforceSuperCallExpressions(SUPERCALL_ERROR);
params = params.enforceSuperPropertyExpressions(SUPERPROPERTY_ERROR);
if (node.isGenerator) {
params.yieldExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Generator parameters must not contain yield expressions'));
});
}
if (node.isAsync) {
params.awaitExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Async function parameters must not contain await expressions'));
});
}
params = params.clearNewTargetExpressions();
body = body.clearNewTargetExpressions();
if (isStrictFunctionBody(node.body)) {
params = params.enforceStrictErrors();
body = body.enforceStrictErrors();
}
let s = super.reduceFunctionDeclaration(node, { name, params, body });
if (!isSimpleParameterList && isStrictFunctionBody(node.body)) {
s = s.addError(new EarlyError(node, 'Functions with non-simple parameter lists may not contain a "use strict" directive'));
}
s = s.clearYieldExpressions();
s = s.clearAwaitExpressions();
s = s.observeFunctionDeclaration();
return s;
}
reduceFunctionExpression(node, { name, params, body }) {
let isSimpleParameterList = node.params.rest == null && node.params.items.every(i => i.type === 'BindingIdentifier');
let addError = !isSimpleParameterList || node.isGenerator ? 'addError' : 'addStrictError';
params.lexicallyDeclaredNames.forEachEntry((nodes, bindingName) => {
if (nodes.length > 1) {
nodes.slice(1).forEach(dupeNode => {
params = params[addError](new EarlyError(dupeNode, `Duplicate binding ${JSON.stringify(bindingName)}`));
});
}
});
body = body.enforceConflictingLexicallyDeclaredNames(params.lexicallyDeclaredNames, DUPLICATE_BINDING);
body = body.enforceSuperCallExpressions(SUPERCALL_ERROR);
body = body.enforceSuperPropertyExpressions(SUPERPROPERTY_ERROR);
params = params.enforceSuperCallExpressions(SUPERCALL_ERROR);
params = params.enforceSuperPropertyExpressions(SUPERPROPERTY_ERROR);
if (node.isGenerator) {
params.yieldExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Generator parameters must not contain yield expressions'));
});
}
if (node.isAsync) {
params.awaitExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Async function parameters must not contain await expressions'));
});
}
params = params.clearNewTargetExpressions();
body = body.clearNewTargetExpressions();
if (isStrictFunctionBody(node.body)) {
params = params.enforceStrictErrors();
body = body.enforceStrictErrors();
}
let s = super.reduceFunctionExpression(node, { name, params, body });
if (!isSimpleParameterList && isStrictFunctionBody(node.body)) {
s = s.addError(new EarlyError(node, 'Functions with non-simple parameter lists may not contain a "use strict" directive'));
}
s = s.clearBoundNames();
s = s.clearYieldExpressions();
s = s.clearAwaitExpressions();
s = s.observeVarBoundary();
return s;
}
reduceGetter(node, { name, body }) {
body = body.enforceSuperCallExpressions(SUPERCALL_ERROR);
body = body.clearSuperPropertyExpressions();
body = body.clearNewTargetExpressions();
if (isStrictFunctionBody(node.body)) {
body = body.enforceStrictErrors();
}
let s = super.reduceGetter(node, { name, body });
s = s.observeVarBoundary();
return s;
}
reduceIdentifierExpression(node) {
let s = this.identity;
if (isStrictModeReservedWord(node.name)) {
s = s.addStrictError(new EarlyError(node, `The identifier ${JSON.stringify(node.name)} must not be in expression position in strict mode`));
}
return s;
}
reduceIfStatement(node, { test, consequent, alternate }) {
if (isLabelledFunction(node.consequent)) {
consequent = consequent.addError(new EarlyError(node.consequent, 'The consequent of an if statement must not be a labeled function declaration'));
}
if (node.alternate != null && isLabelledFunction(node.alternate)) {
alternate = alternate.addError(new EarlyError(node.alternate, 'The alternate of an if statement must not be a labeled function declaration'));
}
if (node.consequent.type === 'FunctionDeclaration') {
consequent = consequent.addStrictError(new EarlyError(node.consequent, 'FunctionDeclarations in IfStatements are disallowed in strict mode'));
consequent = consequent.observeLexicalBoundary();
}
if (node.alternate != null && node.alternate.type === 'FunctionDeclaration') {
alternate = alternate.addStrictError(new EarlyError(node.alternate, 'FunctionDeclarations in IfStatements are disallowed in strict mode'));
alternate = alternate.observeLexicalBoundary();
}
return super.reduceIfStatement(node, { test, consequent, alternate });
}
reduceImport() {
let s = super.reduceImport(...arguments);
s = s.observeLexicalDeclaration();
return s;
}
reduceImportNamespace() {
let s = super.reduceImportNamespace(...arguments);
s = s.observeLexicalDeclaration();
return s;
}
reduceLabeledStatement(node) {
let s = super.reduceLabeledStatement(...arguments);
if (node.label === 'yield' || isStrictModeReservedWord(node.label)) {
s = s.addStrictError(new EarlyError(node, `The identifier ${JSON.stringify(node.label)} must not be in label position in strict mode`));
}
if (s.usedLabelNames.indexOf(node.label) >= 0) {
s = s.addError(new EarlyError(node, `Label ${JSON.stringify(node.label)} has already been declared`));
}
if (node.body.type === 'FunctionDeclaration') {
s = s.addStrictError(new EarlyError(node, 'Labeled FunctionDeclarations are disallowed in strict mode'));
}
s = isIterationStatement(node.body)
? s.observeIterationLabel(node.label)
: s.observeNonIterationLabel(node.label);
return s;
}
reduceLiteralRegExpExpression() {
let s = this.identity;
// NOTE: the RegExp pattern acceptor is disabled until we have more confidence in its correctness (more tests)
// if (!PatternAcceptor.test(node.pattern, node.flags.indexOf("u") >= 0)) {
// s = s.addError(new EarlyError(node, "Invalid regular expression pattern"));
// }
return s;
}
reduceMethod(node, { name, params, body }) {
let isSimpleParameterList = node.params.rest == null && node.params.items.every(i => i.type === 'BindingIdentifier');
params = params.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
body = body.enforceConflictingLexicallyDeclaredNames(params.lexicallyDeclaredNames, DUPLICATE_BINDING);
if (node.name.type === 'StaticPropertyName' && node.name.value === 'constructor') {
body = body.observeConstructorMethod();
params = params.observeConstructorMethod();
} else {
body = body.enforceSuperCallExpressions(SUPERCALL_ERROR);
params = params.enforceSuperCallExpressions(SUPERCALL_ERROR);
}
if (node.isGenerator) {
params.yieldExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Generator parameters must not contain yield expressions'));
});
}
if (node.isAsync) {
params.awaitExpressions.forEach(n => {
params = params.addError(new EarlyError(n, 'Async function parameters must not contain await expressions'));
});
}
body = body.clearSuperPropertyExpressions();
params = params.clearSuperPropertyExpressions();
params = params.clearNewTargetExpressions();
body = body.clearNewTargetExpressions();
if (isStrictFunctionBody(node.body)) {
params = params.enforceStrictErrors();
body = body.enforceStrictErrors();
}
let s = super.reduceMethod(node, { name, params, body });
if (!isSimpleParameterList && isStrictFunctionBody(node.body)) {
s = s.addError(new EarlyError(node, 'Functions with non-simple parameter lists may not contain a "use strict" directive'));
}
s = s.clearYieldExpressions();
s = s.clearAwaitExpressions();
s = s.observeVarBoundary();
return s;
}
reduceModule() {
let s = super.reduceModule(...arguments);
s = s.functionDeclarationNamesAreLexical();
s = s.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
s = s.enforceConflictingLexicallyDeclaredNames(s.varDeclaredNames, DUPLICATE_BINDING);
s.exportedNames.forEachEntry((nodes, bindingName) => {
if (nodes.length > 1) {
nodes.slice(1).forEach(dupeNode => {
s = s.addError(new EarlyError(dupeNode, `Duplicate export ${JSON.stringify(bindingName)}`));
});
}
});
s.exportedBindings.forEachEntry((nodes, bindingName) => {
if (!s.lexicallyDeclaredNames.has(bindingName) && !s.varDeclaredNames.has(bindingName)) {
nodes.forEach(undeclaredNode => {
s = s.addError(new EarlyError(undeclaredNode, `Exported binding ${JSON.stringify(bindingName)} is not declared`));
});
}
});
s.newTargetExpressions.forEach(node => {
s = s.addError(new EarlyError(node, 'new.target must be within function (but not arrow expression) code'));
});
s = s.enforceFreeContinueStatementErrors(FREE_CONTINUE);
s = s.enforceFreeLabeledContinueStatementErrors(UNBOUND_CONTINUE);
s = s.enforceFreeBreakStatementErrors(FREE_BREAK);
s = s.enforceFreeLabeledBreakStatementErrors(UNBOUND_BREAK);
s = s.enforceSuperCallExpressions(SUPERCALL_ERROR);
s = s.enforceSuperPropertyExpressions(SUPERPROPERTY_ERROR);
s = s.enforceStrictErrors();
return s;
}
reduceNewTargetExpression(node) {
return this.identity.observeNewTargetExpression(node);
}
reduceObjectExpression(node) {
let s = super.reduceObjectExpression(...arguments);
s = s.enforceSuperCallExpressionsInConstructorMethod(SUPERCALL_ERROR);
let protos = node.properties.filter(p => p.type === 'DataProperty' && p.name.type === 'StaticPropertyName' && p.name.value === '__proto__');
protos.slice(1).forEach(n => {
s = s.addError(new EarlyError(n, 'Duplicate __proto__ property in object literal not allowed'));
});
return s;
}
reduceUpdateExpression() {
let s = super.reduceUpdateExpression(...arguments);
s = s.clearBoundNames();
return s;
}
reduceUnaryExpression(node) {
let s = super.reduceUnaryExpression(...arguments);
if (node.operator === 'delete' && node.operand.type === 'IdentifierExpression') {
s = s.addStrictError(new EarlyError(node, 'Identifier expressions must not be deleted in strict mode'));
}
return s;
}
reduceScript(node) {
let s = super.reduceScript(...arguments);
s = s.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
s = s.enforceConflictingLexicallyDeclaredNames(s.varDeclaredNames, DUPLICATE_BINDING);
s.newTargetExpressions.forEach(n => {
s = s.addError(new EarlyError(n, 'new.target must be within function (but not arrow expression) code'));
});
s = s.enforceFreeContinueStatementErrors(FREE_CONTINUE);
s = s.enforceFreeLabeledContinueStatementErrors(UNBOUND_CONTINUE);
s = s.enforceFreeBreakStatementErrors(FREE_BREAK);
s = s.enforceFreeLabeledBreakStatementErrors(UNBOUND_BREAK);
s = s.enforceSuperCallExpressions(SUPERCALL_ERROR);
s = s.enforceSuperPropertyExpressions(SUPERPROPERTY_ERROR);
if (isStrictFunctionBody(node)) {
s = s.enforceStrictErrors();
}
return s;
}
reduceSetter(node, { name, param, body }) {
let isSimpleParameterList = node.param.type === 'BindingIdentifier';
param = param.observeLexicalDeclaration();
param = param.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
body = body.enforceConflictingLexicallyDeclaredNames(param.lexicallyDeclaredNames, DUPLICATE_BINDING);
param = param.enforceSuperCallExpressions(SUPERCALL_ERROR);
body = body.enforceSuperCallExpressions(SUPERCALL_ERROR);
param = param.clearSuperPropertyExpressions();
body = body.clearSuperPropertyExpressions();
param = param.clearNewTargetExpressions();
body = body.clearNewTargetExpressions();
if (isStrictFunctionBody(node.body)) {
param = param.enforceStrictErrors();
body = body.enforceStrictErrors();
}
let s = super.reduceSetter(node, { name, param, body });
if (!isSimpleParameterList && isStrictFunctionBody(node.body)) {
s = s.addError(new EarlyError(node, 'Functions with non-simple parameter lists may not contain a "use strict" directive'));
}
s = s.observeVarBoundary();
return s;
}
reduceStaticMemberExpression(node) {
let s = super.reduceStaticMemberExpression(...arguments);
if (node.object.type === 'Super') {
s = s.observeSuperPropertyExpression(node);
}
return s;
}
reduceSwitchStatement(node, { discriminant, cases }) {
let sCases = this.append(...cases);
sCases = sCases.functionDeclarationNamesAreLexical();
sCases = sCases.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
sCases = sCases.enforceConflictingLexicallyDeclaredNames(sCases.varDeclaredNames, DUPLICATE_BINDING);
sCases = sCases.observeLexicalBoundary();
let s = this.append(discriminant, sCases);
s = s.clearFreeBreakStatements();
return s;
}
reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) {
let sCases = this.append(defaultCase, ...preDefaultCases, ...postDefaultCases);
sCases = sCases.functionDeclarationNamesAreLexical();
sCases = sCases.enforceDuplicateLexicallyDeclaredNames(DUPLICATE_BINDING);
sCases = sCases.enforceConflictingLexicallyDeclaredNames(sCases.varDeclaredNames, DUPLICATE_BINDING);
sCases = sCases.observeLexicalBoundary();
let s = this.append(discriminant, sCases);
s = s.clearFreeBreakStatements();
return s;
}
reduceVariableDeclaration(node) {
let s = super.reduceVariableDeclaration(...arguments);
switch (node.kind) {
case 'const':
case 'let': {
s = s.observeLexicalDeclaration();
if (s.lexicallyDeclaredNames.has('let')) {
s.lexicallyDeclaredNames.get('let').forEach(n => {
s = s.addError(new EarlyError(n, 'Lexical declarations must not have a binding named "let"'));
});
}
break;
}
case 'var':
s = s.observeVarDeclaration();
break;
}
return s;
}
reduceVariableDeclarationStatement(node) {
let s = super.reduceVariableDeclarationStatement(...arguments);
if (node.declaration.kind === 'const') {
node.declaration.declarators.forEach(declarator => {
if (declarator.init == null) {
s = s.addError(new EarlyError(declarator, 'Constant lexical declarations must have an initialiser'));
}
});
}
return s;
}
reduceWhileStatement(node) {
let s = super.reduceWhileStatement(...arguments);
if (isLabelledFunction(node.body)) {
s = s.addError(new EarlyError(node.body, 'The body of a while statement must not be a labeled function declaration'));
}
s = s.clearFreeContinueStatements().clearFreeBreakStatements();
return s;
}
reduceWithStatement(node) {
let s = super.reduceWithStatement(...arguments);
if (isLabelledFunction(node.body)) {
s = s.addError(new EarlyError(node.body, 'The body of a with statement must not be a labeled function declaration'));
}
s = s.addStrictError(new EarlyError(node, 'Strict mode code must not include a with statement'));
return s;
}
reduceYieldExpression(node) {
let s = super.reduceYieldExpression(...arguments);
s = s.observeYieldExpression(node);
return s;
}
reduceYieldGeneratorExpression(node) {
let s = super.reduceYieldGeneratorExpression(...arguments);
s = s.observeYieldExpression(node);
return s;
}
static check(node) {
return reduce(new EarlyErrorChecker, node).errors;
}
}

View File

@ -0,0 +1,119 @@
/**
* Copyright 2014 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const ErrorMessages = {
UNEXPECTED_TOKEN(id) {
return `Unexpected token ${JSON.stringify(id)}`;
},
UNEXPECTED_ILLEGAL_TOKEN(id) {
return `Unexpected ${JSON.stringify(id)}`;
},
UNEXPECTED_ESCAPED_KEYWORD: 'Unexpected escaped keyword',
UNEXPECTED_NUMBER: 'Unexpected number',
UNEXPECTED_STRING: 'Unexpected string',
UNEXPECTED_IDENTIFIER: 'Unexpected identifier',
UNEXPECTED_RESERVED_WORD: 'Unexpected reserved word',
UNEXPECTED_TEMPLATE: 'Unexpected template',
UNEXPECTED_EOS: 'Unexpected end of input',
UNEXPECTED_LINE_TERMINATOR: 'Unexpected line terminator',
UNEXPECTED_COMMA_AFTER_REST: 'Unexpected comma after rest',
UNEXPECTED_REST_PARAMETERS_INITIALIZATION: 'Rest parameter may not have a default initializer',
NEWLINE_AFTER_THROW: 'Illegal newline after throw',
UNTERMINATED_REGEXP: 'Invalid regular expression: missing /',
INVALID_LAST_REST_PARAMETER: 'Rest parameter must be last formal parameter',
INVALID_REST_PARAMETERS_INITIALIZATION: 'Rest parameter may not have a default initializer',
INVALID_REGEXP_FLAGS: 'Invalid regular expression flags',
INVALID_REGEX: 'Invalid regular expression',
INVALID_LHS_IN_ASSIGNMENT: 'Invalid left-hand side in assignment',
INVALID_LHS_IN_BINDING: 'Invalid left-hand side in binding', // todo collapse messages?
INVALID_LHS_IN_FOR_IN: 'Invalid left-hand side in for-in',
INVALID_LHS_IN_FOR_OF: 'Invalid left-hand side in for-of',
INVALID_LHS_IN_FOR_AWAIT: 'Invalid left-hand side in for-await',
INVALID_UPDATE_OPERAND: 'Increment/decrement target must be an identifier or member expression',
INVALID_EXPONENTIATION_LHS: 'Unary expressions as the left operand of an exponentation expression ' +
'must be disambiguated with parentheses',
MULTIPLE_DEFAULTS_IN_SWITCH: 'More than one default clause in switch statement',
NO_CATCH_OR_FINALLY: 'Missing catch or finally after try',
ILLEGAL_RETURN: 'Illegal return statement',
ILLEGAL_ARROW_FUNCTION_PARAMS: 'Illegal arrow function parameter list',
INVALID_ASYNC_PARAMS: 'Async function parameters must not contain await expressions',
INVALID_VAR_INIT_FOR_IN: 'Invalid variable declaration in for-in statement',
INVALID_VAR_INIT_FOR_OF: 'Invalid variable declaration in for-of statement',
INVALID_VAR_INIT_FOR_AWAIT: 'Invalid variable declaration in for-await statement',
UNINITIALIZED_BINDINGPATTERN_IN_FOR_INIT: 'Binding pattern appears without initializer in for statement init',
ILLEGAL_PROPERTY: 'Illegal property initializer',
INVALID_ID_BINDING_STRICT_MODE(id) {
return `The identifier ${JSON.stringify(id)} must not be in binding position in strict mode`;
},
INVALID_ID_IN_LABEL_STRICT_MODE(id) {
return `The identifier ${JSON.stringify(id)} must not be in label position in strict mode`;
},
INVALID_ID_IN_EXPRESSION_STRICT_MODE(id) {
return `The identifier ${JSON.stringify(id)} must not be in expression position in strict mode`;
},
INVALID_CALL_TO_SUPER: 'Calls to super must be in the "constructor" method of a class expression ' +
'or class declaration that has a superclass',
INVALID_DELETE_STRICT_MODE: 'Identifier expressions must not be deleted in strict mode',
DUPLICATE_BINDING(id) {
return `Duplicate binding ${JSON.stringify(id)}`;
},
ILLEGAL_ID_IN_LEXICAL_DECLARATION(id) {
return `Lexical declarations must not have a binding named ${JSON.stringify(id)}`;
},
UNITIALIZED_CONST: 'Constant lexical declarations must have an initialiser',
ILLEGAL_LABEL_IN_BODY(stmt) {
return `The body of a ${stmt} statement must not be a labeled function declaration`;
},
ILLEGEAL_LABEL_IN_IF: 'The consequent of an if statement must not be a labeled function declaration',
ILLEGAL_LABEL_IN_ELSE: 'The alternate of an if statement must not be a labeled function declaration',
ILLEGAL_CONTINUE_WITHOUT_ITERATION_WITH_ID(id) {
return `Continue statement must be nested within an iteration statement with label ${JSON.stringify(id)}`;
},
ILLEGAL_CONTINUE_WITHOUT_ITERATION: 'Continue statement must be nested within an iteration statement',
ILLEGAL_BREAK_WITHOUT_ITERATION_OR_SWITCH:
'Break statement must be nested within an iteration statement or a switch statement',
ILLEGAL_WITH_STRICT_MODE: 'Strict mode code must not include a with statement',
ILLEGAL_ACCESS_SUPER_MEMBER: 'Member access on super must be in a method',
ILLEGAL_SUPER_CALL: 'Calls to super must be in the "constructor" method of a class expression or class declaration that has a superclass',
DUPLICATE_LABEL_DECLARATION(label) {
return `Label ${JSON.stringify(label)} has already been declared`;
},
ILLEGAL_BREAK_WITHIN_LABEL(label) {
return `Break statement must be nested within a statement with label ${JSON.stringify(label)}`;
},
ILLEGAL_YIELD_EXPRESSIONS(paramType) {
return `${paramType} parameters must not contain yield expressions`;
},
ILLEGAL_YIELD_IDENTIFIER: '"yield" may not be used as an identifier in this context',
ILLEGAL_AWAIT_IDENTIFIER: '"await" may not be used as an identifier in this context',
DUPLICATE_CONSTRUCTOR: 'Duplicate constructor method in class',
ILLEGAL_CONSTRUCTORS: 'Constructors cannot be async, generators, getters or setters',
ILLEGAL_STATIC_CLASS_NAME: 'Static class methods cannot be named "prototype"',
NEW_TARGET_ERROR: 'new.target must be within function (but not arrow expression) code',
DUPLICATE_EXPORT(id) {
return `Duplicate export ${JSON.stringify(id)}`;
},
UNDECLARED_BINDING(id) {
return `Exported binding ${JSON.stringify(id)} is not declared`;
},
DUPLICATE_PROPTO_PROP: 'Duplicate __proto__ property in object literal not allowed',
ILLEGAL_LABEL_FUNC_DECLARATION: 'Labeled FunctionDeclarations are disallowed in strict mode',
ILLEGAL_FUNC_DECL_IF: 'FunctionDeclarations in IfStatements are disallowed in strict mode',
ILLEGAL_USE_STRICT: 'Functions with non-simple parameter lists may not contain a "use strict" directive',
ILLEGAL_EXPORTED_NAME: 'Names of variables used in an export specifier from the current module must be identifiers',
NO_OCTALS_IN_TEMPLATES: 'Template literals may not contain octal escape sequences',
NO_AWAIT_IN_ASYNC_PARAMS: 'Async arrow parameters may not contain "await"',
};

View File

@ -0,0 +1,149 @@
/**
* Copyright 2016 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { GenericParser } from './parser';
import { JsError } from './tokenizer';
import { EarlyErrorChecker } from './early-errors';
import { isLineTerminator } from './utils';
class ParserWithLocation extends GenericParser {
constructor(source) {
super(source);
this.locations = new WeakMap;
this.comments = [];
}
startNode() {
return this.getLocation();
}
finishNode(node, start) {
if (node.type === 'Script' || node.type === 'Module') {
this.locations.set(node, {
start: { line: 1, column: 0, offset: 0 },
end: this.getLocation(),
});
return node;
}
if (node.type === 'TemplateExpression') {
// Adjust TemplateElements to not include surrounding backticks or braces
for (let i = 0; i < node.elements.length; i += 2) {
const endAdjustment = i < node.elements.length - 1 ? 2 : 1; // discard '${' or '`' respectively
const element = node.elements[i];
const location = this.locations.get(element);
this.locations.set(element, {
start: { line: location.start.line, column: location.start.column + 1, offset: location.start.offset + 1 }, // discard '}' or '`'
end: { line: location.end.line, column: location.end.column - endAdjustment, offset: location.end.offset - endAdjustment },
});
}
}
this.locations.set(node, {
start,
end: this.getLastTokenEndLocation(),
});
return node;
}
copyNode(src, dest) {
this.locations.set(dest, this.locations.get(src)); // todo check undefined
return dest;
}
skipSingleLineComment(offset) {
// We're actually extending the *tokenizer*, here.
const start = {
line: this.line + 1,
column: this.index - this.lineStart,
offset: this.index,
};
const c = this.source[this.index];
const type = c === '/' ? 'SingleLine' : c === '<' ? 'HTMLOpen' : 'HTMLClose';
super.skipSingleLineComment(offset);
const end = {
line: this.line + 1,
column: this.index - this.lineStart,
offset: this.index,
};
const trailingLineTerminatorCharacters = this.source[this.index - 2] === '\r' ? 2 : isLineTerminator(this.source.charCodeAt(this.index - 1)) ? 1 : 0;
const text = this.source.substring(start.offset + offset, end.offset - trailingLineTerminatorCharacters);
this.comments.push({ text, type, start, end });
}
skipMultiLineComment() {
const start = {
line: this.line + 1,
column: this.index - this.lineStart,
offset: this.index,
};
const type = 'MultiLine';
const retval = super.skipMultiLineComment();
const end = {
line: this.line + 1,
column: this.index - this.lineStart,
offset: this.index,
};
const text = this.source.substring(start.offset + 2, end.offset - 2);
this.comments.push({ text, type, start, end });
return retval;
}
}
function generateInterface(parsingFunctionName) {
return function parse(code, { earlyErrors = true } = {}) {
let parser = new GenericParser(code);
let tree = parser[parsingFunctionName]();
if (earlyErrors) {
let errors = EarlyErrorChecker.check(tree);
// for now, just throw the first error; we will handle multiple errors later
if (errors.length > 0) {
throw new JsError(0, 1, 0, errors[0].message);
}
}
return tree;
};
}
function generateInterfaceWithLocation(parsingFunctionName) {
return function parse(code, { earlyErrors = true } = {}) {
let parser = new ParserWithLocation(code);
let tree = parser[parsingFunctionName]();
if (earlyErrors) {
let errors = EarlyErrorChecker.check(tree);
// for now, just throw the first error; we will handle multiple errors later
if (errors.length > 0) {
let { node, message } = errors[0];
let { offset, line, column } = parser.locations.get(node).start;
throw new JsError(offset, line, column, message);
}
}
return { tree, locations: parser.locations, comments: parser.comments };
};
}
export const parseModule = generateInterface('parseModule');
export const parseScript = generateInterface('parseScript');
export const parseModuleWithLocation = generateInterfaceWithLocation('parseModule');
export const parseScriptWithLocation = generateInterfaceWithLocation('parseScript');
export default parseScript;
export { EarlyErrorChecker, GenericParser, ParserWithLocation };
export { default as Tokenizer, TokenClass, TokenType } from './tokenizer';

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,105 @@
/**
* Copyright 2017 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { whitespaceArray, whitespaceBool, idStartLargeRegex, idStartBool, idContinueLargeRegex, idContinueBool } from './unicode';
const strictReservedWords = [
'null',
'true',
'false',
'implements',
'interface',
'package',
'private',
'protected',
'public',
'static',
'let',
'if',
'in',
'do',
'var',
'for',
'new',
'try',
'this',
'else',
'case',
'void',
'with',
'enum',
'while',
'break',
'catch',
'throw',
'const',
'yield',
'class',
'super',
'return',
'typeof',
'delete',
'switch',
'export',
'import',
'default',
'finally',
'extends',
'function',
'continue',
'debugger',
'instanceof',
];
export function isStrictModeReservedWord(id) {
return strictReservedWords.indexOf(id) !== -1;
}
export function isWhiteSpace(ch) {
return ch < 128 ? whitespaceBool[ch] : ch === 0xA0 || ch > 0x167F && whitespaceArray.indexOf(ch) !== -1;
}
export function isLineTerminator(ch) {
return ch === 0x0A || ch === 0x0D || ch === 0x2028 || ch === 0x2029;
}
export function isIdentifierStart(ch) {
return ch < 128 ? idStartBool[ch] : idStartLargeRegex.test(String.fromCodePoint(ch));
}
export function isIdentifierPart(ch) {
return ch < 128 ? idContinueBool[ch] : idContinueLargeRegex.test(String.fromCodePoint(ch));
}
export function isDecimalDigit(ch) {
return ch >= 48 && ch <= 57;
}
export function getHexValue(rune) {
if (rune >= '0' && rune <= '9') {
return rune.charCodeAt(0) - 48;
}
if (rune >= 'a' && rune <= 'f') {
return rune.charCodeAt(0) - 87;
}
if (rune >= 'A' && rune <= 'F') {
return rune.charCodeAt(0) - 55;
}
return -1;
}

View File

@ -0,0 +1,418 @@
// Generated by generate-adapt.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as Shift from 'shift-ast';
export default (fn, reducer) => ({
__proto__: reducer,
reduceArrayAssignmentTarget(node, data) {
return fn(super.reduceArrayAssignmentTarget(node, data), node);
},
reduceArrayBinding(node, data) {
return fn(super.reduceArrayBinding(node, data), node);
},
reduceArrayExpression(node, data) {
return fn(super.reduceArrayExpression(node, data), node);
},
reduceArrowExpression(node, data) {
return fn(super.reduceArrowExpression(node, data), node);
},
reduceAssignmentExpression(node, data) {
return fn(super.reduceAssignmentExpression(node, data), node);
},
reduceAssignmentTargetIdentifier(node, data) {
return fn(super.reduceAssignmentTargetIdentifier(node, data), node);
},
reduceAssignmentTargetPropertyIdentifier(node, data) {
return fn(super.reduceAssignmentTargetPropertyIdentifier(node, data), node);
},
reduceAssignmentTargetPropertyProperty(node, data) {
return fn(super.reduceAssignmentTargetPropertyProperty(node, data), node);
},
reduceAssignmentTargetWithDefault(node, data) {
return fn(super.reduceAssignmentTargetWithDefault(node, data), node);
},
reduceAwaitExpression(node, data) {
return fn(super.reduceAwaitExpression(node, data), node);
},
reduceBinaryExpression(node, data) {
return fn(super.reduceBinaryExpression(node, data), node);
},
reduceBindingIdentifier(node, data) {
return fn(super.reduceBindingIdentifier(node, data), node);
},
reduceBindingPropertyIdentifier(node, data) {
return fn(super.reduceBindingPropertyIdentifier(node, data), node);
},
reduceBindingPropertyProperty(node, data) {
return fn(super.reduceBindingPropertyProperty(node, data), node);
},
reduceBindingWithDefault(node, data) {
return fn(super.reduceBindingWithDefault(node, data), node);
},
reduceBlock(node, data) {
return fn(super.reduceBlock(node, data), node);
},
reduceBlockStatement(node, data) {
return fn(super.reduceBlockStatement(node, data), node);
},
reduceBreakStatement(node, data) {
return fn(super.reduceBreakStatement(node, data), node);
},
reduceCallExpression(node, data) {
return fn(super.reduceCallExpression(node, data), node);
},
reduceCatchClause(node, data) {
return fn(super.reduceCatchClause(node, data), node);
},
reduceClassDeclaration(node, data) {
return fn(super.reduceClassDeclaration(node, data), node);
},
reduceClassElement(node, data) {
return fn(super.reduceClassElement(node, data), node);
},
reduceClassExpression(node, data) {
return fn(super.reduceClassExpression(node, data), node);
},
reduceCompoundAssignmentExpression(node, data) {
return fn(super.reduceCompoundAssignmentExpression(node, data), node);
},
reduceComputedMemberAssignmentTarget(node, data) {
return fn(super.reduceComputedMemberAssignmentTarget(node, data), node);
},
reduceComputedMemberExpression(node, data) {
return fn(super.reduceComputedMemberExpression(node, data), node);
},
reduceComputedPropertyName(node, data) {
return fn(super.reduceComputedPropertyName(node, data), node);
},
reduceConditionalExpression(node, data) {
return fn(super.reduceConditionalExpression(node, data), node);
},
reduceContinueStatement(node, data) {
return fn(super.reduceContinueStatement(node, data), node);
},
reduceDataProperty(node, data) {
return fn(super.reduceDataProperty(node, data), node);
},
reduceDebuggerStatement(node, data) {
return fn(super.reduceDebuggerStatement(node, data), node);
},
reduceDirective(node, data) {
return fn(super.reduceDirective(node, data), node);
},
reduceDoWhileStatement(node, data) {
return fn(super.reduceDoWhileStatement(node, data), node);
},
reduceEmptyStatement(node, data) {
return fn(super.reduceEmptyStatement(node, data), node);
},
reduceExport(node, data) {
return fn(super.reduceExport(node, data), node);
},
reduceExportAllFrom(node, data) {
return fn(super.reduceExportAllFrom(node, data), node);
},
reduceExportDefault(node, data) {
return fn(super.reduceExportDefault(node, data), node);
},
reduceExportFrom(node, data) {
return fn(super.reduceExportFrom(node, data), node);
},
reduceExportFromSpecifier(node, data) {
return fn(super.reduceExportFromSpecifier(node, data), node);
},
reduceExportLocalSpecifier(node, data) {
return fn(super.reduceExportLocalSpecifier(node, data), node);
},
reduceExportLocals(node, data) {
return fn(super.reduceExportLocals(node, data), node);
},
reduceExpressionStatement(node, data) {
return fn(super.reduceExpressionStatement(node, data), node);
},
reduceForAwaitStatement(node, data) {
return fn(super.reduceForAwaitStatement(node, data), node);
},
reduceForInStatement(node, data) {
return fn(super.reduceForInStatement(node, data), node);
},
reduceForOfStatement(node, data) {
return fn(super.reduceForOfStatement(node, data), node);
},
reduceForStatement(node, data) {
return fn(super.reduceForStatement(node, data), node);
},
reduceFormalParameters(node, data) {
return fn(super.reduceFormalParameters(node, data), node);
},
reduceFunctionBody(node, data) {
return fn(super.reduceFunctionBody(node, data), node);
},
reduceFunctionDeclaration(node, data) {
return fn(super.reduceFunctionDeclaration(node, data), node);
},
reduceFunctionExpression(node, data) {
return fn(super.reduceFunctionExpression(node, data), node);
},
reduceGetter(node, data) {
return fn(super.reduceGetter(node, data), node);
},
reduceIdentifierExpression(node, data) {
return fn(super.reduceIdentifierExpression(node, data), node);
},
reduceIfStatement(node, data) {
return fn(super.reduceIfStatement(node, data), node);
},
reduceImport(node, data) {
return fn(super.reduceImport(node, data), node);
},
reduceImportNamespace(node, data) {
return fn(super.reduceImportNamespace(node, data), node);
},
reduceImportSpecifier(node, data) {
return fn(super.reduceImportSpecifier(node, data), node);
},
reduceLabeledStatement(node, data) {
return fn(super.reduceLabeledStatement(node, data), node);
},
reduceLiteralBooleanExpression(node, data) {
return fn(super.reduceLiteralBooleanExpression(node, data), node);
},
reduceLiteralInfinityExpression(node, data) {
return fn(super.reduceLiteralInfinityExpression(node, data), node);
},
reduceLiteralNullExpression(node, data) {
return fn(super.reduceLiteralNullExpression(node, data), node);
},
reduceLiteralNumericExpression(node, data) {
return fn(super.reduceLiteralNumericExpression(node, data), node);
},
reduceLiteralRegExpExpression(node, data) {
return fn(super.reduceLiteralRegExpExpression(node, data), node);
},
reduceLiteralStringExpression(node, data) {
return fn(super.reduceLiteralStringExpression(node, data), node);
},
reduceMethod(node, data) {
return fn(super.reduceMethod(node, data), node);
},
reduceModule(node, data) {
return fn(super.reduceModule(node, data), node);
},
reduceNewExpression(node, data) {
return fn(super.reduceNewExpression(node, data), node);
},
reduceNewTargetExpression(node, data) {
return fn(super.reduceNewTargetExpression(node, data), node);
},
reduceObjectAssignmentTarget(node, data) {
return fn(super.reduceObjectAssignmentTarget(node, data), node);
},
reduceObjectBinding(node, data) {
return fn(super.reduceObjectBinding(node, data), node);
},
reduceObjectExpression(node, data) {
return fn(super.reduceObjectExpression(node, data), node);
},
reduceReturnStatement(node, data) {
return fn(super.reduceReturnStatement(node, data), node);
},
reduceScript(node, data) {
return fn(super.reduceScript(node, data), node);
},
reduceSetter(node, data) {
return fn(super.reduceSetter(node, data), node);
},
reduceShorthandProperty(node, data) {
return fn(super.reduceShorthandProperty(node, data), node);
},
reduceSpreadElement(node, data) {
return fn(super.reduceSpreadElement(node, data), node);
},
reduceSpreadProperty(node, data) {
return fn(super.reduceSpreadProperty(node, data), node);
},
reduceStaticMemberAssignmentTarget(node, data) {
return fn(super.reduceStaticMemberAssignmentTarget(node, data), node);
},
reduceStaticMemberExpression(node, data) {
return fn(super.reduceStaticMemberExpression(node, data), node);
},
reduceStaticPropertyName(node, data) {
return fn(super.reduceStaticPropertyName(node, data), node);
},
reduceSuper(node, data) {
return fn(super.reduceSuper(node, data), node);
},
reduceSwitchCase(node, data) {
return fn(super.reduceSwitchCase(node, data), node);
},
reduceSwitchDefault(node, data) {
return fn(super.reduceSwitchDefault(node, data), node);
},
reduceSwitchStatement(node, data) {
return fn(super.reduceSwitchStatement(node, data), node);
},
reduceSwitchStatementWithDefault(node, data) {
return fn(super.reduceSwitchStatementWithDefault(node, data), node);
},
reduceTemplateElement(node, data) {
return fn(super.reduceTemplateElement(node, data), node);
},
reduceTemplateExpression(node, data) {
return fn(super.reduceTemplateExpression(node, data), node);
},
reduceThisExpression(node, data) {
return fn(super.reduceThisExpression(node, data), node);
},
reduceThrowStatement(node, data) {
return fn(super.reduceThrowStatement(node, data), node);
},
reduceTryCatchStatement(node, data) {
return fn(super.reduceTryCatchStatement(node, data), node);
},
reduceTryFinallyStatement(node, data) {
return fn(super.reduceTryFinallyStatement(node, data), node);
},
reduceUnaryExpression(node, data) {
return fn(super.reduceUnaryExpression(node, data), node);
},
reduceUpdateExpression(node, data) {
return fn(super.reduceUpdateExpression(node, data), node);
},
reduceVariableDeclaration(node, data) {
return fn(super.reduceVariableDeclaration(node, data), node);
},
reduceVariableDeclarationStatement(node, data) {
return fn(super.reduceVariableDeclarationStatement(node, data), node);
},
reduceVariableDeclarator(node, data) {
return fn(super.reduceVariableDeclarator(node, data), node);
},
reduceWhileStatement(node, data) {
return fn(super.reduceWhileStatement(node, data), node);
},
reduceWithStatement(node, data) {
return fn(super.reduceWithStatement(node, data), node);
},
reduceYieldExpression(node, data) {
return fn(super.reduceYieldExpression(node, data), node);
},
reduceYieldGeneratorExpression(node, data) {
return fn(super.reduceYieldGeneratorExpression(node, data), node);
},
});

View File

@ -0,0 +1,416 @@
// Generated by generate-clone-reducer.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as Shift from 'shift-ast';
export default class CloneReducer {
reduceArrayAssignmentTarget(node, { elements, rest }) {
return new Shift.ArrayAssignmentTarget({ elements, rest });
}
reduceArrayBinding(node, { elements, rest }) {
return new Shift.ArrayBinding({ elements, rest });
}
reduceArrayExpression(node, { elements }) {
return new Shift.ArrayExpression({ elements });
}
reduceArrowExpression(node, { params, body }) {
return new Shift.ArrowExpression({ isAsync: node.isAsync, params, body });
}
reduceAssignmentExpression(node, { binding, expression }) {
return new Shift.AssignmentExpression({ binding, expression });
}
reduceAssignmentTargetIdentifier(node) {
return new Shift.AssignmentTargetIdentifier({ name: node.name });
}
reduceAssignmentTargetPropertyIdentifier(node, { binding, init }) {
return new Shift.AssignmentTargetPropertyIdentifier({ binding, init });
}
reduceAssignmentTargetPropertyProperty(node, { name, binding }) {
return new Shift.AssignmentTargetPropertyProperty({ name, binding });
}
reduceAssignmentTargetWithDefault(node, { binding, init }) {
return new Shift.AssignmentTargetWithDefault({ binding, init });
}
reduceAwaitExpression(node, { expression }) {
return new Shift.AwaitExpression({ expression });
}
reduceBinaryExpression(node, { left, right }) {
return new Shift.BinaryExpression({ left, operator: node.operator, right });
}
reduceBindingIdentifier(node) {
return new Shift.BindingIdentifier({ name: node.name });
}
reduceBindingPropertyIdentifier(node, { binding, init }) {
return new Shift.BindingPropertyIdentifier({ binding, init });
}
reduceBindingPropertyProperty(node, { name, binding }) {
return new Shift.BindingPropertyProperty({ name, binding });
}
reduceBindingWithDefault(node, { binding, init }) {
return new Shift.BindingWithDefault({ binding, init });
}
reduceBlock(node, { statements }) {
return new Shift.Block({ statements });
}
reduceBlockStatement(node, { block }) {
return new Shift.BlockStatement({ block });
}
reduceBreakStatement(node) {
return new Shift.BreakStatement({ label: node.label });
}
reduceCallExpression(node, { callee, arguments: _arguments }) {
return new Shift.CallExpression({ callee, arguments: _arguments });
}
reduceCatchClause(node, { binding, body }) {
return new Shift.CatchClause({ binding, body });
}
reduceClassDeclaration(node, { name, super: _super, elements }) {
return new Shift.ClassDeclaration({ name, super: _super, elements });
}
reduceClassElement(node, { method }) {
return new Shift.ClassElement({ isStatic: node.isStatic, method });
}
reduceClassExpression(node, { name, super: _super, elements }) {
return new Shift.ClassExpression({ name, super: _super, elements });
}
reduceCompoundAssignmentExpression(node, { binding, expression }) {
return new Shift.CompoundAssignmentExpression({ binding, operator: node.operator, expression });
}
reduceComputedMemberAssignmentTarget(node, { object, expression }) {
return new Shift.ComputedMemberAssignmentTarget({ object, expression });
}
reduceComputedMemberExpression(node, { object, expression }) {
return new Shift.ComputedMemberExpression({ object, expression });
}
reduceComputedPropertyName(node, { expression }) {
return new Shift.ComputedPropertyName({ expression });
}
reduceConditionalExpression(node, { test, consequent, alternate }) {
return new Shift.ConditionalExpression({ test, consequent, alternate });
}
reduceContinueStatement(node) {
return new Shift.ContinueStatement({ label: node.label });
}
reduceDataProperty(node, { name, expression }) {
return new Shift.DataProperty({ name, expression });
}
reduceDebuggerStatement(node) {
return new Shift.DebuggerStatement;
}
reduceDirective(node) {
return new Shift.Directive({ rawValue: node.rawValue });
}
reduceDoWhileStatement(node, { body, test }) {
return new Shift.DoWhileStatement({ body, test });
}
reduceEmptyStatement(node) {
return new Shift.EmptyStatement;
}
reduceExport(node, { declaration }) {
return new Shift.Export({ declaration });
}
reduceExportAllFrom(node) {
return new Shift.ExportAllFrom({ moduleSpecifier: node.moduleSpecifier });
}
reduceExportDefault(node, { body }) {
return new Shift.ExportDefault({ body });
}
reduceExportFrom(node, { namedExports }) {
return new Shift.ExportFrom({ namedExports, moduleSpecifier: node.moduleSpecifier });
}
reduceExportFromSpecifier(node) {
return new Shift.ExportFromSpecifier({ name: node.name, exportedName: node.exportedName });
}
reduceExportLocalSpecifier(node, { name }) {
return new Shift.ExportLocalSpecifier({ name, exportedName: node.exportedName });
}
reduceExportLocals(node, { namedExports }) {
return new Shift.ExportLocals({ namedExports });
}
reduceExpressionStatement(node, { expression }) {
return new Shift.ExpressionStatement({ expression });
}
reduceForAwaitStatement(node, { left, right, body }) {
return new Shift.ForAwaitStatement({ left, right, body });
}
reduceForInStatement(node, { left, right, body }) {
return new Shift.ForInStatement({ left, right, body });
}
reduceForOfStatement(node, { left, right, body }) {
return new Shift.ForOfStatement({ left, right, body });
}
reduceForStatement(node, { init, test, update, body }) {
return new Shift.ForStatement({ init, test, update, body });
}
reduceFormalParameters(node, { items, rest }) {
return new Shift.FormalParameters({ items, rest });
}
reduceFunctionBody(node, { directives, statements }) {
return new Shift.FunctionBody({ directives, statements });
}
reduceFunctionDeclaration(node, { name, params, body }) {
return new Shift.FunctionDeclaration({ isAsync: node.isAsync, isGenerator: node.isGenerator, name, params, body });
}
reduceFunctionExpression(node, { name, params, body }) {
return new Shift.FunctionExpression({ isAsync: node.isAsync, isGenerator: node.isGenerator, name, params, body });
}
reduceGetter(node, { name, body }) {
return new Shift.Getter({ name, body });
}
reduceIdentifierExpression(node) {
return new Shift.IdentifierExpression({ name: node.name });
}
reduceIfStatement(node, { test, consequent, alternate }) {
return new Shift.IfStatement({ test, consequent, alternate });
}
reduceImport(node, { defaultBinding, namedImports }) {
return new Shift.Import({ defaultBinding, namedImports, moduleSpecifier: node.moduleSpecifier });
}
reduceImportNamespace(node, { defaultBinding, namespaceBinding }) {
return new Shift.ImportNamespace({ defaultBinding, namespaceBinding, moduleSpecifier: node.moduleSpecifier });
}
reduceImportSpecifier(node, { binding }) {
return new Shift.ImportSpecifier({ name: node.name, binding });
}
reduceLabeledStatement(node, { body }) {
return new Shift.LabeledStatement({ label: node.label, body });
}
reduceLiteralBooleanExpression(node) {
return new Shift.LiteralBooleanExpression({ value: node.value });
}
reduceLiteralInfinityExpression(node) {
return new Shift.LiteralInfinityExpression;
}
reduceLiteralNullExpression(node) {
return new Shift.LiteralNullExpression;
}
reduceLiteralNumericExpression(node) {
return new Shift.LiteralNumericExpression({ value: node.value });
}
reduceLiteralRegExpExpression(node) {
return new Shift.LiteralRegExpExpression({ pattern: node.pattern, global: node.global, ignoreCase: node.ignoreCase, multiLine: node.multiLine, dotAll: node.dotAll, unicode: node.unicode, sticky: node.sticky });
}
reduceLiteralStringExpression(node) {
return new Shift.LiteralStringExpression({ value: node.value });
}
reduceMethod(node, { name, params, body }) {
return new Shift.Method({ isAsync: node.isAsync, isGenerator: node.isGenerator, name, params, body });
}
reduceModule(node, { directives, items }) {
return new Shift.Module({ directives, items });
}
reduceNewExpression(node, { callee, arguments: _arguments }) {
return new Shift.NewExpression({ callee, arguments: _arguments });
}
reduceNewTargetExpression(node) {
return new Shift.NewTargetExpression;
}
reduceObjectAssignmentTarget(node, { properties, rest }) {
return new Shift.ObjectAssignmentTarget({ properties, rest });
}
reduceObjectBinding(node, { properties, rest }) {
return new Shift.ObjectBinding({ properties, rest });
}
reduceObjectExpression(node, { properties }) {
return new Shift.ObjectExpression({ properties });
}
reduceReturnStatement(node, { expression }) {
return new Shift.ReturnStatement({ expression });
}
reduceScript(node, { directives, statements }) {
return new Shift.Script({ directives, statements });
}
reduceSetter(node, { name, param, body }) {
return new Shift.Setter({ name, param, body });
}
reduceShorthandProperty(node, { name }) {
return new Shift.ShorthandProperty({ name });
}
reduceSpreadElement(node, { expression }) {
return new Shift.SpreadElement({ expression });
}
reduceSpreadProperty(node, { expression }) {
return new Shift.SpreadProperty({ expression });
}
reduceStaticMemberAssignmentTarget(node, { object }) {
return new Shift.StaticMemberAssignmentTarget({ object, property: node.property });
}
reduceStaticMemberExpression(node, { object }) {
return new Shift.StaticMemberExpression({ object, property: node.property });
}
reduceStaticPropertyName(node) {
return new Shift.StaticPropertyName({ value: node.value });
}
reduceSuper(node) {
return new Shift.Super;
}
reduceSwitchCase(node, { test, consequent }) {
return new Shift.SwitchCase({ test, consequent });
}
reduceSwitchDefault(node, { consequent }) {
return new Shift.SwitchDefault({ consequent });
}
reduceSwitchStatement(node, { discriminant, cases }) {
return new Shift.SwitchStatement({ discriminant, cases });
}
reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) {
return new Shift.SwitchStatementWithDefault({ discriminant, preDefaultCases, defaultCase, postDefaultCases });
}
reduceTemplateElement(node) {
return new Shift.TemplateElement({ rawValue: node.rawValue });
}
reduceTemplateExpression(node, { tag, elements }) {
return new Shift.TemplateExpression({ tag, elements });
}
reduceThisExpression(node) {
return new Shift.ThisExpression;
}
reduceThrowStatement(node, { expression }) {
return new Shift.ThrowStatement({ expression });
}
reduceTryCatchStatement(node, { body, catchClause }) {
return new Shift.TryCatchStatement({ body, catchClause });
}
reduceTryFinallyStatement(node, { body, catchClause, finalizer }) {
return new Shift.TryFinallyStatement({ body, catchClause, finalizer });
}
reduceUnaryExpression(node, { operand }) {
return new Shift.UnaryExpression({ operator: node.operator, operand });
}
reduceUpdateExpression(node, { operand }) {
return new Shift.UpdateExpression({ isPrefix: node.isPrefix, operator: node.operator, operand });
}
reduceVariableDeclaration(node, { declarators }) {
return new Shift.VariableDeclaration({ kind: node.kind, declarators });
}
reduceVariableDeclarationStatement(node, { declaration }) {
return new Shift.VariableDeclarationStatement({ declaration });
}
reduceVariableDeclarator(node, { binding, init }) {
return new Shift.VariableDeclarator({ binding, init });
}
reduceWhileStatement(node, { test, body }) {
return new Shift.WhileStatement({ test, body });
}
reduceWithStatement(node, { object, body }) {
return new Shift.WithStatement({ object, body });
}
reduceYieldExpression(node, { expression }) {
return new Shift.YieldExpression({ expression });
}
reduceYieldGeneratorExpression(node, { expression }) {
return new Shift.YieldGeneratorExpression({ expression });
}
}

View File

@ -0,0 +1,418 @@
// Generated by generate-director.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const director = {
ArrayAssignmentTarget(reducer, node) {
return reducer.reduceArrayAssignmentTarget(node, { elements: node.elements.map(v => v && this[v.type](reducer, v)), rest: node.rest && this[node.rest.type](reducer, node.rest) });
},
ArrayBinding(reducer, node) {
return reducer.reduceArrayBinding(node, { elements: node.elements.map(v => v && this[v.type](reducer, v)), rest: node.rest && this[node.rest.type](reducer, node.rest) });
},
ArrayExpression(reducer, node) {
return reducer.reduceArrayExpression(node, { elements: node.elements.map(v => v && this[v.type](reducer, v)) });
},
ArrowExpression(reducer, node) {
return reducer.reduceArrowExpression(node, { params: this.FormalParameters(reducer, node.params), body: this[node.body.type](reducer, node.body) });
},
AssignmentExpression(reducer, node) {
return reducer.reduceAssignmentExpression(node, { binding: this[node.binding.type](reducer, node.binding), expression: this[node.expression.type](reducer, node.expression) });
},
AssignmentTargetIdentifier(reducer, node) {
return reducer.reduceAssignmentTargetIdentifier(node);
},
AssignmentTargetPropertyIdentifier(reducer, node) {
return reducer.reduceAssignmentTargetPropertyIdentifier(node, { binding: this.AssignmentTargetIdentifier(reducer, node.binding), init: node.init && this[node.init.type](reducer, node.init) });
},
AssignmentTargetPropertyProperty(reducer, node) {
return reducer.reduceAssignmentTargetPropertyProperty(node, { name: this[node.name.type](reducer, node.name), binding: this[node.binding.type](reducer, node.binding) });
},
AssignmentTargetWithDefault(reducer, node) {
return reducer.reduceAssignmentTargetWithDefault(node, { binding: this[node.binding.type](reducer, node.binding), init: this[node.init.type](reducer, node.init) });
},
AwaitExpression(reducer, node) {
return reducer.reduceAwaitExpression(node, { expression: this[node.expression.type](reducer, node.expression) });
},
BinaryExpression(reducer, node) {
return reducer.reduceBinaryExpression(node, { left: this[node.left.type](reducer, node.left), right: this[node.right.type](reducer, node.right) });
},
BindingIdentifier(reducer, node) {
return reducer.reduceBindingIdentifier(node);
},
BindingPropertyIdentifier(reducer, node) {
return reducer.reduceBindingPropertyIdentifier(node, { binding: this.BindingIdentifier(reducer, node.binding), init: node.init && this[node.init.type](reducer, node.init) });
},
BindingPropertyProperty(reducer, node) {
return reducer.reduceBindingPropertyProperty(node, { name: this[node.name.type](reducer, node.name), binding: this[node.binding.type](reducer, node.binding) });
},
BindingWithDefault(reducer, node) {
return reducer.reduceBindingWithDefault(node, { binding: this[node.binding.type](reducer, node.binding), init: this[node.init.type](reducer, node.init) });
},
Block(reducer, node) {
return reducer.reduceBlock(node, { statements: node.statements.map(v => this[v.type](reducer, v)) });
},
BlockStatement(reducer, node) {
return reducer.reduceBlockStatement(node, { block: this.Block(reducer, node.block) });
},
BreakStatement(reducer, node) {
return reducer.reduceBreakStatement(node);
},
CallExpression(reducer, node) {
return reducer.reduceCallExpression(node, { callee: this[node.callee.type](reducer, node.callee), arguments: node.arguments.map(v => this[v.type](reducer, v)) });
},
CatchClause(reducer, node) {
return reducer.reduceCatchClause(node, { binding: this[node.binding.type](reducer, node.binding), body: this.Block(reducer, node.body) });
},
ClassDeclaration(reducer, node) {
return reducer.reduceClassDeclaration(node, { name: this.BindingIdentifier(reducer, node.name), super: node.super && this[node.super.type](reducer, node.super), elements: node.elements.map(v => this.ClassElement(reducer, v)) });
},
ClassElement(reducer, node) {
return reducer.reduceClassElement(node, { method: this[node.method.type](reducer, node.method) });
},
ClassExpression(reducer, node) {
return reducer.reduceClassExpression(node, { name: node.name && this.BindingIdentifier(reducer, node.name), super: node.super && this[node.super.type](reducer, node.super), elements: node.elements.map(v => this.ClassElement(reducer, v)) });
},
CompoundAssignmentExpression(reducer, node) {
return reducer.reduceCompoundAssignmentExpression(node, { binding: this[node.binding.type](reducer, node.binding), expression: this[node.expression.type](reducer, node.expression) });
},
ComputedMemberAssignmentTarget(reducer, node) {
return reducer.reduceComputedMemberAssignmentTarget(node, { object: this[node.object.type](reducer, node.object), expression: this[node.expression.type](reducer, node.expression) });
},
ComputedMemberExpression(reducer, node) {
return reducer.reduceComputedMemberExpression(node, { object: this[node.object.type](reducer, node.object), expression: this[node.expression.type](reducer, node.expression) });
},
ComputedPropertyName(reducer, node) {
return reducer.reduceComputedPropertyName(node, { expression: this[node.expression.type](reducer, node.expression) });
},
ConditionalExpression(reducer, node) {
return reducer.reduceConditionalExpression(node, { test: this[node.test.type](reducer, node.test), consequent: this[node.consequent.type](reducer, node.consequent), alternate: this[node.alternate.type](reducer, node.alternate) });
},
ContinueStatement(reducer, node) {
return reducer.reduceContinueStatement(node);
},
DataProperty(reducer, node) {
return reducer.reduceDataProperty(node, { name: this[node.name.type](reducer, node.name), expression: this[node.expression.type](reducer, node.expression) });
},
DebuggerStatement(reducer, node) {
return reducer.reduceDebuggerStatement(node);
},
Directive(reducer, node) {
return reducer.reduceDirective(node);
},
DoWhileStatement(reducer, node) {
return reducer.reduceDoWhileStatement(node, { body: this[node.body.type](reducer, node.body), test: this[node.test.type](reducer, node.test) });
},
EmptyStatement(reducer, node) {
return reducer.reduceEmptyStatement(node);
},
Export(reducer, node) {
return reducer.reduceExport(node, { declaration: this[node.declaration.type](reducer, node.declaration) });
},
ExportAllFrom(reducer, node) {
return reducer.reduceExportAllFrom(node);
},
ExportDefault(reducer, node) {
return reducer.reduceExportDefault(node, { body: this[node.body.type](reducer, node.body) });
},
ExportFrom(reducer, node) {
return reducer.reduceExportFrom(node, { namedExports: node.namedExports.map(v => this.ExportFromSpecifier(reducer, v)) });
},
ExportFromSpecifier(reducer, node) {
return reducer.reduceExportFromSpecifier(node);
},
ExportLocalSpecifier(reducer, node) {
return reducer.reduceExportLocalSpecifier(node, { name: this.IdentifierExpression(reducer, node.name) });
},
ExportLocals(reducer, node) {
return reducer.reduceExportLocals(node, { namedExports: node.namedExports.map(v => this.ExportLocalSpecifier(reducer, v)) });
},
ExpressionStatement(reducer, node) {
return reducer.reduceExpressionStatement(node, { expression: this[node.expression.type](reducer, node.expression) });
},
ForAwaitStatement(reducer, node) {
return reducer.reduceForAwaitStatement(node, { left: this[node.left.type](reducer, node.left), right: this[node.right.type](reducer, node.right), body: this[node.body.type](reducer, node.body) });
},
ForInStatement(reducer, node) {
return reducer.reduceForInStatement(node, { left: this[node.left.type](reducer, node.left), right: this[node.right.type](reducer, node.right), body: this[node.body.type](reducer, node.body) });
},
ForOfStatement(reducer, node) {
return reducer.reduceForOfStatement(node, { left: this[node.left.type](reducer, node.left), right: this[node.right.type](reducer, node.right), body: this[node.body.type](reducer, node.body) });
},
ForStatement(reducer, node) {
return reducer.reduceForStatement(node, { init: node.init && this[node.init.type](reducer, node.init), test: node.test && this[node.test.type](reducer, node.test), update: node.update && this[node.update.type](reducer, node.update), body: this[node.body.type](reducer, node.body) });
},
FormalParameters(reducer, node) {
return reducer.reduceFormalParameters(node, { items: node.items.map(v => this[v.type](reducer, v)), rest: node.rest && this[node.rest.type](reducer, node.rest) });
},
FunctionBody(reducer, node) {
return reducer.reduceFunctionBody(node, { directives: node.directives.map(v => this.Directive(reducer, v)), statements: node.statements.map(v => this[v.type](reducer, v)) });
},
FunctionDeclaration(reducer, node) {
return reducer.reduceFunctionDeclaration(node, { name: this.BindingIdentifier(reducer, node.name), params: this.FormalParameters(reducer, node.params), body: this.FunctionBody(reducer, node.body) });
},
FunctionExpression(reducer, node) {
return reducer.reduceFunctionExpression(node, { name: node.name && this.BindingIdentifier(reducer, node.name), params: this.FormalParameters(reducer, node.params), body: this.FunctionBody(reducer, node.body) });
},
Getter(reducer, node) {
return reducer.reduceGetter(node, { name: this[node.name.type](reducer, node.name), body: this.FunctionBody(reducer, node.body) });
},
IdentifierExpression(reducer, node) {
return reducer.reduceIdentifierExpression(node);
},
IfStatement(reducer, node) {
return reducer.reduceIfStatement(node, { test: this[node.test.type](reducer, node.test), consequent: this[node.consequent.type](reducer, node.consequent), alternate: node.alternate && this[node.alternate.type](reducer, node.alternate) });
},
Import(reducer, node) {
return reducer.reduceImport(node, { defaultBinding: node.defaultBinding && this.BindingIdentifier(reducer, node.defaultBinding), namedImports: node.namedImports.map(v => this.ImportSpecifier(reducer, v)) });
},
ImportNamespace(reducer, node) {
return reducer.reduceImportNamespace(node, { defaultBinding: node.defaultBinding && this.BindingIdentifier(reducer, node.defaultBinding), namespaceBinding: this.BindingIdentifier(reducer, node.namespaceBinding) });
},
ImportSpecifier(reducer, node) {
return reducer.reduceImportSpecifier(node, { binding: this.BindingIdentifier(reducer, node.binding) });
},
LabeledStatement(reducer, node) {
return reducer.reduceLabeledStatement(node, { body: this[node.body.type](reducer, node.body) });
},
LiteralBooleanExpression(reducer, node) {
return reducer.reduceLiteralBooleanExpression(node);
},
LiteralInfinityExpression(reducer, node) {
return reducer.reduceLiteralInfinityExpression(node);
},
LiteralNullExpression(reducer, node) {
return reducer.reduceLiteralNullExpression(node);
},
LiteralNumericExpression(reducer, node) {
return reducer.reduceLiteralNumericExpression(node);
},
LiteralRegExpExpression(reducer, node) {
return reducer.reduceLiteralRegExpExpression(node);
},
LiteralStringExpression(reducer, node) {
return reducer.reduceLiteralStringExpression(node);
},
Method(reducer, node) {
return reducer.reduceMethod(node, { name: this[node.name.type](reducer, node.name), params: this.FormalParameters(reducer, node.params), body: this.FunctionBody(reducer, node.body) });
},
Module(reducer, node) {
return reducer.reduceModule(node, { directives: node.directives.map(v => this.Directive(reducer, v)), items: node.items.map(v => this[v.type](reducer, v)) });
},
NewExpression(reducer, node) {
return reducer.reduceNewExpression(node, { callee: this[node.callee.type](reducer, node.callee), arguments: node.arguments.map(v => this[v.type](reducer, v)) });
},
NewTargetExpression(reducer, node) {
return reducer.reduceNewTargetExpression(node);
},
ObjectAssignmentTarget(reducer, node) {
return reducer.reduceObjectAssignmentTarget(node, { properties: node.properties.map(v => this[v.type](reducer, v)), rest: node.rest && this[node.rest.type](reducer, node.rest) });
},
ObjectBinding(reducer, node) {
return reducer.reduceObjectBinding(node, { properties: node.properties.map(v => this[v.type](reducer, v)), rest: node.rest && this[node.rest.type](reducer, node.rest) });
},
ObjectExpression(reducer, node) {
return reducer.reduceObjectExpression(node, { properties: node.properties.map(v => this[v.type](reducer, v)) });
},
ReturnStatement(reducer, node) {
return reducer.reduceReturnStatement(node, { expression: node.expression && this[node.expression.type](reducer, node.expression) });
},
Script(reducer, node) {
return reducer.reduceScript(node, { directives: node.directives.map(v => this.Directive(reducer, v)), statements: node.statements.map(v => this[v.type](reducer, v)) });
},
Setter(reducer, node) {
return reducer.reduceSetter(node, { name: this[node.name.type](reducer, node.name), param: this[node.param.type](reducer, node.param), body: this.FunctionBody(reducer, node.body) });
},
ShorthandProperty(reducer, node) {
return reducer.reduceShorthandProperty(node, { name: this.IdentifierExpression(reducer, node.name) });
},
SpreadElement(reducer, node) {
return reducer.reduceSpreadElement(node, { expression: this[node.expression.type](reducer, node.expression) });
},
SpreadProperty(reducer, node) {
return reducer.reduceSpreadProperty(node, { expression: this[node.expression.type](reducer, node.expression) });
},
StaticMemberAssignmentTarget(reducer, node) {
return reducer.reduceStaticMemberAssignmentTarget(node, { object: this[node.object.type](reducer, node.object) });
},
StaticMemberExpression(reducer, node) {
return reducer.reduceStaticMemberExpression(node, { object: this[node.object.type](reducer, node.object) });
},
StaticPropertyName(reducer, node) {
return reducer.reduceStaticPropertyName(node);
},
Super(reducer, node) {
return reducer.reduceSuper(node);
},
SwitchCase(reducer, node) {
return reducer.reduceSwitchCase(node, { test: this[node.test.type](reducer, node.test), consequent: node.consequent.map(v => this[v.type](reducer, v)) });
},
SwitchDefault(reducer, node) {
return reducer.reduceSwitchDefault(node, { consequent: node.consequent.map(v => this[v.type](reducer, v)) });
},
SwitchStatement(reducer, node) {
return reducer.reduceSwitchStatement(node, { discriminant: this[node.discriminant.type](reducer, node.discriminant), cases: node.cases.map(v => this.SwitchCase(reducer, v)) });
},
SwitchStatementWithDefault(reducer, node) {
return reducer.reduceSwitchStatementWithDefault(node, { discriminant: this[node.discriminant.type](reducer, node.discriminant), preDefaultCases: node.preDefaultCases.map(v => this.SwitchCase(reducer, v)), defaultCase: this.SwitchDefault(reducer, node.defaultCase), postDefaultCases: node.postDefaultCases.map(v => this.SwitchCase(reducer, v)) });
},
TemplateElement(reducer, node) {
return reducer.reduceTemplateElement(node);
},
TemplateExpression(reducer, node) {
return reducer.reduceTemplateExpression(node, { tag: node.tag && this[node.tag.type](reducer, node.tag), elements: node.elements.map(v => this[v.type](reducer, v)) });
},
ThisExpression(reducer, node) {
return reducer.reduceThisExpression(node);
},
ThrowStatement(reducer, node) {
return reducer.reduceThrowStatement(node, { expression: this[node.expression.type](reducer, node.expression) });
},
TryCatchStatement(reducer, node) {
return reducer.reduceTryCatchStatement(node, { body: this.Block(reducer, node.body), catchClause: this.CatchClause(reducer, node.catchClause) });
},
TryFinallyStatement(reducer, node) {
return reducer.reduceTryFinallyStatement(node, { body: this.Block(reducer, node.body), catchClause: node.catchClause && this.CatchClause(reducer, node.catchClause), finalizer: this.Block(reducer, node.finalizer) });
},
UnaryExpression(reducer, node) {
return reducer.reduceUnaryExpression(node, { operand: this[node.operand.type](reducer, node.operand) });
},
UpdateExpression(reducer, node) {
return reducer.reduceUpdateExpression(node, { operand: this[node.operand.type](reducer, node.operand) });
},
VariableDeclaration(reducer, node) {
return reducer.reduceVariableDeclaration(node, { declarators: node.declarators.map(v => this.VariableDeclarator(reducer, v)) });
},
VariableDeclarationStatement(reducer, node) {
return reducer.reduceVariableDeclarationStatement(node, { declaration: this.VariableDeclaration(reducer, node.declaration) });
},
VariableDeclarator(reducer, node) {
return reducer.reduceVariableDeclarator(node, { binding: this[node.binding.type](reducer, node.binding), init: node.init && this[node.init.type](reducer, node.init) });
},
WhileStatement(reducer, node) {
return reducer.reduceWhileStatement(node, { test: this[node.test.type](reducer, node.test), body: this[node.body.type](reducer, node.body) });
},
WithStatement(reducer, node) {
return reducer.reduceWithStatement(node, { object: this[node.object.type](reducer, node.object), body: this[node.body.type](reducer, node.body) });
},
YieldExpression(reducer, node) {
return reducer.reduceYieldExpression(node, { expression: node.expression && this[node.expression.type](reducer, node.expression) });
},
YieldGeneratorExpression(reducer, node) {
return reducer.reduceYieldGeneratorExpression(node, { expression: this[node.expression.type](reducer, node.expression) });
},
};
export function reduce(reducer, node) {
return director[node.type](reducer, node);
}

View File

@ -0,0 +1,27 @@
/*
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { reduce, reduce as default } from './director.js';
export { thunkedReduce } from './thunked-director.js';
export { default as thunkify } from './thunkify.js';
export { default as thunkifyClass } from './thunkify-class.js';
export { default as memoize } from './memoize.js';
export { default as CloneReducer } from './clone-reducer.js';
export { default as LazyCloneReducer } from './lazy-clone-reducer.js';
export { default as MonoidalReducer } from './monoidal-reducer.js';
export { default as ThunkedMonoidalReducer } from './thunked-monoidal-reducer.js';
export { default as adapt } from './adapt.js';
export { PlusReducer, ThunkedPlusReducer, ConcatReducer, ThunkedConcatReducer, AndReducer, ThunkedAndReducer, OrReducer, ThunkedOrReducer } from './reducers.js';

View File

@ -0,0 +1,650 @@
// Generated by generate-lazy-clone-reducer.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as Shift from 'shift-ast';
export default class LazyCloneReducer {
reduceArrayAssignmentTarget(node, { elements, rest }) {
if ((node.elements.length === elements.length && node.elements.every((v, i) => v === elements[i])) && node.rest === rest) {
return node;
}
return new Shift.ArrayAssignmentTarget({ elements, rest });
}
reduceArrayBinding(node, { elements, rest }) {
if ((node.elements.length === elements.length && node.elements.every((v, i) => v === elements[i])) && node.rest === rest) {
return node;
}
return new Shift.ArrayBinding({ elements, rest });
}
reduceArrayExpression(node, { elements }) {
if ((node.elements.length === elements.length && node.elements.every((v, i) => v === elements[i]))) {
return node;
}
return new Shift.ArrayExpression({ elements });
}
reduceArrowExpression(node, { params, body }) {
if (node.params === params && node.body === body) {
return node;
}
return new Shift.ArrowExpression({ isAsync: node.isAsync, params, body });
}
reduceAssignmentExpression(node, { binding, expression }) {
if (node.binding === binding && node.expression === expression) {
return node;
}
return new Shift.AssignmentExpression({ binding, expression });
}
reduceAssignmentTargetIdentifier(node) {
return node;
}
reduceAssignmentTargetPropertyIdentifier(node, { binding, init }) {
if (node.binding === binding && node.init === init) {
return node;
}
return new Shift.AssignmentTargetPropertyIdentifier({ binding, init });
}
reduceAssignmentTargetPropertyProperty(node, { name, binding }) {
if (node.name === name && node.binding === binding) {
return node;
}
return new Shift.AssignmentTargetPropertyProperty({ name, binding });
}
reduceAssignmentTargetWithDefault(node, { binding, init }) {
if (node.binding === binding && node.init === init) {
return node;
}
return new Shift.AssignmentTargetWithDefault({ binding, init });
}
reduceAwaitExpression(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.AwaitExpression({ expression });
}
reduceBinaryExpression(node, { left, right }) {
if (node.left === left && node.right === right) {
return node;
}
return new Shift.BinaryExpression({ left, operator: node.operator, right });
}
reduceBindingIdentifier(node) {
return node;
}
reduceBindingPropertyIdentifier(node, { binding, init }) {
if (node.binding === binding && node.init === init) {
return node;
}
return new Shift.BindingPropertyIdentifier({ binding, init });
}
reduceBindingPropertyProperty(node, { name, binding }) {
if (node.name === name && node.binding === binding) {
return node;
}
return new Shift.BindingPropertyProperty({ name, binding });
}
reduceBindingWithDefault(node, { binding, init }) {
if (node.binding === binding && node.init === init) {
return node;
}
return new Shift.BindingWithDefault({ binding, init });
}
reduceBlock(node, { statements }) {
if ((node.statements.length === statements.length && node.statements.every((v, i) => v === statements[i]))) {
return node;
}
return new Shift.Block({ statements });
}
reduceBlockStatement(node, { block }) {
if (node.block === block) {
return node;
}
return new Shift.BlockStatement({ block });
}
reduceBreakStatement(node) {
return node;
}
reduceCallExpression(node, { callee, arguments: _arguments }) {
if (node.callee === callee && (node.arguments.length === _arguments.length && node.arguments.every((v, i) => v === _arguments[i]))) {
return node;
}
return new Shift.CallExpression({ callee, arguments: _arguments });
}
reduceCatchClause(node, { binding, body }) {
if (node.binding === binding && node.body === body) {
return node;
}
return new Shift.CatchClause({ binding, body });
}
reduceClassDeclaration(node, { name, super: _super, elements }) {
if (node.name === name && node.super === _super && (node.elements.length === elements.length && node.elements.every((v, i) => v === elements[i]))) {
return node;
}
return new Shift.ClassDeclaration({ name, super: _super, elements });
}
reduceClassElement(node, { method }) {
if (node.method === method) {
return node;
}
return new Shift.ClassElement({ isStatic: node.isStatic, method });
}
reduceClassExpression(node, { name, super: _super, elements }) {
if (node.name === name && node.super === _super && (node.elements.length === elements.length && node.elements.every((v, i) => v === elements[i]))) {
return node;
}
return new Shift.ClassExpression({ name, super: _super, elements });
}
reduceCompoundAssignmentExpression(node, { binding, expression }) {
if (node.binding === binding && node.expression === expression) {
return node;
}
return new Shift.CompoundAssignmentExpression({ binding, operator: node.operator, expression });
}
reduceComputedMemberAssignmentTarget(node, { object, expression }) {
if (node.object === object && node.expression === expression) {
return node;
}
return new Shift.ComputedMemberAssignmentTarget({ object, expression });
}
reduceComputedMemberExpression(node, { object, expression }) {
if (node.object === object && node.expression === expression) {
return node;
}
return new Shift.ComputedMemberExpression({ object, expression });
}
reduceComputedPropertyName(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.ComputedPropertyName({ expression });
}
reduceConditionalExpression(node, { test, consequent, alternate }) {
if (node.test === test && node.consequent === consequent && node.alternate === alternate) {
return node;
}
return new Shift.ConditionalExpression({ test, consequent, alternate });
}
reduceContinueStatement(node) {
return node;
}
reduceDataProperty(node, { name, expression }) {
if (node.name === name && node.expression === expression) {
return node;
}
return new Shift.DataProperty({ name, expression });
}
reduceDebuggerStatement(node) {
return node;
}
reduceDirective(node) {
return node;
}
reduceDoWhileStatement(node, { body, test }) {
if (node.body === body && node.test === test) {
return node;
}
return new Shift.DoWhileStatement({ body, test });
}
reduceEmptyStatement(node) {
return node;
}
reduceExport(node, { declaration }) {
if (node.declaration === declaration) {
return node;
}
return new Shift.Export({ declaration });
}
reduceExportAllFrom(node) {
return node;
}
reduceExportDefault(node, { body }) {
if (node.body === body) {
return node;
}
return new Shift.ExportDefault({ body });
}
reduceExportFrom(node, { namedExports }) {
if ((node.namedExports.length === namedExports.length && node.namedExports.every((v, i) => v === namedExports[i]))) {
return node;
}
return new Shift.ExportFrom({ namedExports, moduleSpecifier: node.moduleSpecifier });
}
reduceExportFromSpecifier(node) {
return node;
}
reduceExportLocalSpecifier(node, { name }) {
if (node.name === name) {
return node;
}
return new Shift.ExportLocalSpecifier({ name, exportedName: node.exportedName });
}
reduceExportLocals(node, { namedExports }) {
if ((node.namedExports.length === namedExports.length && node.namedExports.every((v, i) => v === namedExports[i]))) {
return node;
}
return new Shift.ExportLocals({ namedExports });
}
reduceExpressionStatement(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.ExpressionStatement({ expression });
}
reduceForAwaitStatement(node, { left, right, body }) {
if (node.left === left && node.right === right && node.body === body) {
return node;
}
return new Shift.ForAwaitStatement({ left, right, body });
}
reduceForInStatement(node, { left, right, body }) {
if (node.left === left && node.right === right && node.body === body) {
return node;
}
return new Shift.ForInStatement({ left, right, body });
}
reduceForOfStatement(node, { left, right, body }) {
if (node.left === left && node.right === right && node.body === body) {
return node;
}
return new Shift.ForOfStatement({ left, right, body });
}
reduceForStatement(node, { init, test, update, body }) {
if (node.init === init && node.test === test && node.update === update && node.body === body) {
return node;
}
return new Shift.ForStatement({ init, test, update, body });
}
reduceFormalParameters(node, { items, rest }) {
if ((node.items.length === items.length && node.items.every((v, i) => v === items[i])) && node.rest === rest) {
return node;
}
return new Shift.FormalParameters({ items, rest });
}
reduceFunctionBody(node, { directives, statements }) {
if ((node.directives.length === directives.length && node.directives.every((v, i) => v === directives[i])) && (node.statements.length === statements.length && node.statements.every((v, i) => v === statements[i]))) {
return node;
}
return new Shift.FunctionBody({ directives, statements });
}
reduceFunctionDeclaration(node, { name, params, body }) {
if (node.name === name && node.params === params && node.body === body) {
return node;
}
return new Shift.FunctionDeclaration({ isAsync: node.isAsync, isGenerator: node.isGenerator, name, params, body });
}
reduceFunctionExpression(node, { name, params, body }) {
if (node.name === name && node.params === params && node.body === body) {
return node;
}
return new Shift.FunctionExpression({ isAsync: node.isAsync, isGenerator: node.isGenerator, name, params, body });
}
reduceGetter(node, { name, body }) {
if (node.name === name && node.body === body) {
return node;
}
return new Shift.Getter({ name, body });
}
reduceIdentifierExpression(node) {
return node;
}
reduceIfStatement(node, { test, consequent, alternate }) {
if (node.test === test && node.consequent === consequent && node.alternate === alternate) {
return node;
}
return new Shift.IfStatement({ test, consequent, alternate });
}
reduceImport(node, { defaultBinding, namedImports }) {
if (node.defaultBinding === defaultBinding && (node.namedImports.length === namedImports.length && node.namedImports.every((v, i) => v === namedImports[i]))) {
return node;
}
return new Shift.Import({ defaultBinding, namedImports, moduleSpecifier: node.moduleSpecifier });
}
reduceImportNamespace(node, { defaultBinding, namespaceBinding }) {
if (node.defaultBinding === defaultBinding && node.namespaceBinding === namespaceBinding) {
return node;
}
return new Shift.ImportNamespace({ defaultBinding, namespaceBinding, moduleSpecifier: node.moduleSpecifier });
}
reduceImportSpecifier(node, { binding }) {
if (node.binding === binding) {
return node;
}
return new Shift.ImportSpecifier({ name: node.name, binding });
}
reduceLabeledStatement(node, { body }) {
if (node.body === body) {
return node;
}
return new Shift.LabeledStatement({ label: node.label, body });
}
reduceLiteralBooleanExpression(node) {
return node;
}
reduceLiteralInfinityExpression(node) {
return node;
}
reduceLiteralNullExpression(node) {
return node;
}
reduceLiteralNumericExpression(node) {
return node;
}
reduceLiteralRegExpExpression(node) {
return node;
}
reduceLiteralStringExpression(node) {
return node;
}
reduceMethod(node, { name, params, body }) {
if (node.name === name && node.params === params && node.body === body) {
return node;
}
return new Shift.Method({ isAsync: node.isAsync, isGenerator: node.isGenerator, name, params, body });
}
reduceModule(node, { directives, items }) {
if ((node.directives.length === directives.length && node.directives.every((v, i) => v === directives[i])) && (node.items.length === items.length && node.items.every((v, i) => v === items[i]))) {
return node;
}
return new Shift.Module({ directives, items });
}
reduceNewExpression(node, { callee, arguments: _arguments }) {
if (node.callee === callee && (node.arguments.length === _arguments.length && node.arguments.every((v, i) => v === _arguments[i]))) {
return node;
}
return new Shift.NewExpression({ callee, arguments: _arguments });
}
reduceNewTargetExpression(node) {
return node;
}
reduceObjectAssignmentTarget(node, { properties, rest }) {
if ((node.properties.length === properties.length && node.properties.every((v, i) => v === properties[i])) && node.rest === rest) {
return node;
}
return new Shift.ObjectAssignmentTarget({ properties, rest });
}
reduceObjectBinding(node, { properties, rest }) {
if ((node.properties.length === properties.length && node.properties.every((v, i) => v === properties[i])) && node.rest === rest) {
return node;
}
return new Shift.ObjectBinding({ properties, rest });
}
reduceObjectExpression(node, { properties }) {
if ((node.properties.length === properties.length && node.properties.every((v, i) => v === properties[i]))) {
return node;
}
return new Shift.ObjectExpression({ properties });
}
reduceReturnStatement(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.ReturnStatement({ expression });
}
reduceScript(node, { directives, statements }) {
if ((node.directives.length === directives.length && node.directives.every((v, i) => v === directives[i])) && (node.statements.length === statements.length && node.statements.every((v, i) => v === statements[i]))) {
return node;
}
return new Shift.Script({ directives, statements });
}
reduceSetter(node, { name, param, body }) {
if (node.name === name && node.param === param && node.body === body) {
return node;
}
return new Shift.Setter({ name, param, body });
}
reduceShorthandProperty(node, { name }) {
if (node.name === name) {
return node;
}
return new Shift.ShorthandProperty({ name });
}
reduceSpreadElement(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.SpreadElement({ expression });
}
reduceSpreadProperty(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.SpreadProperty({ expression });
}
reduceStaticMemberAssignmentTarget(node, { object }) {
if (node.object === object) {
return node;
}
return new Shift.StaticMemberAssignmentTarget({ object, property: node.property });
}
reduceStaticMemberExpression(node, { object }) {
if (node.object === object) {
return node;
}
return new Shift.StaticMemberExpression({ object, property: node.property });
}
reduceStaticPropertyName(node) {
return node;
}
reduceSuper(node) {
return node;
}
reduceSwitchCase(node, { test, consequent }) {
if (node.test === test && (node.consequent.length === consequent.length && node.consequent.every((v, i) => v === consequent[i]))) {
return node;
}
return new Shift.SwitchCase({ test, consequent });
}
reduceSwitchDefault(node, { consequent }) {
if ((node.consequent.length === consequent.length && node.consequent.every((v, i) => v === consequent[i]))) {
return node;
}
return new Shift.SwitchDefault({ consequent });
}
reduceSwitchStatement(node, { discriminant, cases }) {
if (node.discriminant === discriminant && (node.cases.length === cases.length && node.cases.every((v, i) => v === cases[i]))) {
return node;
}
return new Shift.SwitchStatement({ discriminant, cases });
}
reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) {
if (node.discriminant === discriminant && (node.preDefaultCases.length === preDefaultCases.length && node.preDefaultCases.every((v, i) => v === preDefaultCases[i])) && node.defaultCase === defaultCase && (node.postDefaultCases.length === postDefaultCases.length && node.postDefaultCases.every((v, i) => v === postDefaultCases[i]))) {
return node;
}
return new Shift.SwitchStatementWithDefault({ discriminant, preDefaultCases, defaultCase, postDefaultCases });
}
reduceTemplateElement(node) {
return node;
}
reduceTemplateExpression(node, { tag, elements }) {
if (node.tag === tag && (node.elements.length === elements.length && node.elements.every((v, i) => v === elements[i]))) {
return node;
}
return new Shift.TemplateExpression({ tag, elements });
}
reduceThisExpression(node) {
return node;
}
reduceThrowStatement(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.ThrowStatement({ expression });
}
reduceTryCatchStatement(node, { body, catchClause }) {
if (node.body === body && node.catchClause === catchClause) {
return node;
}
return new Shift.TryCatchStatement({ body, catchClause });
}
reduceTryFinallyStatement(node, { body, catchClause, finalizer }) {
if (node.body === body && node.catchClause === catchClause && node.finalizer === finalizer) {
return node;
}
return new Shift.TryFinallyStatement({ body, catchClause, finalizer });
}
reduceUnaryExpression(node, { operand }) {
if (node.operand === operand) {
return node;
}
return new Shift.UnaryExpression({ operator: node.operator, operand });
}
reduceUpdateExpression(node, { operand }) {
if (node.operand === operand) {
return node;
}
return new Shift.UpdateExpression({ isPrefix: node.isPrefix, operator: node.operator, operand });
}
reduceVariableDeclaration(node, { declarators }) {
if ((node.declarators.length === declarators.length && node.declarators.every((v, i) => v === declarators[i]))) {
return node;
}
return new Shift.VariableDeclaration({ kind: node.kind, declarators });
}
reduceVariableDeclarationStatement(node, { declaration }) {
if (node.declaration === declaration) {
return node;
}
return new Shift.VariableDeclarationStatement({ declaration });
}
reduceVariableDeclarator(node, { binding, init }) {
if (node.binding === binding && node.init === init) {
return node;
}
return new Shift.VariableDeclarator({ binding, init });
}
reduceWhileStatement(node, { test, body }) {
if (node.test === test && node.body === body) {
return node;
}
return new Shift.WhileStatement({ test, body });
}
reduceWithStatement(node, { object, body }) {
if (node.object === object && node.body === body) {
return node;
}
return new Shift.WithStatement({ object, body });
}
reduceYieldExpression(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.YieldExpression({ expression });
}
reduceYieldGeneratorExpression(node, { expression }) {
if (node.expression === expression) {
return node;
}
return new Shift.YieldGeneratorExpression({ expression });
}
}

View File

@ -0,0 +1,914 @@
// Generated by generate-memoize.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as Shift from 'shift-ast';
export default function memoize(reducer) {
const cache = new WeakMap;
return {
reduceArrayAssignmentTarget(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceArrayAssignmentTarget(node, arg);
cache.set(node, res);
return res;
},
reduceArrayBinding(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceArrayBinding(node, arg);
cache.set(node, res);
return res;
},
reduceArrayExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceArrayExpression(node, arg);
cache.set(node, res);
return res;
},
reduceArrowExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceArrowExpression(node, arg);
cache.set(node, res);
return res;
},
reduceAssignmentExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceAssignmentExpression(node, arg);
cache.set(node, res);
return res;
},
reduceAssignmentTargetIdentifier(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceAssignmentTargetIdentifier(node);
cache.set(node, res);
return res;
},
reduceAssignmentTargetPropertyIdentifier(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceAssignmentTargetPropertyIdentifier(node, arg);
cache.set(node, res);
return res;
},
reduceAssignmentTargetPropertyProperty(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceAssignmentTargetPropertyProperty(node, arg);
cache.set(node, res);
return res;
},
reduceAssignmentTargetWithDefault(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceAssignmentTargetWithDefault(node, arg);
cache.set(node, res);
return res;
},
reduceAwaitExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceAwaitExpression(node, arg);
cache.set(node, res);
return res;
},
reduceBinaryExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBinaryExpression(node, arg);
cache.set(node, res);
return res;
},
reduceBindingIdentifier(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBindingIdentifier(node);
cache.set(node, res);
return res;
},
reduceBindingPropertyIdentifier(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBindingPropertyIdentifier(node, arg);
cache.set(node, res);
return res;
},
reduceBindingPropertyProperty(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBindingPropertyProperty(node, arg);
cache.set(node, res);
return res;
},
reduceBindingWithDefault(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBindingWithDefault(node, arg);
cache.set(node, res);
return res;
},
reduceBlock(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBlock(node, arg);
cache.set(node, res);
return res;
},
reduceBlockStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBlockStatement(node, arg);
cache.set(node, res);
return res;
},
reduceBreakStatement(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceBreakStatement(node);
cache.set(node, res);
return res;
},
reduceCallExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceCallExpression(node, arg);
cache.set(node, res);
return res;
},
reduceCatchClause(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceCatchClause(node, arg);
cache.set(node, res);
return res;
},
reduceClassDeclaration(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceClassDeclaration(node, arg);
cache.set(node, res);
return res;
},
reduceClassElement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceClassElement(node, arg);
cache.set(node, res);
return res;
},
reduceClassExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceClassExpression(node, arg);
cache.set(node, res);
return res;
},
reduceCompoundAssignmentExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceCompoundAssignmentExpression(node, arg);
cache.set(node, res);
return res;
},
reduceComputedMemberAssignmentTarget(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceComputedMemberAssignmentTarget(node, arg);
cache.set(node, res);
return res;
},
reduceComputedMemberExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceComputedMemberExpression(node, arg);
cache.set(node, res);
return res;
},
reduceComputedPropertyName(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceComputedPropertyName(node, arg);
cache.set(node, res);
return res;
},
reduceConditionalExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceConditionalExpression(node, arg);
cache.set(node, res);
return res;
},
reduceContinueStatement(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceContinueStatement(node);
cache.set(node, res);
return res;
},
reduceDataProperty(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceDataProperty(node, arg);
cache.set(node, res);
return res;
},
reduceDebuggerStatement(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceDebuggerStatement(node);
cache.set(node, res);
return res;
},
reduceDirective(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceDirective(node);
cache.set(node, res);
return res;
},
reduceDoWhileStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceDoWhileStatement(node, arg);
cache.set(node, res);
return res;
},
reduceEmptyStatement(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceEmptyStatement(node);
cache.set(node, res);
return res;
},
reduceExport(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExport(node, arg);
cache.set(node, res);
return res;
},
reduceExportAllFrom(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExportAllFrom(node);
cache.set(node, res);
return res;
},
reduceExportDefault(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExportDefault(node, arg);
cache.set(node, res);
return res;
},
reduceExportFrom(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExportFrom(node, arg);
cache.set(node, res);
return res;
},
reduceExportFromSpecifier(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExportFromSpecifier(node);
cache.set(node, res);
return res;
},
reduceExportLocalSpecifier(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExportLocalSpecifier(node, arg);
cache.set(node, res);
return res;
},
reduceExportLocals(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExportLocals(node, arg);
cache.set(node, res);
return res;
},
reduceExpressionStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceExpressionStatement(node, arg);
cache.set(node, res);
return res;
},
reduceForAwaitStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceForAwaitStatement(node, arg);
cache.set(node, res);
return res;
},
reduceForInStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceForInStatement(node, arg);
cache.set(node, res);
return res;
},
reduceForOfStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceForOfStatement(node, arg);
cache.set(node, res);
return res;
},
reduceForStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceForStatement(node, arg);
cache.set(node, res);
return res;
},
reduceFormalParameters(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceFormalParameters(node, arg);
cache.set(node, res);
return res;
},
reduceFunctionBody(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceFunctionBody(node, arg);
cache.set(node, res);
return res;
},
reduceFunctionDeclaration(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceFunctionDeclaration(node, arg);
cache.set(node, res);
return res;
},
reduceFunctionExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceFunctionExpression(node, arg);
cache.set(node, res);
return res;
},
reduceGetter(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceGetter(node, arg);
cache.set(node, res);
return res;
},
reduceIdentifierExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceIdentifierExpression(node);
cache.set(node, res);
return res;
},
reduceIfStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceIfStatement(node, arg);
cache.set(node, res);
return res;
},
reduceImport(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceImport(node, arg);
cache.set(node, res);
return res;
},
reduceImportNamespace(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceImportNamespace(node, arg);
cache.set(node, res);
return res;
},
reduceImportSpecifier(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceImportSpecifier(node, arg);
cache.set(node, res);
return res;
},
reduceLabeledStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceLabeledStatement(node, arg);
cache.set(node, res);
return res;
},
reduceLiteralBooleanExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceLiteralBooleanExpression(node);
cache.set(node, res);
return res;
},
reduceLiteralInfinityExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceLiteralInfinityExpression(node);
cache.set(node, res);
return res;
},
reduceLiteralNullExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceLiteralNullExpression(node);
cache.set(node, res);
return res;
},
reduceLiteralNumericExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceLiteralNumericExpression(node);
cache.set(node, res);
return res;
},
reduceLiteralRegExpExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceLiteralRegExpExpression(node);
cache.set(node, res);
return res;
},
reduceLiteralStringExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceLiteralStringExpression(node);
cache.set(node, res);
return res;
},
reduceMethod(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceMethod(node, arg);
cache.set(node, res);
return res;
},
reduceModule(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceModule(node, arg);
cache.set(node, res);
return res;
},
reduceNewExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceNewExpression(node, arg);
cache.set(node, res);
return res;
},
reduceNewTargetExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceNewTargetExpression(node);
cache.set(node, res);
return res;
},
reduceObjectAssignmentTarget(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceObjectAssignmentTarget(node, arg);
cache.set(node, res);
return res;
},
reduceObjectBinding(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceObjectBinding(node, arg);
cache.set(node, res);
return res;
},
reduceObjectExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceObjectExpression(node, arg);
cache.set(node, res);
return res;
},
reduceReturnStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceReturnStatement(node, arg);
cache.set(node, res);
return res;
},
reduceScript(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceScript(node, arg);
cache.set(node, res);
return res;
},
reduceSetter(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSetter(node, arg);
cache.set(node, res);
return res;
},
reduceShorthandProperty(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceShorthandProperty(node, arg);
cache.set(node, res);
return res;
},
reduceSpreadElement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSpreadElement(node, arg);
cache.set(node, res);
return res;
},
reduceSpreadProperty(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSpreadProperty(node, arg);
cache.set(node, res);
return res;
},
reduceStaticMemberAssignmentTarget(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceStaticMemberAssignmentTarget(node, arg);
cache.set(node, res);
return res;
},
reduceStaticMemberExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceStaticMemberExpression(node, arg);
cache.set(node, res);
return res;
},
reduceStaticPropertyName(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceStaticPropertyName(node);
cache.set(node, res);
return res;
},
reduceSuper(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSuper(node);
cache.set(node, res);
return res;
},
reduceSwitchCase(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSwitchCase(node, arg);
cache.set(node, res);
return res;
},
reduceSwitchDefault(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSwitchDefault(node, arg);
cache.set(node, res);
return res;
},
reduceSwitchStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSwitchStatement(node, arg);
cache.set(node, res);
return res;
},
reduceSwitchStatementWithDefault(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceSwitchStatementWithDefault(node, arg);
cache.set(node, res);
return res;
},
reduceTemplateElement(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceTemplateElement(node);
cache.set(node, res);
return res;
},
reduceTemplateExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceTemplateExpression(node, arg);
cache.set(node, res);
return res;
},
reduceThisExpression(node) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceThisExpression(node);
cache.set(node, res);
return res;
},
reduceThrowStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceThrowStatement(node, arg);
cache.set(node, res);
return res;
},
reduceTryCatchStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceTryCatchStatement(node, arg);
cache.set(node, res);
return res;
},
reduceTryFinallyStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceTryFinallyStatement(node, arg);
cache.set(node, res);
return res;
},
reduceUnaryExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceUnaryExpression(node, arg);
cache.set(node, res);
return res;
},
reduceUpdateExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceUpdateExpression(node, arg);
cache.set(node, res);
return res;
},
reduceVariableDeclaration(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceVariableDeclaration(node, arg);
cache.set(node, res);
return res;
},
reduceVariableDeclarationStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceVariableDeclarationStatement(node, arg);
cache.set(node, res);
return res;
},
reduceVariableDeclarator(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceVariableDeclarator(node, arg);
cache.set(node, res);
return res;
},
reduceWhileStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceWhileStatement(node, arg);
cache.set(node, res);
return res;
},
reduceWithStatement(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceWithStatement(node, arg);
cache.set(node, res);
return res;
},
reduceYieldExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceYieldExpression(node, arg);
cache.set(node, res);
return res;
},
reduceYieldGeneratorExpression(node, arg) {
if (cache.has(node)) {
return cache.get(node);
}
const res = reducer.reduceYieldGeneratorExpression(node, arg);
cache.set(node, res);
return res;
},
};
}

View File

@ -0,0 +1,430 @@
// Generated by generate-monoidal-reducer.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Shift from 'shift-ast';
export default class MonoidalReducer {
constructor(monoid) {
let identity = monoid.empty();
this.identity = identity;
let concat;
if (monoid.prototype && typeof monoid.prototype.concat === 'function') {
concat = Function.prototype.call.bind(monoid.prototype.concat);
} else if (typeof monoid.concat === 'function') {
concat = monoid.concat;
} else {
throw new TypeError('Monoid must provide a `concat` method');
}
this.append = (...args) => args.reduce(concat, identity);
}
reduceArrayAssignmentTarget(node, { elements, rest }) {
return this.append(...elements.filter(n => n != null), rest == null ? this.identity : rest);
}
reduceArrayBinding(node, { elements, rest }) {
return this.append(...elements.filter(n => n != null), rest == null ? this.identity : rest);
}
reduceArrayExpression(node, { elements }) {
return this.append(...elements.filter(n => n != null));
}
reduceArrowExpression(node, { params, body }) {
return this.append(params, body);
}
reduceAssignmentExpression(node, { binding, expression }) {
return this.append(binding, expression);
}
reduceAssignmentTargetIdentifier(node) {
return this.identity;
}
reduceAssignmentTargetPropertyIdentifier(node, { binding, init }) {
return this.append(binding, init == null ? this.identity : init);
}
reduceAssignmentTargetPropertyProperty(node, { name, binding }) {
return this.append(name, binding);
}
reduceAssignmentTargetWithDefault(node, { binding, init }) {
return this.append(binding, init);
}
reduceAwaitExpression(node, { expression }) {
return expression;
}
reduceBinaryExpression(node, { left, right }) {
return this.append(left, right);
}
reduceBindingIdentifier(node) {
return this.identity;
}
reduceBindingPropertyIdentifier(node, { binding, init }) {
return this.append(binding, init == null ? this.identity : init);
}
reduceBindingPropertyProperty(node, { name, binding }) {
return this.append(name, binding);
}
reduceBindingWithDefault(node, { binding, init }) {
return this.append(binding, init);
}
reduceBlock(node, { statements }) {
return this.append(...statements);
}
reduceBlockStatement(node, { block }) {
return block;
}
reduceBreakStatement(node) {
return this.identity;
}
reduceCallExpression(node, { callee, arguments: _arguments }) {
return this.append(callee, ..._arguments);
}
reduceCatchClause(node, { binding, body }) {
return this.append(binding, body);
}
reduceClassDeclaration(node, { name, super: _super, elements }) {
return this.append(name, _super == null ? this.identity : _super, ...elements);
}
reduceClassElement(node, { method }) {
return method;
}
reduceClassExpression(node, { name, super: _super, elements }) {
return this.append(name == null ? this.identity : name, _super == null ? this.identity : _super, ...elements);
}
reduceCompoundAssignmentExpression(node, { binding, expression }) {
return this.append(binding, expression);
}
reduceComputedMemberAssignmentTarget(node, { object, expression }) {
return this.append(object, expression);
}
reduceComputedMemberExpression(node, { object, expression }) {
return this.append(object, expression);
}
reduceComputedPropertyName(node, { expression }) {
return expression;
}
reduceConditionalExpression(node, { test, consequent, alternate }) {
return this.append(test, consequent, alternate);
}
reduceContinueStatement(node) {
return this.identity;
}
reduceDataProperty(node, { name, expression }) {
return this.append(name, expression);
}
reduceDebuggerStatement(node) {
return this.identity;
}
reduceDirective(node) {
return this.identity;
}
reduceDoWhileStatement(node, { body, test }) {
return this.append(body, test);
}
reduceEmptyStatement(node) {
return this.identity;
}
reduceExport(node, { declaration }) {
return declaration;
}
reduceExportAllFrom(node) {
return this.identity;
}
reduceExportDefault(node, { body }) {
return body;
}
reduceExportFrom(node, { namedExports }) {
return this.append(...namedExports);
}
reduceExportFromSpecifier(node) {
return this.identity;
}
reduceExportLocalSpecifier(node, { name }) {
return name;
}
reduceExportLocals(node, { namedExports }) {
return this.append(...namedExports);
}
reduceExpressionStatement(node, { expression }) {
return expression;
}
reduceForAwaitStatement(node, { left, right, body }) {
return this.append(left, right, body);
}
reduceForInStatement(node, { left, right, body }) {
return this.append(left, right, body);
}
reduceForOfStatement(node, { left, right, body }) {
return this.append(left, right, body);
}
reduceForStatement(node, { init, test, update, body }) {
return this.append(init == null ? this.identity : init, test == null ? this.identity : test, update == null ? this.identity : update, body);
}
reduceFormalParameters(node, { items, rest }) {
return this.append(...items, rest == null ? this.identity : rest);
}
reduceFunctionBody(node, { directives, statements }) {
return this.append(...directives, ...statements);
}
reduceFunctionDeclaration(node, { name, params, body }) {
return this.append(name, params, body);
}
reduceFunctionExpression(node, { name, params, body }) {
return this.append(name == null ? this.identity : name, params, body);
}
reduceGetter(node, { name, body }) {
return this.append(name, body);
}
reduceIdentifierExpression(node) {
return this.identity;
}
reduceIfStatement(node, { test, consequent, alternate }) {
return this.append(test, consequent, alternate == null ? this.identity : alternate);
}
reduceImport(node, { defaultBinding, namedImports }) {
return this.append(defaultBinding == null ? this.identity : defaultBinding, ...namedImports);
}
reduceImportNamespace(node, { defaultBinding, namespaceBinding }) {
return this.append(defaultBinding == null ? this.identity : defaultBinding, namespaceBinding);
}
reduceImportSpecifier(node, { binding }) {
return binding;
}
reduceLabeledStatement(node, { body }) {
return body;
}
reduceLiteralBooleanExpression(node) {
return this.identity;
}
reduceLiteralInfinityExpression(node) {
return this.identity;
}
reduceLiteralNullExpression(node) {
return this.identity;
}
reduceLiteralNumericExpression(node) {
return this.identity;
}
reduceLiteralRegExpExpression(node) {
return this.identity;
}
reduceLiteralStringExpression(node) {
return this.identity;
}
reduceMethod(node, { name, params, body }) {
return this.append(name, params, body);
}
reduceModule(node, { directives, items }) {
return this.append(...directives, ...items);
}
reduceNewExpression(node, { callee, arguments: _arguments }) {
return this.append(callee, ..._arguments);
}
reduceNewTargetExpression(node) {
return this.identity;
}
reduceObjectAssignmentTarget(node, { properties, rest }) {
return this.append(...properties, rest == null ? this.identity : rest);
}
reduceObjectBinding(node, { properties, rest }) {
return this.append(...properties, rest == null ? this.identity : rest);
}
reduceObjectExpression(node, { properties }) {
return this.append(...properties);
}
reduceReturnStatement(node, { expression }) {
return expression == null ? this.identity : expression;
}
reduceScript(node, { directives, statements }) {
return this.append(...directives, ...statements);
}
reduceSetter(node, { name, param, body }) {
return this.append(name, param, body);
}
reduceShorthandProperty(node, { name }) {
return name;
}
reduceSpreadElement(node, { expression }) {
return expression;
}
reduceSpreadProperty(node, { expression }) {
return expression;
}
reduceStaticMemberAssignmentTarget(node, { object }) {
return object;
}
reduceStaticMemberExpression(node, { object }) {
return object;
}
reduceStaticPropertyName(node) {
return this.identity;
}
reduceSuper(node) {
return this.identity;
}
reduceSwitchCase(node, { test, consequent }) {
return this.append(test, ...consequent);
}
reduceSwitchDefault(node, { consequent }) {
return this.append(...consequent);
}
reduceSwitchStatement(node, { discriminant, cases }) {
return this.append(discriminant, ...cases);
}
reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) {
return this.append(discriminant, ...preDefaultCases, defaultCase, ...postDefaultCases);
}
reduceTemplateElement(node) {
return this.identity;
}
reduceTemplateExpression(node, { tag, elements }) {
return this.append(tag == null ? this.identity : tag, ...elements);
}
reduceThisExpression(node) {
return this.identity;
}
reduceThrowStatement(node, { expression }) {
return expression;
}
reduceTryCatchStatement(node, { body, catchClause }) {
return this.append(body, catchClause);
}
reduceTryFinallyStatement(node, { body, catchClause, finalizer }) {
return this.append(body, catchClause == null ? this.identity : catchClause, finalizer);
}
reduceUnaryExpression(node, { operand }) {
return operand;
}
reduceUpdateExpression(node, { operand }) {
return operand;
}
reduceVariableDeclaration(node, { declarators }) {
return this.append(...declarators);
}
reduceVariableDeclarationStatement(node, { declaration }) {
return declaration;
}
reduceVariableDeclarator(node, { binding, init }) {
return this.append(binding, init == null ? this.identity : init);
}
reduceWhileStatement(node, { test, body }) {
return this.append(test, body);
}
reduceWithStatement(node, { object, body }) {
return this.append(object, body);
}
reduceYieldExpression(node, { expression }) {
return expression == null ? this.identity : expression;
}
reduceYieldGeneratorExpression(node, { expression }) {
return expression;
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
import MonoidalReducer from './monoidal-reducer.js';
import ThunkedMonoidalReducer from './thunked-monoidal-reducer.js';
const PlusMonoid = {
empty: () => 0,
concat: (a, b) => a + b,
};
const ConcatMonoid = {
empty: () => [],
concat: (a, b) => a.concat(b),
};
const AndMonoid = {
empty: () => true,
concat: (a, b) => a && b,
concatThunk: (a, b) => a && b(),
};
const OrMonoid = {
empty: () => false,
concat: (a, b) => a || b,
concatThunk: (a, b) => a || b(),
};
export class PlusReducer extends MonoidalReducer {
constructor() {
super(PlusMonoid);
}
}
export class ThunkedPlusReducer extends ThunkedMonoidalReducer {
constructor() {
super(PlusMonoid);
}
}
export class ConcatReducer extends MonoidalReducer {
constructor() {
super(ConcatMonoid);
}
}
export class ThunkedConcatReducer extends ThunkedMonoidalReducer {
constructor() {
super(ConcatMonoid);
}
}
export class AndReducer extends MonoidalReducer {
constructor() {
super(AndMonoid);
}
}
export class ThunkedAndReducer extends ThunkedMonoidalReducer {
constructor() {
super(AndMonoid);
}
}
export class OrReducer extends MonoidalReducer {
constructor() {
super(OrMonoid);
}
}
export class ThunkedOrReducer extends ThunkedMonoidalReducer {
constructor() {
super(OrMonoid);
}
}

View File

@ -0,0 +1,418 @@
// Generated by generate-director.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const director = {
ArrayAssignmentTarget(reducer, node) {
return reducer.reduceArrayAssignmentTarget(node, { elements: node.elements.map(v => v && (() => this[v.type](reducer, v))), rest: node.rest && (() => this[node.rest.type](reducer, node.rest)) });
},
ArrayBinding(reducer, node) {
return reducer.reduceArrayBinding(node, { elements: node.elements.map(v => v && (() => this[v.type](reducer, v))), rest: node.rest && (() => this[node.rest.type](reducer, node.rest)) });
},
ArrayExpression(reducer, node) {
return reducer.reduceArrayExpression(node, { elements: node.elements.map(v => v && (() => this[v.type](reducer, v))) });
},
ArrowExpression(reducer, node) {
return reducer.reduceArrowExpression(node, { params: (() => this.FormalParameters(reducer, node.params)), body: (() => this[node.body.type](reducer, node.body)) });
},
AssignmentExpression(reducer, node) {
return reducer.reduceAssignmentExpression(node, { binding: (() => this[node.binding.type](reducer, node.binding)), expression: (() => this[node.expression.type](reducer, node.expression)) });
},
AssignmentTargetIdentifier(reducer, node) {
return reducer.reduceAssignmentTargetIdentifier(node);
},
AssignmentTargetPropertyIdentifier(reducer, node) {
return reducer.reduceAssignmentTargetPropertyIdentifier(node, { binding: (() => this.AssignmentTargetIdentifier(reducer, node.binding)), init: node.init && (() => this[node.init.type](reducer, node.init)) });
},
AssignmentTargetPropertyProperty(reducer, node) {
return reducer.reduceAssignmentTargetPropertyProperty(node, { name: (() => this[node.name.type](reducer, node.name)), binding: (() => this[node.binding.type](reducer, node.binding)) });
},
AssignmentTargetWithDefault(reducer, node) {
return reducer.reduceAssignmentTargetWithDefault(node, { binding: (() => this[node.binding.type](reducer, node.binding)), init: (() => this[node.init.type](reducer, node.init)) });
},
AwaitExpression(reducer, node) {
return reducer.reduceAwaitExpression(node, { expression: (() => this[node.expression.type](reducer, node.expression)) });
},
BinaryExpression(reducer, node) {
return reducer.reduceBinaryExpression(node, { left: (() => this[node.left.type](reducer, node.left)), right: (() => this[node.right.type](reducer, node.right)) });
},
BindingIdentifier(reducer, node) {
return reducer.reduceBindingIdentifier(node);
},
BindingPropertyIdentifier(reducer, node) {
return reducer.reduceBindingPropertyIdentifier(node, { binding: (() => this.BindingIdentifier(reducer, node.binding)), init: node.init && (() => this[node.init.type](reducer, node.init)) });
},
BindingPropertyProperty(reducer, node) {
return reducer.reduceBindingPropertyProperty(node, { name: (() => this[node.name.type](reducer, node.name)), binding: (() => this[node.binding.type](reducer, node.binding)) });
},
BindingWithDefault(reducer, node) {
return reducer.reduceBindingWithDefault(node, { binding: (() => this[node.binding.type](reducer, node.binding)), init: (() => this[node.init.type](reducer, node.init)) });
},
Block(reducer, node) {
return reducer.reduceBlock(node, { statements: node.statements.map(v => (() => this[v.type](reducer, v))) });
},
BlockStatement(reducer, node) {
return reducer.reduceBlockStatement(node, { block: (() => this.Block(reducer, node.block)) });
},
BreakStatement(reducer, node) {
return reducer.reduceBreakStatement(node);
},
CallExpression(reducer, node) {
return reducer.reduceCallExpression(node, { callee: (() => this[node.callee.type](reducer, node.callee)), arguments: node.arguments.map(v => (() => this[v.type](reducer, v))) });
},
CatchClause(reducer, node) {
return reducer.reduceCatchClause(node, { binding: (() => this[node.binding.type](reducer, node.binding)), body: (() => this.Block(reducer, node.body)) });
},
ClassDeclaration(reducer, node) {
return reducer.reduceClassDeclaration(node, { name: (() => this.BindingIdentifier(reducer, node.name)), super: node.super && (() => this[node.super.type](reducer, node.super)), elements: node.elements.map(v => (() => this.ClassElement(reducer, v))) });
},
ClassElement(reducer, node) {
return reducer.reduceClassElement(node, { method: (() => this[node.method.type](reducer, node.method)) });
},
ClassExpression(reducer, node) {
return reducer.reduceClassExpression(node, { name: node.name && (() => this.BindingIdentifier(reducer, node.name)), super: node.super && (() => this[node.super.type](reducer, node.super)), elements: node.elements.map(v => (() => this.ClassElement(reducer, v))) });
},
CompoundAssignmentExpression(reducer, node) {
return reducer.reduceCompoundAssignmentExpression(node, { binding: (() => this[node.binding.type](reducer, node.binding)), expression: (() => this[node.expression.type](reducer, node.expression)) });
},
ComputedMemberAssignmentTarget(reducer, node) {
return reducer.reduceComputedMemberAssignmentTarget(node, { object: (() => this[node.object.type](reducer, node.object)), expression: (() => this[node.expression.type](reducer, node.expression)) });
},
ComputedMemberExpression(reducer, node) {
return reducer.reduceComputedMemberExpression(node, { object: (() => this[node.object.type](reducer, node.object)), expression: (() => this[node.expression.type](reducer, node.expression)) });
},
ComputedPropertyName(reducer, node) {
return reducer.reduceComputedPropertyName(node, { expression: (() => this[node.expression.type](reducer, node.expression)) });
},
ConditionalExpression(reducer, node) {
return reducer.reduceConditionalExpression(node, { test: (() => this[node.test.type](reducer, node.test)), consequent: (() => this[node.consequent.type](reducer, node.consequent)), alternate: (() => this[node.alternate.type](reducer, node.alternate)) });
},
ContinueStatement(reducer, node) {
return reducer.reduceContinueStatement(node);
},
DataProperty(reducer, node) {
return reducer.reduceDataProperty(node, { name: (() => this[node.name.type](reducer, node.name)), expression: (() => this[node.expression.type](reducer, node.expression)) });
},
DebuggerStatement(reducer, node) {
return reducer.reduceDebuggerStatement(node);
},
Directive(reducer, node) {
return reducer.reduceDirective(node);
},
DoWhileStatement(reducer, node) {
return reducer.reduceDoWhileStatement(node, { body: (() => this[node.body.type](reducer, node.body)), test: (() => this[node.test.type](reducer, node.test)) });
},
EmptyStatement(reducer, node) {
return reducer.reduceEmptyStatement(node);
},
Export(reducer, node) {
return reducer.reduceExport(node, { declaration: (() => this[node.declaration.type](reducer, node.declaration)) });
},
ExportAllFrom(reducer, node) {
return reducer.reduceExportAllFrom(node);
},
ExportDefault(reducer, node) {
return reducer.reduceExportDefault(node, { body: (() => this[node.body.type](reducer, node.body)) });
},
ExportFrom(reducer, node) {
return reducer.reduceExportFrom(node, { namedExports: node.namedExports.map(v => (() => this.ExportFromSpecifier(reducer, v))) });
},
ExportFromSpecifier(reducer, node) {
return reducer.reduceExportFromSpecifier(node);
},
ExportLocalSpecifier(reducer, node) {
return reducer.reduceExportLocalSpecifier(node, { name: (() => this.IdentifierExpression(reducer, node.name)) });
},
ExportLocals(reducer, node) {
return reducer.reduceExportLocals(node, { namedExports: node.namedExports.map(v => (() => this.ExportLocalSpecifier(reducer, v))) });
},
ExpressionStatement(reducer, node) {
return reducer.reduceExpressionStatement(node, { expression: (() => this[node.expression.type](reducer, node.expression)) });
},
ForAwaitStatement(reducer, node) {
return reducer.reduceForAwaitStatement(node, { left: (() => this[node.left.type](reducer, node.left)), right: (() => this[node.right.type](reducer, node.right)), body: (() => this[node.body.type](reducer, node.body)) });
},
ForInStatement(reducer, node) {
return reducer.reduceForInStatement(node, { left: (() => this[node.left.type](reducer, node.left)), right: (() => this[node.right.type](reducer, node.right)), body: (() => this[node.body.type](reducer, node.body)) });
},
ForOfStatement(reducer, node) {
return reducer.reduceForOfStatement(node, { left: (() => this[node.left.type](reducer, node.left)), right: (() => this[node.right.type](reducer, node.right)), body: (() => this[node.body.type](reducer, node.body)) });
},
ForStatement(reducer, node) {
return reducer.reduceForStatement(node, { init: node.init && (() => this[node.init.type](reducer, node.init)), test: node.test && (() => this[node.test.type](reducer, node.test)), update: node.update && (() => this[node.update.type](reducer, node.update)), body: (() => this[node.body.type](reducer, node.body)) });
},
FormalParameters(reducer, node) {
return reducer.reduceFormalParameters(node, { items: node.items.map(v => (() => this[v.type](reducer, v))), rest: node.rest && (() => this[node.rest.type](reducer, node.rest)) });
},
FunctionBody(reducer, node) {
return reducer.reduceFunctionBody(node, { directives: node.directives.map(v => (() => this.Directive(reducer, v))), statements: node.statements.map(v => (() => this[v.type](reducer, v))) });
},
FunctionDeclaration(reducer, node) {
return reducer.reduceFunctionDeclaration(node, { name: (() => this.BindingIdentifier(reducer, node.name)), params: (() => this.FormalParameters(reducer, node.params)), body: (() => this.FunctionBody(reducer, node.body)) });
},
FunctionExpression(reducer, node) {
return reducer.reduceFunctionExpression(node, { name: node.name && (() => this.BindingIdentifier(reducer, node.name)), params: (() => this.FormalParameters(reducer, node.params)), body: (() => this.FunctionBody(reducer, node.body)) });
},
Getter(reducer, node) {
return reducer.reduceGetter(node, { name: (() => this[node.name.type](reducer, node.name)), body: (() => this.FunctionBody(reducer, node.body)) });
},
IdentifierExpression(reducer, node) {
return reducer.reduceIdentifierExpression(node);
},
IfStatement(reducer, node) {
return reducer.reduceIfStatement(node, { test: (() => this[node.test.type](reducer, node.test)), consequent: (() => this[node.consequent.type](reducer, node.consequent)), alternate: node.alternate && (() => this[node.alternate.type](reducer, node.alternate)) });
},
Import(reducer, node) {
return reducer.reduceImport(node, { defaultBinding: node.defaultBinding && (() => this.BindingIdentifier(reducer, node.defaultBinding)), namedImports: node.namedImports.map(v => (() => this.ImportSpecifier(reducer, v))) });
},
ImportNamespace(reducer, node) {
return reducer.reduceImportNamespace(node, { defaultBinding: node.defaultBinding && (() => this.BindingIdentifier(reducer, node.defaultBinding)), namespaceBinding: (() => this.BindingIdentifier(reducer, node.namespaceBinding)) });
},
ImportSpecifier(reducer, node) {
return reducer.reduceImportSpecifier(node, { binding: (() => this.BindingIdentifier(reducer, node.binding)) });
},
LabeledStatement(reducer, node) {
return reducer.reduceLabeledStatement(node, { body: (() => this[node.body.type](reducer, node.body)) });
},
LiteralBooleanExpression(reducer, node) {
return reducer.reduceLiteralBooleanExpression(node);
},
LiteralInfinityExpression(reducer, node) {
return reducer.reduceLiteralInfinityExpression(node);
},
LiteralNullExpression(reducer, node) {
return reducer.reduceLiteralNullExpression(node);
},
LiteralNumericExpression(reducer, node) {
return reducer.reduceLiteralNumericExpression(node);
},
LiteralRegExpExpression(reducer, node) {
return reducer.reduceLiteralRegExpExpression(node);
},
LiteralStringExpression(reducer, node) {
return reducer.reduceLiteralStringExpression(node);
},
Method(reducer, node) {
return reducer.reduceMethod(node, { name: (() => this[node.name.type](reducer, node.name)), params: (() => this.FormalParameters(reducer, node.params)), body: (() => this.FunctionBody(reducer, node.body)) });
},
Module(reducer, node) {
return reducer.reduceModule(node, { directives: node.directives.map(v => (() => this.Directive(reducer, v))), items: node.items.map(v => (() => this[v.type](reducer, v))) });
},
NewExpression(reducer, node) {
return reducer.reduceNewExpression(node, { callee: (() => this[node.callee.type](reducer, node.callee)), arguments: node.arguments.map(v => (() => this[v.type](reducer, v))) });
},
NewTargetExpression(reducer, node) {
return reducer.reduceNewTargetExpression(node);
},
ObjectAssignmentTarget(reducer, node) {
return reducer.reduceObjectAssignmentTarget(node, { properties: node.properties.map(v => (() => this[v.type](reducer, v))), rest: node.rest && (() => this[node.rest.type](reducer, node.rest)) });
},
ObjectBinding(reducer, node) {
return reducer.reduceObjectBinding(node, { properties: node.properties.map(v => (() => this[v.type](reducer, v))), rest: node.rest && (() => this[node.rest.type](reducer, node.rest)) });
},
ObjectExpression(reducer, node) {
return reducer.reduceObjectExpression(node, { properties: node.properties.map(v => (() => this[v.type](reducer, v))) });
},
ReturnStatement(reducer, node) {
return reducer.reduceReturnStatement(node, { expression: node.expression && (() => this[node.expression.type](reducer, node.expression)) });
},
Script(reducer, node) {
return reducer.reduceScript(node, { directives: node.directives.map(v => (() => this.Directive(reducer, v))), statements: node.statements.map(v => (() => this[v.type](reducer, v))) });
},
Setter(reducer, node) {
return reducer.reduceSetter(node, { name: (() => this[node.name.type](reducer, node.name)), param: (() => this[node.param.type](reducer, node.param)), body: (() => this.FunctionBody(reducer, node.body)) });
},
ShorthandProperty(reducer, node) {
return reducer.reduceShorthandProperty(node, { name: (() => this.IdentifierExpression(reducer, node.name)) });
},
SpreadElement(reducer, node) {
return reducer.reduceSpreadElement(node, { expression: (() => this[node.expression.type](reducer, node.expression)) });
},
SpreadProperty(reducer, node) {
return reducer.reduceSpreadProperty(node, { expression: (() => this[node.expression.type](reducer, node.expression)) });
},
StaticMemberAssignmentTarget(reducer, node) {
return reducer.reduceStaticMemberAssignmentTarget(node, { object: (() => this[node.object.type](reducer, node.object)) });
},
StaticMemberExpression(reducer, node) {
return reducer.reduceStaticMemberExpression(node, { object: (() => this[node.object.type](reducer, node.object)) });
},
StaticPropertyName(reducer, node) {
return reducer.reduceStaticPropertyName(node);
},
Super(reducer, node) {
return reducer.reduceSuper(node);
},
SwitchCase(reducer, node) {
return reducer.reduceSwitchCase(node, { test: (() => this[node.test.type](reducer, node.test)), consequent: node.consequent.map(v => (() => this[v.type](reducer, v))) });
},
SwitchDefault(reducer, node) {
return reducer.reduceSwitchDefault(node, { consequent: node.consequent.map(v => (() => this[v.type](reducer, v))) });
},
SwitchStatement(reducer, node) {
return reducer.reduceSwitchStatement(node, { discriminant: (() => this[node.discriminant.type](reducer, node.discriminant)), cases: node.cases.map(v => (() => this.SwitchCase(reducer, v))) });
},
SwitchStatementWithDefault(reducer, node) {
return reducer.reduceSwitchStatementWithDefault(node, { discriminant: (() => this[node.discriminant.type](reducer, node.discriminant)), preDefaultCases: node.preDefaultCases.map(v => (() => this.SwitchCase(reducer, v))), defaultCase: (() => this.SwitchDefault(reducer, node.defaultCase)), postDefaultCases: node.postDefaultCases.map(v => (() => this.SwitchCase(reducer, v))) });
},
TemplateElement(reducer, node) {
return reducer.reduceTemplateElement(node);
},
TemplateExpression(reducer, node) {
return reducer.reduceTemplateExpression(node, { tag: node.tag && (() => this[node.tag.type](reducer, node.tag)), elements: node.elements.map(v => (() => this[v.type](reducer, v))) });
},
ThisExpression(reducer, node) {
return reducer.reduceThisExpression(node);
},
ThrowStatement(reducer, node) {
return reducer.reduceThrowStatement(node, { expression: (() => this[node.expression.type](reducer, node.expression)) });
},
TryCatchStatement(reducer, node) {
return reducer.reduceTryCatchStatement(node, { body: (() => this.Block(reducer, node.body)), catchClause: (() => this.CatchClause(reducer, node.catchClause)) });
},
TryFinallyStatement(reducer, node) {
return reducer.reduceTryFinallyStatement(node, { body: (() => this.Block(reducer, node.body)), catchClause: node.catchClause && (() => this.CatchClause(reducer, node.catchClause)), finalizer: (() => this.Block(reducer, node.finalizer)) });
},
UnaryExpression(reducer, node) {
return reducer.reduceUnaryExpression(node, { operand: (() => this[node.operand.type](reducer, node.operand)) });
},
UpdateExpression(reducer, node) {
return reducer.reduceUpdateExpression(node, { operand: (() => this[node.operand.type](reducer, node.operand)) });
},
VariableDeclaration(reducer, node) {
return reducer.reduceVariableDeclaration(node, { declarators: node.declarators.map(v => (() => this.VariableDeclarator(reducer, v))) });
},
VariableDeclarationStatement(reducer, node) {
return reducer.reduceVariableDeclarationStatement(node, { declaration: (() => this.VariableDeclaration(reducer, node.declaration)) });
},
VariableDeclarator(reducer, node) {
return reducer.reduceVariableDeclarator(node, { binding: (() => this[node.binding.type](reducer, node.binding)), init: node.init && (() => this[node.init.type](reducer, node.init)) });
},
WhileStatement(reducer, node) {
return reducer.reduceWhileStatement(node, { test: (() => this[node.test.type](reducer, node.test)), body: (() => this[node.body.type](reducer, node.body)) });
},
WithStatement(reducer, node) {
return reducer.reduceWithStatement(node, { object: (() => this[node.object.type](reducer, node.object)), body: (() => this[node.body.type](reducer, node.body)) });
},
YieldExpression(reducer, node) {
return reducer.reduceYieldExpression(node, { expression: node.expression && (() => this[node.expression.type](reducer, node.expression)) });
},
YieldGeneratorExpression(reducer, node) {
return reducer.reduceYieldGeneratorExpression(node, { expression: (() => this[node.expression.type](reducer, node.expression)) });
},
};
export function thunkedReduce(reducer, node) {
return director[node.type](reducer, node);
}

View File

@ -0,0 +1,444 @@
// Generated by generate-monoidal-reducer.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Shift from 'shift-ast';
export default class MonoidalReducer {
constructor(monoid) {
let identity = monoid.empty();
this.identity = identity;
let concatThunk;
if (monoid.prototype && typeof monoid.prototype.concatThunk === 'function') {
concatThunk = Function.prototype.call.bind(monoid.prototype.concatThunk);
} else if (typeof monoid.concatThunk === 'function') {
concatThunk = monoid.concatThunk;
} else {
let concat;
if (monoid.prototype && typeof monoid.prototype.concat === 'function') {
concat = Function.prototype.call.bind(monoid.prototype.concat);
} else if (typeof monoid.concat === 'function') {
concat = monoid.concat;
} else {
throw new TypeError('Monoid must provide a `concatThunk` or `concat` method');
}
if (typeof monoid.isAbsorbing === 'function') {
let isAbsorbing = monoid.isAbsorbing;
concatThunk = (a, b) => isAbsorbing(a) ? a : concat(a, b());
} else {
concatThunk = (a, b) => concat(a, b());
}
}
this.append = (...args) => args.reduce(concatThunk, identity);
}
reduceArrayAssignmentTarget(node, { elements, rest }) {
return this.append(...elements.filter(n => n != null), rest == null ? () => this.identity : rest);
}
reduceArrayBinding(node, { elements, rest }) {
return this.append(...elements.filter(n => n != null), rest == null ? () => this.identity : rest);
}
reduceArrayExpression(node, { elements }) {
return this.append(...elements.filter(n => n != null));
}
reduceArrowExpression(node, { params, body }) {
return this.append(params, body);
}
reduceAssignmentExpression(node, { binding, expression }) {
return this.append(binding, expression);
}
reduceAssignmentTargetIdentifier(node) {
return this.identity;
}
reduceAssignmentTargetPropertyIdentifier(node, { binding, init }) {
return this.append(binding, init == null ? () => this.identity : init);
}
reduceAssignmentTargetPropertyProperty(node, { name, binding }) {
return this.append(name, binding);
}
reduceAssignmentTargetWithDefault(node, { binding, init }) {
return this.append(binding, init);
}
reduceAwaitExpression(node, { expression }) {
return expression();
}
reduceBinaryExpression(node, { left, right }) {
return this.append(left, right);
}
reduceBindingIdentifier(node) {
return this.identity;
}
reduceBindingPropertyIdentifier(node, { binding, init }) {
return this.append(binding, init == null ? () => this.identity : init);
}
reduceBindingPropertyProperty(node, { name, binding }) {
return this.append(name, binding);
}
reduceBindingWithDefault(node, { binding, init }) {
return this.append(binding, init);
}
reduceBlock(node, { statements }) {
return this.append(...statements);
}
reduceBlockStatement(node, { block }) {
return block();
}
reduceBreakStatement(node) {
return this.identity;
}
reduceCallExpression(node, { callee, arguments: _arguments }) {
return this.append(callee, ..._arguments);
}
reduceCatchClause(node, { binding, body }) {
return this.append(binding, body);
}
reduceClassDeclaration(node, { name, super: _super, elements }) {
return this.append(name, _super == null ? () => this.identity : _super, ...elements);
}
reduceClassElement(node, { method }) {
return method();
}
reduceClassExpression(node, { name, super: _super, elements }) {
return this.append(name == null ? () => this.identity : name, _super == null ? () => this.identity : _super, ...elements);
}
reduceCompoundAssignmentExpression(node, { binding, expression }) {
return this.append(binding, expression);
}
reduceComputedMemberAssignmentTarget(node, { object, expression }) {
return this.append(object, expression);
}
reduceComputedMemberExpression(node, { object, expression }) {
return this.append(object, expression);
}
reduceComputedPropertyName(node, { expression }) {
return expression();
}
reduceConditionalExpression(node, { test, consequent, alternate }) {
return this.append(test, consequent, alternate);
}
reduceContinueStatement(node) {
return this.identity;
}
reduceDataProperty(node, { name, expression }) {
return this.append(name, expression);
}
reduceDebuggerStatement(node) {
return this.identity;
}
reduceDirective(node) {
return this.identity;
}
reduceDoWhileStatement(node, { body, test }) {
return this.append(body, test);
}
reduceEmptyStatement(node) {
return this.identity;
}
reduceExport(node, { declaration }) {
return declaration();
}
reduceExportAllFrom(node) {
return this.identity;
}
reduceExportDefault(node, { body }) {
return body();
}
reduceExportFrom(node, { namedExports }) {
return this.append(...namedExports);
}
reduceExportFromSpecifier(node) {
return this.identity;
}
reduceExportLocalSpecifier(node, { name }) {
return name();
}
reduceExportLocals(node, { namedExports }) {
return this.append(...namedExports);
}
reduceExpressionStatement(node, { expression }) {
return expression();
}
reduceForAwaitStatement(node, { left, right, body }) {
return this.append(left, right, body);
}
reduceForInStatement(node, { left, right, body }) {
return this.append(left, right, body);
}
reduceForOfStatement(node, { left, right, body }) {
return this.append(left, right, body);
}
reduceForStatement(node, { init, test, update, body }) {
return this.append(init == null ? () => this.identity : init, test == null ? () => this.identity : test, update == null ? () => this.identity : update, body);
}
reduceFormalParameters(node, { items, rest }) {
return this.append(...items, rest == null ? () => this.identity : rest);
}
reduceFunctionBody(node, { directives, statements }) {
return this.append(...directives, ...statements);
}
reduceFunctionDeclaration(node, { name, params, body }) {
return this.append(name, params, body);
}
reduceFunctionExpression(node, { name, params, body }) {
return this.append(name == null ? () => this.identity : name, params, body);
}
reduceGetter(node, { name, body }) {
return this.append(name, body);
}
reduceIdentifierExpression(node) {
return this.identity;
}
reduceIfStatement(node, { test, consequent, alternate }) {
return this.append(test, consequent, alternate == null ? () => this.identity : alternate);
}
reduceImport(node, { defaultBinding, namedImports }) {
return this.append(defaultBinding == null ? () => this.identity : defaultBinding, ...namedImports);
}
reduceImportNamespace(node, { defaultBinding, namespaceBinding }) {
return this.append(defaultBinding == null ? () => this.identity : defaultBinding, namespaceBinding);
}
reduceImportSpecifier(node, { binding }) {
return binding();
}
reduceLabeledStatement(node, { body }) {
return body();
}
reduceLiteralBooleanExpression(node) {
return this.identity;
}
reduceLiteralInfinityExpression(node) {
return this.identity;
}
reduceLiteralNullExpression(node) {
return this.identity;
}
reduceLiteralNumericExpression(node) {
return this.identity;
}
reduceLiteralRegExpExpression(node) {
return this.identity;
}
reduceLiteralStringExpression(node) {
return this.identity;
}
reduceMethod(node, { name, params, body }) {
return this.append(name, params, body);
}
reduceModule(node, { directives, items }) {
return this.append(...directives, ...items);
}
reduceNewExpression(node, { callee, arguments: _arguments }) {
return this.append(callee, ..._arguments);
}
reduceNewTargetExpression(node) {
return this.identity;
}
reduceObjectAssignmentTarget(node, { properties, rest }) {
return this.append(...properties, rest == null ? () => this.identity : rest);
}
reduceObjectBinding(node, { properties, rest }) {
return this.append(...properties, rest == null ? () => this.identity : rest);
}
reduceObjectExpression(node, { properties }) {
return this.append(...properties);
}
reduceReturnStatement(node, { expression }) {
return expression == null ? this.identity : expression();
}
reduceScript(node, { directives, statements }) {
return this.append(...directives, ...statements);
}
reduceSetter(node, { name, param, body }) {
return this.append(name, param, body);
}
reduceShorthandProperty(node, { name }) {
return name();
}
reduceSpreadElement(node, { expression }) {
return expression();
}
reduceSpreadProperty(node, { expression }) {
return expression();
}
reduceStaticMemberAssignmentTarget(node, { object }) {
return object();
}
reduceStaticMemberExpression(node, { object }) {
return object();
}
reduceStaticPropertyName(node) {
return this.identity;
}
reduceSuper(node) {
return this.identity;
}
reduceSwitchCase(node, { test, consequent }) {
return this.append(test, ...consequent);
}
reduceSwitchDefault(node, { consequent }) {
return this.append(...consequent);
}
reduceSwitchStatement(node, { discriminant, cases }) {
return this.append(discriminant, ...cases);
}
reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) {
return this.append(discriminant, ...preDefaultCases, defaultCase, ...postDefaultCases);
}
reduceTemplateElement(node) {
return this.identity;
}
reduceTemplateExpression(node, { tag, elements }) {
return this.append(tag == null ? () => this.identity : tag, ...elements);
}
reduceThisExpression(node) {
return this.identity;
}
reduceThrowStatement(node, { expression }) {
return expression();
}
reduceTryCatchStatement(node, { body, catchClause }) {
return this.append(body, catchClause);
}
reduceTryFinallyStatement(node, { body, catchClause, finalizer }) {
return this.append(body, catchClause == null ? () => this.identity : catchClause, finalizer);
}
reduceUnaryExpression(node, { operand }) {
return operand();
}
reduceUpdateExpression(node, { operand }) {
return operand();
}
reduceVariableDeclaration(node, { declarators }) {
return this.append(...declarators);
}
reduceVariableDeclarationStatement(node, { declaration }) {
return declaration();
}
reduceVariableDeclarator(node, { binding, init }) {
return this.append(binding, init == null ? () => this.identity : init);
}
reduceWhileStatement(node, { test, body }) {
return this.append(test, body);
}
reduceWithStatement(node, { object, body }) {
return this.append(object, body);
}
reduceYieldExpression(node, { expression }) {
return expression == null ? this.identity : expression();
}
reduceYieldGeneratorExpression(node, { expression }) {
return expression();
}
}

View File

@ -0,0 +1,416 @@
// Generated by generate-thunkify.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default function thunkifyClass(reducerClass) {
return class extends reducerClass {
reduceArrayAssignmentTarget(node, { elements, rest }) {
return super.reduceArrayAssignmentTarget(node, { elements: elements.map(n => n == null ? null : n()), rest: rest == null ? null : rest() });
}
reduceArrayBinding(node, { elements, rest }) {
return super.reduceArrayBinding(node, { elements: elements.map(n => n == null ? null : n()), rest: rest == null ? null : rest() });
}
reduceArrayExpression(node, { elements }) {
return super.reduceArrayExpression(node, { elements: elements.map(n => n == null ? null : n()) });
}
reduceArrowExpression(node, { params, body }) {
return super.reduceArrowExpression(node, { params: params(), body: body() });
}
reduceAssignmentExpression(node, { binding, expression }) {
return super.reduceAssignmentExpression(node, { binding: binding(), expression: expression() });
}
reduceAssignmentTargetIdentifier(node) {
return super.reduceAssignmentTargetIdentifier(node);
}
reduceAssignmentTargetPropertyIdentifier(node, { binding, init }) {
return super.reduceAssignmentTargetPropertyIdentifier(node, { binding: binding(), init: init == null ? null : init() });
}
reduceAssignmentTargetPropertyProperty(node, { name, binding }) {
return super.reduceAssignmentTargetPropertyProperty(node, { name: name(), binding: binding() });
}
reduceAssignmentTargetWithDefault(node, { binding, init }) {
return super.reduceAssignmentTargetWithDefault(node, { binding: binding(), init: init() });
}
reduceAwaitExpression(node, { expression }) {
return super.reduceAwaitExpression(node, { expression: expression() });
}
reduceBinaryExpression(node, { left, right }) {
return super.reduceBinaryExpression(node, { left: left(), right: right() });
}
reduceBindingIdentifier(node) {
return super.reduceBindingIdentifier(node);
}
reduceBindingPropertyIdentifier(node, { binding, init }) {
return super.reduceBindingPropertyIdentifier(node, { binding: binding(), init: init == null ? null : init() });
}
reduceBindingPropertyProperty(node, { name, binding }) {
return super.reduceBindingPropertyProperty(node, { name: name(), binding: binding() });
}
reduceBindingWithDefault(node, { binding, init }) {
return super.reduceBindingWithDefault(node, { binding: binding(), init: init() });
}
reduceBlock(node, { statements }) {
return super.reduceBlock(node, { statements: statements.map(n => n()) });
}
reduceBlockStatement(node, { block }) {
return super.reduceBlockStatement(node, { block: block() });
}
reduceBreakStatement(node) {
return super.reduceBreakStatement(node);
}
reduceCallExpression(node, { callee, arguments: _arguments }) {
return super.reduceCallExpression(node, { callee: callee(), arguments: _arguments.map(n => n()) });
}
reduceCatchClause(node, { binding, body }) {
return super.reduceCatchClause(node, { binding: binding(), body: body() });
}
reduceClassDeclaration(node, { name, super: _super, elements }) {
return super.reduceClassDeclaration(node, { name: name(), super: _super == null ? null : _super(), elements: elements.map(n => n()) });
}
reduceClassElement(node, { method }) {
return super.reduceClassElement(node, { method: method() });
}
reduceClassExpression(node, { name, super: _super, elements }) {
return super.reduceClassExpression(node, { name: name == null ? null : name(), super: _super == null ? null : _super(), elements: elements.map(n => n()) });
}
reduceCompoundAssignmentExpression(node, { binding, expression }) {
return super.reduceCompoundAssignmentExpression(node, { binding: binding(), expression: expression() });
}
reduceComputedMemberAssignmentTarget(node, { object, expression }) {
return super.reduceComputedMemberAssignmentTarget(node, { object: object(), expression: expression() });
}
reduceComputedMemberExpression(node, { object, expression }) {
return super.reduceComputedMemberExpression(node, { object: object(), expression: expression() });
}
reduceComputedPropertyName(node, { expression }) {
return super.reduceComputedPropertyName(node, { expression: expression() });
}
reduceConditionalExpression(node, { test, consequent, alternate }) {
return super.reduceConditionalExpression(node, { test: test(), consequent: consequent(), alternate: alternate() });
}
reduceContinueStatement(node) {
return super.reduceContinueStatement(node);
}
reduceDataProperty(node, { name, expression }) {
return super.reduceDataProperty(node, { name: name(), expression: expression() });
}
reduceDebuggerStatement(node) {
return super.reduceDebuggerStatement(node);
}
reduceDirective(node) {
return super.reduceDirective(node);
}
reduceDoWhileStatement(node, { body, test }) {
return super.reduceDoWhileStatement(node, { body: body(), test: test() });
}
reduceEmptyStatement(node) {
return super.reduceEmptyStatement(node);
}
reduceExport(node, { declaration }) {
return super.reduceExport(node, { declaration: declaration() });
}
reduceExportAllFrom(node) {
return super.reduceExportAllFrom(node);
}
reduceExportDefault(node, { body }) {
return super.reduceExportDefault(node, { body: body() });
}
reduceExportFrom(node, { namedExports }) {
return super.reduceExportFrom(node, { namedExports: namedExports.map(n => n()) });
}
reduceExportFromSpecifier(node) {
return super.reduceExportFromSpecifier(node);
}
reduceExportLocalSpecifier(node, { name }) {
return super.reduceExportLocalSpecifier(node, { name: name() });
}
reduceExportLocals(node, { namedExports }) {
return super.reduceExportLocals(node, { namedExports: namedExports.map(n => n()) });
}
reduceExpressionStatement(node, { expression }) {
return super.reduceExpressionStatement(node, { expression: expression() });
}
reduceForAwaitStatement(node, { left, right, body }) {
return super.reduceForAwaitStatement(node, { left: left(), right: right(), body: body() });
}
reduceForInStatement(node, { left, right, body }) {
return super.reduceForInStatement(node, { left: left(), right: right(), body: body() });
}
reduceForOfStatement(node, { left, right, body }) {
return super.reduceForOfStatement(node, { left: left(), right: right(), body: body() });
}
reduceForStatement(node, { init, test, update, body }) {
return super.reduceForStatement(node, { init: init == null ? null : init(), test: test == null ? null : test(), update: update == null ? null : update(), body: body() });
}
reduceFormalParameters(node, { items, rest }) {
return super.reduceFormalParameters(node, { items: items.map(n => n()), rest: rest == null ? null : rest() });
}
reduceFunctionBody(node, { directives, statements }) {
return super.reduceFunctionBody(node, { directives: directives.map(n => n()), statements: statements.map(n => n()) });
}
reduceFunctionDeclaration(node, { name, params, body }) {
return super.reduceFunctionDeclaration(node, { name: name(), params: params(), body: body() });
}
reduceFunctionExpression(node, { name, params, body }) {
return super.reduceFunctionExpression(node, { name: name == null ? null : name(), params: params(), body: body() });
}
reduceGetter(node, { name, body }) {
return super.reduceGetter(node, { name: name(), body: body() });
}
reduceIdentifierExpression(node) {
return super.reduceIdentifierExpression(node);
}
reduceIfStatement(node, { test, consequent, alternate }) {
return super.reduceIfStatement(node, { test: test(), consequent: consequent(), alternate: alternate == null ? null : alternate() });
}
reduceImport(node, { defaultBinding, namedImports }) {
return super.reduceImport(node, { defaultBinding: defaultBinding == null ? null : defaultBinding(), namedImports: namedImports.map(n => n()) });
}
reduceImportNamespace(node, { defaultBinding, namespaceBinding }) {
return super.reduceImportNamespace(node, { defaultBinding: defaultBinding == null ? null : defaultBinding(), namespaceBinding: namespaceBinding() });
}
reduceImportSpecifier(node, { binding }) {
return super.reduceImportSpecifier(node, { binding: binding() });
}
reduceLabeledStatement(node, { body }) {
return super.reduceLabeledStatement(node, { body: body() });
}
reduceLiteralBooleanExpression(node) {
return super.reduceLiteralBooleanExpression(node);
}
reduceLiteralInfinityExpression(node) {
return super.reduceLiteralInfinityExpression(node);
}
reduceLiteralNullExpression(node) {
return super.reduceLiteralNullExpression(node);
}
reduceLiteralNumericExpression(node) {
return super.reduceLiteralNumericExpression(node);
}
reduceLiteralRegExpExpression(node) {
return super.reduceLiteralRegExpExpression(node);
}
reduceLiteralStringExpression(node) {
return super.reduceLiteralStringExpression(node);
}
reduceMethod(node, { name, params, body }) {
return super.reduceMethod(node, { name: name(), params: params(), body: body() });
}
reduceModule(node, { directives, items }) {
return super.reduceModule(node, { directives: directives.map(n => n()), items: items.map(n => n()) });
}
reduceNewExpression(node, { callee, arguments: _arguments }) {
return super.reduceNewExpression(node, { callee: callee(), arguments: _arguments.map(n => n()) });
}
reduceNewTargetExpression(node) {
return super.reduceNewTargetExpression(node);
}
reduceObjectAssignmentTarget(node, { properties, rest }) {
return super.reduceObjectAssignmentTarget(node, { properties: properties.map(n => n()), rest: rest == null ? null : rest() });
}
reduceObjectBinding(node, { properties, rest }) {
return super.reduceObjectBinding(node, { properties: properties.map(n => n()), rest: rest == null ? null : rest() });
}
reduceObjectExpression(node, { properties }) {
return super.reduceObjectExpression(node, { properties: properties.map(n => n()) });
}
reduceReturnStatement(node, { expression }) {
return super.reduceReturnStatement(node, { expression: expression == null ? null : expression() });
}
reduceScript(node, { directives, statements }) {
return super.reduceScript(node, { directives: directives.map(n => n()), statements: statements.map(n => n()) });
}
reduceSetter(node, { name, param, body }) {
return super.reduceSetter(node, { name: name(), param: param(), body: body() });
}
reduceShorthandProperty(node, { name }) {
return super.reduceShorthandProperty(node, { name: name() });
}
reduceSpreadElement(node, { expression }) {
return super.reduceSpreadElement(node, { expression: expression() });
}
reduceSpreadProperty(node, { expression }) {
return super.reduceSpreadProperty(node, { expression: expression() });
}
reduceStaticMemberAssignmentTarget(node, { object }) {
return super.reduceStaticMemberAssignmentTarget(node, { object: object() });
}
reduceStaticMemberExpression(node, { object }) {
return super.reduceStaticMemberExpression(node, { object: object() });
}
reduceStaticPropertyName(node) {
return super.reduceStaticPropertyName(node);
}
reduceSuper(node) {
return super.reduceSuper(node);
}
reduceSwitchCase(node, { test, consequent }) {
return super.reduceSwitchCase(node, { test: test(), consequent: consequent.map(n => n()) });
}
reduceSwitchDefault(node, { consequent }) {
return super.reduceSwitchDefault(node, { consequent: consequent.map(n => n()) });
}
reduceSwitchStatement(node, { discriminant, cases }) {
return super.reduceSwitchStatement(node, { discriminant: discriminant(), cases: cases.map(n => n()) });
}
reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) {
return super.reduceSwitchStatementWithDefault(node, { discriminant: discriminant(), preDefaultCases: preDefaultCases.map(n => n()), defaultCase: defaultCase(), postDefaultCases: postDefaultCases.map(n => n()) });
}
reduceTemplateElement(node) {
return super.reduceTemplateElement(node);
}
reduceTemplateExpression(node, { tag, elements }) {
return super.reduceTemplateExpression(node, { tag: tag == null ? null : tag(), elements: elements.map(n => n()) });
}
reduceThisExpression(node) {
return super.reduceThisExpression(node);
}
reduceThrowStatement(node, { expression }) {
return super.reduceThrowStatement(node, { expression: expression() });
}
reduceTryCatchStatement(node, { body, catchClause }) {
return super.reduceTryCatchStatement(node, { body: body(), catchClause: catchClause() });
}
reduceTryFinallyStatement(node, { body, catchClause, finalizer }) {
return super.reduceTryFinallyStatement(node, { body: body(), catchClause: catchClause == null ? null : catchClause(), finalizer: finalizer() });
}
reduceUnaryExpression(node, { operand }) {
return super.reduceUnaryExpression(node, { operand: operand() });
}
reduceUpdateExpression(node, { operand }) {
return super.reduceUpdateExpression(node, { operand: operand() });
}
reduceVariableDeclaration(node, { declarators }) {
return super.reduceVariableDeclaration(node, { declarators: declarators.map(n => n()) });
}
reduceVariableDeclarationStatement(node, { declaration }) {
return super.reduceVariableDeclarationStatement(node, { declaration: declaration() });
}
reduceVariableDeclarator(node, { binding, init }) {
return super.reduceVariableDeclarator(node, { binding: binding(), init: init == null ? null : init() });
}
reduceWhileStatement(node, { test, body }) {
return super.reduceWhileStatement(node, { test: test(), body: body() });
}
reduceWithStatement(node, { object, body }) {
return super.reduceWithStatement(node, { object: object(), body: body() });
}
reduceYieldExpression(node, { expression }) {
return super.reduceYieldExpression(node, { expression: expression == null ? null : expression() });
}
reduceYieldGeneratorExpression(node, { expression }) {
return super.reduceYieldGeneratorExpression(node, { expression: expression() });
}
};
}

View File

@ -0,0 +1,416 @@
// Generated by generate-thunkify.js
/**
* Copyright 2018 Shape Security, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export default function thunkify(reducer) {
return {
reduceArrayAssignmentTarget(node, { elements, rest }) {
return reducer.reduceArrayAssignmentTarget(node, { elements: elements.map(n => n == null ? null : n()), rest: rest == null ? null : rest() });
},
reduceArrayBinding(node, { elements, rest }) {
return reducer.reduceArrayBinding(node, { elements: elements.map(n => n == null ? null : n()), rest: rest == null ? null : rest() });
},
reduceArrayExpression(node, { elements }) {
return reducer.reduceArrayExpression(node, { elements: elements.map(n => n == null ? null : n()) });
},
reduceArrowExpression(node, { params, body }) {
return reducer.reduceArrowExpression(node, { params: params(), body: body() });
},
reduceAssignmentExpression(node, { binding, expression }) {
return reducer.reduceAssignmentExpression(node, { binding: binding(), expression: expression() });
},
reduceAssignmentTargetIdentifier(node) {
return reducer.reduceAssignmentTargetIdentifier(node);
},
reduceAssignmentTargetPropertyIdentifier(node, { binding, init }) {
return reducer.reduceAssignmentTargetPropertyIdentifier(node, { binding: binding(), init: init == null ? null : init() });
},
reduceAssignmentTargetPropertyProperty(node, { name, binding }) {
return reducer.reduceAssignmentTargetPropertyProperty(node, { name: name(), binding: binding() });
},
reduceAssignmentTargetWithDefault(node, { binding, init }) {
return reducer.reduceAssignmentTargetWithDefault(node, { binding: binding(), init: init() });
},
reduceAwaitExpression(node, { expression }) {
return reducer.reduceAwaitExpression(node, { expression: expression() });
},
reduceBinaryExpression(node, { left, right }) {
return reducer.reduceBinaryExpression(node, { left: left(), right: right() });
},
reduceBindingIdentifier(node) {
return reducer.reduceBindingIdentifier(node);
},
reduceBindingPropertyIdentifier(node, { binding, init }) {
return reducer.reduceBindingPropertyIdentifier(node, { binding: binding(), init: init == null ? null : init() });
},
reduceBindingPropertyProperty(node, { name, binding }) {
return reducer.reduceBindingPropertyProperty(node, { name: name(), binding: binding() });
},
reduceBindingWithDefault(node, { binding, init }) {
return reducer.reduceBindingWithDefault(node, { binding: binding(), init: init() });
},
reduceBlock(node, { statements }) {
return reducer.reduceBlock(node, { statements: statements.map(n => n()) });
},
reduceBlockStatement(node, { block }) {
return reducer.reduceBlockStatement(node, { block: block() });
},
reduceBreakStatement(node) {
return reducer.reduceBreakStatement(node);
},
reduceCallExpression(node, { callee, arguments: _arguments }) {
return reducer.reduceCallExpression(node, { callee: callee(), arguments: _arguments.map(n => n()) });
},
reduceCatchClause(node, { binding, body }) {
return reducer.reduceCatchClause(node, { binding: binding(), body: body() });
},
reduceClassDeclaration(node, { name, super: _super, elements }) {
return reducer.reduceClassDeclaration(node, { name: name(), super: _super == null ? null : _super(), elements: elements.map(n => n()) });
},
reduceClassElement(node, { method }) {
return reducer.reduceClassElement(node, { method: method() });
},
reduceClassExpression(node, { name, super: _super, elements }) {
return reducer.reduceClassExpression(node, { name: name == null ? null : name(), super: _super == null ? null : _super(), elements: elements.map(n => n()) });
},
reduceCompoundAssignmentExpression(node, { binding, expression }) {
return reducer.reduceCompoundAssignmentExpression(node, { binding: binding(), expression: expression() });
},
reduceComputedMemberAssignmentTarget(node, { object, expression }) {
return reducer.reduceComputedMemberAssignmentTarget(node, { object: object(), expression: expression() });
},
reduceComputedMemberExpression(node, { object, expression }) {
return reducer.reduceComputedMemberExpression(node, { object: object(), expression: expression() });
},
reduceComputedPropertyName(node, { expression }) {
return reducer.reduceComputedPropertyName(node, { expression: expression() });
},
reduceConditionalExpression(node, { test, consequent, alternate }) {
return reducer.reduceConditionalExpression(node, { test: test(), consequent: consequent(), alternate: alternate() });
},
reduceContinueStatement(node) {
return reducer.reduceContinueStatement(node);
},
reduceDataProperty(node, { name, expression }) {
return reducer.reduceDataProperty(node, { name: name(), expression: expression() });
},
reduceDebuggerStatement(node) {
return reducer.reduceDebuggerStatement(node);
},
reduceDirective(node) {
return reducer.reduceDirective(node);
},
reduceDoWhileStatement(node, { body, test }) {
return reducer.reduceDoWhileStatement(node, { body: body(), test: test() });
},
reduceEmptyStatement(node) {
return reducer.reduceEmptyStatement(node);
},
reduceExport(node, { declaration }) {
return reducer.reduceExport(node, { declaration: declaration() });
},
reduceExportAllFrom(node) {
return reducer.reduceExportAllFrom(node);
},
reduceExportDefault(node, { body }) {
return reducer.reduceExportDefault(node, { body: body() });
},
reduceExportFrom(node, { namedExports }) {
return reducer.reduceExportFrom(node, { namedExports: namedExports.map(n => n()) });
},
reduceExportFromSpecifier(node) {
return reducer.reduceExportFromSpecifier(node);
},
reduceExportLocalSpecifier(node, { name }) {
return reducer.reduceExportLocalSpecifier(node, { name: name() });
},
reduceExportLocals(node, { namedExports }) {
return reducer.reduceExportLocals(node, { namedExports: namedExports.map(n => n()) });
},
reduceExpressionStatement(node, { expression }) {
return reducer.reduceExpressionStatement(node, { expression: expression() });
},
reduceForAwaitStatement(node, { left, right, body }) {
return reducer.reduceForAwaitStatement(node, { left: left(), right: right(), body: body() });
},
reduceForInStatement(node, { left, right, body }) {
return reducer.reduceForInStatement(node, { left: left(), right: right(), body: body() });
},
reduceForOfStatement(node, { left, right, body }) {
return reducer.reduceForOfStatement(node, { left: left(), right: right(), body: body() });
},
reduceForStatement(node, { init, test, update, body }) {
return reducer.reduceForStatement(node, { init: init == null ? null : init(), test: test == null ? null : test(), update: update == null ? null : update(), body: body() });
},
reduceFormalParameters(node, { items, rest }) {
return reducer.reduceFormalParameters(node, { items: items.map(n => n()), rest: rest == null ? null : rest() });
},
reduceFunctionBody(node, { directives, statements }) {
return reducer.reduceFunctionBody(node, { directives: directives.map(n => n()), statements: statements.map(n => n()) });
},
reduceFunctionDeclaration(node, { name, params, body }) {
return reducer.reduceFunctionDeclaration(node, { name: name(), params: params(), body: body() });
},
reduceFunctionExpression(node, { name, params, body }) {
return reducer.reduceFunctionExpression(node, { name: name == null ? null : name(), params: params(), body: body() });
},
reduceGetter(node, { name, body }) {
return reducer.reduceGetter(node, { name: name(), body: body() });
},
reduceIdentifierExpression(node) {
return reducer.reduceIdentifierExpression(node);
},
reduceIfStatement(node, { test, consequent, alternate }) {
return reducer.reduceIfStatement(node, { test: test(), consequent: consequent(), alternate: alternate == null ? null : alternate() });
},
reduceImport(node, { defaultBinding, namedImports }) {
return reducer.reduceImport(node, { defaultBinding: defaultBinding == null ? null : defaultBinding(), namedImports: namedImports.map(n => n()) });
},
reduceImportNamespace(node, { defaultBinding, namespaceBinding }) {
return reducer.reduceImportNamespace(node, { defaultBinding: defaultBinding == null ? null : defaultBinding(), namespaceBinding: namespaceBinding() });
},
reduceImportSpecifier(node, { binding }) {
return reducer.reduceImportSpecifier(node, { binding: binding() });
},
reduceLabeledStatement(node, { body }) {
return reducer.reduceLabeledStatement(node, { body: body() });
},
reduceLiteralBooleanExpression(node) {
return reducer.reduceLiteralBooleanExpression(node);
},
reduceLiteralInfinityExpression(node) {
return reducer.reduceLiteralInfinityExpression(node);
},
reduceLiteralNullExpression(node) {
return reducer.reduceLiteralNullExpression(node);
},
reduceLiteralNumericExpression(node) {
return reducer.reduceLiteralNumericExpression(node);
},
reduceLiteralRegExpExpression(node) {
return reducer.reduceLiteralRegExpExpression(node);
},
reduceLiteralStringExpression(node) {
return reducer.reduceLiteralStringExpression(node);
},
reduceMethod(node, { name, params, body }) {
return reducer.reduceMethod(node, { name: name(), params: params(), body: body() });
},
reduceModule(node, { directives, items }) {
return reducer.reduceModule(node, { directives: directives.map(n => n()), items: items.map(n => n()) });
},
reduceNewExpression(node, { callee, arguments: _arguments }) {
return reducer.reduceNewExpression(node, { callee: callee(), arguments: _arguments.map(n => n()) });
},
reduceNewTargetExpression(node) {
return reducer.reduceNewTargetExpression(node);
},
reduceObjectAssignmentTarget(node, { properties, rest }) {
return reducer.reduceObjectAssignmentTarget(node, { properties: properties.map(n => n()), rest: rest == null ? null : rest() });
},
reduceObjectBinding(node, { properties, rest }) {
return reducer.reduceObjectBinding(node, { properties: properties.map(n => n()), rest: rest == null ? null : rest() });
},
reduceObjectExpression(node, { properties }) {
return reducer.reduceObjectExpression(node, { properties: properties.map(n => n()) });
},
reduceReturnStatement(node, { expression }) {
return reducer.reduceReturnStatement(node, { expression: expression == null ? null : expression() });
},
reduceScript(node, { directives, statements }) {
return reducer.reduceScript(node, { directives: directives.map(n => n()), statements: statements.map(n => n()) });
},
reduceSetter(node, { name, param, body }) {
return reducer.reduceSetter(node, { name: name(), param: param(), body: body() });
},
reduceShorthandProperty(node, { name }) {
return reducer.reduceShorthandProperty(node, { name: name() });
},
reduceSpreadElement(node, { expression }) {
return reducer.reduceSpreadElement(node, { expression: expression() });
},
reduceSpreadProperty(node, { expression }) {
return reducer.reduceSpreadProperty(node, { expression: expression() });
},
reduceStaticMemberAssignmentTarget(node, { object }) {
return reducer.reduceStaticMemberAssignmentTarget(node, { object: object() });
},
reduceStaticMemberExpression(node, { object }) {
return reducer.reduceStaticMemberExpression(node, { object: object() });
},
reduceStaticPropertyName(node) {
return reducer.reduceStaticPropertyName(node);
},
reduceSuper(node) {
return reducer.reduceSuper(node);
},
reduceSwitchCase(node, { test, consequent }) {
return reducer.reduceSwitchCase(node, { test: test(), consequent: consequent.map(n => n()) });
},
reduceSwitchDefault(node, { consequent }) {
return reducer.reduceSwitchDefault(node, { consequent: consequent.map(n => n()) });
},
reduceSwitchStatement(node, { discriminant, cases }) {
return reducer.reduceSwitchStatement(node, { discriminant: discriminant(), cases: cases.map(n => n()) });
},
reduceSwitchStatementWithDefault(node, { discriminant, preDefaultCases, defaultCase, postDefaultCases }) {
return reducer.reduceSwitchStatementWithDefault(node, { discriminant: discriminant(), preDefaultCases: preDefaultCases.map(n => n()), defaultCase: defaultCase(), postDefaultCases: postDefaultCases.map(n => n()) });
},
reduceTemplateElement(node) {
return reducer.reduceTemplateElement(node);
},
reduceTemplateExpression(node, { tag, elements }) {
return reducer.reduceTemplateExpression(node, { tag: tag == null ? null : tag(), elements: elements.map(n => n()) });
},
reduceThisExpression(node) {
return reducer.reduceThisExpression(node);
},
reduceThrowStatement(node, { expression }) {
return reducer.reduceThrowStatement(node, { expression: expression() });
},
reduceTryCatchStatement(node, { body, catchClause }) {
return reducer.reduceTryCatchStatement(node, { body: body(), catchClause: catchClause() });
},
reduceTryFinallyStatement(node, { body, catchClause, finalizer }) {
return reducer.reduceTryFinallyStatement(node, { body: body(), catchClause: catchClause == null ? null : catchClause(), finalizer: finalizer() });
},
reduceUnaryExpression(node, { operand }) {
return reducer.reduceUnaryExpression(node, { operand: operand() });
},
reduceUpdateExpression(node, { operand }) {
return reducer.reduceUpdateExpression(node, { operand: operand() });
},
reduceVariableDeclaration(node, { declarators }) {
return reducer.reduceVariableDeclaration(node, { declarators: declarators.map(n => n()) });
},
reduceVariableDeclarationStatement(node, { declaration }) {
return reducer.reduceVariableDeclarationStatement(node, { declaration: declaration() });
},
reduceVariableDeclarator(node, { binding, init }) {
return reducer.reduceVariableDeclarator(node, { binding: binding(), init: init == null ? null : init() });
},
reduceWhileStatement(node, { test, body }) {
return reducer.reduceWhileStatement(node, { test: test(), body: body() });
},
reduceWithStatement(node, { object, body }) {
return reducer.reduceWithStatement(node, { object: object(), body: body() });
},
reduceYieldExpression(node, { expression }) {
return reducer.reduceYieldExpression(node, { expression: expression == null ? null : expression() });
},
reduceYieldGeneratorExpression(node, { expression }) {
return reducer.reduceYieldGeneratorExpression(node, { expression: expression() });
},
};
}

View File

@ -0,0 +1,61 @@
/*
Copyright (C) 2014 Yusuke Suzuki <utatane.tea@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import Spec from 'shift-spec';
// import { version } from '../package.json'
// Loading uncached estraverse for changing estraverse.Syntax.
import _estraverse from 'estraverse';
const estraverse = _estraverse.cloneEnvironment();
// Adjust estraverse members.
Object.keys(estraverse.Syntax)
.filter((key) => key !== 'Property')
.forEach((key) => {
delete estraverse.Syntax[key];
delete estraverse.VisitorKeys[key];
});
Object.assign(
estraverse.Syntax,
Object.keys(Spec).reduce((result, key) => {
result[key] = key;
return result;
}, {})
);
Object.assign(
estraverse.VisitorKeys,
Object.keys(Spec).reduce((result, key) => {
result[key] = Spec[key].fields.map((field) => field.name);
return result;
}, {})
);
// estraverse.version = version;
export default estraverse;
/* vim: set sw=4 ts=4 et tw=80 : */

View File

@ -1,14 +1,18 @@
import { Pattern as _Pattern } from '../../strudel.mjs';
import { AutoFilter, Destination, Filter, Gain, Transport, Synth } from 'tone';
import { AutoFilter, Destination, Filter, Gain, isNote, Synth } from 'tone';
const Pattern = _Pattern as any;
const getTrigger = (getChain: any, value: any) => (time: number, event: any) => {
const chain = getChain(time); // make sure this returns a node that is connected toDestination
const chain = getChain(); // make sure this returns a node that is connected toDestination // time
if (!isNote(value)) {
throw new Error('not a note: ' + value);
}
chain.triggerAttackRelease(value, event.duration, time);
Transport.scheduleOnce(() => {
setTimeout(() => {
// setTimeout is a little bit better compared to Transport.scheduleOnce
chain.dispose(); // mark for garbage collection
}, '+' + event.duration * 2);
}, event.duration * 2000);
};
Pattern.prototype._synth = function (type: any = 'triangle') {
@ -54,8 +58,8 @@ Pattern.prototype.chain = function (...effectGetters: any) {
throw new Error('cannot chain: need instrument first (like synth)');
}
const chain = (value.chain || []).concat(effectGetters);
const getChain = (time: number) => {
const effects = chain.map((getEffect: any) => getEffect(time));
const getChain = () => {
const effects = chain.map((getEffect: any) => getEffect());
return value.getInstrument().chain(...effects, Destination);
};
const onTrigger = getTrigger(getChain, value.value);

View File

@ -1,3 +1,26 @@
export const shapeShifted = `stack(
sequence(
e5, [b4, c5], d5, [c5, b4],
a4, [a4, c5], e5, [d5, c5],
b4, [r, c5], d5, e5,
c5, a4, a4, r,
[r, d5], [r, f5], a5, [g5, f5],
e5, [r, c5], e5, [d5, c5],
b4, [b4, c5], d5, e5,
c5, a4, a4, r,
).rev(),
sequence(
e2, e3, e2, e3, e2, e3, e2, e3,
a2, a3, a2, a3, a2, a3, a2, a3,
gs2, gs3, gs2, gs3, e2, e3, e2, e3,
a2, a3, a2, a3, a2, a3, b1, c2,
d2, d3, d2, d3, d2, d3, d2, d3,
c2, c3, c2, c3, c2, c3, c2, c3,
b1, b2, b1, b2, e2, e3, e2, e3,
a1, a2, a1, a2, a1, a2, a1, a2,
).rev()
).slow(16).rev()`;
export const tetrisWithFunctions = `stack(sequence(
'e5', sequence('b4', 'c5'), 'd5', sequence('c5', 'b4'),
'a4', sequence('a4', 'c5'), 'e5', sequence('d5', 'c5'),